diff --git a/.github/workflows/action-pr-approved.yaml b/.github/workflows/action-pr-approved.yaml deleted file mode 100644 index d9289e66cad8..000000000000 --- a/.github/workflows/action-pr-approved.yaml +++ /dev/null @@ -1,17 +0,0 @@ -name: Pull Request Reviewed - -on: - pull_request_review: - types: [submitted] - -jobs: - pr-reviewed: - if: github.event.review.state == 'approved' - runs-on: ubuntu-latest - steps: - - name: Update Asana task -> PR approved - uses: duckduckgo/native-github-asana-sync@v1.1 - with: - asana-pat: ${{ secrets.GH_ASANA_SECRET }} - trigger-phrase: "Task/Issue URL:" - action: 'notify-pr-approved' \ No newline at end of file diff --git a/.github/workflows/pr-review-notifications.yaml b/.github/workflows/pr-review-notifications.yaml index fc2c2b9d745c..e39c117c962f 100644 --- a/.github/workflows/pr-review-notifications.yaml +++ b/.github/workflows/pr-review-notifications.yaml @@ -1,4 +1,4 @@ -name: Pull Request Reviewed -> Asana Sync +name: Pull Request Reviewed -> Sync With Asana on: pull_request_review: @@ -6,8 +6,8 @@ on: jobs: pr-reviewed: - name: Update Asana task -> PR reviewed - uses: duckduckgo/native-github-asana-sync/.github/workflows/pr-review-notifications.yml@david/improve-pr-notifications + name: Add PR reviewed comment + uses: duckduckgo/native-github-asana-sync/.github/workflows/pr-review-notifications.yml@v1.4.1 with: trigger-phrase: "Task/Issue URL:" secrets: diff --git a/app/lint-baseline.xml b/app/lint-baseline.xml index 734ba3cc6bc5..32ea3646c177 100644 --- a/app/lint-baseline.xml +++ b/app/lint-baseline.xml @@ -7679,4 +7679,15 @@ column="9"/> + + + + diff --git a/app/src/androidTest/resources/reference_tests/domain_matching_tests.json b/app/src/androidTest/resources/reference_tests/domain_matching_tests.json index 6186e1181f02..22b32afcfc65 100644 --- a/app/src/androidTest/resources/reference_tests/domain_matching_tests.json +++ b/app/src/androidTest/resources/reference_tests/domain_matching_tests.json @@ -34,6 +34,13 @@ "requestType": "script", "expectAction": "ignore" }, + { + "name": "same party ignore with deeper subdomain", + "siteURL": "https://bad.etld-plus-two.site/", + "requestURL": "https://bad.etld-plus-two.site/script.js", + "requestType": "script", + "expectAction": "ignore" + }, { "name": "tracker loads ignore", "siteURL": "https://bad.third-party.site/", diff --git a/app/src/androidTest/resources/reference_tests/tracker_radar_reference.json b/app/src/androidTest/resources/reference_tests/tracker_radar_reference.json index 9a831c9e5063..aff7c7750124 100644 --- a/app/src/androidTest/resources/reference_tests/tracker_radar_reference.json +++ b/app/src/androidTest/resources/reference_tests/tracker_radar_reference.json @@ -255,6 +255,21 @@ "rules": [], "default": "ignore" }, + "bad.etld-plus-two.site": { + "domain": "bad.etld-plus-two.site", + "owner": { + "name": "Test Site for Tracker Blocking With eTLD+2", + "displayName": "Bad Third Party Site eTLD+2", + "privacyPolicy": "", + "url": "http://bad.etld-plus-two.site" + }, + "prevalence": 0.1, + "fingerprinting": 3, + "cookies": 0.1, + "categories": [], + "default": "block", + "rules": [] + }, "tracker.test": { "domain": "tracker.test", "owner": { @@ -819,6 +834,13 @@ "prevalence": 0.1, "displayName": "Test Site for Tracker Blocking" }, + "Test Site for Tracker Blocking With eTLD+2": { + "domains": [ + "bad.etld-plus-two.site" + ], + "prevalence": 0.1, + "displayName": "Bad Third Party Site eTLD+2" + }, "Tests for formatting": { "domains": [ "format.test" @@ -876,6 +898,7 @@ "bad.third-party.site": "Test Site for Tracker Blocking", "sometimes-bad.third-party.site": "Test Site for Tracker Blocking", "broken.third-party.site": "Test Site for Tracker Blocking", + "bad.etld-plus-two.site": "Test Site for Tracker Blocking With eTLD+2", "format.test": "Tests for formatting", "third-party.site": "Test Site for Tracker Blocking", "tracker.test": "Test Site for Tracker Blocking", diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserActivity.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserActivity.kt index b04da52c6bdb..53cb2e137eda 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserActivity.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserActivity.kt @@ -31,6 +31,7 @@ import androidx.activity.OnBackPressedCallback import androidx.activity.result.ActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.annotation.VisibleForTesting +import androidx.core.view.isVisible import androidx.lifecycle.flowWithLifecycle import androidx.lifecycle.lifecycleScope import androidx.viewpager2.widget.MarginPageTransformer @@ -186,7 +187,7 @@ open class BrowserActivity : DuckDuckGoActivity() { wasSwipingStarted = false viewModel.onTabsSwiped() - tabManager.tabPagerAdapter.onPageChanged(position) + tabManager.onTabPageSwiped(position) } } @@ -234,6 +235,9 @@ open class BrowserActivity : DuckDuckGoActivity() { } setContentView(binding.root) + + initializeTabs() + viewModel.viewState.observe(this) { renderer.renderBrowserViewState(it) } @@ -420,7 +424,7 @@ open class BrowserActivity : DuckDuckGoActivity() { val existingTabId = intent.getStringExtra(OPEN_EXISTING_TAB_ID_EXTRA) if (existingTabId != null) { if (swipingTabsFeature.isEnabled) { - tabManager.openExistingTab(existingTabId) + tabManager.switchToTab(existingTabId) } else { openExistingTab(existingTabId) } @@ -442,7 +446,7 @@ open class BrowserActivity : DuckDuckGoActivity() { } else { Timber.w("can't use current tab, opening in new tab instead") if (swipingTabsFeature.isEnabled) { - tabManager.openInNewTab(query = sharedText, skipHome = true) + tabManager.launchNewTab(query = sharedText, skipHome = true) } else { lifecycleScope.launch { viewModel.onOpenInNewTabRequested(query = sharedText, skipHome = true) } } @@ -459,7 +463,7 @@ open class BrowserActivity : DuckDuckGoActivity() { val sourceTabId = if (selectedText) currentTab?.tabId else null val skipHome = !selectedText if (swipingTabsFeature.isEnabled) { - tabManager.openInNewTab(sourceTabId = sourceTabId, query = sharedText, skipHome = skipHome) + tabManager.launchNewTab(sourceTabId = sourceTabId, query = sharedText, skipHome = skipHome) } else { lifecycleScope.launch { viewModel.onOpenInNewTabRequested(sourceTabId = sourceTabId, query = sharedText, skipHome = skipHome) } } @@ -480,7 +484,7 @@ open class BrowserActivity : DuckDuckGoActivity() { if (swipingTabsFeature.isEnabled) { lifecycleScope.launch { viewModel.tabsFlow.flowWithLifecycle(lifecycle).collectLatest { - tabManager.onTabsUpdated(it) + tabManager.onTabsChanged(it) } } @@ -562,8 +566,8 @@ open class BrowserActivity : DuckDuckGoActivity() { is Command.ShowAppRatingPrompt -> showAppRatingDialog(command.promptCount) is Command.ShowAppFeedbackPrompt -> showGiveFeedbackDialog(command.promptCount) is Command.LaunchFeedbackView -> startActivity(FeedbackActivity.intent(this)) - is Command.SwitchToTab -> tabManager.openExistingTab(command.tabId) - is Command.OpenInNewTab -> tabManager.openInNewTab(command.url) + is Command.SwitchToTab -> tabManager.switchToTab(command.tabId) + is Command.OpenInNewTab -> tabManager.launchNewTab(command.url) is Command.OpenSavedSite -> currentTab?.submitQuery(command.url) } } @@ -777,19 +781,15 @@ open class BrowserActivity : DuckDuckGoActivity() { } } - @SuppressLint("ClickableViewAccessibility", "WrongConstant") private fun initializeTabs() { if (swipingTabsFeature.isEnabled) { tabPager.adapter = tabManager.tabPagerAdapter tabPager.registerOnPageChangeCallback(onTabPageChangeListener) tabPager.setPageTransformer(MarginPageTransformer(resources.getDimension(com.duckduckgo.mobile.android.R.dimen.keyline_2).toPx().toInt())) - - binding.fragmentContainer.gone() - tabPager.show() - } else { - binding.fragmentContainer.show() - tabPager.gone() } + + binding.fragmentContainer.isVisible = !swipingTabsFeature.isEnabled + tabPager.isVisible = swipingTabsFeature.isEnabled } private val Intent.launchedFromRecents: Boolean diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt index 429cc1e980bc..aa567c8b14bc 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabFragment.kt @@ -835,10 +835,9 @@ class BrowserTabFragment : } } - override fun onViewCreated( - view: View, - savedInstanceState: Bundle?, - ) { + override fun onActivityCreated(savedInstanceState: Bundle?) { + super.onActivityCreated(savedInstanceState) + omnibar = Omnibar(settingsDataStore.omnibarPosition, changeOmnibarPositionFeature.refactor().isEnabled(), binding) webViewContainer = binding.webViewContainer @@ -1076,6 +1075,9 @@ class BrowserTabFragment : onMenuItemClicked(changeBrowserModeMenuItem) { viewModel.onChangeBrowserModeClicked() } + onMenuItemClicked(defaultBrowserMenuItem) { + viewModel.onSetDefaultBrowserSelected() + } onMenuItemClicked(sharePageMenuItem) { pixel.fire(AppPixelName.MENU_ACTION_SHARE_PRESSED) viewModel.onShareSelected() @@ -1530,7 +1532,7 @@ class BrowserTabFragment : is NavigationCommand.Refresh -> refresh() is Command.OpenInNewTab -> { if (swipingTabsFeature.isEnabled) { - requireBrowserActivity().tabManager.openInNewTab(it.query, it.sourceTabId) + requireBrowserActivity().tabManager.launchNewTab(it.query, it.sourceTabId) } else { browserActivity?.openInNewTab(it.query, it.sourceTabId) } @@ -1808,7 +1810,7 @@ class BrowserTabFragment : binding.autoCompleteSuggestionsList.gone() if (swipingTabsFeature.isEnabled) { - requireBrowserActivity().tabManager.openExistingTab(it.tabId) + requireBrowserActivity().tabManager.switchToTab(it.tabId) } else { browserActivity?.openExistingTab(it.tabId) } @@ -3017,15 +3019,17 @@ class BrowserTabFragment : } override fun onContextItemSelected(item: MenuItem): Boolean { - runCatching { - webView?.safeHitTestResult?.let { - val target = getLongPressTarget(it) - if (target != null && viewModel.userSelectedItemFromLongPressMenu(target, item)) { - return true + if (this.isResumed) { + runCatching { + webView?.safeHitTestResult?.let { + val target = getLongPressTarget(it) + if (target != null && viewModel.userSelectedItemFromLongPressMenu(target, item)) { + return true + } } + }.onFailure { exception -> + Timber.e(exception, "Failed to get HitTestResult") } - }.onFailure { exception -> - Timber.e(exception, "Failed to get HitTestResult") } return super.onContextItemSelected(item) } diff --git a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt index 84540ecce5bd..3fe751887c2c 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/BrowserTabViewModel.kt @@ -2525,6 +2525,10 @@ class BrowserTabViewModel @Inject constructor( } } + fun onSetDefaultBrowserSelected() { + // no-op, to be implemented + } + fun onShareSelected() { url?.let { viewModelScope.launch(dispatchers.io()) { diff --git a/app/src/main/java/com/duckduckgo/app/browser/menu/BrowserPopupMenu.kt b/app/src/main/java/com/duckduckgo/app/browser/menu/BrowserPopupMenu.kt index b955233543cb..d62cf953ca03 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/menu/BrowserPopupMenu.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/menu/BrowserPopupMenu.kt @@ -87,6 +87,13 @@ class BrowserPopupMenu( } } + internal val defaultBrowserMenuItem: View by lazy { + when (omnibarPosition) { + TOP -> topBinding.includeDefaultBrowserMenuItem.defaultBrowserMenuItem + BOTTOM -> bottomBinding.includeDefaultBrowserMenuItem.defaultBrowserMenuItem + } + } + internal val sharePageMenuItem: View by lazy { when (omnibarPosition) { TOP -> topBinding.sharePageMenuItem @@ -240,6 +247,8 @@ class BrowserPopupMenu( newTabMenuItem.isVisible = browserShowing && !displayedInCustomTabScreen sharePageMenuItem.isVisible = viewState.canSharePage + defaultBrowserMenuItem.isVisible = viewState.showSelectDefaultBrowserMenuItem + bookmarksMenuItem.isVisible = !displayedInCustomTabScreen downloadsMenuItem.isVisible = !displayedInCustomTabScreen settingsMenuItem.isVisible = !displayedInCustomTabScreen diff --git a/app/src/main/java/com/duckduckgo/app/browser/tabs/DefaultTabManager.kt b/app/src/main/java/com/duckduckgo/app/browser/tabs/DefaultTabManager.kt index 9f8d2c298aab..04d9336d4d2d 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/tabs/DefaultTabManager.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/tabs/DefaultTabManager.kt @@ -20,130 +20,83 @@ import android.os.Message import androidx.lifecycle.lifecycleScope import com.duckduckgo.app.browser.BrowserActivity import com.duckduckgo.app.browser.BrowserTabFragment -import com.duckduckgo.app.browser.SkipUrlConversionOnNewTabFeature -import com.duckduckgo.app.browser.omnibar.OmnibarEntryConverter import com.duckduckgo.app.browser.tabs.adapter.TabPagerAdapter import com.duckduckgo.app.tabs.model.TabEntity -import com.duckduckgo.app.tabs.model.TabRepository -import com.duckduckgo.common.utils.DispatcherProvider import com.duckduckgo.di.scopes.ActivityScope import com.squareup.anvil.annotations.ContributesBinding import dagger.SingleInstanceIn import dagger.android.DaggerActivity import javax.inject.Inject +import kotlin.coroutines.CoroutineContext +import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Job -import kotlinx.coroutines.flow.first -import kotlinx.coroutines.flow.transformWhile import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking -import timber.log.Timber + +interface TabManager : CoroutineScope { + companion object { + const val MAX_ACTIVE_TABS = 20 + } + + val tabOperationManager: TabOperationManager + + val currentTab: BrowserTabFragment? + val tabPagerAdapter: TabPagerAdapter + + fun onTabPageSwiped(newPosition: Int) + fun openMessageInNewTab(message: Message, sourceTabId: String?) + fun clearTabsInMemory() + fun onCleanup() + + fun onSelectedTabChanged(tabId: String) = tabOperationManager.onSelectedTabChanged(tabId) + fun onTabsChanged(updatedTabIds: List) = launch { tabOperationManager.onTabsChanged(updatedTabIds) } + fun switchToTab(tabId: String) = launch { tabOperationManager.selectTab(tabId) } + fun launchNewTab(query: String? = null, sourceTabId: String? = null, skipHome: Boolean = false) = launch { + tabOperationManager.openNewTab(query, sourceTabId, skipHome) + } +} @ContributesBinding(ActivityScope::class) @SingleInstanceIn(ActivityScope::class) class DefaultTabManager @Inject constructor( activity: DaggerActivity, - private val tabRepository: TabRepository, - private val dispatchers: DispatcherProvider, - private val queryUrlConverter: OmnibarEntryConverter, - private val skipUrlConversionOnNewTabFeature: SkipUrlConversionOnNewTabFeature, + override val tabOperationManager: TabOperationManager, ) : TabManager { private val browserActivity = activity as BrowserActivity private val supportFragmentManager = activity.supportFragmentManager - private var openMessageInNewTabJob: Job? = null - - private val keepSingleTab: Boolean - get() = !browserActivity.tabPager.isUserInputEnabled - private val coroutineScope = browserActivity.lifecycleScope - var selectedTabId: String? = null - private set + private var openMessageInNewTabJob: Job? = null override val tabPagerAdapter by lazy { TabPagerAdapter( fragmentManager = supportFragmentManager, lifecycleOwner = browserActivity, activityIntent = browserActivity.intent, - getSelectedTabId = { selectedTabId }, + getSelectedTabId = { tabOperationManager.getSelectedTabId() }, getTabById = ::getTabById, - requestNewTab = ::requestNewTab, - onTabSelected = { tabId -> openExistingTab(tabId) }, + requestAndWaitForNewTab = ::requestAndWaitForNewTab, ) } - override val currentTab: BrowserTabFragment? - get() = tabPagerAdapter.currentFragment - - override fun onSelectedTabChanged(tabId: String) { - Timber.d("### TabManager.onSelectedTabChanged: $tabId") - selectedTabId = tabId - - if (keepSingleTab) { - tabPagerAdapter.onTabsUpdated(listOf(tabId)) - } + init { + tabOperationManager.registerCallbacks(::onTabsUpdated, ::shouldKeepSingleTab) } - override fun onTabsUpdated(updatedTabIds: List) { - Timber.d("### TabManager.onTabsUpdated: $updatedTabIds") - if (keepSingleTab) { - updatedTabIds.firstOrNull { it == selectedTabId }?.let { - tabPagerAdapter.onTabsUpdated(listOf(it)) - } - } else { - tabPagerAdapter.onTabsUpdated(updatedTabIds) - } - - if (updatedTabIds.isEmpty()) { - coroutineScope.launch(dispatchers.io()) { - Timber.i("Tabs list is null or empty; adding default tab") - tabRepository.addDefaultTab() - } + override fun onTabPageSwiped(newPosition: Int) { + val tabId = tabPagerAdapter.getTabIdAtPosition(newPosition) + if (tabId != null) { + switchToTab(tabId) } } + override val currentTab: BrowserTabFragment? + get() = tabPagerAdapter.currentFragment + override fun openMessageInNewTab(message: Message, sourceTabId: String?) { openMessageInNewTabJob = coroutineScope.launch { tabPagerAdapter.setMessageForNewFragment(message) - openNewTab(sourceTabId) - } - } - - override fun openExistingTab(tabId: String) { - coroutineScope.launch(dispatchers.io()) { - if (tabId != tabRepository.getSelectedTab()?.tabId) { - tabRepository.select(tabId) - } - } - } - - override fun launchNewTab() { - coroutineScope.launch { openNewTab() } - } - - override fun openInNewTab( - query: String, - sourceTabId: String?, - skipHome: Boolean, - ) { - coroutineScope.launch { - val url = if (skipUrlConversionOnNewTabFeature.self().isEnabled()) { - query - } else { - queryUrlConverter.convertQueryToUrl(query) - } - - if (sourceTabId != null) { - tabRepository.addFromSourceTab( - url = url, - skipHome = skipHome, - sourceTabId = sourceTabId, - ) - } else { - tabRepository.add( - url = url, - skipHome = skipHome, - ) - } + tabOperationManager.openNewTab(sourceTabId) } } @@ -155,26 +108,19 @@ class DefaultTabManager @Inject constructor( openMessageInNewTabJob?.cancel() } - private suspend fun openNewTab(sourceTabId: String? = null): String { - return if (sourceTabId != null) { - tabRepository.addFromSourceTab(sourceTabId = sourceTabId) - } else { - tabRepository.add() - } + private fun onTabsUpdated(updatedTabIds: List) { + tabPagerAdapter.onTabsUpdated(updatedTabIds) } - private fun requestNewTab(): TabEntity = runBlocking(dispatchers.io()) { - val tabId = openNewTab() - return@runBlocking tabRepository.flowTabs.transformWhile { result -> - result.firstOrNull { it.tabId == tabId }?.let { entity -> - emit(entity) - return@transformWhile true - } - return@transformWhile false - }.first() - } + private fun shouldKeepSingleTab() = !browserActivity.tabPager.isUserInputEnabled private fun getTabById(tabId: String): TabEntity? = runBlocking { - tabRepository.getTab(tabId) + return@runBlocking tabOperationManager.getTabById(tabId) + } + + private fun requestAndWaitForNewTab(): TabEntity = runBlocking { + return@runBlocking tabOperationManager.requestAndWaitForNewTab() } + + override val coroutineContext: CoroutineContext = activity.lifecycleScope.coroutineContext } diff --git a/app/src/main/java/com/duckduckgo/app/browser/tabs/DefaultTabOperationManager.kt b/app/src/main/java/com/duckduckgo/app/browser/tabs/DefaultTabOperationManager.kt new file mode 100644 index 000000000000..ea40c1697335 --- /dev/null +++ b/app/src/main/java/com/duckduckgo/app/browser/tabs/DefaultTabOperationManager.kt @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * Licensed 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 com.duckduckgo.app.browser.tabs + +import com.duckduckgo.app.browser.SkipUrlConversionOnNewTabFeature +import com.duckduckgo.app.browser.omnibar.OmnibarEntryConverter +import com.duckduckgo.app.tabs.model.TabEntity +import com.duckduckgo.app.tabs.model.TabRepository +import com.duckduckgo.common.utils.DispatcherProvider +import com.duckduckgo.di.scopes.ActivityScope +import com.squareup.anvil.annotations.ContributesBinding +import javax.inject.Inject +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.transformWhile +import kotlinx.coroutines.withContext +import timber.log.Timber + +interface TabOperationManager { + fun registerCallbacks(onTabsUpdated: (List) -> Unit, shouldKeepSingleTab: () -> Boolean) + fun getSelectedTabId(): String? + fun onSelectedTabChanged(tabId: String) + + suspend fun onTabsChanged(updatedTabIds: List) + suspend fun selectTab(tabId: String) + suspend fun requestAndWaitForNewTab(): TabEntity + suspend fun openNewTab(query: String? = null, sourceTabId: String? = null, skipHome: Boolean = false): String + suspend fun getTabById(tabId: String): TabEntity? +} + +@ContributesBinding(ActivityScope::class) +class DefaultTabOperationManager @Inject constructor( + private val tabRepository: TabRepository, + private val dispatchers: DispatcherProvider, + private val queryUrlConverter: OmnibarEntryConverter, + private val skipUrlConversionOnNewTabFeature: SkipUrlConversionOnNewTabFeature, +) : TabOperationManager { + private lateinit var onTabsUpdated: (List) -> Unit + private lateinit var shouldKeepSingleTab: () -> Boolean + private var selectedTabId: String? = null + + override fun registerCallbacks(onTabsUpdated: (List) -> Unit, shouldKeepSingleTab: () -> Boolean) { + this.onTabsUpdated = onTabsUpdated + this.shouldKeepSingleTab = shouldKeepSingleTab + } + + override fun getSelectedTabId(): String? = selectedTabId + + override fun onSelectedTabChanged(tabId: String) { + Timber.d("### TabManager.onSelectedTabChanged: $tabId") + selectedTabId = tabId + + if (shouldKeepSingleTab()) { + onTabsUpdated(listOf(tabId)) + } + } + + override suspend fun onTabsChanged(updatedTabIds: List) { + Timber.d("### TabManager.onTabsUpdated: $updatedTabIds") + if (shouldKeepSingleTab()) { + updatedTabIds.firstOrNull { it == selectedTabId }?.let { + onTabsUpdated(listOf(it)) + } + } else { + onTabsUpdated(updatedTabIds) + } + + if (updatedTabIds.isEmpty()) { + withContext(dispatchers.io()) { + Timber.i("Tabs list is null or empty; adding default tab") + tabRepository.addDefaultTab() + } + } + } + + override suspend fun requestAndWaitForNewTab(): TabEntity = withContext(dispatchers.io()) { + val tabId = openNewTab() + return@withContext tabRepository.flowTabs.transformWhile { result -> + result.firstOrNull { it.tabId == tabId }?.let { entity -> + emit(entity) + return@transformWhile true + } + return@transformWhile false + }.first() + } + + override suspend fun selectTab(tabId: String) = withContext(dispatchers.io()) { + if (tabId != tabRepository.getSelectedTab()?.tabId) { + tabRepository.select(tabId) + } + } + + override suspend fun openNewTab( + query: String?, + sourceTabId: String?, + skipHome: Boolean, + ): String = withContext(dispatchers.io()) { + val url = query?.let { + if (skipUrlConversionOnNewTabFeature.self().isEnabled()) { + query + } else { + queryUrlConverter.convertQueryToUrl(query) + } + } + + return@withContext if (sourceTabId != null) { + tabRepository.addFromSourceTab( + url = url, + skipHome = skipHome, + sourceTabId = sourceTabId, + ) + } else { + tabRepository.add( + url = url, + skipHome = skipHome, + ) + } + } + + override suspend fun getTabById(tabId: String): TabEntity? = withContext(dispatchers.io()) { + return@withContext tabRepository.getTab(tabId) + } +} diff --git a/app/src/main/java/com/duckduckgo/app/browser/tabs/TabManager.kt b/app/src/main/java/com/duckduckgo/app/browser/tabs/TabManager.kt deleted file mode 100644 index 76606c7a0ee8..000000000000 --- a/app/src/main/java/com/duckduckgo/app/browser/tabs/TabManager.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2024 DuckDuckGo - * - * Licensed 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 com.duckduckgo.app.browser.tabs - -import android.os.Message -import com.duckduckgo.app.browser.BrowserTabFragment -import com.duckduckgo.app.browser.tabs.adapter.TabPagerAdapter - -interface TabManager { - companion object { - const val MAX_ACTIVE_TABS = 20 - } - - val currentTab: BrowserTabFragment? - val tabPagerAdapter: TabPagerAdapter - - fun onSelectedTabChanged(tabId: String) - fun onTabsUpdated(updatedTabIds: List) - - fun openMessageInNewTab(message: Message, sourceTabId: String?) - fun openExistingTab(tabId: String) - fun launchNewTab() - fun openInNewTab(query: String, sourceTabId: String? = null, skipHome: Boolean = false) - - fun clearTabsInMemory() - fun onCleanup() -} diff --git a/app/src/main/java/com/duckduckgo/app/browser/tabs/adapter/TabPagerAdapter.kt b/app/src/main/java/com/duckduckgo/app/browser/tabs/adapter/TabPagerAdapter.kt index 09c146a0f869..485bae7f8618 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/tabs/adapter/TabPagerAdapter.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/tabs/adapter/TabPagerAdapter.kt @@ -32,9 +32,8 @@ class TabPagerAdapter( private val fragmentManager: FragmentManager, private val activityIntent: Intent?, private val getTabById: (String) -> TabEntity?, - private val requestNewTab: () -> TabEntity, + private val requestAndWaitForNewTab: () -> TabEntity, private val getSelectedTabId: () -> String?, - private val onTabSelected: (String) -> Unit, ) : FragmentStateAdapter(fragmentManager, lifecycleOwner.lifecycle) { private val tabIds = mutableListOf() private var messageForNewFragment: Message? = null @@ -51,7 +50,7 @@ class TabPagerAdapter( .firstOrNull { it.tabId == getSelectedTabId() } override fun createFragment(position: Int): Fragment { - val tab = getTabById(tabIds[position]) ?: requestNewTab() + val tab = getTabById(tabIds[position]) ?: requestAndWaitForNewTab() val isExternal = activityIntent?.getBooleanExtra(BrowserActivity.LAUNCH_FROM_EXTERNAL_EXTRA, false) == true return if (messageForNewFragment != null) { @@ -77,9 +76,11 @@ class TabPagerAdapter( tabIds.addAll(newTabs) } - fun onPageChanged(position: Int) { - if (position < tabIds.size) { - onTabSelected(tabIds[position]) + fun getTabIdAtPosition(position: Int): String? { + return if (position < tabIds.size) { + tabIds[position] + } else { + null } } diff --git a/app/src/main/java/com/duckduckgo/app/browser/viewstate/BrowserViewState.kt b/app/src/main/java/com/duckduckgo/app/browser/viewstate/BrowserViewState.kt index 66dd8df17782..bfb487f1e751 100644 --- a/app/src/main/java/com/duckduckgo/app/browser/viewstate/BrowserViewState.kt +++ b/app/src/main/java/com/duckduckgo/app/browser/viewstate/BrowserViewState.kt @@ -34,6 +34,7 @@ data class BrowserViewState( val showTabsButton: Boolean = true, val fireButton: HighlightableButton = HighlightableButton.Visible(), val showMenuButton: HighlightableButton = HighlightableButton.Visible(), + val showSelectDefaultBrowserMenuItem: Boolean = false, val canSharePage: Boolean = false, val canSaveSite: Boolean = false, val bookmark: SavedSite.Bookmark? = null, diff --git a/app/src/main/java/com/duckduckgo/app/cta/ui/CtaViewModel.kt b/app/src/main/java/com/duckduckgo/app/cta/ui/CtaViewModel.kt index 429c4902c5c2..54c6c7c5e661 100644 --- a/app/src/main/java/com/duckduckgo/app/cta/ui/CtaViewModel.kt +++ b/app/src/main/java/com/duckduckgo/app/cta/ui/CtaViewModel.kt @@ -139,40 +139,41 @@ class CtaViewModel @Inject constructor( } suspend fun onCtaShown(cta: Cta) { - cta.shownPixel?.let { - val canSendPixel = when (cta) { - is DaxCta -> cta.canSendShownPixel() - else -> true + withContext(dispatchers.io()) { + cta.shownPixel?.let { + val canSendPixel = when (cta) { + is DaxCta -> cta.canSendShownPixel() + else -> true + } + if (canSendPixel) { + pixel.fire(it, cta.pixelShownParameters()) + } } - if (canSendPixel) { - pixel.fire(it, cta.pixelShownParameters()) + if (cta is OnboardingDaxDialogCta && cta.markAsReadOnShow) { + dismissedCtaDao.insert(DismissedCta(cta.ctaId)) } - } - if (cta is OnboardingDaxDialogCta && cta.markAsReadOnShow) { - dismissedCtaDao.insert(DismissedCta(cta.ctaId)) - } - if (cta is BrokenSitePromptDialogCta) { - brokenSitePrompt.ctaShown() - } - withContext(dispatchers.io()) { + if (cta is BrokenSitePromptDialogCta) { + brokenSitePrompt.ctaShown() + } + if (cta is DaxBubbleCta.DaxPrivacyProCta || cta is DaxBubbleCta.DaxExperimentPrivacyProCta) { extendedOnboardingPixelsPlugin.testPrivacyProOnboardingShownMetricPixel()?.getPixelDefinitions()?.forEach { pixel.fire(it.pixelName, it.params) } } - } - // Temporary pixel - val isVisitSiteSuggestionsCta = - cta is DaxBubbleCta.DaxIntroVisitSiteOptionsCta || cta is DaxBubbleCta.DaxExperimentIntroVisitSiteOptionsCta || - cta is OnboardingDaxDialogCta.DaxSiteSuggestionsCta || cta is OnboardingDaxDialogCta.DaxExperimentSiteSuggestionsCta - if (isVisitSiteSuggestionsCta) { - if (userBrowserProperties.daysSinceInstalled() <= MIN_DAYS_TO_COUNT_ONBOARDING_CTA_SHOWN) { - val count = onboardingStore.visitSiteCtaDisplayCount ?: 0 - pixel.fire(AppPixelName.ONBOARDING_VISIT_SITE_CTA_SHOWN, mapOf("count" to count.toString())) - onboardingStore.visitSiteCtaDisplayCount = count + 1 - } else { - onboardingStore.clearVisitSiteCtaDisplayCount() + // Temporary pixel + val isVisitSiteSuggestionsCta = + cta is DaxBubbleCta.DaxIntroVisitSiteOptionsCta || cta is DaxBubbleCta.DaxExperimentIntroVisitSiteOptionsCta || + cta is OnboardingDaxDialogCta.DaxSiteSuggestionsCta || cta is OnboardingDaxDialogCta.DaxExperimentSiteSuggestionsCta + if (isVisitSiteSuggestionsCta) { + if (userBrowserProperties.daysSinceInstalled() <= MIN_DAYS_TO_COUNT_ONBOARDING_CTA_SHOWN) { + val count = onboardingStore.visitSiteCtaDisplayCount ?: 0 + pixel.fire(AppPixelName.ONBOARDING_VISIT_SITE_CTA_SHOWN, mapOf("count" to count.toString())) + onboardingStore.visitSiteCtaDisplayCount = count + 1 + } else { + onboardingStore.clearVisitSiteCtaDisplayCount() + } } } } @@ -250,8 +251,8 @@ class CtaViewModel @Inject constructor( } suspend fun getFireDialogCta(): OnboardingDaxDialogCta? { - if (!daxOnboardingActive() || daxDialogFireEducationShown()) return null return withContext(dispatchers.io()) { + if (!daxOnboardingActive() || daxDialogFireEducationShown()) return@withContext null if (highlightsOnboardingExperimentManager.isHighlightsEnabled()) { return@withContext OnboardingDaxDialogCta.DaxExperimentFireButtonCta(onboardingStore, appInstallStore) } else { @@ -261,8 +262,8 @@ class CtaViewModel @Inject constructor( } suspend fun getSiteSuggestionsDialogCta(): OnboardingDaxDialogCta? { - if (!daxOnboardingActive() || !canShowDaxIntroVisitSiteCta()) return null return withContext(dispatchers.io()) { + if (!daxOnboardingActive() || !canShowDaxIntroVisitSiteCta()) return@withContext null if (highlightsOnboardingExperimentManager.isHighlightsEnabled()) { return@withContext OnboardingDaxDialogCta.DaxExperimentSiteSuggestionsCta(onboardingStore, appInstallStore) } else { @@ -272,8 +273,8 @@ class CtaViewModel @Inject constructor( } suspend fun getEndStaticDialogCta(): OnboardingDaxDialogCta.DaxExperimentEndStaticCta? { - if (!daxOnboardingActive() && daxDialogEndShown()) return null return withContext(dispatchers.io()) { + if (!daxOnboardingActive() && daxDialogEndShown()) return@withContext null return@withContext OnboardingDaxDialogCta.DaxExperimentEndStaticCta(onboardingStore, appInstallStore) } } @@ -473,7 +474,7 @@ class CtaViewModel @Inject constructor( } } - private suspend fun isSiteNotAllowedForOnboarding(site: Site): Boolean { + private fun isSiteNotAllowedForOnboarding(site: Site): Boolean { val uri = site.url.toUri() if (subscriptions.isPrivacyProUrl(uri)) return true @@ -502,9 +503,11 @@ class CtaViewModel @Inject constructor( // We only want to show New Tab when the Home CTAs from Onboarding has finished // https://app.asana.com/0/1157893581871903/1207769731595075/f suspend fun areBubbleDaxDialogsCompleted(): Boolean { - val noBrowserCtaExperiment = extendedOnboardingFeatureToggles.noBrowserCtas().isEnabled() - val bubbleCtasShown = daxDialogEndShown() && (daxDialogNetworkShown() || daxDialogOtherShown() || daxDialogTrackersFoundShown()) - return noBrowserCtaExperiment || bubbleCtasShown || hideTips() || !userStageStore.daxOnboardingActive() + return withContext(dispatchers.io()) { + val noBrowserCtaExperiment = extendedOnboardingFeatureToggles.noBrowserCtas().isEnabled() + val bubbleCtasShown = daxDialogEndShown() && (daxDialogNetworkShown() || daxDialogOtherShown() || daxDialogTrackersFoundShown()) + noBrowserCtaExperiment || bubbleCtasShown || hideTips() || !userStageStore.daxOnboardingActive() + } } private fun daxDialogSerpShown(): Boolean = dismissedCtaDao.exists(CtaId.DAX_DIALOG_SERP) diff --git a/app/src/main/res/drawable/background_default_browser_menu_item.xml b/app/src/main/res/drawable/background_default_browser_menu_item.xml new file mode 100644 index 000000000000..2b7583e3949c --- /dev/null +++ b/app/src/main/res/drawable/background_default_browser_menu_item.xml @@ -0,0 +1,20 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/popup_window_browser_menu.xml b/app/src/main/res/layout/popup_window_browser_menu.xml index 255f393c7760..98a6a4907ce5 100644 --- a/app/src/main/res/layout/popup_window_browser_menu.xml +++ b/app/src/main/res/layout/popup_window_browser_menu.xml @@ -97,6 +97,10 @@ android:layout_width="match_parent" android:layout_height="wrap_content" /> + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/test/java/com/duckduckgo/app/browser/BrowserViewModelTest.kt b/app/src/test/java/com/duckduckgo/app/browser/BrowserViewModelTest.kt index 5430f65e7a59..77c3eb510824 100644 --- a/app/src/test/java/com/duckduckgo/app/browser/BrowserViewModelTest.kt +++ b/app/src/test/java/com/duckduckgo/app/browser/BrowserViewModelTest.kt @@ -39,6 +39,7 @@ import com.duckduckgo.app.tabs.model.TabRepository import com.duckduckgo.common.test.CoroutineTestRule import com.duckduckgo.feature.toggles.api.FakeFeatureToggleFactory import com.duckduckgo.feature.toggles.api.Toggle.State +import com.duckduckgo.tabs.model.TabDataRepositoryTest.Companion.TAB_ID import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.After diff --git a/app/src/test/java/com/duckduckgo/app/cta/ui/OnboardingDaxDialogTests.kt b/app/src/test/java/com/duckduckgo/app/cta/ui/OnboardingDaxDialogTests.kt index 2bdf27b047be..020ded0aeaa5 100644 --- a/app/src/test/java/com/duckduckgo/app/cta/ui/OnboardingDaxDialogTests.kt +++ b/app/src/test/java/com/duckduckgo/app/cta/ui/OnboardingDaxDialogTests.kt @@ -38,7 +38,6 @@ import com.duckduckgo.app.widget.ui.WidgetCapabilities import com.duckduckgo.brokensite.api.BrokenSitePrompt import com.duckduckgo.browser.api.UserBrowserProperties import com.duckduckgo.common.test.CoroutineTestRule -import com.duckduckgo.common.utils.DispatcherProvider import com.duckduckgo.duckplayer.api.DuckPlayer import com.duckduckgo.feature.toggles.api.Toggle import kotlinx.coroutines.test.runTest @@ -72,7 +71,6 @@ class OnboardingDaxDialogTests { private val onboardingStore: OnboardingStore = mock() private val userStageStore: UserStageStore = mock() private val tabRepository: TabRepository = mock() - private val dispatchers: DispatcherProvider = mock() private val duckDuckGoUrlDetector: DuckDuckGoUrlDetector = mock() private val extendedOnboardingFeatureToggles: ExtendedOnboardingFeatureToggles = mock() private val mockDuckPlayer: DuckPlayer = mock() @@ -95,7 +93,13 @@ class OnboardingDaxDialogTests { widgetCapabilities, dismissedCtaDao, userAllowListRepository, - settingsDataStore, onboardingStore, userStageStore, tabRepository, dispatchers, duckDuckGoUrlDetector, extendedOnboardingFeatureToggles, + settingsDataStore, + onboardingStore, + userStageStore, + tabRepository, + coroutineRule.testDispatcherProvider, + duckDuckGoUrlDetector, + extendedOnboardingFeatureToggles, subscriptions = mock(), mockDuckPlayer, mockHighlightsOnboardingExperimentManager, diff --git a/common/common-ui/src/main/res/drawable/ic_default_browser_mobile_color_16.xml b/common/common-ui/src/main/res/drawable/ic_default_browser_mobile_color_16.xml new file mode 100644 index 000000000000..8e8bd4b949ff --- /dev/null +++ b/common/common-ui/src/main/res/drawable/ic_default_browser_mobile_color_16.xml @@ -0,0 +1,21 @@ + + + + + + + + diff --git a/network-protection/network-protection-api/src/main/java/com/duckduckgo/networkprotection/api/NetworkProtectionState.kt b/network-protection/network-protection-api/src/main/java/com/duckduckgo/networkprotection/api/NetworkProtectionState.kt index 1c67dee66dde..2119466a3fb4 100644 --- a/network-protection/network-protection-api/src/main/java/com/duckduckgo/networkprotection/api/NetworkProtectionState.kt +++ b/network-protection/network-protection-api/src/main/java/com/duckduckgo/networkprotection/api/NetworkProtectionState.kt @@ -91,5 +91,8 @@ interface NetworkProtectionState { CONNECTED, CONNECTING, DISCONNECTED, + ; + + fun isConnected(): Boolean = this == CONNECTED } } diff --git a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/NetpSubscriptionManager.kt b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/NetpSubscriptionManager.kt index 643b764de7d5..7d45824807f6 100644 --- a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/NetpSubscriptionManager.kt +++ b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/NetpSubscriptionManager.kt @@ -19,6 +19,7 @@ package com.duckduckgo.networkprotection.impl.subscription import com.duckduckgo.common.utils.DispatcherProvider import com.duckduckgo.di.scopes.AppScope import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus +import com.duckduckgo.settings.api.NewSettingsFeature import com.duckduckgo.subscriptions.api.Product.NetP import com.duckduckgo.subscriptions.api.SubscriptionStatus import com.duckduckgo.subscriptions.api.Subscriptions @@ -37,6 +38,8 @@ interface NetpSubscriptionManager { EXPIRED, SIGNED_OUT, INACTIVE, + WAITING, + INELIGIBLE, } } @@ -52,6 +55,7 @@ fun VpnStatus.isExpired(): Boolean { class RealNetpSubscriptionManager @Inject constructor( private val subscriptions: Subscriptions, private val dispatcherProvider: DispatcherProvider, + private val newSettingsFeature: NewSettingsFeature, ) : NetpSubscriptionManager { override suspend fun getVpnStatus(): VpnStatus { @@ -71,15 +75,29 @@ class RealNetpSubscriptionManager @Inject constructor( private fun hasValidEntitlementFlow(): Flow = subscriptions.getEntitlementStatus().map { it.contains(NetP) } private suspend fun getVpnStatusInternal(hasValidEntitlement: Boolean): VpnStatus { - val subscriptionState = subscriptions.getSubscriptionStatus() - return when (subscriptionState) { - SubscriptionStatus.INACTIVE, SubscriptionStatus.EXPIRED -> VpnStatus.EXPIRED - SubscriptionStatus.UNKNOWN -> VpnStatus.SIGNED_OUT - else -> { - if (hasValidEntitlement) { - VpnStatus.ACTIVE - } else { - VpnStatus.INACTIVE + return if (newSettingsFeature.self().isEnabled()) { + when { + !hasValidEntitlement -> VpnStatus.INELIGIBLE + else -> { + when (subscriptions.getSubscriptionStatus()) { + SubscriptionStatus.INACTIVE, SubscriptionStatus.EXPIRED -> VpnStatus.EXPIRED + SubscriptionStatus.UNKNOWN -> VpnStatus.SIGNED_OUT + SubscriptionStatus.AUTO_RENEWABLE, SubscriptionStatus.NOT_AUTO_RENEWABLE, SubscriptionStatus.GRACE_PERIOD -> VpnStatus.ACTIVE + SubscriptionStatus.WAITING -> VpnStatus.WAITING + } + } + } + } else { + val subscriptionState = subscriptions.getSubscriptionStatus() + when (subscriptionState) { + SubscriptionStatus.INACTIVE, SubscriptionStatus.EXPIRED -> VpnStatus.EXPIRED + SubscriptionStatus.UNKNOWN -> VpnStatus.SIGNED_OUT + else -> { + if (hasValidEntitlement) { + VpnStatus.ACTIVE + } else { + VpnStatus.INACTIVE + } } } } diff --git a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPView.kt b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPView.kt new file mode 100644 index 000000000000..99b2edc9d248 --- /dev/null +++ b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPView.kt @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * Licensed 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 com.duckduckgo.networkprotection.impl.subscription.settings + +import android.annotation.SuppressLint +import android.content.Context +import android.util.AttributeSet +import android.widget.FrameLayout +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.findViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeViewModelStoreOwner +import com.duckduckgo.anvil.annotations.InjectWith +import com.duckduckgo.common.ui.view.gone +import com.duckduckgo.common.ui.view.show +import com.duckduckgo.common.ui.viewbinding.viewBinding +import com.duckduckgo.di.scopes.ViewScope +import com.duckduckgo.mobile.android.R as CommonR +import com.duckduckgo.navigation.api.GlobalActivityStarter +import com.duckduckgo.networkprotection.impl.databinding.LegacyViewSettingsNetpBinding +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.Command +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.Command.OpenNetPScreen +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.Factory +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.Hidden +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.Pending +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.ShowState +import dagger.android.support.AndroidSupportInjection +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach + +@InjectWith(ViewScope::class) +class LegacyProSettingNetPView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyle: Int = 0, +) : FrameLayout(context, attrs, defStyle) { + + @Inject + lateinit var viewModelFactory: Factory + + @Inject + lateinit var globalActivityStarter: GlobalActivityStarter + + private var coroutineScope: CoroutineScope? = null + + private val binding: LegacyViewSettingsNetpBinding by viewBinding() + + private val viewModel: LegacyProSettingNetPViewModel by lazy { + ViewModelProvider(findViewTreeViewModelStoreOwner()!!, viewModelFactory)[LegacyProSettingNetPViewModel::class.java] + } + + override fun onAttachedToWindow() { + AndroidSupportInjection.inject(this) + super.onAttachedToWindow() + + findViewTreeLifecycleOwner()?.lifecycle?.addObserver(viewModel) + + binding.netpPSetting.setClickListener { + viewModel.onNetPSettingClicked() + } + + @SuppressLint("NoHardcodedCoroutineDispatcher") + coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) + + viewModel.viewState + .onEach { updateNetPSettings(it.networkProtectionEntryState) } + .launchIn(coroutineScope!!) + + viewModel.commands() + .onEach { processCommands(it) } + .launchIn(coroutineScope!!) + } + + private fun updateNetPSettings(networkProtectionEntryState: NetPEntryState) { + with(binding.netpPSetting) { + when (networkProtectionEntryState) { + Hidden -> this.gone() + Pending -> { + this.show() + this.setLeadingIconResource(CommonR.drawable.ic_check_grey_round_16) + } + is ShowState -> { + this.show() + this.setLeadingIconResource(networkProtectionEntryState.icon) + } + } + } + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + findViewTreeLifecycleOwner()?.lifecycle?.removeObserver(viewModel) + coroutineScope?.cancel() + coroutineScope = null + } + + private fun processCommands(command: Command) { + when (command) { + is OpenNetPScreen -> { + globalActivityStarter.start(context, command.params) + } + } + } +} diff --git a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPViewModel.kt b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPViewModel.kt new file mode 100644 index 000000000000..686f54ddc531 --- /dev/null +++ b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPViewModel.kt @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * Licensed 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 com.duckduckgo.networkprotection.impl.subscription.settings + +import android.annotation.SuppressLint +import androidx.annotation.DrawableRes +import androidx.annotation.StringRes +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.ViewModel +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.viewModelScope +import com.duckduckgo.app.statistics.pixels.Pixel +import com.duckduckgo.common.utils.DispatcherProvider +import com.duckduckgo.mobile.android.R as CommonR +import com.duckduckgo.navigation.api.GlobalActivityStarter.ActivityParams +import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState +import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState.NetPAccessState +import com.duckduckgo.networkprotection.api.NetworkProtectionState +import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState +import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.CONNECTED +import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.CONNECTING +import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.DISCONNECTED +import com.duckduckgo.networkprotection.impl.R +import com.duckduckgo.networkprotection.impl.pixels.NetworkProtectionPixelNames.NETP_SETTINGS_PRESSED +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.Command.OpenNetPScreen +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.Hidden +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.Pending +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.ShowState +import javax.inject.Inject +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.launch +import logcat.logcat + +@SuppressLint("NoLifecycleObserver") // we don't observe app lifecycle +class LegacyProSettingNetPViewModel( + private val networkProtectionAccessState: NetworkProtectionAccessState, + private val networkProtectionState: NetworkProtectionState, + private val dispatcherProvider: DispatcherProvider, + private val pixel: Pixel, +) : ViewModel(), DefaultLifecycleObserver { + + data class ViewState(val networkProtectionEntryState: NetPEntryState = Hidden) + + sealed class Command { + data class OpenNetPScreen(val params: ActivityParams) : Command() + } + + sealed class NetPEntryState { + data object Hidden : NetPEntryState() + data object Pending : NetPEntryState() + data class ShowState( + @DrawableRes val icon: Int, + @StringRes val subtitle: Int, + ) : NetPEntryState() + } + + private val command = Channel(1, BufferOverflow.DROP_OLDEST) + internal fun commands(): Flow = command.receiveAsFlow() + private val _viewState = MutableStateFlow(ViewState()) + val viewState = _viewState.asStateFlow() + + override fun onStart(owner: LifecycleOwner) { + super.onStart(owner) + + viewModelScope.launch { + combine(networkProtectionAccessState.getStateFlow(), networkProtectionState.getConnectionStateFlow()) { accessState, connectionState -> + _viewState.emit( + viewState.value.copy( + networkProtectionEntryState = getNetworkProtectionEntryState(accessState, connectionState), + ), + ) + }.flowOn(dispatcherProvider.main()).launchIn(viewModelScope) + } + } + + fun onNetPSettingClicked() { + viewModelScope.launch { + val screen = networkProtectionAccessState.getScreenForCurrentState() + screen?.let { + command.send(OpenNetPScreen(screen)) + pixel.fire(NETP_SETTINGS_PRESSED) + } ?: logcat { "Get screen for current NetP state is null" } + } + } + + private suspend fun getNetworkProtectionEntryState( + accessState: NetPAccessState, + networkProtectionConnectionState: ConnectionState, + ): NetPEntryState { + return when (accessState) { + is NetPAccessState.UnLocked -> { + if (networkProtectionState.isOnboarded()) { + val subtitle = when (networkProtectionConnectionState) { + CONNECTED -> R.string.netpSubscriptionSettingsConnected + CONNECTING -> R.string.netpSubscriptionSettingsConnecting + else -> R.string.netpSubscriptionSettingsDisconnected + } + + val netPItemIcon = if (networkProtectionConnectionState != DISCONNECTED) { + CommonR.drawable.ic_check_green_round_16 + } else { + CommonR.drawable.ic_exclamation_yellow_16 + } + + ShowState( + icon = netPItemIcon, + subtitle = subtitle, + ) + } else { + Pending + } + } + + NetPAccessState.Locked -> Hidden + } + } + + @Suppress("UNCHECKED_CAST") + class Factory @Inject constructor( + private val networkProtectionAccessState: NetworkProtectionAccessState, + private val networkProtectionState: NetworkProtectionState, + private val dispatcherProvider: DispatcherProvider, + private val pixel: Pixel, + ) : ViewModelProvider.NewInstanceFactory() { + override fun create(modelClass: Class): T { + return with(modelClass) { + when { + isAssignableFrom(LegacyProSettingNetPViewModel::class.java) -> LegacyProSettingNetPViewModel( + networkProtectionAccessState, + networkProtectionState, + dispatcherProvider, + pixel, + ) + + else -> throw IllegalArgumentException("Unknown ViewModel class: ${modelClass.name}") + } + } as T + } + } +} diff --git a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsState.kt b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsState.kt new file mode 100644 index 000000000000..9d4df6906dec --- /dev/null +++ b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsState.kt @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * Licensed 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 com.duckduckgo.networkprotection.impl.subscription.settings + +import kotlinx.coroutines.flow.Flow + +interface NetworkProtectionSettingsState { + + /** + * Returns a flow of the visibility states of NetP + * The caller DOES NOT need to specify the dispatcher when calling this method + */ + suspend fun getNetPSettingsStateFlow(): Flow + + /** + * If the Netp Settings Item should be visible to the user and it's current subscription state + */ + sealed interface NetPSettingsState { + + sealed interface Visible : NetPSettingsState { + data object Subscribed : Visible + data object Expired : Visible + data object Activating : Visible + } + data object Hidden : NetPSettingsState + } +} diff --git a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsStateImpl.kt b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsStateImpl.kt new file mode 100644 index 000000000000..a129e1208617 --- /dev/null +++ b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsStateImpl.kt @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * Licensed 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 com.duckduckgo.networkprotection.impl.subscription.settings + +import com.duckduckgo.common.utils.DispatcherProvider +import com.duckduckgo.di.scopes.AppScope +import com.duckduckgo.networkprotection.api.NetworkProtectionState +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus.ACTIVE +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus.EXPIRED +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus.INACTIVE +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus.INELIGIBLE +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus.SIGNED_OUT +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus.WAITING +import com.duckduckgo.networkprotection.impl.subscription.isActive +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState.Hidden +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState.Visible.Activating +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState.Visible.Expired +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState.Visible.Subscribed +import com.squareup.anvil.annotations.ContributesBinding +import javax.inject.Inject +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOn +import kotlinx.coroutines.flow.map + +@ContributesBinding(AppScope::class) +class NetworkProtectionSettingsStateImpl @Inject constructor( + private val dispatcherProvider: DispatcherProvider, + private val networkProtectionState: NetworkProtectionState, + private val netpSubscriptionManager: NetpSubscriptionManager, +) : NetworkProtectionSettingsState { + + override suspend fun getNetPSettingsStateFlow(): Flow = + netpSubscriptionManager.vpnStatus().map { status -> + if (!status.isActive()) { + // if entitlement check succeeded and not an active subscription then reset state + handleRevokedVPNState() + } + + mapToSettingsState(status) + }.flowOn(dispatcherProvider.io()) + + private fun mapToSettingsState(vpnStatus: VpnStatus): NetPSettingsState = when (vpnStatus) { + ACTIVE -> Subscribed + INACTIVE, EXPIRED -> Expired + WAITING -> Activating + SIGNED_OUT, INELIGIBLE -> Hidden + } + + private suspend fun handleRevokedVPNState() { + if (networkProtectionState.isEnabled()) { + networkProtectionState.stop() + } + } +} diff --git a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPView.kt b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPView.kt index c82423994b22..dcfc63c9974c 100644 --- a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPView.kt +++ b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPView.kt @@ -20,24 +20,25 @@ import android.annotation.SuppressLint import android.content.Context import android.util.AttributeSet import android.widget.FrameLayout +import androidx.core.view.isGone +import androidx.core.view.isVisible import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.lifecycle.findViewTreeViewModelStoreOwner import com.duckduckgo.anvil.annotations.InjectWith -import com.duckduckgo.common.ui.view.gone -import com.duckduckgo.common.ui.view.show import com.duckduckgo.common.ui.viewbinding.viewBinding import com.duckduckgo.di.scopes.ViewScope -import com.duckduckgo.mobile.android.R as CommonR import com.duckduckgo.navigation.api.GlobalActivityStarter +import com.duckduckgo.networkprotection.impl.R import com.duckduckgo.networkprotection.impl.databinding.ViewSettingsNetpBinding import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.Command import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.Command.OpenNetPScreen import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.Factory import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState +import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Activating +import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Expired import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Hidden -import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Pending -import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.ShowState +import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Subscribed import dagger.android.support.AndroidSupportInjection import javax.inject.Inject import kotlinx.coroutines.CoroutineScope @@ -74,10 +75,6 @@ class ProSettingNetPView @JvmOverloads constructor( findViewTreeLifecycleOwner()?.lifecycle?.addObserver(viewModel) - binding.netpPSetting.setClickListener { - viewModel.onNetPSettingClicked() - } - @SuppressLint("NoHardcodedCoroutineDispatcher") coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) @@ -93,14 +90,21 @@ class ProSettingNetPView @JvmOverloads constructor( private fun updateNetPSettings(networkProtectionEntryState: NetPEntryState) { with(binding.netpPSetting) { when (networkProtectionEntryState) { - Hidden -> this.gone() - Pending -> { - this.show() - this.setLeadingIconResource(CommonR.drawable.ic_check_grey_round_16) + Hidden -> isGone = true + Activating, + Expired, + -> { + isVisible = true + isClickable = false + setLeadingIconResource(R.drawable.ic_vpn_grayscale_color_24) + setStatus(isOn = false) } - is ShowState -> { - this.show() - this.setLeadingIconResource(networkProtectionEntryState.icon) + is Subscribed -> { + isVisible = true + isClickable = true + setClickListener { viewModel.onNetPSettingClicked() } + setLeadingIconResource(R.drawable.ic_vpn_color_24) + setStatus(isOn = networkProtectionEntryState.isActive) } } } diff --git a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPViewModel.kt b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPViewModel.kt index 866d8ca0887f..303b10d7af77 100644 --- a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPViewModel.kt +++ b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPViewModel.kt @@ -17,8 +17,6 @@ package com.duckduckgo.networkprotection.impl.subscription.settings import android.annotation.SuppressLint -import androidx.annotation.DrawableRes -import androidx.annotation.StringRes import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.LifecycleOwner import androidx.lifecycle.ViewModel @@ -26,21 +24,17 @@ import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.viewModelScope import com.duckduckgo.app.statistics.pixels.Pixel import com.duckduckgo.common.utils.DispatcherProvider -import com.duckduckgo.mobile.android.R as CommonR import com.duckduckgo.navigation.api.GlobalActivityStarter.ActivityParams import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState -import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState.NetPAccessState import com.duckduckgo.networkprotection.api.NetworkProtectionState import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState -import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.CONNECTED -import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.CONNECTING -import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.DISCONNECTED -import com.duckduckgo.networkprotection.impl.R import com.duckduckgo.networkprotection.impl.pixels.NetworkProtectionPixelNames.NETP_SETTINGS_PRESSED +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState.Hidden +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState.Visible.Activating +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState.Visible.Expired +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState.Visible.Subscribed import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.Command.OpenNetPScreen -import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Hidden -import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Pending -import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.ShowState import javax.inject.Inject import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.Channel @@ -56,13 +50,14 @@ import logcat.logcat @SuppressLint("NoLifecycleObserver") // we don't observe app lifecycle class ProSettingNetPViewModel( - private val networkProtectionAccessState: NetworkProtectionAccessState, + private val networkProtectionSettingsState: NetworkProtectionSettingsState, private val networkProtectionState: NetworkProtectionState, + private val networkProtectionAccessState: NetworkProtectionAccessState, private val dispatcherProvider: DispatcherProvider, private val pixel: Pixel, ) : ViewModel(), DefaultLifecycleObserver { - data class ViewState(val networkProtectionEntryState: NetPEntryState = Hidden) + data class ViewState(val networkProtectionEntryState: NetPEntryState = NetPEntryState.Hidden) sealed class Command { data class OpenNetPScreen(val params: ActivityParams) : Command() @@ -70,11 +65,9 @@ class ProSettingNetPViewModel( sealed class NetPEntryState { data object Hidden : NetPEntryState() - data object Pending : NetPEntryState() - data class ShowState( - @DrawableRes val icon: Int, - @StringRes val subtitle: Int, - ) : NetPEntryState() + data class Subscribed(val isActive: Boolean) : NetPEntryState() + data object Expired : NetPEntryState() + data object Activating : NetPEntryState() } private val command = Channel(1, BufferOverflow.DROP_OLDEST) @@ -86,7 +79,10 @@ class ProSettingNetPViewModel( super.onStart(owner) viewModelScope.launch { - combine(networkProtectionAccessState.getStateFlow(), networkProtectionState.getConnectionStateFlow()) { accessState, connectionState -> + combine( + networkProtectionSettingsState.getNetPSettingsStateFlow(), + networkProtectionState.getConnectionStateFlow(), + ) { accessState, connectionState -> _viewState.emit( viewState.value.copy( networkProtectionEntryState = getNetworkProtectionEntryState(accessState, connectionState), @@ -106,42 +102,22 @@ class ProSettingNetPViewModel( } } - private suspend fun getNetworkProtectionEntryState( - accessState: NetPAccessState, + private fun getNetworkProtectionEntryState( + settingsState: NetPSettingsState, networkProtectionConnectionState: ConnectionState, - ): NetPEntryState { - return when (accessState) { - is NetPAccessState.UnLocked -> { - if (networkProtectionState.isOnboarded()) { - val subtitle = when (networkProtectionConnectionState) { - CONNECTED -> R.string.netpSubscriptionSettingsConnected - CONNECTING -> R.string.netpSubscriptionSettingsConnecting - else -> R.string.netpSubscriptionSettingsDisconnected - } - - val netPItemIcon = if (networkProtectionConnectionState != DISCONNECTED) { - CommonR.drawable.ic_check_green_round_16 - } else { - CommonR.drawable.ic_exclamation_yellow_16 - } - - ShowState( - icon = netPItemIcon, - subtitle = subtitle, - ) - } else { - Pending - } - } - - NetPAccessState.Locked -> Hidden + ): NetPEntryState = + when (settingsState) { + Hidden -> NetPEntryState.Hidden + Subscribed -> NetPEntryState.Subscribed(isActive = networkProtectionConnectionState.isConnected()) + Activating -> NetPEntryState.Activating + Expired -> NetPEntryState.Expired } - } @Suppress("UNCHECKED_CAST") class Factory @Inject constructor( - private val networkProtectionAccessState: NetworkProtectionAccessState, + private val networkProtectionSettingsState: NetworkProtectionSettingsState, private val networkProtectionState: NetworkProtectionState, + private val networkProtectionAccessState: NetworkProtectionAccessState, private val dispatcherProvider: DispatcherProvider, private val pixel: Pixel, ) : ViewModelProvider.NewInstanceFactory() { @@ -149,8 +125,9 @@ class ProSettingNetPViewModel( return with(modelClass) { when { isAssignableFrom(ProSettingNetPViewModel::class.java) -> ProSettingNetPViewModel( - networkProtectionAccessState, + networkProtectionSettingsState, networkProtectionState, + networkProtectionAccessState, dispatcherProvider, pixel, ) diff --git a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/SubsSettingsPlugin.kt b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/SubsSettingsPlugin.kt index 108c75960b3d..d721a5dea065 100644 --- a/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/SubsSettingsPlugin.kt +++ b/network-protection/network-protection-impl/src/main/java/com/duckduckgo/networkprotection/impl/subscription/settings/SubsSettingsPlugin.kt @@ -20,14 +20,19 @@ import android.content.Context import android.view.View import com.duckduckgo.anvil.annotations.PriorityKey import com.duckduckgo.di.scopes.ActivityScope +import com.duckduckgo.settings.api.NewSettingsFeature import com.duckduckgo.settings.api.ProSettingsPlugin import com.squareup.anvil.annotations.ContributesMultibinding import javax.inject.Inject @ContributesMultibinding(ActivityScope::class) @PriorityKey(200) -class ProSettingsNetP @Inject constructor() : ProSettingsPlugin { +class ProSettingsNetP @Inject constructor(private val newSettingsFeature: NewSettingsFeature) : ProSettingsPlugin { override fun getView(context: Context): View { - return ProSettingNetPView(context) + return if (newSettingsFeature.self().isEnabled()) { + ProSettingNetPView(context) + } else { + return LegacyProSettingNetPView(context) + } } } diff --git a/network-protection/network-protection-impl/src/main/res/layout/legacy_view_settings_netp.xml b/network-protection/network-protection-impl/src/main/res/layout/legacy_view_settings_netp.xml new file mode 100644 index 000000000000..6fbef946751f --- /dev/null +++ b/network-protection/network-protection-impl/src/main/res/layout/legacy_view_settings_netp.xml @@ -0,0 +1,25 @@ + + + \ No newline at end of file diff --git a/network-protection/network-protection-impl/src/main/res/layout/view_settings_netp.xml b/network-protection/network-protection-impl/src/main/res/layout/view_settings_netp.xml index 6fbef946751f..509de9f75387 100644 --- a/network-protection/network-protection-impl/src/main/res/layout/view_settings_netp.xml +++ b/network-protection/network-protection-impl/src/main/res/layout/view_settings_netp.xml @@ -14,12 +14,11 @@ ~ limitations under the License. --> - \ No newline at end of file + \ No newline at end of file diff --git a/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPViewModelTest.kt b/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPViewModelTest.kt new file mode 100644 index 000000000000..25866ec4dd9a --- /dev/null +++ b/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/LegacyProSettingNetPViewModelTest.kt @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * Licensed 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 com.duckduckgo.networkprotection.impl.subscription.settings + +import app.cash.turbine.test +import com.duckduckgo.app.statistics.pixels.Pixel +import com.duckduckgo.common.test.CoroutineTestRule +import com.duckduckgo.mobile.android.R as CommonR +import com.duckduckgo.navigation.api.GlobalActivityStarter.ActivityParams +import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState +import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState.NetPAccessState.Locked +import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState.NetPAccessState.UnLocked +import com.duckduckgo.networkprotection.api.NetworkProtectionState +import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.CONNECTED +import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.CONNECTING +import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.DISCONNECTED +import com.duckduckgo.networkprotection.impl.R +import com.duckduckgo.networkprotection.impl.pixels.NetworkProtectionPixelNames.NETP_SETTINGS_PRESSED +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.Command +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.Hidden +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.Pending +import com.duckduckgo.networkprotection.impl.subscription.settings.LegacyProSettingNetPViewModel.NetPEntryState.ShowState +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.junit.Assert.* +import org.junit.Before +import org.junit.Rule +import org.junit.Test +import org.mockito.kotlin.mock +import org.mockito.kotlin.verify +import org.mockito.kotlin.whenever + +class LegacyProSettingNetPViewModelTest { + + @get:Rule + val coroutineTestRule: CoroutineTestRule = CoroutineTestRule() + + private val pixel: Pixel = mock() + private val networkProtectionState: NetworkProtectionState = mock() + private val networkProtectionAccessState: NetworkProtectionAccessState = mock() + private lateinit var proSettingNetPViewModel: LegacyProSettingNetPViewModel + + @Before + fun before() { + proSettingNetPViewModel = LegacyProSettingNetPViewModel( + networkProtectionAccessState, + networkProtectionState, + coroutineTestRule.testDispatcherProvider, + pixel, + ) + } + + @Test + fun whenNetPSettingClickedThenReturnScreenForCurrentState() = runTest { + val testScreen = object : ActivityParams {} + whenever(networkProtectionAccessState.getScreenForCurrentState()).thenReturn(testScreen) + + proSettingNetPViewModel.commands().test { + proSettingNetPViewModel.onNetPSettingClicked() + + assertEquals(Command.OpenNetPScreen(testScreen), awaitItem()) + verify(pixel).fire(NETP_SETTINGS_PRESSED) + + cancelAndConsumeRemainingEvents() + } + } + + @Test + fun whenNetPIsNotUnlockedThenNetPEntryStateShouldShowHidden() = runTest { + whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(DISCONNECTED)) + whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(Locked)) + + proSettingNetPViewModel.onStart(mock()) + + proSettingNetPViewModel.viewState.test { + assertEquals( + Hidden, + expectMostRecentItem().networkProtectionEntryState, + ) + } + } + + @Test + fun whenNetPStateIsInBetaButNotAcceptedTermsThenNetPEntryStateShouldShowPending() = runTest { + whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(DISCONNECTED)) + whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) + whenever(networkProtectionState.isOnboarded()).thenReturn(false) + + proSettingNetPViewModel.onStart(mock()) + + proSettingNetPViewModel.viewState.test { + assertEquals( + Pending, + expectMostRecentItem().networkProtectionEntryState, + ) + } + } + + @Test + fun whenNetPStateIsInBetaAndOnboardedAndEnabledThenNetPEntryStateShouldCorrectShowState() = runTest { + whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(CONNECTED)) + whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) + whenever(networkProtectionState.isOnboarded()).thenReturn(true) + + proSettingNetPViewModel.onStart(mock()) + + proSettingNetPViewModel.viewState.test { + assertEquals( + ShowState( + icon = CommonR.drawable.ic_check_green_round_16, + subtitle = R.string.netpSubscriptionSettingsConnected, + ), + expectMostRecentItem().networkProtectionEntryState, + ) + } + } + + @Test + fun whenNetPStateIsInBetaAndNotOnboardedAndEnabledThenNetPEntryStateShouldCorrectShowState() = runTest { + whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(CONNECTED)) + whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) + whenever(networkProtectionState.isOnboarded()).thenReturn(false) + + proSettingNetPViewModel.onStart(mock()) + + proSettingNetPViewModel.viewState.test { + assertEquals( + Pending, + expectMostRecentItem().networkProtectionEntryState, + ) + } + } + + @Test + fun whenNetPStateIsInBetaOnboardedAndEnabledThenNetPEntryStateShouldCorrectShowState() = runTest { + whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(CONNECTED)) + whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) + whenever(networkProtectionState.isOnboarded()).thenReturn(true) + + proSettingNetPViewModel.onStart(mock()) + + proSettingNetPViewModel.viewState.test { + assertEquals( + ShowState( + icon = CommonR.drawable.ic_check_green_round_16, + subtitle = R.string.netpSubscriptionSettingsConnected, + ), + expectMostRecentItem().networkProtectionEntryState, + ) + } + } + + @Test + fun whenNetPStateIsInBetaAndConnectingThenNetPEntryStateShouldCorrectShowState() = runTest { + whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(CONNECTING)) + whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) + whenever(networkProtectionState.isOnboarded()).thenReturn(true) + + proSettingNetPViewModel.onStart(mock()) + + proSettingNetPViewModel.viewState.test { + assertEquals( + ShowState( + icon = CommonR.drawable.ic_check_green_round_16, + subtitle = R.string.netpSubscriptionSettingsConnecting, + ), + expectMostRecentItem().networkProtectionEntryState, + ) + } + } + + @Test + fun whenNetPStateIsInBetaAndDisabledThenNetPEntryStateShouldCorrectShowState() = runTest { + whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(DISCONNECTED)) + whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) + whenever(networkProtectionState.isOnboarded()).thenReturn(true) + + proSettingNetPViewModel.onStart(mock()) + + proSettingNetPViewModel.viewState.test { + assertEquals( + ShowState( + icon = CommonR.drawable.ic_exclamation_yellow_16, + subtitle = R.string.netpSubscriptionSettingsDisconnected, + ), + expectMostRecentItem().networkProtectionEntryState, + ) + } + } +} diff --git a/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsStateImplTest.kt b/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsStateImplTest.kt new file mode 100644 index 000000000000..c95f916d502d --- /dev/null +++ b/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/NetworkProtectionSettingsStateImplTest.kt @@ -0,0 +1,124 @@ +package com.duckduckgo.networkprotection.impl.subscription.settings + +import app.cash.turbine.test +import com.duckduckgo.common.test.CoroutineTestRule +import com.duckduckgo.networkprotection.api.NetworkProtectionState +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager +import com.duckduckgo.networkprotection.impl.subscription.NetpSubscriptionManager.VpnStatus +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Before +import org.junit.Rule +import org.junit.Test + +class NetworkProtectionSettingsStateImplTest { + + @get:Rule + val coroutineTestRule = CoroutineTestRule() + + private lateinit var networkProtectionSettingsState: NetworkProtectionSettingsStateImpl + private lateinit var fakeNetworkProtectionState: FakeNetworkProtectionState + private lateinit var fakeNetpSubscriptionManager: FakeNetpSubscriptionManager + + @Before + fun setUp() { + fakeNetworkProtectionState = FakeNetworkProtectionState() + fakeNetpSubscriptionManager = FakeNetpSubscriptionManager() + + networkProtectionSettingsState = NetworkProtectionSettingsStateImpl( + dispatcherProvider = coroutineTestRule.testDispatcherProvider, + networkProtectionState = fakeNetworkProtectionState, + netpSubscriptionManager = fakeNetpSubscriptionManager, + ) + } + + @Test + fun `when VpnStatus is active then returns subscribed`() = runTest { + fakeNetpSubscriptionManager.setVpnStatus(VpnStatus.ACTIVE) + + networkProtectionSettingsState.getNetPSettingsStateFlow().test { + assertEquals(NetPSettingsState.Visible.Subscribed, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when VpnStatus is inactive then returns expired`() = runTest { + fakeNetpSubscriptionManager.setVpnStatus(VpnStatus.INACTIVE) + + networkProtectionSettingsState.getNetPSettingsStateFlow().test { + assertEquals(NetPSettingsState.Visible.Expired, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when VpnStatus is expired then returns expired`() = runTest { + fakeNetpSubscriptionManager.setVpnStatus(VpnStatus.EXPIRED) + + networkProtectionSettingsState.getNetPSettingsStateFlow().test { + assertEquals(NetPSettingsState.Visible.Expired, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when VpnStatus is activating then returns waiting`() = runTest { + fakeNetpSubscriptionManager.setVpnStatus(VpnStatus.WAITING) + + networkProtectionSettingsState.getNetPSettingsStateFlow().test { + assertEquals(NetPSettingsState.Visible.Activating, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when VpnStatus is signed out then returns hidden`() = runTest { + fakeNetpSubscriptionManager.setVpnStatus(VpnStatus.SIGNED_OUT) + + networkProtectionSettingsState.getNetPSettingsStateFlow().test { + assertEquals(NetPSettingsState.Hidden, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when VpnStatus is ineligible then returns hidden`() = runTest { + fakeNetpSubscriptionManager.setVpnStatus(VpnStatus.INELIGIBLE) + + networkProtectionSettingsState.getNetPSettingsStateFlow().test { + assertEquals(NetPSettingsState.Hidden, awaitItem()) + awaitComplete() + } + } +} + +private class FakeNetworkProtectionState : NetworkProtectionState { + override suspend fun isOnboarded(): Boolean = false + override suspend fun isEnabled(): Boolean = false + override suspend fun isRunning(): Boolean = false + override fun start() {} + override fun restart() {} + override fun clearVPNConfigurationAndRestart() {} + override suspend fun stop() {} + override fun clearVPNConfigurationAndStop() {} + override fun serverLocation(): String? = null + override fun getConnectionStateFlow(): Flow = flowOf() + override suspend fun getExcludedApps(): List = emptyList() +} + +private class FakeNetpSubscriptionManager : NetpSubscriptionManager { + + private var vpnStatusFlow: Flow = flowOf() + + override suspend fun getVpnStatus(): VpnStatus = vpnStatusFlow.first() + override suspend fun vpnStatus(): Flow = vpnStatusFlow + + fun setVpnStatus(status: VpnStatus) { + vpnStatusFlow = flowOf(status) + } +} diff --git a/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPViewModelTest.kt b/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPViewModelTest.kt index f46553aad3a8..68d72548e687 100644 --- a/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPViewModelTest.kt +++ b/network-protection/network-protection-impl/src/test/java/com/duckduckgo/networkprotection/impl/subscription/settings/ProSettingNetPViewModelTest.kt @@ -19,21 +19,19 @@ package com.duckduckgo.networkprotection.impl.subscription.settings import app.cash.turbine.test import com.duckduckgo.app.statistics.pixels.Pixel import com.duckduckgo.common.test.CoroutineTestRule -import com.duckduckgo.mobile.android.R as CommonR import com.duckduckgo.navigation.api.GlobalActivityStarter.ActivityParams import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState -import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState.NetPAccessState.Locked -import com.duckduckgo.networkprotection.api.NetworkProtectionAccessState.NetPAccessState.UnLocked import com.duckduckgo.networkprotection.api.NetworkProtectionState import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.CONNECTED import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.CONNECTING import com.duckduckgo.networkprotection.api.NetworkProtectionState.ConnectionState.DISCONNECTED -import com.duckduckgo.networkprotection.impl.R import com.duckduckgo.networkprotection.impl.pixels.NetworkProtectionPixelNames.NETP_SETTINGS_PRESSED +import com.duckduckgo.networkprotection.impl.subscription.settings.NetworkProtectionSettingsState.NetPSettingsState import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.Command +import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Activating +import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Expired import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Hidden -import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Pending -import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.ShowState +import com.duckduckgo.networkprotection.impl.subscription.settings.ProSettingNetPViewModel.NetPEntryState.Subscribed import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest import org.junit.Assert.* @@ -52,20 +50,22 @@ class ProSettingNetPViewModelTest { private val pixel: Pixel = mock() private val networkProtectionState: NetworkProtectionState = mock() private val networkProtectionAccessState: NetworkProtectionAccessState = mock() + private val networkProtectionSettingsState: NetworkProtectionSettingsState = mock() private lateinit var proSettingNetPViewModel: ProSettingNetPViewModel @Before fun before() { proSettingNetPViewModel = ProSettingNetPViewModel( - networkProtectionAccessState, + networkProtectionSettingsState, networkProtectionState, + networkProtectionAccessState, coroutineTestRule.testDispatcherProvider, pixel, ) } @Test - fun whenNetPSettingClickedThenReturnScreenForCurrentState() = runTest { + fun whenNetPSettingClickedThenNetPScreenOpened() = runTest { val testScreen = object : ActivityParams {} whenever(networkProtectionAccessState.getScreenForCurrentState()).thenReturn(testScreen) @@ -80,9 +80,9 @@ class ProSettingNetPViewModelTest { } @Test - fun whenNetPIsNotUnlockedThenNetPEntryStateShouldShowHidden() = runTest { + fun whenNetPVisibilityStateIsHiddenThenNetPEntryStateIsHidden() = runTest { whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(DISCONNECTED)) - whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(Locked)) + whenever(networkProtectionSettingsState.getNetPSettingsStateFlow()).thenReturn(flowOf(NetPSettingsState.Hidden)) proSettingNetPViewModel.onStart(mock()) @@ -95,108 +95,75 @@ class ProSettingNetPViewModelTest { } @Test - fun whenNetPStateIsInBetaButNotAcceptedTermsThenNetPEntryStateShouldShowPending() = runTest { + fun whenNetPVisibilityStateIsActivatingThenNetPEntryStateIsActivating() = runTest { whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(DISCONNECTED)) - whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) - whenever(networkProtectionState.isOnboarded()).thenReturn(false) - - proSettingNetPViewModel.onStart(mock()) - - proSettingNetPViewModel.viewState.test { - assertEquals( - Pending, - expectMostRecentItem().networkProtectionEntryState, - ) - } - } - - @Test - fun whenNetPStateIsInBetaAndOnboardedAndEnabledThenNetPEntryStateShouldCorrectShowState() = runTest { - whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(CONNECTED)) - whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) - whenever(networkProtectionState.isOnboarded()).thenReturn(true) + whenever(networkProtectionSettingsState.getNetPSettingsStateFlow()).thenReturn(flowOf(NetPSettingsState.Visible.Activating)) proSettingNetPViewModel.onStart(mock()) proSettingNetPViewModel.viewState.test { assertEquals( - ShowState( - icon = CommonR.drawable.ic_check_green_round_16, - subtitle = R.string.netpSubscriptionSettingsConnected, - ), + Activating, expectMostRecentItem().networkProtectionEntryState, ) } } @Test - fun whenNetPStateIsInBetaAndNotOnboardedAndEnabledThenNetPEntryStateShouldCorrectShowState() = runTest { + fun whenNetPVisibilityStateConnectedAndAccessStateIsSubscribedThenNetPEntryStateIsSubscribedAndActive() = runTest { whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(CONNECTED)) - whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) - whenever(networkProtectionState.isOnboarded()).thenReturn(false) + whenever(networkProtectionSettingsState.getNetPSettingsStateFlow()).thenReturn(flowOf(NetPSettingsState.Visible.Subscribed)) proSettingNetPViewModel.onStart(mock()) proSettingNetPViewModel.viewState.test { assertEquals( - Pending, + Subscribed(isActive = true), expectMostRecentItem().networkProtectionEntryState, ) } } @Test - fun whenNetPStateIsInBetaOnboardedAndEnabledThenNetPEntryStateShouldCorrectShowState() = runTest { - whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(CONNECTED)) - whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) - whenever(networkProtectionState.isOnboarded()).thenReturn(true) + fun whenNetPVisibilityStateDisconnectedAndAccessStateIsSubscribedThenNetPEntryStateIsSubscribedAndInactive() = runTest { + whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(DISCONNECTED)) + whenever(networkProtectionSettingsState.getNetPSettingsStateFlow()).thenReturn(flowOf(NetPSettingsState.Visible.Subscribed)) proSettingNetPViewModel.onStart(mock()) proSettingNetPViewModel.viewState.test { assertEquals( - ShowState( - icon = CommonR.drawable.ic_check_green_round_16, - subtitle = R.string.netpSubscriptionSettingsConnected, - ), + Subscribed(isActive = false), expectMostRecentItem().networkProtectionEntryState, ) } } @Test - fun whenNetPStateIsInBetaAndConnectingThenNetPEntryStateShouldCorrectShowState() = runTest { + fun whenNetPVisibilityStateIsConnectingThenNetPEntryStateIsSubscribedAndNotActive() = runTest { whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(CONNECTING)) - whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) - whenever(networkProtectionState.isOnboarded()).thenReturn(true) + whenever(networkProtectionSettingsState.getNetPSettingsStateFlow()).thenReturn(flowOf(NetPSettingsState.Visible.Subscribed)) proSettingNetPViewModel.onStart(mock()) proSettingNetPViewModel.viewState.test { assertEquals( - ShowState( - icon = CommonR.drawable.ic_check_green_round_16, - subtitle = R.string.netpSubscriptionSettingsConnecting, - ), + Subscribed(isActive = false), expectMostRecentItem().networkProtectionEntryState, ) } } @Test - fun whenNetPStateIsInBetaAndDisabledThenNetPEntryStateShouldCorrectShowState() = runTest { + fun whenNetPVisibilityStateIsExpiredThenNetPEntryStateIsExpired() = runTest { whenever(networkProtectionState.getConnectionStateFlow()).thenReturn(flowOf(DISCONNECTED)) - whenever(networkProtectionAccessState.getStateFlow()).thenReturn(flowOf(UnLocked)) - whenever(networkProtectionState.isOnboarded()).thenReturn(true) + whenever(networkProtectionSettingsState.getNetPSettingsStateFlow()).thenReturn(flowOf(NetPSettingsState.Visible.Expired)) proSettingNetPViewModel.onStart(mock()) proSettingNetPViewModel.viewState.test { assertEquals( - ShowState( - icon = CommonR.drawable.ic_exclamation_yellow_16, - subtitle = R.string.netpSubscriptionSettingsDisconnected, - ), + Expired, expectMostRecentItem().networkProtectionEntryState, ) } diff --git a/node_modules/@duckduckgo/autofill/dist/autofill-debug.js b/node_modules/@duckduckgo/autofill/dist/autofill-debug.js index b02ab092e3a5..a3ad7f79835a 100644 --- a/node_modules/@duckduckgo/autofill/dist/autofill-debug.js +++ b/node_modules/@duckduckgo/autofill/dist/autofill-debug.js @@ -138,6 +138,11 @@ class ZodError extends Error { processError(this); return fieldErrors; } + static assert(value) { + if (!(value instanceof ZodError)) { + throw new Error(`Not a ZodError: ${value}`); + } + } toString() { return this.message; } @@ -267,6 +272,13 @@ const makeIssue = params => { ...issueData, path: fullPath }; + if (issueData.message !== undefined) { + return { + ...issueData, + path: fullPath, + message: issueData.message + }; + } let errorMessage = ""; const maps = errorMaps.filter(m => !!m).slice().reverse(); for (const map of maps) { @@ -278,17 +290,18 @@ const makeIssue = params => { return { ...issueData, path: fullPath, - message: issueData.message || errorMessage + message: errorMessage }; }; exports.makeIssue = makeIssue; exports.EMPTY_PATH = []; function addIssueToContext(ctx, issueData) { + const overrideMap = (0, errors_1.getErrorMap)(); const issue = (0, exports.makeIssue)({ issueData: issueData, data: ctx.data, path: ctx.path, - errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, (0, errors_1.getErrorMap)(), en_1.default // then global default map + errorMaps: [ctx.common.contextualErrorMap, ctx.schemaErrorMap, overrideMap, overrideMap === en_1.default ? undefined : en_1.default // then global default map ].filter(x => !!x) }); ctx.common.issues.push(issue); @@ -319,9 +332,11 @@ class ParseStatus { static async mergeObjectAsync(status, pairs) { const syncPairs = []; for (const pair of pairs) { + const key = await pair.key; + const value = await pair.value; syncPairs.push({ - key: await pair.key, - value: await pair.value + key, + value }); } return ParseStatus.mergeObjectSync(status, syncPairs); @@ -632,11 +647,23 @@ exports.default = errorMap; },{"../ZodError":2,"../helpers/util":8}],11:[function(require,module,exports){ "use strict"; +var __classPrivateFieldGet = void 0 && (void 0).__classPrivateFieldGet || function (receiver, state, kind, f) { + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); + return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); +}; +var __classPrivateFieldSet = void 0 && (void 0).__classPrivateFieldSet || function (receiver, state, value, kind, f) { + if (kind === "m") throw new TypeError("Private method is not writable"); + if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); + if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); + return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; +}; +var _ZodEnum_cache, _ZodNativeEnum_cache; Object.defineProperty(exports, "__esModule", { value: true }); -exports.date = exports.boolean = exports.bigint = exports.array = exports.any = exports.coerce = exports.ZodFirstPartyTypeKind = exports.late = exports.ZodSchema = exports.Schema = exports.custom = exports.ZodReadonly = exports.ZodPipeline = exports.ZodBranded = exports.BRAND = exports.ZodNaN = exports.ZodCatch = exports.ZodDefault = exports.ZodNullable = exports.ZodOptional = exports.ZodTransformer = exports.ZodEffects = exports.ZodPromise = exports.ZodNativeEnum = exports.ZodEnum = exports.ZodLiteral = exports.ZodLazy = exports.ZodFunction = exports.ZodSet = exports.ZodMap = exports.ZodRecord = exports.ZodTuple = exports.ZodIntersection = exports.ZodDiscriminatedUnion = exports.ZodUnion = exports.ZodObject = exports.ZodArray = exports.ZodVoid = exports.ZodNever = exports.ZodUnknown = exports.ZodAny = exports.ZodNull = exports.ZodUndefined = exports.ZodSymbol = exports.ZodDate = exports.ZodBoolean = exports.ZodBigInt = exports.ZodNumber = exports.ZodString = exports.ZodType = void 0; -exports.NEVER = exports.void = exports.unknown = exports.union = exports.undefined = exports.tuple = exports.transformer = exports.symbol = exports.string = exports.strictObject = exports.set = exports.record = exports.promise = exports.preprocess = exports.pipeline = exports.ostring = exports.optional = exports.onumber = exports.oboolean = exports.object = exports.number = exports.nullable = exports.null = exports.never = exports.nativeEnum = exports.nan = exports.map = exports.literal = exports.lazy = exports.intersection = exports.instanceof = exports.function = exports.enum = exports.effect = exports.discriminatedUnion = void 0; +exports.boolean = exports.bigint = exports.array = exports.any = exports.coerce = exports.ZodFirstPartyTypeKind = exports.late = exports.ZodSchema = exports.Schema = exports.custom = exports.ZodReadonly = exports.ZodPipeline = exports.ZodBranded = exports.BRAND = exports.ZodNaN = exports.ZodCatch = exports.ZodDefault = exports.ZodNullable = exports.ZodOptional = exports.ZodTransformer = exports.ZodEffects = exports.ZodPromise = exports.ZodNativeEnum = exports.ZodEnum = exports.ZodLiteral = exports.ZodLazy = exports.ZodFunction = exports.ZodSet = exports.ZodMap = exports.ZodRecord = exports.ZodTuple = exports.ZodIntersection = exports.ZodDiscriminatedUnion = exports.ZodUnion = exports.ZodObject = exports.ZodArray = exports.ZodVoid = exports.ZodNever = exports.ZodUnknown = exports.ZodAny = exports.ZodNull = exports.ZodUndefined = exports.ZodSymbol = exports.ZodDate = exports.ZodBoolean = exports.ZodBigInt = exports.ZodNumber = exports.ZodString = exports.datetimeRegex = exports.ZodType = void 0; +exports.NEVER = exports.void = exports.unknown = exports.union = exports.undefined = exports.tuple = exports.transformer = exports.symbol = exports.string = exports.strictObject = exports.set = exports.record = exports.promise = exports.preprocess = exports.pipeline = exports.ostring = exports.optional = exports.onumber = exports.oboolean = exports.object = exports.number = exports.nullable = exports.null = exports.never = exports.nativeEnum = exports.nan = exports.map = exports.literal = exports.lazy = exports.intersection = exports.instanceof = exports.function = exports.enum = exports.effect = exports.discriminatedUnion = exports.date = void 0; const errors_1 = require("./errors"); const errorUtil_1 = require("./helpers/errorUtil"); const parseUtil_1 = require("./helpers/parseUtil"); @@ -698,16 +725,25 @@ function processCreateParams(params) { description }; const customMap = (iss, ctx) => { - if (iss.code !== "invalid_type") return { - message: ctx.defaultError - }; + var _a, _b; + const { + message + } = params; + if (iss.code === "invalid_enum_value") { + return { + message: message !== null && message !== void 0 ? message : ctx.defaultError + }; + } if (typeof ctx.data === "undefined") { return { - message: required_error !== null && required_error !== void 0 ? required_error : ctx.defaultError + message: (_a = message !== null && message !== void 0 ? message : required_error) !== null && _a !== void 0 ? _a : ctx.defaultError }; } + if (iss.code !== "invalid_type") return { + message: ctx.defaultError + }; return { - message: invalid_type_error !== null && invalid_type_error !== void 0 ? invalid_type_error : ctx.defaultError + message: (_b = message !== null && message !== void 0 ? message : invalid_type_error) !== null && _b !== void 0 ? _b : ctx.defaultError }; }; return { @@ -977,11 +1013,13 @@ exports.ZodType = ZodType; exports.Schema = ZodType; exports.ZodSchema = ZodType; const cuidRegex = /^c[^\s-]{8,}$/i; -const cuid2Regex = /^[a-z][a-z0-9]*$/; +const cuid2Regex = /^[0-9a-z]+$/; const ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/; // const uuidRegex = // /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[a-f0-9]{4}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i; const uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i; +const nanoidRegex = /^[a-z0-9_-]{21}$/i; +const durationRegex = /^[-+]?P(?!$)(?:(?:[-+]?\d+Y)|(?:[-+]?\d+[.,]\d+Y$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:(?:[-+]?\d+W)|(?:[-+]?\d+[.,]\d+W$))?(?:(?:[-+]?\d+D)|(?:[-+]?\d+[.,]\d+D$))?(?:T(?=[\d+-])(?:(?:[-+]?\d+H)|(?:[-+]?\d+[.,]\d+H$))?(?:(?:[-+]?\d+M)|(?:[-+]?\d+[.,]\d+M$))?(?:[-+]?\d+(?:[.,]\d+)?S)?)??$/; // from https://stackoverflow.com/a/46181/1550155 // old version: too slow, didn't support unicode // const emailRegex = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i; @@ -994,36 +1032,47 @@ const uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA- // /^[a-zA-Z0-9\.\!\#\$\%\&\'\*\+\/\=\?\^\_\`\{\|\}\~\-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/; // const emailRegex = // /^(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/i; -const emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_+-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i; +const emailRegex = /^(?!\.)(?!.*\.\.)([A-Z0-9_'+\-\.]*)[A-Z0-9_+-]@([A-Z0-9][A-Z0-9\-]*\.)+[A-Z]{2,}$/i; // const emailRegex = // /^[a-z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-z0-9-]+(?:\.[a-z0-9\-]+)*$/i; // from https://thekevinscott.com/emojis-in-javascript/#writing-a-regular-expression const _emojiRegex = `^(\\p{Extended_Pictographic}|\\p{Emoji_Component})+$`; let emojiRegex; -const ipv4Regex = /^(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))$/; +// faster, simpler, safer +const ipv4Regex = /^(?:(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])$/; const ipv6Regex = /^(([a-f0-9]{1,4}:){7}|::([a-f0-9]{1,4}:){0,6}|([a-f0-9]{1,4}:){1}:([a-f0-9]{1,4}:){0,5}|([a-f0-9]{1,4}:){2}:([a-f0-9]{1,4}:){0,4}|([a-f0-9]{1,4}:){3}:([a-f0-9]{1,4}:){0,3}|([a-f0-9]{1,4}:){4}:([a-f0-9]{1,4}:){0,2}|([a-f0-9]{1,4}:){5}:([a-f0-9]{1,4}:){0,1})([a-f0-9]{1,4}|(((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2}))\.){3}((25[0-5])|(2[0-4][0-9])|(1[0-9]{2})|([0-9]{1,2})))$/; -// Adapted from https://stackoverflow.com/a/3143231 -const datetimeRegex = args => { +// https://stackoverflow.com/questions/7860392/determine-if-string-is-in-base64-using-javascript +const base64Regex = /^([0-9a-zA-Z+/]{4})*(([0-9a-zA-Z+/]{2}==)|([0-9a-zA-Z+/]{3}=))?$/; +// simple +// const dateRegexSource = `\\d{4}-\\d{2}-\\d{2}`; +// no leap year validation +// const dateRegexSource = `\\d{4}-((0[13578]|10|12)-31|(0[13-9]|1[0-2])-30|(0[1-9]|1[0-2])-(0[1-9]|1\\d|2\\d))`; +// with leap year validation +const dateRegexSource = `((\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-((0[13578]|1[02])-(0[1-9]|[12]\\d|3[01])|(0[469]|11)-(0[1-9]|[12]\\d|30)|(02)-(0[1-9]|1\\d|2[0-8])))`; +const dateRegex = new RegExp(`^${dateRegexSource}$`); +function timeRegexSource(args) { + // let regex = `\\d{2}:\\d{2}:\\d{2}`; + let regex = `([01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d`; if (args.precision) { - if (args.offset) { - return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{${args.precision}}(([+-]\\d{2}(:?\\d{2})?)|Z)$`); - } else { - return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{${args.precision}}Z$`); - } - } else if (args.precision === 0) { - if (args.offset) { - return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(([+-]\\d{2}(:?\\d{2})?)|Z)$`); - } else { - return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$`); - } - } else { - if (args.offset) { - return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?(([+-]\\d{2}(:?\\d{2})?)|Z)$`); - } else { - return new RegExp(`^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d+)?Z$`); - } + regex = `${regex}\\.\\d{${args.precision}}`; + } else if (args.precision == null) { + regex = `${regex}(\\.\\d+)?`; } -}; + return regex; +} +function timeRegex(args) { + return new RegExp(`^${timeRegexSource(args)}$`); +} +// Adapted from https://stackoverflow.com/a/3143231 +function datetimeRegex(args) { + let regex = `${dateRegexSource}T${timeRegexSource(args)}`; + const opts = []; + opts.push(args.local ? `Z?` : `Z`); + if (args.offset) opts.push(`([+-]\\d{2}:?\\d{2})`); + regex = `${regex}(${opts.join("|")})`; + return new RegExp(`^${regex}$`); +} +exports.datetimeRegex = datetimeRegex; function isValidIP(ip, version) { if ((version === "v4" || !version) && ipv4Regex.test(ip)) { return true; @@ -1045,10 +1094,7 @@ class ZodString extends ZodType { code: ZodError_1.ZodIssueCode.invalid_type, expected: util_1.ZodParsedType.string, received: ctx.parsedType - } - // - ); - + }); return parseUtil_1.INVALID; } const status = new parseUtil_1.ParseStatus(); @@ -1139,6 +1185,16 @@ class ZodString extends ZodType { }); status.dirty(); } + } else if (check.kind === "nanoid") { + if (!nanoidRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_1.addIssueToContext)(ctx, { + validation: "nanoid", + code: ZodError_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } } else if (check.kind === "cuid") { if (!cuidRegex.test(input.data)) { ctx = this._getOrReturnCtx(input, ctx); @@ -1247,6 +1303,38 @@ class ZodString extends ZodType { }); status.dirty(); } + } else if (check.kind === "date") { + const regex = dateRegex; + if (!regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_1.addIssueToContext)(ctx, { + code: ZodError_1.ZodIssueCode.invalid_string, + validation: "date", + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "time") { + const regex = timeRegex(check); + if (!regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_1.addIssueToContext)(ctx, { + code: ZodError_1.ZodIssueCode.invalid_string, + validation: "time", + message: check.message + }); + status.dirty(); + } + } else if (check.kind === "duration") { + if (!durationRegex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_1.addIssueToContext)(ctx, { + validation: "duration", + code: ZodError_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } } else if (check.kind === "ip") { if (!isValidIP(input.data, check.version)) { ctx = this._getOrReturnCtx(input, ctx); @@ -1257,6 +1345,16 @@ class ZodString extends ZodType { }); status.dirty(); } + } else if (check.kind === "base64") { + if (!base64Regex.test(input.data)) { + ctx = this._getOrReturnCtx(input, ctx); + (0, parseUtil_1.addIssueToContext)(ctx, { + validation: "base64", + code: ZodError_1.ZodIssueCode.invalid_string, + message: check.message + }); + status.dirty(); + } } else { util_1.util.assertNever(check); } @@ -1303,6 +1401,12 @@ class ZodString extends ZodType { ...errorUtil_1.errorUtil.errToObj(message) }); } + nanoid(message) { + return this._addCheck({ + kind: "nanoid", + ...errorUtil_1.errorUtil.errToObj(message) + }); + } cuid(message) { return this._addCheck({ kind: "cuid", @@ -1321,6 +1425,12 @@ class ZodString extends ZodType { ...errorUtil_1.errorUtil.errToObj(message) }); } + base64(message) { + return this._addCheck({ + kind: "base64", + ...errorUtil_1.errorUtil.errToObj(message) + }); + } ip(options) { return this._addCheck({ kind: "ip", @@ -1328,12 +1438,13 @@ class ZodString extends ZodType { }); } datetime(options) { - var _a; + var _a, _b; if (typeof options === "string") { return this._addCheck({ kind: "datetime", precision: null, offset: false, + local: false, message: options }); } @@ -1341,9 +1452,36 @@ class ZodString extends ZodType { kind: "datetime", precision: typeof (options === null || options === void 0 ? void 0 : options.precision) === "undefined" ? null : options === null || options === void 0 ? void 0 : options.precision, offset: (_a = options === null || options === void 0 ? void 0 : options.offset) !== null && _a !== void 0 ? _a : false, + local: (_b = options === null || options === void 0 ? void 0 : options.local) !== null && _b !== void 0 ? _b : false, + ...errorUtil_1.errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message) + }); + } + date(message) { + return this._addCheck({ + kind: "date", + message + }); + } + time(options) { + if (typeof options === "string") { + return this._addCheck({ + kind: "time", + precision: null, + message: options + }); + } + return this._addCheck({ + kind: "time", + precision: typeof (options === null || options === void 0 ? void 0 : options.precision) === "undefined" ? null : options === null || options === void 0 ? void 0 : options.precision, ...errorUtil_1.errorUtil.errToObj(options === null || options === void 0 ? void 0 : options.message) }); } + duration(message) { + return this._addCheck({ + kind: "duration", + ...errorUtil_1.errorUtil.errToObj(message) + }); + } regex(regex, message) { return this._addCheck({ kind: "regex", @@ -1428,6 +1566,15 @@ class ZodString extends ZodType { get isDatetime() { return !!this._def.checks.find(ch => ch.kind === "datetime"); } + get isDate() { + return !!this._def.checks.find(ch => ch.kind === "date"); + } + get isTime() { + return !!this._def.checks.find(ch => ch.kind === "time"); + } + get isDuration() { + return !!this._def.checks.find(ch => ch.kind === "duration"); + } get isEmail() { return !!this._def.checks.find(ch => ch.kind === "email"); } @@ -1440,6 +1587,9 @@ class ZodString extends ZodType { get isUUID() { return !!this._def.checks.find(ch => ch.kind === "uuid"); } + get isNANOID() { + return !!this._def.checks.find(ch => ch.kind === "nanoid"); + } get isCUID() { return !!this._def.checks.find(ch => ch.kind === "cuid"); } @@ -1452,6 +1602,9 @@ class ZodString extends ZodType { get isIP() { return !!this._def.checks.find(ch => ch.kind === "ip"); } + get isBase64() { + return !!this._def.checks.find(ch => ch.kind === "base64"); + } get minLength() { let min = null; for (const ch of this._def.checks) { @@ -2442,9 +2595,10 @@ class ZodObject extends ZodType { const syncPairs = []; for (const pair of pairs) { const key = await pair.key; + const value = await pair.value; syncPairs.push({ key, - value: await pair.value, + value, alwaysSet: pair.alwaysSet }); } @@ -2814,15 +2968,25 @@ const getDiscriminator = type => { return type.options; } else if (type instanceof ZodNativeEnum) { // eslint-disable-next-line ban/ban - return Object.keys(type.enum); + return util_1.util.objectValues(type.enum); } else if (type instanceof ZodDefault) { return getDiscriminator(type._def.innerType); } else if (type instanceof ZodUndefined) { return [undefined]; } else if (type instanceof ZodNull) { return [null]; + } else if (type instanceof ZodOptional) { + return [undefined, ...getDiscriminator(type.unwrap())]; + } else if (type instanceof ZodNullable) { + return [null, ...getDiscriminator(type.unwrap())]; + } else if (type instanceof ZodBranded) { + return getDiscriminator(type.unwrap()); + } else if (type instanceof ZodReadonly) { + return getDiscriminator(type.unwrap()); + } else if (type instanceof ZodCatch) { + return getDiscriminator(type._def.innerType); } else { - return null; + return []; } }; class ZodDiscriminatedUnion extends ZodType { @@ -2886,7 +3050,7 @@ class ZodDiscriminatedUnion extends ZodType { // try { for (const type of options) { const discriminatorValues = getDiscriminator(type.shape[discriminator]); - if (!discriminatorValues) { + if (!discriminatorValues.length) { throw new Error(`A discriminator value for key \`${discriminator}\` could not be extracted from all schema options`); } for (const value of discriminatorValues) { @@ -3123,7 +3287,8 @@ class ZodRecord extends ZodType { for (const key in ctx.data) { pairs.push({ key: keyType._parse(new ParseInputLazyPath(ctx, key, ctx.path, key)), - value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)) + value: valueType._parse(new ParseInputLazyPath(ctx, ctx.data[key], ctx.path, key)), + alwaysSet: key in ctx.data }); } if (ctx.common.async) { @@ -3511,6 +3676,10 @@ function createZodEnum(values, params) { }); } class ZodEnum extends ZodType { + constructor() { + super(...arguments); + _ZodEnum_cache.set(this, void 0); + } _parse(input) { if (typeof input.data !== "string") { const ctx = this._getOrReturnCtx(input); @@ -3522,7 +3691,10 @@ class ZodEnum extends ZodType { }); return parseUtil_1.INVALID; } - if (this._def.values.indexOf(input.data) === -1) { + if (!__classPrivateFieldGet(this, _ZodEnum_cache, "f")) { + __classPrivateFieldSet(this, _ZodEnum_cache, new Set(this._def.values), "f"); + } + if (!__classPrivateFieldGet(this, _ZodEnum_cache, "f").has(input.data)) { const ctx = this._getOrReturnCtx(input); const expectedValues = this._def.values; (0, parseUtil_1.addIssueToContext)(ctx, { @@ -3559,15 +3731,28 @@ class ZodEnum extends ZodType { return enumValues; } extract(values) { - return ZodEnum.create(values); + let newDef = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this._def; + return ZodEnum.create(values, { + ...this._def, + ...newDef + }); } exclude(values) { - return ZodEnum.create(this.options.filter(opt => !values.includes(opt))); + let newDef = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : this._def; + return ZodEnum.create(this.options.filter(opt => !values.includes(opt)), { + ...this._def, + ...newDef + }); } } exports.ZodEnum = ZodEnum; +_ZodEnum_cache = new WeakMap(); ZodEnum.create = createZodEnum; class ZodNativeEnum extends ZodType { + constructor() { + super(...arguments); + _ZodNativeEnum_cache.set(this, void 0); + } _parse(input) { const nativeEnumValues = util_1.util.getValidEnumValues(this._def.values); const ctx = this._getOrReturnCtx(input); @@ -3580,7 +3765,10 @@ class ZodNativeEnum extends ZodType { }); return parseUtil_1.INVALID; } - if (nativeEnumValues.indexOf(input.data) === -1) { + if (!__classPrivateFieldGet(this, _ZodNativeEnum_cache, "f")) { + __classPrivateFieldSet(this, _ZodNativeEnum_cache, new Set(util_1.util.getValidEnumValues(this._def.values)), "f"); + } + if (!__classPrivateFieldGet(this, _ZodNativeEnum_cache, "f").has(input.data)) { const expectedValues = util_1.util.objectValues(nativeEnumValues); (0, parseUtil_1.addIssueToContext)(ctx, { received: ctx.data, @@ -3596,6 +3784,7 @@ class ZodNativeEnum extends ZodType { } } exports.ZodNativeEnum = ZodNativeEnum; +_ZodNativeEnum_cache = new WeakMap(); ZodNativeEnum.create = (values, params) => { return new ZodNativeEnum({ values: values, @@ -3665,32 +3854,34 @@ class ZodEffects extends ZodType { checkCtx.addIssue = checkCtx.addIssue.bind(checkCtx); if (effect.type === "preprocess") { const processed = effect.transform(ctx.data, checkCtx); - if (ctx.common.issues.length) { - return { - status: "dirty", - value: ctx.data - }; - } if (ctx.common.async) { - return Promise.resolve(processed).then(processed => { - return this._def.schema._parseAsync({ + return Promise.resolve(processed).then(async processed => { + if (status.value === "aborted") return parseUtil_1.INVALID; + const result = await this._def.schema._parseAsync({ data: processed, path: ctx.path, parent: ctx }); + if (result.status === "aborted") return parseUtil_1.INVALID; + if (result.status === "dirty") return (0, parseUtil_1.DIRTY)(result.value); + if (status.value === "dirty") return (0, parseUtil_1.DIRTY)(result.value); + return result; }); } else { - return this._def.schema._parseSync({ + if (status.value === "aborted") return parseUtil_1.INVALID; + const result = this._def.schema._parseSync({ data: processed, path: ctx.path, parent: ctx }); + if (result.status === "aborted") return parseUtil_1.INVALID; + if (result.status === "dirty") return (0, parseUtil_1.DIRTY)(result.value); + if (status.value === "dirty") return (0, parseUtil_1.DIRTY)(result.value); + return result; } } if (effect.type === "refinement") { - const executeRefinement = (acc - // effect: RefinementEffect - ) => { + const executeRefinement = acc => { const result = effect.refinement(acc, checkCtx); if (ctx.common.async) { return Promise.resolve(result); @@ -4013,10 +4204,16 @@ exports.ZodPipeline = ZodPipeline; class ZodReadonly extends ZodType { _parse(input) { const result = this._def.innerType._parse(input); - if ((0, parseUtil_1.isValid)(result)) { - result.value = Object.freeze(result.value); - } - return result; + const freeze = data => { + if ((0, parseUtil_1.isValid)(data)) { + data.value = Object.freeze(data.value); + } + return data; + }; + return (0, parseUtil_1.isAsync)(result) ? result.then(data => freeze(data)) : freeze(result); + } + unwrap() { + return this._def.innerType; } } exports.ZodReadonly = ZodReadonly; @@ -4027,7 +4224,7 @@ ZodReadonly.create = (type, params) => { ...processCreateParams(params) }); }; -const custom = function (check) { +function custom(check) { let params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; let /** @@ -4059,7 +4256,7 @@ const custom = function (check) { } }); return ZodAny.create(); -}; +} exports.custom = custom; exports.late = { object: ZodObject.lazycreate @@ -4113,7 +4310,7 @@ cls) { let params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : { message: `Input not instance of ${cls.name}` }; - return (0, exports.custom)(data => data instanceof cls, params); + return custom(data => data instanceof cls, params); }; exports.instanceof = instanceOfType; const stringType = ZodString.create; @@ -4435,8 +4632,8 @@ class SchemaValidationError extends Error { } case 'invalid_union': { - for (let unionError of issue.unionErrors) { - for (let issue1 of unionError.issues) { + for (const unionError of issue.unionErrors) { + for (const issue1 of unionError.issues) { log(issue1); } } @@ -4448,7 +4645,7 @@ class SchemaValidationError extends Error { } } } - for (let error of errors) { + for (const error of errors) { log(error); } const message = [heading, 'please see the details above'].join('\n '); @@ -4571,8 +4768,8 @@ class DeviceApi { */ async request(deviceApiCall, options) { deviceApiCall.validateParams(); - let result = await this.transport.send(deviceApiCall, options); - let processed = deviceApiCall.preResultValidation(result); + const result = await this.transport.send(deviceApiCall, options); + const processed = deviceApiCall.preResultValidation(result); return deviceApiCall.validateResult(processed); } /** @@ -4660,44 +4857,44 @@ var _webkit = require("./webkit.js"); */ class Messaging { /** - * @param {WebkitMessagingConfig} config - */ + * @param {WebkitMessagingConfig} config + */ constructor(config) { this.transport = getTransport(config); } /** - * Send a 'fire-and-forget' message. - * @throws {Error} - * {@link MissingHandler} - * - * @example - * - * ``` - * const messaging = new Messaging(config) - * messaging.notify("foo", {bar: "baz"}) - * ``` - * @param {string} name - * @param {Record} [data] - */ + * Send a 'fire-and-forget' message. + * @throws {Error} + * {@link MissingHandler} + * + * @example + * + * ``` + * const messaging = new Messaging(config) + * messaging.notify("foo", {bar: "baz"}) + * ``` + * @param {string} name + * @param {Record} [data] + */ notify(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; this.transport.notify(name, data); } /** - * Send a request, and wait for a response - * @throws {Error} - * {@link MissingHandler} - * - * @example - * ``` - * const messaging = new Messaging(config) - * const response = await messaging.request("foo", {bar: "baz"}) - * ``` - * - * @param {string} name - * @param {Record} [data] - * @return {Promise} - */ + * Send a request, and wait for a response + * @throws {Error} + * {@link MissingHandler} + * + * @example + * ``` + * const messaging = new Messaging(config) + * const response = await messaging.request("foo", {bar: "baz"}) + * ``` + * + * @param {string} name + * @param {Record} [data] + * @return {Promise} + */ request(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return this.transport.request(name, data); @@ -4710,20 +4907,20 @@ class Messaging { exports.Messaging = Messaging; class MessagingTransport { /** - * @param {string} name - * @param {Record} [data] - * @returns {void} - */ + * @param {string} name + * @param {Record} [data] + * @returns {void} + */ // @ts-ignore - ignoring a no-unused ts error, this is only an interface. notify(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; throw new Error("must implement 'notify'"); } /** - * @param {string} name - * @param {Record} [data] - * @return {Promise} - */ + * @param {string} name + * @param {Record} [data] + * @return {Promise} + */ // @ts-ignore - ignoring a no-unused ts error, this is only an interface. request(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; @@ -4748,9 +4945,9 @@ function getTransport(config) { */ class MissingHandler extends Error { /** - * @param {string} message - * @param {string} handlerName - */ + * @param {string} message + * @param {string} handlerName + */ constructor(message, handlerName) { super(message); this.handlerName = handlerName; @@ -4856,8 +5053,8 @@ class WebkitMessagingTransport { config; globals; /** - * @param {WebkitMessagingConfig} config - */ + * @param {WebkitMessagingConfig} config + */ constructor(config) { this.config = config; this.globals = captureGlobals(); @@ -4866,11 +5063,11 @@ class WebkitMessagingTransport { } } /** - * Sends message to the webkit layer (fire and forget) - * @param {String} handler - * @param {*} data - * @internal - */ + * Sends message to the webkit layer (fire and forget) + * @param {String} handler + * @param {*} data + * @internal + */ wkSend(handler) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (!(handler in this.globals.window.webkit.messageHandlers)) { @@ -4894,12 +5091,12 @@ class WebkitMessagingTransport { } /** - * Sends message to the webkit layer and waits for the specified response - * @param {String} handler - * @param {*} data - * @returns {Promise<*>} - * @internal - */ + * Sends message to the webkit layer and waits for the specified response + * @param {String} handler + * @param {*} data + * @returns {Promise<*>} + * @internal + */ async wkSendAndWait(handler) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (this.config.hasModernWebkitAPI) { @@ -4940,27 +5137,27 @@ class WebkitMessagingTransport { } } /** - * @param {string} name - * @param {Record} [data] - */ + * @param {string} name + * @param {Record} [data] + */ notify(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; this.wkSend(name, data); } /** - * @param {string} name - * @param {Record} [data] - */ + * @param {string} name + * @param {Record} [data] + */ request(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return this.wkSendAndWait(name, data); } /** - * Generate a random method name and adds it to the global scope - * The native layer will use this method to send the response - * @param {string | number} randomMethodName - * @param {Function} callback - */ + * Generate a random method name and adds it to the global scope + * The native layer will use this method to send the response + * @param {string | number} randomMethodName + * @param {Function} callback + */ generateRandomMethod(randomMethodName, callback) { var _this = this; this.globals.ObjectDefineProperty(this.globals.window, randomMethodName, { @@ -4969,8 +5166,8 @@ class WebkitMessagingTransport { configurable: true, writable: false, /** - * @param {any[]} args - */ + * @param {any[]} args + */ value: function () { callback(...arguments); // @ts-ignore - we want this to throw if it fails as it would indicate a fatal error. @@ -4986,16 +5183,16 @@ class WebkitMessagingTransport { } /** - * @type {{name: string, length: number}} - */ + * @type {{name: string, length: number}} + */ algoObj = { name: 'AES-GCM', length: 256 }; /** - * @returns {Promise} - */ + * @returns {Promise} + */ async createRandKey() { const key = await this.globals.generateKey(this.algoObj, true, ['encrypt', 'decrypt']); const exportedKey = await this.globals.exportKey('raw', key); @@ -5003,44 +5200,44 @@ class WebkitMessagingTransport { } /** - * @returns {Uint8Array} - */ + * @returns {Uint8Array} + */ createRandIv() { return this.globals.getRandomValues(new this.globals.Uint8Array(12)); } /** - * @param {BufferSource} ciphertext - * @param {BufferSource} key - * @param {Uint8Array} iv - * @returns {Promise} - */ + * @param {BufferSource} ciphertext + * @param {BufferSource} key + * @param {Uint8Array} iv + * @returns {Promise} + */ async decrypt(ciphertext, key, iv) { const cryptoKey = await this.globals.importKey('raw', key, 'AES-GCM', false, ['decrypt']); const algo = { name: 'AES-GCM', iv }; - let decrypted = await this.globals.decrypt(algo, cryptoKey, ciphertext); - let dec = new this.globals.TextDecoder(); + const decrypted = await this.globals.decrypt(algo, cryptoKey, ciphertext); + const dec = new this.globals.TextDecoder(); return dec.decode(decrypted); } /** - * When required (such as on macos 10.x), capture the `postMessage` method on - * each webkit messageHandler - * - * @param {string[]} handlerNames - */ + * When required (such as on macos 10.x), capture the `postMessage` method on + * each webkit messageHandler + * + * @param {string[]} handlerNames + */ captureWebkitHandlers(handlerNames) { const handlers = window.webkit.messageHandlers; if (!handlers) throw new _messaging.MissingHandler('window.webkit.messageHandlers was absent', 'all'); - for (let webkitMessageHandlerName of handlerNames) { + for (const webkitMessageHandlerName of handlerNames) { if (typeof handlers[webkitMessageHandlerName]?.postMessage === 'function') { /** - * `bind` is used here to ensure future calls to the captured - * `postMessage` have the correct `this` context - */ + * `bind` is used here to ensure future calls to the captured + * `postMessage` have the correct `this` context + */ const original = handlers[webkitMessageHandlerName]; const bound = handlers[webkitMessageHandlerName].postMessage?.bind(original); this.globals.capturedWebkitHandlers[webkitMessageHandlerName] = bound; @@ -5069,11 +5266,11 @@ class WebkitMessagingTransport { exports.WebkitMessagingTransport = WebkitMessagingTransport; class WebkitMessagingConfig { /** - * @param {object} params - * @param {boolean} params.hasModernWebkitAPI - * @param {string[]} params.webkitMessageHandlerNames - * @param {string} params.secret - */ + * @param {object} params + * @param {boolean} params.hasModernWebkitAPI + * @param {string[]} params.webkitMessageHandlerNames + * @param {string} params.secret + */ constructor(params) { /** * Whether or not the current WebKit Platform supports secure messaging @@ -5081,13 +5278,13 @@ class WebkitMessagingConfig { */ this.hasModernWebkitAPI = params.hasModernWebkitAPI; /** - * A list of WebKit message handler names that a user script can send - */ + * A list of WebKit message handler names that a user script can send + */ this.webkitMessageHandlerNames = params.webkitMessageHandlerNames; /** - * A string provided by native platforms to be sent with future outgoing - * messages - */ + * A string provided by native platforms to be sent with future outgoing + * messages + */ this.secret = params.secret; } } @@ -5099,28 +5296,28 @@ class WebkitMessagingConfig { exports.WebkitMessagingConfig = WebkitMessagingConfig; class SecureMessagingParams { /** - * @param {object} params - * @param {string} params.methodName - * @param {string} params.secret - * @param {number[]} params.key - * @param {number[]} params.iv - */ + * @param {object} params + * @param {string} params.methodName + * @param {string} params.secret + * @param {number[]} params.key + * @param {number[]} params.iv + */ constructor(params) { /** * The method that's been appended to `window` to be called later */ this.methodName = params.methodName; /** - * The secret used to ensure message sender validity - */ + * The secret used to ensure message sender validity + */ this.secret = params.secret; /** - * The CipherKey as number[] - */ + * The CipherKey as number[] + */ this.key = params.key; /** - * The Initial Vector as number[] - */ + * The Initial Vector as number[] + */ this.iv = params.iv; } } @@ -5331,7 +5528,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && * }} PasswordParameters */ const defaults = Object.freeze({ - SCAN_SET_ORDER: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\\\"'<>,.?/ ]", + SCAN_SET_ORDER: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\\"\'<>,.?/ ]', defaultUnambiguousCharacters: 'abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789', defaultPasswordLength: _constants.constants.DEFAULT_MIN_LENGTH, defaultPasswordRules: _constants.constants.DEFAULT_PASSWORD_RULES, @@ -5458,7 +5655,7 @@ class Password { _requirementsFromRules(passwordRules) { /** @type {Requirements} */ const requirements = {}; - for (let rule of passwordRules) { + for (const rule of passwordRules) { if (rule.name === parser.RuleName.ALLOWED) { console.assert(!('PasswordAllowedCharacters' in requirements)); const chars = this._charactersFromCharactersClasses(rule.value); @@ -5789,7 +5986,7 @@ class Password { */ _charactersFromCharactersClasses(characterClasses) { const output = []; - for (let characterClass of characterClasses) { + for (const characterClass of characterClasses) { output.push(...this._scanSetFromCharacterClass(characterClass)); } return output; @@ -5803,9 +6000,9 @@ class Password { if (!characters.length) { return ''; } - let shadowCharacters = Array.prototype.slice.call(characters); + const shadowCharacters = Array.prototype.slice.call(characters); shadowCharacters.sort((a, b) => this.options.SCAN_SET_ORDER.indexOf(a) - this.options.SCAN_SET_ORDER.indexOf(b)); - let uniqueCharacters = [shadowCharacters[0]]; + const uniqueCharacters = [shadowCharacters[0]]; for (let i = 1, length = shadowCharacters.length; i < length; ++i) { if (shadowCharacters[i] === shadowCharacters[i - 1]) { continue; @@ -5845,6 +6042,7 @@ Object.defineProperty(exports, "__esModule", { }); exports.SHOULD_NOT_BE_REACHED = exports.RuleName = exports.Rule = exports.ParserError = exports.NamedCharacterClass = exports.Identifier = exports.CustomCharacterClass = void 0; exports.parsePasswordRules = parsePasswordRules; +/* eslint-disable no-var */ // Copyright (c) 2019 - 2020 Apple Inc. Licensed under MIT License. /* @@ -5897,7 +6095,6 @@ class Rule { } } exports.Rule = Rule; -; class NamedCharacterClass { constructor(name) { console.assert(_isValidRequiredOrAllowedPropertyValueIdentifier(name)); @@ -5914,10 +6111,8 @@ class NamedCharacterClass { } } exports.NamedCharacterClass = NamedCharacterClass; -; class ParserError extends Error {} exports.ParserError = ParserError; -; class CustomCharacterClass { constructor(characters) { console.assert(characters instanceof Array); @@ -5933,14 +6128,11 @@ class CustomCharacterClass { return `[${this._characters.join('').replace('"', '"')}]`; } } -exports.CustomCharacterClass = CustomCharacterClass; -; // MARK: Lexer functions - +exports.CustomCharacterClass = CustomCharacterClass; function _isIdentifierCharacter(c) { console.assert(c.length === 1); - // eslint-disable-next-line no-mixed-operators return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c === '-'; } function _isASCIIDigit(c) { @@ -5986,14 +6178,14 @@ function _markBitsForNamedCharacterClass(bitSet, namedCharacterClass) { } } function _markBitsForCustomCharacterClass(bitSet, customCharacterClass) { - for (let character of customCharacterClass.characters) { + for (const character of customCharacterClass.characters) { bitSet[_bitSetIndexForCharacter(character)] = true; } } function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFormatCompliant) { // @ts-ignore - let asciiPrintableBitSet = new Array('~'.codePointAt(0) - ' '.codePointAt(0) + 1); - for (let propertyValue of propertyValues) { + const asciiPrintableBitSet = new Array('~'.codePointAt(0) - ' '.codePointAt(0) + 1); + for (const propertyValue of propertyValues) { if (propertyValue instanceof NamedCharacterClass) { if (propertyValue.name === Identifier.UNICODE) { return [new NamedCharacterClass(Identifier.UNICODE)]; @@ -6008,32 +6200,32 @@ function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFo } let charactersSeen = []; function checkRange(start, end) { - let temp = []; + const temp = []; for (let i = _bitSetIndexForCharacter(start); i <= _bitSetIndexForCharacter(end); ++i) { if (asciiPrintableBitSet[i]) { temp.push(_characterAtBitSetIndex(i)); } } - let result = temp.length === _bitSetIndexForCharacter(end) - _bitSetIndexForCharacter(start) + 1; + const result = temp.length === _bitSetIndexForCharacter(end) - _bitSetIndexForCharacter(start) + 1; if (!result) { charactersSeen = charactersSeen.concat(temp); } return result; } - let hasAllUpper = checkRange('A', 'Z'); - let hasAllLower = checkRange('a', 'z'); - let hasAllDigits = checkRange('0', '9'); + const hasAllUpper = checkRange('A', 'Z'); + const hasAllLower = checkRange('a', 'z'); + const hasAllDigits = checkRange('0', '9'); // Check for special characters, accounting for characters that are given special treatment (i.e. '-' and ']') let hasAllSpecial = false; let hasDash = false; let hasRightSquareBracket = false; - let temp = []; + const temp = []; for (let i = _bitSetIndexForCharacter(' '); i <= _bitSetIndexForCharacter('/'); ++i) { if (!asciiPrintableBitSet[i]) { continue; } - let character = _characterAtBitSetIndex(i); + const character = _characterAtBitSetIndex(i); if (keepCustomCharacterClassFormatCompliant && character === '-') { hasDash = true; } else { @@ -6049,7 +6241,7 @@ function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFo if (!asciiPrintableBitSet[i]) { continue; } - let character = _characterAtBitSetIndex(i); + const character = _characterAtBitSetIndex(i); if (keepCustomCharacterClassFormatCompliant && character === ']') { hasRightSquareBracket = true; } else { @@ -6067,12 +6259,12 @@ function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFo if (hasRightSquareBracket) { temp.push(']'); } - let numberOfSpecialCharacters = _bitSetIndexForCharacter('/') - _bitSetIndexForCharacter(' ') + 1 + (_bitSetIndexForCharacter('@') - _bitSetIndexForCharacter(':') + 1) + (_bitSetIndexForCharacter('`') - _bitSetIndexForCharacter('[') + 1) + (_bitSetIndexForCharacter('~') - _bitSetIndexForCharacter('{') + 1); + const numberOfSpecialCharacters = _bitSetIndexForCharacter('/') - _bitSetIndexForCharacter(' ') + 1 + (_bitSetIndexForCharacter('@') - _bitSetIndexForCharacter(':') + 1) + (_bitSetIndexForCharacter('`') - _bitSetIndexForCharacter('[') + 1) + (_bitSetIndexForCharacter('~') - _bitSetIndexForCharacter('{') + 1); hasAllSpecial = temp.length === numberOfSpecialCharacters; if (!hasAllSpecial) { charactersSeen = charactersSeen.concat(temp); } - let result = []; + const result = []; if (hasAllUpper && hasAllLower && hasAllDigits && hasAllSpecial) { return [new NamedCharacterClass(Identifier.ASCII_PRINTABLE)]; } @@ -6100,7 +6292,7 @@ function _indexOfNonWhitespaceCharacter(input) { let position = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; console.assert(position >= 0); console.assert(position <= input.length); - let length = input.length; + const length = input.length; while (position < length && _isASCIIWhitespace(input[position])) { ++position; } @@ -6110,10 +6302,10 @@ function _parseIdentifier(input, position) { console.assert(position >= 0); console.assert(position < input.length); console.assert(_isIdentifierCharacter(input[position])); - let length = input.length; - let seenIdentifiers = []; + const length = input.length; + const seenIdentifiers = []; do { - let c = input[position]; + const c = input[position]; if (!_isIdentifierCharacter(c)) { break; } @@ -6129,16 +6321,16 @@ function _parseCustomCharacterClass(input, position) { console.assert(position >= 0); console.assert(position < input.length); console.assert(input[position] === CHARACTER_CLASS_START_SENTINEL); - let length = input.length; + const length = input.length; ++position; if (position >= length) { // console.error('Found end-of-line instead of character class character') return [null, position]; } - let initialPosition = position; - let result = []; + const initialPosition = position; + const result = []; do { - let c = input[position]; + const c = input[position]; if (!_isASCIIPrintableCharacter(c)) { ++position; continue; @@ -6174,11 +6366,11 @@ function _parseCustomCharacterClass(input, position) { function _parsePasswordRequiredOrAllowedPropertyValue(input, position) { console.assert(position >= 0); console.assert(position < input.length); - let length = input.length; - let propertyValues = []; + const length = input.length; + const propertyValues = []; while (true) { if (_isIdentifierCharacter(input[position])) { - let identifierStartPosition = position; + const identifierStartPosition = position; // eslint-disable-next-line no-redeclare var [propertyValue, position] = _parseIdentifier(input, position); if (!_isValidRequiredOrAllowedPropertyValueIdentifier(propertyValue)) { @@ -6225,8 +6417,8 @@ function _parsePasswordRule(input, position) { console.assert(position >= 0); console.assert(position < input.length); console.assert(_isIdentifierCharacter(input[position])); - let length = input.length; - var mayBeIdentifierStartPosition = position; + const length = input.length; + const mayBeIdentifierStartPosition = position; // eslint-disable-next-line no-redeclare var [identifier, position] = _parseIdentifier(input, position); if (!Object.values(RuleName).includes(identifier)) { @@ -6241,7 +6433,7 @@ function _parsePasswordRule(input, position) { // console.error('Failed to find start of property value: ' + input.substr(position)) return [null, position, undefined]; } - let property = { + const property = { name: identifier, value: null }; @@ -6297,7 +6489,7 @@ function _parseInteger(input, position) { // console.error('Failed to parse value of type integer; not a number: ' + input.substr(position)) return [null, position]; } - let length = input.length; + const length = input.length; // let initialPosition = position let result = 0; do { @@ -6318,8 +6510,8 @@ function _parseInteger(input, position) { * @private */ function _parsePasswordRulesInternal(input) { - let parsedProperties = []; - let length = input.length; + const parsedProperties = []; + const length = input.length; var position = _indexOfNonWhitespaceCharacter(input); while (position < length) { if (!_isIdentifierCharacter(input[position])) { @@ -6356,7 +6548,7 @@ function _parsePasswordRulesInternal(input) { * @returns {Rule[]} */ function parsePasswordRules(input, formatRulesForMinifiedVersion) { - let [passwordRules, maybeMessage] = _parsePasswordRulesInternal(input); + const [passwordRules, maybeMessage] = _parsePasswordRulesInternal(input); if (!passwordRules) { throw new ParserError(maybeMessage); } @@ -6366,13 +6558,13 @@ function parsePasswordRules(input, formatRulesForMinifiedVersion) { // When formatting rules for minified version, we should keep the formatted rules // as similar to the input as possible. Avoid copying required rules to allowed rules. - let suppressCopyingRequiredToAllowed = formatRulesForMinifiedVersion; - let requiredRules = []; + const suppressCopyingRequiredToAllowed = formatRulesForMinifiedVersion; + const requiredRules = []; let newAllowedValues = []; let minimumMaximumConsecutiveCharacters = null; let maximumMinLength = 0; let minimumMaxLength = null; - for (let rule of passwordRules) { + for (const rule of passwordRules) { switch (rule.name) { case RuleName.MAX_CONSECUTIVE: minimumMaximumConsecutiveCharacters = minimumMaximumConsecutiveCharacters ? Math.min(rule.value, minimumMaximumConsecutiveCharacters) : rule.value; @@ -6405,10 +6597,10 @@ function parsePasswordRules(input, formatRulesForMinifiedVersion) { if (minimumMaximumConsecutiveCharacters !== null) { newPasswordRules.push(new Rule(RuleName.MAX_CONSECUTIVE, minimumMaximumConsecutiveCharacters)); } - let sortedRequiredRules = requiredRules.sort(function (a, b) { + const sortedRequiredRules = requiredRules.sort(function (a, b) { const namedCharacterClassOrder = [Identifier.LOWER, Identifier.UPPER, Identifier.DIGIT, Identifier.SPECIAL, Identifier.ASCII_PRINTABLE, Identifier.UNICODE]; - let aIsJustOneNamedCharacterClass = a.value.length === 1 && a.value[0] instanceof NamedCharacterClass; - let bIsJustOneNamedCharacterClass = b.value.length === 1 && b.value[0] instanceof NamedCharacterClass; + const aIsJustOneNamedCharacterClass = a.value.length === 1 && a.value[0] instanceof NamedCharacterClass; + const bIsJustOneNamedCharacterClass = b.value.length === 1 && b.value[0] instanceof NamedCharacterClass; if (aIsJustOneNamedCharacterClass && !bIsJustOneNamedCharacterClass) { return -1; } @@ -6416,8 +6608,8 @@ function parsePasswordRules(input, formatRulesForMinifiedVersion) { return 1; } if (aIsJustOneNamedCharacterClass && bIsJustOneNamedCharacterClass) { - let aIndex = namedCharacterClassOrder.indexOf(a.value[0].name); - let bIndex = namedCharacterClassOrder.indexOf(b.value[0].name); + const aIndex = namedCharacterClassOrder.indexOf(a.value[0].name); + const bIndex = namedCharacterClassOrder.indexOf(b.value[0].name); return aIndex - bIndex; } return 0; @@ -7062,6 +7254,9 @@ module.exports={ "keldoc.com": { "password-rules": "minlength: 12; required: lower; required: upper; required: digit; required: [!@#$%^&*];" }, + "kennedy-center.org": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&*?@];" + }, "key.harvard.edu": { "password-rules": "minlength: 10; maxlength: 100; required: lower; required: upper; required: digit; allowed: [-@_#!&$`%*+()./,;~:{}|?>=<^[']];" }, @@ -7574,8 +7769,8 @@ class CredentialsImport { activeInput?.focus(); } async started() { - this.device.deviceApi.notify(new _deviceApiCalls.CloseAutofillParentCall(null)); this.device.deviceApi.notify(new _deviceApiCalls.StartCredentialsImportFlowCall({})); + this.device.deviceApi.notify(new _deviceApiCalls.CloseAutofillParentCall(null)); } async dismissed() { this.device.deviceApi.notify(new _deviceApiCalls.CredentialsImportFlowPermanentlyDismissedCall(null)); @@ -7619,7 +7814,7 @@ function createDevice() { }; // Create the DeviceAPI + Setting - let deviceApi = new _index.DeviceApi(globalConfig.isDDGTestMode ? loggingTransport : transport); + const deviceApi = new _index.DeviceApi(globalConfig.isDDGTestMode ? loggingTransport : transport); const settings = new _Settings.Settings(globalConfig, deviceApi); if (globalConfig.isWindows) { if (globalConfig.isTopFrame) { @@ -7753,9 +7948,9 @@ class AndroidInterface extends _InterfacePrototype.default { } /** - * Used by the email web app - * Provides functionality to log the user out - */ + * Used by the email web app + * Provides functionality to log the user out + */ removeUserData() { try { return window.EmailInterface.removeCredentials(); @@ -9024,14 +9219,16 @@ class InterfacePrototype { }); break; default: - // Also fire pixel when filling an identity with the personal duck address from an email field - const checks = [subtype === 'emailAddress', this.hasLocalAddresses, data?.emailAddress === (0, _autofillUtils.formatDuckAddress)(this.#addresses.personalAddress)]; - if (checks.every(Boolean)) { - this.firePixel({ - pixelName: 'autofill_personal_address' - }); + { + // Also fire pixel when filling an identity with the personal duck address from an email field + const checks = [subtype === 'emailAddress', this.hasLocalAddresses, data?.emailAddress === (0, _autofillUtils.formatDuckAddress)(this.#addresses.personalAddress)]; + if (checks.every(Boolean)) { + this.firePixel({ + pixelName: 'autofill_personal_address' + }); + } + break; } - break; } } // some platforms do not include a `success` object, why? @@ -9279,13 +9476,15 @@ class InterfacePrototype { postSubmit(values, form) { if (!form.form) return; if (!form.hasValues(values)) return; - const checks = [form.shouldPromptToStoreData && !form.submitHandlerExecuted, this.passwordGenerator.generated]; + const shouldTriggerPartialSave = Object.keys(values?.credentials || {}).length === 1 && Boolean(values?.credentials?.username) && this.settings.featureToggles.partial_form_saves; + const checks = [form.shouldPromptToStoreData && !form.submitHandlerExecuted, this.passwordGenerator.generated, shouldTriggerPartialSave]; if (checks.some(Boolean)) { const formData = (0, _Credentials.appendGeneratedKey)(values, { password: this.passwordGenerator.password, username: this.emailProtection.lastGenerated }); - this.storeFormData(formData, 'formSubmission'); + const trigger = shouldTriggerPartialSave ? 'partialSave' : 'formSubmission'; + this.storeFormData(formData, trigger); } } @@ -9706,6 +9905,7 @@ function initFormSubmissionsApi(forms, matching) { // @ts-ignore if (btns.find(btn => btn.contains(realTarget))) return true; + return false; }); matchingForm?.submitHandler('global pointerdown event + matching form'); if (!matchingForm) { @@ -9801,7 +10001,7 @@ function overlayApi(device) { * @returns {Promise} */ async selectedDetail(data, type) { - let detailsEntries = Object.entries(data).map(_ref => { + const detailsEntries = Object.entries(data).map(_ref => { let [key, value] = _ref; return [key, String(value)]; }); @@ -10064,7 +10264,7 @@ class Form { */ getValuesReadyForStorage() { const formValues = this.getRawValues(); - return (0, _formatters.prepareFormValuesForStorage)(formValues); + return (0, _formatters.prepareFormValuesForStorage)(formValues, this.device.settings.featureToggles.partial_form_saves); } /** @@ -10095,7 +10295,7 @@ class Form { if (!input.classList.contains('ddg-autofilled')) return; (0, _autofillUtils.removeInlineStyles)(input, (0, _inputStyles.getIconStylesAutofilled)(input, this)); (0, _autofillUtils.removeInlineStyles)(input, { - 'cursor': 'pointer' + cursor: 'pointer' }); input.classList.remove('ddg-autofilled'); this.addAutofillStyles(input); @@ -10216,20 +10416,10 @@ class Form { if (this.form.matches(selector)) { this.addInput(this.form); } else { - /** @type {Element[] | NodeList} */ - let foundInputs = []; - // Some sites seem to be overriding `form.elements`, so we need to check if it's still iterable. - if (this.form instanceof HTMLFormElement && this.form.elements != null && Symbol.iterator in Object(this.form.elements)) { - // For form elements we use .elements to catch fields outside the form itself using the form attribute. - // It also catches all elements when the markup is broken. - // We use .filter to avoid fieldset, button, textarea etc. - const formElements = [...this.form.elements].filter(el => el.matches(selector)); - // If there are no form elements, we try to look for all - // enclosed elements within the form. - foundInputs = formElements.length > 0 ? formElements : (0, _autofillUtils.findEnclosedElements)(this.form, selector); - } else { - foundInputs = this.form.querySelectorAll(selector); - } + // Attempt to get form's control elements first as it can catch elements when markup is broke, or if the fields are outside the form. + // Other wise use queryElementsWithShadow, that can scan for shadow tree. + const formControlElements = (0, _autofillUtils.getFormControlElements)(this.form, selector); + const foundInputs = formControlElements != null ? [...formControlElements, ...(0, _autofillUtils.findElementsInShadowTree)(this.form, selector)] : (0, _autofillUtils.queryElementsWithShadow)(this.form, selector, true); if (foundInputs.length < MAX_INPUTS_PER_FORM) { foundInputs.forEach(input => this.addInput(input)); } else { @@ -10290,7 +10480,7 @@ class Form { } get submitButtons() { const selector = this.matching.cssSelector('submitButtonSelector'); - const allButtons = /** @type {HTMLElement[]} */(0, _autofillUtils.findEnclosedElements)(this.form, selector); + const allButtons = /** @type {HTMLElement[]} */(0, _autofillUtils.queryElementsWithShadow)(this.form, selector); return allButtons.filter(btn => (0, _autofillUtils.isPotentiallyViewable)(btn) && (0, _autofillUtils.isLikelyASubmitButton)(btn, this.matching) && (0, _autofillUtils.buttonMatchesFormType)(btn, this)); } attemptSubmissionIfNeeded() { @@ -10413,12 +10603,12 @@ class Form { if ((0, _autofillUtils.wasAutofilledByChrome)(input)) return; if ((0, _autofillUtils.isEventWithinDax)(e, e.target)) { (0, _autofillUtils.addInlineStyles)(e.target, { - 'cursor': 'pointer', + cursor: 'pointer', ...onMouseMove }); } else { (0, _autofillUtils.removeInlineStyles)(e.target, { - 'cursor': 'pointer' + cursor: 'pointer' }); // Only overwrite active icon styles if tooltip is closed if (!this.device.isTooltipActive()) { @@ -10430,7 +10620,7 @@ class Form { }); this.addListener(input, 'mouseleave', e => { (0, _autofillUtils.removeInlineStyles)(e.target, { - 'cursor': 'pointer' + cursor: 'pointer' }); // Only overwrite active icon styles if tooltip is closed if (!this.device.isTooltipActive()) { @@ -10528,7 +10718,7 @@ class Form { this.touched.add(input); this.device.attachTooltip({ form: this, - input: input, + input, click: clickCoords, trigger: 'userInitiated', triggerMetaData: { @@ -10757,7 +10947,7 @@ class Form { }, 'credentials'); this.device.attachTooltip({ form: this, - input: input, + input, click: null, trigger: 'autoprompt', triggerMetaData: { @@ -10992,6 +11182,23 @@ class FormAnalyzer { } }); } + + /** + * Function that checks if the element is an external link or a custom web element that + * encapsulates a link. + * @param {any} el + * @returns {boolean} + */ + isElementExternalLink(el) { + // Checks if the element is present in the cusotm elements registry and ends with a '-link' suffix. + // If it does, it checks if it contains an anchor element inside. + const tagName = el.nodeName.toLowerCase(); + const isCustomWebElementLink = customElements?.get(tagName) != null && /-link$/.test(tagName) && (0, _autofillUtils.findElementsInShadowTree)(el, 'a').length > 0; + + // if an external link matches one of the regexes, we assume the match is not pertinent to the current form + const isElementLink = el instanceof HTMLAnchorElement && el.href && el.getAttribute('href') !== '#' || (el.getAttribute('role') || '').toUpperCase() === 'LINK' || el.matches('button[class*=secondary]'); + return isCustomWebElementLink || isElementLink; + } evaluateElement(el) { const string = (0, _autofillUtils.getTextShallow)(el); if (el.matches(this.matching.cssSelector('password'))) { @@ -11012,7 +11219,7 @@ class FormAnalyzer { if (likelyASubmit) { this.form.querySelectorAll('input[type=submit], button[type=submit]').forEach(submit => { // If there is another element marked as submit and this is not, flip back to false - if (el.type !== 'submit' && el !== submit) { + if (el.getAttribute('type') !== 'submit' && el !== submit) { likelyASubmit = false; } }); @@ -11031,8 +11238,7 @@ class FormAnalyzer { }); return; } - // if an external link matches one of the regexes, we assume the match is not pertinent to the current form - if (el instanceof HTMLAnchorElement && el.href && el.getAttribute('href') !== '#' || (el.getAttribute('role') || '').toUpperCase() === 'LINK' || el.matches('button[class*=secondary]')) { + if (this.isElementExternalLink(el)) { let shouldFlip = true; let strength = 1; // Don't flip forgotten password links @@ -11051,9 +11257,10 @@ class FormAnalyzer { }); } else { // any other case + const isH1Element = el.tagName === 'H1'; this.updateSignal({ string, - strength: 1, + strength: isH1Element ? 3 : 1, signalType: `generic: ${string}`, shouldCheckUnifiedForm: true }); @@ -11071,7 +11278,7 @@ class FormAnalyzer { // Check form contents (noisy elements are skipped with the safeUniversalSelector) const selector = this.matching.cssSelector('safeUniversalSelector'); - const formElements = (0, _autofillUtils.findEnclosedElements)(this.form, selector); + const formElements = (0, _autofillUtils.queryElementsWithShadow)(this.form, selector); for (let i = 0; i < formElements.length; i++) { // Safety cutoff to avoid huge DOMs freezing the browser if (i >= 200) break; @@ -11131,7 +11338,7 @@ class FormAnalyzer { } // Match form textContent against common cc fields (includes hidden labels) - const textMatches = formEl.textContent?.match(/(credit|payment).?card(.?number)?|ccv|security.?code|cvv|cvc|csc/ig); + const textMatches = formEl.textContent?.match(/(credit|payment).?card(.?number)?|ccv|security.?code|cvv|cvc|csc/gi); // De-dupe matches to avoid counting the same element more than once const deDupedMatches = new Set(textMatches?.map(match => match.toLowerCase())); @@ -11450,7 +11657,7 @@ const COUNTRY_NAMES_TO_CODES = exports.COUNTRY_NAMES_TO_CODES = { Anguilla: 'AI', Albania: 'AL', Armenia: 'AM', - 'Curaçao': 'CW', + Curaçao: 'CW', Angola: 'AO', Antarctica: 'AQ', Argentina: 'AR', @@ -11639,7 +11846,7 @@ const COUNTRY_NAMES_TO_CODES = exports.COUNTRY_NAMES_TO_CODES = { Paraguay: 'PY', Qatar: 'QA', 'Outlying Oceania': 'QO', - 'Réunion': 'RE', + Réunion: 'RE', Zimbabwe: 'ZW', Romania: 'RO', Russia: 'SU', @@ -11716,6 +11923,7 @@ Object.defineProperty(exports, "__esModule", { exports.prepareFormValuesForStorage = exports.inferCountryCodeFromElement = exports.getUnifiedExpiryDate = exports.getMMAndYYYYFromString = exports.getCountryName = exports.getCountryDisplayName = exports.formatPhoneNumber = exports.formatFullName = exports.formatCCYear = void 0; var _matching = require("./matching.js"); var _countryNames = require("./countryNames.js"); +var _autofillUtils = require("../autofill-utils.js"); // Matches strings like mm/yy, mm-yyyy, mm-aa, 12 / 2024 const DATE_SEPARATOR_REGEX = /\b((.)\2{1,3}|\d+)(?\s?[/\s.\-_—–]\s?)((.)\5{1,3}|\d+)\b/i; // Matches 4 non-digit repeated characters (YYYY or AAAA) or 4 digits (2022) @@ -11884,36 +12092,25 @@ const getMMAndYYYYFromString = expiration => { }; /** - * @param {InternalDataStorageObject} credentials + * @param {InternalDataStorageObject} data * @return {boolean} */ exports.getMMAndYYYYFromString = getMMAndYYYYFromString; -const shouldStoreCredentials = _ref3 => { - let { - credentials - } = _ref3; - return Boolean(credentials.password); -}; - -/** - * @param {InternalDataStorageObject} credentials - * @return {boolean} - */ -const shouldStoreIdentities = _ref4 => { +const shouldStoreIdentities = _ref3 => { let { identities - } = _ref4; + } = _ref3; return Boolean((identities.firstName || identities.fullName) && identities.addressStreet && identities.addressCity); }; /** - * @param {InternalDataStorageObject} credentials + * @param {InternalDataStorageObject} data * @return {boolean} */ -const shouldStoreCreditCards = _ref5 => { +const shouldStoreCreditCards = _ref4 => { let { creditCards - } = _ref5; + } = _ref4; if (!creditCards.cardNumber) return false; if (creditCards.cardSecurityCode) return true; // Some forms (Amazon) don't have the cvv, so we still save if there's the expiration @@ -11936,7 +12133,8 @@ const formatPhoneNumber = phone => phone.replaceAll(/[^0-9|+]/g, ''); * @return {DataStorageObject} */ exports.formatPhoneNumber = formatPhoneNumber; -const prepareFormValuesForStorage = formValues => { +const prepareFormValuesForStorage = function (formValues) { + let canTriggerPartialSave = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; /** @type {Partial} */ let { credentials, @@ -11949,14 +12147,15 @@ const prepareFormValuesForStorage = formValues => { creditCards.cardName = identities?.fullName || formatFullName(identities); } - /** Fixes for credentials **/ - // Don't store if there isn't enough data - if (shouldStoreCredentials(formValues)) { - // If we don't have a username to match a password, let's see if the email is available - if (credentials.password && !credentials.username && identities.emailAddress) { - credentials.username = identities.emailAddress; - } - } else { + /** Fixes for credentials */ + // If we don't have a username to match a password, let's see if email or phone are available + if (credentials.password && !credentials.username && (0, _autofillUtils.hasUsernameLikeIdentity)(identities)) { + // @ts-ignore - username will be likely undefined, but needs to be specifically assigned to a string value + credentials.username = identities.emailAddress || identities.phone; + } + + // If there's no password, and we shouldn't trigger a partial save, let's discard the object + if (!credentials.password && !canTriggerPartialSave) { credentials = undefined; } @@ -12012,7 +12211,7 @@ const prepareFormValuesForStorage = formValues => { }; exports.prepareFormValuesForStorage = prepareFormValuesForStorage; -},{"./countryNames.js":36,"./matching.js":44}],38:[function(require,module,exports){ +},{"../autofill-utils.js":64,"./countryNames.js":36,"./matching.js":44}],38:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -12055,7 +12254,7 @@ const getBasicStyles = (input, icon) => ({ 'background-repeat': 'no-repeat', 'background-origin': 'content-box', 'background-image': `url(${icon})`, - 'transition': 'background 0s' + transition: 'background 0s' }); /** @@ -12098,7 +12297,7 @@ const getIconStylesAutofilled = (input, form) => { return { ...iconStyle, 'background-color': '#F8F498', - 'color': '#333333' + color: '#333333' }; }; exports.getIconStylesAutofilled = getIconStylesAutofilled; @@ -12386,14 +12585,14 @@ const extractElementStrings = element => { // only take the string when it's an explicit text node if (el.nodeType === el.TEXT_NODE || !el.childNodes.length) { - let trimmedText = (0, _matching.removeExcessWhitespace)(el.textContent); + const trimmedText = (0, _matching.removeExcessWhitespace)(el.textContent); if (trimmedText) { strings.add(trimmedText); } return; } - for (let node of el.childNodes) { - let nodeType = node.nodeType; + for (const node of el.childNodes) { + const nodeType = node.nodeType; if (nodeType !== node.ELEMENT_NODE && nodeType !== node.TEXT_NODE) { continue; } @@ -12795,7 +12994,7 @@ const matchingConfiguration = exports.matchingConfiguration = { match: /sign.?up|join|register|enroll|(create|new).+account|newsletter|subscri(be|ption)|settings|preferences|profile|update|iscri(viti|zione)|registra(ti|zione)|(?:nuovo|crea(?:zione)?) account|contatt(?:ac)?i|sottoscriv|sottoscrizione|impostazioni|preferenze|aggiorna|anmeld(en|ung)|registrier(en|ung)|neukunde|neuer (kunde|benutzer|nutzer)|registreren|eigenschappen|profiel|bijwerken|s.inscrire|inscription|s.abonner|abonnement|préférences|profil|créer un compte|regis(trarse|tro)|regístrate|inscr(ibirse|ipción|íbete)|crea(r cuenta)?|nueva cuenta|nuevo (cliente|usuario)|preferencias|perfil|lista de correo|registrer(a|ing)|(nytt|öppna) konto|nyhetsbrev|prenumer(era|ation)|kontakt|skapa|starta|inställningar|min (sida|kundvagn)|uppdatera/iu }, resetPasswordLink: { - match: /(forgot(ten)?|reset|don't remember) (your )?password|password forgotten|password dimenticata|reset(?:ta) password|recuper[ao] password|(vergessen|verloren|verlegt|wiederherstellen) passwort|wachtwoord (vergeten|reset)|(oublié|récupérer) ((mon|ton|votre|le) )?mot de passe|mot de passe (oublié|perdu)|re(iniciar|cuperar) (contraseña|clave)|olvid(ó su|aste tu|é mi) (contraseña|clave)|recordar( su)? (contraseña|clave)|glömt lösenord|återställ lösenord/iu + match: /(forgot(ten)?|reset|don't remember).?(your )?password|password forgotten|password dimenticata|reset(?:ta) password|recuper[ao] password|(vergessen|verloren|verlegt|wiederherstellen) passwort|wachtwoord (vergeten|reset)|(oublié|récupérer) ((mon|ton|votre|le) )?mot de passe|mot de passe (oublié|perdu)|re(iniciar|cuperar) (contraseña|clave)|olvid(ó su|aste tu|é mi) (contraseña|clave)|recordar( su)? (contraseña|clave)|glömt lösenord|återställ lösenord/iu }, loginProvidersRegex: { match: / with | con | mit | met | avec /iu @@ -13060,8 +13259,8 @@ class Matching { * * `email: [{type: "email", strategies: {cssSelector: "email", ... etc}]` */ - for (let [listName, matcherNames] of Object.entries(this.#config.matchers.lists)) { - for (let fieldName of matcherNames) { + for (const [listName, matcherNames] of Object.entries(this.#config.matchers.lists)) { + for (const fieldName of matcherNames) { if (!this.#matcherLists[listName]) { this.#matcherLists[listName] = []; } @@ -13178,7 +13377,7 @@ class Matching { * @type {string[]} */ const selectors = []; - for (let matcher of matcherList) { + for (const matcher of matcherList) { if (matcher.strategies.cssSelector) { const css = this.cssSelector(matcher.strategies.cssSelector); if (css) { @@ -13315,12 +13514,12 @@ class Matching { /** * Loop through each strategy in order */ - for (let strategyName of this.#defaultStrategyOrder) { + for (const strategyName of this.#defaultStrategyOrder) { let result; /** * Now loop through each matcher in the list. */ - for (let matcher of matchers) { + for (const matcher of matchers) { /** * for each `strategyName` (such as cssSelector), check * if the current matcher implements it. @@ -13445,16 +13644,16 @@ class Matching { if (!ddgMatcher || !ddgMatcher.match) { return defaultResult; } - let matchRexExp = this.getDDGMatcherRegex(lookup); + const matchRexExp = this.getDDGMatcherRegex(lookup); if (!matchRexExp) { return defaultResult; } - let requiredScore = ['match', 'forceUnknown', 'maxDigits'].filter(ddgMatcherProp => ddgMatcherProp in ddgMatcher).length; + const requiredScore = ['match', 'forceUnknown', 'maxDigits'].filter(ddgMatcherProp => ddgMatcherProp in ddgMatcher).length; /** @type {MatchableStrings[]} */ const matchableStrings = ddgMatcher.matchableStrings || ['labelText', 'placeholderAttr', 'relatedText']; - for (let stringName of matchableStrings) { - let elementString = this.activeElementStrings[stringName]; + for (const stringName of matchableStrings) { + const elementString = this.activeElementStrings[stringName]; if (!elementString) continue; // Scoring to ensure all DDG tests are valid @@ -13470,7 +13669,7 @@ class Matching { // If a negated regex was provided, ensure it does not match // If it DOES match - then we need to prevent any future strategies from continuing if (ddgMatcher.forceUnknown) { - let notRegex = ddgMatcher.forceUnknown; + const notRegex = ddgMatcher.forceUnknown; if (!notRegex) { return { ...result, @@ -13489,7 +13688,7 @@ class Matching { } } if (ddgMatcher.skip) { - let skipRegex = ddgMatcher.skip; + const skipRegex = ddgMatcher.skip; if (!skipRegex) { return { ...result, @@ -13554,8 +13753,8 @@ class Matching { } /** @type {MatchableStrings[]} */ const stringsToMatch = ['placeholderAttr', 'nameAttr', 'labelText', 'id', 'relatedText']; - for (let stringName of stringsToMatch) { - let elementString = this.activeElementStrings[stringName]; + for (const stringName of stringsToMatch) { + const elementString = this.activeElementStrings[stringName]; if (!elementString) continue; if ((0, _autofillUtils.safeRegexTest)(regex, elementString)) { return { @@ -13629,14 +13828,14 @@ class Matching { fields: {} }, strategies: { - 'vendorRegex': { + vendorRegex: { rules: {}, ruleSets: [] }, - 'ddgMatcher': { + ddgMatcher: { matchers: {} }, - 'cssSelector': { + cssSelector: { selectors: {} } } @@ -13807,7 +14006,7 @@ const removeExcessWhitespace = function () { exports.removeExcessWhitespace = removeExcessWhitespace; const getExplicitLabelsText = el => { const labelTextCandidates = []; - for (let label of el.labels || []) { + for (const label of el.labels || []) { labelTextCandidates.push(...(0, _labelUtil.extractElementStrings)(label)); } if (el.hasAttribute('aria-label')) { @@ -13862,7 +14061,7 @@ const getRelatedText = (el, form, cssSelector) => { // If we didn't find a container, try looking for an adjacent label if (scope === el) { - let previousEl = recursiveGetPreviousElSibling(el); + const previousEl = recursiveGetPreviousElSibling(el); if (previousEl instanceof HTMLElement) { scope = previousEl; } @@ -14521,19 +14720,18 @@ class DefaultScanner { if (this.device.globalConfig.isDDGDomain) { return this; } - if ('matches' in context && context.matches?.(this.matching.cssSelector('formInputsSelectorWithoutSelect'))) { + const formInputsSelectorWithoutSelect = this.matching.cssSelector('formInputsSelectorWithoutSelect'); + if ('matches' in context && context.matches?.(formInputsSelectorWithoutSelect)) { this.addInput(context); } else { - const selector = this.matching.cssSelector('formInputsSelectorWithoutSelect'); - const inputs = context.querySelectorAll(selector); + const inputs = context.querySelectorAll(formInputsSelectorWithoutSelect); if (inputs.length > this.options.maxInputsPerPage) { this.setMode('stopped', `Too many input fields in the given context (${inputs.length}), stop scanning`, context); return this; } inputs.forEach(input => this.addInput(input)); if (context instanceof HTMLFormElement && this.forms.get(context)?.hasShadowTree) { - const selector = this.matching.cssSelector('formInputsSelectorWithoutSelect'); - (0, _autofillUtils.findEnclosedElements)(context, selector).forEach(input => { + (0, _autofillUtils.findElementsInShadowTree)(context, formInputsSelectorWithoutSelect).forEach(input => { if (input instanceof HTMLInputElement) { this.addInput(input, context); } @@ -14619,12 +14817,16 @@ class DefaultScanner { } if (element.parentElement) { element = element.parentElement; - const inputs = element.querySelectorAll(this.matching.cssSelector('formInputsSelector')); - const buttons = element.querySelectorAll(this.matching.cssSelector('submitButtonSelector')); - // If we find a button or another input, we assume that's our form - if (inputs.length > 1 || buttons.length) { - // found related input, return common ancestor - return element; + // If the parent is a redundant component (only contains a single element or is a shadowRoot) do not increase the traversal count. + if (element.childElementCount > 1) { + const inputs = element.querySelectorAll(this.matching.cssSelector('formInputsSelector')); + const buttons = element.querySelectorAll(this.matching.cssSelector('submitButtonSelector')); + // If we find a button or another input, we assume that's our form + if (inputs.length > 1 || buttons.length) { + // found related input, return common ancestor + return element; + } + traversalLayerCount++; } } else { // possibly a shadow boundary, so traverse through the shadow root and find the form @@ -14632,9 +14834,11 @@ class DefaultScanner { if (root instanceof ShadowRoot && root.host) { // @ts-ignore element = root.host; + } else { + // We're in a strange state (no parent or shadow root), just break out of the loop for safety + break; } } - traversalLayerCount++; } return input; } @@ -14717,7 +14921,7 @@ class DefaultScanner { this.changedElements.clear(); } else if (!this.rescanAll) { // otherwise keep adding each element to the queue - for (let element of htmlElements) { + for (const element of htmlElements) { this.changedElements.add(element); } } @@ -14741,7 +14945,7 @@ class DefaultScanner { this.findEligibleInputs(document); return; } - for (let element of this.changedElements) { + for (const element of this.changedElements) { if (element.isConnected) { this.findEligibleInputs(element); } @@ -14762,7 +14966,7 @@ class DefaultScanner { const outgoing = []; for (const mutationRecord of mutationList) { if (mutationRecord.type === 'childList') { - for (let addedNode of mutationRecord.addedNodes) { + for (const addedNode of mutationRecord.addedNodes) { if (!(addedNode instanceof HTMLElement)) continue; if (addedNode.nodeName === 'DDG-AUTOFILL') continue; outgoing.push(addedNode); @@ -14796,12 +15000,13 @@ class DefaultScanner { // find the enclosing parent form, and scan it. if (realTarget instanceof HTMLInputElement && !realTarget.hasAttribute(ATTR_INPUT_TYPE)) { const parentForm = this.getParentForm(realTarget); - if (parentForm && parentForm instanceof HTMLFormElement) { - const hasShadowTree = event.target?.shadowRoot != null; - const form = new _Form.Form(parentForm, realTarget, this.device, this.matching, this.shouldAutoprompt, hasShadowTree); - this.forms.set(parentForm, form); - this.findEligibleInputs(parentForm); - } + + // If the parent form is an input element we bail. + if (parentForm instanceof HTMLInputElement) return; + const hasShadowTree = event.target?.shadowRoot != null; + const form = new _Form.Form(parentForm, realTarget, this.device, this.matching, this.shouldAutoprompt, hasShadowTree); + this.forms.set(parentForm, form); + this.findEligibleInputs(parentForm); } window.performance?.mark?.('scan_shadow:init:end'); (0, _autofillUtils.logPerformance)('scan_shadow'); @@ -15176,7 +15381,8 @@ class Settings { inputType_credentials: false, inputType_creditCards: false, inlineIcon_credentials: false, - unknown_username_categorization: false + unknown_username_categorization: false, + partial_form_saves: false }, /** @type {AvailableInputTypes} */ availableInputTypes: { @@ -15500,7 +15706,7 @@ ${css} if (btn.matches('.wrapper:not(.top-autofill) button:hover, .currentFocus')) { callbacks.onSelect(btn.id); } else { - console.warn('The button doesn\'t seem to be hovered. Please check.'); + console.warn("The button doesn't seem to be hovered. Please check."); } }); }); @@ -15704,7 +15910,9 @@ const defaultOptions = exports.defaultOptions = { }`, css: ``, setSize: undefined, - remove: () => {/** noop */}, + remove: () => { + /** noop */ + }, testMode: false, checkVisibility: true, hasCaret: false, @@ -15732,9 +15940,9 @@ class HTMLTooltip { this.tooltip = null; this.getPosition = getPosition; const forcedVisibilityStyles = { - 'display': 'block', - 'visibility': 'visible', - 'opacity': '1' + display: 'block', + visibility: 'visible', + opacity: '1' }; // @ts-ignore how to narrow this.host to HTMLElement? (0, _autofillUtils.addInlineStyles)(this.host, forcedVisibilityStyles); @@ -15992,7 +16200,7 @@ class HTMLTooltip { checkVisibility: this.options.checkVisibility }); } else { - console.warn('The button doesn\'t seem to be hovered. Please check.'); + console.warn("The button doesn't seem to be hovered. Please check."); } } } @@ -16374,25 +16582,27 @@ class HTMLTooltipUIController extends _UIController.UIController { /** * Called when clicking on the Manage… button in the html tooltip - * * @param {SupportedMainTypes} type * @returns {*} * @private */ _onManage(type) { - this.removeTooltip(); switch (type) { case 'credentials': - return this._options.device.openManagePasswords(); + this._options.device.openManagePasswords(); + break; case 'creditCards': - return this._options.device.openManageCreditCards(); + this._options.device.openManageCreditCards(); + break; case 'identities': - return this._options.device.openManageIdentities(); + this._options.device.openManageIdentities(); + break; default: // noop } - } + this.removeTooltip(); + } _onIncontextSignupDismissed(_ref) { let { hasOtherOptions @@ -16936,10 +17146,14 @@ Object.defineProperty(exports, "__esModule", { }); exports.buttonMatchesFormType = exports.autofillEnabled = exports.addInlineStyles = exports.SIGN_IN_MSG = exports.ADDRESS_DOMAIN = void 0; exports.escapeXML = escapeXML; -exports.findEnclosedElements = findEnclosedElements; +exports.findElementsInShadowTree = findElementsInShadowTree; exports.formatDuckAddress = void 0; exports.getActiveElement = getActiveElement; -exports.isEventWithinDax = exports.isAutofillEnabledFromProcessedConfig = exports.getTextShallow = exports.getDaxBoundingBox = void 0; +exports.getDaxBoundingBox = void 0; +exports.getFormControlElements = getFormControlElements; +exports.getTextShallow = void 0; +exports.hasUsernameLikeIdentity = hasUsernameLikeIdentity; +exports.isEventWithinDax = exports.isAutofillEnabledFromProcessedConfig = void 0; exports.isFormLikelyToBeUsedAsPageWrapper = isFormLikelyToBeUsedAsPageWrapper; exports.isLikelyASubmitButton = exports.isIncontextSignupEnabledFromProcessedConfig = void 0; exports.isLocalNetwork = isLocalNetwork; @@ -16948,6 +17162,7 @@ exports.isValidTLD = isValidTLD; exports.logPerformance = logPerformance; exports.notifyWebApp = void 0; exports.pierceShadowTree = pierceShadowTree; +exports.queryElementsWithShadow = queryElementsWithShadow; exports.safeExecute = exports.removeInlineStyles = void 0; exports.safeRegexTest = safeRegexTest; exports.setValue = exports.sendAndWaitForAnswer = void 0; @@ -17320,8 +17535,9 @@ const isLikelyASubmitButton = (el, matching) => { // has high-signal submit classes safeRegexTest(/submit/i, dataTestId) || safeRegexTest(matching.getDDGMatcherRegex('submitButtonRegex'), text) || // has high-signal text - el.offsetHeight * el.offsetWidth >= 10000 && !safeRegexTest(/secondary/i, el.className) // it's a large element 250x40px - ) && el.offsetHeight * el.offsetWidth >= 2000 && + el.offsetHeight * el.offsetWidth >= 10000 && !safeRegexTest(/secondary/i, el.className)) && + // it's a large element 250x40px + el.offsetHeight * el.offsetWidth >= 2000 && // it's not a very small button like inline links and such !safeRegexTest(matching.getDDGMatcherRegex('submitButtonUnlikelyRegex'), text + ' ' + ariaLabel); }; @@ -17549,22 +17765,16 @@ function getActiveElement() { } /** - * Takes a root element and tries to find visible elements first, and if it fails, it tries to find shadow elements + * Takes a root element and tries to find elements in shadow DOMs that match the selector * @param {HTMLElement|HTMLFormElement} root * @param {string} selector * @returns {Element[]} */ -function findEnclosedElements(root, selector) { - // Check if there are any normal elements that match the selector - const elements = root.querySelectorAll(selector); - if (elements.length > 0) { - return Array.from(elements); - } - - // Check if there are any shadow elements that match the selector +function findElementsInShadowTree(root, selector) { const shadowElements = []; const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT); - let node = walker.nextNode(); + /** @type {Node|null} */ + let node = walker.currentNode; while (node) { if (node instanceof HTMLElement && node.shadowRoot) { shadowElements.push(...node.shadowRoot.querySelectorAll(selector)); @@ -17574,6 +17784,52 @@ function findEnclosedElements(root, selector) { return shadowElements; } +/** + * The function looks for form's control elements, and returns them if they're iterable. + * @param {HTMLElement} form + * @param {string} selector + * @returns {Element[]|null} + */ +function getFormControlElements(form, selector) { + // Some sites seem to be overriding `form.elements`, so we need to check if it's still iterable. + if (form instanceof HTMLFormElement && form.elements != null && Symbol.iterator in Object(form.elements)) { + // For form elements we use .elements to catch fields outside the form itself using the form attribute. + // It also catches all elements when the markup is broken. + // We use .filter to avoid specific types of elements. + const formControls = [...form.elements].filter(el => el.matches(selector)); + return [...formControls]; + } else { + return null; + } +} + +/** + * Default operation: finds elements using querySelectorAll. + * Optionally, can be forced to scan the shadow tree. + * @param {HTMLElement} element + * @param {string} selector + * @param {boolean} forceScanShadowTree + * @returns {Element[]} + */ +function queryElementsWithShadow(element, selector) { + let forceScanShadowTree = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + /** @type {Element[]|NodeListOf} element */ + const elements = element.querySelectorAll(selector); + if (forceScanShadowTree || elements.length === 0) { + return [...elements, ...findElementsInShadowTree(element, selector)]; + } + return [...elements]; +} + +/** + * Checks if there is a single username-like identity, i.e. email or phone + * @param {InternalIdentityObject} identities + * @returns {boolean} + */ +function hasUsernameLikeIdentity(identities) { + return Object.keys(identities ?? {}).length === 1 && Boolean(identities?.emailAddress || identities.phone); +} + },{"./Form/matching.js":44,"./constants.js":67,"@duckduckgo/content-scope-scripts/src/apple-utils":1}],65:[function(require,module,exports){ "use strict"; @@ -17613,7 +17869,8 @@ Object.defineProperty(exports, "__esModule", { }); exports.DDG_DOMAIN_REGEX = void 0; exports.createGlobalConfig = createGlobalConfig; -const DDG_DOMAIN_REGEX = exports.DDG_DOMAIN_REGEX = new RegExp(/^https:\/\/(([a-z0-9-_]+?)\.)?duckduckgo\.com\/email/); +/* eslint-disable prefer-const */ +const DDG_DOMAIN_REGEX = exports.DDG_DOMAIN_REGEX = /^https:\/\/(([a-z0-9-_]+?)\.)?duckduckgo\.com\/email/; /** * This is a centralised place to contain all string/variable replacements @@ -18124,6 +18381,26 @@ const availableInputTypesSchema = exports.availableInputTypesSchema = _zod.z.obj credentialsProviderStatus: _zod.z.union([_zod.z.literal("locked"), _zod.z.literal("unlocked")]).optional(), credentialsImport: _zod.z.boolean().optional() }); +const getAutofillInitDataResponseSchema = exports.getAutofillInitDataResponseSchema = _zod.z.object({ + type: _zod.z.literal("getAutofillInitDataResponse").optional(), + success: _zod.z.object({ + credentials: _zod.z.array(credentialsSchema), + identities: _zod.z.array(_zod.z.record(_zod.z.unknown())), + creditCards: _zod.z.array(_zod.z.record(_zod.z.unknown())), + serializedInputContext: _zod.z.string() + }).optional(), + error: genericErrorSchema.optional() +}); +const getAutofillCredentialsResultSchema = exports.getAutofillCredentialsResultSchema = _zod.z.object({ + type: _zod.z.literal("getAutofillCredentialsResponse").optional(), + success: _zod.z.object({ + id: _zod.z.string().optional(), + autogenerated: _zod.z.boolean().optional(), + username: _zod.z.string(), + password: _zod.z.string().optional() + }).optional(), + error: genericErrorSchema.optional() +}); const availableInputTypes1Schema = exports.availableInputTypes1Schema = _zod.z.object({ credentials: _zod.z.object({ username: _zod.z.boolean().optional(), @@ -18156,6 +18433,11 @@ const availableInputTypes1Schema = exports.availableInputTypes1Schema = _zod.z.o credentialsProviderStatus: _zod.z.union([_zod.z.literal("locked"), _zod.z.literal("unlocked")]).optional(), credentialsImport: _zod.z.boolean().optional() }); +const providerStatusUpdatedSchema = exports.providerStatusUpdatedSchema = _zod.z.object({ + status: _zod.z.union([_zod.z.literal("locked"), _zod.z.literal("unlocked")]), + credentials: _zod.z.array(credentialsSchema), + availableInputTypes: availableInputTypes1Schema +}); const autofillFeatureTogglesSchema = exports.autofillFeatureTogglesSchema = _zod.z.object({ inputType_credentials: _zod.z.boolean().optional(), inputType_identities: _zod.z.boolean().optional(), @@ -18166,56 +18448,8 @@ const autofillFeatureTogglesSchema = exports.autofillFeatureTogglesSchema = _zod credentials_saving: _zod.z.boolean().optional(), inlineIcon_credentials: _zod.z.boolean().optional(), third_party_credentials_provider: _zod.z.boolean().optional(), - unknown_username_categorization: _zod.z.boolean().optional() -}); -const getAutofillDataRequestSchema = exports.getAutofillDataRequestSchema = _zod.z.object({ - generatedPassword: generatedPasswordSchema.optional(), - inputType: _zod.z.string(), - mainType: _zod.z.union([_zod.z.literal("credentials"), _zod.z.literal("identities"), _zod.z.literal("creditCards")]), - subType: _zod.z.string(), - trigger: _zod.z.union([_zod.z.literal("userInitiated"), _zod.z.literal("autoprompt"), _zod.z.literal("postSignup")]).optional(), - serializedInputContext: _zod.z.string().optional(), - triggerContext: triggerContextSchema.optional() -}); -const getAutofillDataResponseSchema = exports.getAutofillDataResponseSchema = _zod.z.object({ - type: _zod.z.literal("getAutofillDataResponse").optional(), - success: _zod.z.object({ - credentials: credentialsSchema.optional(), - action: _zod.z.union([_zod.z.literal("fill"), _zod.z.literal("focus"), _zod.z.literal("none"), _zod.z.literal("refreshAvailableInputTypes"), _zod.z.literal("acceptGeneratedPassword"), _zod.z.literal("rejectGeneratedPassword")]) - }).optional(), - error: genericErrorSchema.optional() -}); -const storeFormDataSchema = exports.storeFormDataSchema = _zod.z.object({ - credentials: outgoingCredentialsSchema.optional(), - trigger: _zod.z.union([_zod.z.literal("formSubmission"), _zod.z.literal("passwordGeneration"), _zod.z.literal("emailProtection")]).optional() -}); -const getAvailableInputTypesResultSchema = exports.getAvailableInputTypesResultSchema = _zod.z.object({ - type: _zod.z.literal("getAvailableInputTypesResponse").optional(), - success: availableInputTypesSchema, - error: genericErrorSchema.optional() -}); -const getAutofillInitDataResponseSchema = exports.getAutofillInitDataResponseSchema = _zod.z.object({ - type: _zod.z.literal("getAutofillInitDataResponse").optional(), - success: _zod.z.object({ - credentials: _zod.z.array(credentialsSchema), - identities: _zod.z.array(_zod.z.record(_zod.z.unknown())), - creditCards: _zod.z.array(_zod.z.record(_zod.z.unknown())), - serializedInputContext: _zod.z.string() - }).optional(), - error: genericErrorSchema.optional() -}); -const getAutofillCredentialsResultSchema = exports.getAutofillCredentialsResultSchema = _zod.z.object({ - type: _zod.z.literal("getAutofillCredentialsResponse").optional(), - success: _zod.z.object({ - id: _zod.z.string().optional(), - autogenerated: _zod.z.boolean().optional(), - username: _zod.z.string(), - password: _zod.z.string().optional() - }).optional(), - error: genericErrorSchema.optional() -}); -const autofillSettingsSchema = exports.autofillSettingsSchema = _zod.z.object({ - featureToggles: autofillFeatureTogglesSchema + unknown_username_categorization: _zod.z.boolean().optional(), + partial_form_saves: _zod.z.boolean().optional() }); const emailProtectionGetIsLoggedInResultSchema = exports.emailProtectionGetIsLoggedInResultSchema = _zod.z.object({ success: _zod.z.boolean().optional(), @@ -18251,19 +18485,30 @@ const emailProtectionRefreshPrivateAddressResultSchema = exports.emailProtection }).optional(), error: genericErrorSchema.optional() }); -const runtimeConfigurationSchema = exports.runtimeConfigurationSchema = _zod.z.object({ - contentScope: contentScopeSchema, - userUnprotectedDomains: _zod.z.array(_zod.z.string()), - userPreferences: userPreferencesSchema +const getAutofillDataRequestSchema = exports.getAutofillDataRequestSchema = _zod.z.object({ + generatedPassword: generatedPasswordSchema.optional(), + inputType: _zod.z.string(), + mainType: _zod.z.union([_zod.z.literal("credentials"), _zod.z.literal("identities"), _zod.z.literal("creditCards")]), + subType: _zod.z.string(), + trigger: _zod.z.union([_zod.z.literal("userInitiated"), _zod.z.literal("autoprompt"), _zod.z.literal("postSignup")]).optional(), + serializedInputContext: _zod.z.string().optional(), + triggerContext: triggerContextSchema.optional() }); -const providerStatusUpdatedSchema = exports.providerStatusUpdatedSchema = _zod.z.object({ - status: _zod.z.union([_zod.z.literal("locked"), _zod.z.literal("unlocked")]), - credentials: _zod.z.array(credentialsSchema), - availableInputTypes: availableInputTypes1Schema +const getAutofillDataResponseSchema = exports.getAutofillDataResponseSchema = _zod.z.object({ + type: _zod.z.literal("getAutofillDataResponse").optional(), + success: _zod.z.object({ + credentials: credentialsSchema.optional(), + action: _zod.z.union([_zod.z.literal("fill"), _zod.z.literal("focus"), _zod.z.literal("none"), _zod.z.literal("refreshAvailableInputTypes"), _zod.z.literal("acceptGeneratedPassword"), _zod.z.literal("rejectGeneratedPassword")]) + }).optional(), + error: genericErrorSchema.optional() }); -const getRuntimeConfigurationResponseSchema = exports.getRuntimeConfigurationResponseSchema = _zod.z.object({ - type: _zod.z.literal("getRuntimeConfigurationResponse").optional(), - success: runtimeConfigurationSchema.optional(), +const storeFormDataSchema = exports.storeFormDataSchema = _zod.z.object({ + credentials: outgoingCredentialsSchema.optional(), + trigger: _zod.z.union([_zod.z.literal("partialSave"), _zod.z.literal("formSubmission"), _zod.z.literal("passwordGeneration"), _zod.z.literal("emailProtection")]).optional() +}); +const getAvailableInputTypesResultSchema = exports.getAvailableInputTypesResultSchema = _zod.z.object({ + type: _zod.z.literal("getAvailableInputTypesResponse").optional(), + success: availableInputTypesSchema, error: genericErrorSchema.optional() }); const askToUnlockProviderResultSchema = exports.askToUnlockProviderResultSchema = _zod.z.object({ @@ -18276,6 +18521,19 @@ const checkCredentialsProviderStatusResultSchema = exports.checkCredentialsProvi success: providerStatusUpdatedSchema, error: genericErrorSchema.optional() }); +const autofillSettingsSchema = exports.autofillSettingsSchema = _zod.z.object({ + featureToggles: autofillFeatureTogglesSchema +}); +const runtimeConfigurationSchema = exports.runtimeConfigurationSchema = _zod.z.object({ + contentScope: contentScopeSchema, + userUnprotectedDomains: _zod.z.array(_zod.z.string()), + userPreferences: userPreferencesSchema +}); +const getRuntimeConfigurationResponseSchema = exports.getRuntimeConfigurationResponseSchema = _zod.z.object({ + type: _zod.z.literal("getRuntimeConfigurationResponse").optional(), + success: runtimeConfigurationSchema.optional(), + error: genericErrorSchema.optional() +}); const apiSchema = exports.apiSchema = _zod.z.object({ addDebugFlag: _zod.z.record(_zod.z.unknown()).and(_zod.z.object({ paramsValidator: addDebugFlagParamsSchema.optional() @@ -18492,7 +18750,7 @@ function waitForResponse(expectedResponse, config) { return; } try { - let data = JSON.parse(e.data); + const data = JSON.parse(e.data); if (data.type === expectedResponse) { window.removeEventListener('message', handler); return resolve(data); @@ -18647,7 +18905,7 @@ async function extensionSpecificRuntimeConfiguration(deviceApi) { return { success: { // @ts-ignore - contentScope: contentScope, + contentScope, // @ts-ignore userPreferences: { // Copy locale to user preferences as 'language' to match expected payload @@ -18841,6 +19099,7 @@ function waitForWindowsResponse(responseId, options) { if (options?.signal?.aborted) { return reject(new DOMException('Aborted', 'AbortError')); } + // eslint-disable-next-line prefer-const let teardown; // The event handler @@ -21727,7 +21986,6 @@ exports.default = void 0; window.requestIdleCallback = window.requestIdleCallback || function (cb) { return setTimeout(function () { const start = Date.now(); - // eslint-disable-next-line standard/no-callback-literal cb({ didTimeout: false, timeRemaining: function () { diff --git a/node_modules/@duckduckgo/autofill/dist/autofill.js b/node_modules/@duckduckgo/autofill/dist/autofill.js index 6a97e06c86fa..c4584483dadf 100644 --- a/node_modules/@duckduckgo/autofill/dist/autofill.js +++ b/node_modules/@duckduckgo/autofill/dist/autofill.js @@ -269,8 +269,8 @@ class SchemaValidationError extends Error { } case 'invalid_union': { - for (let unionError of issue.unionErrors) { - for (let issue1 of unionError.issues) { + for (const unionError of issue.unionErrors) { + for (const issue1 of unionError.issues) { log(issue1); } } @@ -282,7 +282,7 @@ class SchemaValidationError extends Error { } } } - for (let error of errors) { + for (const error of errors) { log(error); } const message = [heading, 'please see the details above'].join('\n '); @@ -405,8 +405,8 @@ class DeviceApi { */ async request(deviceApiCall, options) { deviceApiCall.validateParams(); - let result = await this.transport.send(deviceApiCall, options); - let processed = deviceApiCall.preResultValidation(result); + const result = await this.transport.send(deviceApiCall, options); + const processed = deviceApiCall.preResultValidation(result); return deviceApiCall.validateResult(processed); } /** @@ -494,44 +494,44 @@ var _webkit = require("./webkit.js"); */ class Messaging { /** - * @param {WebkitMessagingConfig} config - */ + * @param {WebkitMessagingConfig} config + */ constructor(config) { this.transport = getTransport(config); } /** - * Send a 'fire-and-forget' message. - * @throws {Error} - * {@link MissingHandler} - * - * @example - * - * ``` - * const messaging = new Messaging(config) - * messaging.notify("foo", {bar: "baz"}) - * ``` - * @param {string} name - * @param {Record} [data] - */ + * Send a 'fire-and-forget' message. + * @throws {Error} + * {@link MissingHandler} + * + * @example + * + * ``` + * const messaging = new Messaging(config) + * messaging.notify("foo", {bar: "baz"}) + * ``` + * @param {string} name + * @param {Record} [data] + */ notify(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; this.transport.notify(name, data); } /** - * Send a request, and wait for a response - * @throws {Error} - * {@link MissingHandler} - * - * @example - * ``` - * const messaging = new Messaging(config) - * const response = await messaging.request("foo", {bar: "baz"}) - * ``` - * - * @param {string} name - * @param {Record} [data] - * @return {Promise} - */ + * Send a request, and wait for a response + * @throws {Error} + * {@link MissingHandler} + * + * @example + * ``` + * const messaging = new Messaging(config) + * const response = await messaging.request("foo", {bar: "baz"}) + * ``` + * + * @param {string} name + * @param {Record} [data] + * @return {Promise} + */ request(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return this.transport.request(name, data); @@ -544,20 +544,20 @@ class Messaging { exports.Messaging = Messaging; class MessagingTransport { /** - * @param {string} name - * @param {Record} [data] - * @returns {void} - */ + * @param {string} name + * @param {Record} [data] + * @returns {void} + */ // @ts-ignore - ignoring a no-unused ts error, this is only an interface. notify(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; throw new Error("must implement 'notify'"); } /** - * @param {string} name - * @param {Record} [data] - * @return {Promise} - */ + * @param {string} name + * @param {Record} [data] + * @return {Promise} + */ // @ts-ignore - ignoring a no-unused ts error, this is only an interface. request(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; @@ -582,9 +582,9 @@ function getTransport(config) { */ class MissingHandler extends Error { /** - * @param {string} message - * @param {string} handlerName - */ + * @param {string} message + * @param {string} handlerName + */ constructor(message, handlerName) { super(message); this.handlerName = handlerName; @@ -690,8 +690,8 @@ class WebkitMessagingTransport { config; globals; /** - * @param {WebkitMessagingConfig} config - */ + * @param {WebkitMessagingConfig} config + */ constructor(config) { this.config = config; this.globals = captureGlobals(); @@ -700,11 +700,11 @@ class WebkitMessagingTransport { } } /** - * Sends message to the webkit layer (fire and forget) - * @param {String} handler - * @param {*} data - * @internal - */ + * Sends message to the webkit layer (fire and forget) + * @param {String} handler + * @param {*} data + * @internal + */ wkSend(handler) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (!(handler in this.globals.window.webkit.messageHandlers)) { @@ -728,12 +728,12 @@ class WebkitMessagingTransport { } /** - * Sends message to the webkit layer and waits for the specified response - * @param {String} handler - * @param {*} data - * @returns {Promise<*>} - * @internal - */ + * Sends message to the webkit layer and waits for the specified response + * @param {String} handler + * @param {*} data + * @returns {Promise<*>} + * @internal + */ async wkSendAndWait(handler) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (this.config.hasModernWebkitAPI) { @@ -774,27 +774,27 @@ class WebkitMessagingTransport { } } /** - * @param {string} name - * @param {Record} [data] - */ + * @param {string} name + * @param {Record} [data] + */ notify(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; this.wkSend(name, data); } /** - * @param {string} name - * @param {Record} [data] - */ + * @param {string} name + * @param {Record} [data] + */ request(name) { let data = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; return this.wkSendAndWait(name, data); } /** - * Generate a random method name and adds it to the global scope - * The native layer will use this method to send the response - * @param {string | number} randomMethodName - * @param {Function} callback - */ + * Generate a random method name and adds it to the global scope + * The native layer will use this method to send the response + * @param {string | number} randomMethodName + * @param {Function} callback + */ generateRandomMethod(randomMethodName, callback) { var _this = this; this.globals.ObjectDefineProperty(this.globals.window, randomMethodName, { @@ -803,8 +803,8 @@ class WebkitMessagingTransport { configurable: true, writable: false, /** - * @param {any[]} args - */ + * @param {any[]} args + */ value: function () { callback(...arguments); // @ts-ignore - we want this to throw if it fails as it would indicate a fatal error. @@ -820,16 +820,16 @@ class WebkitMessagingTransport { } /** - * @type {{name: string, length: number}} - */ + * @type {{name: string, length: number}} + */ algoObj = { name: 'AES-GCM', length: 256 }; /** - * @returns {Promise} - */ + * @returns {Promise} + */ async createRandKey() { const key = await this.globals.generateKey(this.algoObj, true, ['encrypt', 'decrypt']); const exportedKey = await this.globals.exportKey('raw', key); @@ -837,44 +837,44 @@ class WebkitMessagingTransport { } /** - * @returns {Uint8Array} - */ + * @returns {Uint8Array} + */ createRandIv() { return this.globals.getRandomValues(new this.globals.Uint8Array(12)); } /** - * @param {BufferSource} ciphertext - * @param {BufferSource} key - * @param {Uint8Array} iv - * @returns {Promise} - */ + * @param {BufferSource} ciphertext + * @param {BufferSource} key + * @param {Uint8Array} iv + * @returns {Promise} + */ async decrypt(ciphertext, key, iv) { const cryptoKey = await this.globals.importKey('raw', key, 'AES-GCM', false, ['decrypt']); const algo = { name: 'AES-GCM', iv }; - let decrypted = await this.globals.decrypt(algo, cryptoKey, ciphertext); - let dec = new this.globals.TextDecoder(); + const decrypted = await this.globals.decrypt(algo, cryptoKey, ciphertext); + const dec = new this.globals.TextDecoder(); return dec.decode(decrypted); } /** - * When required (such as on macos 10.x), capture the `postMessage` method on - * each webkit messageHandler - * - * @param {string[]} handlerNames - */ + * When required (such as on macos 10.x), capture the `postMessage` method on + * each webkit messageHandler + * + * @param {string[]} handlerNames + */ captureWebkitHandlers(handlerNames) { const handlers = window.webkit.messageHandlers; if (!handlers) throw new _messaging.MissingHandler('window.webkit.messageHandlers was absent', 'all'); - for (let webkitMessageHandlerName of handlerNames) { + for (const webkitMessageHandlerName of handlerNames) { if (typeof handlers[webkitMessageHandlerName]?.postMessage === 'function') { /** - * `bind` is used here to ensure future calls to the captured - * `postMessage` have the correct `this` context - */ + * `bind` is used here to ensure future calls to the captured + * `postMessage` have the correct `this` context + */ const original = handlers[webkitMessageHandlerName]; const bound = handlers[webkitMessageHandlerName].postMessage?.bind(original); this.globals.capturedWebkitHandlers[webkitMessageHandlerName] = bound; @@ -903,11 +903,11 @@ class WebkitMessagingTransport { exports.WebkitMessagingTransport = WebkitMessagingTransport; class WebkitMessagingConfig { /** - * @param {object} params - * @param {boolean} params.hasModernWebkitAPI - * @param {string[]} params.webkitMessageHandlerNames - * @param {string} params.secret - */ + * @param {object} params + * @param {boolean} params.hasModernWebkitAPI + * @param {string[]} params.webkitMessageHandlerNames + * @param {string} params.secret + */ constructor(params) { /** * Whether or not the current WebKit Platform supports secure messaging @@ -915,13 +915,13 @@ class WebkitMessagingConfig { */ this.hasModernWebkitAPI = params.hasModernWebkitAPI; /** - * A list of WebKit message handler names that a user script can send - */ + * A list of WebKit message handler names that a user script can send + */ this.webkitMessageHandlerNames = params.webkitMessageHandlerNames; /** - * A string provided by native platforms to be sent with future outgoing - * messages - */ + * A string provided by native platforms to be sent with future outgoing + * messages + */ this.secret = params.secret; } } @@ -933,28 +933,28 @@ class WebkitMessagingConfig { exports.WebkitMessagingConfig = WebkitMessagingConfig; class SecureMessagingParams { /** - * @param {object} params - * @param {string} params.methodName - * @param {string} params.secret - * @param {number[]} params.key - * @param {number[]} params.iv - */ + * @param {object} params + * @param {string} params.methodName + * @param {string} params.secret + * @param {number[]} params.key + * @param {number[]} params.iv + */ constructor(params) { /** * The method that's been appended to `window` to be called later */ this.methodName = params.methodName; /** - * The secret used to ensure message sender validity - */ + * The secret used to ensure message sender validity + */ this.secret = params.secret; /** - * The CipherKey as number[] - */ + * The CipherKey as number[] + */ this.key = params.key; /** - * The Initial Vector as number[] - */ + * The Initial Vector as number[] + */ this.iv = params.iv; } } @@ -1165,7 +1165,7 @@ function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && * }} PasswordParameters */ const defaults = Object.freeze({ - SCAN_SET_ORDER: "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\\\"'<>,.?/ ]", + SCAN_SET_ORDER: 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-~!@#$%^&*_+=`|(){}[:;\\"\'<>,.?/ ]', defaultUnambiguousCharacters: 'abcdefghijkmnopqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ0123456789', defaultPasswordLength: _constants.constants.DEFAULT_MIN_LENGTH, defaultPasswordRules: _constants.constants.DEFAULT_PASSWORD_RULES, @@ -1292,7 +1292,7 @@ class Password { _requirementsFromRules(passwordRules) { /** @type {Requirements} */ const requirements = {}; - for (let rule of passwordRules) { + for (const rule of passwordRules) { if (rule.name === parser.RuleName.ALLOWED) { console.assert(!('PasswordAllowedCharacters' in requirements)); const chars = this._charactersFromCharactersClasses(rule.value); @@ -1623,7 +1623,7 @@ class Password { */ _charactersFromCharactersClasses(characterClasses) { const output = []; - for (let characterClass of characterClasses) { + for (const characterClass of characterClasses) { output.push(...this._scanSetFromCharacterClass(characterClass)); } return output; @@ -1637,9 +1637,9 @@ class Password { if (!characters.length) { return ''; } - let shadowCharacters = Array.prototype.slice.call(characters); + const shadowCharacters = Array.prototype.slice.call(characters); shadowCharacters.sort((a, b) => this.options.SCAN_SET_ORDER.indexOf(a) - this.options.SCAN_SET_ORDER.indexOf(b)); - let uniqueCharacters = [shadowCharacters[0]]; + const uniqueCharacters = [shadowCharacters[0]]; for (let i = 1, length = shadowCharacters.length; i < length; ++i) { if (shadowCharacters[i] === shadowCharacters[i - 1]) { continue; @@ -1679,6 +1679,7 @@ Object.defineProperty(exports, "__esModule", { }); exports.SHOULD_NOT_BE_REACHED = exports.RuleName = exports.Rule = exports.ParserError = exports.NamedCharacterClass = exports.Identifier = exports.CustomCharacterClass = void 0; exports.parsePasswordRules = parsePasswordRules; +/* eslint-disable no-var */ // Copyright (c) 2019 - 2020 Apple Inc. Licensed under MIT License. /* @@ -1731,7 +1732,6 @@ class Rule { } } exports.Rule = Rule; -; class NamedCharacterClass { constructor(name) { console.assert(_isValidRequiredOrAllowedPropertyValueIdentifier(name)); @@ -1748,10 +1748,8 @@ class NamedCharacterClass { } } exports.NamedCharacterClass = NamedCharacterClass; -; class ParserError extends Error {} exports.ParserError = ParserError; -; class CustomCharacterClass { constructor(characters) { console.assert(characters instanceof Array); @@ -1767,14 +1765,11 @@ class CustomCharacterClass { return `[${this._characters.join('').replace('"', '"')}]`; } } -exports.CustomCharacterClass = CustomCharacterClass; -; // MARK: Lexer functions - +exports.CustomCharacterClass = CustomCharacterClass; function _isIdentifierCharacter(c) { console.assert(c.length === 1); - // eslint-disable-next-line no-mixed-operators return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c === '-'; } function _isASCIIDigit(c) { @@ -1820,14 +1815,14 @@ function _markBitsForNamedCharacterClass(bitSet, namedCharacterClass) { } } function _markBitsForCustomCharacterClass(bitSet, customCharacterClass) { - for (let character of customCharacterClass.characters) { + for (const character of customCharacterClass.characters) { bitSet[_bitSetIndexForCharacter(character)] = true; } } function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFormatCompliant) { // @ts-ignore - let asciiPrintableBitSet = new Array('~'.codePointAt(0) - ' '.codePointAt(0) + 1); - for (let propertyValue of propertyValues) { + const asciiPrintableBitSet = new Array('~'.codePointAt(0) - ' '.codePointAt(0) + 1); + for (const propertyValue of propertyValues) { if (propertyValue instanceof NamedCharacterClass) { if (propertyValue.name === Identifier.UNICODE) { return [new NamedCharacterClass(Identifier.UNICODE)]; @@ -1842,32 +1837,32 @@ function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFo } let charactersSeen = []; function checkRange(start, end) { - let temp = []; + const temp = []; for (let i = _bitSetIndexForCharacter(start); i <= _bitSetIndexForCharacter(end); ++i) { if (asciiPrintableBitSet[i]) { temp.push(_characterAtBitSetIndex(i)); } } - let result = temp.length === _bitSetIndexForCharacter(end) - _bitSetIndexForCharacter(start) + 1; + const result = temp.length === _bitSetIndexForCharacter(end) - _bitSetIndexForCharacter(start) + 1; if (!result) { charactersSeen = charactersSeen.concat(temp); } return result; } - let hasAllUpper = checkRange('A', 'Z'); - let hasAllLower = checkRange('a', 'z'); - let hasAllDigits = checkRange('0', '9'); + const hasAllUpper = checkRange('A', 'Z'); + const hasAllLower = checkRange('a', 'z'); + const hasAllDigits = checkRange('0', '9'); // Check for special characters, accounting for characters that are given special treatment (i.e. '-' and ']') let hasAllSpecial = false; let hasDash = false; let hasRightSquareBracket = false; - let temp = []; + const temp = []; for (let i = _bitSetIndexForCharacter(' '); i <= _bitSetIndexForCharacter('/'); ++i) { if (!asciiPrintableBitSet[i]) { continue; } - let character = _characterAtBitSetIndex(i); + const character = _characterAtBitSetIndex(i); if (keepCustomCharacterClassFormatCompliant && character === '-') { hasDash = true; } else { @@ -1883,7 +1878,7 @@ function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFo if (!asciiPrintableBitSet[i]) { continue; } - let character = _characterAtBitSetIndex(i); + const character = _characterAtBitSetIndex(i); if (keepCustomCharacterClassFormatCompliant && character === ']') { hasRightSquareBracket = true; } else { @@ -1901,12 +1896,12 @@ function _canonicalizedPropertyValues(propertyValues, keepCustomCharacterClassFo if (hasRightSquareBracket) { temp.push(']'); } - let numberOfSpecialCharacters = _bitSetIndexForCharacter('/') - _bitSetIndexForCharacter(' ') + 1 + (_bitSetIndexForCharacter('@') - _bitSetIndexForCharacter(':') + 1) + (_bitSetIndexForCharacter('`') - _bitSetIndexForCharacter('[') + 1) + (_bitSetIndexForCharacter('~') - _bitSetIndexForCharacter('{') + 1); + const numberOfSpecialCharacters = _bitSetIndexForCharacter('/') - _bitSetIndexForCharacter(' ') + 1 + (_bitSetIndexForCharacter('@') - _bitSetIndexForCharacter(':') + 1) + (_bitSetIndexForCharacter('`') - _bitSetIndexForCharacter('[') + 1) + (_bitSetIndexForCharacter('~') - _bitSetIndexForCharacter('{') + 1); hasAllSpecial = temp.length === numberOfSpecialCharacters; if (!hasAllSpecial) { charactersSeen = charactersSeen.concat(temp); } - let result = []; + const result = []; if (hasAllUpper && hasAllLower && hasAllDigits && hasAllSpecial) { return [new NamedCharacterClass(Identifier.ASCII_PRINTABLE)]; } @@ -1934,7 +1929,7 @@ function _indexOfNonWhitespaceCharacter(input) { let position = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0; console.assert(position >= 0); console.assert(position <= input.length); - let length = input.length; + const length = input.length; while (position < length && _isASCIIWhitespace(input[position])) { ++position; } @@ -1944,10 +1939,10 @@ function _parseIdentifier(input, position) { console.assert(position >= 0); console.assert(position < input.length); console.assert(_isIdentifierCharacter(input[position])); - let length = input.length; - let seenIdentifiers = []; + const length = input.length; + const seenIdentifiers = []; do { - let c = input[position]; + const c = input[position]; if (!_isIdentifierCharacter(c)) { break; } @@ -1963,16 +1958,16 @@ function _parseCustomCharacterClass(input, position) { console.assert(position >= 0); console.assert(position < input.length); console.assert(input[position] === CHARACTER_CLASS_START_SENTINEL); - let length = input.length; + const length = input.length; ++position; if (position >= length) { // console.error('Found end-of-line instead of character class character') return [null, position]; } - let initialPosition = position; - let result = []; + const initialPosition = position; + const result = []; do { - let c = input[position]; + const c = input[position]; if (!_isASCIIPrintableCharacter(c)) { ++position; continue; @@ -2008,11 +2003,11 @@ function _parseCustomCharacterClass(input, position) { function _parsePasswordRequiredOrAllowedPropertyValue(input, position) { console.assert(position >= 0); console.assert(position < input.length); - let length = input.length; - let propertyValues = []; + const length = input.length; + const propertyValues = []; while (true) { if (_isIdentifierCharacter(input[position])) { - let identifierStartPosition = position; + const identifierStartPosition = position; // eslint-disable-next-line no-redeclare var [propertyValue, position] = _parseIdentifier(input, position); if (!_isValidRequiredOrAllowedPropertyValueIdentifier(propertyValue)) { @@ -2059,8 +2054,8 @@ function _parsePasswordRule(input, position) { console.assert(position >= 0); console.assert(position < input.length); console.assert(_isIdentifierCharacter(input[position])); - let length = input.length; - var mayBeIdentifierStartPosition = position; + const length = input.length; + const mayBeIdentifierStartPosition = position; // eslint-disable-next-line no-redeclare var [identifier, position] = _parseIdentifier(input, position); if (!Object.values(RuleName).includes(identifier)) { @@ -2075,7 +2070,7 @@ function _parsePasswordRule(input, position) { // console.error('Failed to find start of property value: ' + input.substr(position)) return [null, position, undefined]; } - let property = { + const property = { name: identifier, value: null }; @@ -2131,7 +2126,7 @@ function _parseInteger(input, position) { // console.error('Failed to parse value of type integer; not a number: ' + input.substr(position)) return [null, position]; } - let length = input.length; + const length = input.length; // let initialPosition = position let result = 0; do { @@ -2152,8 +2147,8 @@ function _parseInteger(input, position) { * @private */ function _parsePasswordRulesInternal(input) { - let parsedProperties = []; - let length = input.length; + const parsedProperties = []; + const length = input.length; var position = _indexOfNonWhitespaceCharacter(input); while (position < length) { if (!_isIdentifierCharacter(input[position])) { @@ -2190,7 +2185,7 @@ function _parsePasswordRulesInternal(input) { * @returns {Rule[]} */ function parsePasswordRules(input, formatRulesForMinifiedVersion) { - let [passwordRules, maybeMessage] = _parsePasswordRulesInternal(input); + const [passwordRules, maybeMessage] = _parsePasswordRulesInternal(input); if (!passwordRules) { throw new ParserError(maybeMessage); } @@ -2200,13 +2195,13 @@ function parsePasswordRules(input, formatRulesForMinifiedVersion) { // When formatting rules for minified version, we should keep the formatted rules // as similar to the input as possible. Avoid copying required rules to allowed rules. - let suppressCopyingRequiredToAllowed = formatRulesForMinifiedVersion; - let requiredRules = []; + const suppressCopyingRequiredToAllowed = formatRulesForMinifiedVersion; + const requiredRules = []; let newAllowedValues = []; let minimumMaximumConsecutiveCharacters = null; let maximumMinLength = 0; let minimumMaxLength = null; - for (let rule of passwordRules) { + for (const rule of passwordRules) { switch (rule.name) { case RuleName.MAX_CONSECUTIVE: minimumMaximumConsecutiveCharacters = minimumMaximumConsecutiveCharacters ? Math.min(rule.value, minimumMaximumConsecutiveCharacters) : rule.value; @@ -2239,10 +2234,10 @@ function parsePasswordRules(input, formatRulesForMinifiedVersion) { if (minimumMaximumConsecutiveCharacters !== null) { newPasswordRules.push(new Rule(RuleName.MAX_CONSECUTIVE, minimumMaximumConsecutiveCharacters)); } - let sortedRequiredRules = requiredRules.sort(function (a, b) { + const sortedRequiredRules = requiredRules.sort(function (a, b) { const namedCharacterClassOrder = [Identifier.LOWER, Identifier.UPPER, Identifier.DIGIT, Identifier.SPECIAL, Identifier.ASCII_PRINTABLE, Identifier.UNICODE]; - let aIsJustOneNamedCharacterClass = a.value.length === 1 && a.value[0] instanceof NamedCharacterClass; - let bIsJustOneNamedCharacterClass = b.value.length === 1 && b.value[0] instanceof NamedCharacterClass; + const aIsJustOneNamedCharacterClass = a.value.length === 1 && a.value[0] instanceof NamedCharacterClass; + const bIsJustOneNamedCharacterClass = b.value.length === 1 && b.value[0] instanceof NamedCharacterClass; if (aIsJustOneNamedCharacterClass && !bIsJustOneNamedCharacterClass) { return -1; } @@ -2250,8 +2245,8 @@ function parsePasswordRules(input, formatRulesForMinifiedVersion) { return 1; } if (aIsJustOneNamedCharacterClass && bIsJustOneNamedCharacterClass) { - let aIndex = namedCharacterClassOrder.indexOf(a.value[0].name); - let bIndex = namedCharacterClassOrder.indexOf(b.value[0].name); + const aIndex = namedCharacterClassOrder.indexOf(a.value[0].name); + const bIndex = namedCharacterClassOrder.indexOf(b.value[0].name); return aIndex - bIndex; } return 0; @@ -2896,6 +2891,9 @@ module.exports={ "keldoc.com": { "password-rules": "minlength: 12; required: lower; required: upper; required: digit; required: [!@#$%^&*];" }, + "kennedy-center.org": { + "password-rules": "minlength: 8; required: lower; required: upper; required: digit; required: [!#$%&*?@];" + }, "key.harvard.edu": { "password-rules": "minlength: 10; maxlength: 100; required: lower; required: upper; required: digit; allowed: [-@_#!&$`%*+()./,;~:{}|?>=<^[']];" }, @@ -3408,8 +3406,8 @@ class CredentialsImport { activeInput?.focus(); } async started() { - this.device.deviceApi.notify(new _deviceApiCalls.CloseAutofillParentCall(null)); this.device.deviceApi.notify(new _deviceApiCalls.StartCredentialsImportFlowCall({})); + this.device.deviceApi.notify(new _deviceApiCalls.CloseAutofillParentCall(null)); } async dismissed() { this.device.deviceApi.notify(new _deviceApiCalls.CredentialsImportFlowPermanentlyDismissedCall(null)); @@ -3453,7 +3451,7 @@ function createDevice() { }; // Create the DeviceAPI + Setting - let deviceApi = new _index.DeviceApi(globalConfig.isDDGTestMode ? loggingTransport : transport); + const deviceApi = new _index.DeviceApi(globalConfig.isDDGTestMode ? loggingTransport : transport); const settings = new _Settings.Settings(globalConfig, deviceApi); if (globalConfig.isWindows) { if (globalConfig.isTopFrame) { @@ -3587,9 +3585,9 @@ class AndroidInterface extends _InterfacePrototype.default { } /** - * Used by the email web app - * Provides functionality to log the user out - */ + * Used by the email web app + * Provides functionality to log the user out + */ removeUserData() { try { return window.EmailInterface.removeCredentials(); @@ -4858,14 +4856,16 @@ class InterfacePrototype { }); break; default: - // Also fire pixel when filling an identity with the personal duck address from an email field - const checks = [subtype === 'emailAddress', this.hasLocalAddresses, data?.emailAddress === (0, _autofillUtils.formatDuckAddress)(this.#addresses.personalAddress)]; - if (checks.every(Boolean)) { - this.firePixel({ - pixelName: 'autofill_personal_address' - }); + { + // Also fire pixel when filling an identity with the personal duck address from an email field + const checks = [subtype === 'emailAddress', this.hasLocalAddresses, data?.emailAddress === (0, _autofillUtils.formatDuckAddress)(this.#addresses.personalAddress)]; + if (checks.every(Boolean)) { + this.firePixel({ + pixelName: 'autofill_personal_address' + }); + } + break; } - break; } } // some platforms do not include a `success` object, why? @@ -5113,13 +5113,15 @@ class InterfacePrototype { postSubmit(values, form) { if (!form.form) return; if (!form.hasValues(values)) return; - const checks = [form.shouldPromptToStoreData && !form.submitHandlerExecuted, this.passwordGenerator.generated]; + const shouldTriggerPartialSave = Object.keys(values?.credentials || {}).length === 1 && Boolean(values?.credentials?.username) && this.settings.featureToggles.partial_form_saves; + const checks = [form.shouldPromptToStoreData && !form.submitHandlerExecuted, this.passwordGenerator.generated, shouldTriggerPartialSave]; if (checks.some(Boolean)) { const formData = (0, _Credentials.appendGeneratedKey)(values, { password: this.passwordGenerator.password, username: this.emailProtection.lastGenerated }); - this.storeFormData(formData, 'formSubmission'); + const trigger = shouldTriggerPartialSave ? 'partialSave' : 'formSubmission'; + this.storeFormData(formData, trigger); } } @@ -5540,6 +5542,7 @@ function initFormSubmissionsApi(forms, matching) { // @ts-ignore if (btns.find(btn => btn.contains(realTarget))) return true; + return false; }); matchingForm?.submitHandler('global pointerdown event + matching form'); if (!matchingForm) { @@ -5635,7 +5638,7 @@ function overlayApi(device) { * @returns {Promise} */ async selectedDetail(data, type) { - let detailsEntries = Object.entries(data).map(_ref => { + const detailsEntries = Object.entries(data).map(_ref => { let [key, value] = _ref; return [key, String(value)]; }); @@ -5898,7 +5901,7 @@ class Form { */ getValuesReadyForStorage() { const formValues = this.getRawValues(); - return (0, _formatters.prepareFormValuesForStorage)(formValues); + return (0, _formatters.prepareFormValuesForStorage)(formValues, this.device.settings.featureToggles.partial_form_saves); } /** @@ -5929,7 +5932,7 @@ class Form { if (!input.classList.contains('ddg-autofilled')) return; (0, _autofillUtils.removeInlineStyles)(input, (0, _inputStyles.getIconStylesAutofilled)(input, this)); (0, _autofillUtils.removeInlineStyles)(input, { - 'cursor': 'pointer' + cursor: 'pointer' }); input.classList.remove('ddg-autofilled'); this.addAutofillStyles(input); @@ -6050,20 +6053,10 @@ class Form { if (this.form.matches(selector)) { this.addInput(this.form); } else { - /** @type {Element[] | NodeList} */ - let foundInputs = []; - // Some sites seem to be overriding `form.elements`, so we need to check if it's still iterable. - if (this.form instanceof HTMLFormElement && this.form.elements != null && Symbol.iterator in Object(this.form.elements)) { - // For form elements we use .elements to catch fields outside the form itself using the form attribute. - // It also catches all elements when the markup is broken. - // We use .filter to avoid fieldset, button, textarea etc. - const formElements = [...this.form.elements].filter(el => el.matches(selector)); - // If there are no form elements, we try to look for all - // enclosed elements within the form. - foundInputs = formElements.length > 0 ? formElements : (0, _autofillUtils.findEnclosedElements)(this.form, selector); - } else { - foundInputs = this.form.querySelectorAll(selector); - } + // Attempt to get form's control elements first as it can catch elements when markup is broke, or if the fields are outside the form. + // Other wise use queryElementsWithShadow, that can scan for shadow tree. + const formControlElements = (0, _autofillUtils.getFormControlElements)(this.form, selector); + const foundInputs = formControlElements != null ? [...formControlElements, ...(0, _autofillUtils.findElementsInShadowTree)(this.form, selector)] : (0, _autofillUtils.queryElementsWithShadow)(this.form, selector, true); if (foundInputs.length < MAX_INPUTS_PER_FORM) { foundInputs.forEach(input => this.addInput(input)); } else { @@ -6124,7 +6117,7 @@ class Form { } get submitButtons() { const selector = this.matching.cssSelector('submitButtonSelector'); - const allButtons = /** @type {HTMLElement[]} */(0, _autofillUtils.findEnclosedElements)(this.form, selector); + const allButtons = /** @type {HTMLElement[]} */(0, _autofillUtils.queryElementsWithShadow)(this.form, selector); return allButtons.filter(btn => (0, _autofillUtils.isPotentiallyViewable)(btn) && (0, _autofillUtils.isLikelyASubmitButton)(btn, this.matching) && (0, _autofillUtils.buttonMatchesFormType)(btn, this)); } attemptSubmissionIfNeeded() { @@ -6247,12 +6240,12 @@ class Form { if ((0, _autofillUtils.wasAutofilledByChrome)(input)) return; if ((0, _autofillUtils.isEventWithinDax)(e, e.target)) { (0, _autofillUtils.addInlineStyles)(e.target, { - 'cursor': 'pointer', + cursor: 'pointer', ...onMouseMove }); } else { (0, _autofillUtils.removeInlineStyles)(e.target, { - 'cursor': 'pointer' + cursor: 'pointer' }); // Only overwrite active icon styles if tooltip is closed if (!this.device.isTooltipActive()) { @@ -6264,7 +6257,7 @@ class Form { }); this.addListener(input, 'mouseleave', e => { (0, _autofillUtils.removeInlineStyles)(e.target, { - 'cursor': 'pointer' + cursor: 'pointer' }); // Only overwrite active icon styles if tooltip is closed if (!this.device.isTooltipActive()) { @@ -6362,7 +6355,7 @@ class Form { this.touched.add(input); this.device.attachTooltip({ form: this, - input: input, + input, click: clickCoords, trigger: 'userInitiated', triggerMetaData: { @@ -6591,7 +6584,7 @@ class Form { }, 'credentials'); this.device.attachTooltip({ form: this, - input: input, + input, click: null, trigger: 'autoprompt', triggerMetaData: { @@ -6826,6 +6819,23 @@ class FormAnalyzer { } }); } + + /** + * Function that checks if the element is an external link or a custom web element that + * encapsulates a link. + * @param {any} el + * @returns {boolean} + */ + isElementExternalLink(el) { + // Checks if the element is present in the cusotm elements registry and ends with a '-link' suffix. + // If it does, it checks if it contains an anchor element inside. + const tagName = el.nodeName.toLowerCase(); + const isCustomWebElementLink = customElements?.get(tagName) != null && /-link$/.test(tagName) && (0, _autofillUtils.findElementsInShadowTree)(el, 'a').length > 0; + + // if an external link matches one of the regexes, we assume the match is not pertinent to the current form + const isElementLink = el instanceof HTMLAnchorElement && el.href && el.getAttribute('href') !== '#' || (el.getAttribute('role') || '').toUpperCase() === 'LINK' || el.matches('button[class*=secondary]'); + return isCustomWebElementLink || isElementLink; + } evaluateElement(el) { const string = (0, _autofillUtils.getTextShallow)(el); if (el.matches(this.matching.cssSelector('password'))) { @@ -6846,7 +6856,7 @@ class FormAnalyzer { if (likelyASubmit) { this.form.querySelectorAll('input[type=submit], button[type=submit]').forEach(submit => { // If there is another element marked as submit and this is not, flip back to false - if (el.type !== 'submit' && el !== submit) { + if (el.getAttribute('type') !== 'submit' && el !== submit) { likelyASubmit = false; } }); @@ -6865,8 +6875,7 @@ class FormAnalyzer { }); return; } - // if an external link matches one of the regexes, we assume the match is not pertinent to the current form - if (el instanceof HTMLAnchorElement && el.href && el.getAttribute('href') !== '#' || (el.getAttribute('role') || '').toUpperCase() === 'LINK' || el.matches('button[class*=secondary]')) { + if (this.isElementExternalLink(el)) { let shouldFlip = true; let strength = 1; // Don't flip forgotten password links @@ -6885,9 +6894,10 @@ class FormAnalyzer { }); } else { // any other case + const isH1Element = el.tagName === 'H1'; this.updateSignal({ string, - strength: 1, + strength: isH1Element ? 3 : 1, signalType: `generic: ${string}`, shouldCheckUnifiedForm: true }); @@ -6905,7 +6915,7 @@ class FormAnalyzer { // Check form contents (noisy elements are skipped with the safeUniversalSelector) const selector = this.matching.cssSelector('safeUniversalSelector'); - const formElements = (0, _autofillUtils.findEnclosedElements)(this.form, selector); + const formElements = (0, _autofillUtils.queryElementsWithShadow)(this.form, selector); for (let i = 0; i < formElements.length; i++) { // Safety cutoff to avoid huge DOMs freezing the browser if (i >= 200) break; @@ -6965,7 +6975,7 @@ class FormAnalyzer { } // Match form textContent against common cc fields (includes hidden labels) - const textMatches = formEl.textContent?.match(/(credit|payment).?card(.?number)?|ccv|security.?code|cvv|cvc|csc/ig); + const textMatches = formEl.textContent?.match(/(credit|payment).?card(.?number)?|ccv|security.?code|cvv|cvc|csc/gi); // De-dupe matches to avoid counting the same element more than once const deDupedMatches = new Set(textMatches?.map(match => match.toLowerCase())); @@ -7284,7 +7294,7 @@ const COUNTRY_NAMES_TO_CODES = exports.COUNTRY_NAMES_TO_CODES = { Anguilla: 'AI', Albania: 'AL', Armenia: 'AM', - 'Curaçao': 'CW', + Curaçao: 'CW', Angola: 'AO', Antarctica: 'AQ', Argentina: 'AR', @@ -7473,7 +7483,7 @@ const COUNTRY_NAMES_TO_CODES = exports.COUNTRY_NAMES_TO_CODES = { Paraguay: 'PY', Qatar: 'QA', 'Outlying Oceania': 'QO', - 'Réunion': 'RE', + Réunion: 'RE', Zimbabwe: 'ZW', Romania: 'RO', Russia: 'SU', @@ -7550,6 +7560,7 @@ Object.defineProperty(exports, "__esModule", { exports.prepareFormValuesForStorage = exports.inferCountryCodeFromElement = exports.getUnifiedExpiryDate = exports.getMMAndYYYYFromString = exports.getCountryName = exports.getCountryDisplayName = exports.formatPhoneNumber = exports.formatFullName = exports.formatCCYear = void 0; var _matching = require("./matching.js"); var _countryNames = require("./countryNames.js"); +var _autofillUtils = require("../autofill-utils.js"); // Matches strings like mm/yy, mm-yyyy, mm-aa, 12 / 2024 const DATE_SEPARATOR_REGEX = /\b((.)\2{1,3}|\d+)(?\s?[/\s.\-_—–]\s?)((.)\5{1,3}|\d+)\b/i; // Matches 4 non-digit repeated characters (YYYY or AAAA) or 4 digits (2022) @@ -7718,36 +7729,25 @@ const getMMAndYYYYFromString = expiration => { }; /** - * @param {InternalDataStorageObject} credentials + * @param {InternalDataStorageObject} data * @return {boolean} */ exports.getMMAndYYYYFromString = getMMAndYYYYFromString; -const shouldStoreCredentials = _ref3 => { - let { - credentials - } = _ref3; - return Boolean(credentials.password); -}; - -/** - * @param {InternalDataStorageObject} credentials - * @return {boolean} - */ -const shouldStoreIdentities = _ref4 => { +const shouldStoreIdentities = _ref3 => { let { identities - } = _ref4; + } = _ref3; return Boolean((identities.firstName || identities.fullName) && identities.addressStreet && identities.addressCity); }; /** - * @param {InternalDataStorageObject} credentials + * @param {InternalDataStorageObject} data * @return {boolean} */ -const shouldStoreCreditCards = _ref5 => { +const shouldStoreCreditCards = _ref4 => { let { creditCards - } = _ref5; + } = _ref4; if (!creditCards.cardNumber) return false; if (creditCards.cardSecurityCode) return true; // Some forms (Amazon) don't have the cvv, so we still save if there's the expiration @@ -7770,7 +7770,8 @@ const formatPhoneNumber = phone => phone.replaceAll(/[^0-9|+]/g, ''); * @return {DataStorageObject} */ exports.formatPhoneNumber = formatPhoneNumber; -const prepareFormValuesForStorage = formValues => { +const prepareFormValuesForStorage = function (formValues) { + let canTriggerPartialSave = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; /** @type {Partial} */ let { credentials, @@ -7783,14 +7784,15 @@ const prepareFormValuesForStorage = formValues => { creditCards.cardName = identities?.fullName || formatFullName(identities); } - /** Fixes for credentials **/ - // Don't store if there isn't enough data - if (shouldStoreCredentials(formValues)) { - // If we don't have a username to match a password, let's see if the email is available - if (credentials.password && !credentials.username && identities.emailAddress) { - credentials.username = identities.emailAddress; - } - } else { + /** Fixes for credentials */ + // If we don't have a username to match a password, let's see if email or phone are available + if (credentials.password && !credentials.username && (0, _autofillUtils.hasUsernameLikeIdentity)(identities)) { + // @ts-ignore - username will be likely undefined, but needs to be specifically assigned to a string value + credentials.username = identities.emailAddress || identities.phone; + } + + // If there's no password, and we shouldn't trigger a partial save, let's discard the object + if (!credentials.password && !canTriggerPartialSave) { credentials = undefined; } @@ -7846,7 +7848,7 @@ const prepareFormValuesForStorage = formValues => { }; exports.prepareFormValuesForStorage = prepareFormValuesForStorage; -},{"./countryNames.js":26,"./matching.js":34}],28:[function(require,module,exports){ +},{"../autofill-utils.js":54,"./countryNames.js":26,"./matching.js":34}],28:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { @@ -7889,7 +7891,7 @@ const getBasicStyles = (input, icon) => ({ 'background-repeat': 'no-repeat', 'background-origin': 'content-box', 'background-image': `url(${icon})`, - 'transition': 'background 0s' + transition: 'background 0s' }); /** @@ -7932,7 +7934,7 @@ const getIconStylesAutofilled = (input, form) => { return { ...iconStyle, 'background-color': '#F8F498', - 'color': '#333333' + color: '#333333' }; }; exports.getIconStylesAutofilled = getIconStylesAutofilled; @@ -8220,14 +8222,14 @@ const extractElementStrings = element => { // only take the string when it's an explicit text node if (el.nodeType === el.TEXT_NODE || !el.childNodes.length) { - let trimmedText = (0, _matching.removeExcessWhitespace)(el.textContent); + const trimmedText = (0, _matching.removeExcessWhitespace)(el.textContent); if (trimmedText) { strings.add(trimmedText); } return; } - for (let node of el.childNodes) { - let nodeType = node.nodeType; + for (const node of el.childNodes) { + const nodeType = node.nodeType; if (nodeType !== node.ELEMENT_NODE && nodeType !== node.TEXT_NODE) { continue; } @@ -8629,7 +8631,7 @@ const matchingConfiguration = exports.matchingConfiguration = { match: /sign.?up|join|register|enroll|(create|new).+account|newsletter|subscri(be|ption)|settings|preferences|profile|update|iscri(viti|zione)|registra(ti|zione)|(?:nuovo|crea(?:zione)?) account|contatt(?:ac)?i|sottoscriv|sottoscrizione|impostazioni|preferenze|aggiorna|anmeld(en|ung)|registrier(en|ung)|neukunde|neuer (kunde|benutzer|nutzer)|registreren|eigenschappen|profiel|bijwerken|s.inscrire|inscription|s.abonner|abonnement|préférences|profil|créer un compte|regis(trarse|tro)|regístrate|inscr(ibirse|ipción|íbete)|crea(r cuenta)?|nueva cuenta|nuevo (cliente|usuario)|preferencias|perfil|lista de correo|registrer(a|ing)|(nytt|öppna) konto|nyhetsbrev|prenumer(era|ation)|kontakt|skapa|starta|inställningar|min (sida|kundvagn)|uppdatera/iu }, resetPasswordLink: { - match: /(forgot(ten)?|reset|don't remember) (your )?password|password forgotten|password dimenticata|reset(?:ta) password|recuper[ao] password|(vergessen|verloren|verlegt|wiederherstellen) passwort|wachtwoord (vergeten|reset)|(oublié|récupérer) ((mon|ton|votre|le) )?mot de passe|mot de passe (oublié|perdu)|re(iniciar|cuperar) (contraseña|clave)|olvid(ó su|aste tu|é mi) (contraseña|clave)|recordar( su)? (contraseña|clave)|glömt lösenord|återställ lösenord/iu + match: /(forgot(ten)?|reset|don't remember).?(your )?password|password forgotten|password dimenticata|reset(?:ta) password|recuper[ao] password|(vergessen|verloren|verlegt|wiederherstellen) passwort|wachtwoord (vergeten|reset)|(oublié|récupérer) ((mon|ton|votre|le) )?mot de passe|mot de passe (oublié|perdu)|re(iniciar|cuperar) (contraseña|clave)|olvid(ó su|aste tu|é mi) (contraseña|clave)|recordar( su)? (contraseña|clave)|glömt lösenord|återställ lösenord/iu }, loginProvidersRegex: { match: / with | con | mit | met | avec /iu @@ -8894,8 +8896,8 @@ class Matching { * * `email: [{type: "email", strategies: {cssSelector: "email", ... etc}]` */ - for (let [listName, matcherNames] of Object.entries(this.#config.matchers.lists)) { - for (let fieldName of matcherNames) { + for (const [listName, matcherNames] of Object.entries(this.#config.matchers.lists)) { + for (const fieldName of matcherNames) { if (!this.#matcherLists[listName]) { this.#matcherLists[listName] = []; } @@ -9012,7 +9014,7 @@ class Matching { * @type {string[]} */ const selectors = []; - for (let matcher of matcherList) { + for (const matcher of matcherList) { if (matcher.strategies.cssSelector) { const css = this.cssSelector(matcher.strategies.cssSelector); if (css) { @@ -9149,12 +9151,12 @@ class Matching { /** * Loop through each strategy in order */ - for (let strategyName of this.#defaultStrategyOrder) { + for (const strategyName of this.#defaultStrategyOrder) { let result; /** * Now loop through each matcher in the list. */ - for (let matcher of matchers) { + for (const matcher of matchers) { /** * for each `strategyName` (such as cssSelector), check * if the current matcher implements it. @@ -9279,16 +9281,16 @@ class Matching { if (!ddgMatcher || !ddgMatcher.match) { return defaultResult; } - let matchRexExp = this.getDDGMatcherRegex(lookup); + const matchRexExp = this.getDDGMatcherRegex(lookup); if (!matchRexExp) { return defaultResult; } - let requiredScore = ['match', 'forceUnknown', 'maxDigits'].filter(ddgMatcherProp => ddgMatcherProp in ddgMatcher).length; + const requiredScore = ['match', 'forceUnknown', 'maxDigits'].filter(ddgMatcherProp => ddgMatcherProp in ddgMatcher).length; /** @type {MatchableStrings[]} */ const matchableStrings = ddgMatcher.matchableStrings || ['labelText', 'placeholderAttr', 'relatedText']; - for (let stringName of matchableStrings) { - let elementString = this.activeElementStrings[stringName]; + for (const stringName of matchableStrings) { + const elementString = this.activeElementStrings[stringName]; if (!elementString) continue; // Scoring to ensure all DDG tests are valid @@ -9304,7 +9306,7 @@ class Matching { // If a negated regex was provided, ensure it does not match // If it DOES match - then we need to prevent any future strategies from continuing if (ddgMatcher.forceUnknown) { - let notRegex = ddgMatcher.forceUnknown; + const notRegex = ddgMatcher.forceUnknown; if (!notRegex) { return { ...result, @@ -9323,7 +9325,7 @@ class Matching { } } if (ddgMatcher.skip) { - let skipRegex = ddgMatcher.skip; + const skipRegex = ddgMatcher.skip; if (!skipRegex) { return { ...result, @@ -9388,8 +9390,8 @@ class Matching { } /** @type {MatchableStrings[]} */ const stringsToMatch = ['placeholderAttr', 'nameAttr', 'labelText', 'id', 'relatedText']; - for (let stringName of stringsToMatch) { - let elementString = this.activeElementStrings[stringName]; + for (const stringName of stringsToMatch) { + const elementString = this.activeElementStrings[stringName]; if (!elementString) continue; if ((0, _autofillUtils.safeRegexTest)(regex, elementString)) { return { @@ -9463,14 +9465,14 @@ class Matching { fields: {} }, strategies: { - 'vendorRegex': { + vendorRegex: { rules: {}, ruleSets: [] }, - 'ddgMatcher': { + ddgMatcher: { matchers: {} }, - 'cssSelector': { + cssSelector: { selectors: {} } } @@ -9641,7 +9643,7 @@ const removeExcessWhitespace = function () { exports.removeExcessWhitespace = removeExcessWhitespace; const getExplicitLabelsText = el => { const labelTextCandidates = []; - for (let label of el.labels || []) { + for (const label of el.labels || []) { labelTextCandidates.push(...(0, _labelUtil.extractElementStrings)(label)); } if (el.hasAttribute('aria-label')) { @@ -9696,7 +9698,7 @@ const getRelatedText = (el, form, cssSelector) => { // If we didn't find a container, try looking for an adjacent label if (scope === el) { - let previousEl = recursiveGetPreviousElSibling(el); + const previousEl = recursiveGetPreviousElSibling(el); if (previousEl instanceof HTMLElement) { scope = previousEl; } @@ -10355,19 +10357,18 @@ class DefaultScanner { if (this.device.globalConfig.isDDGDomain) { return this; } - if ('matches' in context && context.matches?.(this.matching.cssSelector('formInputsSelectorWithoutSelect'))) { + const formInputsSelectorWithoutSelect = this.matching.cssSelector('formInputsSelectorWithoutSelect'); + if ('matches' in context && context.matches?.(formInputsSelectorWithoutSelect)) { this.addInput(context); } else { - const selector = this.matching.cssSelector('formInputsSelectorWithoutSelect'); - const inputs = context.querySelectorAll(selector); + const inputs = context.querySelectorAll(formInputsSelectorWithoutSelect); if (inputs.length > this.options.maxInputsPerPage) { this.setMode('stopped', `Too many input fields in the given context (${inputs.length}), stop scanning`, context); return this; } inputs.forEach(input => this.addInput(input)); if (context instanceof HTMLFormElement && this.forms.get(context)?.hasShadowTree) { - const selector = this.matching.cssSelector('formInputsSelectorWithoutSelect'); - (0, _autofillUtils.findEnclosedElements)(context, selector).forEach(input => { + (0, _autofillUtils.findElementsInShadowTree)(context, formInputsSelectorWithoutSelect).forEach(input => { if (input instanceof HTMLInputElement) { this.addInput(input, context); } @@ -10453,12 +10454,16 @@ class DefaultScanner { } if (element.parentElement) { element = element.parentElement; - const inputs = element.querySelectorAll(this.matching.cssSelector('formInputsSelector')); - const buttons = element.querySelectorAll(this.matching.cssSelector('submitButtonSelector')); - // If we find a button or another input, we assume that's our form - if (inputs.length > 1 || buttons.length) { - // found related input, return common ancestor - return element; + // If the parent is a redundant component (only contains a single element or is a shadowRoot) do not increase the traversal count. + if (element.childElementCount > 1) { + const inputs = element.querySelectorAll(this.matching.cssSelector('formInputsSelector')); + const buttons = element.querySelectorAll(this.matching.cssSelector('submitButtonSelector')); + // If we find a button or another input, we assume that's our form + if (inputs.length > 1 || buttons.length) { + // found related input, return common ancestor + return element; + } + traversalLayerCount++; } } else { // possibly a shadow boundary, so traverse through the shadow root and find the form @@ -10466,9 +10471,11 @@ class DefaultScanner { if (root instanceof ShadowRoot && root.host) { // @ts-ignore element = root.host; + } else { + // We're in a strange state (no parent or shadow root), just break out of the loop for safety + break; } } - traversalLayerCount++; } return input; } @@ -10551,7 +10558,7 @@ class DefaultScanner { this.changedElements.clear(); } else if (!this.rescanAll) { // otherwise keep adding each element to the queue - for (let element of htmlElements) { + for (const element of htmlElements) { this.changedElements.add(element); } } @@ -10575,7 +10582,7 @@ class DefaultScanner { this.findEligibleInputs(document); return; } - for (let element of this.changedElements) { + for (const element of this.changedElements) { if (element.isConnected) { this.findEligibleInputs(element); } @@ -10596,7 +10603,7 @@ class DefaultScanner { const outgoing = []; for (const mutationRecord of mutationList) { if (mutationRecord.type === 'childList') { - for (let addedNode of mutationRecord.addedNodes) { + for (const addedNode of mutationRecord.addedNodes) { if (!(addedNode instanceof HTMLElement)) continue; if (addedNode.nodeName === 'DDG-AUTOFILL') continue; outgoing.push(addedNode); @@ -10630,12 +10637,13 @@ class DefaultScanner { // find the enclosing parent form, and scan it. if (realTarget instanceof HTMLInputElement && !realTarget.hasAttribute(ATTR_INPUT_TYPE)) { const parentForm = this.getParentForm(realTarget); - if (parentForm && parentForm instanceof HTMLFormElement) { - const hasShadowTree = event.target?.shadowRoot != null; - const form = new _Form.Form(parentForm, realTarget, this.device, this.matching, this.shouldAutoprompt, hasShadowTree); - this.forms.set(parentForm, form); - this.findEligibleInputs(parentForm); - } + + // If the parent form is an input element we bail. + if (parentForm instanceof HTMLInputElement) return; + const hasShadowTree = event.target?.shadowRoot != null; + const form = new _Form.Form(parentForm, realTarget, this.device, this.matching, this.shouldAutoprompt, hasShadowTree); + this.forms.set(parentForm, form); + this.findEligibleInputs(parentForm); } window.performance?.mark?.('scan_shadow:init:end'); (0, _autofillUtils.logPerformance)('scan_shadow'); @@ -11010,7 +11018,8 @@ class Settings { inputType_credentials: false, inputType_creditCards: false, inlineIcon_credentials: false, - unknown_username_categorization: false + unknown_username_categorization: false, + partial_form_saves: false }, /** @type {AvailableInputTypes} */ availableInputTypes: { @@ -11334,7 +11343,7 @@ ${css} if (btn.matches('.wrapper:not(.top-autofill) button:hover, .currentFocus')) { callbacks.onSelect(btn.id); } else { - console.warn('The button doesn\'t seem to be hovered. Please check.'); + console.warn("The button doesn't seem to be hovered. Please check."); } }); }); @@ -11538,7 +11547,9 @@ const defaultOptions = exports.defaultOptions = { }`, css: ``, setSize: undefined, - remove: () => {/** noop */}, + remove: () => { + /** noop */ + }, testMode: false, checkVisibility: true, hasCaret: false, @@ -11566,9 +11577,9 @@ class HTMLTooltip { this.tooltip = null; this.getPosition = getPosition; const forcedVisibilityStyles = { - 'display': 'block', - 'visibility': 'visible', - 'opacity': '1' + display: 'block', + visibility: 'visible', + opacity: '1' }; // @ts-ignore how to narrow this.host to HTMLElement? (0, _autofillUtils.addInlineStyles)(this.host, forcedVisibilityStyles); @@ -11826,7 +11837,7 @@ class HTMLTooltip { checkVisibility: this.options.checkVisibility }); } else { - console.warn('The button doesn\'t seem to be hovered. Please check.'); + console.warn("The button doesn't seem to be hovered. Please check."); } } } @@ -12208,25 +12219,27 @@ class HTMLTooltipUIController extends _UIController.UIController { /** * Called when clicking on the Manage… button in the html tooltip - * * @param {SupportedMainTypes} type * @returns {*} * @private */ _onManage(type) { - this.removeTooltip(); switch (type) { case 'credentials': - return this._options.device.openManagePasswords(); + this._options.device.openManagePasswords(); + break; case 'creditCards': - return this._options.device.openManageCreditCards(); + this._options.device.openManageCreditCards(); + break; case 'identities': - return this._options.device.openManageIdentities(); + this._options.device.openManageIdentities(); + break; default: // noop } - } + this.removeTooltip(); + } _onIncontextSignupDismissed(_ref) { let { hasOtherOptions @@ -12770,10 +12783,14 @@ Object.defineProperty(exports, "__esModule", { }); exports.buttonMatchesFormType = exports.autofillEnabled = exports.addInlineStyles = exports.SIGN_IN_MSG = exports.ADDRESS_DOMAIN = void 0; exports.escapeXML = escapeXML; -exports.findEnclosedElements = findEnclosedElements; +exports.findElementsInShadowTree = findElementsInShadowTree; exports.formatDuckAddress = void 0; exports.getActiveElement = getActiveElement; -exports.isEventWithinDax = exports.isAutofillEnabledFromProcessedConfig = exports.getTextShallow = exports.getDaxBoundingBox = void 0; +exports.getDaxBoundingBox = void 0; +exports.getFormControlElements = getFormControlElements; +exports.getTextShallow = void 0; +exports.hasUsernameLikeIdentity = hasUsernameLikeIdentity; +exports.isEventWithinDax = exports.isAutofillEnabledFromProcessedConfig = void 0; exports.isFormLikelyToBeUsedAsPageWrapper = isFormLikelyToBeUsedAsPageWrapper; exports.isLikelyASubmitButton = exports.isIncontextSignupEnabledFromProcessedConfig = void 0; exports.isLocalNetwork = isLocalNetwork; @@ -12782,6 +12799,7 @@ exports.isValidTLD = isValidTLD; exports.logPerformance = logPerformance; exports.notifyWebApp = void 0; exports.pierceShadowTree = pierceShadowTree; +exports.queryElementsWithShadow = queryElementsWithShadow; exports.safeExecute = exports.removeInlineStyles = void 0; exports.safeRegexTest = safeRegexTest; exports.setValue = exports.sendAndWaitForAnswer = void 0; @@ -13154,8 +13172,9 @@ const isLikelyASubmitButton = (el, matching) => { // has high-signal submit classes safeRegexTest(/submit/i, dataTestId) || safeRegexTest(matching.getDDGMatcherRegex('submitButtonRegex'), text) || // has high-signal text - el.offsetHeight * el.offsetWidth >= 10000 && !safeRegexTest(/secondary/i, el.className) // it's a large element 250x40px - ) && el.offsetHeight * el.offsetWidth >= 2000 && + el.offsetHeight * el.offsetWidth >= 10000 && !safeRegexTest(/secondary/i, el.className)) && + // it's a large element 250x40px + el.offsetHeight * el.offsetWidth >= 2000 && // it's not a very small button like inline links and such !safeRegexTest(matching.getDDGMatcherRegex('submitButtonUnlikelyRegex'), text + ' ' + ariaLabel); }; @@ -13383,22 +13402,16 @@ function getActiveElement() { } /** - * Takes a root element and tries to find visible elements first, and if it fails, it tries to find shadow elements + * Takes a root element and tries to find elements in shadow DOMs that match the selector * @param {HTMLElement|HTMLFormElement} root * @param {string} selector * @returns {Element[]} */ -function findEnclosedElements(root, selector) { - // Check if there are any normal elements that match the selector - const elements = root.querySelectorAll(selector); - if (elements.length > 0) { - return Array.from(elements); - } - - // Check if there are any shadow elements that match the selector +function findElementsInShadowTree(root, selector) { const shadowElements = []; const walker = document.createTreeWalker(root, NodeFilter.SHOW_ELEMENT); - let node = walker.nextNode(); + /** @type {Node|null} */ + let node = walker.currentNode; while (node) { if (node instanceof HTMLElement && node.shadowRoot) { shadowElements.push(...node.shadowRoot.querySelectorAll(selector)); @@ -13408,6 +13421,52 @@ function findEnclosedElements(root, selector) { return shadowElements; } +/** + * The function looks for form's control elements, and returns them if they're iterable. + * @param {HTMLElement} form + * @param {string} selector + * @returns {Element[]|null} + */ +function getFormControlElements(form, selector) { + // Some sites seem to be overriding `form.elements`, so we need to check if it's still iterable. + if (form instanceof HTMLFormElement && form.elements != null && Symbol.iterator in Object(form.elements)) { + // For form elements we use .elements to catch fields outside the form itself using the form attribute. + // It also catches all elements when the markup is broken. + // We use .filter to avoid specific types of elements. + const formControls = [...form.elements].filter(el => el.matches(selector)); + return [...formControls]; + } else { + return null; + } +} + +/** + * Default operation: finds elements using querySelectorAll. + * Optionally, can be forced to scan the shadow tree. + * @param {HTMLElement} element + * @param {string} selector + * @param {boolean} forceScanShadowTree + * @returns {Element[]} + */ +function queryElementsWithShadow(element, selector) { + let forceScanShadowTree = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false; + /** @type {Element[]|NodeListOf} element */ + const elements = element.querySelectorAll(selector); + if (forceScanShadowTree || elements.length === 0) { + return [...elements, ...findElementsInShadowTree(element, selector)]; + } + return [...elements]; +} + +/** + * Checks if there is a single username-like identity, i.e. email or phone + * @param {InternalIdentityObject} identities + * @returns {boolean} + */ +function hasUsernameLikeIdentity(identities) { + return Object.keys(identities ?? {}).length === 1 && Boolean(identities?.emailAddress || identities.phone); +} + },{"./Form/matching.js":34,"./constants.js":57,"@duckduckgo/content-scope-scripts/src/apple-utils":1}],55:[function(require,module,exports){ "use strict"; @@ -13447,7 +13506,8 @@ Object.defineProperty(exports, "__esModule", { }); exports.DDG_DOMAIN_REGEX = void 0; exports.createGlobalConfig = createGlobalConfig; -const DDG_DOMAIN_REGEX = exports.DDG_DOMAIN_REGEX = new RegExp(/^https:\/\/(([a-z0-9-_]+?)\.)?duckduckgo\.com\/email/); +/* eslint-disable prefer-const */ +const DDG_DOMAIN_REGEX = exports.DDG_DOMAIN_REGEX = /^https:\/\/(([a-z0-9-_]+?)\.)?duckduckgo\.com\/email/; /** * This is a centralised place to contain all string/variable replacements @@ -13828,25 +13888,25 @@ const contentScopeSchema = exports.contentScopeSchema = null; const userPreferencesSchema = exports.userPreferencesSchema = null; const outgoingCredentialsSchema = exports.outgoingCredentialsSchema = null; const availableInputTypesSchema = exports.availableInputTypesSchema = null; -const availableInputTypes1Schema = exports.availableInputTypes1Schema = null; -const autofillFeatureTogglesSchema = exports.autofillFeatureTogglesSchema = null; -const getAutofillDataRequestSchema = exports.getAutofillDataRequestSchema = null; -const getAutofillDataResponseSchema = exports.getAutofillDataResponseSchema = null; -const storeFormDataSchema = exports.storeFormDataSchema = null; -const getAvailableInputTypesResultSchema = exports.getAvailableInputTypesResultSchema = null; const getAutofillInitDataResponseSchema = exports.getAutofillInitDataResponseSchema = null; const getAutofillCredentialsResultSchema = exports.getAutofillCredentialsResultSchema = null; -const autofillSettingsSchema = exports.autofillSettingsSchema = null; +const availableInputTypes1Schema = exports.availableInputTypes1Schema = null; +const providerStatusUpdatedSchema = exports.providerStatusUpdatedSchema = null; +const autofillFeatureTogglesSchema = exports.autofillFeatureTogglesSchema = null; const emailProtectionGetIsLoggedInResultSchema = exports.emailProtectionGetIsLoggedInResultSchema = null; const emailProtectionGetUserDataResultSchema = exports.emailProtectionGetUserDataResultSchema = null; const emailProtectionGetCapabilitiesResultSchema = exports.emailProtectionGetCapabilitiesResultSchema = null; const emailProtectionGetAddressesResultSchema = exports.emailProtectionGetAddressesResultSchema = null; const emailProtectionRefreshPrivateAddressResultSchema = exports.emailProtectionRefreshPrivateAddressResultSchema = null; -const runtimeConfigurationSchema = exports.runtimeConfigurationSchema = null; -const providerStatusUpdatedSchema = exports.providerStatusUpdatedSchema = null; -const getRuntimeConfigurationResponseSchema = exports.getRuntimeConfigurationResponseSchema = null; +const getAutofillDataRequestSchema = exports.getAutofillDataRequestSchema = null; +const getAutofillDataResponseSchema = exports.getAutofillDataResponseSchema = null; +const storeFormDataSchema = exports.storeFormDataSchema = null; +const getAvailableInputTypesResultSchema = exports.getAvailableInputTypesResultSchema = null; const askToUnlockProviderResultSchema = exports.askToUnlockProviderResultSchema = null; const checkCredentialsProviderStatusResultSchema = exports.checkCredentialsProviderStatusResultSchema = null; +const autofillSettingsSchema = exports.autofillSettingsSchema = null; +const runtimeConfigurationSchema = exports.runtimeConfigurationSchema = null; +const getRuntimeConfigurationResponseSchema = exports.getRuntimeConfigurationResponseSchema = null; const apiSchema = exports.apiSchema = null; },{}],60:[function(require,module,exports){ @@ -13964,7 +14024,7 @@ function waitForResponse(expectedResponse, config) { return; } try { - let data = JSON.parse(e.data); + const data = JSON.parse(e.data); if (data.type === expectedResponse) { window.removeEventListener('message', handler); return resolve(data); @@ -14119,7 +14179,7 @@ async function extensionSpecificRuntimeConfiguration(deviceApi) { return { success: { // @ts-ignore - contentScope: contentScope, + contentScope, // @ts-ignore userPreferences: { // Copy locale to user preferences as 'language' to match expected payload @@ -14313,6 +14373,7 @@ function waitForWindowsResponse(responseId, options) { if (options?.signal?.aborted) { return reject(new DOMException('Aborted', 'AbortError')); } + // eslint-disable-next-line prefer-const let teardown; // The event handler @@ -17199,7 +17260,6 @@ exports.default = void 0; window.requestIdleCallback = window.requestIdleCallback || function (cb) { return setTimeout(function () { const start = Date.now(); - // eslint-disable-next-line standard/no-callback-literal cb({ didTimeout: false, timeRemaining: function () { diff --git a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/index.css b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/index.css similarity index 100% rename from node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/index.css rename to node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/index.css diff --git a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/index.js b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/index.js similarity index 99% rename from node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/index.js rename to node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/index.js index 4999e435b990..8119bf66cd0a 100644 --- a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/index.js +++ b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/index.js @@ -1942,7 +1942,7 @@ return null; } - // pages/duckplayer/src/locales/en/duckplayer.json + // pages/duckplayer/public/locales/en/duckplayer.json var duckplayer_default = { smartling: { string_format: "icu", @@ -2004,7 +2004,7 @@ this.focusMode = focusMode; } /** - * @param {keyof import("../../../types/duckplayer").DuckPlayerPageSettings} named + * @param {keyof import("../types/duckplayer.js").DuckPlayerPageSettings} named * @param {{state: 'enabled' | 'disabled'} | null | undefined} settings * @return {Settings} */ @@ -2092,12 +2092,12 @@ }; } var MessagingContext2 = G( - /** @type {import("../src/js/index.js").DuckplayerPage} */ + /** @type {import("../src/index.js").DuckplayerPage} */ {} ); var useMessaging = () => x2(MessagingContext2); var TelemetryContext = G( - /** @type {import("../src/js/index.js").Telemetry} */ + /** @type {import("../src/index.js").Telemetry} */ {} ); var useTelemetry = () => x2(TelemetryContext); @@ -2858,7 +2858,7 @@ } }; - // pages/duckplayer/src/js/utils.js + // pages/duckplayer/src/utils.js function createYoutubeURLForError(href, urlBase) { const valid = VideoParams.forWatchPage(href); if (!valid) return null; @@ -3360,7 +3360,7 @@ } } - // pages/duckplayer/src/js/storage.js + // pages/duckplayer/src/storage.js function deleteStorage(subject) { Object.keys(subject).forEach((key) => { if (key.indexOf("yt-player") === 0) { @@ -3391,7 +3391,7 @@ }); } - // pages/duckplayer/src/js/index.js + // pages/duckplayer/src/index.js var DuckplayerPage = class { /** * @param {import("@duckduckgo/messaging").Messaging} messaging @@ -3403,7 +3403,7 @@ /** * This will be sent if the application has loaded, but a client-side error * has occurred that cannot be recovered from - * @returns {Promise} + * @returns {Promise} */ initialSetup() { if (this.injectName === "integration") { @@ -3427,7 +3427,7 @@ /** * This is sent when the user wants to set Duck Player as the default. * - * @param {import("../../../../types/duckplayer").UserValues} userValues + * @param {import("../types/duckplayer.ts").UserValues} userValues */ setUserValues(userValues) { return this.messaging.request("setUserValues", userValues); @@ -3467,7 +3467,7 @@ * } * ``` * - * @param {(value: import("../../../../types/duckplayer").UserValues) => void} cb + * @param {(value: import("../types/duckplayer.ts").UserValues) => void} cb */ onUserValuesChanged(cb) { return this.messaging.subscribe("onUserValuesChanged", cb); @@ -3501,7 +3501,7 @@ this.messaging = messaging2; } /** - * @param {import('../../../../types/duckplayer').TelemetryEvent} event + * @param {import('../types/duckplayer.ts').TelemetryEvent} event * @internal */ _event(event) { diff --git a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/inline.js b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/inline.js similarity index 90% rename from node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/inline.js rename to node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/inline.js index 6f18bb2bfd2e..41908278e673 100644 --- a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/inline.js +++ b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/inline.js @@ -1,6 +1,6 @@ "use strict"; (() => { - // pages/duckplayer/src/js/inline.js + // pages/duckplayer/src/inline.js var param = new URLSearchParams(window.location.search).get("platform"); if (isAllowed(param)) { document.documentElement.dataset.platform = String(param); diff --git a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/mobile-bg-GCRU67TC.jpg b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/mobile-bg-GCRU67TC.jpg similarity index 100% rename from node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/mobile-bg-GCRU67TC.jpg rename to node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/mobile-bg-GCRU67TC.jpg diff --git a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/player-bg-F7QLKTXS.jpg b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/player-bg-F7QLKTXS.jpg similarity index 100% rename from node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/player-bg-F7QLKTXS.jpg rename to node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/dist/player-bg-F7QLKTXS.jpg diff --git a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/index.html b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/index.html index f48bb6eef269..0c4099075b32 100644 --- a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/index.html +++ b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/index.html @@ -4,11 +4,11 @@ Duck Player - - + +
- + diff --git a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/storage.js b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/storage.js deleted file mode 100644 index be18978d7789..000000000000 --- a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/storage.js +++ /dev/null @@ -1,32 +0,0 @@ -function deleteStorage(subject) { - Object.keys(subject).forEach((key) => { - if (key.indexOf('yt-player') === 0) { - return; - } - subject.removeItem(key); - }); -} - -function deleteAllCookies() { - const cookies = document.cookie.split(';'); - for (let i = 0; i < cookies.length; i++) { - const cookie = cookies[i]; - const eqPos = cookie.indexOf('='); - const name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie; - document.cookie = name + '=;expires=Thu, 01 Jan 1970 00:00:00 GMT;domain=youtube-nocookie.com;path=/;'; - } -} - -export function initStorage() { - window.addEventListener('unload', () => { - deleteStorage(localStorage); - deleteStorage(sessionStorage); - deleteAllCookies(); - }); - - window.addEventListener('load', () => { - deleteStorage(localStorage); - deleteStorage(sessionStorage); - deleteAllCookies(); - }); -} diff --git a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/utils.js b/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/utils.js deleted file mode 100644 index 19781547aeab..000000000000 --- a/node_modules/@duckduckgo/content-scope-scripts/build/android/pages/duckplayer/js/utils.js +++ /dev/null @@ -1,40 +0,0 @@ -import { VideoParams } from 'injected/src/features/duckplayer/util.js'; - -/** - * @param {string} href - * @param {string} urlBase - * @return {null | string} - */ -export function createYoutubeURLForError(href, urlBase) { - const valid = VideoParams.forWatchPage(href); - if (!valid) return null; - - // this will not throw, since it was guarded above - const original = new URL(href); - - // for now, we're only intercepting clicks when `emb_err_woyt` is present - // this may not be enough to cover all situations, but it solves our immediate - // problems whilst keeping the blast radius low - if (original.searchParams.get('feature') !== 'emb_err_woyt') return null; - - // if we get this far, we think a click is occurring that would cause a navigation loop - // construct the 'next' url - const url = new URL(urlBase); - url.searchParams.set('v', valid.id); - - if (typeof valid.time === 'string') { - url.searchParams.set('t', valid.time); - } - - return url.toString(); -} - -/** - * @param {string|null|undefined} iframeTitle - * @return {string | null} - */ -export function getValidVideoTitle(iframeTitle) { - if (typeof iframeTitle !== 'string') return null; - if (iframeTitle === 'YouTube') return null; - return iframeTitle.replace(/ - YouTube$/g, ''); -} diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/.npmignore b/node_modules/@duckduckgo/privacy-dashboard/build/app/.npmignore new file mode 100644 index 000000000000..f9be8dfe0908 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/.npmignore @@ -0,0 +1 @@ +!* diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/font/.npmignore b/node_modules/@duckduckgo/privacy-dashboard/build/app/font/.npmignore new file mode 100644 index 000000000000..f9be8dfe0908 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/font/.npmignore @@ -0,0 +1 @@ +!* diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/.npmignore b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/.npmignore new file mode 100644 index 000000000000..f9be8dfe0908 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/.npmignore @@ -0,0 +1 @@ +!* diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/android.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/android.html deleted file mode 100644 index 7c9b0a2f8b0a..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/android.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - DuckDuckGo - - - - - - -
- - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/browser.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/browser.html deleted file mode 100644 index 1da908bbb756..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/browser.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - DuckDuckGo - - - - - - -
- - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/ios.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/ios.html deleted file mode 100644 index c20561b583fd..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/ios.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - DuckDuckGo - - - - - - -
- - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/macos.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/macos.html deleted file mode 100644 index 4f83c6830c37..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/macos.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - DuckDuckGo - - - - - - -
- - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/popup.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/popup.html deleted file mode 100644 index cba0171ac1df..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/popup.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - DuckDuckGo - - - - - - -
- - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/windows.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/html/windows.html deleted file mode 100644 index 1c4578fe6407..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/html/windows.html +++ /dev/null @@ -1,32 +0,0 @@ - - - - - - - DuckDuckGo - - - - - - -
- - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/.npmignore b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/.npmignore new file mode 100644 index 000000000000..f9be8dfe0908 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/.npmignore @@ -0,0 +1 @@ +!* diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow--large.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow--large.svg deleted file mode 100644 index b0fac34d7f5f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow--large.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@2x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@2x.png deleted file mode 100644 index 028fe33a282a..000000000000 Binary files a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@2x.png and /dev/null differ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@3x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@3x.png deleted file mode 100644 index 83d8e275fe89..000000000000 Binary files a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/arrow@3x.png and /dev/null differ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--off.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--off.svg deleted file mode 100644 index 0ab2130baa2d..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--off.svg +++ /dev/null @@ -1 +0,0 @@ -Icon OFF- Networks Blocked \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--on.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--on.svg deleted file mode 100644 index de51d5669252..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/blocking--on.svg +++ /dev/null @@ -1 +0,0 @@ -Icon ON- Networks Blocked \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/broken-bicycle.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/broken-bicycle.svg deleted file mode 100644 index c6c6e9024e8a..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/broken-bicycle.svg +++ /dev/null @@ -1,87 +0,0 @@ - - - - Group 73 - Created with Sketch. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/check.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/check.svg deleted file mode 100644 index 415122ee30d6..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/check.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/close.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/close.svg deleted file mode 100644 index 163acb0e33c3..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/close.svg +++ /dev/null @@ -1,12 +0,0 @@ - -Union -Created using Figma - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/ddg-icon@2x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/ddg-icon@2x.png deleted file mode 100644 index 41ca76607be4..000000000000 Binary files a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/ddg-icon@2x.png and /dev/null differ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/ddg-logo-simple@2x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/ddg-logo-simple@2x.png deleted file mode 100644 index 131a5189a303..000000000000 Binary files a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/ddg-logo-simple@2x.png and /dev/null differ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/error.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/error.svg deleted file mode 100644 index fabecd0fbff3..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/error.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/fire-button-header.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/fire-button-header.svg deleted file mode 100644 index 1151a5e558d1..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/fire-button-header.svg +++ /dev/null @@ -1,26 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks-big.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks-big.svg deleted file mode 100644 index 4f5e241b570f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks-big.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks.svg deleted file mode 100644 index 8c6a43371303..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-on-major-networks.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__bad.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__bad.svg deleted file mode 100644 index 2f5a1aceef19..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__bad.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__good.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__good.svg deleted file mode 100644 index 4527a8f0e3c3..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__good.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__mixed.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__mixed.svg deleted file mode 100644 index 1801055f44d3..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-ribbon__mixed.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-warning-major-networks.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-warning-major-networks.svg deleted file mode 100644 index 8ee83ae4dbdd..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/hero-warning-major-networks.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--off.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--off.svg deleted file mode 100644 index 03e4ef15071b..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--off.svg +++ /dev/null @@ -1 +0,0 @@ -Icon OFF- Connection \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--on.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--on.svg deleted file mode 100644 index 534f54444e7d..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/https--on.svg +++ /dev/null @@ -1 +0,0 @@ -Icon ON- Connection \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_128.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_128.png deleted file mode 100755 index e661553ef452..000000000000 Binary files a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_128.png and /dev/null differ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_16.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_16.png deleted file mode 100644 index d2f71339abe3..000000000000 Binary files a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_16.png and /dev/null differ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_19.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_19.png deleted file mode 100644 index 149582f90ba9..000000000000 Binary files a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_19.png and /dev/null differ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_38.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_38.png deleted file mode 100644 index 74e80cffe1c3..000000000000 Binary files a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_38.png and /dev/null differ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_48.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_48.png deleted file mode 100755 index 3346cbf3f62b..000000000000 Binary files a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/icon_48.png and /dev/null differ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal.png deleted file mode 100644 index 259aaa6d9c8f..000000000000 Binary files a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal.png and /dev/null differ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@2x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@2x.png deleted file mode 100644 index 10487147fb3e..000000000000 Binary files a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@2x.png and /dev/null differ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@3x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@3x.png deleted file mode 100644 index 8d88fd63053e..000000000000 Binary files a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-horizontal@3x.png and /dev/null differ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-small-new.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-small-new.svg deleted file mode 100644 index 40cfface0ef3..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-small-new.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-small.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-small.svg deleted file mode 100644 index 4f4179f7a888..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/logo-small.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/loupe.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/loupe.svg deleted file mode 100644 index 595f4092e713..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/loupe.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--bad.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--bad.svg deleted file mode 100644 index 3f1ac0baf712..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--bad.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--good.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--good.svg deleted file mode 100644 index b749e73b61a1..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--good.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--mixed.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--mixed.svg deleted file mode 100644 index aa7a3cc20844..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/privacy--mixed.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Allowed-96.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Allowed-96.svg deleted file mode 100644 index 3bdc8437306b..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Allowed-96.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Disabled-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Disabled-128.svg deleted file mode 100644 index 7feac82df076..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Disabled-128.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Info-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Info-128.svg deleted file mode 100644 index ab30f2c6854f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Block-Info-128.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-128.svg deleted file mode 100644 index 9743f903c955..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-128.svg +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-96.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-96.svg deleted file mode 100644 index 26b2b27cc47e..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Breakage-96.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Check-Color-16.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Check-Color-16.svg deleted file mode 100644 index fbc0e1800214..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Check-Color-16.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Hidden-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Hidden-128.svg deleted file mode 100644 index 3c7720d7c1fb..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Hidden-128.svg +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Managed-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Managed-128.svg deleted file mode 100644 index 0b97dd242cb6..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Cookies-Managed-128.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Counter-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Counter-128.svg deleted file mode 100644 index acc7e592179a..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Counter-128.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Error-Color-16.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Error-Color-16.svg deleted file mode 100644 index 9d536db9607f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Error-Color-16.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-128.svg deleted file mode 100644 index aa650f927a0c..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-128.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-96.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-96.svg deleted file mode 100644 index 8120be1fde02..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Locked-96.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Network-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Network-128.svg deleted file mode 100644 index 9393f7e9c04f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Network-128.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Phishing-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Phishing-128.svg deleted file mode 100644 index bac34c4036c7..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Phishing-128.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Shield-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Shield-128.svg deleted file mode 100644 index da13b75c79c6..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Shield-128.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Stop-Grey-16.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Stop-Grey-16.svg deleted file mode 100644 index 5d644c8cc65a..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Stop-Grey-16.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-128.svg deleted file mode 100644 index 9eb63ce5bb61..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-128.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-96.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-96.svg deleted file mode 100644 index a97be77f652e..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/Unlocked-96.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow--light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow--light.svg deleted file mode 100644 index 1553bd9eceba..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow--light.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android--light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android--light.svg deleted file mode 100644 index bb9ce40066db..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android--light.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android.svg deleted file mode 100644 index 284e3274ecb9..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow-android.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow.svg deleted file mode 100644 index 72e560547da0..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-arrow.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios--light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios--light.svg deleted file mode 100644 index b901366815ec..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios--light.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios.svg deleted file mode 100644 index 4fd2d0704d74..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/back-chevron-ios.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/breakage-sent.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/breakage-sent.svg deleted file mode 100644 index 8ae55c2b93e8..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/breakage-sent.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chat-private-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chat-private-128.svg deleted file mode 100644 index 8efa014dec0c..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chat-private-128.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron--light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron--light.svg deleted file mode 100644 index 5bb6f1dbe0b6..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron--light.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron.svg deleted file mode 100644 index 7ab5fb3393a8..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/chevron.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera-light.svg deleted file mode 100644 index c8277654d710..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera-light.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera.svg deleted file mode 100644 index 8850b78a635a..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-camera.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme-light.svg deleted file mode 100644 index 8233dd2c9344..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme-light.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme.svg deleted file mode 100644 index 0eb789d68a08..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-externalScheme.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location-light.svg deleted file mode 100644 index 6724f6ae8f4a..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location-light.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location.svg deleted file mode 100644 index 12a8ece441cc..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-location.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone-light.svg deleted file mode 100644 index 9a39aad5e9fc..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone-light.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone.svg deleted file mode 100644 index 1c99013109e3..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-microphone.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification-light.svg deleted file mode 100644 index 3fa19cfa016f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification-light.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification.svg deleted file mode 100644 index a25af02d7840..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-notification.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups-light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups-light.svg deleted file mode 100644 index beb4a7c968e2..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups-light.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups.svg deleted file mode 100644 index 51fd6569d4f5..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/permissions-popups.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/switch-shield-128.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/switch-shield-128.svg deleted file mode 100644 index 503c722ce911..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/switch-shield-128.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/A.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/A.svg deleted file mode 100644 index 41de0c0e7517..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/A.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/B.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/B.svg deleted file mode 100644 index 2f60d2dce0c3..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/B.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/C.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/C.svg deleted file mode 100644 index 90eaf7b9afde..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/C.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/D.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/D.svg deleted file mode 100644 index db24c455872c..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/D.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/E.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/E.svg deleted file mode 100644 index ad198885039b..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/E.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/F.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/F.svg deleted file mode 100644 index 48e96aec6201..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/F.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/G.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/G.svg deleted file mode 100644 index 7699a554bae4..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/G.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/H.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/H.svg deleted file mode 100644 index 54966438d6da..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/H.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/I.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/I.svg deleted file mode 100644 index 217710ed392a..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/I.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/J.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/J.svg deleted file mode 100644 index 557f383ef140..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/J.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/K.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/K.svg deleted file mode 100644 index 9a607d3be398..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/K.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/L.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/L.svg deleted file mode 100644 index 27a4e261430d..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/L.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/M.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/M.svg deleted file mode 100644 index 6ab437376ac9..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/M.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/N.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/N.svg deleted file mode 100644 index a07fd9d3343c..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/N.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/O.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/O.svg deleted file mode 100644 index ebd1150930fc..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/O.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/P.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/P.svg deleted file mode 100644 index a82731fd0f6f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/P.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Q.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Q.svg deleted file mode 100644 index efbc7e7d2bc1..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Q.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/R.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/R.svg deleted file mode 100644 index fd18ad222138..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/R.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/S.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/S.svg deleted file mode 100644 index 71d9a7283602..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/S.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/T.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/T.svg deleted file mode 100644 index 691de321114d..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/T.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/U.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/U.svg deleted file mode 100644 index 2eede0c86d82..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/U.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/V.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/V.svg deleted file mode 100644 index 1a9f05da238e..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/V.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/W.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/W.svg deleted file mode 100644 index 3c67bb2432c3..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/W.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/X.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/X.svg deleted file mode 100644 index 5a018ca116c5..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/X.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Y.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Y.svg deleted file mode 100644 index 9df9996b2519..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Y.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Z.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Z.svg deleted file mode 100644 index e5b1f3601112..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/letters/Z.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adjust.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adjust.svg deleted file mode 100644 index 73061f624a4d..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adjust.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adobe.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adobe.svg deleted file mode 100644 index 6c55271db543..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/adobe.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amazon.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amazon.svg deleted file mode 100644 index 078b7f3ca596..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amazon.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amplitude.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amplitude.svg deleted file mode 100644 index 7c2201d756a9..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/amplitude.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appnexus.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appnexus.svg deleted file mode 100644 index 78b3fc219c7f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appnexus.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appsflyer.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appsflyer.svg deleted file mode 100644 index ec5fb508fb54..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/appsflyer.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/beeswax.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/beeswax.svg deleted file mode 100644 index ebaef38672e7..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/beeswax.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/branchmetrics.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/branchmetrics.svg deleted file mode 100644 index a2ecd8951fc5..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/branchmetrics.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/braze.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/braze.svg deleted file mode 100644 index 2886bd063bf0..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/braze.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/bugsnag.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/bugsnag.svg deleted file mode 100644 index a159993eb801..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/bugsnag.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/chartbeat.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/chartbeat.svg deleted file mode 100644 index 44ef561b9d82..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/chartbeat.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/comscore.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/comscore.svg deleted file mode 100644 index 9fbe6cc2d396..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/comscore.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/criteo.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/criteo.svg deleted file mode 100644 index ef918b151f48..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/criteo.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/facebook.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/facebook.svg deleted file mode 100644 index 74f82edf6f51..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/facebook.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/google.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/google.svg deleted file mode 100644 index e0bf2621cec7..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/google.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg deleted file mode 100644 index 22335b2d6445..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg deleted file mode 100644 index b228eb881dc4..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/indexexchange.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/indexexchange.svg deleted file mode 100644 index 95588eee0ad9..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/indexexchange.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/instagramfacebook.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/instagramfacebook.svg deleted file mode 100644 index 84f0a83a41d6..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/instagramfacebook.svg +++ /dev/null @@ -1,24 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/iponweb.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/iponweb.svg deleted file mode 100644 index 0f5f6bd37818..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/iponweb.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/kochava.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/kochava.svg deleted file mode 100644 index 88ec01584b52..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/kochava.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/linkedin.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/linkedin.svg deleted file mode 100644 index 9c83f7776d96..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/linkedin.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/liveramp.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/liveramp.svg deleted file mode 100644 index cb9c6419ab41..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/liveramp.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/magnite.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/magnite.svg deleted file mode 100644 index 82f881f1ef58..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/magnite.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mediamath.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mediamath.svg deleted file mode 100644 index 90952097ed49..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mediamath.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/microsoft.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/microsoft.svg deleted file mode 100644 index 42306cc6f258..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/microsoft.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mixpanel.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mixpanel.svg deleted file mode 100644 index ca839565481c..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/mixpanel.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/neustar.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/neustar.svg deleted file mode 100644 index 4a172fc9cfd8..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/neustar.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/newrelic.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/newrelic.svg deleted file mode 100644 index b249a46bdc68..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/newrelic.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/openx.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/openx.svg deleted file mode 100644 index cc9a12fba995..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/openx.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/oracle.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/oracle.svg deleted file mode 100644 index 710faa0ac489..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/oracle.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/outbrain.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/outbrain.svg deleted file mode 100644 index 1ae3cb6236ac..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/outbrain.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pinterest.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pinterest.svg deleted file mode 100644 index 1861c6fda86f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pinterest.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pubmatic.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pubmatic.svg deleted file mode 100644 index 24dfbe3c552c..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/pubmatic.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/quantcast.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/quantcast.svg deleted file mode 100644 index 1e7b7bc1d08f..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/quantcast.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/rythmone.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/rythmone.svg deleted file mode 100644 index cd1c24272388..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/rythmone.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/salesforce.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/salesforce.svg deleted file mode 100644 index 7ea9317db840..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/salesforce.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/sharetrough.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/sharetrough.svg deleted file mode 100644 index 3e9f9a865c4d..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/sharetrough.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/smaato.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/smaato.svg deleted file mode 100644 index bce4703b7311..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/smaato.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/spotx.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/spotx.svg deleted file mode 100644 index 8c511ae16ada..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/spotx.svg +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/taboola.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/taboola.svg deleted file mode 100644 index fb4b829cb20b..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/taboola.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/tapad.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/tapad.svg deleted file mode 100644 index 1ac1ff7989f5..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/tapad.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thenielsencompany.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thenielsencompany.svg deleted file mode 100644 index 6de712e80d55..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thenielsencompany.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thetradedesk.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thetradedesk.svg deleted file mode 100644 index c364b6bc78ac..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/thetradedesk.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/twitter.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/twitter.svg deleted file mode 100644 index 1d28fca2dcb1..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/twitter.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/urbanairship.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/urbanairship.svg deleted file mode 100644 index 95e5854c3e08..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/urbanairship.svg +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/verizonmedia.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/verizonmedia.svg deleted file mode 100644 index d2388f83ab79..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/verizonmedia.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/warnermedia.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/warnermedia.svg deleted file mode 100644 index 8be72004993c..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/warnermedia.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/xaxis.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/xaxis.svg deleted file mode 100644 index 622c53da79f6..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/xaxis.svg +++ /dev/null @@ -1,376 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yahoojapan.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yahoojapan.svg deleted file mode 100644 index f30bfa642c27..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yahoojapan.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yandex.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yandex.svg deleted file mode 100644 index 94cdab1a79a0..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/yandex.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/youtubegoogle.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/youtubegoogle.svg deleted file mode 100644 index 559e5b863820..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/youtubegoogle.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/zeotap.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/zeotap.svg deleted file mode 100644 index 5bbdbd28280e..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/refresh-assets/tracker-icons/logos/zeotap.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/settings-gear@2x.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/settings-gear@2x.png deleted file mode 100644 index 73706c82f1ef..000000000000 Binary files a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/settings-gear@2x.png and /dev/null differ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/shield.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/shield.svg deleted file mode 100644 index dbb455ffa73c..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/shield.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_comment.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_comment.svg deleted file mode 100644 index 4d5c03f44e62..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_comment.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_facebook_logo.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_facebook_logo.svg deleted file mode 100644 index 85492e752622..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_facebook_logo.svg +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_group.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_group.svg deleted file mode 100644 index 06ef74dbea90..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_group.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_page.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_page.svg deleted file mode 100644 index a719dfda7cac..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_page.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_post.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_post.svg deleted file mode 100644 index 729c1332ae7e..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_post.svg +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_video.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_video.svg deleted file mode 100644 index 0223061416e7..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/blocked_video.svg +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/dax.png b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/dax.png deleted file mode 100644 index d86991121305..000000000000 Binary files a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/dax.png and /dev/null differ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_dark.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_dark.svg deleted file mode 100644 index e7fa529fbad5..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_dark.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_light.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_light.svg deleted file mode 100644 index 09d92456dfbf..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/social/loading_light.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/spinner.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/spinner.svg deleted file mode 100644 index 616649e71fec..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/spinner.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--bad.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--bad.svg deleted file mode 100644 index 86b88037dfa2..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--bad.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--good.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--good.svg deleted file mode 100644 index c82fddf86b52..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--good.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--info.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--info.svg deleted file mode 100644 index ad24185a26a1..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--info.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--mixed.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--mixed.svg deleted file mode 100644 index 3910c2941080..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/status--mixed.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/wand.svg b/node_modules/@duckduckgo/privacy-dashboard/build/app/img/wand.svg deleted file mode 100644 index df1d25f89b9e..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/img/wand.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/index.html b/node_modules/@duckduckgo/privacy-dashboard/build/app/index.html deleted file mode 100644 index a9b67364af59..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/index.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - Privacy Dashboard - - -

Links

- - - diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/.npmignore b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/.npmignore new file mode 100644 index 000000000000..f9be8dfe0908 --- /dev/null +++ b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/.npmignore @@ -0,0 +1 @@ +!* diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/android.css b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/android.css deleted file mode 100644 index b21ec65a2e2a..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/android.css +++ /dev/null @@ -1,148 +0,0 @@ -.material-design-ripple { - --mdc-ripple-fg-size: 0; - --mdc-ripple-left: 0; - --mdc-ripple-top: 0; - --mdc-ripple-fg-scale: 1; - --mdc-ripple-fg-translate-end: 0; - --mdc-ripple-fg-translate-start: 0; - -webkit-tap-highlight-color: rgba(0, 0, 0, 0); - will-change: transform, opacity; - overflow: hidden; -} -.material-design-ripple::before, .material-design-ripple::after { - position: absolute; - border-radius: 50%; - opacity: 0; - pointer-events: none; - content: ""; -} -.material-design-ripple::before { - transition: opacity 15ms linear, background-color 15ms linear; - z-index: 1; - /* @alternate */ - z-index: var(--mdc-ripple-z-index, 1); -} -.material-design-ripple::after { - z-index: 0; - /* @alternate */ - z-index: var(--mdc-ripple-z-index, 0); -} -.material-design-ripple.mdc-ripple-upgraded::before { - transform: scale(var(--mdc-ripple-fg-scale, 1)); -} -.material-design-ripple.mdc-ripple-upgraded::after { - top: 0; - /* @noflip */ /*rtl:ignore*/ - left: 0; - transform: scale(0); - transform-origin: center center; -} -.material-design-ripple.mdc-ripple-upgraded--unbounded::after { - top: var(--mdc-ripple-top, 0); - /* @noflip */ /*rtl:ignore*/ - left: var(--mdc-ripple-left, 0); -} -.material-design-ripple.mdc-ripple-upgraded--foreground-activation::after { - animation: mdc-ripple-fg-radius-in 225ms forwards, mdc-ripple-fg-opacity-in 75ms forwards; -} -.material-design-ripple.mdc-ripple-upgraded--foreground-deactivation::after { - animation: mdc-ripple-fg-opacity-out 150ms; - transform: translate(var(--mdc-ripple-fg-translate-end, 0)) scale(var(--mdc-ripple-fg-scale, 1)); -} -.material-design-ripple::before, .material-design-ripple::after { - top: calc(50% - 100%); - /* @noflip */ /*rtl:ignore*/ - left: calc(50% - 100%); - width: 200%; - height: 200%; -} -.material-design-ripple.mdc-ripple-upgraded::after { - width: var(--mdc-ripple-fg-size, 100%); - height: var(--mdc-ripple-fg-size, 100%); -} -.material-design-ripple::before, .material-design-ripple::after { - background-color: #000; - /* @alternate */ - background-color: var(--mdc-ripple-color, #000); -} -.material-design-ripple:hover::before, .material-design-ripple.mdc-ripple-surface--hover::before { - opacity: 0.04; - /* @alternate */ - opacity: var(--mdc-ripple-hover-opacity, 0.04); -} -.material-design-ripple.mdc-ripple-upgraded--background-focused::before, .material-design-ripple:not(.mdc-ripple-upgraded):focus::before { - transition-duration: 75ms; - opacity: 0.12; - /* @alternate */ - opacity: var(--mdc-ripple-focus-opacity, 0.12); -} -.material-design-ripple:not(.mdc-ripple-upgraded)::after { - transition: opacity 150ms linear; -} -.material-design-ripple:not(.mdc-ripple-upgraded):active::after { - transition-duration: 75ms; - opacity: 0.12; - /* @alternate */ - opacity: var(--mdc-ripple-press-opacity, 0.12); -} -.material-design-ripple.mdc-ripple-upgraded { - --mdc-ripple-fg-opacity: var(--mdc-ripple-press-opacity, 0.12); -} - -.body--theme-light .material-design-ripple::before, .body--theme-light .material-design-ripple::after { - background-color: black; - /* @alternate */ - background-color: var(--mdc-ripple-color, black); -} -.body--theme-light .material-design-ripple:hover::before, .body--theme-light .material-design-ripple.mdc-ripple-surface--hover::before { - opacity: 0; - /* @alternate */ - opacity: var(--mdc-ripple-hover-opacity, 0); -} -.body--theme-light .material-design-ripple.mdc-ripple-upgraded--background-focused::before, .body--theme-light .material-design-ripple:not(.mdc-ripple-upgraded):focus::before { - transition-duration: 75ms; - opacity: 0.08; - /* @alternate */ - opacity: var(--mdc-ripple-focus-opacity, 0.08); -} -.body--theme-light .material-design-ripple:not(.mdc-ripple-upgraded)::after { - transition: opacity 150ms linear; -} -.body--theme-light .material-design-ripple:not(.mdc-ripple-upgraded):active::after { - transition-duration: 75ms; - opacity: 0.08; - /* @alternate */ - opacity: var(--mdc-ripple-press-opacity, 0.08); -} -.body--theme-light .material-design-ripple.mdc-ripple-upgraded { - --mdc-ripple-fg-opacity: var(--mdc-ripple-press-opacity, 0.08); -} - -.body--theme-dark .material-design-ripple::before, .body--theme-dark .material-design-ripple::after { - background-color: white; - /* @alternate */ - background-color: var(--mdc-ripple-color, white); -} -.body--theme-dark .material-design-ripple:hover::before, .body--theme-dark .material-design-ripple.mdc-ripple-surface--hover::before { - opacity: 0; - /* @alternate */ - opacity: var(--mdc-ripple-hover-opacity, 0); -} -.body--theme-dark .material-design-ripple.mdc-ripple-upgraded--background-focused::before, .body--theme-dark .material-design-ripple:not(.mdc-ripple-upgraded):focus::before { - transition-duration: 75ms; - opacity: 0.3; - /* @alternate */ - opacity: var(--mdc-ripple-focus-opacity, 0.3); -} -.body--theme-dark .material-design-ripple:not(.mdc-ripple-upgraded)::after { - transition: opacity 150ms linear; -} -.body--theme-dark .material-design-ripple:not(.mdc-ripple-upgraded):active::after { - transition-duration: 75ms; - opacity: 0.3; - /* @alternate */ - opacity: var(--mdc-ripple-press-opacity, 0.3); -} -.body--theme-dark .material-design-ripple.mdc-ripple-upgraded { - --mdc-ripple-fg-opacity: var(--mdc-ripple-press-opacity, 0.3); -} diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/base.css b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/base.css deleted file mode 100644 index 2721c686a2f4..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/base.css +++ /dev/null @@ -1,765 +0,0 @@ -/* Status icons */ -/* Colors */ -/* Dark theme */ -/* Neutral Colors */ -/* #888 */ -/* #d0d0d0 */ -/* Cards */ -/* CSS Arrow */ -/* links */ -/** Separators */ -/* Status icons */ -/* Colors */ -/* Dark theme */ -/* Neutral Colors */ -/* #888 */ -/* #d0d0d0 */ -/* Cards */ -/* CSS Arrow */ -/* links */ -/** Separators */ -/* Logo */ -/* Font groupings */ -.uppercase { - font-size: 12px; - color: #888888; - text-transform: uppercase; - letter-spacing: 0.1em; - font-weight: bold; -} - -/* Lists */ -/* Images & icons */ -/* Cross-platform background image */ -* { - box-sizing: border-box; -} - -/* Normalize File */ -/*! normalize.scss v0.1.0 | MIT License | based on git.io/normalize */ -/** - * 1. Set default font family to sans-serif. - * 2. Prevent iOS text size adjust after orientation change, without disabling - * user zoom. - */ -html { - font-family: sans-serif; /* 1 */ - -ms-text-size-adjust: 100%; /* 2 */ - -webkit-text-size-adjust: 100%; /* 2 */ -} - -/** - * Remove default margin. - */ -body { - margin: 0; -} - -/* HTML5 display definitions - ========================================================================== */ -/** - * Correct `block` display not defined for any HTML5 element in IE 8/9. - * Correct `block` display not defined for `details` or `summary` in IE 10/11 - * and Firefox. - * Correct `block` display not defined for `main` in IE 11. - */ -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -main, -menu, -nav, -section, -summary { - display: block; -} - -/** - * 1. Correct `inline-block` display not defined in IE 8/9. - * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera. - */ -audio, -canvas, -progress, -video { - display: inline-block; /* 1 */ - vertical-align: baseline; /* 2 */ -} - -/** - * Prevent modern browsers from displaying `audio` without controls. - * Remove excess height in iOS 5 devices. - */ -audio:not([controls]) { - display: none; - height: 0; -} - -/** - * Address `[hidden]` styling not present in IE 8/9/10. - * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22. - */ -[hidden], -template { - display: none; -} - -/* Links - ========================================================================== */ -/** - * Remove the gray background color from active links in IE 10. - */ -a { - background-color: transparent; -} - -/** - * Improve readability when focused and also mouse hovered in all browsers. - */ -a:active, -a:hover { - outline: 0; -} - -/* Text-level semantics - ========================================================================== */ -/** - * Address styling not present in IE 8/9/10/11, Safari, and Chrome. - */ -abbr[title] { - border-bottom: 1px dotted; -} - -/** - * Address style set to `bolder` in Firefox 4+, Safari, and Chrome. - */ -b, -strong { - font-weight: bold; -} - -/** - * Address styling not present in Safari and Chrome. - */ -dfn { - font-style: italic; -} - -/** - * Address variable `h1` font-size and margin within `section` and `article` - * contexts in Firefox 4+, Safari, and Chrome. - */ -h1 { - font-size: 2em; - margin: 0.67em 0; -} - -/** - * Address styling not present in IE 8/9. - */ -mark { - background: #ff0; - color: #000; -} - -/** - * Address inconsistent and variable font size in all browsers. - */ -small { - font-size: 80%; -} - -/** - * Prevent `sub` and `sup` affecting `line-height` in all browsers. - */ -sub, -sup { - font-size: 75%; - line-height: 0; - position: relative; - vertical-align: baseline; -} - -sup { - top: -0.5em; -} - -sub { - bottom: -0.25em; -} - -/* Embedded content - ========================================================================== */ -/** - * Remove border when inside `a` element in IE 8/9/10. - */ -img { - border: 0; -} - -/** - * Correct overflow not hidden in IE 9/10/11. - */ -svg:not(:root) { - overflow: hidden; -} - -/* Grouping content - ========================================================================== */ -/** - * Address margin not present in IE 8/9 and Safari. - */ -figure { - margin: 1em 40px; -} - -/** - * Address differences between Firefox and other browsers. - */ -hr { - -moz-box-sizing: content-box; - box-sizing: content-box; - height: 0; -} - -/** - * Contain overflow in all browsers. - */ -pre { - overflow: auto; -} - -/** - * Address odd `em`-unit font size rendering in all browsers. - */ -code, -kbd, -pre, -samp { - font-family: monospace, monospace; - font-size: 1em; -} - -/* Forms - ========================================================================== */ -/** - * Known limitation: by default, Chrome and Safari on OS X allow very limited - * styling of `select`, unless a `border` property is set. - */ -/** - * 1. Correct color not being inherited. - * Known issue: affects color of disabled elements. - * 2. Correct font properties not being inherited. - * 3. Address margins set differently in Firefox 4+, Safari, and Chrome. - */ -button, -input, -optgroup, -select, -textarea { - color: inherit; /* 1 */ - font: inherit; /* 2 */ - margin: 0; /* 3 */ -} - -/** - * Address `overflow` set to `hidden` in IE 8/9/10/11. - */ -button { - overflow: visible; -} - -/** - * Address inconsistent `text-transform` inheritance for `button` and `select`. - * All other form control elements do not inherit `text-transform` values. - * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera. - * Correct `select` style inheritance in Firefox. - */ -button, -select { - text-transform: none; -} - -/** - * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio` - * and `video` controls. - * 2. Correct inability to style clickable `input` types in iOS. - * 3. Improve usability and consistency of cursor style between image-type - * `input` and others. - */ -button, -html input[type=button], -input[type=reset], -input[type=submit] { - -webkit-appearance: button; /* 2 */ - cursor: pointer; /* 3 */ -} - -/** - * Re-set default cursor for disabled elements. - */ -button[disabled], -html input[disabled] { - cursor: default; -} - -/** - * Remove inner padding and border in Firefox 4+. - */ -button::-moz-focus-inner, -input::-moz-focus-inner { - border: 0; - padding: 0; -} - -/** - * Address Firefox 4+ setting `line-height` on `input` using `!important` in - * the UA stylesheet. - */ -input { - line-height: normal; -} - -/** - * It's recommended that you don't attempt to style these elements. - * Firefox's implementation doesn't respect box-sizing, padding, or width. - * - * 1. Address box sizing set to `content-box` in IE 8/9/10. - * 2. Remove excess padding in IE 8/9/10. - */ -input[type=checkbox], -input[type=radio] { - box-sizing: border-box; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Fix the cursor style for Chrome's increment/decrement buttons. For certain - * `font-size` values of the `input`, it causes the cursor style of the - * decrement button to change from `default` to `text`. - */ -input[type=number]::-webkit-inner-spin-button, -input[type=number]::-webkit-outer-spin-button { - height: auto; -} - -/** - * 1. Address `appearance` set to `searchfield` in Safari and Chrome. - * 2. Address `box-sizing` set to `border-box` in Safari and Chrome - * (include `-moz` to future-proof). - */ -input[type=search] { - -webkit-appearance: textfield; /* 1 */ - -moz-box-sizing: content-box; - -webkit-box-sizing: content-box; /* 2 */ - box-sizing: content-box; -} - -/** - * Remove inner padding and search cancel button in Safari and Chrome on OS X. - * Safari (but not Chrome) clips the cancel button when the search input has - * padding (and `textfield` appearance). - */ -input[type=search]::-webkit-search-cancel-button, -input[type=search]::-webkit-search-decoration { - -webkit-appearance: none; -} - -/** - * Define consistent border, margin, and padding. - */ -fieldset { - border: 1px solid #c0c0c0; - margin: 0 2px; - padding: 0.35em 0.625em 0.75em; -} - -/** - * 1. Correct `color` not being inherited in IE 8/9/10/11. - * 2. Remove padding so people aren't caught out if they zero out fieldsets. - */ -legend { - border: 0; /* 1 */ - padding: 0; /* 2 */ -} - -/** - * Remove default vertical scrollbar in IE 8/9/10/11. - */ -textarea { - overflow: auto; -} - -/** - * Don't inherit the `font-weight` (applied by a rule above). - * NOTE: the default cannot safely be changed in Chrome and Safari on OS X. - */ -optgroup { - font-weight: bold; -} - -/* Tables - ========================================================================== */ -/** - * Remove most spacing between table cells. - */ -table { - border-collapse: collapse; - border-spacing: 0; -} - -td, -th { - padding: 0; -} - -/** - * DDG Extension Resets & Base Styles - */ -h1, -h2, -h3, -h4, -h5, -h5, -p, -div { - margin: 0; - padding: 0; -} - -section, -ul, -ol, -li { - margin: 0; - padding: 0; - position: relative; -} - -.environment--android form, -.environment--android input, -.environment--android select, -.environment--android option, -.environment--android button, -.environment--ios form, -.environment--ios input, -.environment--ios select, -.environment--ios option, -.environment--ios button { - outline: none; -} -.environment--android form *, -.environment--android input *, -.environment--android select *, -.environment--android option *, -.environment--android button *, -.environment--ios form *, -.environment--ios input *, -.environment--ios select *, -.environment--ios option *, -.environment--ios button * { - outline: none; -} - -button { - border: none; - background-color: #ffffff; - padding: 0; -} - -/* Fonts */ -input, -textarea, -select { - color: #333333; -} - -.body--theme-dark input, -.body--theme-dark textarea { - color: rgba(255, 255, 255, 0.9); -} -.body--theme-dark input, -.body--theme-dark textarea { - background-color: #333333; -} - -.body--theme-dark.environment--windows select { - background-color: rgba(255, 255, 255, 0.06); - border-color: #444; - color: rgba(255, 255, 255, 0.9); -} - -.body--theme-dark.environment--windows select > option { - background-color: #333333; -} - -.bold { - font-weight: bold; -} - -strong { - font-weight: bold; -} -.environment--browser strong { - font-weight: 600; -} - -/* Links */ -a { - color: var(--color-accent-blue); - text-decoration: none; -} -a:hover { - text-decoration: underline; -} -.environment--ios a.link-action:visited, .environment--ios a.link-action:active, .environment--ios a.link-action:hover, .environment--android a.link-action:visited, .environment--android a.link-action:active, .environment--android a.link-action:hover { - text-decoration: none; -} -a.link-action--text { - padding: 16px 0; - display: block; -} -a.link-action--text-short { - display: block; - padding: 12px 0; -} -a.link-action--text-micro { - display: block; - padding: 8px 0; -} -a.link-action--rounded { - border-radius: 12px; - padding-top: 14px; - padding-bottom: 14px; -} -.environment--ios a.link-action--rounded { - font-size: 14px; - padding-top: 16px; - padding-bottom: 16px; -} -.environment--windows a.link-action--rounded { - line-height: 22px; - font-size: 14px; - padding-top: 16px; - padding-bottom: 16px; -} -.environment--browser a.link-action--rounded { - line-height: 18px; - font-size: 14px; - padding-top: 12px; - padding-bottom: 12px; -} - -/** - * DDG Extension Helper Classes - */ -/* Hide element */ -.is-hidden { - display: none; -} - -/* Position */ -.pull-right { - position: absolute; - right: 16px; -} - -.pull-left { - position: absolute; - left: 16px; -} - -/* Display */ -.block { - display: block; -} - -/* Floats */ -.float-left { - float: left; -} - -.float-right { - float: right; -} - -.clearfix { - clear: both; - height: 0; - line-height: 0; -} - -/* Text Centering */ -.text--center { - text-align: center; -} - -.height-full { - height: 100%; -} - -.text--left { - text-align: left; -} - -/* Text Wrap */ -.text--balance { - text-wrap: balance; -} - -/* Borders */ -.border--top { - border-top: 1px solid var(--color-lines-light); -} - -.border--bottom { - border-bottom: 1px solid var(--color-lines-light); -} - -.border-light--top { - border-top: 1px solid var(--color-lines-lighter); -} - -.border--top--inner { - position: relative; -} -.border--top--inner:before { - content: ""; - border-top: 1px solid var(--color-lines-light); - position: absolute; - top: 0; - left: 0; - right: 0; -} - -.padding-x { - padding-left: 16px; - padding-right: 16px; -} - -.padding-y { - padding-top: 16px; - padding-bottom: 16px; -} - -.padding-y-third { - padding-top: 24px; - padding-bottom: 24px; -} - -.padding-y--reduced { - padding-top: 14px; - padding-bottom: 14px; -} -.environment--ios .padding-y--reduced, .environment--android .padding-y--reduced { - padding-top: 8.5px; - padding-bottom: 8.5px; -} - -.padding-bottom-half { - padding-bottom: 10px; -} - -.bg-primary { - background: white; -} - -.padding-x-double { - padding-left: 32px; - padding-right: 32px; -} - -.padding-x-third { - padding-left: 24px; - padding-right: 24px; -} - -.padding-x-xl { - padding-left: 44px; - padding-right: 44px; -} - -.padded--top { - padding: 24px 0 0; -} - -.padded--no-bottom-padding { - padding-bottom: 0; -} - -/* Icons */ -/* Standard icon display within the extension */ -.icon { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - /* you'll need to set the background image within each instance of .icon */ -} -.icon.icon__close { - width: 14px; - height: 14px; - background-image: url("../../img/close.svg"); -} -.icon.icon__arrow { - width: 12px; - height: 12px; - background-size: contain; - background-image: url("../../img/refresh-assets/chevron.svg"); -} -.body--theme-dark .icon.icon__arrow { - background-image: url("../../img/refresh-assets/chevron--light.svg"); -} -.icon.icon__arrow.icon__arrow--left { - transform: rotate(180deg); -} -.icon.icon__arrow.icon__arrow--large { - width: 7px; - margin-top: -20px; - background-image: url("../../img/arrow--large.svg"); -} -.icon.icon__back-arrow { - background-size: contain; - background-image: url("../../img/refresh-assets/back-arrow.svg"); -} -.body--theme-dark .icon.icon__back-arrow { - background-image: url("../../img/refresh-assets/back-arrow--light.svg"); -} -.environment--android .icon.icon__back-arrow { - background-image: url("../../img/refresh-assets/back-arrow-android.svg"); -} -.body--theme-dark.environment--android .icon.icon__back-arrow { - background-image: url("../../img/refresh-assets/back-arrow-android--light.svg"); -} -.environment--ios .icon.icon__back-arrow { - background-image: url("../../img/refresh-assets/back-chevron-ios.svg"); - width: 20px; - height: 20px; -} -.environment--ios .icon.icon__back-arrow:before { - content: attr(data-icon-text); - display: block; - height: 20px; - line-height: 20px; - margin-left: 20px; -} -.body--theme-dark.environment--ios .icon.icon__back-arrow { - background-image: url("../../img/refresh-assets/back-chevron-ios--light.svg"); -} - -.separator { - width: 1px; - height: 18px; - background-color: rgba(0, 0, 0, 0.05); - display: inline-block; - vertical-align: bottom; - margin: 0 7px; -} diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/popup.css b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/popup.css deleted file mode 100644 index 4d02f2bf9b19..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/css/popup.css +++ /dev/null @@ -1,4095 +0,0 @@ -@charset "UTF-8"; -/* Status icons */ -/* Colors */ -/* Dark theme */ -/* Neutral Colors */ -/* #888 */ -/* #d0d0d0 */ -/* Cards */ -/* CSS Arrow */ -/* links */ -/** Separators */ -/* Status icons */ -/* Colors */ -/* Dark theme */ -/* Neutral Colors */ -/* #888 */ -/* #d0d0d0 */ -/* Cards */ -/* CSS Arrow */ -/* links */ -/** Separators */ -/* Logo */ -/* Font groupings */ -.uppercase { - font-size: 12px; - color: #888888; - text-transform: uppercase; - letter-spacing: 0.1em; - font-weight: bold; -} - -/* Lists */ -/* Images & icons */ -/* Cross-platform background image */ -/** - * We are using a subset of DDG fonts that are compatible with Chrome: - */ -@font-face { - font-family: "DDG_ProximaNova"; - src: url("/public/font/ProximaNova-Reg-webfont.woff") format("woff"); - font-weight: normal; - font-style: normal; -} -@font-face { - font-family: "DDG_ProximaNova"; - src: url("/public/font/ProximaNova-Sbold-webfont.woff") format("woff"); - font-weight: 600; - font-style: bold; -} -.token-body { - font-family: system, -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - font-size: 13px; - font-weight: 400; - line-height: 16px; -} -.token-body.environment--android { - font-size: 14px; - font-weight: 400; - line-height: 20px; -} -.token-body.environment--browser { - font-family: "DDG_ProximaNova"; - font-style: normal; - font-weight: 400; - font-size: 14px; - line-height: 18px; -} - -.token-body-em { - font-size: 13px; - font-weight: 600; - line-height: 16px; -} -.environment--android .token-body-em { - font-size: 14px; - font-weight: 500; - line-height: 20px; -} -.environment--ios .token-body-em { - font-size: 15px; - font-weight: 600; - line-height: 22px; -} -.environment--browser .token-body-em { - font-family: "DDG_ProximaNova"; - font-style: normal; - font-weight: 600; - font-size: 14px; - line-height: 20px; -} - -/* Mac/System Keywords/Title 2 (Emphasis) */ -.token-title-2-em { - font-size: 17px; - font-style: normal; - font-weight: 600; - line-height: 22px; -} - -.token-title-3 { - font-size: 15px; - font-weight: 400; - line-height: 20px; -} -.environment--ios .token-title-3 { - font-size: 16px; - line-height: 22px; - letter-spacing: 0; -} -.environment--android .token-title-3 { - font-size: 16px; - line-height: 20px; - letter-spacing: 0; -} -.environment--browser .token-title-3 { - font-family: "DDG_ProximaNova"; - font-size: 16px; - line-height: 20px; -} - -.token-ios-title-3 { - font-size: 20px; - font-weight: 600; - line-height: 1.25; -} - -.token-title-3-em { - font-size: 16px; - font-weight: 600; - line-height: 22px; -} -.environment--android .token-title-3-em { - font-size: 16px; - line-height: 20px; -} -.token-title-3-em .environment--windows { - font-size: 16px; - font-weight: 600; - line-height: 1.25; -} -.environment--browser .token-title-3-em { - font-family: "DDG_ProximaNova"; - font-style: normal; - font-size: 16px; - line-height: 20px; -} - -.token-breakage-form-body { - font-size: 13px; - font-weight: 400; - line-height: 16px; -} -.environment--android .token-breakage-form-body { - font-size: 16px; - font-weight: 400; - line-height: 20px; - letter-spacing: 0em; -} -.environment--browser .token-breakage-form-body { - font-size: 14px; - font-weight: 400; - line-height: 18px; -} -.environment--windows .token-breakage-form-body { - font-size: 14px; - font-weight: 400; - line-height: 20px; -} - -.token-headline-2 { - font-size: 20px; - font-weight: 500; - line-height: 1.2; -} - -.token-label-em { - font-size: 13px; - font-weight: 600; - line-height: 13px; -} -.environment--android .token-label-em { - font-size: 15px; - font-weight: 700; - line-height: 21px; - letter-spacing: 0em; -} -.environment--browser .token-label-em { - font-size: 13px; - font-weight: 600; - line-height: 13px; -} - -.token-search-input { - font-weight: 400; - font-size: 15px; - line-height: 20px; -} - -.token-bold { - font-weight: 600; -} - -@media (prefers-reduced-motion: reduce) { - * { - transition: none !important; - } -} - -/* Popup */ -body { - font-family: system, -apple-system, system-ui, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; - font-size: 13px; - font-weight: 400; - line-height: 16px; - overflow: hidden; - user-select: none; - -webkit-user-select: none; - -webkit-tap-highlight-color: transparent; - --width: 360px; - --height: 100vh; - --bg: #eee; - --page-bg: #ffffff; - --page-outer-bg: #eee; - --color-text-primary: rgba(0, 0, 0, 0.84); - --color-text-secondary: rgba(0, 0, 0, 0.6); - --color-accent-blue: #3969ef; - --color-accent-blue-active: #1e42a4; - --color-lines-light: rgba(0, 0, 0, 0.12); - --color-lines-lighter: rgba(0, 0, 0, 0.06); - --color-hover-bg: rgba(0, 0, 0, 0.06); - --color-system-lines: rgba(0, 0, 0, 0.09); - --size-unit: 16px; - --size-unit-half: calc(var(--size-unit) / 2); - --size-unit-double: calc(var(--size-unit) * 2); - --btn-accent-border-radius: 8px; - --btn-accent-border: 0.5px solid rgba(40, 145, 255, 0.05); - --btn-accent-bg: linear-gradient(180deg, #4690f7 0%, #307bf7 100%); - --btn-accent-bg-hover: linear-gradient(180deg, #4690f7 0%, #307bf7 100%); - --btn-accent-bg-active: linear-gradient(0deg, rgba(0, 0, 0, 0.12), rgba(0, 0, 0, 0.12)), - linear-gradient(180deg, #1f8aff 0%, #0173ff 100%); - --btn-accent-color: #ffffff; - --btn-accent-shadow: 0px 0px 1px rgba(40, 145, 255, 0.05), 0px 1px 1px rgba(40, 145, 255, 0.1); - color: var(--color-text-primary); - background: var(--bg); - width: var(--width); - height: var(--height); -} -body.environment--android { - font-size: 14px; - font-weight: 400; - line-height: 20px; -} -body.environment--browser { - font-family: "DDG_ProximaNova"; - font-style: normal; - font-weight: 400; - font-size: 14px; - line-height: 18px; -} -body.environment--ios { - --width: 100%; - --height: -webkit-fill-available; -} -body.environment--android { - --width: 100%; -} -body.environment--macos[data-screen=toggleReport] { - --height: auto; -} -body.environment--browser { - --height: 600px; -} -body.environment--windows { - --bg: #ffffff; - --btn-accent-border-radius: none; - --btn-accent-border: 0.5px solid rgba(40, 145, 255, 0.05); - --btn-accent-bg: #3969ef; - --btn-accent-bg-hover: #2b55ca; - --btn-accent-bg-active: #1e42a4; - --btn-accent-shadow: none; -} -body.body--theme-light.environment--ios, body.body--theme-light.environment--android { - --bg: #ffffff; -} -body.body--theme-dark { - --text: rgba(255, 255, 255, 0.9); - --page-bg: #333333; - --bg: #34383b; - --page-outer-bg: #34383b; - --color-text-primary: rgba(255, 255, 255, 0.84); - --color-text-secondary: rgba(255, 255, 255, 0.6); - --color-accent-blue: #7295f6; - --color-accent-blue-active: #8fabf9; - --color-lines-light: rgba(255, 255, 255, 0.18); - --color-lines-lighter: rgba(255, 255, 255, 0.09); - --color-hover-bg: rgba(255, 255, 255, 0.12); - --color-system-lines: rgba(255, 255, 255, 0.09); -} -body.body--theme-dark.environment--windows { - --btn-accent-color: #000000; - --btn-accent-bg: #7295f6; - --btn-accent-bg-hover: #557ff3; - --btn-accent-bg-active: #3969ef; -} -body.body--theme-dark.environment--android { - --bg: #111111; - --page-bg: #111111; -} -body.body--theme-dark.environment--ios { - --bg: #222222; - --page-bg: #222222; -} - -.app-height { - height: var(--height); -} - -#popup-container { - display: block; -} -#popup-container section::-webkit-scrollbar { - display: none; -} -#popup-container .text-line-after-icon { - margin-left: 12px; -} -#popup-container .sliding-subview { - background-color: var(--page-bg); -} - -body { - /* 'toggle' here means the wrapping container, a button element */ - --toggle-width: 32px; - --toggle-height: 18px; - --toggle-opacity: 1; - --toggle-opacity-disabled: 1; - /* the 'knob', also referred to as the 'handle' */ - --handle-size: 16px; - --handle-offset: 1px; - --handle-color: #ffffff; - --handle-color-off: #ffffff; - --handle-shadow: 0 1px 4px 0 rgba(0, 0, 0, 0.25); - /* the 'track' is the underlying colored background */ - --track-color: #007aff; - --track-outline: none; - --track-outline-off: none; - --track-color-off: #d8d8d8; - /* the 'spinner' is only used on ios/macos */ - --toggle-spinner-size: 18px; -} -body.environment--ios { - --toggle-width: 51px; - --toggle-height: 31px; - --toggle-spinner-size: 31px; - --handle-size: 27px; - --handle-offset: 2px; - --track-color: #21c000; -} -body.environment--android { - --toggle-width: 51px; - --toggle-height: 31px; - --toggle-spinner-size: 31px; - --handle-size: 24px; - --handle-offset: 4px; - --handle-shadow: none; - --track-color: #3969ef; - --track-color-off: rgba(136, 136, 136, 0.5); -} -body.environment--android.body--theme-dark { - --track-color: #7295f6; - --track-color-off: rgba(204, 204, 204, 0.5); -} -body.environment--windows { - --toggle-width: 40px; - --toggle-height: 20px; - --handle-size: 10px; - --handle-offset: 5px; - --handle-color-off: rgba(0, 0, 0, 0.9); - --handle-shadow: none; - --track-color: #3969ef; - --track-color-off: #ffffff; - --track-outline: 1px solid var(--track-color); - --track-outline-off: 1px solid rgba(0, 0, 0, 0.48); - --toggle-opacity-disabled: 0.6; -} - -.toggle-button { - z-index: 0; - margin: 0; - padding: 0; - border: none; - background-color: transparent; - text-align: left; - position: relative; - border-radius: 100px; - opacity: var(--toggle-opacity); - width: var(--toggle-width); - height: var(--toggle-height); -} -.toggle-button[disabled] { - opacity: var(--toggle-opacity-disabled); -} - -.toggle-button__track { - z-index: -1; - position: absolute; - right: 0; - top: 0; - overflow: visible; - border-radius: 100px; - border: var(--track-outline); - width: var(--toggle-width); - height: var(--toggle-height); - background-color: var(--track-color); -} -[aria-checked=false] .toggle-button__track { - background-color: var(--track-color-off); - border: var(--track-outline-off); -} - -.toggle-button__handle { - z-index: 2; - position: absolute; - border-radius: 100px; - top: 50%; - transform: translateY(-50%); - transition: all 0.2s ease; - box-shadow: var(--handle-shadow); - background-color: var(--handle-color); - width: var(--handle-size); - height: var(--handle-size); - right: var(--handle-offset); -} -[aria-checked=false] .toggle-button__handle { - right: calc(100% - var(--handle-size) - var(--handle-offset)); - background-color: var(--handle-color-off); -} - -.toggle-spinner { - margin: 0 auto; - height: var(--toggle-spinner-size); - width: var(--toggle-spinner-size); -} - -.page { - display: flex; - flex-direction: column; -} -.environment--browser .page, .environment--ios .page, .environment--android .page { - height: 100%; -} - -.page-inner { - display: flex; - flex-direction: column; - flex-flow: column; - z-index: 1; - overflow-y: auto; - -ms-overflow-style: none; - scrollbar-width: none; - background: var(--page-bg); -} -.page-inner::-webkit-scrollbar { - display: none; -} -.environment--browser .page-inner, .environment--ios .page-inner, .environment--android .page-inner { - height: 100%; -} -.page-inner[data-with-permissions=true] { - border-bottom-left-radius: 8px; - border-bottom-right-radius: 8px; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.05), 0px 1px 0px rgba(0, 0, 0, 0.1); -} - -.page-outer { - z-index: 0; - background: var(--page-outer-bg); -} - -.header { - padding-left: 16px; - padding-right: 16px; - border-bottom: 1px solid var(--color-lines-light); -} -.environment--macos .header { - padding-top: 16px; - padding-bottom: 2px; -} -.environment--windows .header { - padding-top: 16px; -} -.environment--browser .header { - padding-top: 6px; -} -.environment--android .header { - padding-bottom: 10px; -} -.environment--ios .header { - padding-bottom: 10px; -} - -.header--breakage { - padding-left: 16px; - padding-right: 16px; - padding-bottom: 16px; - border-bottom: 0; -} -.environment--macos .header--breakage, .environment--windows .header--breakage { - padding-bottom: 16px; -} -.environment--browser .header--breakage { - padding-top: 16px; - padding-bottom: 12px; -} - -.header-spacer { - padding-top: 24px; -} -.environment--macos .header-spacer { - padding-top: 20px; -} -.environment--windows .header-spacer { - padding-top: 20px; -} -.environment--browser .header-spacer { - padding-top: 12px; -} - -.footer { - margin-top: auto; -} -.environment--macos .footer, .environment--windows .footer { - padding-bottom: 20px; -} - -.site-info { - margin-top: 0; -} -.environment--browser .site-info { - height: 100%; -} -.environment--ios .site-info > :last-child { - padding-bottom: 18px; -} -.site-info .list-wrapper { - background-color: var(--page-bg); -} -.site-info .default-list { - padding-bottom: 0; -} -.site-info:has(.page-outer) .page-inner { - border-bottom-left-radius: 8px; - border-bottom-right-radius: 8px; - box-shadow: 0px 4px 4px rgba(0, 0, 0, 0.05), 0px 1px 0px rgba(0, 0, 0, 0.1); -} - -.site-info__page-permission label { - display: flex; - justify-content: space-between; - overflow: hidden; - padding: 16px 0; -} -.site-info__page-permission select { - float: right; - max-width: 170px; -} -.site-info__page-permission + .site-info__page-permission { - border-top: 1px solid var(--color-lines-light); -} - -.site-info__li--manage-permissions { - padding: 5px 16px 0; -} - -.site-info__page-permission__icon { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - margin-right: 8px; -} -.site-info__page-permission__icon[data-icon=geolocation] { - background-image: url("../../img/refresh-assets/permissions-location.svg"); -} -.body--theme-dark .site-info__page-permission__icon[data-icon=geolocation] { - background-image: url("../../img/refresh-assets/permissions-location-light.svg"); -} -.site-info__page-permission__icon[data-icon=microphone] { - background-image: url("../../img/refresh-assets/permissions-microphone.svg"); - margin-top: -2px; -} -.body--theme-dark .site-info__page-permission__icon[data-icon=microphone] { - background-image: url("../../img/refresh-assets/permissions-microphone-light.svg"); -} -.site-info__page-permission__icon[data-icon=camera] { - background-image: url("../../img/refresh-assets/permissions-camera.svg"); - width: 16px; - height: 12px; - margin-top: -2px; -} -.body--theme-dark .site-info__page-permission__icon[data-icon=camera] { - background-image: url("../../img/refresh-assets/permissions-camera-light.svg"); -} -.site-info__page-permission__icon[data-icon=popups] { - background-image: url("../../img/refresh-assets/permissions-popups.svg"); -} -.body--theme-dark .site-info__page-permission__icon[data-icon=popups] { - background-image: url("../../img/refresh-assets/permissions-popups-light.svg"); -} -.site-info__page-permission__icon[data-icon=externalScheme] { - background-image: url("../../img/refresh-assets/permissions-externalScheme.svg"); - margin-top: -4px; -} -.body--theme-dark .site-info__page-permission__icon[data-icon=externalScheme] { - background-image: url("../../img/refresh-assets/permissions-externalScheme-light.svg"); -} -.site-info__page-permission__icon[data-icon=notification] { - background-image: url("../../img/refresh-assets/permissions-notification.svg"); - width: 16px; - height: 14px; - margin-top: -4px; -} -.body--theme-dark .site-info__page-permission__icon[data-icon=notification] { - background-image: url("../../img/refresh-assets/permissions-notification-light.svg"); -} - -.site-info__protection-wrapper { - padding: 16px; -} - -.site-info__protection { - opacity: 1; - margin-top: 0; - padding-right: 10px; -} - -.site-info-toggle { - color: #333333; - display: flex; - align-items: center; -} -.body--theme-dark .site-info-toggle { - color: rgba(255, 255, 255, 0.9); -} - -.site-info__toggle-container { - margin-left: auto; - text-align: center; - display: flex; - width: var(--toggle-width); - height: var(--toggle-height); -} - -.card { - background-color: var(--page-bg); -} -.environment--browser .card { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; -} - -.card-list--bordered { - border: 1px solid var(--color-lines-light); - border-radius: 12px; - position: relative; - z-index: 0; - overflow: hidden; -} - -.main-nav { - border: 1px solid var(--color-lines-light); - border-radius: 12px; - position: relative; - z-index: 0; - overflow: hidden; -} - -.main-nav__row { - position: relative; - /* - The following avoids height shifts when hovering over nav rows. - - Each row has an :after element that provides the separator line. When hovering a row, we need to change the color of any adjacent separators (i.e. the current row and the row above it). - - We do that by targeting the current row directly, then use a :has selector to also target the previous sibling of the current row. - - We also use the :not selector to exclude any rows marked as no-hover. - */ -} -.main-nav__row:after { - content: " "; - display: block; - width: calc(100% - 32px); - height: 1px; - background: var(--color-lines-light); - position: absolute; - bottom: -0.5px; - left: 16px; -} -.main-nav__row:not(.no-hover):hover:after, .main-nav__row:has(+ :not(.no-hover):hover):after { - background-color: var(--page-bg); -} -.main-nav__row:last-child { - border-bottom: none; -} -.main-nav__row:last-child:after { - display: none; -} - -.main-nav__item { - z-index: 10; - position: relative; - display: flex; - height: 44px; - align-items: center; - -webkit-touch-callout: none; -} -.environment--ios .main-nav__item, .environment--android .main-nav__item { - height: 48px; -} -.environment--browser .main-nav__item { - height: 40px; -} -.main-nav__item:has(.main-nav__icon) .main-nav__text { - margin-left: 10px; -} - -.main-nav__item--link { - color: var(--color-text-primary); -} -.environment--example .main-nav__item--link:focus, .environment--browser .main-nav__item--link:focus, .environment--windows .main-nav__item--link:focus, .environment--macos .main-nav__item--link:focus { - outline: 0; - text-decoration: underline; -} -.environment--example .main-nav__item--link:visited, .environment--example .main-nav__item--link:active, .environment--example .main-nav__item--link:hover, .environment--browser .main-nav__item--link:visited, .environment--browser .main-nav__item--link:active, .environment--browser .main-nav__item--link:hover, .environment--windows .main-nav__item--link:visited, .environment--windows .main-nav__item--link:active, .environment--windows .main-nav__item--link:hover, .environment--macos .main-nav__item--link:visited, .environment--macos .main-nav__item--link:active, .environment--macos .main-nav__item--link:hover { - text-decoration: none; - background: var(--color-hover-bg); -} -.environment--ios .main-nav__item--link:active { - opacity: 0.5; -} - -.main-nav__icon { - width: 18px; - height: 18px; - z-index: 1; - margin-left: 19px; - background-repeat: no-repeat; - background-size: cover; - flex-shrink: 0; -} - -.main-nav__text { - display: block; - z-index: 1; - margin-left: 16px; - margin-right: 10px; - line-height: 1; - /** TODO: Move */ -} -.environment--ios .main-nav__text { - line-height: 1.3333333333; -} -.environment--android .main-nav__text { - line-height: 1.4285714286; -} -.environment--macos .main-nav__text { - line-height: 1.2307692308; -} -.environment--windows .main-nav__text { - line-height: 1.2857142857; -} - -.main-nav__chev { - width: 7px; - height: 18px; - margin-left: auto; - margin-right: 16px; - background-repeat: no-repeat; - background-size: 7px; - background-position: center center; - opacity: 60%; - background-image: url("../../img/refresh-assets/chevron.svg"); -} -.body--theme-dark .main-nav__chev { - background-image: url("../../img/refresh-assets/chevron--light.svg"); -} -.environment--ios .main-nav__chev, .environment--android .main-nav__chev { - opacity: 24%; -} - -.icon-small--info { - background-image: url("../../img/status--info.svg"); -} - -.icon-small--blocked, -.icon-small--secure { - background-image: url("../../img/refresh-assets/Check-Color-16.svg"); -} - -.icon-small--warning, -.icon-small--insecure { - background-image: url("../../img/refresh-assets/Error-Color-16.svg"); -} - -.search { - display: flex; - align-items: center; - padding: 8px; - background: #ffffff; - height: 56px; -} -.body--theme-dark .search { - background-color: #333333; -} - -.search-form { - flex: 1; - display: flex; - margin-right: 8px; -} - -.search-form__input { - -moz-appearance: none; - outline: medium none; - border: medium none; - padding-left: 46px; - z-index: 1; - color: #333333; - height: 40px; - background-color: #eee; - background-image: url("../../img/logo-small-new.svg"); - background-repeat: no-repeat; - background-position: 10px 8px; - background-size: 24px; - border-radius: 10px 0 0 10px; - flex-grow: 1; -} -.body--theme-dark .search-form__input { - background-color: rgba(255, 255, 255, 0.12); -} -.search-form__input::placeholder { - color: #999999; -} - -.search-form__go { - display: flex; - align-items: center; - justify-content: center; - background-color: #eee; - height: 40px; - width: 42px; - padding: 0 0.64em; - min-height: 1.8em; - -moz-appearance: none; - cursor: pointer; - text-align: center; - border: medium none; - outline: medium none; - z-index: 2; - border-radius: 0 10px 10px 0; -} -.search-form__go svg { - position: relative; - top: -1px; - left: -1px; -} -.search-form__go .loupe-handle { - fill: currentColor; - opacity: 0.8; -} -.search-form__go .loupe-glass { - stroke: currentColor; - opacity: 0.8; -} -.body--theme-dark .search-form__go { - background-color: rgba(255, 255, 255, 0.12); -} -.body--theme-dark .search-form__go:hover, .body--theme-dark .search-form__go:focus { - background-color: rgba(255, 255, 255, 0.2); -} -.search-form__go:hover, .search-form__go:focus { - background-color: #2950bf; - color: white; -} -[data-focussed=true] .search-form__go, .search-form__go.go--focused { - background-color: #3969ef; - color: white; -} -[data-focussed=true] .search-form__go:hover, [data-focussed=true] .search-form__go:focus, .search-form__go.go--focused:hover, .search-form__go.go--focused:focus { - background-color: #2950bf; -} - -/* cog-button */ -.cog-button { - display: flex; - align-items: center; - justify-content: center; - width: 32px; - height: 32px; - background-position: center; - background-repeat: no-repeat; - background-color: transparent; - border-radius: 3px; -} -.cog-button:hover, .cog-button:active, .cog-button:focus { - background-color: #eee; -} -.body--theme-dark .cog-button:hover, .body--theme-dark .cog-button:active, .body--theme-dark .cog-button:focus { - background-color: #444; -} -.cog-button .settings-cog { - fill: black; -} -.body--theme-dark .cog-button .settings-cog { - fill: white; - opacity: 0.8; -} - -.fire-button { - display: flex; - align-items: center; - justify-content: center; - width: 32px; - height: 32px; - background-position: center; - background-repeat: no-repeat; - background-color: transparent; - border-radius: 3px; -} -.fire-button:hover, .fire-button:active, .fire-button:focus { - background-color: #eee; -} -.body--theme-dark .fire-button:hover, .body--theme-dark .fire-button:active, .body--theme-dark .fire-button:focus { - background-color: #444; -} -.fire-button .fire-icon { - fill: black; -} -.body--theme-dark .fire-button .fire-icon { - fill: white; - opacity: 0.8; -} - -.large-icon-container { - height: 96px; - background-position: center center; - background-repeat: no-repeat; - margin-bottom: 24px; - background-size: contain; -} - -.medium-icon-container { - height: 72px; - background-position: center center; - background-repeat: no-repeat; - margin-bottom: 16px; - background-size: contain; -} - -.hero-icon--breakage-form { - background-image: url("../../img/refresh-assets/Breakage-128.svg"); - margin-bottom: 20px; -} -.environment--browser .hero-icon--breakage-form { - margin-bottom: 16px; -} - -.hero-icon--toggle-report { - background-image: url("../../img/refresh-assets/Breakage-128.svg"); - margin-bottom: 0; -} - -.hero-icon--toggle-report-sent { - background-image: url("../../img/refresh-assets/breakage-sent.svg"); -} - -.hero-icon--tracker-network { - background-image: url("../../img/refresh-assets/Network-128.svg"); -} - -.hero-icon--insecure-connection, -.hero-icon--trackers-blocked, -.hero-icon--connection-none, -.hero-icon--connection-invalid { - background-image: url("../../img/refresh-assets/Unlocked-128.svg"); -} - -.hero-icon--major-networks-blocked { - background-image: url("../../img/refresh-assets/Shield-128.svg"); -} - -.hero-icon--protections-off, -.hero-icon--major-networks-warning, -.hero-icon--major-networks-protections-off { - background-image: url("../../img/refresh-assets/Block-Disabled-128.svg"); -} - -.hero-icon--info, -.hero-icon--major-networks-info { - background-image: url("../../img/refresh-assets/Block-Info-128.svg"); -} - -.hero-icon--no-activity, -.hero-icon--major-networks-no-activity { - background-image: url("../../img/refresh-assets/Counter-128.svg"); -} - -.hero-icon--connection-secure, -.hero-icon--connection-upgraded { - background-image: url("../../img/refresh-assets/Locked-128.svg"); -} - -.hero-icon--cookies-managed { - background-image: url("../../img/refresh-assets/Cookies-Managed-128.svg"); -} - -.hero-icon--cookies-hidden { - background-image: url("../../img/refresh-assets/Cookies-Hidden-128.svg"); -} - -.hero-icon--phishing, -.hero-icon--connection-phishing { - background-image: url("../../img/refresh-assets/Phishing-128.svg"); -} - -.hero-icon--chat { - background-image: url("../../img/refresh-assets/chat-private-128.svg"); -} - -.hero-icon--switch-shield { - background-image: url("../../img/refresh-assets/switch-shield-128.svg"); -} - -.key-insight { - position: relative; - padding-bottom: 24px; - text-align: center; -} -.key-insight[data-suffix=about-link] { - padding-bottom: 12px; -} -.environment--browser .key-insight { - background-color: transparent; -} -.environment--ios .key-insight { - padding-top: 6px; -} -.key-insight .token-title-3-em { - margin-bottom: 8px; -} - -.key-insight__icon { - height: 96px; - background-position: center center; - background-repeat: no-repeat; - margin-bottom: 24px; - background-size: contain; -} -.environment--macos .key-insight__icon { - margin-bottom: 20px; -} -.environment--windows .key-insight__icon { - margin-bottom: 20px; -} -.environment--browser .key-insight__icon { - margin-bottom: 12px; -} - -.environment--macos .key-insight--main { - padding-bottom: 20px; -} -.environment--windows .key-insight--main { - padding-bottom: 20px; -} -.environment--browser .key-insight--main { - padding-bottom: 12px; -} - -.key-insight--breakage { - padding-bottom: 20px; -} -.environment--browser .key-insight--breakage { - padding-bottom: 16px; -} -.environment--windows .key-insight--breakage { - padding-bottom: 12px; -} - -body { - --nav-height: 56px; -} -body.environment--macos, body.environment--browser, body.environment--windows, body.environment--example { - --nav-height: var(--size-unit-double); -} - -.top-nav { - text-align: center; - position: fixed; - z-index: 1; - width: 100%; - height: var(--nav-height); - background: var(--page-bg); -} - -.top-nav__spacer { - height: var(--nav-height); -} - -.top-nav__back { - position: absolute; - padding: var(--size-unit-half); - left: var(--size-unit-half); - top: 50%; - transform: translateY(-50%); - display: flex; - color: var(--color-text-primary); -} -.top-nav__back:hover, .top-nav__back:focus, .top-nav__back:active { - text-decoration: none; -} -.environment--android .top-nav__back { - border-radius: 100%; - left: 10px; -} -.environment--ios .top-nav__back { - font-size: 17px; - font-weight: 400; - left: 0; -} -.environment--ios .top-nav__back:active { - opacity: 0.5; -} -.environment--macos .top-nav__back, .environment--browser .top-nav__back, .environment--windows .top-nav__back, .environment--example .top-nav__back { - border-radius: 0; - bottom: 0; - padding: 0; - height: 32px; - width: 32px; -} -.environment--macos .top-nav__back .icon, .environment--browser .top-nav__back .icon, .environment--windows .top-nav__back .icon, .environment--example .top-nav__back .icon { - position: absolute; - left: 50%; - transform: translateX(-50%) translateY(100%); - width: 15px; - height: 15px; -} - -.top-nav__done { - position: absolute; - padding: 0 var(--size-unit-half); - right: var(--size-unit-half); - height: var(--nav-height); - line-height: var(--nav-height); - color: var(--color-text-primary); -} -.top-nav__done:hover, .top-nav__done:focus, .top-nav__done:active { - text-decoration: none; -} -.environment--ios .top-nav__done { - font-size: 17px; - font-weight: 600; - font-weight: 600; -} -.environment--ios .top-nav__done:active { - opacity: 0.5; -} -.environment--macos .top-nav__done { - height: auto; - line-height: normal; - bottom: 0; -} - -.top-nav__cancel { - position: absolute; - padding: 0 var(--size-unit-half); - right: var(--size-unit-half); - height: var(--nav-height); - line-height: var(--nav-height); - color: var(--color-text-primary); -} -.top-nav__cancel:hover, .top-nav__cancel:focus, .top-nav__cancel:active { - text-decoration: none; -} -.environment--ios .top-nav__cancel { - font-size: 17px; -} -.environment--ios .top-nav__cancel:active { - opacity: 0.5; -} - -.top-nav__title { - position: absolute; - height: var(--nav-height); - line-height: 1.1; - color: var(--color-text-primary); - left: 50%; - transform: translateX(-50%); - display: flex; - align-items: center; -} -.environment--ios .top-nav__title { - font-size: 17px; - font-weight: 600; -} -.environment--ios .top-nav__title:active { - opacity: 0.5; -} -.environment--android .top-nav__title { - transform: unset; - left: 72px; - top: 2px; - font-size: 20px; - font-weight: 500; -} -.environment--android .top-nav__title:active { - opacity: 0.5; -} - -.status-list--right .status-list__item { - padding-left: 0; - padding-right: 40px; -} -.status-list--right .status-list__item:before { - left: auto; - right: 0; -} - -.status-list__item { - padding-left: 40px; - list-style-type: none; - line-height: 22px; - margin-bottom: 23px; -} -.status-list__item:last-child { - margin-bottom: 0; -} -.status-list__item:before { - content: ""; - position: absolute; - left: 0; - height: 20px; - width: 23px; - top: -1px; - background-repeat: no-repeat; - background-position-y: center; - min-height: 22px; - max-height: 30px; -} - -.status-list__item--good:before { - background-image: url("../../img/status--good.svg"); -} - -.status-list__item--bad:before { - background-image: url("../../img/status--bad.svg"); -} - -.status-list__item--mixed:before { - background-image: url("../../img/status--mixed.svg"); -} - -/* privacy practices uses the modifier 'poor' */ -.status-list__item--poor:before { - background-image: url("../../img/status--bad.svg"); -} - -.icon-list { - position: relative; - display: flex; - justify-content: center; -} - -.icon-list__item { - display: flex; - align-items: center; -} - -.icon-list__count { - display: inline-block; - letter-spacing: -0.7px; -} - -.icon-list__icon { - border-radius: 50%; - overflow: hidden; - background-size: contain; - margin: 0; - width: 20px; - height: 20px; -} -.icon-list__icon.color-1 { - background-color: #94b3af; -} -.icon-list__icon.color-2 { - background-color: #727998; -} -.icon-list__icon.color-3 { - background-color: #645468; -} -.icon-list__icon.color-4 { - background-color: #4d5f7f; -} -.icon-list__icon.color-5 { - background-color: #855db6; -} -.icon-list__icon.color-6 { - background-color: #5e5adb; -} -.icon-list__icon.color-7 { - background-color: #678fff; -} -.icon-list__icon.color-8 { - background-color: #6bb4ef; -} -.icon-list__icon.color-9 { - background-color: #4a9bae; -} -.icon-list__icon.color-10 { - background-color: #66c4c6; -} -.icon-list__icon.color-11 { - background-color: #55d388; -} -.icon-list__icon.color-12 { - background-color: #99db7a; -} -.icon-list__icon.color-13 { - background-color: #eccc7b; -} -.icon-list__icon.color-14 { - background-color: #e7a538; -} -.icon-list__icon.color-15 { - background-color: #dd6b4c; -} -.icon-list__icon.color-16 { - background-color: #d65d62; -} -.icon-list__icon.A { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/A.svg"); -} -.icon-list__icon.B { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/B.svg"); -} -.icon-list__icon.C { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/C.svg"); -} -.icon-list__icon.D { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/D.svg"); -} -.icon-list__icon.E { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/E.svg"); -} -.icon-list__icon.F { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/F.svg"); -} -.icon-list__icon.G { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/G.svg"); -} -.icon-list__icon.H { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/H.svg"); -} -.icon-list__icon.I { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/I.svg"); -} -.icon-list__icon.J { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/J.svg"); -} -.icon-list__icon.K { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/K.svg"); -} -.icon-list__icon.L { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/L.svg"); -} -.icon-list__icon.M { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/M.svg"); -} -.icon-list__icon.N { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/N.svg"); -} -.icon-list__icon.O { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/O.svg"); -} -.icon-list__icon.P { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/P.svg"); -} -.icon-list__icon.Q { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/Q.svg"); -} -.icon-list__icon.R { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/R.svg"); -} -.icon-list__icon.S { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/S.svg"); -} -.icon-list__icon.T { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/T.svg"); -} -.icon-list__icon.U { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/U.svg"); -} -.icon-list__icon.V { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/V.svg"); -} -.icon-list__icon.W { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/W.svg"); -} -.icon-list__icon.X { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/X.svg"); -} -.icon-list__icon.Y { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/Y.svg"); -} -.icon-list__icon.Z { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/Z.svg"); -} -.icon-list__icon.adjust { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/adjust.svg"); - background-color: transparent; -} -.icon-list__icon.adobe { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/adobe.svg"); - background-color: transparent; -} -.icon-list__icon.amazon { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/amazon.svg"); - background-color: transparent; -} -.icon-list__icon.amplitude { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/amplitude.svg"); - background-color: transparent; -} -.icon-list__icon.appnexus { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/appnexus.svg"); - background-color: transparent; -} -.icon-list__icon.appsflyer { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/appsflyer.svg"); - background-color: transparent; -} -.icon-list__icon.beeswax { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/beeswax.svg"); - background-color: transparent; -} -.icon-list__icon.branchmetrics { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/branchmetrics.svg"); - background-color: transparent; -} -.icon-list__icon.braze { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/braze.svg"); - background-color: transparent; -} -.icon-list__icon.bugsnag { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/bugsnag.svg"); - background-color: transparent; -} -.icon-list__icon.chartbeat { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/chartbeat.svg"); - background-color: transparent; -} -.icon-list__icon.comscore { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/comscore.svg"); - background-color: transparent; -} -.icon-list__icon.criteo { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/criteo.svg"); - background-color: transparent; -} -.icon-list__icon.facebook { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/facebook.svg"); - background-color: transparent; -} -.icon-list__icon.google { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/google.svg"); - background-color: transparent; -} -.icon-list__icon.googleadsgoogle { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg"); - background-color: transparent; -} -.icon-list__icon.googleanalyticsgoogle { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg"); - background-color: transparent; -} -.icon-list__icon.indexexchange { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/indexexchange.svg"); - background-color: transparent; -} -.icon-list__icon.iponweb { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/iponweb.svg"); - background-color: transparent; -} -.icon-list__icon.instagramfacebook { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/instagramfacebook.svg"); - background-color: transparent; -} -.icon-list__icon.kochava { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/kochava.svg"); - background-color: transparent; -} -.icon-list__icon.linkedin { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/linkedin.svg"); - background-color: transparent; -} -.icon-list__icon.liveramp { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/liveramp.svg"); - background-color: transparent; -} -.icon-list__icon.mediamath { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/mediamath.svg"); - background-color: transparent; -} -.icon-list__icon.microsoft { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/microsoft.svg"); - background-color: transparent; -} -.icon-list__icon.mixpanel { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/mixpanel.svg"); - background-color: transparent; -} -.icon-list__icon.neustar { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/neustar.svg"); - background-color: transparent; -} -.icon-list__icon.newrelic { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/newrelic.svg"); - background-color: transparent; -} -.icon-list__icon.openx { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/openx.svg"); - background-color: transparent; -} -.icon-list__icon.oracle { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/oracle.svg"); - background-color: transparent; -} -.icon-list__icon.outbrain { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/outbrain.svg"); - background-color: transparent; -} -.icon-list__icon.pinterest { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/pinterest.svg"); - background-color: transparent; -} -.icon-list__icon.pubmatic { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/pubmatic.svg"); - background-color: transparent; -} -.icon-list__icon.quantcast { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/quantcast.svg"); - background-color: transparent; -} -.icon-list__icon.magnite { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/magnite.svg"); - background-color: transparent; -} -.icon-list__icon.rythmone { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/rythmone.svg"); - background-color: transparent; -} -.icon-list__icon.salesforce { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/salesforce.svg"); - background-color: transparent; -} -.icon-list__icon.sharetrough { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/sharetrough.svg"); - background-color: transparent; -} -.icon-list__icon.smaato { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/smaato.svg"); - background-color: transparent; -} -.icon-list__icon.spotx { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/spotx.svg"); - background-color: transparent; -} -.icon-list__icon.taboola { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/taboola.svg"); - background-color: transparent; -} -.icon-list__icon.tapad { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/tapad.svg"); - background-color: transparent; -} -.icon-list__icon.thenielsencompany { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/thenielsencompany.svg"); - background-color: transparent; -} -.icon-list__icon.thetradedesk { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/thetradedesk.svg"); - background-color: transparent; -} -.icon-list__icon.twitter { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/twitter.svg"); - background-color: transparent; -} -.icon-list__icon.urbanairship { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/urbanairship.svg"); - background-color: transparent; -} -.icon-list__icon.verizonmedia { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/verizonmedia.svg"); - background-color: transparent; -} -.icon-list__icon.warnermedia { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/warnermedia.svg"); - background-color: transparent; -} -.icon-list__icon.xaxis { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/xaxis.svg"); - background-color: transparent; -} -.icon-list__icon.yahoojapan { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/yahoojapan.svg"); - background-color: transparent; -} -.icon-list__icon.yandex { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/yandex.svg"); - background-color: transparent; -} -.icon-list__icon.youtubegoogle { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/youtubegoogle.svg"); - background-color: transparent; -} -.icon-list__icon.zeotap { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/zeotap.svg"); - background-color: transparent; -} - -.icon-list__blocked-icon { - border-radius: 100%; - position: absolute; -} -.icon-list__blocked-icon svg path { - shape-rendering: geometricPrecision; -} -.icon-list__blocked-icon svg circle { - shape-rendering: geometricPrecision; -} -.body--theme-dark .icon-list__blocked-icon circle { - fill: #222; -} - -[data-company-icon-position]:nth-child(n+2):nth-child(odd) { - margin-left: -8px; -} - -[data-company-icon-position]:nth-child(n+2):nth-child(even) { - margin-right: -8px; -} - -[data-company-icon-size=large] { - z-index: 4; - display: block; - box-shadow: 0px 1px 4px rgba(0, 0, 0, 0.1), 0px 4px 8px rgba(0, 0, 0, 0.08); - height: 96px; - width: 96px; -} -[data-company-icon-size=large] .icon-list__icon { - margin: 0; - width: 64px; - height: 64px; -} -[data-company-icon-size=large] .icon-list__blocked-icon { - bottom: 14px; - right: 14px; - width: 30px; - height: 30px; -} -.environment--browser [data-company-icon-size=large] .icon-list__blocked-icon { - bottom: 10px; - right: 10px; -} - -[data-company-icon-size=medium] { - z-index: 3; - box-shadow: 0px 0px 3px rgba(0, 0, 0, 0.08), 0px 2px 4px rgba(0, 0, 0, 0.1); - height: 64px; - width: 64px; -} -[data-company-icon-size=medium] .icon-list__icon { - margin: 0; - width: 32px; - height: 32px; -} -[data-company-icon-size=medium] .icon-list__blocked-icon { - width: 24px; - height: 24px; - bottom: 8px; - right: 8px; -} - -[data-company-icon-size=small] { - z-index: 2; - border: 1px solid #f2f2f2; - box-shadow: 0px 1px 0px rgba(125, 125, 125, 0.06); - height: 48px; - width: 48px; -} -[data-company-icon-size=small] .icon-list__icon { - margin: 0; - width: 20px; - height: 20px; -} -[data-company-icon-size=small] .icon-list__blocked-icon { - width: 24px; - height: 24px; - bottom: 3px; - right: 3px; -} - -.icon-list__wrapper { - background-color: #ffffff; - border-radius: 50%; - position: relative; - display: flex; - color: rgba(0, 0, 0, 0.85); - align-items: center; - justify-content: center; -} -.body--theme-dark .icon-list__wrapper { - background-color: #222; - border-color: #222; - color: rgba(255, 255, 255, 0.85); -} - -.icon-list__wrapper--count { - border: 1px solid var(--color-lines-light); - height: 46px; - width: 46px; - background: #fafafa; - font-size: 16px; -} - -.tracker-networks__explainer { - padding: 0 32px 0; -} -.tracker-networks__explainer .about-link { - display: block; - padding-top: 8px; - margin-bottom: 20px; -} - -.section-list-header { - color: var(--color-text-secondary); - padding: 12px 0; - text-align: center; - border-top: 1px solid var(--color-lines-light); - border-bottom: 1px solid var(--color-lines-light); -} -.section-list-header[data-section-name=adAttribution] { - padding-bottom: 4px; -} - -.icon-major-networks-blocked { - background-image: url("../../img/refresh-assets/Check-Color-16.svg"); -} - -.icon-major-networks-warning { - background-image: url("../../img/refresh-assets/Error-Color-16.svg"); -} - -.icon-major-networks-info { - background-image: url("../../img/status--info.svg"); -} - -.icon-major-networks-mixed { - background-image: url("../../img/refresh-assets/Stop-Grey-16.svg"); -} - -.site-info__tracker__icon { - border-radius: 50%; - overflow: hidden; - background-size: contain; - margin-right: 8px; -} -.site-info__tracker__icon.color-1 { - background-color: #94b3af; -} -.site-info__tracker__icon.color-2 { - background-color: #727998; -} -.site-info__tracker__icon.color-3 { - background-color: #645468; -} -.site-info__tracker__icon.color-4 { - background-color: #4d5f7f; -} -.site-info__tracker__icon.color-5 { - background-color: #855db6; -} -.site-info__tracker__icon.color-6 { - background-color: #5e5adb; -} -.site-info__tracker__icon.color-7 { - background-color: #678fff; -} -.site-info__tracker__icon.color-8 { - background-color: #6bb4ef; -} -.site-info__tracker__icon.color-9 { - background-color: #4a9bae; -} -.site-info__tracker__icon.color-10 { - background-color: #66c4c6; -} -.site-info__tracker__icon.color-11 { - background-color: #55d388; -} -.site-info__tracker__icon.color-12 { - background-color: #99db7a; -} -.site-info__tracker__icon.color-13 { - background-color: #eccc7b; -} -.site-info__tracker__icon.color-14 { - background-color: #e7a538; -} -.site-info__tracker__icon.color-15 { - background-color: #dd6b4c; -} -.site-info__tracker__icon.color-16 { - background-color: #d65d62; -} -.site-info__tracker__icon.A { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/A.svg"); -} -.site-info__tracker__icon.B { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/B.svg"); -} -.site-info__tracker__icon.C { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/C.svg"); -} -.site-info__tracker__icon.D { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/D.svg"); -} -.site-info__tracker__icon.E { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/E.svg"); -} -.site-info__tracker__icon.F { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/F.svg"); -} -.site-info__tracker__icon.G { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/G.svg"); -} -.site-info__tracker__icon.H { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/H.svg"); -} -.site-info__tracker__icon.I { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/I.svg"); -} -.site-info__tracker__icon.J { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/J.svg"); -} -.site-info__tracker__icon.K { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/K.svg"); -} -.site-info__tracker__icon.L { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/L.svg"); -} -.site-info__tracker__icon.M { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/M.svg"); -} -.site-info__tracker__icon.N { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/N.svg"); -} -.site-info__tracker__icon.O { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/O.svg"); -} -.site-info__tracker__icon.P { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/P.svg"); -} -.site-info__tracker__icon.Q { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/Q.svg"); -} -.site-info__tracker__icon.R { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/R.svg"); -} -.site-info__tracker__icon.S { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/S.svg"); -} -.site-info__tracker__icon.T { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/T.svg"); -} -.site-info__tracker__icon.U { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/U.svg"); -} -.site-info__tracker__icon.V { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/V.svg"); -} -.site-info__tracker__icon.W { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/W.svg"); -} -.site-info__tracker__icon.X { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/X.svg"); -} -.site-info__tracker__icon.Y { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/Y.svg"); -} -.site-info__tracker__icon.Z { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/letters/Z.svg"); -} -.site-info__tracker__icon.adjust { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/adjust.svg"); - background-color: transparent; -} -.site-info__tracker__icon.adobe { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/adobe.svg"); - background-color: transparent; -} -.site-info__tracker__icon.amazon { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/amazon.svg"); - background-color: transparent; -} -.site-info__tracker__icon.amplitude { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/amplitude.svg"); - background-color: transparent; -} -.site-info__tracker__icon.appnexus { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/appnexus.svg"); - background-color: transparent; -} -.site-info__tracker__icon.appsflyer { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/appsflyer.svg"); - background-color: transparent; -} -.site-info__tracker__icon.beeswax { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/beeswax.svg"); - background-color: transparent; -} -.site-info__tracker__icon.branchmetrics { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/branchmetrics.svg"); - background-color: transparent; -} -.site-info__tracker__icon.braze { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/braze.svg"); - background-color: transparent; -} -.site-info__tracker__icon.bugsnag { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/bugsnag.svg"); - background-color: transparent; -} -.site-info__tracker__icon.chartbeat { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/chartbeat.svg"); - background-color: transparent; -} -.site-info__tracker__icon.comscore { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/comscore.svg"); - background-color: transparent; -} -.site-info__tracker__icon.criteo { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/criteo.svg"); - background-color: transparent; -} -.site-info__tracker__icon.facebook { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/facebook.svg"); - background-color: transparent; -} -.site-info__tracker__icon.google { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/google.svg"); - background-color: transparent; -} -.site-info__tracker__icon.googleadsgoogle { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/googleadsgoogle.svg"); - background-color: transparent; -} -.site-info__tracker__icon.googleanalyticsgoogle { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/googleanalyticsgoogle.svg"); - background-color: transparent; -} -.site-info__tracker__icon.indexexchange { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/indexexchange.svg"); - background-color: transparent; -} -.site-info__tracker__icon.iponweb { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/iponweb.svg"); - background-color: transparent; -} -.site-info__tracker__icon.instagramfacebook { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/instagramfacebook.svg"); - background-color: transparent; -} -.site-info__tracker__icon.kochava { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/kochava.svg"); - background-color: transparent; -} -.site-info__tracker__icon.linkedin { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/linkedin.svg"); - background-color: transparent; -} -.site-info__tracker__icon.liveramp { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/liveramp.svg"); - background-color: transparent; -} -.site-info__tracker__icon.mediamath { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/mediamath.svg"); - background-color: transparent; -} -.site-info__tracker__icon.microsoft { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/microsoft.svg"); - background-color: transparent; -} -.site-info__tracker__icon.mixpanel { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/mixpanel.svg"); - background-color: transparent; -} -.site-info__tracker__icon.neustar { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/neustar.svg"); - background-color: transparent; -} -.site-info__tracker__icon.newrelic { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/newrelic.svg"); - background-color: transparent; -} -.site-info__tracker__icon.openx { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/openx.svg"); - background-color: transparent; -} -.site-info__tracker__icon.oracle { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/oracle.svg"); - background-color: transparent; -} -.site-info__tracker__icon.outbrain { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/outbrain.svg"); - background-color: transparent; -} -.site-info__tracker__icon.pinterest { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/pinterest.svg"); - background-color: transparent; -} -.site-info__tracker__icon.pubmatic { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/pubmatic.svg"); - background-color: transparent; -} -.site-info__tracker__icon.quantcast { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/quantcast.svg"); - background-color: transparent; -} -.site-info__tracker__icon.magnite { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/magnite.svg"); - background-color: transparent; -} -.site-info__tracker__icon.rythmone { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/rythmone.svg"); - background-color: transparent; -} -.site-info__tracker__icon.salesforce { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/salesforce.svg"); - background-color: transparent; -} -.site-info__tracker__icon.sharetrough { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/sharetrough.svg"); - background-color: transparent; -} -.site-info__tracker__icon.smaato { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/smaato.svg"); - background-color: transparent; -} -.site-info__tracker__icon.spotx { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/spotx.svg"); - background-color: transparent; -} -.site-info__tracker__icon.taboola { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/taboola.svg"); - background-color: transparent; -} -.site-info__tracker__icon.tapad { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/tapad.svg"); - background-color: transparent; -} -.site-info__tracker__icon.thenielsencompany { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/thenielsencompany.svg"); - background-color: transparent; -} -.site-info__tracker__icon.thetradedesk { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/thetradedesk.svg"); - background-color: transparent; -} -.site-info__tracker__icon.twitter { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/twitter.svg"); - background-color: transparent; -} -.site-info__tracker__icon.urbanairship { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/urbanairship.svg"); - background-color: transparent; -} -.site-info__tracker__icon.verizonmedia { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/verizonmedia.svg"); - background-color: transparent; -} -.site-info__tracker__icon.warnermedia { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/warnermedia.svg"); - background-color: transparent; -} -.site-info__tracker__icon.xaxis { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/xaxis.svg"); - background-color: transparent; -} -.site-info__tracker__icon.yahoojapan { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/yahoojapan.svg"); - background-color: transparent; -} -.site-info__tracker__icon.yandex { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/yandex.svg"); - background-color: transparent; -} -.site-info__tracker__icon.youtubegoogle { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/youtubegoogle.svg"); - background-color: transparent; -} -.site-info__tracker__icon.zeotap { - background-repeat: no-repeat; - background-size: cover; - display: inline-block; - width: 18px; - height: 18px; - vertical-align: middle; - background-image: url("../../img/refresh-assets/tracker-icons/logos/zeotap.svg"); - background-color: transparent; -} - -.site-info__tracker__icon--company { - width: 24px !important; - height: 24px !important; - flex-shrink: 0; -} - -.site-info__domain { - overflow: hidden; - text-overflow: ellipsis; - padding-right: 12px; - display: flex; - align-items: center; -} - -.site-info__trackers__company-list--bordered { - border-top: 1px solid var(--color-lines-light); -} - -.site-info__trackers__company-list-item { - margin-top: 16px; - margin-bottom: 16px; -} - -.site-info__trackers__company-list-item + .site-info__trackers__company-list-item { - padding-top: 16px; - border-top: 1px solid var(--color-lines-lighter); -} -.body--theme-dark .site-info__trackers__company-list-item + .site-info__trackers__company-list-item { - border-top: 1px solid rgba(255, 255, 255, 0.06); -} - -.site-info__trackers__company-list__url-list .url-list-item { - display: flex; - margin-top: 8px; - align-items: baseline; -} -.site-info__trackers__company-list__url-list .url { - width: 100%; - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; - direction: rtl; - padding-right: 10px; - line-height: 18px; -} -.site-info__trackers__company-list__url-list .category { - padding: 1px 8px; - border-radius: 33px; - color: var(--color-text-secondary); - background-color: var(--color-lines-lighter); - white-space: nowrap; - text-align: right; -} - -.page-connection__certificate-value { - text-align: right; - color: #666; -} -.body--theme-dark .page-connection__certificate-value { - color: #aaa; -} - -.page-connection__certificate-details { - padding: 18px 0; -} -.page-connection__certificate-details h3 { - color: #111111; - margin-bottom: 14px; -} -.body--theme-dark .page-connection__certificate-details h3 { - color: rgba(255, 255, 255, 0.9); -} -.page-connection__certificate-details > div { - color: #333333; - display: flex; - margin-top: 6px; - justify-content: space-between; -} -.body--theme-dark .page-connection__certificate-details > div { - color: rgba(255, 255, 255, 0.9); -} -.page-connection__certificate-details + .page-connection__certificate-details { - border-top: 1px solid var(--color-lines-lighter); -} -.body--theme-dark .page-connection__certificate-details + .page-connection__certificate-details { - border-top: 1px solid var(--color-lines-lighter); -} - -.environment--browser .breakage-form { - padding-bottom: 0; -} - -.breakage-form__content { - z-index: 1; - position: relative; - text-align: center; -} -[data-state=sent] .breakage-form__content { - display: none; -} - -.breakage-form__close-container { - top: 13px; - right: 15px; - position: absolute; -} - -.form__icon--wrapper { - padding-bottom: 5px; - margin: 0 20px; - position: relative; -} - -.breakage-form__element { - display: flex; - flex-direction: column; - gap: 24px; - opacity: 1; - transition: all 0.2s ease-in-out; -} -.breakage-form__element.is-transparent { - opacity: 0; - max-height: 0; - overflow: hidden; -} - -.breakage-form__title { - padding: 5px 0 0; -} - -.breakage-form__advise { - display: none; -} -[data-state=idle] .breakage-form__advise { - display: block; -} - -.form__label__select { - display: block; - text-align: left; -} - -.form__group { - display: flex; - flex-direction: column; - gap: 16px; -} - -.form__select { - width: 100%; -} - -.form__select select { - cursor: pointer; - display: block; - width: 100%; - min-height: 20px; - border: 1px solid var(--color-lines-light); - border-radius: 4px; -} -.environment--ios .form__select select { - height: 34px; -} -.environment--windows .form__select select { - min-height: 34px; -} - -.form__textarea { - resize: none; - width: 100%; - height: 88px; - display: block; - box-sizing: border-box; - padding: var(--size-unit-half) var(--size-unit); - border: 1px solid var(--color-lines-light); - border-radius: 4px; - font-size: 13px; - line-height: 16px; -} -.form__textarea::placeholder { - color: rgba(0, 0, 0, 0.6); -} -.body--theme-dark .form__textarea { - background-color: rgba(255, 255, 255, 0.12); - border-color: var(--color-lines-light); -} -.body--theme-dark .form__textarea::placeholder { - color: rgba(255, 255, 255, 0.6); -} -.environment--macos .form__textarea { - height: 102px; -} -.environment--windows .form__textarea { - height: 102px; - line-height: 20px; -} - -.form__submit { - text-align: center; - padding: 10px 12px; - cursor: pointer; - display: block; - text-decoration: none; - width: 100%; - box-shadow: var(--btn-accent-shadow); - border-radius: var(--btn-accent-border-radius); - border: var(--btn-accent-border); - color: var(--btn-accent-color); - background: var(--btn-accent-bg); - /* https://www.figma.com/file/DBZiXJRgTTJTuBeWAPyE5h/Desktop-Components?node-id=9113%3A130956&t=de8DMDVt8GbRBQub-0 */ -} -.form__submit:hover { - background: var(--btn-accent-bg-hover); -} -.form__submit:active { - background: var(--btn-accent-bg-active); -} -.environment--windows .form__submit { - /* Windows/Label */ - box-shadow: none; - font-style: normal; - font-weight: 400; - font-size: 14px; - line-height: 19px; - border-radius: 4px; -} -.environment--windows .form__submit:focus { - /* todo(Shane): where does this live? */ - box-shadow: 0px 0px 0px 1px #ffffff, 0px 0px 0px 3px #3969ef; -} -.environment--windows .form__submit:active { - box-shadow: none; -} - -.breakage-form__footer { - padding-bottom: 24px; - padding-top: 24px; - text-align: center; -} -.body--theme-dark .breakage-form__footer { - color: rgba(255, 255, 255, 0.5); -} -.environment--browser .breakage-form__footer { - margin-top: auto; -} -[data-state=sent] .breakage-form__footer { - display: none; -} - -.breakage-form__inner { - height: calc(100% - var(--nav-height)); - display: flex; - flex-direction: column; -} - -.thanks { - text-align: center; - padding-bottom: 20px; - transition: all 0.2s ease-in-out; - opacity: 1; - display: none; -} -[data-state=sent] .thanks { - display: block; -} - -.thanks__primary { - font-size: 15px; - font-style: normal; - font-weight: 800; - line-height: 20px; /* 133.333% */ - margin-bottom: 8px; -} -.environment--macos .thanks__primary, .environment--macos .thanks__primary { - font-size: 17px; - font-style: normal; - font-weight: 600; - line-height: 22px; /* 129.412% */ -} - -.thanks__secondary { - font-size: 16px; - font-style: normal; - font-weight: 400; - line-height: 20px; -} -.environment--macos .thanks__secondary { - font-size: 15px; - font-style: normal; - font-weight: 400; - line-height: 20px; -} - -/* Android-specific styles */ -.environment--android { - --btn-accent-bg: #3969ef; - --btn-accent-bg-hover: #1e42a4; - --btn-accent-bg-active: #1e42a4; - --btn-accent-color: #fff; - --form-select-bg: none; - --form-select-color: rgba(0, 0, 0, 0.6); - --form-select-border-color: rgba(0, 0, 0, 0.3); - --form-select-chevron: url("../../img/refresh-assets/chevron.svg"); - /** - * prevent the empty element from taking any screen height - */ -} -.environment--android ddg-android-breakage-dialog { - position: absolute; -} -.environment--android .breakage-form .form__submit { - height: calc(var(--size-unit) * 3); -} -.environment--android .breakage-form .breakage-form__input--dropdown { - position: relative; -} -.environment--android .breakage-form .breakage-form__input--dropdown select { - appearance: none; - background: var(--form-select-bg); - border: 1px solid var(--form-select-border-color); - border-radius: var(--size-unit-half); - color: var(--form-select-color); - font-size: var(--size-unit); - padding: var(--size-unit); -} -.environment--android .breakage-form .breakage-form__input--dropdown::after { - content: ""; - position: absolute; - right: var(--size-unit); - top: calc(1.25 * var(--size-unit)); - background-image: var(--form-select-chevron); - width: 8px; - height: 14px; - transform: rotate(90deg); - opacity: 0.75; -} -.environment--android .breakage-form textarea { - border-radius: var(--size-unit-half); - border-color: var(--form-select-border-color); - font-size: var(--size-unit); - line-height: 1.25; - height: calc(var(--size-unit) * 7); - padding: var(--size-unit); - background: none; -} -.environment--android .breakage-form .breakage-form__content.padding-x-double { - padding-left: var(--size-unit); - padding-right: var(--size-unit); -} -.environment--android.body--theme-dark { - --btn-accent-bg: #7295f6; - --btn-accent-bg-hover: #3969ef; - --btn-accent-bg-active: #3969ef; - --btn-accent-color: rgba(0, 0, 0, 0.84); - --form-select-color: rgba(255, 255, 255, 0.9); - --form-select-border-color: rgba(255, 255, 255, 0.3); - --form-select-chevron: url("../../img/refresh-assets/chevron--light.svg"); -} - -.email-alias { - margin-bottom: var(--size-unit); -} - -.email-alias__button { - display: block; - padding: 5px 10px; - background: var(--color-lines-lighter); - border: 1px solid transparent; - width: 100%; - border-radius: 8px; - vertical-align: middle; -} -.email-alias__button svg { - vertical-align: middle; - position: relative; - top: -1px; - left: -4px; -} -.email-alias__button svg path { - fill: currentColor; -} -.email-alias__button:hover, .email-alias__button:focus, .email-alias__button:active { - background: var(--color-lines-light); -} -.email-alias__button[data-state=added] { - background: white; - border-color: var(--color-lines-lighter); -} -.body--theme-dark .email-alias__button { - border: 1px solid transparent; -} -.body--theme-dark .email-alias__button:hover, .body--theme-dark .email-alias__button:focus, .body--theme-dark .email-alias__button:active { - background: rgba(255, 255, 255, 0.25); -} -.body--theme-dark .email-alias__button[data-state=added] { - border: 1px solid rgba(255, 255, 255, 0.18); - background: transparent; -} - -.cta-screen { - padding-top: 24px; -} - -.cta { - max-width: 85%; - margin: 0 auto; - margin-top: 32px; -} - -.cta__icon { - width: 100px; - height: 100px; - margin-left: auto; - margin-right: auto; - display: flex; - justify-content: center; - align-items: center; -} - -.cta__title { - font-size: 16px; - line-height: 20px; - margin-top: 14px; -} - -.cta__text { - font-size: 16px; - line-height: 22px; - font-weight: normal; - margin-top: 2px; -} - -.cta__action { - text-align: center; - margin-top: 22px; -} - -.cta__button { - display: inline-block; - background: var(--color-accent-blue); - border-radius: 8px; - padding: 10px 16px; - max-width: 250px; - font-style: normal; - font-weight: 600; - font-size: 13px; - line-height: 14px; - color: #ffffff; -} -.cta__button:hover, .cta__button:focus { - background-color: #2950bf; - text-decoration: none; -} -.body--theme-dark .cta__button { - color: #222222; -} -.body--theme-dark .cta__button:hover, .body--theme-dark .cta__button:focus { - background-color: #4271f3; - text-decoration: none; -} - -.note { - background: #fff0c2; - border-radius: 12px; - padding: 12px 16px; -} -.body--theme-dark .note { - background: rgba(255, 222, 122, 0.18); -} - -.note--nested { - border-top-left-radius: 0; - border-top-right-radius: 0; -} - -.note--nested--alt { - background: #ccdaff; -} -.body--theme-dark .note--nested--alt { - background: rgba(85, 127, 243, 0.18); -} - -.note--key-insight { - margin-top: 12px; - margin-left: -16px; - margin-right: -16px; -} - -#fire-button-container { - position: fixed; - top: 0; - left: 0; - width: 100%; - height: 100%; - z-index: 100; - background-color: rgba(0, 0, 0, 0.6); - border: 0px; - color: rgba(0, 0, 0, 0.84); -} -.body--theme-dark #fire-button-container { - color: rgba(255, 255, 255, 0.84); -} - -#fire-button-header { - font-weight: 600; - font-size: 17px; - text-align: center; - padding-bottom: 4px; -} - -#fire-button-content { - box-sizing: border-box; - /* Auto layout */ - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - padding: 16px; - gap: 12px; - background: #ffffff; - /* Tints-Shades/Shade 12% */ - border: 1px solid rgba(0, 0, 0, 0.12); - /* Shadows/On Light/Elevation 90 */ - box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.1), 0px 20px 40px rgba(0, 0, 0, 0.08); - border-radius: 16px; -} -.body--theme-dark #fire-button-content { - background-color: #333333; - border: 1px solid rgba(255, 255, 255, 0.12); -} - -#fire-button-burn { - background: #3969ef; - color: #fff; - font-weight: 600; - font-size: 15px; - line-height: 16px; -} -.body--theme-dark #fire-button-burn { - background: #7295f6; - color: rgba(0, 0, 0, 0.84); -} -#fire-button-burn:hover { - background: #2b55ca; -} -#fire-button-burn:active { - background: #1e42a4; -} - -#fire-button-cancel { - font-weight: 600; - font-size: 15px; - line-height: 16px; - background-color: rgba(0, 0, 0, 0.06); -} -.body--theme-dark #fire-button-cancel { - background-color: rgba(0, 0, 0, 0.18); -} -.body--theme-dark #fire-button-cancel:hover { - background: rgba(0, 0, 0, 0.09); -} -#fire-button-cancel:hover { - background: rgba(0, 0, 0, 0.03); -} -#fire-button-cancel:active { - background: rgba(0, 0, 0, 0.06); -} - -#fire-button-row { - display: flex; - justify-content: center; - align-items: center; - gap: 12px; - align-self: stretch; -} - -#fire-button-row > button { - display: flex; - height: 40px; - justify-content: center; - align-items: center; - gap: 10px; - flex: 1 0 0; - border-radius: 8px; -} - -#fire-button-summary { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - gap: 12px; - padding-top: 4px; - padding-bottom: 4px; -} - -#fire-button-summary .fire-button-disclaimer { - font-size: 15px; -} - -#fire-button-summary p { - text-align: center; - font-weight: 400; - font-size: 15px; - line-height: 22px; -} - -#fire-button-opts { - width: 100%; - height: 30px; - -webkit-box-sizing: border-box; - -moz-box-sizing: border-box; - box-sizing: border-box; - border-radius: 8px; - display: inline-block; - position: relative; - overflow: hidden; - line-height: 2.2; - border: 1px solid #ddd; - background-color: #fafafa; - color: #333; - padding: 0 32px 0 0.75em; - vertical-align: middle; - margin-bottom: 0; - cursor: pointer; - -webkit-appearance: none !important; - -moz-appearance: none !important; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAgCAYAAABgrToAAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACVSURBVHgB7dXtCYAgEMbxq0ZqjtZwqBZomVqgaepAQUTzzrcvPT8QP+TRHyEiAgAA+L3NrlFz6pecdhnFnPHmqiJnxVlDskjpOZEl8/y2+xrsV+J8GLe/66AKuUA/JhcZi9upkiTQj0lFdolj0kA/Zo3sXeLYRHpfH0HTOKa5QSe8Sad5HCsJZGFkl7gWhvwtAAAAyj31qB2UieFidQAAAABJRU5ErkJggg==); - background-position: 100%; - background-repeat: no-repeat; - background-size: 20px; -} -#fire-button-opts:hover { - background-color: #fff; -} -#fire-button-opts select { - -webkit-appearance: none; - -moz-appearance: none; - -ms-appearance: none; - -o-appearance: none; - appearance: none; - background: none; - cursor: pointer; - margin: 0; - padding: 0 32px 0 0.75em; - position: relative; - display: block; - font-size: 1em; - line-height: inherit; - min-width: 10em; - width: 140% !important; - height: 2.2em !important; - outline: none !important; - border: none !important; -} -@media (prefers-color-scheme: dark) { - #fire-button-opts { - border: 1px solid #444; - background-color: #333; - color: #fafafa; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAgCAYAAABgrToAAAAACXBIWXMAABYlAAAWJQFJUiTwAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAACFSURBVHgB7dVdCoAgEATg3e7XNTxUZ+pOxoIPJf3suGYPzQcSxC6OoihCRET0bznn2YaAWvtaJlnLSEBf2vWFQk5AbfKELDXuxYRVu3G7k0jt8JCfhfMEeDOcIsUn52sp38M/VV2kEyigebgEXcMZOKC5CNk9XEh17sZeCK8hrwUREVHIBuQ4wvCLsemUAAAAAElFTkSuQmCC); - } - #fire-button-opts:hover { - background-color: #444; - } -} - -.protection-toggle__row { - padding: 12px; -} -.environment--browser .protection-toggle__row { - padding-top: 11px; - padding-bottom: 11px; -} -.environment--ios .protection-toggle__row { - padding: 8.5px 16px; - font-size: 15px; - font-style: normal; - font-weight: 400; - line-height: 20px; -} -.environment--android .protection-toggle__row { - padding: 8.5px 16px; - font-size: 15px; - font-style: normal; - font-weight: 400; - line-height: 20px; -} -.environment--windows .protection-toggle__row { - padding: 10px 16px; - font-size: 14px; - font-style: normal; - font-weight: 400; - line-height: 24px; -} -.environment--macos .protection-toggle__row { - padding-top: 13px; - padding-bottom: 13px; -} - -.protection-toggle__row--alt { - background: #ccdaff; -} -.body--theme-dark .protection-toggle__row--alt { - background: rgba(85, 127, 243, 0.18); -} -.environment--ios .protection-toggle__row--alt { - padding: 12px 16px; -} -.environment--android .protection-toggle__row--alt { - padding: 12px 16px; -} - -/* Generic menu list styling */ -.default-list { - list-style-type: none; - padding-left: 0; - margin-top: 0; -} -.default-list li .icon__arrow { - right: 15px; - top: calc(50% - 6px); -} -.environment--browser .default-list li .icon__arrow { - right: 10px; -} - -/* Sliding subviews */ -.sliding-subview { - position: absolute; - top: 0; - left: 100%; - width: 100%; - height: 100%; - box-sizing: border-box; -} -.sliding-subview.sliding-subview--root { - position: relative; - top: 0; - left: 0; - transition: left 0.3s ease-in-out; -} -.sliding-subview.sliding-subview--root.sliding-subview--immediate { - transition: none; -} -.sliding-subview.sliding-subview--root.sliding-subview--open { - left: -100%; -} - -/* Sliding subviews */ -.sliding-subview-v2 { - position: absolute; - top: 0; - width: var(--width); - height: var(--height); - box-sizing: border-box; -} -.sliding-subview-v2:not(.sliding-subview-v2--root) { - overflow-y: auto; -} - -.sliding-subview-v2--root { - position: absolute; - top: 0; - left: 0; -} - -.sliding-subview-v2--animating { - transition: transform 0.3s ease-in-out; -} - -.platform-limitations { - padding: 16px 0; - text-align: center; -} - -.button[data-size=small] { - line-height: 13px; - height: 20px; - padding: 0px 12px; - border-radius: 5px; -} -.button[data-size=big] { - height: 50px; - padding: 0px 24px; - /* Button */ - font-size: 15px; - font-style: normal; - font-weight: 600; - line-height: 20px; /* 133.333% */ -} -.button[data-size=desktop-large] { - height: 29px; - padding: 0px 12px; -} -.button[data-variant=desktop-standard] { - background: rgba(0, 0, 0, 0.06); - border-radius: 6px; - color: rgba(0, 0, 0, 0.84); -} -.button[data-variant=desktop-standard]:hover { - background: rgba(0, 0, 0, 0.09); -} -.button[data-variant=desktop-standard]:active { - background: rgba(0, 0, 0, 0.12); -} -.button[data-variant=desktop-standard]:disabled { - opacity: 0.8; -} -.body--theme-dark .button[data-variant=desktop-standard] { - background: rgba(255, 255, 255, 0.12); - color: rgba(255, 255, 255, 0.84); -} -.body--theme-dark .button[data-variant=desktop-standard]:hover { - background: rgba(255, 255, 255, 0.18); -} -.body--theme-dark .button[data-variant=desktop-standard]:active { - background: rgba(255, 255, 255, 0.24); -} -.button[data-variant=desktop-standard][data-size=desktop-large] { - font-size: 14px; - font-weight: 400; - height: 40px; - padding: 0 16px; -} -.button[data-variant=desktop-vibrancy] { - border-radius: 6px; - background: rgba(0, 0, 0, 0.1); - /* Mac/Control/Vibrant */ - box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0), 0px 0px 1px 0px rgba(0, 0, 0, 0), 0px 1px 1px 0px rgba(0, 0, 0, 0); -} -.button[data-variant=desktop-vibrancy]:active { - border-radius: 6px; - background: rgba(0, 0, 0, 0.2); - /* Mac/Control/Vibrant */ - box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0), 0px 0px 1px 0px rgba(0, 0, 0, 0), 0px 1px 1px 0px rgba(0, 0, 0, 0); -} -.body--theme-dark .button[data-variant=desktop-vibrancy] { - border-radius: 6px; - background: rgba(255, 255, 255, 0.28); - /* Mac/Control/Vibrant */ - box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0.05) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0.1), 0px 0px 1px 0px rgba(0, 0, 0, 0.05), 0px 1px 1px 0px rgba(0, 0, 0, 0.2); -} -.body--theme-dark .button[data-variant=desktop-vibrancy]:active { - border-radius: 6px; - background: rgba(255, 255, 255, 0.35); - /* Mac/Control/Vibrant */ - box-shadow: 0px 0.5px 0px 0px rgba(255, 255, 255, 0.2) inset, 0px 1px 0px 0px rgba(255, 255, 255, 0.05) inset, 0px 0px 0px 0.5px rgba(0, 0, 0, 0.1), 0px 0px 1px 0px rgba(0, 0, 0, 0.05), 0px 1px 1px 0px rgba(0, 0, 0, 0.2); -} -.button[data-variant=ios-secondary] { - justify-content: center; - align-items: center; - gap: 8px; - flex-shrink: 0; - border-radius: 8px; - border: 1px solid var(--color-accent-blue); - color: var(--color-accent-blue); - text-align: center; - background: transparent; -} -.button[data-variant=ios-secondary]:active { - background: rgba(57, 105, 239, 0.2); - color: var(--color-accent-blue-active); -} - -.button-bar[data-layout=horizontal] { - display: grid; - gap: 12px; - grid-template-columns: 1fr 1fr; -} -.button-bar[data-layout=vertical] { - display: flex; - gap: 12px; - flex-direction: column; -} -.button-bar[data-layout=vertical] > * { - width: 100%; -} -.environment--android .button-bar[data-layout=vertical] { - gap: 8px; -} - -.text-link-as-button:hover { - text-decoration: underline; -} -.text-link-as-button:active { - text-decoration: none; -} - -.stack { - display: flex; - flex-direction: column; - gap: 24px; - width: 100%; -} -.stack[data-debug=true] > * { - outline: 1px dotted black; -} - -.scrollable { - height: 280px; - overflow-y: scroll; - border-radius: 6px; - border: 1px solid rgba(0, 0, 0, 0.1); - /* NOTE: this is not using alpha because the custom scrollbars need to stack */ - background: rgb(252, 252, 252); - padding: 16px 20px 20px 16px; -} -.body--theme-dark .scrollable { - /* NOTE: this is not using alpha because the custom scrollbars need to stack */ - background: rgb(57, 57, 57); - border-color: rgba(255, 255, 255, 0.09); -} - -.data-list__content { - font-size: 14px; - font-weight: 400; - line-height: 1.4285714286; -} -.environment--android .data-list__content { - font-size: 14px; - font-weight: 400; - line-height: 1.2857142857; -} -.environment--ios .data-list__content, .environment--macos .data-list__content { - font-size: 13px; - font-weight: 400; - line-height: 1.3846153846; -} -.environment--android .data-list__content--breakage, .environment--browser .data-list__content--breakage, .environment--ios .data-list__content--breakage, .environment--macos .data-list__content--breakage, .environment--windows .data-list__content--breakage { - font-size: 13px; - line-height: 1.3846153846; -} - -.data-list__heading { - font-weight: 600; -} -.environment--android .data-list__heading { - font-weight: 700; -} - -.data-list { - list-style: none; -} - -.data-list__item { - word-wrap: anywhere; - color: var(--color-text-secondary); - position: relative; - padding-left: 20px; -} -.data-list__item + .data-list__item { - margin-top: 3px; -} - -.data-list__item::before { - content: "•"; - font-size: 12px; - position: absolute; - left: 8px; - top: 8px; - transform: translateY(-50%); - color: currentColor; -} - -.ios-separator { - padding-top: 16px; - border-top: 1px solid var(--color-system-lines); -} - -.fade-in { - opacity: 0; - visibility: hidden; - animation-name: fade-in; - animation-fill-mode: forwards; - animation-duration: 1s; -} - -@keyframes fade-in { - from { - opacity: 0; - visibility: hidden; - } - to { - opacity: 1; - visibility: visible; - } -} -.environment--macos .toggle-report[data-opener=dashboard] .top-nav { - opacity: 0; - visibility: hidden; -} - -.environment--ios [data-toggle-report=child], -.environment--android [data-toggle-report=child] { - opacity: 0; - visibility: hidden; -} - -.environment--ios [data-toggle-report=child][data-ready=true], -.environment--android [data-toggle-report=child][data-ready=true] { - opacity: 1; - visibility: visible; -} - -.toggle-report__heading { - margin-bottom: 24px; -} - -.toggle-report__scroller { - margin-bottom: 16px; -} -.toggle-report__scroller .scrollable::-webkit-scrollbar { - width: 14px; -} -.toggle-report__scroller .scrollable::-webkit-scrollbar-track { - border-radius: 6px; -} -.toggle-report__scroller .scrollable::-webkit-scrollbar-thumb { - background: rgba(0, 0, 0, 0.1); - /* NOTE: this is not using alpha because the custom scrollbars need to stack */ - border: 2px solid rgb(252, 252, 252); - border-radius: 6px; -} -.body--theme-dark .toggle-report__scroller .scrollable::-webkit-scrollbar-thumb { - /* NOTE: this is not using alpha because the custom scrollbars need to stack */ - border-color: rgb(57, 57, 57); - background: rgba(0, 0, 0, 0.3); -} diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/android-breakage-dialog.js b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/android-breakage-dialog.js deleted file mode 100644 index 1900913d49e9..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/android-breakage-dialog.js +++ /dev/null @@ -1,5042 +0,0 @@ -"use strict"; -(() => { - var __defProp = Object.defineProperty; - var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; - var __publicField = (obj, key, value) => { - __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); - return value; - }; - - // node_modules/@lit/reactive-element/css-tag.js - var t = globalThis; - var e = t.ShadowRoot && (void 0 === t.ShadyCSS || t.ShadyCSS.nativeShadow) && "adoptedStyleSheets" in Document.prototype && "replace" in CSSStyleSheet.prototype; - var s = Symbol(); - var o = /* @__PURE__ */ new WeakMap(); - var n = class { - constructor(t4, e6, o5) { - if (this._$cssResult$ = true, o5 !== s) - throw Error("CSSResult is not constructable. Use `unsafeCSS` or `css` instead."); - this.cssText = t4, this.t = e6; - } - get styleSheet() { - let t4 = this.o; - const s2 = this.t; - if (e && void 0 === t4) { - const e6 = void 0 !== s2 && 1 === s2.length; - e6 && (t4 = o.get(s2)), void 0 === t4 && ((this.o = t4 = new CSSStyleSheet()).replaceSync(this.cssText), e6 && o.set(s2, t4)); - } - return t4; - } - toString() { - return this.cssText; - } - }; - var r = (t4) => new n("string" == typeof t4 ? t4 : t4 + "", void 0, s); - var i = (t4, ...e6) => { - const o5 = 1 === t4.length ? t4[0] : e6.reduce((e7, s2, o6) => e7 + ((t5) => { - if (true === t5._$cssResult$) - return t5.cssText; - if ("number" == typeof t5) - return t5; - throw Error("Value passed to 'css' function must be a 'css' function result: " + t5 + ". Use 'unsafeCSS' to pass non-literal values, but take care to ensure page security."); - })(s2) + t4[o6 + 1], t4[0]); - return new n(o5, t4, s); - }; - var S = (s2, o5) => { - if (e) - s2.adoptedStyleSheets = o5.map((t4) => t4 instanceof CSSStyleSheet ? t4 : t4.styleSheet); - else - for (const e6 of o5) { - const o6 = document.createElement("style"), n5 = t.litNonce; - void 0 !== n5 && o6.setAttribute("nonce", n5), o6.textContent = e6.cssText, s2.appendChild(o6); - } - }; - var c = e ? (t4) => t4 : (t4) => t4 instanceof CSSStyleSheet ? ((t5) => { - let e6 = ""; - for (const s2 of t5.cssRules) - e6 += s2.cssText; - return r(e6); - })(t4) : t4; - - // node_modules/@lit/reactive-element/reactive-element.js - var { is: i2, defineProperty: e2, getOwnPropertyDescriptor: r2, getOwnPropertyNames: h, getOwnPropertySymbols: o2, getPrototypeOf: n2 } = Object; - var a = globalThis; - var c2 = a.trustedTypes; - var l = c2 ? c2.emptyScript : ""; - var p = a.reactiveElementPolyfillSupport; - var d = (t4, s2) => t4; - var u = { toAttribute(t4, s2) { - switch (s2) { - case Boolean: - t4 = t4 ? l : null; - break; - case Object: - case Array: - t4 = null == t4 ? t4 : JSON.stringify(t4); - } - return t4; - }, fromAttribute(t4, s2) { - let i4 = t4; - switch (s2) { - case Boolean: - i4 = null !== t4; - break; - case Number: - i4 = null === t4 ? null : Number(t4); - break; - case Object: - case Array: - try { - i4 = JSON.parse(t4); - } catch (t5) { - i4 = null; - } - } - return i4; - } }; - var f = (t4, s2) => !i2(t4, s2); - var y = { attribute: true, type: String, converter: u, reflect: false, hasChanged: f }; - Symbol.metadata ??= Symbol("metadata"), a.litPropertyMetadata ??= /* @__PURE__ */ new WeakMap(); - var b = class extends HTMLElement { - static addInitializer(t4) { - this._$Ei(), (this.l ??= []).push(t4); - } - static get observedAttributes() { - return this.finalize(), this._$Eh && [...this._$Eh.keys()]; - } - static createProperty(t4, s2 = y) { - if (s2.state && (s2.attribute = false), this._$Ei(), this.elementProperties.set(t4, s2), !s2.noAccessor) { - const i4 = Symbol(), r5 = this.getPropertyDescriptor(t4, i4, s2); - void 0 !== r5 && e2(this.prototype, t4, r5); - } - } - static getPropertyDescriptor(t4, s2, i4) { - const { get: e6, set: h4 } = r2(this.prototype, t4) ?? { get() { - return this[s2]; - }, set(t5) { - this[s2] = t5; - } }; - return { get() { - return e6?.call(this); - }, set(s3) { - const r5 = e6?.call(this); - h4.call(this, s3), this.requestUpdate(t4, r5, i4); - }, configurable: true, enumerable: true }; - } - static getPropertyOptions(t4) { - return this.elementProperties.get(t4) ?? y; - } - static _$Ei() { - if (this.hasOwnProperty(d("elementProperties"))) - return; - const t4 = n2(this); - t4.finalize(), void 0 !== t4.l && (this.l = [...t4.l]), this.elementProperties = new Map(t4.elementProperties); - } - static finalize() { - if (this.hasOwnProperty(d("finalized"))) - return; - if (this.finalized = true, this._$Ei(), this.hasOwnProperty(d("properties"))) { - const t5 = this.properties, s2 = [...h(t5), ...o2(t5)]; - for (const i4 of s2) - this.createProperty(i4, t5[i4]); - } - const t4 = this[Symbol.metadata]; - if (null !== t4) { - const s2 = litPropertyMetadata.get(t4); - if (void 0 !== s2) - for (const [t5, i4] of s2) - this.elementProperties.set(t5, i4); - } - this._$Eh = /* @__PURE__ */ new Map(); - for (const [t5, s2] of this.elementProperties) { - const i4 = this._$Eu(t5, s2); - void 0 !== i4 && this._$Eh.set(i4, t5); - } - this.elementStyles = this.finalizeStyles(this.styles); - } - static finalizeStyles(s2) { - const i4 = []; - if (Array.isArray(s2)) { - const e6 = new Set(s2.flat(1 / 0).reverse()); - for (const s3 of e6) - i4.unshift(c(s3)); - } else - void 0 !== s2 && i4.push(c(s2)); - return i4; - } - static _$Eu(t4, s2) { - const i4 = s2.attribute; - return false === i4 ? void 0 : "string" == typeof i4 ? i4 : "string" == typeof t4 ? t4.toLowerCase() : void 0; - } - constructor() { - super(), this._$Ep = void 0, this.isUpdatePending = false, this.hasUpdated = false, this._$Em = null, this._$Ev(); - } - _$Ev() { - this._$ES = new Promise((t4) => this.enableUpdating = t4), this._$AL = /* @__PURE__ */ new Map(), this._$E_(), this.requestUpdate(), this.constructor.l?.forEach((t4) => t4(this)); - } - addController(t4) { - (this._$EO ??= /* @__PURE__ */ new Set()).add(t4), void 0 !== this.renderRoot && this.isConnected && t4.hostConnected?.(); - } - removeController(t4) { - this._$EO?.delete(t4); - } - _$E_() { - const t4 = /* @__PURE__ */ new Map(), s2 = this.constructor.elementProperties; - for (const i4 of s2.keys()) - this.hasOwnProperty(i4) && (t4.set(i4, this[i4]), delete this[i4]); - t4.size > 0 && (this._$Ep = t4); - } - createRenderRoot() { - const t4 = this.shadowRoot ?? this.attachShadow(this.constructor.shadowRootOptions); - return S(t4, this.constructor.elementStyles), t4; - } - connectedCallback() { - this.renderRoot ??= this.createRenderRoot(), this.enableUpdating(true), this._$EO?.forEach((t4) => t4.hostConnected?.()); - } - enableUpdating(t4) { - } - disconnectedCallback() { - this._$EO?.forEach((t4) => t4.hostDisconnected?.()); - } - attributeChangedCallback(t4, s2, i4) { - this._$AK(t4, i4); - } - _$EC(t4, s2) { - const i4 = this.constructor.elementProperties.get(t4), e6 = this.constructor._$Eu(t4, i4); - if (void 0 !== e6 && true === i4.reflect) { - const r5 = (void 0 !== i4.converter?.toAttribute ? i4.converter : u).toAttribute(s2, i4.type); - this._$Em = t4, null == r5 ? this.removeAttribute(e6) : this.setAttribute(e6, r5), this._$Em = null; - } - } - _$AK(t4, s2) { - const i4 = this.constructor, e6 = i4._$Eh.get(t4); - if (void 0 !== e6 && this._$Em !== e6) { - const t5 = i4.getPropertyOptions(e6), r5 = "function" == typeof t5.converter ? { fromAttribute: t5.converter } : void 0 !== t5.converter?.fromAttribute ? t5.converter : u; - this._$Em = e6, this[e6] = r5.fromAttribute(s2, t5.type), this._$Em = null; - } - } - requestUpdate(t4, s2, i4) { - if (void 0 !== t4) { - if (i4 ??= this.constructor.getPropertyOptions(t4), !(i4.hasChanged ?? f)(this[t4], s2)) - return; - this.P(t4, s2, i4); - } - false === this.isUpdatePending && (this._$ES = this._$ET()); - } - P(t4, s2, i4) { - this._$AL.has(t4) || this._$AL.set(t4, s2), true === i4.reflect && this._$Em !== t4 && (this._$Ej ??= /* @__PURE__ */ new Set()).add(t4); - } - async _$ET() { - this.isUpdatePending = true; - try { - await this._$ES; - } catch (t5) { - Promise.reject(t5); - } - const t4 = this.scheduleUpdate(); - return null != t4 && await t4, !this.isUpdatePending; - } - scheduleUpdate() { - return this.performUpdate(); - } - performUpdate() { - if (!this.isUpdatePending) - return; - if (!this.hasUpdated) { - if (this.renderRoot ??= this.createRenderRoot(), this._$Ep) { - for (const [t6, s3] of this._$Ep) - this[t6] = s3; - this._$Ep = void 0; - } - const t5 = this.constructor.elementProperties; - if (t5.size > 0) - for (const [s3, i4] of t5) - true !== i4.wrapped || this._$AL.has(s3) || void 0 === this[s3] || this.P(s3, this[s3], i4); - } - let t4 = false; - const s2 = this._$AL; - try { - t4 = this.shouldUpdate(s2), t4 ? (this.willUpdate(s2), this._$EO?.forEach((t5) => t5.hostUpdate?.()), this.update(s2)) : this._$EU(); - } catch (s3) { - throw t4 = false, this._$EU(), s3; - } - t4 && this._$AE(s2); - } - willUpdate(t4) { - } - _$AE(t4) { - this._$EO?.forEach((t5) => t5.hostUpdated?.()), this.hasUpdated || (this.hasUpdated = true, this.firstUpdated(t4)), this.updated(t4); - } - _$EU() { - this._$AL = /* @__PURE__ */ new Map(), this.isUpdatePending = false; - } - get updateComplete() { - return this.getUpdateComplete(); - } - getUpdateComplete() { - return this._$ES; - } - shouldUpdate(t4) { - return true; - } - update(t4) { - this._$Ej &&= this._$Ej.forEach((t5) => this._$EC(t5, this[t5])), this._$EU(); - } - updated(t4) { - } - firstUpdated(t4) { - } - }; - b.elementStyles = [], b.shadowRootOptions = { mode: "open" }, b[d("elementProperties")] = /* @__PURE__ */ new Map(), b[d("finalized")] = /* @__PURE__ */ new Map(), p?.({ ReactiveElement: b }), (a.reactiveElementVersions ??= []).push("2.0.4"); - - // node_modules/lit-html/lit-html.js - var n3 = globalThis; - var c3 = n3.trustedTypes; - var h2 = c3 ? c3.createPolicy("lit-html", { createHTML: (t4) => t4 }) : void 0; - var f2 = "$lit$"; - var v = `lit$${Math.random().toFixed(9).slice(2)}$`; - var m = "?" + v; - var _ = `<${m}>`; - var w = document; - var lt = () => w.createComment(""); - var st = (t4) => null === t4 || "object" != typeof t4 && "function" != typeof t4; - var g = Array.isArray; - var $ = (t4) => g(t4) || "function" == typeof t4?.[Symbol.iterator]; - var x = "[ \n\f\r]"; - var T = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g; - var E = /-->/g; - var k = />/g; - var O = RegExp(`>|${x}(?:([^\\s"'>=/]+)(${x}*=${x}*(?:[^ -\f\r"'\`<>=]|("|')|))|$)`, "g"); - var S2 = /'/g; - var j = /"/g; - var M = /^(?:script|style|textarea|title)$/i; - var P = (t4) => (i4, ...s2) => ({ _$litType$: t4, strings: i4, values: s2 }); - var ke = P(1); - var Oe = P(2); - var Se = P(3); - var R = Symbol.for("lit-noChange"); - var D = Symbol.for("lit-nothing"); - var V = /* @__PURE__ */ new WeakMap(); - var I = w.createTreeWalker(w, 129); - function N(t4, i4) { - if (!g(t4) || !t4.hasOwnProperty("raw")) - throw Error("invalid template strings array"); - return void 0 !== h2 ? h2.createHTML(i4) : i4; - } - var U = (t4, i4) => { - const s2 = t4.length - 1, e6 = []; - let h4, o5 = 2 === i4 ? "" : 3 === i4 ? "" : "", n5 = T; - for (let i5 = 0; i5 < s2; i5++) { - const s3 = t4[i5]; - let r5, l2, c4 = -1, a2 = 0; - for (; a2 < s3.length && (n5.lastIndex = a2, l2 = n5.exec(s3), null !== l2); ) - a2 = n5.lastIndex, n5 === T ? "!--" === l2[1] ? n5 = E : void 0 !== l2[1] ? n5 = k : void 0 !== l2[2] ? (M.test(l2[2]) && (h4 = RegExp("" === l2[0] ? (n5 = h4 ?? T, c4 = -1) : void 0 === l2[1] ? c4 = -2 : (c4 = n5.lastIndex - l2[2].length, r5 = l2[1], n5 = void 0 === l2[3] ? O : '"' === l2[3] ? j : S2) : n5 === j || n5 === S2 ? n5 = O : n5 === E || n5 === k ? n5 = T : (n5 = O, h4 = void 0); - const u2 = n5 === O && t4[i5 + 1].startsWith("/>") ? " " : ""; - o5 += n5 === T ? s3 + _ : c4 >= 0 ? (e6.push(r5), s3.slice(0, c4) + f2 + s3.slice(c4) + v + u2) : s3 + v + (-2 === c4 ? i5 : u2); - } - return [N(t4, o5 + (t4[s2] || "") + (2 === i4 ? "" : 3 === i4 ? "" : "")), e6]; - }; - var B = class _B { - constructor({ strings: t4, _$litType$: i4 }, s2) { - let e6; - this.parts = []; - let h4 = 0, o5 = 0; - const n5 = t4.length - 1, r5 = this.parts, [l2, a2] = U(t4, i4); - if (this.el = _B.createElement(l2, s2), I.currentNode = this.el.content, 2 === i4 || 3 === i4) { - const t5 = this.el.content.firstChild; - t5.replaceWith(...t5.childNodes); - } - for (; null !== (e6 = I.nextNode()) && r5.length < n5; ) { - if (1 === e6.nodeType) { - if (e6.hasAttributes()) - for (const t5 of e6.getAttributeNames()) - if (t5.endsWith(f2)) { - const i5 = a2[o5++], s3 = e6.getAttribute(t5).split(v), n6 = /([.?@])?(.*)/.exec(i5); - r5.push({ type: 1, index: h4, name: n6[2], strings: s3, ctor: "." === n6[1] ? Y : "?" === n6[1] ? Z : "@" === n6[1] ? q : G }), e6.removeAttribute(t5); - } else - t5.startsWith(v) && (r5.push({ type: 6, index: h4 }), e6.removeAttribute(t5)); - if (M.test(e6.tagName)) { - const t5 = e6.textContent.split(v), i5 = t5.length - 1; - if (i5 > 0) { - e6.textContent = c3 ? c3.emptyScript : ""; - for (let s3 = 0; s3 < i5; s3++) - e6.append(t5[s3], lt()), I.nextNode(), r5.push({ type: 2, index: ++h4 }); - e6.append(t5[i5], lt()); - } - } - } else if (8 === e6.nodeType) - if (e6.data === m) - r5.push({ type: 2, index: h4 }); - else { - let t5 = -1; - for (; -1 !== (t5 = e6.data.indexOf(v, t5 + 1)); ) - r5.push({ type: 7, index: h4 }), t5 += v.length - 1; - } - h4++; - } - } - static createElement(t4, i4) { - const s2 = w.createElement("template"); - return s2.innerHTML = t4, s2; - } - }; - function z(t4, i4, s2 = t4, e6) { - if (i4 === R) - return i4; - let h4 = void 0 !== e6 ? s2.o?.[e6] : s2.l; - const o5 = st(i4) ? void 0 : i4._$litDirective$; - return h4?.constructor !== o5 && (h4?._$AO?.(false), void 0 === o5 ? h4 = void 0 : (h4 = new o5(t4), h4._$AT(t4, s2, e6)), void 0 !== e6 ? (s2.o ??= [])[e6] = h4 : s2.l = h4), void 0 !== h4 && (i4 = z(t4, h4._$AS(t4, i4.values), h4, e6)), i4; - } - var F = class { - constructor(t4, i4) { - this._$AV = [], this._$AN = void 0, this._$AD = t4, this._$AM = i4; - } - get parentNode() { - return this._$AM.parentNode; - } - get _$AU() { - return this._$AM._$AU; - } - u(t4) { - const { el: { content: i4 }, parts: s2 } = this._$AD, e6 = (t4?.creationScope ?? w).importNode(i4, true); - I.currentNode = e6; - let h4 = I.nextNode(), o5 = 0, n5 = 0, r5 = s2[0]; - for (; void 0 !== r5; ) { - if (o5 === r5.index) { - let i5; - 2 === r5.type ? i5 = new et(h4, h4.nextSibling, this, t4) : 1 === r5.type ? i5 = new r5.ctor(h4, r5.name, r5.strings, this, t4) : 6 === r5.type && (i5 = new K(h4, this, t4)), this._$AV.push(i5), r5 = s2[++n5]; - } - o5 !== r5?.index && (h4 = I.nextNode(), o5++); - } - return I.currentNode = w, e6; - } - p(t4) { - let i4 = 0; - for (const s2 of this._$AV) - void 0 !== s2 && (void 0 !== s2.strings ? (s2._$AI(t4, s2, i4), i4 += s2.strings.length - 2) : s2._$AI(t4[i4])), i4++; - } - }; - var et = class _et { - get _$AU() { - return this._$AM?._$AU ?? this.v; - } - constructor(t4, i4, s2, e6) { - this.type = 2, this._$AH = D, this._$AN = void 0, this._$AA = t4, this._$AB = i4, this._$AM = s2, this.options = e6, this.v = e6?.isConnected ?? true; - } - get parentNode() { - let t4 = this._$AA.parentNode; - const i4 = this._$AM; - return void 0 !== i4 && 11 === t4?.nodeType && (t4 = i4.parentNode), t4; - } - get startNode() { - return this._$AA; - } - get endNode() { - return this._$AB; - } - _$AI(t4, i4 = this) { - t4 = z(this, t4, i4), st(t4) ? t4 === D || null == t4 || "" === t4 ? (this._$AH !== D && this._$AR(), this._$AH = D) : t4 !== this._$AH && t4 !== R && this._(t4) : void 0 !== t4._$litType$ ? this.$(t4) : void 0 !== t4.nodeType ? this.T(t4) : $(t4) ? this.k(t4) : this._(t4); - } - O(t4) { - return this._$AA.parentNode.insertBefore(t4, this._$AB); - } - T(t4) { - this._$AH !== t4 && (this._$AR(), this._$AH = this.O(t4)); - } - _(t4) { - this._$AH !== D && st(this._$AH) ? this._$AA.nextSibling.data = t4 : this.T(w.createTextNode(t4)), this._$AH = t4; - } - $(t4) { - const { values: i4, _$litType$: s2 } = t4, e6 = "number" == typeof s2 ? this._$AC(t4) : (void 0 === s2.el && (s2.el = B.createElement(N(s2.h, s2.h[0]), this.options)), s2); - if (this._$AH?._$AD === e6) - this._$AH.p(i4); - else { - const t5 = new F(e6, this), s3 = t5.u(this.options); - t5.p(i4), this.T(s3), this._$AH = t5; - } - } - _$AC(t4) { - let i4 = V.get(t4.strings); - return void 0 === i4 && V.set(t4.strings, i4 = new B(t4)), i4; - } - k(t4) { - g(this._$AH) || (this._$AH = [], this._$AR()); - const i4 = this._$AH; - let s2, e6 = 0; - for (const h4 of t4) - e6 === i4.length ? i4.push(s2 = new _et(this.O(lt()), this.O(lt()), this, this.options)) : s2 = i4[e6], s2._$AI(h4), e6++; - e6 < i4.length && (this._$AR(s2 && s2._$AB.nextSibling, e6), i4.length = e6); - } - _$AR(t4 = this._$AA.nextSibling, i4) { - for (this._$AP?.(false, true, i4); t4 && t4 !== this._$AB; ) { - const i5 = t4.nextSibling; - t4.remove(), t4 = i5; - } - } - setConnected(t4) { - void 0 === this._$AM && (this.v = t4, this._$AP?.(t4)); - } - }; - var G = class { - get tagName() { - return this.element.tagName; - } - get _$AU() { - return this._$AM._$AU; - } - constructor(t4, i4, s2, e6, h4) { - this.type = 1, this._$AH = D, this._$AN = void 0, this.element = t4, this.name = i4, this._$AM = e6, this.options = h4, s2.length > 2 || "" !== s2[0] || "" !== s2[1] ? (this._$AH = Array(s2.length - 1).fill(new String()), this.strings = s2) : this._$AH = D; - } - _$AI(t4, i4 = this, s2, e6) { - const h4 = this.strings; - let o5 = false; - if (void 0 === h4) - t4 = z(this, t4, i4, 0), o5 = !st(t4) || t4 !== this._$AH && t4 !== R, o5 && (this._$AH = t4); - else { - const e7 = t4; - let n5, r5; - for (t4 = h4[0], n5 = 0; n5 < h4.length - 1; n5++) - r5 = z(this, e7[s2 + n5], i4, n5), r5 === R && (r5 = this._$AH[n5]), o5 ||= !st(r5) || r5 !== this._$AH[n5], r5 === D ? t4 = D : t4 !== D && (t4 += (r5 ?? "") + h4[n5 + 1]), this._$AH[n5] = r5; - } - o5 && !e6 && this.j(t4); - } - j(t4) { - t4 === D ? this.element.removeAttribute(this.name) : this.element.setAttribute(this.name, t4 ?? ""); - } - }; - var Y = class extends G { - constructor() { - super(...arguments), this.type = 3; - } - j(t4) { - this.element[this.name] = t4 === D ? void 0 : t4; - } - }; - var Z = class extends G { - constructor() { - super(...arguments), this.type = 4; - } - j(t4) { - this.element.toggleAttribute(this.name, !!t4 && t4 !== D); - } - }; - var q = class extends G { - constructor(t4, i4, s2, e6, h4) { - super(t4, i4, s2, e6, h4), this.type = 5; - } - _$AI(t4, i4 = this) { - if ((t4 = z(this, t4, i4, 0) ?? D) === R) - return; - const s2 = this._$AH, e6 = t4 === D && s2 !== D || t4.capture !== s2.capture || t4.once !== s2.once || t4.passive !== s2.passive, h4 = t4 !== D && (s2 === D || e6); - e6 && this.element.removeEventListener(this.name, this, s2), h4 && this.element.addEventListener(this.name, this, t4), this._$AH = t4; - } - handleEvent(t4) { - "function" == typeof this._$AH ? this._$AH.call(this.options?.host ?? this.element, t4) : this._$AH.handleEvent(t4); - } - }; - var K = class { - constructor(t4, i4, s2) { - this.element = t4, this.type = 6, this._$AN = void 0, this._$AM = i4, this.options = s2; - } - get _$AU() { - return this._$AM._$AU; - } - _$AI(t4) { - z(this, t4); - } - }; - var si = { M: f2, P: v, A: m, C: 1, L: U, R: F, D: $, V: z, I: et, H: G, N: Z, U: q, B: Y, F: K }; - var Re = n3.litHtmlPolyfillSupport; - Re?.(B, et), (n3.litHtmlVersions ??= []).push("3.2.0"); - var Q = (t4, i4, s2) => { - const e6 = s2?.renderBefore ?? i4; - let h4 = e6._$litPart$; - if (void 0 === h4) { - const t5 = s2?.renderBefore ?? null; - e6._$litPart$ = h4 = new et(i4.insertBefore(lt(), t5), t5, void 0, s2 ?? {}); - } - return h4._$AI(t4), h4; - }; - - // node_modules/lit-element/lit-element.js - var h3 = class extends b { - constructor() { - super(...arguments), this.renderOptions = { host: this }, this.o = void 0; - } - createRenderRoot() { - const t4 = super.createRenderRoot(); - return this.renderOptions.renderBefore ??= t4.firstChild, t4; - } - update(t4) { - const e6 = this.render(); - this.hasUpdated || (this.renderOptions.isConnected = this.isConnected), super.update(t4), this.o = Q(e6, this.renderRoot, this.renderOptions); - } - connectedCallback() { - super.connectedCallback(), this.o?.setConnected(true); - } - disconnectedCallback() { - super.disconnectedCallback(), this.o?.setConnected(false); - } - render() { - return R; - } - }; - h3._$litElement$ = true, h3["finalized"] = true, globalThis.litElementHydrateSupport?.({ LitElement: h3 }); - var f3 = globalThis.litElementPolyfillSupport; - f3?.({ LitElement: h3 }); - (globalThis.litElementVersions ??= []).push("4.1.0"); - - // node_modules/lit-html/is-server.js - var co = false; - - // node_modules/lit-html/directives/map.js - function* oo(o5, f4) { - if (void 0 !== o5) { - let i4 = 0; - for (const t4 of o5) - yield f4(t4, i4++); - } - } - - // node_modules/tslib/tslib.es6.js - function __decorate(decorators, target, key, desc) { - var c4 = arguments.length, r5 = c4 < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d2; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") - r5 = Reflect.decorate(decorators, target, key, desc); - else - for (var i4 = decorators.length - 1; i4 >= 0; i4--) - if (d2 = decorators[i4]) - r5 = (c4 < 3 ? d2(r5) : c4 > 3 ? d2(target, key, r5) : d2(target, key)) || r5; - return c4 > 3 && r5 && Object.defineProperty(target, key, r5), r5; - } - - // node_modules/@lit/reactive-element/decorators/custom-element.js - var t2 = (t4) => (e6, o5) => { - void 0 !== o5 ? o5.addInitializer(() => { - customElements.define(t4, e6); - }) : customElements.define(t4, e6); - }; - - // node_modules/@lit/reactive-element/decorators/property.js - var o3 = { attribute: true, type: String, converter: u, reflect: false, hasChanged: f }; - var r3 = (t4 = o3, e6, r5) => { - const { kind: n5, metadata: i4 } = r5; - let s2 = globalThis.litPropertyMetadata.get(i4); - if (void 0 === s2 && globalThis.litPropertyMetadata.set(i4, s2 = /* @__PURE__ */ new Map()), s2.set(r5.name, t4), "accessor" === n5) { - const { name: o5 } = r5; - return { set(r6) { - const n6 = e6.get.call(this); - e6.set.call(this, r6), this.requestUpdate(o5, n6, t4); - }, init(e7) { - return void 0 !== e7 && this.P(o5, void 0, t4), e7; - } }; - } - if ("setter" === n5) { - const { name: o5 } = r5; - return function(r6) { - const n6 = this[o5]; - e6.call(this, r6), this.requestUpdate(o5, n6, t4); - }; - } - throw Error("Unsupported decorator location: " + n5); - }; - function n4(t4) { - return (e6, o5) => "object" == typeof o5 ? r3(t4, e6, o5) : ((t5, e7, o6) => { - const r5 = e7.hasOwnProperty(o6); - return e7.constructor.createProperty(o6, r5 ? { ...t5, wrapped: true } : t5), r5 ? Object.getOwnPropertyDescriptor(e7, o6) : void 0; - })(t4, e6, o5); - } - - // node_modules/@lit/reactive-element/decorators/state.js - function r4(r5) { - return n4({ ...r5, state: true, attribute: false }); - } - - // node_modules/@lit/reactive-element/decorators/base.js - var e3 = (e6, t4, c4) => (c4.configurable = true, c4.enumerable = true, Reflect.decorate && "object" != typeof t4 && Object.defineProperty(e6, t4, c4), c4); - - // node_modules/@lit/reactive-element/decorators/query.js - function e4(e6, r5) { - return (n5, s2, i4) => { - const o5 = (t4) => t4.renderRoot?.querySelector(e6) ?? null; - if (r5) { - const { get: e7, set: r6 } = "object" == typeof s2 ? n5 : i4 ?? (() => { - const t4 = Symbol(); - return { get() { - return this[t4]; - }, set(e8) { - this[t4] = e8; - } }; - })(); - return e3(n5, s2, { get() { - let t4 = e7.call(this); - return void 0 === t4 && (t4 = o5(this), (null !== t4 || this.hasUpdated) && r6.call(this, t4)), t4; - } }); - } - return e3(n5, s2, { get() { - return o5(this); - } }); - }; - } - - // node_modules/@lit/reactive-element/decorators/query-assigned-elements.js - function o4(o5) { - return (e6, n5) => { - const { slot: r5, selector: s2 } = o5 ?? {}, c4 = "slot" + (r5 ? `[name=${r5}]` : ":not([name])"); - return e3(e6, n5, { get() { - const t4 = this.renderRoot?.querySelector(c4), e7 = t4?.assignedElements(o5) ?? []; - return void 0 === s2 ? e7 : e7.filter((t5) => t5.matches(s2)); - } }); - }; - } - - // node_modules/@material/web/elevation/internal/elevation.js - var Elevation = class extends h3 { - connectedCallback() { - super.connectedCallback(); - this.setAttribute("aria-hidden", "true"); - } - render() { - return ke``; - } - }; - - // node_modules/@material/web/elevation/internal/elevation-styles.js - var styles = i`:host,.shadow,.shadow::before,.shadow::after{border-radius:inherit;inset:0;position:absolute;transition-duration:inherit;transition-property:inherit;transition-timing-function:inherit}:host{display:flex;pointer-events:none;transition-property:box-shadow,opacity}.shadow::before,.shadow::after{content:"";transition-property:box-shadow,opacity;--_level: var(--md-elevation-level, 0);--_shadow-color: var(--md-elevation-shadow-color, var(--md-sys-color-shadow, #000))}.shadow::before{box-shadow:0px calc(1px*(clamp(0,var(--_level),1) + clamp(0,var(--_level) - 3,1) + 2*clamp(0,var(--_level) - 4,1))) calc(1px*(2*clamp(0,var(--_level),1) + clamp(0,var(--_level) - 2,1) + clamp(0,var(--_level) - 4,1))) 0px var(--_shadow-color);opacity:.3}.shadow::after{box-shadow:0px calc(1px*(clamp(0,var(--_level),1) + clamp(0,var(--_level) - 1,1) + 2*clamp(0,var(--_level) - 2,3))) calc(1px*(3*clamp(0,var(--_level),2) + 2*clamp(0,var(--_level) - 2,3))) calc(1px*(clamp(0,var(--_level),4) + 2*clamp(0,var(--_level) - 4,1))) var(--_shadow-color);opacity:.15} -`; - - // node_modules/@material/web/elevation/elevation.js - var MdElevation = class MdElevation2 extends Elevation { - }; - MdElevation.styles = [styles]; - MdElevation = __decorate([ - t2("md-elevation") - ], MdElevation); - - // node_modules/@material/web/internal/controller/attachable-controller.js - var ATTACHABLE_CONTROLLER = Symbol("attachableController"); - var FOR_ATTRIBUTE_OBSERVER; - if (!co) { - FOR_ATTRIBUTE_OBSERVER = new MutationObserver((records) => { - for (const record of records) { - record.target[ATTACHABLE_CONTROLLER]?.hostConnected(); - } - }); - } - var AttachableController = class { - get htmlFor() { - return this.host.getAttribute("for"); - } - set htmlFor(htmlFor) { - if (htmlFor === null) { - this.host.removeAttribute("for"); - } else { - this.host.setAttribute("for", htmlFor); - } - } - get control() { - if (this.host.hasAttribute("for")) { - if (!this.htmlFor || !this.host.isConnected) { - return null; - } - return this.host.getRootNode().querySelector(`#${this.htmlFor}`); - } - return this.currentControl || this.host.parentElement; - } - set control(control) { - if (control) { - this.attach(control); - } else { - this.detach(); - } - } - /** - * Creates a new controller for an `Attachable` element. - * - * @param host The `Attachable` element. - * @param onControlChange A callback with two parameters for the previous and - * next control. An `Attachable` element may perform setup or teardown - * logic whenever the control changes. - */ - constructor(host, onControlChange) { - this.host = host; - this.onControlChange = onControlChange; - this.currentControl = null; - host.addController(this); - host[ATTACHABLE_CONTROLLER] = this; - FOR_ATTRIBUTE_OBSERVER?.observe(host, { attributeFilter: ["for"] }); - } - attach(control) { - if (control === this.currentControl) { - return; - } - this.setCurrentControl(control); - this.host.removeAttribute("for"); - } - detach() { - this.setCurrentControl(null); - this.host.setAttribute("for", ""); - } - /** @private */ - hostConnected() { - this.setCurrentControl(this.control); - } - /** @private */ - hostDisconnected() { - this.setCurrentControl(null); - } - setCurrentControl(control) { - this.onControlChange(this.currentControl, control); - this.currentControl = control; - } - }; - - // node_modules/@material/web/focus/internal/focus-ring.js - var EVENTS = ["focusin", "focusout", "pointerdown"]; - var FocusRing = class extends h3 { - constructor() { - super(...arguments); - this.visible = false; - this.inward = false; - this.attachableController = new AttachableController(this, this.onControlChange.bind(this)); - } - get htmlFor() { - return this.attachableController.htmlFor; - } - set htmlFor(htmlFor) { - this.attachableController.htmlFor = htmlFor; - } - get control() { - return this.attachableController.control; - } - set control(control) { - this.attachableController.control = control; - } - attach(control) { - this.attachableController.attach(control); - } - detach() { - this.attachableController.detach(); - } - connectedCallback() { - super.connectedCallback(); - this.setAttribute("aria-hidden", "true"); - } - /** @private */ - handleEvent(event) { - if (event[HANDLED_BY_FOCUS_RING]) { - return; - } - switch (event.type) { - default: - return; - case "focusin": - this.visible = this.control?.matches(":focus-visible") ?? false; - break; - case "focusout": - case "pointerdown": - this.visible = false; - break; - } - event[HANDLED_BY_FOCUS_RING] = true; - } - onControlChange(prev, next) { - if (co) - return; - for (const event of EVENTS) { - prev?.removeEventListener(event, this); - next?.addEventListener(event, this); - } - } - update(changed) { - if (changed.has("visible")) { - this.dispatchEvent(new Event("visibility-changed")); - } - super.update(changed); - } - }; - __decorate([ - n4({ type: Boolean, reflect: true }) - ], FocusRing.prototype, "visible", void 0); - __decorate([ - n4({ type: Boolean, reflect: true }) - ], FocusRing.prototype, "inward", void 0); - var HANDLED_BY_FOCUS_RING = Symbol("handledByFocusRing"); - - // node_modules/@material/web/focus/internal/focus-ring-styles.js - var styles2 = i`:host{animation-delay:0s,calc(var(--md-focus-ring-duration, 600ms)*.25);animation-duration:calc(var(--md-focus-ring-duration, 600ms)*.25),calc(var(--md-focus-ring-duration, 600ms)*.75);animation-timing-function:cubic-bezier(0.2, 0, 0, 1);box-sizing:border-box;color:var(--md-focus-ring-color, var(--md-sys-color-secondary, #625b71));display:none;pointer-events:none;position:absolute}:host([visible]){display:flex}:host(:not([inward])){animation-name:outward-grow,outward-shrink;border-end-end-radius:calc(var(--md-focus-ring-shape-end-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));border-end-start-radius:calc(var(--md-focus-ring-shape-end-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));border-start-end-radius:calc(var(--md-focus-ring-shape-start-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));border-start-start-radius:calc(var(--md-focus-ring-shape-start-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) + var(--md-focus-ring-outward-offset, 2px));inset:calc(-1*var(--md-focus-ring-outward-offset, 2px));outline:var(--md-focus-ring-width, 3px) solid currentColor}:host([inward]){animation-name:inward-grow,inward-shrink;border-end-end-radius:calc(var(--md-focus-ring-shape-end-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border-end-start-radius:calc(var(--md-focus-ring-shape-end-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border-start-end-radius:calc(var(--md-focus-ring-shape-start-end, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border-start-start-radius:calc(var(--md-focus-ring-shape-start-start, var(--md-focus-ring-shape, var(--md-sys-shape-corner-full, 9999px))) - var(--md-focus-ring-inward-offset, 0px));border:var(--md-focus-ring-width, 3px) solid currentColor;inset:var(--md-focus-ring-inward-offset, 0px)}@keyframes outward-grow{from{outline-width:0}to{outline-width:var(--md-focus-ring-active-width, 8px)}}@keyframes outward-shrink{from{outline-width:var(--md-focus-ring-active-width, 8px)}}@keyframes inward-grow{from{border-width:0}to{border-width:var(--md-focus-ring-active-width, 8px)}}@keyframes inward-shrink{from{border-width:var(--md-focus-ring-active-width, 8px)}}@media(prefers-reduced-motion){:host{animation:none}} -`; - - // node_modules/@material/web/focus/md-focus-ring.js - var MdFocusRing = class MdFocusRing2 extends FocusRing { - }; - MdFocusRing.styles = [styles2]; - MdFocusRing = __decorate([ - t2("md-focus-ring") - ], MdFocusRing); - - // node_modules/lit-html/directive.js - var t3 = { ATTRIBUTE: 1, CHILD: 2, PROPERTY: 3, BOOLEAN_ATTRIBUTE: 4, EVENT: 5, ELEMENT: 6 }; - var e5 = (t4) => (...e6) => ({ _$litDirective$: t4, values: e6 }); - var i3 = class { - constructor(t4) { - } - get _$AU() { - return this._$AM._$AU; - } - _$AT(t4, e6, i4) { - this.t = t4, this._$AM = e6, this.i = i4; - } - _$AS(t4, e6) { - return this.update(t4, e6); - } - update(t4, e6) { - return this.render(...e6); - } - }; - - // node_modules/lit-html/directives/class-map.js - var Rt = e5(class extends i3 { - constructor(s2) { - if (super(s2), s2.type !== t3.ATTRIBUTE || "class" !== s2.name || s2.strings?.length > 2) - throw Error("`classMap()` can only be used in the `class` attribute and must be the only part in the attribute."); - } - render(t4) { - return " " + Object.keys(t4).filter((s2) => t4[s2]).join(" ") + " "; - } - update(t4, [s2]) { - if (void 0 === this.st) { - this.st = /* @__PURE__ */ new Set(), void 0 !== t4.strings && (this.nt = new Set(t4.strings.join(" ").split(/\s/).filter((t5) => "" !== t5))); - for (const t5 in s2) - s2[t5] && !this.nt?.has(t5) && this.st.add(t5); - return this.render(s2); - } - const i4 = t4.element.classList; - for (const t5 of this.st) - t5 in s2 || (i4.remove(t5), this.st.delete(t5)); - for (const t5 in s2) { - const r5 = !!s2[t5]; - r5 === this.st.has(t5) || this.nt?.has(t5) || (r5 ? (i4.add(t5), this.st.add(t5)) : (i4.remove(t5), this.st.delete(t5))); - } - return R; - } - }); - - // node_modules/@material/web/internal/motion/animation.js - var EASING = { - STANDARD: "cubic-bezier(0.2, 0, 0, 1)", - STANDARD_ACCELERATE: "cubic-bezier(.3,0,1,1)", - STANDARD_DECELERATE: "cubic-bezier(0,0,0,1)", - EMPHASIZED: "cubic-bezier(.3,0,0,1)", - EMPHASIZED_ACCELERATE: "cubic-bezier(.3,0,.8,.15)", - EMPHASIZED_DECELERATE: "cubic-bezier(.05,.7,.1,1)" - }; - - // node_modules/@material/web/ripple/internal/ripple.js - var PRESS_GROW_MS = 450; - var MINIMUM_PRESS_MS = 225; - var INITIAL_ORIGIN_SCALE = 0.2; - var PADDING = 10; - var SOFT_EDGE_MINIMUM_SIZE = 75; - var SOFT_EDGE_CONTAINER_RATIO = 0.35; - var PRESS_PSEUDO = "::after"; - var ANIMATION_FILL = "forwards"; - var State; - (function(State2) { - State2[State2["INACTIVE"] = 0] = "INACTIVE"; - State2[State2["TOUCH_DELAY"] = 1] = "TOUCH_DELAY"; - State2[State2["HOLDING"] = 2] = "HOLDING"; - State2[State2["WAITING_FOR_CLICK"] = 3] = "WAITING_FOR_CLICK"; - })(State || (State = {})); - var EVENTS2 = [ - "click", - "contextmenu", - "pointercancel", - "pointerdown", - "pointerenter", - "pointerleave", - "pointerup" - ]; - var TOUCH_DELAY_MS = 150; - var FORCED_COLORS = co ? null : window.matchMedia("(forced-colors: active)"); - var Ripple = class extends h3 { - constructor() { - super(...arguments); - this.disabled = false; - this.hovered = false; - this.pressed = false; - this.rippleSize = ""; - this.rippleScale = ""; - this.initialSize = 0; - this.state = State.INACTIVE; - this.checkBoundsAfterContextMenu = false; - this.attachableController = new AttachableController(this, this.onControlChange.bind(this)); - } - get htmlFor() { - return this.attachableController.htmlFor; - } - set htmlFor(htmlFor) { - this.attachableController.htmlFor = htmlFor; - } - get control() { - return this.attachableController.control; - } - set control(control) { - this.attachableController.control = control; - } - attach(control) { - this.attachableController.attach(control); - } - detach() { - this.attachableController.detach(); - } - connectedCallback() { - super.connectedCallback(); - this.setAttribute("aria-hidden", "true"); - } - render() { - const classes = { - "hovered": this.hovered, - "pressed": this.pressed - }; - return ke`
`; - } - update(changedProps) { - if (changedProps.has("disabled") && this.disabled) { - this.hovered = false; - this.pressed = false; - } - super.update(changedProps); - } - /** - * TODO(b/269799771): make private - * @private only public for slider - */ - handlePointerenter(event) { - if (!this.shouldReactToEvent(event)) { - return; - } - this.hovered = true; - } - /** - * TODO(b/269799771): make private - * @private only public for slider - */ - handlePointerleave(event) { - if (!this.shouldReactToEvent(event)) { - return; - } - this.hovered = false; - if (this.state !== State.INACTIVE) { - this.endPressAnimation(); - } - } - handlePointerup(event) { - if (!this.shouldReactToEvent(event)) { - return; - } - if (this.state === State.HOLDING) { - this.state = State.WAITING_FOR_CLICK; - return; - } - if (this.state === State.TOUCH_DELAY) { - this.state = State.WAITING_FOR_CLICK; - this.startPressAnimation(this.rippleStartEvent); - return; - } - } - async handlePointerdown(event) { - if (!this.shouldReactToEvent(event)) { - return; - } - this.rippleStartEvent = event; - if (!this.isTouch(event)) { - this.state = State.WAITING_FOR_CLICK; - this.startPressAnimation(event); - return; - } - if (this.checkBoundsAfterContextMenu && !this.inBounds(event)) { - return; - } - this.checkBoundsAfterContextMenu = false; - this.state = State.TOUCH_DELAY; - await new Promise((resolve) => { - setTimeout(resolve, TOUCH_DELAY_MS); - }); - if (this.state !== State.TOUCH_DELAY) { - return; - } - this.state = State.HOLDING; - this.startPressAnimation(event); - } - handleClick() { - if (this.disabled) { - return; - } - if (this.state === State.WAITING_FOR_CLICK) { - this.endPressAnimation(); - return; - } - if (this.state === State.INACTIVE) { - this.startPressAnimation(); - this.endPressAnimation(); - } - } - handlePointercancel(event) { - if (!this.shouldReactToEvent(event)) { - return; - } - this.endPressAnimation(); - } - handleContextmenu() { - if (this.disabled) { - return; - } - this.checkBoundsAfterContextMenu = true; - this.endPressAnimation(); - } - determineRippleSize() { - const { height, width } = this.getBoundingClientRect(); - const maxDim = Math.max(height, width); - const softEdgeSize = Math.max(SOFT_EDGE_CONTAINER_RATIO * maxDim, SOFT_EDGE_MINIMUM_SIZE); - const initialSize = Math.floor(maxDim * INITIAL_ORIGIN_SCALE); - const hypotenuse = Math.sqrt(width ** 2 + height ** 2); - const maxRadius = hypotenuse + PADDING; - this.initialSize = initialSize; - this.rippleScale = `${(maxRadius + softEdgeSize) / initialSize}`; - this.rippleSize = `${initialSize}px`; - } - getNormalizedPointerEventCoords(pointerEvent) { - const { scrollX, scrollY } = window; - const { left, top } = this.getBoundingClientRect(); - const documentX = scrollX + left; - const documentY = scrollY + top; - const { pageX, pageY } = pointerEvent; - return { x: pageX - documentX, y: pageY - documentY }; - } - getTranslationCoordinates(positionEvent) { - const { height, width } = this.getBoundingClientRect(); - const endPoint = { - x: (width - this.initialSize) / 2, - y: (height - this.initialSize) / 2 - }; - let startPoint; - if (positionEvent instanceof PointerEvent) { - startPoint = this.getNormalizedPointerEventCoords(positionEvent); - } else { - startPoint = { - x: width / 2, - y: height / 2 - }; - } - startPoint = { - x: startPoint.x - this.initialSize / 2, - y: startPoint.y - this.initialSize / 2 - }; - return { startPoint, endPoint }; - } - startPressAnimation(positionEvent) { - if (!this.mdRoot) { - return; - } - this.pressed = true; - this.growAnimation?.cancel(); - this.determineRippleSize(); - const { startPoint, endPoint } = this.getTranslationCoordinates(positionEvent); - const translateStart = `${startPoint.x}px, ${startPoint.y}px`; - const translateEnd = `${endPoint.x}px, ${endPoint.y}px`; - this.growAnimation = this.mdRoot.animate({ - top: [0, 0], - left: [0, 0], - height: [this.rippleSize, this.rippleSize], - width: [this.rippleSize, this.rippleSize], - transform: [ - `translate(${translateStart}) scale(1)`, - `translate(${translateEnd}) scale(${this.rippleScale})` - ] - }, { - pseudoElement: PRESS_PSEUDO, - duration: PRESS_GROW_MS, - easing: EASING.STANDARD, - fill: ANIMATION_FILL - }); - } - async endPressAnimation() { - this.rippleStartEvent = void 0; - this.state = State.INACTIVE; - const animation = this.growAnimation; - let pressAnimationPlayState = Infinity; - if (typeof animation?.currentTime === "number") { - pressAnimationPlayState = animation.currentTime; - } else if (animation?.currentTime) { - pressAnimationPlayState = animation.currentTime.to("ms").value; - } - if (pressAnimationPlayState >= MINIMUM_PRESS_MS) { - this.pressed = false; - return; - } - await new Promise((resolve) => { - setTimeout(resolve, MINIMUM_PRESS_MS - pressAnimationPlayState); - }); - if (this.growAnimation !== animation) { - return; - } - this.pressed = false; - } - /** - * Returns `true` if - * - the ripple element is enabled - * - the pointer is primary for the input type - * - the pointer is the pointer that started the interaction, or will start - * the interaction - * - the pointer is a touch, or the pointer state has the primary button - * held, or the pointer is hovering - */ - shouldReactToEvent(event) { - if (this.disabled || !event.isPrimary) { - return false; - } - if (this.rippleStartEvent && this.rippleStartEvent.pointerId !== event.pointerId) { - return false; - } - if (event.type === "pointerenter" || event.type === "pointerleave") { - return !this.isTouch(event); - } - const isPrimaryButton = event.buttons === 1; - return this.isTouch(event) || isPrimaryButton; - } - /** - * Check if the event is within the bounds of the element. - * - * This is only needed for the "stuck" contextmenu longpress on Chrome. - */ - inBounds({ x: x2, y: y2 }) { - const { top, left, bottom, right } = this.getBoundingClientRect(); - return x2 >= left && x2 <= right && y2 >= top && y2 <= bottom; - } - isTouch({ pointerType }) { - return pointerType === "touch"; - } - /** @private */ - async handleEvent(event) { - if (FORCED_COLORS?.matches) { - return; - } - switch (event.type) { - case "click": - this.handleClick(); - break; - case "contextmenu": - this.handleContextmenu(); - break; - case "pointercancel": - this.handlePointercancel(event); - break; - case "pointerdown": - await this.handlePointerdown(event); - break; - case "pointerenter": - this.handlePointerenter(event); - break; - case "pointerleave": - this.handlePointerleave(event); - break; - case "pointerup": - this.handlePointerup(event); - break; - default: - break; - } - } - onControlChange(prev, next) { - if (co) - return; - for (const event of EVENTS2) { - prev?.removeEventListener(event, this); - next?.addEventListener(event, this); - } - } - }; - __decorate([ - n4({ type: Boolean, reflect: true }) - ], Ripple.prototype, "disabled", void 0); - __decorate([ - r4() - ], Ripple.prototype, "hovered", void 0); - __decorate([ - r4() - ], Ripple.prototype, "pressed", void 0); - __decorate([ - e4(".surface") - ], Ripple.prototype, "mdRoot", void 0); - - // node_modules/@material/web/ripple/internal/ripple-styles.js - var styles3 = i`:host{display:flex;margin:auto;pointer-events:none}:host([disabled]){display:none}@media(forced-colors: active){:host{display:none}}:host,.surface{border-radius:inherit;position:absolute;inset:0;overflow:hidden}.surface{-webkit-tap-highlight-color:rgba(0,0,0,0)}.surface::before,.surface::after{content:"";opacity:0;position:absolute}.surface::before{background-color:var(--md-ripple-hover-color, var(--md-sys-color-on-surface, #1d1b20));inset:0;transition:opacity 15ms linear,background-color 15ms linear}.surface::after{background:radial-gradient(closest-side, var(--md-ripple-pressed-color, var(--md-sys-color-on-surface, #1d1b20)) max(100% - 70px, 65%), transparent 100%);transform-origin:center center;transition:opacity 375ms linear}.hovered::before{background-color:var(--md-ripple-hover-color, var(--md-sys-color-on-surface, #1d1b20));opacity:var(--md-ripple-hover-opacity, 0.08)}.pressed::after{opacity:var(--md-ripple-pressed-opacity, 0.12);transition-duration:105ms} -`; - - // node_modules/@material/web/ripple/ripple.js - var MdRipple = class MdRipple2 extends Ripple { - }; - MdRipple.styles = [styles3]; - MdRipple = __decorate([ - t2("md-ripple") - ], MdRipple); - - // node_modules/@material/web/internal/aria/aria.js - var ARIA_PROPERTIES = [ - "role", - "ariaAtomic", - "ariaAutoComplete", - "ariaBusy", - "ariaChecked", - "ariaColCount", - "ariaColIndex", - "ariaColSpan", - "ariaCurrent", - "ariaDisabled", - "ariaExpanded", - "ariaHasPopup", - "ariaHidden", - "ariaInvalid", - "ariaKeyShortcuts", - "ariaLabel", - "ariaLevel", - "ariaLive", - "ariaModal", - "ariaMultiLine", - "ariaMultiSelectable", - "ariaOrientation", - "ariaPlaceholder", - "ariaPosInSet", - "ariaPressed", - "ariaReadOnly", - "ariaRequired", - "ariaRoleDescription", - "ariaRowCount", - "ariaRowIndex", - "ariaRowSpan", - "ariaSelected", - "ariaSetSize", - "ariaSort", - "ariaValueMax", - "ariaValueMin", - "ariaValueNow", - "ariaValueText" - ]; - var ARIA_ATTRIBUTES = ARIA_PROPERTIES.map(ariaPropertyToAttribute); - function isAriaAttribute(attribute) { - return ARIA_ATTRIBUTES.includes(attribute); - } - function ariaPropertyToAttribute(property) { - return property.replace("aria", "aria-").replace(/Elements?/g, "").toLowerCase(); - } - - // node_modules/@material/web/internal/aria/delegate.js - var privateIgnoreAttributeChangesFor = Symbol("privateIgnoreAttributeChangesFor"); - function mixinDelegatesAria(base) { - var _a2; - if (co) { - return base; - } - class WithDelegatesAriaElement extends base { - constructor() { - super(...arguments); - this[_a2] = /* @__PURE__ */ new Set(); - } - attributeChangedCallback(name, oldValue, newValue) { - if (!isAriaAttribute(name)) { - super.attributeChangedCallback(name, oldValue, newValue); - return; - } - if (this[privateIgnoreAttributeChangesFor].has(name)) { - return; - } - this[privateIgnoreAttributeChangesFor].add(name); - this.removeAttribute(name); - this[privateIgnoreAttributeChangesFor].delete(name); - const dataProperty = ariaAttributeToDataProperty(name); - if (newValue === null) { - delete this.dataset[dataProperty]; - } else { - this.dataset[dataProperty] = newValue; - } - this.requestUpdate(ariaAttributeToDataProperty(name), oldValue); - } - getAttribute(name) { - if (isAriaAttribute(name)) { - return super.getAttribute(ariaAttributeToDataAttribute(name)); - } - return super.getAttribute(name); - } - removeAttribute(name) { - super.removeAttribute(name); - if (isAriaAttribute(name)) { - super.removeAttribute(ariaAttributeToDataAttribute(name)); - this.requestUpdate(); - } - } - } - _a2 = privateIgnoreAttributeChangesFor; - setupDelegatesAriaProperties(WithDelegatesAriaElement); - return WithDelegatesAriaElement; - } - function setupDelegatesAriaProperties(ctor) { - for (const ariaProperty of ARIA_PROPERTIES) { - const ariaAttribute = ariaPropertyToAttribute(ariaProperty); - const dataAttribute = ariaAttributeToDataAttribute(ariaAttribute); - const dataProperty = ariaAttributeToDataProperty(ariaAttribute); - ctor.createProperty(ariaProperty, { - attribute: ariaAttribute, - noAccessor: true - }); - ctor.createProperty(Symbol(dataAttribute), { - attribute: dataAttribute, - noAccessor: true - }); - Object.defineProperty(ctor.prototype, ariaProperty, { - configurable: true, - enumerable: true, - get() { - return this.dataset[dataProperty] ?? null; - }, - set(value) { - const prevValue = this.dataset[dataProperty] ?? null; - if (value === prevValue) { - return; - } - if (value === null) { - delete this.dataset[dataProperty]; - } else { - this.dataset[dataProperty] = value; - } - this.requestUpdate(ariaProperty, prevValue); - } - }); - } - } - function ariaAttributeToDataAttribute(ariaAttribute) { - return `data-${ariaAttribute}`; - } - function ariaAttributeToDataProperty(ariaAttribute) { - return ariaAttribute.replace(/-\w/, (dashLetter) => dashLetter[1].toUpperCase()); - } - - // node_modules/@material/web/labs/behaviors/element-internals.js - var internals = Symbol("internals"); - var privateInternals = Symbol("privateInternals"); - function mixinElementInternals(base) { - class WithElementInternalsElement extends base { - get [internals]() { - if (!this[privateInternals]) { - this[privateInternals] = this.attachInternals(); - } - return this[privateInternals]; - } - } - return WithElementInternalsElement; - } - - // node_modules/@material/web/internal/controller/form-submitter.js - function setupFormSubmitter(ctor) { - if (co) { - return; - } - ctor.addInitializer((instance) => { - const submitter = instance; - submitter.addEventListener("click", async (event) => { - const { type, [internals]: elementInternals } = submitter; - const { form } = elementInternals; - if (!form || type === "button") { - return; - } - await new Promise((resolve) => { - setTimeout(resolve); - }); - if (event.defaultPrevented) { - return; - } - if (type === "reset") { - form.reset(); - return; - } - form.addEventListener("submit", (submitEvent) => { - Object.defineProperty(submitEvent, "submitter", { - configurable: true, - enumerable: true, - get: () => submitter - }); - }, { capture: true, once: true }); - elementInternals.setFormValue(submitter.value); - form.requestSubmit(); - }); - }); - } - - // node_modules/@material/web/internal/events/form-label-activation.js - function dispatchActivationClick(element) { - const event = new MouseEvent("click", { bubbles: true }); - element.dispatchEvent(event); - return event; - } - function isActivationClick(event) { - if (event.currentTarget !== event.target) { - return false; - } - if (event.composedPath()[0] !== event.target) { - return false; - } - if (event.target.disabled) { - return false; - } - return !squelchEvent(event); - } - function squelchEvent(event) { - const squelched = isSquelchingEvents; - if (squelched) { - event.preventDefault(); - event.stopImmediatePropagation(); - } - squelchEventsForMicrotask(); - return squelched; - } - var isSquelchingEvents = false; - async function squelchEventsForMicrotask() { - isSquelchingEvents = true; - await null; - isSquelchingEvents = false; - } - - // node_modules/@material/web/button/internal/button.js - var buttonBaseClass = mixinDelegatesAria(mixinElementInternals(h3)); - var Button = class extends buttonBaseClass { - get name() { - return this.getAttribute("name") ?? ""; - } - set name(name) { - this.setAttribute("name", name); - } - /** - * The associated form element with which this element's value will submit. - */ - get form() { - return this[internals].form; - } - constructor() { - super(); - this.disabled = false; - this.softDisabled = false; - this.href = ""; - this.target = ""; - this.trailingIcon = false; - this.hasIcon = false; - this.type = "submit"; - this.value = ""; - if (!co) { - this.addEventListener("click", this.handleClick.bind(this)); - } - } - focus() { - this.buttonElement?.focus(); - } - blur() { - this.buttonElement?.blur(); - } - render() { - const isRippleDisabled = !this.href && (this.disabled || this.softDisabled); - const buttonOrLink = this.href ? this.renderLink() : this.renderButton(); - const buttonId = this.href ? "link" : "button"; - return ke` - ${this.renderElevationOrOutline?.()} -
- - - ${buttonOrLink} - `; - } - renderButton() { - const { ariaLabel, ariaHasPopup, ariaExpanded } = this; - return ke``; - } - renderLink() { - const { ariaLabel, ariaHasPopup, ariaExpanded } = this; - return ke`${this.renderContent()} - `; - } - renderContent() { - const icon = ke``; - return ke` - - ${this.trailingIcon ? D : icon} - - ${this.trailingIcon ? icon : D} - `; - } - handleClick(event) { - if (!this.href && this.softDisabled) { - event.stopImmediatePropagation(); - event.preventDefault(); - return; - } - if (!isActivationClick(event) || !this.buttonElement) { - return; - } - this.focus(); - dispatchActivationClick(this.buttonElement); - } - handleSlotChange() { - this.hasIcon = this.assignedIcons.length > 0; - } - }; - (() => { - setupFormSubmitter(Button); - })(); - Button.formAssociated = true; - Button.shadowRootOptions = { - mode: "open", - delegatesFocus: true - }; - __decorate([ - n4({ type: Boolean, reflect: true }) - ], Button.prototype, "disabled", void 0); - __decorate([ - n4({ type: Boolean, attribute: "soft-disabled", reflect: true }) - ], Button.prototype, "softDisabled", void 0); - __decorate([ - n4() - ], Button.prototype, "href", void 0); - __decorate([ - n4() - ], Button.prototype, "target", void 0); - __decorate([ - n4({ type: Boolean, attribute: "trailing-icon", reflect: true }) - ], Button.prototype, "trailingIcon", void 0); - __decorate([ - n4({ type: Boolean, attribute: "has-icon", reflect: true }) - ], Button.prototype, "hasIcon", void 0); - __decorate([ - n4() - ], Button.prototype, "type", void 0); - __decorate([ - n4({ reflect: true }) - ], Button.prototype, "value", void 0); - __decorate([ - e4(".button") - ], Button.prototype, "buttonElement", void 0); - __decorate([ - o4({ slot: "icon", flatten: true }) - ], Button.prototype, "assignedIcons", void 0); - - // node_modules/@material/web/button/internal/filled-button.js - var FilledButton = class extends Button { - renderElevationOrOutline() { - return ke``; - } - }; - - // node_modules/@material/web/button/internal/filled-styles.js - var styles4 = i`:host{--_container-color: var(--md-filled-button-container-color, var(--md-sys-color-primary, #6750a4));--_container-elevation: var(--md-filled-button-container-elevation, 0);--_container-height: var(--md-filled-button-container-height, 40px);--_container-shadow-color: var(--md-filled-button-container-shadow-color, var(--md-sys-color-shadow, #000));--_disabled-container-color: var(--md-filled-button-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-container-elevation: var(--md-filled-button-disabled-container-elevation, 0);--_disabled-container-opacity: var(--md-filled-button-disabled-container-opacity, 0.12);--_disabled-label-text-color: var(--md-filled-button-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-filled-button-disabled-label-text-opacity, 0.38);--_focus-container-elevation: var(--md-filled-button-focus-container-elevation, 0);--_focus-label-text-color: var(--md-filled-button-focus-label-text-color, var(--md-sys-color-on-primary, #fff));--_hover-container-elevation: var(--md-filled-button-hover-container-elevation, 1);--_hover-label-text-color: var(--md-filled-button-hover-label-text-color, var(--md-sys-color-on-primary, #fff));--_hover-state-layer-color: var(--md-filled-button-hover-state-layer-color, var(--md-sys-color-on-primary, #fff));--_hover-state-layer-opacity: var(--md-filled-button-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-filled-button-label-text-color, var(--md-sys-color-on-primary, #fff));--_label-text-font: var(--md-filled-button-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-filled-button-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-filled-button-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-filled-button-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-container-elevation: var(--md-filled-button-pressed-container-elevation, 0);--_pressed-label-text-color: var(--md-filled-button-pressed-label-text-color, var(--md-sys-color-on-primary, #fff));--_pressed-state-layer-color: var(--md-filled-button-pressed-state-layer-color, var(--md-sys-color-on-primary, #fff));--_pressed-state-layer-opacity: var(--md-filled-button-pressed-state-layer-opacity, 0.12);--_disabled-icon-color: var(--md-filled-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-filled-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-filled-button-focus-icon-color, var(--md-sys-color-on-primary, #fff));--_hover-icon-color: var(--md-filled-button-hover-icon-color, var(--md-sys-color-on-primary, #fff));--_icon-color: var(--md-filled-button-icon-color, var(--md-sys-color-on-primary, #fff));--_icon-size: var(--md-filled-button-icon-size, 18px);--_pressed-icon-color: var(--md-filled-button-pressed-icon-color, var(--md-sys-color-on-primary, #fff));--_container-shape-start-start: var(--md-filled-button-container-shape-start-start, var(--md-filled-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-filled-button-container-shape-start-end, var(--md-filled-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-filled-button-container-shape-end-end, var(--md-filled-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-filled-button-container-shape-end-start, var(--md-filled-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_leading-space: var(--md-filled-button-leading-space, 24px);--_trailing-space: var(--md-filled-button-trailing-space, 24px);--_with-leading-icon-leading-space: var(--md-filled-button-with-leading-icon-leading-space, 16px);--_with-leading-icon-trailing-space: var(--md-filled-button-with-leading-icon-trailing-space, 24px);--_with-trailing-icon-leading-space: var(--md-filled-button-with-trailing-icon-leading-space, 24px);--_with-trailing-icon-trailing-space: var(--md-filled-button-with-trailing-icon-trailing-space, 16px)} -`; - - // node_modules/@material/web/button/internal/shared-elevation-styles.js - var styles5 = i`md-elevation{transition-duration:280ms}:host(:is([disabled],[soft-disabled])) md-elevation{transition:none}md-elevation{--md-elevation-level: var(--_container-elevation);--md-elevation-shadow-color: var(--_container-shadow-color)}:host(:focus-within) md-elevation{--md-elevation-level: var(--_focus-container-elevation)}:host(:hover) md-elevation{--md-elevation-level: var(--_hover-container-elevation)}:host(:active) md-elevation{--md-elevation-level: var(--_pressed-container-elevation)}:host(:is([disabled],[soft-disabled])) md-elevation{--md-elevation-level: var(--_disabled-container-elevation)} -`; - - // node_modules/@material/web/button/internal/shared-styles.js - var styles6 = i`:host{border-start-start-radius:var(--_container-shape-start-start);border-start-end-radius:var(--_container-shape-start-end);border-end-start-radius:var(--_container-shape-end-start);border-end-end-radius:var(--_container-shape-end-end);box-sizing:border-box;cursor:pointer;display:inline-flex;gap:8px;min-height:var(--_container-height);outline:none;padding-block:calc((var(--_container-height) - max(var(--_label-text-line-height),var(--_icon-size)))/2);padding-inline-start:var(--_leading-space);padding-inline-end:var(--_trailing-space);place-content:center;place-items:center;position:relative;font-family:var(--_label-text-font);font-size:var(--_label-text-size);line-height:var(--_label-text-line-height);font-weight:var(--_label-text-weight);text-overflow:ellipsis;text-wrap:nowrap;user-select:none;-webkit-tap-highlight-color:rgba(0,0,0,0);vertical-align:top;--md-ripple-hover-color: var(--_hover-state-layer-color);--md-ripple-pressed-color: var(--_pressed-state-layer-color);--md-ripple-hover-opacity: var(--_hover-state-layer-opacity);--md-ripple-pressed-opacity: var(--_pressed-state-layer-opacity)}md-focus-ring{--md-focus-ring-shape-start-start: var(--_container-shape-start-start);--md-focus-ring-shape-start-end: var(--_container-shape-start-end);--md-focus-ring-shape-end-end: var(--_container-shape-end-end);--md-focus-ring-shape-end-start: var(--_container-shape-end-start)}:host(:is([disabled],[soft-disabled])){cursor:default;pointer-events:none}.button{border-radius:inherit;cursor:inherit;display:inline-flex;align-items:center;justify-content:center;border:none;outline:none;-webkit-appearance:none;vertical-align:middle;background:rgba(0,0,0,0);text-decoration:none;min-width:calc(64px - var(--_leading-space) - var(--_trailing-space));width:100%;z-index:0;height:100%;font:inherit;color:var(--_label-text-color);padding:0;gap:inherit;text-transform:inherit}.button::-moz-focus-inner{padding:0;border:0}:host(:hover) .button{color:var(--_hover-label-text-color)}:host(:focus-within) .button{color:var(--_focus-label-text-color)}:host(:active) .button{color:var(--_pressed-label-text-color)}.background{background-color:var(--_container-color);border-radius:inherit;inset:0;position:absolute}.label{overflow:hidden}:is(.button,.label,.label slot),.label ::slotted(*){text-overflow:inherit}:host(:is([disabled],[soft-disabled])) .label{color:var(--_disabled-label-text-color);opacity:var(--_disabled-label-text-opacity)}:host(:is([disabled],[soft-disabled])) .background{background-color:var(--_disabled-container-color);opacity:var(--_disabled-container-opacity)}@media(forced-colors: active){.background{border:1px solid CanvasText}:host(:is([disabled],[soft-disabled])){--_disabled-icon-color: GrayText;--_disabled-icon-opacity: 1;--_disabled-container-opacity: 1;--_disabled-label-text-color: GrayText;--_disabled-label-text-opacity: 1}}:host([has-icon]:not([trailing-icon])){padding-inline-start:var(--_with-leading-icon-leading-space);padding-inline-end:var(--_with-leading-icon-trailing-space)}:host([has-icon][trailing-icon]){padding-inline-start:var(--_with-trailing-icon-leading-space);padding-inline-end:var(--_with-trailing-icon-trailing-space)}::slotted([slot=icon]){display:inline-flex;position:relative;writing-mode:horizontal-tb;fill:currentColor;flex-shrink:0;color:var(--_icon-color);font-size:var(--_icon-size);inline-size:var(--_icon-size);block-size:var(--_icon-size)}:host(:hover) ::slotted([slot=icon]){color:var(--_hover-icon-color)}:host(:focus-within) ::slotted([slot=icon]){color:var(--_focus-icon-color)}:host(:active) ::slotted([slot=icon]){color:var(--_pressed-icon-color)}:host(:is([disabled],[soft-disabled])) ::slotted([slot=icon]){color:var(--_disabled-icon-color);opacity:var(--_disabled-icon-opacity)}.touch{position:absolute;top:50%;height:48px;left:0;right:0;transform:translateY(-50%)}:host([touch-target=wrapper]){margin:max(0px,(48px - var(--_container-height))/2) 0}:host([touch-target=none]) .touch{display:none} -`; - - // node_modules/@material/web/button/filled-button.js - var MdFilledButton = class MdFilledButton2 extends FilledButton { - }; - MdFilledButton.styles = [ - styles6, - styles5, - styles4 - ]; - MdFilledButton = __decorate([ - t2("md-filled-button") - ], MdFilledButton); - - // node_modules/@material/web/button/internal/filled-tonal-button.js - var FilledTonalButton = class extends Button { - renderElevationOrOutline() { - return ke``; - } - }; - - // node_modules/@material/web/button/internal/filled-tonal-styles.js - var styles7 = i`:host{--_container-color: var(--md-filled-tonal-button-container-color, var(--md-sys-color-secondary-container, #e8def8));--_container-elevation: var(--md-filled-tonal-button-container-elevation, 0);--_container-height: var(--md-filled-tonal-button-container-height, 40px);--_container-shadow-color: var(--md-filled-tonal-button-container-shadow-color, var(--md-sys-color-shadow, #000));--_disabled-container-color: var(--md-filled-tonal-button-disabled-container-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-container-elevation: var(--md-filled-tonal-button-disabled-container-elevation, 0);--_disabled-container-opacity: var(--md-filled-tonal-button-disabled-container-opacity, 0.12);--_disabled-label-text-color: var(--md-filled-tonal-button-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-filled-tonal-button-disabled-label-text-opacity, 0.38);--_focus-container-elevation: var(--md-filled-tonal-button-focus-container-elevation, 0);--_focus-label-text-color: var(--md-filled-tonal-button-focus-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-container-elevation: var(--md-filled-tonal-button-hover-container-elevation, 1);--_hover-label-text-color: var(--md-filled-tonal-button-hover-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-state-layer-color: var(--md-filled-tonal-button-hover-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-state-layer-opacity: var(--md-filled-tonal-button-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-filled-tonal-button-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_label-text-font: var(--md-filled-tonal-button-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-filled-tonal-button-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-filled-tonal-button-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-filled-tonal-button-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-container-elevation: var(--md-filled-tonal-button-pressed-container-elevation, 0);--_pressed-label-text-color: var(--md-filled-tonal-button-pressed-label-text-color, var(--md-sys-color-on-secondary-container, #1d192b));--_pressed-state-layer-color: var(--md-filled-tonal-button-pressed-state-layer-color, var(--md-sys-color-on-secondary-container, #1d192b));--_pressed-state-layer-opacity: var(--md-filled-tonal-button-pressed-state-layer-opacity, 0.12);--_disabled-icon-color: var(--md-filled-tonal-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-filled-tonal-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-filled-tonal-button-focus-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_hover-icon-color: var(--md-filled-tonal-button-hover-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_icon-color: var(--md-filled-tonal-button-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_icon-size: var(--md-filled-tonal-button-icon-size, 18px);--_pressed-icon-color: var(--md-filled-tonal-button-pressed-icon-color, var(--md-sys-color-on-secondary-container, #1d192b));--_container-shape-start-start: var(--md-filled-tonal-button-container-shape-start-start, var(--md-filled-tonal-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-filled-tonal-button-container-shape-start-end, var(--md-filled-tonal-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-filled-tonal-button-container-shape-end-end, var(--md-filled-tonal-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-filled-tonal-button-container-shape-end-start, var(--md-filled-tonal-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_leading-space: var(--md-filled-tonal-button-leading-space, 24px);--_trailing-space: var(--md-filled-tonal-button-trailing-space, 24px);--_with-leading-icon-leading-space: var(--md-filled-tonal-button-with-leading-icon-leading-space, 16px);--_with-leading-icon-trailing-space: var(--md-filled-tonal-button-with-leading-icon-trailing-space, 24px);--_with-trailing-icon-leading-space: var(--md-filled-tonal-button-with-trailing-icon-leading-space, 24px);--_with-trailing-icon-trailing-space: var(--md-filled-tonal-button-with-trailing-icon-trailing-space, 16px)} -`; - - // node_modules/@material/web/button/filled-tonal-button.js - var MdFilledTonalButton = class MdFilledTonalButton2 extends FilledTonalButton { - }; - MdFilledTonalButton.styles = [ - styles6, - styles5, - styles7 - ]; - MdFilledTonalButton = __decorate([ - t2("md-filled-tonal-button") - ], MdFilledTonalButton); - - // node_modules/@material/web/button/internal/text-button.js - var TextButton = class extends Button { - }; - - // node_modules/@material/web/button/internal/text-styles.js - var styles8 = i`:host{--_container-height: var(--md-text-button-container-height, 40px);--_disabled-label-text-color: var(--md-text-button-disabled-label-text-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-label-text-opacity: var(--md-text-button-disabled-label-text-opacity, 0.38);--_focus-label-text-color: var(--md-text-button-focus-label-text-color, var(--md-sys-color-primary, #6750a4));--_hover-label-text-color: var(--md-text-button-hover-label-text-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-color: var(--md-text-button-hover-state-layer-color, var(--md-sys-color-primary, #6750a4));--_hover-state-layer-opacity: var(--md-text-button-hover-state-layer-opacity, 0.08);--_label-text-color: var(--md-text-button-label-text-color, var(--md-sys-color-primary, #6750a4));--_label-text-font: var(--md-text-button-label-text-font, var(--md-sys-typescale-label-large-font, var(--md-ref-typeface-plain, Roboto)));--_label-text-line-height: var(--md-text-button-label-text-line-height, var(--md-sys-typescale-label-large-line-height, 1.25rem));--_label-text-size: var(--md-text-button-label-text-size, var(--md-sys-typescale-label-large-size, 0.875rem));--_label-text-weight: var(--md-text-button-label-text-weight, var(--md-sys-typescale-label-large-weight, var(--md-ref-typeface-weight-medium, 500)));--_pressed-label-text-color: var(--md-text-button-pressed-label-text-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-color: var(--md-text-button-pressed-state-layer-color, var(--md-sys-color-primary, #6750a4));--_pressed-state-layer-opacity: var(--md-text-button-pressed-state-layer-opacity, 0.12);--_disabled-icon-color: var(--md-text-button-disabled-icon-color, var(--md-sys-color-on-surface, #1d1b20));--_disabled-icon-opacity: var(--md-text-button-disabled-icon-opacity, 0.38);--_focus-icon-color: var(--md-text-button-focus-icon-color, var(--md-sys-color-primary, #6750a4));--_hover-icon-color: var(--md-text-button-hover-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-color: var(--md-text-button-icon-color, var(--md-sys-color-primary, #6750a4));--_icon-size: var(--md-text-button-icon-size, 18px);--_pressed-icon-color: var(--md-text-button-pressed-icon-color, var(--md-sys-color-primary, #6750a4));--_container-shape-start-start: var(--md-text-button-container-shape-start-start, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-start-end: var(--md-text-button-container-shape-start-end, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-end: var(--md-text-button-container-shape-end-end, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_container-shape-end-start: var(--md-text-button-container-shape-end-start, var(--md-text-button-container-shape, var(--md-sys-shape-corner-full, 9999px)));--_leading-space: var(--md-text-button-leading-space, 12px);--_trailing-space: var(--md-text-button-trailing-space, 12px);--_with-leading-icon-leading-space: var(--md-text-button-with-leading-icon-leading-space, 12px);--_with-leading-icon-trailing-space: var(--md-text-button-with-leading-icon-trailing-space, 16px);--_with-trailing-icon-leading-space: var(--md-text-button-with-trailing-icon-leading-space, 16px);--_with-trailing-icon-trailing-space: var(--md-text-button-with-trailing-icon-trailing-space, 12px);--_container-color: none;--_disabled-container-color: none;--_disabled-container-opacity: 0} -`; - - // node_modules/@material/web/button/text-button.js - var MdTextButton = class MdTextButton2 extends TextButton { - }; - MdTextButton.styles = [styles6, styles8]; - MdTextButton = __decorate([ - t2("md-text-button") - ], MdTextButton); - - // node_modules/@material/web/divider/internal/divider.js - var Divider = class extends h3 { - constructor() { - super(...arguments); - this.inset = false; - this.insetStart = false; - this.insetEnd = false; - } - }; - __decorate([ - n4({ type: Boolean, reflect: true }) - ], Divider.prototype, "inset", void 0); - __decorate([ - n4({ type: Boolean, reflect: true, attribute: "inset-start" }) - ], Divider.prototype, "insetStart", void 0); - __decorate([ - n4({ type: Boolean, reflect: true, attribute: "inset-end" }) - ], Divider.prototype, "insetEnd", void 0); - - // node_modules/@material/web/divider/internal/divider-styles.js - var styles9 = i`:host{box-sizing:border-box;color:var(--md-divider-color, var(--md-sys-color-outline-variant, #cac4d0));display:flex;height:var(--md-divider-thickness, 1px);width:100%}:host([inset]),:host([inset-start]){padding-inline-start:16px}:host([inset]),:host([inset-end]){padding-inline-end:16px}:host::before{background:currentColor;content:"";height:100%;width:100%}@media(forced-colors: active){:host::before{background:CanvasText}} -`; - - // node_modules/@material/web/divider/divider.js - var MdDivider = class MdDivider2 extends Divider { - }; - MdDivider.styles = [styles9]; - MdDivider = __decorate([ - t2("md-divider") - ], MdDivider); - - // node_modules/@material/web/internal/events/redispatch-event.js - function redispatchEvent(element, event) { - if (event.bubbles && (!element.shadowRoot || event.composed)) { - event.stopPropagation(); - } - const copy = Reflect.construct(event.constructor, [event.type, event]); - const dispatched = element.dispatchEvent(copy); - if (!dispatched) { - event.preventDefault(); - } - return dispatched; - } - - // node_modules/@material/web/dialog/internal/animations.js - var DIALOG_DEFAULT_OPEN_ANIMATION = { - dialog: [ - [ - // Dialog slide down - [{ "transform": "translateY(-50px)" }, { "transform": "translateY(0)" }], - { duration: 500, easing: EASING.EMPHASIZED } - ] - ], - scrim: [ - [ - // Scrim fade in - [{ "opacity": 0 }, { "opacity": 0.32 }], - { duration: 500, easing: "linear" } - ] - ], - container: [ - [ - // Container fade in - [{ "opacity": 0 }, { "opacity": 1 }], - { duration: 50, easing: "linear", pseudoElement: "::before" } - ], - [ - // Container grow - // Note: current spec says to grow from 0dp->100% and shrink from - // 100%->35%. We change this to 35%->100% to simplify the animation that - // is supposed to clip content as it grows. From 0dp it's possible to see - // text/actions appear before the container has fully grown. - [{ "height": "35%" }, { "height": "100%" }], - { duration: 500, easing: EASING.EMPHASIZED, pseudoElement: "::before" } - ] - ], - headline: [ - [ - // Headline fade in - [{ "opacity": 0 }, { "opacity": 0, offset: 0.2 }, { "opacity": 1 }], - { duration: 250, easing: "linear", fill: "forwards" } - ] - ], - content: [ - [ - // Content fade in - [{ "opacity": 0 }, { "opacity": 0, offset: 0.2 }, { "opacity": 1 }], - { duration: 250, easing: "linear", fill: "forwards" } - ] - ], - actions: [ - [ - // Actions fade in - [{ "opacity": 0 }, { "opacity": 0, offset: 0.5 }, { "opacity": 1 }], - { duration: 300, easing: "linear", fill: "forwards" } - ] - ] - }; - var DIALOG_DEFAULT_CLOSE_ANIMATION = { - dialog: [ - [ - // Dialog slide up - [{ "transform": "translateY(0)" }, { "transform": "translateY(-50px)" }], - { duration: 150, easing: EASING.EMPHASIZED_ACCELERATE } - ] - ], - scrim: [ - [ - // Scrim fade out - [{ "opacity": 0.32 }, { "opacity": 0 }], - { duration: 150, easing: "linear" } - ] - ], - container: [ - [ - // Container shrink - [{ "height": "100%" }, { "height": "35%" }], - { - duration: 150, - easing: EASING.EMPHASIZED_ACCELERATE, - pseudoElement: "::before" - } - ], - [ - // Container fade out - [{ "opacity": "1" }, { "opacity": "0" }], - { delay: 100, duration: 50, easing: "linear", pseudoElement: "::before" } - ] - ], - headline: [ - [ - // Headline fade out - [{ "opacity": 1 }, { "opacity": 0 }], - { duration: 100, easing: "linear", fill: "forwards" } - ] - ], - content: [ - [ - // Content fade out - [{ "opacity": 1 }, { "opacity": 0 }], - { duration: 100, easing: "linear", fill: "forwards" } - ] - ], - actions: [ - [ - // Actions fade out - [{ "opacity": 1 }, { "opacity": 0 }], - { duration: 100, easing: "linear", fill: "forwards" } - ] - ] - }; - - // node_modules/@material/web/dialog/internal/dialog.js - var dialogBaseClass = mixinDelegatesAria(h3); - var Dialog = class extends dialogBaseClass { - // We do not use `delegatesFocus: true` due to a Chromium bug with - // selecting text. - // See https://bugs.chromium.org/p/chromium/issues/detail?id=950357 - /** - * Opens the dialog when set to `true` and closes it when set to `false`. - */ - get open() { - return this.isOpen; - } - set open(open) { - if (open === this.isOpen) { - return; - } - this.isOpen = open; - if (open) { - this.setAttribute("open", ""); - this.show(); - } else { - this.removeAttribute("open"); - this.close(); - } - } - constructor() { - super(); - this.quick = false; - this.returnValue = ""; - this.noFocusTrap = false; - this.getOpenAnimation = () => DIALOG_DEFAULT_OPEN_ANIMATION; - this.getCloseAnimation = () => DIALOG_DEFAULT_CLOSE_ANIMATION; - this.isOpen = false; - this.isOpening = false; - this.isConnectedPromise = this.getIsConnectedPromise(); - this.isAtScrollTop = false; - this.isAtScrollBottom = false; - this.nextClickIsFromContent = false; - this.hasHeadline = false; - this.hasActions = false; - this.hasIcon = false; - this.escapePressedWithoutCancel = false; - this.treewalker = co ? null : document.createTreeWalker(this, NodeFilter.SHOW_ELEMENT); - if (!co) { - this.addEventListener("submit", this.handleSubmit); - } - } - /** - * Opens the dialog and fires a cancelable `open` event. After a dialog's - * animation, an `opened` event is fired. - * - * Add an `autofocus` attribute to a child of the dialog that should - * receive focus after opening. - * - * @return A Promise that resolves after the animation is finished and the - * `opened` event was fired. - */ - async show() { - this.isOpening = true; - await this.isConnectedPromise; - await this.updateComplete; - const dialog = this.dialog; - if (dialog.open || !this.isOpening) { - this.isOpening = false; - return; - } - const preventOpen = !this.dispatchEvent(new Event("open", { cancelable: true })); - if (preventOpen) { - this.open = false; - this.isOpening = false; - return; - } - dialog.showModal(); - this.open = true; - if (this.scroller) { - this.scroller.scrollTop = 0; - } - this.querySelector("[autofocus]")?.focus(); - await this.animateDialog(this.getOpenAnimation()); - this.dispatchEvent(new Event("opened")); - this.isOpening = false; - } - /** - * Closes the dialog and fires a cancelable `close` event. After a dialog's - * animation, a `closed` event is fired. - * - * @param returnValue A return value usually indicating which button was used - * to close a dialog. If a dialog is canceled by clicking the scrim or - * pressing Escape, it will not change the return value after closing. - * @return A Promise that resolves after the animation is finished and the - * `closed` event was fired. - */ - async close(returnValue = this.returnValue) { - this.isOpening = false; - if (!this.isConnected) { - this.open = false; - return; - } - await this.updateComplete; - const dialog = this.dialog; - if (!dialog.open || this.isOpening) { - this.open = false; - return; - } - const prevReturnValue = this.returnValue; - this.returnValue = returnValue; - const preventClose = !this.dispatchEvent(new Event("close", { cancelable: true })); - if (preventClose) { - this.returnValue = prevReturnValue; - return; - } - await this.animateDialog(this.getCloseAnimation()); - dialog.close(returnValue); - this.open = false; - this.dispatchEvent(new Event("closed")); - } - connectedCallback() { - super.connectedCallback(); - this.isConnectedPromiseResolve(); - } - disconnectedCallback() { - super.disconnectedCallback(); - this.isConnectedPromise = this.getIsConnectedPromise(); - } - render() { - const scrollable = this.open && !(this.isAtScrollTop && this.isAtScrollBottom); - const classes = { - "has-headline": this.hasHeadline, - "has-actions": this.hasActions, - "has-icon": this.hasIcon, - "scrollable": scrollable, - "show-top-divider": scrollable && !this.isAtScrollTop, - "show-bottom-divider": scrollable && !this.isAtScrollBottom - }; - const showFocusTrap = this.open && !this.noFocusTrap; - const focusTrap = ke` - - `; - const { ariaLabel } = this; - return ke` -
- - ${showFocusTrap ? focusTrap : D} -
-
- -

- -

- -
-
-
-
- -
-
-
-
- - -
-
- ${showFocusTrap ? focusTrap : D} -
- `; - } - firstUpdated() { - this.intersectionObserver = new IntersectionObserver((entries) => { - for (const entry of entries) { - this.handleAnchorIntersection(entry); - } - }, { root: this.scroller }); - this.intersectionObserver.observe(this.topAnchor); - this.intersectionObserver.observe(this.bottomAnchor); - } - handleDialogClick() { - if (this.nextClickIsFromContent) { - this.nextClickIsFromContent = false; - return; - } - const preventDefault = !this.dispatchEvent(new Event("cancel", { cancelable: true })); - if (preventDefault) { - return; - } - this.close(); - } - handleContentClick() { - this.nextClickIsFromContent = true; - } - handleSubmit(event) { - const form = event.target; - const { submitter } = event; - if (form.method !== "dialog" || !submitter) { - return; - } - this.close(submitter.getAttribute("value") ?? this.returnValue); - } - handleCancel(event) { - if (event.target !== this.dialog) { - return; - } - this.escapePressedWithoutCancel = false; - const preventDefault = !redispatchEvent(this, event); - event.preventDefault(); - if (preventDefault) { - return; - } - this.close(); - } - handleClose() { - if (!this.escapePressedWithoutCancel) { - return; - } - this.escapePressedWithoutCancel = false; - this.dialog?.dispatchEvent(new Event("cancel", { cancelable: true })); - } - handleKeydown(event) { - if (event.key !== "Escape") { - return; - } - this.escapePressedWithoutCancel = true; - setTimeout(() => { - this.escapePressedWithoutCancel = false; - }); - } - async animateDialog(animation) { - this.cancelAnimations?.abort(); - this.cancelAnimations = new AbortController(); - if (this.quick) { - return; - } - const { dialog, scrim, container, headline, content, actions } = this; - if (!dialog || !scrim || !container || !headline || !content || !actions) { - return; - } - const { container: containerAnimate, dialog: dialogAnimate, scrim: scrimAnimate, headline: headlineAnimate, content: contentAnimate, actions: actionsAnimate } = animation; - const elementAndAnimation = [ - [dialog, dialogAnimate ?? []], - [scrim, scrimAnimate ?? []], - [container, containerAnimate ?? []], - [headline, headlineAnimate ?? []], - [content, contentAnimate ?? []], - [actions, actionsAnimate ?? []] - ]; - const animations = []; - for (const [element, animation2] of elementAndAnimation) { - for (const animateArgs of animation2) { - const animation3 = element.animate(...animateArgs); - this.cancelAnimations.signal.addEventListener("abort", () => { - animation3.cancel(); - }); - animations.push(animation3); - } - } - await Promise.all(animations.map((animation2) => animation2.finished.catch(() => { - }))); - } - handleHeadlineChange(event) { - const slot = event.target; - this.hasHeadline = slot.assignedElements().length > 0; - } - handleActionsChange(event) { - const slot = event.target; - this.hasActions = slot.assignedElements().length > 0; - } - handleIconChange(event) { - const slot = event.target; - this.hasIcon = slot.assignedElements().length > 0; - } - handleAnchorIntersection(entry) { - const { target, isIntersecting } = entry; - if (target === this.topAnchor) { - this.isAtScrollTop = isIntersecting; - } - if (target === this.bottomAnchor) { - this.isAtScrollBottom = isIntersecting; - } - } - getIsConnectedPromise() { - return new Promise((resolve) => { - this.isConnectedPromiseResolve = resolve; - }); - } - handleFocusTrapFocus(event) { - const [firstFocusableChild, lastFocusableChild] = this.getFirstAndLastFocusableChildren(); - if (!firstFocusableChild || !lastFocusableChild) { - this.dialog?.focus(); - return; - } - const isFirstFocusTrap = event.target === this.firstFocusTrap; - const isLastFocusTrap = !isFirstFocusTrap; - const focusCameFromFirstChild = event.relatedTarget === firstFocusableChild; - const focusCameFromLastChild = event.relatedTarget === lastFocusableChild; - const focusCameFromOutsideDialog = !focusCameFromFirstChild && !focusCameFromLastChild; - const shouldFocusFirstChild = isLastFocusTrap && focusCameFromLastChild || isFirstFocusTrap && focusCameFromOutsideDialog; - if (shouldFocusFirstChild) { - firstFocusableChild.focus(); - return; - } - const shouldFocusLastChild = isFirstFocusTrap && focusCameFromFirstChild || isLastFocusTrap && focusCameFromOutsideDialog; - if (shouldFocusLastChild) { - lastFocusableChild.focus(); - return; - } - } - getFirstAndLastFocusableChildren() { - if (!this.treewalker) { - return [null, null]; - } - let firstFocusableChild = null; - let lastFocusableChild = null; - this.treewalker.currentNode = this.treewalker.root; - while (this.treewalker.nextNode()) { - const nextChild = this.treewalker.currentNode; - if (!isFocusable(nextChild)) { - continue; - } - if (!firstFocusableChild) { - firstFocusableChild = nextChild; - } - lastFocusableChild = nextChild; - } - return [firstFocusableChild, lastFocusableChild]; - } - }; - __decorate([ - n4({ type: Boolean }) - ], Dialog.prototype, "open", null); - __decorate([ - n4({ type: Boolean }) - ], Dialog.prototype, "quick", void 0); - __decorate([ - n4({ attribute: false }) - ], Dialog.prototype, "returnValue", void 0); - __decorate([ - n4() - ], Dialog.prototype, "type", void 0); - __decorate([ - n4({ type: Boolean, attribute: "no-focus-trap" }) - ], Dialog.prototype, "noFocusTrap", void 0); - __decorate([ - e4("dialog") - ], Dialog.prototype, "dialog", void 0); - __decorate([ - e4(".scrim") - ], Dialog.prototype, "scrim", void 0); - __decorate([ - e4(".container") - ], Dialog.prototype, "container", void 0); - __decorate([ - e4(".headline") - ], Dialog.prototype, "headline", void 0); - __decorate([ - e4(".content") - ], Dialog.prototype, "content", void 0); - __decorate([ - e4(".actions") - ], Dialog.prototype, "actions", void 0); - __decorate([ - r4() - ], Dialog.prototype, "isAtScrollTop", void 0); - __decorate([ - r4() - ], Dialog.prototype, "isAtScrollBottom", void 0); - __decorate([ - e4(".scroller") - ], Dialog.prototype, "scroller", void 0); - __decorate([ - e4(".top.anchor") - ], Dialog.prototype, "topAnchor", void 0); - __decorate([ - e4(".bottom.anchor") - ], Dialog.prototype, "bottomAnchor", void 0); - __decorate([ - e4(".focus-trap") - ], Dialog.prototype, "firstFocusTrap", void 0); - __decorate([ - r4() - ], Dialog.prototype, "hasHeadline", void 0); - __decorate([ - r4() - ], Dialog.prototype, "hasActions", void 0); - __decorate([ - r4() - ], Dialog.prototype, "hasIcon", void 0); - function isFocusable(element) { - const knownFocusableElements = ":is(button,input,select,textarea,object,:is(a,area)[href],[tabindex],[contenteditable=true])"; - const notDisabled = ":not(:disabled,[disabled])"; - const notNegativeTabIndex = ':not([tabindex^="-"])'; - if (element.matches(knownFocusableElements + notDisabled + notNegativeTabIndex)) { - return true; - } - const isCustomElement = element.localName.includes("-"); - if (!isCustomElement) { - return false; - } - if (!element.matches(notDisabled)) { - return false; - } - return element.shadowRoot?.delegatesFocus ?? false; - } - - // node_modules/@material/web/dialog/internal/dialog-styles.js - var styles10 = i`:host{border-start-start-radius:var(--md-dialog-container-shape-start-start, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));border-start-end-radius:var(--md-dialog-container-shape-start-end, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));border-end-end-radius:var(--md-dialog-container-shape-end-end, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));border-end-start-radius:var(--md-dialog-container-shape-end-start, var(--md-dialog-container-shape, var(--md-sys-shape-corner-extra-large, 28px)));display:contents;margin:auto;max-height:min(560px,100% - 48px);max-width:min(560px,100% - 48px);min-height:140px;min-width:280px;position:fixed;height:fit-content;width:fit-content}dialog{background:rgba(0,0,0,0);border:none;border-radius:inherit;flex-direction:column;height:inherit;margin:inherit;max-height:inherit;max-width:inherit;min-height:inherit;min-width:inherit;outline:none;overflow:visible;padding:0;width:inherit}dialog[open]{display:flex}::backdrop{background:none}.scrim{background:var(--md-sys-color-scrim, #000);display:none;inset:0;opacity:32%;pointer-events:none;position:fixed;z-index:1}:host([open]) .scrim{display:flex}h2{all:unset;align-self:stretch}.headline{align-items:center;color:var(--md-dialog-headline-color, var(--md-sys-color-on-surface, #1d1b20));display:flex;flex-direction:column;font-family:var(--md-dialog-headline-font, var(--md-sys-typescale-headline-small-font, var(--md-ref-typeface-brand, Roboto)));font-size:var(--md-dialog-headline-size, var(--md-sys-typescale-headline-small-size, 1.5rem));line-height:var(--md-dialog-headline-line-height, var(--md-sys-typescale-headline-small-line-height, 2rem));font-weight:var(--md-dialog-headline-weight, var(--md-sys-typescale-headline-small-weight, var(--md-ref-typeface-weight-regular, 400)));position:relative}slot[name=headline]::slotted(*){align-items:center;align-self:stretch;box-sizing:border-box;display:flex;gap:8px;padding:24px 24px 0}.icon{display:flex}slot[name=icon]::slotted(*){color:var(--md-dialog-icon-color, var(--md-sys-color-secondary, #625b71));fill:currentColor;font-size:var(--md-dialog-icon-size, 24px);margin-top:24px;height:var(--md-dialog-icon-size, 24px);width:var(--md-dialog-icon-size, 24px)}.has-icon slot[name=headline]::slotted(*){justify-content:center;padding-top:16px}.scrollable slot[name=headline]::slotted(*){padding-bottom:16px}.scrollable.has-headline slot[name=content]::slotted(*){padding-top:8px}.container{border-radius:inherit;display:flex;flex-direction:column;flex-grow:1;overflow:hidden;position:relative;transform-origin:top}.container::before{background:var(--md-dialog-container-color, var(--md-sys-color-surface-container-high, #ece6f0));border-radius:inherit;content:"";inset:0;position:absolute}.scroller{display:flex;flex:1;flex-direction:column;overflow:hidden;z-index:1}.scrollable .scroller{overflow-y:scroll}.content{color:var(--md-dialog-supporting-text-color, var(--md-sys-color-on-surface-variant, #49454f));font-family:var(--md-dialog-supporting-text-font, var(--md-sys-typescale-body-medium-font, var(--md-ref-typeface-plain, Roboto)));font-size:var(--md-dialog-supporting-text-size, var(--md-sys-typescale-body-medium-size, 0.875rem));line-height:var(--md-dialog-supporting-text-line-height, var(--md-sys-typescale-body-medium-line-height, 1.25rem));flex:1;font-weight:var(--md-dialog-supporting-text-weight, var(--md-sys-typescale-body-medium-weight, var(--md-ref-typeface-weight-regular, 400)));height:min-content;position:relative}slot[name=content]::slotted(*){box-sizing:border-box;padding:24px}.anchor{position:absolute}.top.anchor{top:0}.bottom.anchor{bottom:0}.actions{position:relative}slot[name=actions]::slotted(*){box-sizing:border-box;display:flex;gap:8px;justify-content:flex-end;padding:16px 24px 24px}.has-actions slot[name=content]::slotted(*){padding-bottom:8px}md-divider{display:none;position:absolute}.has-headline.show-top-divider .headline md-divider,.has-actions.show-bottom-divider .actions md-divider{display:flex}.headline md-divider{bottom:0}.actions md-divider{top:0}@media(forced-colors: active){dialog{outline:2px solid WindowText}} -`; - - // node_modules/@material/web/dialog/dialog.js - var MdDialog = class MdDialog2 extends Dialog { - }; - MdDialog.styles = [styles10]; - MdDialog = __decorate([ - t2("md-dialog") - ], MdDialog); - - // node_modules/@material/web/icon/internal/icon.js - var Icon = class extends h3 { - render() { - return ke``; - } - connectedCallback() { - super.connectedCallback(); - const ariaHidden = this.getAttribute("aria-hidden"); - if (ariaHidden === "false") { - this.removeAttribute("aria-hidden"); - return; - } - this.setAttribute("aria-hidden", "true"); - } - }; - - // node_modules/@material/web/icon/internal/icon-styles.js - var styles11 = i`:host{font-size:var(--md-icon-size, 24px);width:var(--md-icon-size, 24px);height:var(--md-icon-size, 24px);color:inherit;font-variation-settings:inherit;font-weight:400;font-family:var(--md-icon-font, Material Symbols Outlined);display:inline-flex;font-style:normal;place-items:center;place-content:center;line-height:1;overflow:hidden;letter-spacing:normal;text-transform:none;user-select:none;white-space:nowrap;word-wrap:normal;flex-shrink:0;-webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;-moz-osx-font-smoothing:grayscale}::slotted(svg){fill:currentColor}::slotted(*){height:100%;width:100%} -`; - - // node_modules/@material/web/icon/icon.js - var MdIcon = class MdIcon2 extends Icon { - }; - MdIcon.styles = [styles11]; - MdIcon = __decorate([ - t2("md-icon") - ], MdIcon); - - // node_modules/lit-html/static.js - var $e = Symbol.for(""); - var xe = (t4) => { - if (t4?.r === $e) - return t4?._$litStatic$; - }; - var er = (t4, ...r5) => ({ _$litStatic$: r5.reduce((r6, e6, a2) => r6 + ((t5) => { - if (void 0 !== t5._$litStatic$) - return t5._$litStatic$; - throw Error(`Value passed to 'literal' function must be a 'literal' result: ${t5}. Use 'unsafeStatic' to pass non-literal values, but - take care to ensure page security.`); - })(e6) + t4[a2 + 1], t4[0]), r: $e }); - var Te = /* @__PURE__ */ new Map(); - var Ee = (t4) => (r5, ...e6) => { - const a2 = e6.length; - let o5, s2; - const i4 = [], l2 = []; - let n5, u2 = 0, c4 = false; - for (; u2 < a2; ) { - for (n5 = r5[u2]; u2 < a2 && void 0 !== (s2 = e6[u2], o5 = xe(s2)); ) - n5 += o5 + r5[++u2], c4 = true; - u2 !== a2 && l2.push(s2), i4.push(n5), u2++; - } - if (u2 === a2 && i4.push(r5[a2]), c4) { - const t5 = i4.join("$$lit$$"); - void 0 === (r5 = Te.get(t5)) && (i4.raw = i4, Te.set(t5, r5 = i4)), e6 = l2; - } - return t4(r5, ...e6); - }; - var ke2 = Ee(ke); - var Oe2 = Ee(Oe); - var Se2 = Ee(Se); - - // node_modules/@material/web/internal/controller/is-rtl.js - function isRtl(el, shouldCheck = true) { - return shouldCheck && getComputedStyle(el).getPropertyValue("direction").trim() === "rtl"; - } - - // node_modules/@material/web/iconbutton/internal/icon-button.js - var iconButtonBaseClass = mixinDelegatesAria(mixinElementInternals(h3)); - var IconButton = class extends iconButtonBaseClass { - get name() { - return this.getAttribute("name") ?? ""; - } - set name(name) { - this.setAttribute("name", name); - } - /** - * The associated form element with which this element's value will submit. - */ - get form() { - return this[internals].form; - } - /** - * The labels this element is associated with. - */ - get labels() { - return this[internals].labels; - } - constructor() { - super(); - this.disabled = false; - this.softDisabled = false; - this.flipIconInRtl = false; - this.href = ""; - this.target = ""; - this.ariaLabelSelected = ""; - this.toggle = false; - this.selected = false; - this.type = "submit"; - this.value = ""; - this.flipIcon = isRtl(this, this.flipIconInRtl); - if (!co) { - this.addEventListener("click", this.handleClick.bind(this)); - } - } - willUpdate() { - if (this.href) { - this.disabled = false; - this.softDisabled = false; - } - } - render() { - const tag = this.href ? er`div` : er`button`; - const { ariaLabel, ariaHasPopup, ariaExpanded } = this; - const hasToggledAriaLabel = ariaLabel && this.ariaLabelSelected; - const ariaPressedValue = !this.toggle ? D : this.selected; - let ariaLabelValue = D; - if (!this.href) { - ariaLabelValue = hasToggledAriaLabel && this.selected ? this.ariaLabelSelected : ariaLabel; - } - return ke2`<${tag} - class="icon-button ${Rt(this.getRenderClasses())}" - id="button" - aria-label="${ariaLabelValue || D}" - aria-haspopup="${!this.href && ariaHasPopup || D}" - aria-expanded="${!this.href && ariaExpanded || D}" - aria-pressed="${ariaPressedValue}" - aria-disabled=${!this.href && this.softDisabled || D} - ?disabled="${!this.href && this.disabled}" - @click="${this.handleClickOnChild}"> - ${this.renderFocusRing()} - ${this.renderRipple()} - ${!this.selected ? this.renderIcon() : D} - ${this.selected ? this.renderSelectedIcon() : D} - ${this.renderTouchTarget()} - ${this.href && this.renderLink()} - `; - } - renderLink() { - const { ariaLabel } = this; - return ke` - - `; - } - getRenderClasses() { - return { - "flip-icon": this.flipIcon, - "selected": this.toggle && this.selected - }; - } - renderIcon() { - return ke``; - } - renderSelectedIcon() { - return ke``; - } - renderTouchTarget() { - return ke``; - } - renderFocusRing() { - return ke``; - } - renderRipple() { - const isRippleDisabled = !this.href && (this.disabled || this.softDisabled); - return ke``; - } - connectedCallback() { - this.flipIcon = isRtl(this, this.flipIconInRtl); - super.connectedCallback(); - } - /** Handles a click on this element. */ - handleClick(event) { - if (!this.href && this.softDisabled) { - event.stopImmediatePropagation(); - event.preventDefault(); - return; - } - } - /** - * Handles a click on the child
or
`; - }); - return import_nanohtml6.default` -
- ${list} -
- `; - } - function blockSvg() { - return import_nanohtml6.default` - - - - - `; - } - - // v2/components/key-insights.jsx - function KeyInsights() { - const data = useData(); - return /* @__PURE__ */ y("div", { id: "key-insight" }, /* @__PURE__ */ y(DomNode, { key: data.count }, renderKeyInsight(data))); - } - function KeyInsightsMain({ title, children, icon = "chat" }) { - return /* @__PURE__ */ y("div", { className: "key-insight key-insight--main" }, /* @__PURE__ */ y("div", { className: `key-insight__icon hero-icon--${icon}` }), /* @__PURE__ */ y("h1", { className: "token-title-3-em" }, title), /* @__PURE__ */ y("div", { className: "token-title-3" }, /* @__PURE__ */ y("span", null, children))); - } - - // shared/js/ui/templates/protection-header.js - var import_nanohtml7 = __toESM(require_browser()); - - // shared/js/ui/components/text-link.jsx - function TextLink(props) { - const { onClick, rounded = false } = props; - const ref = _(null); - useRipple({ ref }); - let classNames = [`link-action`, `link-action--text`]; - if (rounded) - classNames.push(`link-action--rounded`); - return /* @__PURE__ */ y("a", { href: "javascript:void(0)", className: classNames.join(" "), draggable: false, ref, onClick }, props.children); - } - function PlainTextLink({ children, className, ...rest }) { - const classes = ["text-link-as-button"]; - if (className) - classes.push(className); - return /* @__PURE__ */ y("a", { href: "javascript:void(0)", className: classes.join(" "), draggable: false, ...rest }, children); - } - - // shared/js/ui/components/toggle.jsx - function ProtectionToggle(props) { - const [toggleState, toggle] = useToggleState(props.model, props.toggle); - const altText = ns.site("updatingProtectionList.title"); - return /* @__PURE__ */ y("div", { class: `site-info-toggle ${toggleState.active ? "is-active" : ""}` }, /* @__PURE__ */ y("p", { class: "site-info__protection" }, /* @__PURE__ */ y("span", { role: "textbox", dangerouslySetInnerHTML: { __html: toggleState.text } })), /* @__PURE__ */ y("div", { class: "site-info__toggle-container" }, toggleState.toggled && /* @__PURE__ */ y("img", { src: "../img/spinner.svg", className: "toggle-spinner", alt: altText }), !toggleState.toggled && /* @__PURE__ */ y(ToggleButton, { toggleState, onToggle: toggle }))); - } - function useToggleState(model, toggle) { - const [state, setState] = h2(() => { - const toggleState = { - text: ns.site("protectionsEnabled.title"), - active: true, - disabled: false, - label: "", - toggled: false, - sideEffects: false - }; - if (!model.protectionsEnabled) { - toggleState.text = ns.site("protectionsDisabled.title"); - toggleState.active = false; - } - if (model.isBroken) { - if (!isBrowser()) { - toggleState.active = false; - toggleState.disabled = true; - } - } - const labelEnabled = ns.site("enableProtectionsSwitch.title"); - const labelDisabled = ns.site("disableProtectionsSwitch.title"); - toggleState.label = toggleState.active ? labelDisabled : labelEnabled; - return toggleState; - }); - p2(() => { - if (!state.sideEffects) - return; - const isReducedMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches === true; - const timeout = isReducedMotion ? 0 : 300; - const int = setTimeout(() => { - toggle(); - if (model.features.spinnerFollowingProtectionsToggle) { - setState((prev) => { - return { ...prev, toggled: true }; - }); - } - }, timeout); - return () => { - clearTimeout(int); - }; - }, [state.active, state.sideEffects]); - function toggleInternal() { - setState((prev) => { - return { ...prev, active: !prev.active, sideEffects: true }; - }); - } - return [state, toggleInternal]; - } - function ToggleButton(props) { - const { toggleState } = props; - const labelEnabled = ns.site("enableProtectionsSwitch.title"); - const labelDisabled = ns.site("disableProtectionsSwitch.title"); - const label = toggleState.active ? labelDisabled : labelEnabled; - return /* @__PURE__ */ y(DefaultToggleButton, { toggleState, label, onToggle: props.onToggle }); - } - function DefaultToggleButton(props) { - const { toggleState, label } = props; - return /* @__PURE__ */ y( - "button", - { - class: "toggle-button", - type: "button", - role: "switch", - "aria-checked": toggleState.active, - "aria-label": label, - disabled: toggleState.disabled, - onClick: props.onToggle - }, - /* @__PURE__ */ y("div", { class: "toggle-button__track" }), - /* @__PURE__ */ y("div", { class: "toggle-button__handle" }) - ); - } - - // shared/js/ui/templates/protection-header.js - var ProtectionContext = G( - /** @type {{state: UIState, setState: (st: UIState) => void; model: MigrationModel}} */ - {} - ); - function ProtectionHeader({ model, initialState, toggle, children, ...rest }) { - let initial; - if (initialState) { - initial = initialState; - } else { - if (model.isBroken || model.isAllowlisted) { - initial = "form-trigger"; - } else { - initial = "help-trigger"; - } - } - const [state, setState] = h2( - /** @type {UIState} */ - initial - ); - return /* @__PURE__ */ y("div", { ...rest }, /* @__PURE__ */ y("div", { class: "card-list--bordered" }, model.isBroken && /* @__PURE__ */ y(HeaderDisabled, { model, state, toggle }), !model.isBroken && /* @__PURE__ */ y(HeaderDefault, { model, state, toggle })), /* @__PURE__ */ y( - ProtectionContext.Provider, - { - value: { - state, - setState, - model - } - }, - children - )); - } - function HeaderDefault(props) { - const text = ns.site("websiteNotWorkingAdvice.title"); - const showHelp = props.state === "site-not-working" && !props.model.isAllowlisted; - return /* @__PURE__ */ y("div", { className: "protection-toggle" }, /* @__PURE__ */ y("div", { className: "protection-toggle__row" }, /* @__PURE__ */ y(ProtectionToggle, { model: props.model, toggle: props.toggle })), showHelp && /* @__PURE__ */ y("div", { className: "protection-toggle__row protection-toggle__row--alt" }, text)); - } - function HeaderDisabled(props) { - let text = i18n.t("site:protectionsDisabledRemote.title"); - if (props.model.isDenylisted) { - text = i18n.t("site:protectionsDisabledRemoteOverride.title"); - } - return /* @__PURE__ */ y(k, null, /* @__PURE__ */ y("div", { className: "padding-x padding-y--reduced" }, /* @__PURE__ */ y(ProtectionToggle, { model: props.model, toggle: props.toggle })), /* @__PURE__ */ y("div", { className: "note note--nested" }, text)); - } - - // v2/components/protection-header.jsx - function ProtectionHeader2() { - const { push } = useNav(); - const data = useData(); - const onToggle = useToggle(); - const fetcher = useFetcher(); - const { breakageScreen } = useFeatures(); - const featureSettings2 = useFeatureSettings(); - return /* @__PURE__ */ y("div", { "data-testid": "protectionHeader" }, /* @__PURE__ */ y(ProtectionHeader, { model: data, toggle: onToggle }, /* @__PURE__ */ y("div", { className: "text--center" }, /* @__PURE__ */ y( - TextLink, - { - onClick: () => { - fetcher(new CheckBrokenSiteReportHandledMessage()).then(() => { - if (featureSettings2.webBreakageForm.state === "enabled") { - push(breakageScreen); - } - }).catch(console.error); - }, - rounded: true - }, - ns.site("websiteNotWorkingPrompt.title") - )))); - } - - // shared/js/ui/views/fire-dialog.js - var import_nanohtml8 = __toESM(require_browser()); - var import_raw3 = __toESM(require_raw_browser()); - function fireSummaryTemplate(selectedOption) { - const { descriptionStats } = selectedOption; - let template2 = "firebutton:summary"; - if (descriptionStats.clearHistory && descriptionStats.openTabs) { - template2 += "ClearTabsHistory"; - } else if (descriptionStats.clearHistory && !descriptionStats.openTabs) { - template2 += "ClearHistory"; - } else if (!descriptionStats.clearHistory && descriptionStats.openTabs) { - template2 += "ClearTabs"; - } else { - template2 += "ClearCookies"; - } - if (descriptionStats.site) { - template2 += "Site"; - } else if (descriptionStats.duration === "all") { - template2 += "All"; - } else { - template2 += "Duration"; - } - template2 += ".title"; - return import_nanohtml8.default`
-

- ${(0, import_raw3.default)( - i18n.t(template2, { - durationDesc: i18n.t("firebutton:historyDuration.title", { duration: descriptionStats.duration }), - ...descriptionStats - }) - )} -

- ${descriptionStats.site && descriptionStats.clearHistory ? import_nanohtml8.default`

${i18n.t("firebutton:historyAndDownloadsNotAffected.title")}

` : null} - ${descriptionStats.openTabs && descriptionStats.pinnedTabs ? import_nanohtml8.default`

- ${(0, import_raw3.default)(i18n.t("firebutton:summaryPinnedIgnored.title", { tabs: descriptionStats.pinnedTabs }))} -

` : null} -
`; - } - - // v2/components/fire-dialog.jsx - function FireProvider({ onCancel }) { - const [fireOptions, setFireOptions] = h2( - /** @type {null | FireOption[]} */ - null - ); - const fetcher = useFetcher(); - p2(() => { - const msg = new FetchBurnOptions(); - fetcher(msg).then((resp) => { - setFireOptions(resp.options); - }).catch(console.error); - }, [fetcher]); - function onUpdate(index) { - if (!fireOptions) - return; - const selectedOption = index; - const opts = fireOptions[selectedOption]; - fetcher(new SetBurnDefaultOption(opts.name)).catch(console.error); - } - function onBurn(index) { - if (!fireOptions) - return; - const selectedOption = index; - const opts = fireOptions[selectedOption].options; - fetcher(new BurnMessage( - /** @type {any} */ - opts - )).then(() => { - onCancel(); - }); - } - if (fireOptions === null) - return null; - return /* @__PURE__ */ y(FireDialog, { fireOptions, onUpdate, onCancel, onBurn }); - } - function FireDialog({ fireOptions, onUpdate, onCancel, onBurn }) { - if (!fireOptions) { - return /* @__PURE__ */ y("dialog", { id: "fire-button-container" }); - } - let selectedOptionIndex = fireOptions.findIndex(({ selected }) => selected); - if (selectedOptionIndex < 0) { - selectedOptionIndex = 0; - } - const [value, setValue] = h2(selectedOptionIndex); - const selectedOption = fireOptions[value]; - const selectOptions = fireOptions.map(({ name }, index) => /* @__PURE__ */ y("option", { value: index }, i18n.t(`firebutton:option${name}.title`))); - const summary = fireSummaryTemplate(selectedOption); - function onChange(e3) { - setValue(Number(e3.target.value)); - onUpdate(Number(e3.target.value)); - } - return /* @__PURE__ */ y("dialog", { id: "fire-button-container", open: true }, /* @__PURE__ */ y("div", { id: "fire-button-content" }, /* @__PURE__ */ y("span", { id: "fire-button-header" }, /* @__PURE__ */ y("img", { src: "../img/fire-button-header.svg" }), /* @__PURE__ */ y("h3", null, selectedOption.descriptionStats.openTabs > 0 ? i18n.t("firebutton:fireDialogHeader.title") : i18n.t("firebutton:fireDialogHeaderNoTabs.title"))), /* @__PURE__ */ y("select", { id: "fire-button-opts", onChange, value }, selectOptions), /* @__PURE__ */ y(DomNode, null, summary), /* @__PURE__ */ y("div", { id: "fire-button-row" }, /* @__PURE__ */ y("button", { id: "fire-button-cancel", onClick: onCancel }, i18n.t("firebutton:cancel.title")), /* @__PURE__ */ y("button", { id: "fire-button-burn", onClick: () => onBurn(value) }, i18n.t("firebutton:clearData.title"))))); - } - - // v2/components/search-bar.jsx - function SearchBar() { - const data = useData(); - const fetcher = useFetcher(); - const showFireButton = data.fireButton?.enabled === true; - const [focussed, setFocussed] = h2(false); - const [fireDialogOpen, setFireDialogOpen] = h2(false); - function openSettings() { - const msg = new OpenOptionsMessage(); - fetcher(msg).catch(console.error); - } - function openFire() { - setFireDialogOpen(true); - } - function doSearch(e3) { - e3.preventDefault(); - const values = Object.fromEntries(new FormData(e3.target)); - if (!values.q || !(typeof values.q === "string")) { - return console.warn("missing value"); - } - const msg = new SearchMessage({ term: values.q }); - fetcher(msg).catch(console.error); - } - const fireButton = showFireButton ? /* @__PURE__ */ y("button", { type: "button", class: "fire-button", onClick: openFire }, /* @__PURE__ */ y(FireIcon, null)) : null; - if (!data.tab.search) - return null; - return /* @__PURE__ */ y("div", { className: "search token-search-input" }, /* @__PURE__ */ y("form", { className: "search-form", name: "x", "data-test-id": "search-form", "data-focussed": focussed, onSubmit: doSearch }, /* @__PURE__ */ y( - "input", - { - type: "text", - autoComplete: "off", - autoFocus: true, - placeholder: ns.site("searchPlaceholder.title"), - name: "q", - className: "search-form__input", - defaultValue: "", - onInput: (e3) => setFocussed(e3.target.value.length > 0), - onBlur: () => setFocussed(false), - onFocus: (e3) => setFocussed(e3.target.value.length > 0) - } - ), /* @__PURE__ */ y("button", { className: "search-form__go", type: "submit", "aria-label": ns.site("searchGoButton.title") }, /* @__PURE__ */ y(LoupeIcon, null))), fireButton, fireDialogOpen ? /* @__PURE__ */ y(FireProvider, { onCancel: () => setFireDialogOpen(false) }) : null, /* @__PURE__ */ y("button", { type: "button", className: "cog-button", "aria-label": ns.site("optionsButton.title"), onClick: openSettings }, /* @__PURE__ */ y(CogIcon, null))); - } - function LoupeIcon() { - return /* @__PURE__ */ y("svg", { width: "18", height: "18", viewBox: "0 0 18 18", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ y("rect", { class: "loupe-handle", x: "11.5", y: "12.9142", width: "2", height: "6", rx: "1", transform: "rotate(-45 11.5 12.9142)" }), /* @__PURE__ */ y( - "path", - { - class: "loupe-glass", - d: "M12.6976 5.27292C14.7478 7.32317 14.7478 10.6473 12.6976 12.6975C10.6473 14.7478 7.32322 14.7478 5.27297 12.6975C3.22272 10.6473 3.22272 7.32317 5.27297 5.27292C7.32322 3.22267 10.6473 3.22267 12.6976 5.27292Z", - "stroke-width": "1.5" - } - )); - } - function CogIcon() { - return /* @__PURE__ */ y("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ y( - "path", - { - class: "settings-cog", - "fill-rule": "evenodd", - "clip-rule": "evenodd", - d: "M3.43351 13.1462C3.06364 14.0391 3.48767 15.0628 4.3806 15.4327L5.30448 15.8154C6.19741 16.1853 7.2211 15.7612 7.59096 14.8683L7.84778 14.2483C7.89842 14.2495 7.94918 14.2501 8.00007 14.2501C8.05068 14.2501 8.10118 14.2495 8.15154 14.2483L8.40831 14.8682C8.77818 15.7611 9.80187 16.1852 10.6948 15.8153L11.6187 15.4326C12.5116 15.0628 12.9356 14.0391 12.5658 13.1461L12.3093 12.527C12.3828 12.457 12.4546 12.3853 12.5247 12.3118L13.1437 12.5682C14.0366 12.9381 15.0603 12.514 15.4302 11.6211L15.8129 10.6972C16.1827 9.8043 15.7587 8.7806 14.8658 8.41074L14.2482 8.15493C14.2494 8.10345 14.2501 8.05185 14.2501 8.00011C14.2501 7.94964 14.2495 7.89928 14.2483 7.84905L14.8659 7.59324C15.7588 7.22337 16.1828 6.19968 15.8129 5.30675L15.4303 4.38287C15.0604 3.48994 14.0367 3.06592 13.1438 3.43578L12.5273 3.69115C12.4568 3.61712 12.3845 3.54482 12.3105 3.47432L12.5658 2.85787C12.9357 1.96494 12.5117 0.94124 11.6188 0.571378L10.6949 0.188694C9.80195 -0.181168 8.77825 0.242858 8.40839 1.13579L8.15316 1.75196C8.10226 1.75073 8.05122 1.75011 8.00007 1.75011C7.94864 1.75011 7.89734 1.75074 7.84616 1.75198L7.59089 1.13569C7.22102 0.242766 6.19733 -0.181263 5.3044 0.1886L4.38052 0.571284C3.4876 0.941146 3.06357 1.96484 3.43343 2.85777L3.68905 3.47488C3.61513 3.54532 3.54293 3.61755 3.47254 3.69151L2.85533 3.43585C1.9624 3.06599 0.938705 3.49002 0.568843 4.38295L0.186159 5.30683C-0.183704 6.19975 0.240324 7.22345 1.13325 7.59331L1.75185 7.84955C1.75067 7.89961 1.75007 7.9498 1.75007 8.00011C1.75007 8.05168 1.7507 8.10312 1.75194 8.15443L1.13335 8.41066C0.240417 8.78052 -0.18361 9.80422 0.186252 10.6971L0.568936 11.621C0.938798 12.514 1.96249 12.938 2.85542 12.5681L3.47512 12.3114C3.54507 12.3848 3.6168 12.4565 3.69022 12.5265L3.43351 13.1462ZM1.61161 6.43846C1.35648 6.33279 1.23533 6.0403 1.34101 5.78518L1.72369 4.8613C1.82937 4.60618 2.12185 4.48503 2.37697 4.5907L3.47809 5.0468C3.69752 5.13769 3.94855 5.05988 4.09713 4.87459C4.32641 4.58865 4.58647 4.32845 4.87227 4.099C5.05738 3.95039 5.13507 3.69948 5.04422 3.48016L4.58828 2.37941C4.4826 2.12429 4.60375 1.83181 4.85888 1.72613L5.78276 1.34345C6.03788 1.23777 6.33036 1.35893 6.43604 1.61405L6.89159 2.71385C6.98246 2.93322 7.21488 3.05571 7.45092 3.02993C7.63126 3.01022 7.81448 3.00011 8.00007 3.00011C8.18541 3.00011 8.3684 3.0102 8.54851 3.02985C8.78452 3.0556 9.01691 2.93311 9.10776 2.71377L9.56324 1.61414C9.66891 1.35902 9.9614 1.23787 10.2165 1.34354L11.1404 1.72623C11.3955 1.8319 11.5167 2.12439 11.411 2.37951L10.9553 3.47967C10.8644 3.69901 10.9422 3.94995 11.1273 4.09856C11.4132 4.32802 11.6734 4.58826 11.9027 4.87425C12.0513 5.05952 12.3023 5.13731 12.5217 5.04642L13.6221 4.59063C13.8773 4.48495 14.1697 4.6061 14.2754 4.86122L14.6581 5.7851C14.7638 6.04023 14.6426 6.33271 14.3875 6.43839L13.2866 6.89438C13.0674 6.98521 12.9449 7.21748 12.9705 7.45343C12.99 7.63298 13.0001 7.81537 13.0001 8.00011C13.0001 8.18597 12.9899 8.36945 12.9702 8.55005C12.9443 8.78611 13.0668 9.01859 13.2862 9.10947L14.3874 9.56559C14.6425 9.67126 14.7637 9.96375 14.658 10.2189L14.2753 11.1427C14.1696 11.3979 13.8772 11.519 13.622 11.4133L12.5195 10.9566C12.3002 10.8658 12.0493 10.9435 11.9007 11.1285C11.6715 11.4139 11.4117 11.6736 11.1262 11.9026C10.941 12.0511 10.8632 12.3021 10.9541 12.5215L11.4109 13.6245C11.5166 13.8796 11.3954 14.1721 11.1403 14.2778L10.2164 14.6604C9.96132 14.7661 9.66884 14.645 9.56316 14.3898L9.1062 13.2866C9.01536 13.0673 8.78307 12.9449 8.54711 12.9705C8.36745 12.9901 8.18493 13.0001 8.00007 13.0001C7.81497 13.0001 7.63221 12.9901 7.45233 12.9705C7.21634 12.9447 6.984 13.0672 6.89316 13.2865L6.43611 14.3899C6.33044 14.6451 6.03796 14.7662 5.78283 14.6605L4.85895 14.2779C4.60383 14.1722 4.48268 13.8797 4.58836 13.6246L5.04545 12.521C5.13632 12.3017 5.05857 12.0507 4.87337 11.9021C4.58799 11.6731 4.32826 11.4135 4.09918 11.1282C3.95057 10.9431 3.69967 10.8654 3.48037 10.9563L2.37707 11.4133C2.12194 11.5189 1.82946 11.3978 1.72379 11.1427L1.3411 10.2188C1.23543 9.96367 1.35658 9.67119 1.6117 9.56551L2.71385 9.10898C2.93323 9.01811 3.05572 8.78566 3.02992 8.54962C3.01019 8.36916 3.00007 8.18582 3.00007 8.00011C3.00007 7.81552 3.01007 7.63327 3.02957 7.45386C3.0552 7.21793 2.93271 6.98568 2.71345 6.89486L1.61161 6.43846ZM6.12508 8.00008C6.12508 6.96455 6.96455 6.12508 8.00008 6.12508C9.03562 6.12508 9.87508 6.96455 9.87508 8.00008C9.87508 9.03562 9.03562 9.87508 8.00008 9.87508C6.96455 9.87508 6.12508 9.03562 6.12508 8.00008ZM8.00008 4.87508C6.27419 4.87508 4.87508 6.27419 4.87508 8.00008C4.87508 9.72597 6.27419 11.1251 8.00008 11.1251C9.72597 11.1251 11.1251 9.72597 11.1251 8.00008C11.1251 6.27419 9.72597 4.87508 8.00008 4.87508Z", - "fill-opacity": "0.8" - } - )); - } - function FireIcon() { - return /* @__PURE__ */ y("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none", xmlns: "http://www.w3.org/2000/svg" }, /* @__PURE__ */ y( - "path", - { - class: "fire-icon", - "fill-rule": "evenodd", - "clip-rule": "evenodd", - d: "M6.51018 15.53C5.52187 15.1832 4.62831 14.6102 3.90082 13.8566C3.17333 13.1031 2.63205 12.1899 2.32018 11.19C2.00674 10.2021 1.95815 9.14927 2.17926 8.1367C2.40038 7.12413 2.88345 6.18736 3.58018 5.42005C3.55105 5.89155 3.6297 6.36349 3.81018 6.80005C4.02356 7.25295 4.32236 7.6604 4.69018 8.00005C4.69018 8.00005 4.12018 6.49005 5.50018 4.00005C6.05384 3.11404 6.78312 2.35083 7.64306 1.75747C8.50299 1.16412 9.47535 0.7532 10.5002 0.550049C9.98701 1.37608 9.80819 2.36673 10.0002 3.32005C10.3002 4.32005 10.7902 4.86005 11.3402 6.32005C11.6533 7.02128 11.8102 7.78217 11.8002 8.55005C11.8926 8.00549 12.0787 7.48106 12.3502 7.00005C12.8054 6.23481 13.5124 5.65154 14.3502 5.35005C13.9624 6.24354 13.8043 7.21983 13.8902 8.19005C14.1302 9.57207 14.0026 10.9929 13.5202 12.31C13.1428 13.1433 12.5799 13.8792 11.8745 14.4616C11.1691 15.0439 10.3398 15.4573 9.45018 15.67C10.0364 15.44 10.5354 15.0313 10.8765 14.5018C11.2175 13.9723 11.3832 13.349 11.3502 12.72C11.252 11.9769 10.8985 11.2911 10.3502 10.78C10.0002 12.67 9.00018 12.89 9.00018 12.89C9.38752 12.0753 9.62788 11.1985 9.71018 10.3C9.76455 9.73167 9.71025 9.15813 9.55018 8.61005C9.35806 7.62829 8.80504 6.75416 8.00018 6.16005C8.05821 6.68407 8.0102 7.21441 7.85902 7.7195C7.70784 8.22458 7.45657 8.69408 7.12018 9.10005C6.31018 10.36 4.94018 11.29 5.00018 13.17C5.02637 13.6604 5.17925 14.1356 5.44391 14.5492C5.70856 14.9628 6.07594 15.3008 6.51018 15.53Z", - "fill-opacity": "0.84" - } - )); - } - - // v2/components/email.jsx - init_lib(); - var formatAddress = (address) => address + "@duck.com"; - var EmailContext = G({ - /** @type {EmailState} */ - state: { - state: "unknown", - alias: null - }, - /** @type {() => void} */ - copyAlias: () => { - throw new Error("todo: implement refresh"); - } - }); - function EmailProvider({ children }) { - const data = useData(); - const fetcher = useFetcher(); - const hasAlias = typeof data.emailProtectionUserData?.nextAlias === "string"; - const initialState = { - state: hasAlias ? "idle" : "unknown", - alias: hasAlias ? data.emailProtectionUserData?.nextAlias : null - }; - const [state, dispatch] = s2((state2, action) => { - switch (state2.state) { - case "added": { - switch (action.type) { - case "update": { - return { - ...state2, - alias: action.alias - }; - } - case "reset": { - return { - ...state2, - state: ( - /** @type {const} */ - "idle" - ) - }; - } - default: - return state2; - } - } - case "idle": - case "unknown": - switch (action.type) { - case "copy": { - return { - ...state2, - state: ( - /** @type {const} */ - "added" - ) - }; - } - } - break; - } - return state2; - }, initialState); - function copyAlias() { - dispatch({ type: "copy" }); - if (!state.alias) { - return console.warn("missing state.alias"); - } - navigator.clipboard?.writeText(formatAddress(state.alias)); - const msg = new RefreshEmailAliasMessage(); - fetcher(msg).then((resp) => { - console.log("--", resp); - const response = z3.object({ - privateAddress: z3.string().optional() - }); - const parsed = response.safeParse(resp); - if (!parsed.success) { - console.warn("response did not contain a valid private address", resp); - dispatch({ - type: "update", - alias: null - }); - } else { - if (!parsed.data.privateAddress) { - return console.warn("missing `privateAddress`"); - } - dispatch({ - type: "update", - alias: parsed.data.privateAddress - }); - } - }).catch((e3) => console.error("error refreshing", e3)).finally(() => { - setTimeout(() => { - dispatch({ type: "reset" }); - }, 2e3); - }); - } - if (state.state === "unknown") - return null; - return /* @__PURE__ */ y(EmailContext.Provider, { value: { state, copyAlias } }, children); - } - function EmailBar() { - const { state, copyAlias } = q2(EmailContext); - const text = state.state === "idle" ? i18n.t("site:createNewDuckAddress.title") : i18n.t("site:createNewDuckAddressCopied.title"); - const icon = state.state === "idle" ? /* @__PURE__ */ y(WandIcon, null) : /* @__PURE__ */ y(CheckMarkIcon, null); - return /* @__PURE__ */ y("div", { id: "email-alias-container" }, /* @__PURE__ */ y("div", { className: "js-email-alias email-alias token-body-em" }, /* @__PURE__ */ y( - "button", - { - className: "email-alias__button", - type: "button", - "data-state": state.state, - disabled: state.state === "added", - onClick: copyAlias - }, - icon, - /* @__PURE__ */ y("span", { className: "email-alias__text" }, text) - ))); - } - function WandIcon() { - return /* @__PURE__ */ y("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" }, /* @__PURE__ */ y("path", { d: "M10.4998 0.75C10.4998 0.335786 10.164 0 9.74976 0C9.33554 0 8.99976 0.335786 8.99976 0.75V3.25C8.99976 3.66421 9.33554 4 9.74976 4C10.164 4 10.4998 3.66421 10.4998 3.25V0.75Z" }), /* @__PURE__ */ y("path", { d: "M10.4998 9.75C10.4998 9.33579 10.164 9 9.74976 9C9.33554 9 8.99976 9.33579 8.99976 9.75V12.25C8.99976 12.6642 9.33554 13 9.74976 13C10.164 13 10.4998 12.6642 10.4998 12.25V9.75Z" }), /* @__PURE__ */ y("path", { d: "M15.9998 6.25C15.9998 6.66421 15.664 7 15.2498 7H12.7498C12.3355 7 11.9998 6.66421 11.9998 6.25C11.9998 5.83579 12.3355 5.5 12.7498 5.5H15.2498C15.664 5.5 15.9998 5.83579 15.9998 6.25Z" }), /* @__PURE__ */ y("path", { d: "M6.24976 7C6.66397 7 6.99976 6.66421 6.99976 6.25C6.99976 5.83579 6.66397 5.5 6.24976 5.5H3.74976C3.33554 5.5 2.99976 5.83579 2.99976 6.25C2.99976 6.66421 3.33554 7 3.74976 7H6.24976Z" }), /* @__PURE__ */ y("path", { d: "M14.2801 10.7803C13.9872 11.0732 13.5123 11.0732 13.2194 10.7803L11.4694 9.03033C11.1765 8.73744 11.1765 8.26256 11.4694 7.96967C11.7623 7.67678 12.2372 7.67678 12.5301 7.96967L14.2801 9.71967C14.573 10.0126 14.573 10.4874 14.2801 10.7803Z" }), /* @__PURE__ */ y("path", { d: "M6.71942 4.28033C7.01231 4.57322 7.48719 4.57322 7.78008 4.28033C8.07297 3.98744 8.07297 3.51256 7.78008 3.21967L6.03008 1.46967C5.73719 1.17678 5.26231 1.17678 4.96942 1.46967C4.67653 1.76256 4.67653 2.23744 4.96942 2.53033L6.71942 4.28033Z" }), /* @__PURE__ */ y("path", { d: "M11.4694 4.53032C11.1765 4.23743 11.1765 3.76256 11.4694 3.46966L13.2194 1.71966C13.5123 1.42677 13.9872 1.42677 14.2801 1.71966C14.573 2.01256 14.573 2.48743 14.2801 2.78032L12.5301 4.53032C12.2372 4.82322 11.7623 4.82322 11.4694 4.53032Z" }), /* @__PURE__ */ y("path", { d: "M2.28296 12.658L9.24784 5.69307C9.54074 5.40018 10.0156 5.40018 10.3085 5.69307V5.69307C10.6014 5.98597 10.6014 6.46084 10.3085 6.75373L3.34362 13.7186L2.28296 12.658Z" }), /* @__PURE__ */ y("path", { d: "M0.243221 15.7588C-0.0496725 15.466 -0.0496726 14.9911 0.243221 14.6982L1.75195 13.1895L2.81261 14.2501L1.30388 15.7588C1.01099 16.0517 0.536114 16.0517 0.243221 15.7588V15.7588Z" })); - } - function CheckMarkIcon() { - return /* @__PURE__ */ y("svg", { width: "16", height: "16", viewBox: "0 0 16 16", fill: "none" }, /* @__PURE__ */ y("path", { d: "M11.809 6.2501C12.0851 5.94141 12.0588 5.46727 11.7501 5.19108C11.4414 4.91488 10.9673 4.94122 10.6911 5.24991L7.0255 9.34675L5.33049 7.27508C5.06819 6.9545 4.59568 6.90724 4.27509 7.16954C3.95451 7.43183 3.90726 7.90435 4.16955 8.22494L6.41955 10.9749C6.55833 11.1446 6.76436 11.245 6.98346 11.2498C7.20256 11.2547 7.41282 11.1634 7.55895 11.0001L11.809 6.2501Z" }), /* @__PURE__ */ y( - "path", - { - "fill-rule": "evenodd", - "clip-rule": "evenodd", - d: "M8 0C3.58172 0 0 3.58172 0 8C0 12.4183 3.58172 16 8 16C12.4183 16 16 12.4183 16 8C16 3.58172 12.4183 0 8 0ZM1.5 8C1.5 4.41015 4.41015 1.5 8 1.5C11.5899 1.5 14.5 4.41015 14.5 8C14.5 11.5899 11.5899 14.5 8 14.5C4.41015 14.5 1.5 11.5899 1.5 8Z" - } - )); - } - - // shared/js/ui/templates/site.js - var import_nanohtml9 = __toESM(require_browser()); - function localizePermissions(permissions) { - if (!Array.isArray(permissions) || permissions.length === 0) { - return []; - } - const updatedPermissions = JSON.parse(JSON.stringify(permissions)); - return updatedPermissions.map((perm) => { - const permKey = `permissions:${perm.key}.title`; - if (i18n.exists(permKey)) { - perm.title = i18n.t(permKey); - } - perm.options = perm.options.map((option) => { - const optionKey = `permissions:${option.id}.title`; - if (i18n.exists(optionKey)) { - option.title = i18n.t(optionKey); - } - return option; - }); - return perm; - }); - } - - // v2/components/page-outer.jsx - function PageOuter({ children }) { - return /* @__PURE__ */ y("div", { class: "page-outer" }, children); - } - - // v2/components/permissions.jsx - function Permissions() { - const data = useData(); - if (!data.permissions || data.permissions.length === 0) { - return null; - } - const localizedPerms = localizePermissions(data.permissions); - const fetcher = useFetcher(); - function update(id, value) { - console.log(id, value); - fetcher(new UpdatePermissionMessage({ id, value })).catch((e3) => console.error(e3)); - } - return /* @__PURE__ */ y(PageOuter, null, /* @__PURE__ */ y("div", { className: "site-info__li--manage-permissions" }, localizedPerms.map(({ key: permissionId, title, permission, options }) => { - return /* @__PURE__ */ y("div", { className: "site-info__page-permission" }, /* @__PURE__ */ y("label", null, /* @__PURE__ */ y("div", null, /* @__PURE__ */ y("div", { className: "site-info__page-permission__icon", "data-icon": permissionId }), title), /* @__PURE__ */ y("select", { name: permissionId, onChange: (e3) => update( - permissionId, - /** @type {any} */ - e3.target.value - ) }, options.map(({ id, title: title2 }) => /* @__PURE__ */ y("option", { value: id, selected: permission === id }, title2))))); - }))); - } - - // v2/screens/cta-screen.jsx - function CtaScreen() { - const data = useData(); - const ctas = { - spread: { - title: i18n.t("ctascreens:spreadTitle.title"), - text: i18n.t("ctascreens:spreadText.title"), - icon: heartArrowSvg, - action: /* @__PURE__ */ y("a", { href: "https://duckduckgo.com/spread", target: "_blank", class: "cta__button" }, i18n.t("ctascreens:spreadButton.title")) - }, - email: { - title: i18n.t("ctascreens:emailTitle.title"), - text: i18n.t("ctascreens:emailText.title"), - icon: emailSvg, - action: /* @__PURE__ */ y("a", { href: "https://duckduckgo.com/email", target: "_blank", class: "cta__button" }, i18n.t("ctascreens:spreadButton.title")) - } - }; - const keys = Object.keys(ctas); - const ctaKey = data.emailProtectionUserData?.nextAlias ? "spread" : keys[Math.floor(Math.random() * keys.length)]; - const cta = ctas[ctaKey]; - return /* @__PURE__ */ y("div", { className: "cta-screen page-inner" }, /* @__PURE__ */ y("p", { className: "note token-title-3 text--center" }, i18n.t("ctascreens:protectionsUnavailableNote.title")), /* @__PURE__ */ y("div", { className: "cta text--center" }, /* @__PURE__ */ y("div", { className: "cta__icon", dangerouslySetInnerHTML: { __html: cta.icon() } }), /* @__PURE__ */ y("h1", { className: "cta__title" }, cta.title), /* @__PURE__ */ y("h2", { className: "cta__text" }, cta.text), /* @__PURE__ */ y("div", { className: "cta__action" }, cta.action))); - } - function heartArrowSvg() { - return ` - - - - - - - - - - - - - - - - -`; - } - function emailSvg() { - return ` - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -`; - } - - // v2/screens/primary-screen.jsx - function PrimaryScreen() { - const status = usePrimaryStatus(); - return /* @__PURE__ */ y("div", { class: "site-info page" }, /* @__PURE__ */ y("div", { className: "page-inner" }, /* @__PURE__ */ y(SearchBar, null), /* @__PURE__ */ y(PrimaryScreenTopNav, null), status === "error" && /* @__PURE__ */ y(ErrorInner, null), status === "cta" && /* @__PURE__ */ y(CtaScreenInner, null), status === "ready" && /* @__PURE__ */ y(PrimaryScreenInner, null), /* @__PURE__ */ y(Footer, null), /* @__PURE__ */ y(Permissions, null))); - } - function Footer() { - return /* @__PURE__ */ y("footer", { className: "footer" }, /* @__PURE__ */ y("div", { className: "padding-x" }, isBrowser() && /* @__PURE__ */ y(EmailProvider, null, /* @__PURE__ */ y(EmailBar, null)))); - } - function PrimaryScreenInner() { - return /* @__PURE__ */ y(k, null, /* @__PURE__ */ y("header", { class: "header" }, /* @__PURE__ */ y(ProtectionHeader2, null)), /* @__PURE__ */ y("div", { class: "header-spacer" }), /* @__PURE__ */ y("div", { class: "padding-x-double" }, /* @__PURE__ */ y(KeyInsights, null)), /* @__PURE__ */ y("div", { class: "padding-x" }, /* @__PURE__ */ y(MainNav, null))); - } - function PrimaryScreenTopNav() { - const onClose = useClose(); - if (isAndroid()) - return /* @__PURE__ */ y(TopNav, { back: /* @__PURE__ */ y(Back, { onClick: onClose }) }); - if (isIOS()) - return /* @__PURE__ */ y(TopNav, { done: /* @__PURE__ */ y(Done, { onClick: onClose }) }); - return null; - } - function CtaScreenInner() { - return /* @__PURE__ */ y("div", { class: "padding-x" }, /* @__PURE__ */ y(CtaScreen, null)); - } - function ErrorInner() { - const errorText = i18n.t("site:errorMessage.title"); - return /* @__PURE__ */ y("div", { className: "padding-x" }, /* @__PURE__ */ y("div", { className: "cta-screen" }, /* @__PURE__ */ y("p", { className: "note token-title-3 text--center" }, errorText))); - } - - // v2/breakage-categories.js - var defaultCategories = () => { - return { - blocked: ns.report("blocked.title"), - layout: ns.report("layout.title"), - "empty-spaces": ns.report("emptySpaces.title"), - paywall: ns.report("paywall.title"), - videos: ns.report("videos.title"), - comments: ns.report("comments.title"), - login: ns.report("login.title"), - shopping: ns.report("shopping.title"), - other: ns.report("other.title") - }; - }; - function createBreakageFeaturesFrom(platformFeatures) { - return { - /** - * @param {Record} [additional] - * @return {[key: string, description: string][]} - */ - categoryList(additional = {}) { - const items = { - ...defaultCategories(), - ...additional - }; - const list = Object.entries(items); - if (platformFeatures.randomisedCategories) { - return shuffle(list); - } - return list; - } - }; - } - function shuffle(arr2) { - let len = arr2.length; - let temp; - let index; - while (len > 0) { - index = Math.floor(Math.random() * len); - len--; - temp = arr2[len]; - arr2[len] = arr2[index]; - arr2[index] = temp; - } - return arr2; - } - - // v2/components/custom-element-loader.jsx - function CustomElementLoader(props) { - const [state, dispatch] = s2(reducer, { status: "idle" }); - p2(() => { - if (state.status === "idle") { - if (window.__ddg_did_load && window.__ddg_did_load.includes(props.element)) { - dispatch({ kind: "skip-loading" }); - } else { - dispatch({ kind: "load-script", element: props.element }); - } - return; - } - if (state.status === "script-ready") { - dispatch({ kind: "load-element" }); - customElements.whenDefined(props.element).then(() => { - if (!window.__ddg_did_load) - window.__ddg_did_load = []; - window.__ddg_did_load.push(props.element); - dispatch({ kind: "element-loaded" }); - }); - } - }, [state.status, props.src, props.element]); - if (state.status === "element-ready") { - return props.children; - } - if (state.status === "script-pending") { - return /* @__PURE__ */ y("script", { src: props.src, onLoad: () => dispatch({ kind: "script-loaded" }) }); - } - return ( - /** @type {any} */ - null - ); - } - function reducer(state, event) { - console.log("incoming", event, "current", state); - switch (state.status) { - case "idle": { - switch (event.kind) { - case "load-script": { - return { ...state, status: ( - /** @type {const} */ - "script-pending" - ) }; - } - case "skip-loading": { - return { ...state, status: ( - /** @type {const} */ - "element-ready" - ) }; - } - } - break; - } - case "script-pending": { - switch (event.kind) { - case "script-loaded": { - return { ...state, status: ( - /** @type {const} */ - "script-ready" - ) }; - } - } - break; - } - case "script-ready": { - switch (event.kind) { - case "load-element": { - return { ...state, status: ( - /** @type {const} */ - "element-pending" - ) }; - } - } - break; - } - case "element-pending": { - switch (event.kind) { - case "element-loaded": { - return { ...state, status: ( - /** @type {const} */ - "element-ready" - ) }; - } - } - } - } - return state; - } - - // v2/components/android-breakage-modal-wrapper.jsx - var DDG_DIALOG_NAME = "ddg-android-breakage-dialog"; - var DDG_DIALOG_PATH = "../public/js/android-breakage-dialog.js"; - function FormSelectElementWithDialog() { - const platformFeatures = useFeatures(); - const randomised = F(() => { - const f3 = createBreakageFeaturesFrom(platformFeatures); - return f3.categoryList(); - }, [platformFeatures]); - const selectRef = _(null); - function onClick(e3) { - e3.preventDefault(); - e3.stopImmediatePropagation(); - const elem = document.querySelector(DDG_DIALOG_NAME); - if (!elem) - return console.warn("could not find custom element", "ddg-android-breakage-dialog"); - if (!selectRef.current) - return console.warn("could not find select ref"); - elem.show(selectRef.current.value); - } - return /* @__PURE__ */ y(k, null, /* @__PURE__ */ y(CustomElementLoader, { src: DDG_DIALOG_PATH, element: DDG_DIALOG_NAME }, /* @__PURE__ */ y( - AndroidBreakageDialogWrapper, - { - items: randomised, - onSelect: (value) => { - if (!selectRef.current) - return; - selectRef.current.value = value; - } - } - )), /* @__PURE__ */ y("div", { className: "form__select breakage-form__input--dropdown", onClick, "data-testid": "select-click-capture" }, /* @__PURE__ */ y("select", { name: "category", ref: selectRef }, /* @__PURE__ */ y("option", { value: "", selected: true, disabled: true }, ns.report("pickYourIssueFromTheList.title")), randomised.map(([key, value]) => { - return /* @__PURE__ */ y("option", { value: key }, value); - })))); - } - function AndroidBreakageDialogWrapper({ items, onSelect }) { - const ref = _(null); - p2(() => { - const controller = new AbortController(); - ref.current?.addEventListener( - "did-select", - (e3) => { - const selection = ( - /** @type {{value: string}} */ - e3.detail - ); - const matched = items.find(([name]) => name === selection.value); - if (!matched) - throw new Error("value did not match a variant"); - const [value] = matched; - onSelect(value); - }, - { signal: controller.signal } - ); - return () => { - return controller.abort(); - }; - }, []); - return /* @__PURE__ */ y( - "ddg-android-breakage-dialog", - { - items, - ref, - title: ns.report("pickYourIssueFromTheList.title"), - cancelText: ns.site("navigationCancel.title"), - okText: ns.site("okDialogAction.title") - } - ); - } - - // v2/screens/breakage-form-screen.jsx - function BreakageFormScreen({ includeToggle }) { - const data = useData(); - const onToggle = useToggle(); - const onClose = useClose(); - const nav = useNav(); - const canPop = nav.canPop(); - const sendReport = useSendReport(); - const platformFeatures = useFeatures(); - const [state, setState] = h2( - /** @type {"idle" | "sent"} */ - "idle" - ); - const icon = largeHeroIcon({ - status: "breakage-form" - }); - let headerText = includeToggle ? ns.report("selectTheOptionDesc.title") : ns.report("selectTheOptionDescV2.title"); - function submit(e3) { - e3.preventDefault(); - const values = Object.fromEntries(new FormData(e3.target)); - sendReport({ - category: String(values.category || ""), - description: String(values.description || "") - }); - setState("sent"); - } - let topNav2 = platformSwitch({ - android: () => /* @__PURE__ */ y(SecondaryTopNav, null, /* @__PURE__ */ y(Title, null, ns.site("websiteNotWorkingCta.title"))), - default: () => /* @__PURE__ */ y(SecondaryTopNav, null) - }); - if (!canPop) { - topNav2 = platformSwitch({ - ios: () => /* @__PURE__ */ y(TopNav, { done: /* @__PURE__ */ y(Done, { onClick: onClose }) }), - android: () => /* @__PURE__ */ y(TopNav, { back: /* @__PURE__ */ y(Back, { onClick: onClose }) }, /* @__PURE__ */ y(Title, null, ns.site("websiteNotWorkingCta.title"))), - default: () => /* @__PURE__ */ y(TopNav, { done: /* @__PURE__ */ y(Close, { onClick: onClose }) }) - }); - } - return /* @__PURE__ */ y("div", { className: "breakage-form page-inner" }, topNav2, /* @__PURE__ */ y("div", { className: "breakage-form__inner", "data-state": state }, includeToggle && /* @__PURE__ */ y("div", { class: "header header--breakage" }, /* @__PURE__ */ y( - ProtectionHeader, - { - model: data, - initialState: "site-not-working", - toggle: onToggle, - "data-testid": "breakage-form-protection-header" - } - )), /* @__PURE__ */ y("div", { className: "key-insight key-insight--breakage padding-x-double" }, /* @__PURE__ */ y(DomNode, null, icon), /* @__PURE__ */ y("div", { className: "breakage-form__advise" }, /* @__PURE__ */ y("p", { className: "token-title-3" }, headerText)), /* @__PURE__ */ y("div", { className: "thanks" }, /* @__PURE__ */ y("p", { className: "thanks__primary" }, ns.report("thankYou.title")), /* @__PURE__ */ y("p", { className: "thanks__secondary" }, ns.report("yourReportWillHelpDesc.title")))), /* @__PURE__ */ y("div", { className: "breakage-form__content padding-x-double" }, /* @__PURE__ */ y( - FormElement, - { - onSubmit: submit, - before: platformFeatures.breakageFormCategorySelect === "material-web-dialog" ? /* @__PURE__ */ y(FormSelectElementWithDialog, null) : /* @__PURE__ */ y(DefaultSelectElement, null) - } - )), /* @__PURE__ */ y("div", { className: "breakage-form__footer padding-x-double token-breakage-form-body" }, ns.report("reportsAreAnonymousDesc.title")))); - } - function DefaultSelectElement() { - const platformFeatures = useFeatures(); - const randomised = F(() => { - const f3 = createBreakageFeaturesFrom(platformFeatures); - return f3.categoryList(); - }, [platformFeatures]); - return /* @__PURE__ */ y("div", { className: "form__select breakage-form__input--dropdown" }, /* @__PURE__ */ y("select", { name: "category" }, /* @__PURE__ */ y("option", { value: "", selected: true, disabled: true }, ns.report("pickYourIssueFromTheList.title")), randomised.map(([key, value]) => { - return /* @__PURE__ */ y("option", { value: key }, value); - }))); - } - function FormElement({ onSubmit, before, after, placeholder }) { - let bullet = "\n \u2022 "; - placeholder = placeholder || ns.report("tellUsMoreDesc.title", { bullet }); - return /* @__PURE__ */ y("form", { className: "breakage-form__element", onSubmit }, /* @__PURE__ */ y("div", { className: "form__group" }, before, /* @__PURE__ */ y("textarea", { className: "form__textarea", placeholder, maxLength: 2500, name: "description" }), after), /* @__PURE__ */ y("button", { className: "form__submit token-label-em", type: "submit" }, ns.report("sendReport.title"))); - } - - // shared/js/ui/templates/page-trackers.js - var import_nanohtml11 = __toESM(require_browser()); - - // shared/js/ui/templates/shared/platform-limitations.js - var import_nanohtml10 = __toESM(require_browser()); - function platformLimitations() { - return import_nanohtml10.default`

${ns.site("trackerLimitationsNote.title")}

`; - } - - // shared/js/ui/templates/page-trackers.js - function trackerListWrapper(name, heading, companiesList, bordered) { - return import_nanohtml11.default` -
    - ${heading ? import_nanohtml11.default`
  1. ${heading}
  2. ` : import_nanohtml11.default``} ${companiesList} -
- `; - } - function renderCompany(company) { - if (company.displayName && company.displayName === "unknown") { - company.displayName = `(${i18n.t("site:trackerNetworkUnknown.title")})`; - } - const slug = company.normalizedName; - const title = company.name || company.displayName; - const titleClasses = [ - "site-info__tracker__icon", - "site-info__tracker__icon--company", - slug[0].toUpperCase(), - "color-" + getColorId(slug), - slug - ]; - const listLabel = i18n.t("site:trackerDomainsForCompany.title", { - companyName: company.displayName - }); - return import_nanohtml11.default`
  • -

    - - ${company.displayName} -

    -
      - ${Object.keys(company.urls).map((urlHostname) => { - const url = company.urls[urlHostname]; - const matched = displayCategories[url.category]; - return import_nanohtml11.default`
    1. -

      ${urlHostname}

      - ${matched ? import_nanohtml11.default`
      ${i18n.t(matched)}
      ` : ""} -
    2. `; - })} -
    -
  • `; - } - function renderSections(sections) { - const output2 = sections.filter((section) => section.companies.length > 0).map((section) => { - const companiesList = section.companies.map((company) => renderCompany(company)); - const sectionHeading = section.heading(); - return trackerListWrapper(section.name, sectionHeading, companiesList, section.bordered); - }); - return output2; - } - function sectionsFromSiteTrackers(site2) { - const { blocked } = site2.tab.requestDetails; - const sections = renderSections([ - { - name: "blocked", - heading: () => null, - companies: blocked.sortedByPrevalence(), - bordered: true - } - ]); - return sections; - } - - // v2/screens/trackers-screen.jsx - function TrackersScreen() { - const data = useData(); - const ref = useRippleChildren(data.count); - return /* @__PURE__ */ y("div", { className: "site-info card page-inner", "data-page": "trackers" }, /* @__PURE__ */ y(SecondaryTopNav, null), /* @__PURE__ */ y("div", { className: "padding-x-double", ref }, /* @__PURE__ */ y(DomNode, { key: data.count }, heroFromTabTrackers(data.tab.requestDetails, data.protectionsEnabled))), /* @__PURE__ */ y("div", { className: "padding-x-double", "aria-label": "List of Tracker Companies" }, sectionsFromSiteTrackers(data).map((el, index) => { - return /* @__PURE__ */ y(DomNode, { key: String(data.count) + String(index) }, el); - })), data.tab.platformLimitations ? /* @__PURE__ */ y("div", { class: "padding-x-double" }, /* @__PURE__ */ y(DomNode, { key: data.count }, platformLimitations())) : /* @__PURE__ */ y("div", null)); - } - - // shared/js/ui/templates/page-non-trackers.js - var import_nanohtml12 = __toESM(require_browser()); - function sectionsFromSiteNonTracker(site2) { - const requestDetails = site2.tab.requestDetails; - const onlyAllowedNonTrackers = requestDetails.matches(site2.protectionsEnabled, [ - states.protectionsOn_allowedNonTrackers, - states.protectionsOff_allowedNonTrackers, - states.protectionsOn_blocked_allowedNonTrackers - ]); - if (!site2.protectionsEnabled) { - return renderSections([ - { - name: "protectionsDisabled", - heading: () => ns.site("sectionHeadingProtectionsDisabled.title"), - companies: requestDetails.all.sortedByPrevalence(), - bordered: false - } - ]); - } - return renderSections([ - { - name: "adAttribution", - heading: () => import_nanohtml12.default` -
    -

    ${ns.site("sectionHeadingAdAttribution.title", { domain: site2.tab.domain })}

    - ${adAttributionLink()} -
    - `, - companies: requestDetails.allowed.adClickAttribution.sortedByPrevalence() - }, - { - name: "ignored (rule exceptions)", - heading: () => ns.site("sectionHeadingIgnore.title"), - companies: requestDetails.allowed.ruleException.sortedByPrevalence() - }, - { - name: "firstParty", - heading: () => ns.site("sectionHeadingFirstParty.title", { domain: site2.tab.domain }), - companies: requestDetails.allowed.ownedByFirstParty.sortedByPrevalence() - }, - { - name: "thirdParty", - heading: () => { - if (onlyAllowedNonTrackers) { - return null; - } - return ns.site("sectionHeadingThirdParty.title"); - }, - companies: requestDetails.allowed.otherThirdPartyRequest.sortedByPrevalence(), - bordered: onlyAllowedNonTrackers - } - ]); - } - - // v2/screens/non-trackers-screen.jsx - function NonTrackersScreen() { - const data = useData(); - const ref = useRippleChildren(data.count); - return /* @__PURE__ */ y("div", { className: "site-info card page-inner", "data-page": "non-trackers" }, /* @__PURE__ */ y(SecondaryTopNav, null), /* @__PURE__ */ y("div", { className: "padding-x-double", ref }, /* @__PURE__ */ y(DomNode, { key: data.count }, heroFromTabNonTrackers(data.tab.requestDetails, data.protectionsEnabled))), /* @__PURE__ */ y("div", { className: "padding-x-double", "aria-label": "List of Tracker Companies" }, sectionsFromSiteNonTracker(data).map((el, index) => { - return /* @__PURE__ */ y(DomNode, { key: String(data.count) + String(index) }, el); - })), data.tab.platformLimitations && /* @__PURE__ */ y("div", { class: "padding-x-double" }, /* @__PURE__ */ y(DomNode, { key: data.count }, platformLimitations()))); - } - - // v2/screens/consent-managed-screen.jsx - function ConsentManagedScreen({ cosmetic }) { - const data = useData(); - const fetcher = useFetcher(); - const summary = cosmetic ? ns.site("cookiesHiddenSummary.title") : ns.site("cookiesMinimizedSummary.title"); - const icon = largeHeroIcon({ - status: cosmetic ? "cookies-hidden" : "cookies-managed" - }); - const hero = heroTemplate({ - icon, - summary, - suffix: "none" - }); - function disable() { - const msg = new OpenSettingsMessages({ - target: "cpm" - }); - fetcher(msg).catch(console.error); - } - return /* @__PURE__ */ y("div", { className: "card page-inner", "data-page": "cookie-prompt" }, /* @__PURE__ */ y(SecondaryTopNav, null), /* @__PURE__ */ y("div", { className: "padding-x-double" }, /* @__PURE__ */ y(DomNode, { key: data.count }, hero)), /* @__PURE__ */ y("div", { className: "padding-x-double" }, /* @__PURE__ */ y("div", { className: "padding-y border--top--inner text--center" }, /* @__PURE__ */ y(DomNode, { key: data.count }, disableInSettingsLink(disable))))); - } - - // shared/js/ui/components/toggle-report/toggle-report-provider.jsx - init_schema_parsers(); - var ToggleReportContext = G({ - value: ( - /** @type {import('../../../../../schema/__generated__/schema.types').ToggleReportScreen} */ - {} - ), - /** @type {() => void} */ - send: () => { - throw new Error("todo implement send"); - }, - /** @type {() => void} */ - reject: () => { - throw new Error("todo implement reject"); - }, - /** @type {() => void} */ - didShowWhatIsSent: () => { - throw new Error("todo implement didShowWhatIsSent"); - }, - /** @type {() => void} */ - didClickSuccessScreen: () => { - throw new Error("todo implement didClickSuccessScreen"); - } - }); - function ToggleReportProvider({ children, model, screen }) { - const initial = { status: "pending" }; - const [state, dispatch] = s2((state2, action) => action, initial); - p2(() => { - const msg = new FetchToggleReportOptions(); - model.fetch(msg)?.then((data) => { - const parsed = toggleReportScreenSchema.safeParse(data); - if (parsed.success) { - dispatch({ status: "ready", value: data }); - } else { - console.group("ToggleReportProvider"); - console.error("the response for FetchToggleReportOptions did not match the schema"); - console.error("response:", data); - console.error("error:", parsed.error.toString()); - console.groupEnd(); - dispatch({ status: "error", error: parsed.error.toString() }); - } - }).catch((e3) => { - dispatch({ status: "error", error: e3.toString() }); - }); - }, [model]); - function send() { - useConnectionCount.pause(); - model.fetch(new SendToggleBreakageReport()); - } - function reject() { - model.fetch(new RejectToggleBreakageReport()); - } - function didShowWhatIsSent() { - model.fetch(new SeeWhatIsSent()); - } - function didClickSuccessScreen() { - model.fetch(new CloseMessage({ eventOrigin: { screen } })); - } - if (state.status === "ready") { - return /* @__PURE__ */ y( - ToggleReportContext.Provider, - { - value: { - value: state.value, - send, - reject, - didShowWhatIsSent, - didClickSuccessScreen - } - }, - children - ); - } - if (state.status === "error") - return /* @__PURE__ */ y("div", null, /* @__PURE__ */ y("p", null, "Something went wrong"), /* @__PURE__ */ y("pre", null, /* @__PURE__ */ y("code", null, state.error))); - return null; - } - - // shared/js/ui/components/toggle-report/use-toggle-report-state.js - function useToggleReportState() { - const { send, reject, didShowWhatIsSent } = q2(ToggleReportContext); - return s2( - (state, action) => { - switch (action) { - case "toggle-ios": { - didShowWhatIsSent(); - return { - ...state, - value: ( - /** @type {const} */ - "animating" - ) - }; - } - case "animation-complete": { - return { - ...state, - value: ( - /** @type {const} */ - "showing" - ) - }; - } - case "toggle": { - const next = state.value === "hiding" ? ( - /** @type {const} */ - "showing" - ) : ( - /** @type {const} */ - "hiding" - ); - if (next === "showing") { - didShowWhatIsSent(); - } - return { - ...state, - value: next - }; - } - case "send": { - send(); - return { - ...state, - value: ( - /** @type {const} */ - "sent" - ) - }; - } - case "reject": { - reject(); - return state; - } - } - return state; - }, - { value: ( - /** @type {'hiding' | 'showing' | 'sent' | 'rejected' | 'animating'} */ - "hiding" - ) } - ); - } - - // shared/js/ui/components/toggle-report.jsx - var import_classnames2 = __toESM(require_classnames()); - - // shared/js/ui/components/button.jsx - function Button({ children, btnSize, variant = "desktop-vibrancy", ...rest }) { - return /* @__PURE__ */ y("button", { type: "button", className: "button token-body", ...rest, "data-variant": variant, "data-size": btnSize }, children); - } - function ButtonBar({ children, layout = "horizontal", ...rest }) { - return /* @__PURE__ */ y("div", { className: "button-bar", "data-layout": layout, ...rest }, children); - } - - // shared/js/ui/components/stack.jsx - var import_classnames = __toESM(require_classnames()); - function Stack({ children, gap, className, ...rest }) { - return /* @__PURE__ */ y("div", { ...rest, className: (0, import_classnames.default)(["stack", className]), style: { gap } }, children); - } - function Scrollable({ children, ...rest }) { - return /* @__PURE__ */ y("div", { className: "scrollable fade-in", ...rest }, children); - } - - // shared/js/ui/components/toggle-report/use-ios-animation.js - function useIosAnimation(state, dispatch) { - p2(() => { - if (platform.name !== "ios" && platform.name !== "android") - return; - if (state.value === "animating") { - const child = ( - /** @type {HTMLDivElement | null} */ - document.querySelector('[data-toggle-report="child"]') - ); - if (!child) - return; - child.addEventListener("transitionend", () => { - dispatch("animation-complete"); - }); - child.style.transform = "translateY(0)"; - } - }, [state.value]); - p2(() => { - if (platform.name !== "ios" && platform.name !== "android") - return; - const child = ( - /** @type {HTMLDivElement | null} */ - document.querySelector('[data-toggle-report="child"]') - ); - const parent = ( - /** @type {HTMLDivElement | null} */ - document.querySelector('[data-toggle-report="parent"]') - ); - if (!child || !parent) - return; - const rs = new ResizeObserver((r3) => { - for (const resizeObserverEntry of r3) { - if (resizeObserverEntry.contentRect.height === 0) - continue; - const childSize = child.clientHeight; - const parentHeight = resizeObserverEntry.contentRect.height - 56; - const offset2 = (parentHeight - childSize) / 2; - child.style.transform = "translateY(" + offset2 + "px)"; - child.dataset.ready = "true"; - setTimeout(() => { - child.style.transition = "all .3s"; - }, 0); - } - }); - rs.observe(parent); - return () => { - rs.disconnect(); - }; - }, []); - } - - // shared/data/text.js - function namedString(item) { - switch (item.id) { - case "openerContext": - return ns.toggleReport("dynamic_openerContext.title"); - case "userRefreshCount": - return ns.toggleReport("dynamic_userRefreshCount.title"); - case "jsPerformance": - return ns.toggleReport("dynamic_jsPerformance.title"); - case "wvVersion": - return ns.toggleReport("dynamic_wvVersion.title"); - case "requests": - return ns.toggleReport("dynamic_requests.title"); - case "features": - return ns.toggleReport("dynamic_features.title"); - case "appVersion": - return ns.toggleReport("dynamic_appVersion.title"); - case "atb": - return ns.toggleReport("dynamic_atb.title"); - case "errorDescriptions": - return ns.toggleReport("dynamic_errorDescriptions.title"); - case "extensionVersion": - return ns.toggleReport("dynamic_extensionVersion.title"); - case "httpErrorCodes": - return ns.toggleReport("dynamic_httpErrorCodes.title"); - case "lastSentDay": - return ns.toggleReport("dynamic_lastSentDay.title"); - case "device": - return ns.toggleReport("dynamic_device.title"); - case "os": - return ns.toggleReport("dynamic_os.title"); - case "reportFlow": - return ns.toggleReport("dynamic_reportFlow.title"); - case "siteUrl": - return ns.toggleReport("dynamic_siteUrl.title"); - case "listVersions": - return ns.toggleReport("dynamic_listVersions.title"); - case "didOpenReportInfo": - return ns.toggleReport("dynamic_didOpenReportInfo.title"); - case "toggleReportCounter": - return ns.toggleReport("dynamic_toggleReportCounter.title"); - case "locale": - return ns.toggleReport("dynamic_locale.title"); - case "description": - return ns.toggleReport("dynamic_description.title"); - } - } - - // shared/js/ui/components/toggle-report/toggle-report-data-list.jsx - function ToggleReportDataList({ rows }) { - return /* @__PURE__ */ y(Stack, { gap: "4px", className: "data-list__content" }, /* @__PURE__ */ y("p", { className: "data-list__heading" }, ns.toggleReport("reportsNoInfoSent.title")), /* @__PURE__ */ y("ul", { className: "data-list" }, rows.map((item) => { - const string = namedString(item); - const additional = item.id === "siteUrl" ? "[" + item.additional?.url + "]" : null; - return /* @__PURE__ */ y("li", { className: "data-list__item" }, /* @__PURE__ */ y("span", { dangerouslySetInnerHTML: { __html: `` } }), string, additional && /* @__PURE__ */ y("strong", { className: "block" }, additional)); - }))); - } - - // shared/js/ui/components/toggle-report/toggle-report-sent.jsx - function ToggleReportSent({ onClick }) { - return /* @__PURE__ */ y("div", { onClick }, /* @__PURE__ */ y(ToggleReportIcon, { variant: "sent" }), /* @__PURE__ */ y(Stack, { gap: "8px" }, /* @__PURE__ */ y("h1", { className: "token-title-2-em text--center" }, ns.report("thankYou.title")), /* @__PURE__ */ y("h2", { className: "token-title-3 text--center text--balance" }, ns.toggleReport("yourReportWillHelpToggleReport.title")))); - } - - // shared/js/ui/components/toggle-report/toggle-report-wrapper.jsx - function ToggleReportWrapper({ children, state }) { - switch (platform.name) { - case "android": - return /* @__PURE__ */ y("div", { className: "padding-x-xl padding-y-third" }, children); - case "ios": - return /* @__PURE__ */ y("div", { className: "padding-x-xl vertically-centered", "data-state": state, "data-toggle-report": "child" }, children); - case "windows": - case "browser": - case "macos": - return /* @__PURE__ */ y("div", { className: "padding-x-double" }, children, state === "sent" ? /* @__PURE__ */ y("div", { style: "height: 40px" }) : /* @__PURE__ */ y("div", { style: "height: 32px" })); - default: - return null; - } - } - - // shared/js/ui/components/toggle-report/toggle-report-title.jsx - function ToggleReportTitle({ children }) { - switch (platform.name) { - case "android": - return /* @__PURE__ */ y("h1", { className: "token-headline-2 text--center" }, children); - case "ios": - return /* @__PURE__ */ y("h1", { className: "token-ios-title-3 text--center" }, children); - case "windows": - return /* @__PURE__ */ y("h1", { className: "token-title-3-em text--center" }, children); - case "browser": - case "macos": - return /* @__PURE__ */ y("h1", { className: "token-title-2-em text--center" }, children); - default: - return null; - } - } - - // shared/js/ui/components/toggle-report.jsx - function ToggleReportIcon({ variant = "standard" }) { - const classes = (0, import_classnames2.default)({ - "hero-icon--toggle-report": variant === "standard", - "hero-icon--toggle-report-sent": variant === "sent", - "large-icon-container": platform.name === "browser" || platform.name === "windows", - "medium-icon-container": platform.name === "macos" || platform.name === "ios" || platform.name === "android" - }); - return /* @__PURE__ */ y("div", { className: classes }); - } - function ToggleReport() { - const mobile = platform.name === "android" || platform.name === "ios"; - const innerGap = mobile ? "24px" : "16px"; - const desktop = platform.name === "macos" || platform.name === "windows"; - const extension = platform.name === "browser"; - const { value, didClickSuccessScreen } = q2(ToggleReportContext); - const [state, dispatch] = useToggleReportState(); - useIosAnimation(state, dispatch); - if (state.value === "sent" && (desktop || extension)) { - return /* @__PURE__ */ y(ToggleReportWrapper, { state: state.value }, extension && /* @__PURE__ */ y(SetAutoHeight, null), /* @__PURE__ */ y(ToggleReportSent, { onClick: didClickSuccessScreen })); - } - if (desktop || extension) { - return /* @__PURE__ */ y(ToggleReportWrapper, { state: state.value }, extension && /* @__PURE__ */ y(SetAutoHeight, null), /* @__PURE__ */ y(Stack, { gap: "40px" }, /* @__PURE__ */ y(Stack, { gap: "24px" }, /* @__PURE__ */ y(Stack, { gap: innerGap }, /* @__PURE__ */ y(ToggleReportIcon, null), /* @__PURE__ */ y(ToggleReportTitle, null, ns.toggleReport("siteNotWorkingTitle.title")), /* @__PURE__ */ y(Stack, { gap: "24px" }, /* @__PURE__ */ y("h2", { className: "token-title-3 text--center" }, ns.toggleReport("siteNotWorkingSubTitle.title")), /* @__PURE__ */ y(DesktopRevealText, { state, toggle: () => dispatch("toggle") }))), state.value === "showing" && /* @__PURE__ */ y(Scrollable, null, /* @__PURE__ */ y(ToggleReportDataList, { rows: value.data })), /* @__PURE__ */ y(ToggleReportButtons, { send: () => dispatch("send"), reject: () => dispatch("reject") })))); - } - if (mobile) { - return /* @__PURE__ */ y(ToggleReportWrapper, { state: state.value }, /* @__PURE__ */ y(Stack, { gap: "40px" }, /* @__PURE__ */ y(Stack, { gap: "24px" }, /* @__PURE__ */ y(Stack, { gap: innerGap }, /* @__PURE__ */ y(ToggleReportIcon, null), /* @__PURE__ */ y(ToggleReportTitle, null, ns.toggleReport("siteNotWorkingTitle.title")), /* @__PURE__ */ y("div", null, /* @__PURE__ */ y("h2", { className: "token-title-3 text--center" }, ns.toggleReport("siteNotWorkingSubTitle.title")))), /* @__PURE__ */ y(ToggleReportButtons, { send: () => dispatch("send"), reject: () => dispatch("reject") }), state.value !== "showing" && /* @__PURE__ */ y(RevealText, { toggle: () => dispatch(platform.name === "ios" ? "toggle-ios" : "toggle") })), state.value === "showing" && /* @__PURE__ */ y("div", { className: "ios-separator" }, /* @__PURE__ */ y(ToggleReportDataList, { rows: value.data })))); - } - return /* @__PURE__ */ y("p", null, "unsupported platform: ", platform.name); - } - function SetAutoHeight() { - p2(() => { - const inner = ( - /** @type {HTMLElement} */ - document.querySelector('[data-screen="toggleReport"] .page-inner') - ); - if (inner) { - inner.style.height = "auto"; - const height = getContentHeight(); - document.body.style.setProperty("--height", `${height}px`); - const unsub = setupMutationObserverForExtensions((height2) => { - document.body.style.setProperty("--height", `${height2}px`); - }); - return () => { - unsub(); - }; - } else { - console.warn("Could not select the required element"); - } - }, []); - return null; - } - function getButtonStyles() { - switch (platform.name) { - case "ios": - case "android": - return { variant: "ios-secondary", size: "big", layout: "vertical" }; - case "windows": - return { variant: "desktop-standard", size: "desktop-large", layout: "horizontal" }; - default: - return { variant: "desktop-vibrancy", size: "desktop-large", layout: "horizontal" }; - } - } - function ToggleReportButtons({ send, reject }) { - const { variant, size, layout } = getButtonStyles(); - return /* @__PURE__ */ y(ButtonBar, { layout }, /* @__PURE__ */ y(Button, { variant, btnSize: size, onClick: reject }, ns.toggleReport("dontSendReport.title")), /* @__PURE__ */ y(Button, { variant, btnSize: size, onClick: send }, ns.report("sendReport.title"))); - } - function RevealText({ toggle }) { - return /* @__PURE__ */ y("p", { className: "text--center token-title-3" }, /* @__PURE__ */ y(PlainTextLink, { onClick: toggle, className: "token-bold" }, ns.toggleReport("siteNotWorkingInfoReveal.title"))); - } - function DesktopRevealText({ state, toggle }) { - if (state.value === "showing") - return null; - return /* @__PURE__ */ y("div", null, /* @__PURE__ */ y("p", { className: "text--center token-title-3" }, /* @__PURE__ */ y(PlainTextLink, { onClick: toggle }, ns.toggleReport("siteNotWorkingInfoReveal.title")))); - } - - // v2/screens/toggle-report-screen.jsx - function ToggleReportScreen() { - const fetcher = useFetcher(); - const features = useFeatures(); - const { count } = useConnectionCount(); - const connectionId = `connection-${count}`; - p2(() => { - document.body.dataset.screen = "toggleReport"; - return () => { - document.body.dataset.screen = ""; - }; - }, []); - return /* @__PURE__ */ y(ToggleReportProvider, { key: connectionId, model: { fetch: fetcher }, screen: features.initialScreen }, /* @__PURE__ */ y(ToggleReportWrapper2, null, /* @__PURE__ */ y(ToggleReport, null))); - } - function ToggleReportWrapper2({ children }) { - const features = useFeatures(); - const onClose = useClose(); - const [_24, dispatch] = useToggleReportState(); - p2(() => { - document.body.dataset.screen = "toggleReport"; - return () => { - document.body.dataset.screen = ""; - }; - }, []); - const done = platformSwitch({ - ios: () => /* @__PURE__ */ y(Done, { onClick: onClose }), - macos: () => /* @__PURE__ */ y(Close, { onClick: onClose }), - default: () => null - }); - const back = platformSwitch({ - android: () => /* @__PURE__ */ y(Back, { onClick: () => dispatch("reject") }), - default: () => null - }); - return /* @__PURE__ */ y("div", { "data-toggle-report": "parent", class: "toggle-report page-inner", "data-opener": features.opener }, features.opener === "menu" ? /* @__PURE__ */ y(TopNav, { back, done }) : /* @__PURE__ */ y(TopNav, { back }), /* @__PURE__ */ y("div", { "data-testid": "toggle-report" }, children)); - } - - // v2/components/nav.jsx - function Nav({ children }) { - return /* @__PURE__ */ y("ul", { className: "default-list main-nav token-body-em" }, children); - } - function NavItem({ children, label, onClick }) { - return /* @__PURE__ */ y("li", { className: "main-nav__row" }, /* @__PURE__ */ y( - "a", - { - href: "javascript:void(0)", - role: "button", - draggable: false, - "aria-label": typeof children === "string" ? children : label, - className: "main-nav__item main-nav__item--link link-action link-action--dark", - onClick - }, - /* @__PURE__ */ y("span", { className: "main-nav__text" }, children), - /* @__PURE__ */ y("span", { className: "main-nav__chev" }) - )); - } - - // v2/screens/choice-problem.jsx - function CategoryTypeSelection() { - const description = ns.report("selectTheCategoryType.title"); - const { push } = useNav(); - const send = useTelemetry(); - const { tab } = useData(); - const showNativeFeedback2 = useShowNativeFeedback(); - return /* @__PURE__ */ y("div", { className: "site-info page-inner card", "data-page": "choice-problem" }, /* @__PURE__ */ y(NavWrapper, null), /* @__PURE__ */ y("div", { className: "padding-x-double" }, /* @__PURE__ */ y(KeyInsightsMain, { title: tab.domain }, description)), /* @__PURE__ */ y("div", { className: "padding-x" }, /* @__PURE__ */ y(Nav, null, /* @__PURE__ */ y( - NavItem, - { - onClick: () => { - send({ name: "categoryTypeSelected", value: "notWorking" }); - push("categorySelection"); - } - }, - ns.report("categoryType1.title") - ), /* @__PURE__ */ y( - NavItem, - { - onClick: () => { - send({ name: "categoryTypeSelected", value: "dislike" }); - push("choiceBreakageForm", { category: "dislike" }); - } - }, - ns.report("categoryType2.title") - ), /* @__PURE__ */ y( - NavItem, - { - onClick: () => { - send({ name: "categoryTypeSelected", value: "general" }); - showNativeFeedback2(); - } - }, - ns.report("categoryType3.title") - )))); - } - function CategorySelection() { - const description = ns.report("selectTheCategory.title"); - const { push } = useNav(); - const send = useTelemetry(); - const { protectionsEnabled, tab } = useData(); - const text = tab.domain; - const platformFeatures = useFeatures(); - const showToggle = protectionsEnabled && (platformFeatures.breakageScreen === "categoryTypeSelection" || platformFeatures.initialScreen === "categoryTypeSelection"); - const randomised = F(() => { - const f3 = createBreakageFeaturesFrom(platformFeatures); - return f3.categoryList({ - login: ns.report("loginV2.title") - }); - }, [platformFeatures]); - return /* @__PURE__ */ y("div", { className: "site-info page-inner card", "data-page": "choice-category" }, /* @__PURE__ */ y(NavWrapper, null), /* @__PURE__ */ y("div", { className: "padding-x-double" }, /* @__PURE__ */ y(KeyInsightsMain, { title: text }, description)), /* @__PURE__ */ y("div", { className: "padding-x" }, /* @__PURE__ */ y(Nav, null, randomised.map(([value, title]) => { - return /* @__PURE__ */ y( - NavItem, - { - key: value, - onClick: () => { - send({ name: "categorySelected", value: ( - /** @type {any} */ - value - ) }); - if (showToggle) { - push("choiceToggle", { category: value }); - } else { - push("choiceBreakageForm", { category: value }); - } - } - }, - title - ); - })))); - } - function ChoiceToggleScreen() { - const description = ns.report("tryTurningProtectionsOff.title"); - const { push } = useNav(); - const data = useData(); - const text = data.tab.domain; - const onToggle = useToggle(); - const send = useTelemetry(); - return /* @__PURE__ */ y("div", { className: "site-info page-inner card", "data-page": "choice-category" }, /* @__PURE__ */ y(NavWrapper, null), /* @__PURE__ */ y("div", { className: "padding-x-double" }, /* @__PURE__ */ y(KeyInsightsMain, { title: text, icon: "switch-shield" }, description)), /* @__PURE__ */ y("div", { className: "padding-x" }, /* @__PURE__ */ y("div", { class: "card-list--bordered" }, /* @__PURE__ */ y("div", { className: "protection-toggle" }, /* @__PURE__ */ y("div", { className: "protection-toggle__row" }, /* @__PURE__ */ y(ProtectionToggle, { model: data, toggle: onToggle })))), /* @__PURE__ */ y("div", { class: "text--center" }, /* @__PURE__ */ y( - TextLink, - { - onClick: () => { - push("choiceBreakageForm"); - send({ name: "toggleSkipped" }); - } - }, - ns.report("skipThisStep.title") - )))); - } - var validCategories = () => { - return { - ...defaultCategories(), - dislike: ns.report("dislike.title") - }; - }; - function ChoiceBreakageForm() { - const { tab } = useData(); - const sendReport = useSendReport(); - const nav = useNav(); - const showAlert = useShowAlert(); - const categories = validCategories(); - let category = nav.params.get("category"); - if (!category || !Object.hasOwnProperty.call(categories, category)) { - category = "other"; - } - const description = categories[category]; - const placeholder = category === "other" ? ns.report("otherRequired.title") : ns.report("otherOptional.title"); - function submit(e3) { - e3.preventDefault(); - const values = Object.fromEntries(new FormData(e3.target)); - const desc = String(values.description).trim(); - if (category === "other" && desc.length === 0) { - showAlert(); - } else { - sendReport({ - category, - description: desc - }); - } - } - return /* @__PURE__ */ y("div", { className: "site-info page-inner card", "data-page": "choice-category" }, /* @__PURE__ */ y(NavWrapper, null), /* @__PURE__ */ y("div", { className: "padding-x-third" }, /* @__PURE__ */ y(KeyInsightsMain, { title: tab.domain }, description)), /* @__PURE__ */ y("div", { className: "padding-x-third" }, /* @__PURE__ */ y( - FormElement, - { - placeholder, - after: /* @__PURE__ */ y("ul", { class: "padding-x" }, /* @__PURE__ */ y("li", null, ns.report("suggestionWhatHappened.title")), /* @__PURE__ */ y("li", null, ns.report("suggestionWhatHappened2.title")), /* @__PURE__ */ y("li", null, ns.report("suggestionWhatHappened3.title"))), - onSubmit: submit - } - ))); - } - function NavWrapper() { - return /* @__PURE__ */ y(SecondaryTopNavAlt, null, /* @__PURE__ */ y(Title, null, ns.report("reportTitle.title"))); - } - - // v2/navigation.jsx - init_schema_parsers(); - var availableScreens = { - primaryScreen: { kind: "root", component: () => /* @__PURE__ */ y(PrimaryScreen, null) }, - // screens that would load immediately - breakageForm: { kind: "subview", component: () => /* @__PURE__ */ y(BreakageFormScreen, { includeToggle: true }) }, - promptBreakageForm: { kind: "subview", component: () => /* @__PURE__ */ y(BreakageFormScreen, { includeToggle: false }) }, - toggleReport: { kind: "subview", component: () => /* @__PURE__ */ y(ToggleReportScreen, null) }, - // - categoryTypeSelection: { kind: "subview", component: () => /* @__PURE__ */ y(CategoryTypeSelection, null) }, - categorySelection: { kind: "subview", component: () => /* @__PURE__ */ y(CategorySelection, null) }, - choiceToggle: { kind: "subview", component: () => /* @__PURE__ */ y(ChoiceToggleScreen, null) }, - choiceBreakageForm: { kind: "subview", component: () => /* @__PURE__ */ y(ChoiceBreakageForm, null) }, - connection: { kind: "subview", component: () => /* @__PURE__ */ y(ConnectionScreen, null) }, - trackers: { kind: "subview", component: () => /* @__PURE__ */ y(TrackersScreen, null) }, - nonTrackers: { kind: "subview", component: () => /* @__PURE__ */ y(NonTrackersScreen, null) }, - consentManaged: { kind: "subview", component: () => /* @__PURE__ */ y(ConsentManagedScreen, { cosmetic: false }) }, - cookieHidden: { kind: "subview", component: () => /* @__PURE__ */ y(ConsentManagedScreen, { cosmetic: true }) } - }; - var entries = ( - /** @type {[ScreenName, { kind: 'subview' | 'root', component: () => any}][]} */ - Object.entries(availableScreens) - ); - var NavContext = G({ - /** @type {(name: ScreenName, params?: Record) => void} */ - push() { - throw new Error("not implemented"); - }, - /** @type {() => void} */ - pop() { - throw new Error("not implemented"); - }, - params: new URLSearchParams(""), - /** @type {() => boolean} */ - canPop: () => false, - /** @type {(screen: import('../schema/__generated__/schema.types').EventOrigin['screen']) => boolean} */ - canPopFrom: (screen) => false, - /** @type {() => ScreenName} */ - screen: () => { - throw new Error("screen() not implemented"); - } - }); - var ScreenContext = G({ - /** @type {import('../schema/__generated__/schema.types').EventOrigin['screen']} */ - screen: ( - /** @type {const} */ - "primaryScreen" - ) - }); - function useNav() { - return q2(NavContext); - } - function useCanPop() { - const { screen } = q2(ScreenContext); - const { canPopFrom } = useNav(); - return canPopFrom(screen); - } - function isScreenName(input) { - return screenKindSchema.safeParse(input).success; - } - function navReducer(state, event) { - if (!window.__ddg_integration_test) { - console.log("\u{1F4E9}", event, state); - } - switch (state.state) { - case "transitioning": { - switch (event.type) { - case "end": { - return { - ...state, - commit: [], - state: ( - /** @type {const} */ - "settled" - ) - }; - } - } - return state; - } - case "initial": - case "settled": { - switch (event.type) { - case "goto": { - if (!event.opts.animate) { - return { - ...state, - stack: event.stack, - state: ( - /** @type {const} */ - "settled" - ) - }; - } - return { - ...state, - stack: event.stack, - state: ( - /** @type {const} */ - "transitioning" - ) - }; - } - case "push": { - if (!event.opts.animate) { - return { - ...state, - stack: state.stack.concat(event.name), - state: ( - /** @type {const} */ - "settled" - ), - via: "push" - }; - } - return { - ...state, - stack: state.stack.concat(event.name), - state: ( - /** @type {const} */ - "transitioning" - ), - via: "push" - }; - } - case "pop": { - if (state.stack.length < 2) { - if (!window.__ddg_integration_test) { - console.warn("ignoring a `pop` event", window.location.search); - } - return state; - } - if (!event.opts.animate) { - const next = state.stack.slice(0, -1); - return { - ...state, - commit: next, - stack: next, - state: ( - /** @type {const} */ - "settled" - ), - via: "pop" - }; - } - return { - ...state, - commit: state.stack, - stack: state.stack.slice(0, -1), - state: ( - /** @type {const} */ - "transitioning" - ), - via: "pop" - }; - } - default: { - console.warn("ignoring", event, "state", state); - return state; - } - } - } - default: - throw new Error("unreachable"); - } - } - function Navigation(props) { - const [state, dispatch] = s2(navReducer, { - stack: props.stack, - state: "initial", - commit: [], - via: void 0 - }); - const parentRef = _(null); - p2(() => { - const curr = parentRef.current; - if (!curr) - return; - const handler = (e3) => { - if (e3.target !== parentRef.current) - return; - dispatch({ type: "end" }); - }; - curr.addEventListener("transitionend", handler); - return () => { - curr.removeEventListener("transitionend", handler); - }; - }, [state.state]); - p2(() => { - function popstateHandler() { - const currentUrlParams = new URLSearchParams(location.search); - const currentURLStack = currentUrlParams.getAll("stack"); - const navigationIntentionIsForwards = currentURLStack.length > state.stack.length; - if (navigationIntentionIsForwards) { - const lastEntry = currentURLStack[currentURLStack.length - 1]; - if (isScreenName(lastEntry)) { - dispatch({ type: "push", name: lastEntry, opts: { animate: props.animate && isAndroid() } }); - } - } else { - dispatch({ type: "pop", opts: { animate: props.animate && isAndroid() } }); - } - } - window.addEventListener("popstate", popstateHandler); - return () => { - window.removeEventListener("popstate", popstateHandler); - }; - }, [state.state, state.stack, state.via, props.animate]); - const canPop = T2(() => { - if (state.state === "transitioning") { - return state.commit.length > 1 || state.stack.length > 1; - } - return state.stack.length > 1; - }, [state.state, state.stack, state.commit]); - const canPopFrom = T2( - (screen2) => { - if (state.stack[0] === screen2) - return false; - return canPop(); - }, - [state.state, state.stack, state.commit] - ); - const screen = T2(() => { - const v3 = ( - /** @type {ScreenName} */ - state.stack[state.stack.length - 1] - ); - return v3; - }, [state.state, state.stack, state.commit]); - const api = { - /** - * @param {ScreenName} name - * @param {Record} params - */ - push: (name, params = {}) => { - const url = new URL(window.location.href); - for (let [key, value] of Object.entries(params)) { - url.searchParams.set(key, value); - } - url.searchParams.delete("stack"); - for (let string of state.stack) { - url.searchParams.append("stack", string); - } - url.searchParams.append("stack", name); - window.history.pushState({}, "", url); - dispatch({ type: "push", name, opts: { animate: props.animate } }); - }, - pop: () => { - window.history.go(-1); - dispatch({ type: "pop", opts: { animate: props.animate } }); - }, - canPop, - canPopFrom, - screen, - get params() { - return new URLSearchParams(location.search); - } - }; - return /* @__PURE__ */ y(NavContext.Provider, { value: api }, /* @__PURE__ */ y( - "div", - { - id: "popup-container", - ref: parentRef, - className: (0, import_classnames3.default)({ - "sliding-subview-v2": true, - "sliding-subview-v2--root": true, - "sliding-subview-v2--animating": state.state === "transitioning" - }), - style: { - transform: `translateX(` + -((state.stack.length - 1) * 100) + "%)" - } - }, - entries.map(([screenName, item]) => { - const inStack = state.stack.includes(screenName); - const commiting = state.commit.includes(screenName); - const current = state.stack[state.stack.length - 1] === screenName; - if (!inStack && !commiting) - return null; - if (item.kind === "root") { - return /* @__PURE__ */ y(ScreenContext.Provider, { value: { screen: screenName } }, /* @__PURE__ */ y("section", { className: "app-height", key: screenName, "data-testid": `subview-${screenName}` }, item.component())); - } - const translateValue = state.stack.includes(screenName) ? state.stack.indexOf(screenName) : state.commit.includes(screenName) ? state.commit.indexOf(screenName) : 0; - const cssProp = `translateX(${translateValue * 100}%)`; - return /* @__PURE__ */ y(ScreenContext.Provider, { value: { screen: screenName } }, /* @__PURE__ */ y( - "section", - { - "data-current": String(current), - className: "sliding-subview-v2", - key: screenName, - style: { transform: cssProp } - }, - item.component() - )); - }) - )); - } - - // v2/settings.jsx - var SettingsContext = G({ - /** @type {boolean} */ - reducedMotion: false - }); - function SettingsProvider({ children }) { - const [reducedMotion, setReducedMotion] = h2(window.matchMedia("(prefers-reduced-motion: reduce)").matches); - p2(() => { - const mediaQueryList = window.matchMedia("(prefers-reduced-motion: reduce)"); - const listener = (event) => setReducedMotion(event.matches); - mediaQueryList.addEventListener("change", listener); - return () => { - mediaQueryList.removeEventListener("change", listener); - }; - }, []); - return /* @__PURE__ */ y(SettingsContext.Provider, { value: { reducedMotion } }, children); - } - function useGlobalSettings() { - return q2(SettingsContext); - } - - // v2/app.jsx - function App() { - const { reducedMotion } = useGlobalSettings(); - const data = useFeatures(); - const stack = initialStack(data); - return /* @__PURE__ */ y(Navigation, { stack, animate: !reducedMotion, params: new URLSearchParams(window.location.search) }); - } - function initialStack(features) { - if (features.initialScreen === "breakageForm") { - return ["breakageForm"]; - } - if (features.initialScreen === "promptBreakageForm") { - return ["promptBreakageForm"]; - } - if (features.initialScreen === "toggleReport") { - return ["toggleReport"]; - } - if (features.initialScreen === "choiceBreakageForm") { - return ["choiceBreakageForm"]; - } - if (features.initialScreen === "categoryTypeSelection") { - return ["categoryTypeSelection"]; - } - if (features.initialScreen === "categorySelection") { - return ["categorySelection"]; - } - return ["primaryScreen"]; - } - - // v2/index.jsx - window.onunhandledrejection = (event) => { - console.warn(`UNHANDLED PROMISE REJECTION: ${event.reason}`); - }; - async function init2() { - const app = document.querySelector("#app"); - if (!app) - throw new Error("unreachable"); - B( - /* @__PURE__ */ y(SettingsProvider, null, /* @__PURE__ */ y(DataProvider, null, /* @__PURE__ */ y(App, null))), - app - ); - } - init2().catch((e3) => { - console.error("start up error", e3); - }); -})(); -/*! Bundled license information: - -classnames/index.js: - (*! - Copyright (c) 2018 Jed Watson. - Licensed under the MIT License (MIT), see - http://jedwatson.github.io/classnames - *) - -@material/base/foundation.js: - (** - * @license - * Copyright 2016 Google Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - *) - -@material/base/component.js: - (** - * @license - * Copyright 2016 Google Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - *) - -@material/dom/events.js: - (** - * @license - * Copyright 2019 Google Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - *) - -@material/dom/ponyfill.js: - (** - * @license - * Copyright 2018 Google Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - *) - -@material/ripple/constants.js: - (** - * @license - * Copyright 2016 Google Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - *) - -@material/ripple/foundation.js: - (** - * @license - * Copyright 2016 Google Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - *) - -@material/ripple/component.js: - (** - * @license - * Copyright 2016 Google Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - *) -*/ diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfill-loader.js b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfill-loader.js deleted file mode 100644 index 341914af7d7b..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfill-loader.js +++ /dev/null @@ -1,21 +0,0 @@ -/** - * https://bugs.chromium.org/p/v8/issues/detail?id=10682 - */ -function hasIntlGetCanonicalLocalesBug() { - try { - return new Intl.Locale('und-x-private').toString() === 'x-private'; - } catch (e) { - return true; - } -} -function shouldPolyfill() { - return !('Locale' in Intl) || hasIntlGetCanonicalLocalesBug(); -} -/** - * Load the Intl.Locale polyfill if needed - */ -if (shouldPolyfill()) { - const script = document.createElement('script'); - script.src = '../public/js/polyfills.js'; - document.head.appendChild(script); -} diff --git a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfills.js b/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfills.js deleted file mode 100644 index 363804777119..000000000000 --- a/node_modules/@duckduckgo/privacy-dashboard/build/app/public/js/polyfills.js +++ /dev/null @@ -1,6801 +0,0 @@ -"use strict"; -(() => { - var __create = Object.create; - var __defProp = Object.defineProperty; - var __getOwnPropDesc = Object.getOwnPropertyDescriptor; - var __getOwnPropNames = Object.getOwnPropertyNames; - var __getProtoOf = Object.getPrototypeOf; - var __hasOwnProp = Object.prototype.hasOwnProperty; - var __esm = (fn, res) => function __init() { - return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res; - }; - var __commonJS = (cb, mod) => function __require() { - return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports; - }; - var __export = (target, all) => { - for (var name in all) - __defProp(target, name, { get: all[name], enumerable: true }); - }; - var __copyProps = (to, from, except, desc) => { - if (from && typeof from === "object" || typeof from === "function") { - for (let key of __getOwnPropNames(from)) - if (!__hasOwnProp.call(to, key) && key !== except) - __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); - } - return to; - }; - var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( - // If the importer is in node compatibility mode or this is not an ESM - // file that has been converted to a CommonJS file using a Babel- - // compatible transform (i.e. "__esModule" has not been set), then set - // "default" to the CommonJS "module.exports" for node compatibility. - isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, - mod - )); - var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); - - // node_modules/tslib/tslib.es6.js - var tslib_es6_exports = {}; - __export(tslib_es6_exports, { - __assign: () => __assign, - __asyncDelegator: () => __asyncDelegator, - __asyncGenerator: () => __asyncGenerator, - __asyncValues: () => __asyncValues, - __await: () => __await, - __awaiter: () => __awaiter, - __classPrivateFieldGet: () => __classPrivateFieldGet, - __classPrivateFieldIn: () => __classPrivateFieldIn, - __classPrivateFieldSet: () => __classPrivateFieldSet, - __createBinding: () => __createBinding, - __decorate: () => __decorate, - __exportStar: () => __exportStar, - __extends: () => __extends, - __generator: () => __generator, - __importDefault: () => __importDefault, - __importStar: () => __importStar, - __makeTemplateObject: () => __makeTemplateObject, - __metadata: () => __metadata, - __param: () => __param, - __read: () => __read, - __rest: () => __rest, - __spread: () => __spread, - __spreadArray: () => __spreadArray, - __spreadArrays: () => __spreadArrays, - __values: () => __values - }); - function __extends(d, b) { - if (typeof b !== "function" && b !== null) - throw new TypeError("Class extends value " + String(b) + " is not a constructor or null"); - extendStatics(d, b); - function __() { - this.constructor = d; - } - d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); - } - function __rest(s, e) { - var t = {}; - for (var p in s) - if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) - t[p] = s[p]; - if (s != null && typeof Object.getOwnPropertySymbols === "function") - for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { - if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) - t[p[i]] = s[p[i]]; - } - return t; - } - function __decorate(decorators, target, key, desc) { - var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; - if (typeof Reflect === "object" && typeof Reflect.decorate === "function") - r = Reflect.decorate(decorators, target, key, desc); - else - for (var i = decorators.length - 1; i >= 0; i--) - if (d = decorators[i]) - r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; - return c > 3 && r && Object.defineProperty(target, key, r), r; - } - function __param(paramIndex, decorator) { - return function(target, key) { - decorator(target, key, paramIndex); - }; - } - function __metadata(metadataKey, metadataValue) { - if (typeof Reflect === "object" && typeof Reflect.metadata === "function") - return Reflect.metadata(metadataKey, metadataValue); - } - function __awaiter(thisArg, _arguments, P, generator) { - function adopt(value) { - return value instanceof P ? value : new P(function(resolve) { - resolve(value); - }); - } - return new (P || (P = Promise))(function(resolve, reject) { - function fulfilled(value) { - try { - step(generator.next(value)); - } catch (e) { - reject(e); - } - } - function rejected(value) { - try { - step(generator["throw"](value)); - } catch (e) { - reject(e); - } - } - function step(result) { - result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); - } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); - } - function __generator(thisArg, body) { - var _ = { label: 0, sent: function() { - if (t[0] & 1) - throw t[1]; - return t[1]; - }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { - return this; - }), g; - function verb(n) { - return function(v) { - return step([n, v]); - }; - } - function step(op) { - if (f) - throw new TypeError("Generator is already executing."); - while (_) - try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) - return t; - if (y = 0, t) - op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: - case 1: - t = op; - break; - case 4: - _.label++; - return { value: op[1], done: false }; - case 5: - _.label++; - y = op[1]; - op = [0]; - continue; - case 7: - op = _.ops.pop(); - _.trys.pop(); - continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { - _ = 0; - continue; - } - if (op[0] === 3 && (!t || op[1] > t[0] && op[1] < t[3])) { - _.label = op[1]; - break; - } - if (op[0] === 6 && _.label < t[1]) { - _.label = t[1]; - t = op; - break; - } - if (t && _.label < t[2]) { - _.label = t[2]; - _.ops.push(op); - break; - } - if (t[2]) - _.ops.pop(); - _.trys.pop(); - continue; - } - op = body.call(thisArg, _); - } catch (e) { - op = [6, e]; - y = 0; - } finally { - f = t = 0; - } - if (op[0] & 5) - throw op[1]; - return { value: op[0] ? op[1] : void 0, done: true }; - } - } - function __exportStar(m, o) { - for (var p in m) - if (p !== "default" && !Object.prototype.hasOwnProperty.call(o, p)) - __createBinding(o, m, p); - } - function __values(o) { - var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; - if (m) - return m.call(o); - if (o && typeof o.length === "number") - return { - next: function() { - if (o && i >= o.length) - o = void 0; - return { value: o && o[i++], done: !o }; - } - }; - throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); - } - function __read(o, n) { - var m = typeof Symbol === "function" && o[Symbol.iterator]; - if (!m) - return o; - var i = m.call(o), r, ar = [], e; - try { - while ((n === void 0 || n-- > 0) && !(r = i.next()).done) - ar.push(r.value); - } catch (error) { - e = { error }; - } finally { - try { - if (r && !r.done && (m = i["return"])) - m.call(i); - } finally { - if (e) - throw e.error; - } - } - return ar; - } - function __spread() { - for (var ar = [], i = 0; i < arguments.length; i++) - ar = ar.concat(__read(arguments[i])); - return ar; - } - function __spreadArrays() { - for (var s = 0, i = 0, il = arguments.length; i < il; i++) - s += arguments[i].length; - for (var r = Array(s), k = 0, i = 0; i < il; i++) - for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++) - r[k] = a[j]; - return r; - } - function __spreadArray(to, from, pack) { - if (pack || arguments.length === 2) - for (var i = 0, l = from.length, ar; i < l; i++) { - if (ar || !(i in from)) { - if (!ar) - ar = Array.prototype.slice.call(from, 0, i); - ar[i] = from[i]; - } - } - return to.concat(ar || Array.prototype.slice.call(from)); - } - function __await(v) { - return this instanceof __await ? (this.v = v, this) : new __await(v); - } - function __asyncGenerator(thisArg, _arguments, generator) { - if (!Symbol.asyncIterator) - throw new TypeError("Symbol.asyncIterator is not defined."); - var g = generator.apply(thisArg, _arguments || []), i, q = []; - return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { - return this; - }, i; - function verb(n) { - if (g[n]) - i[n] = function(v) { - return new Promise(function(a, b) { - q.push([n, v, a, b]) > 1 || resume(n, v); - }); - }; - } - function resume(n, v) { - try { - step(g[n](v)); - } catch (e) { - settle(q[0][3], e); - } - } - function step(r) { - r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); - } - function fulfill(value) { - resume("next", value); - } - function reject(value) { - resume("throw", value); - } - function settle(f, v) { - if (f(v), q.shift(), q.length) - resume(q[0][0], q[0][1]); - } - } - function __asyncDelegator(o) { - var i, p; - return i = {}, verb("next"), verb("throw", function(e) { - throw e; - }), verb("return"), i[Symbol.iterator] = function() { - return this; - }, i; - function verb(n, f) { - i[n] = o[n] ? function(v) { - return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; - } : f; - } - } - function __asyncValues(o) { - if (!Symbol.asyncIterator) - throw new TypeError("Symbol.asyncIterator is not defined."); - var m = o[Symbol.asyncIterator], i; - return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function() { - return this; - }, i); - function verb(n) { - i[n] = o[n] && function(v) { - return new Promise(function(resolve, reject) { - v = o[n](v), settle(resolve, reject, v.done, v.value); - }); - }; - } - function settle(resolve, reject, d, v) { - Promise.resolve(v).then(function(v2) { - resolve({ value: v2, done: d }); - }, reject); - } - } - function __makeTemplateObject(cooked, raw) { - if (Object.defineProperty) { - Object.defineProperty(cooked, "raw", { value: raw }); - } else { - cooked.raw = raw; - } - return cooked; - } - function __importStar(mod) { - if (mod && mod.__esModule) - return mod; - var result = {}; - if (mod != null) { - for (var k in mod) - if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) - __createBinding(result, mod, k); - } - __setModuleDefault(result, mod); - return result; - } - function __importDefault(mod) { - return mod && mod.__esModule ? mod : { default: mod }; - } - function __classPrivateFieldGet(receiver, state, kind, f) { - if (kind === "a" && !f) - throw new TypeError("Private accessor was defined without a getter"); - if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) - throw new TypeError("Cannot read private member from an object whose class did not declare it"); - return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); - } - function __classPrivateFieldSet(receiver, state, value, kind, f) { - if (kind === "m") - throw new TypeError("Private method is not writable"); - if (kind === "a" && !f) - throw new TypeError("Private accessor was defined without a setter"); - if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) - throw new TypeError("Cannot write private member to an object whose class did not declare it"); - return kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value), value; - } - function __classPrivateFieldIn(state, receiver) { - if (receiver === null || typeof receiver !== "object" && typeof receiver !== "function") - throw new TypeError("Cannot use 'in' operator on non-object"); - return typeof state === "function" ? receiver === state : state.has(receiver); - } - var extendStatics, __assign, __createBinding, __setModuleDefault; - var init_tslib_es6 = __esm({ - "node_modules/tslib/tslib.es6.js"() { - extendStatics = function(d, b) { - extendStatics = Object.setPrototypeOf || { __proto__: [] } instanceof Array && function(d2, b2) { - d2.__proto__ = b2; - } || function(d2, b2) { - for (var p in b2) - if (Object.prototype.hasOwnProperty.call(b2, p)) - d2[p] = b2[p]; - }; - return extendStatics(d, b); - }; - __assign = function() { - __assign = Object.assign || function __assign2(t) { - for (var s, i = 1, n = arguments.length; i < n; i++) { - s = arguments[i]; - for (var p in s) - if (Object.prototype.hasOwnProperty.call(s, p)) - t[p] = s[p]; - } - return t; - }; - return __assign.apply(this, arguments); - }; - __createBinding = Object.create ? function(o, m, k, k2) { - if (k2 === void 0) - k2 = k; - var desc = Object.getOwnPropertyDescriptor(m, k); - if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { - desc = { enumerable: true, get: function() { - return m[k]; - } }; - } - Object.defineProperty(o, k2, desc); - } : function(o, m, k, k2) { - if (k2 === void 0) - k2 = k; - o[k2] = m[k]; - }; - __setModuleDefault = Object.create ? function(o, v) { - Object.defineProperty(o, "default", { enumerable: true, value: v }); - } : function(o, v) { - o["default"] = v; - }; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CanonicalizeLocaleList.js - var require_CanonicalizeLocaleList = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CanonicalizeLocaleList.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.CanonicalizeLocaleList = void 0; - function CanonicalizeLocaleList(locales) { - return Intl.getCanonicalLocales(locales); - } - exports.CanonicalizeLocaleList = CanonicalizeLocaleList; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CanonicalizeTimeZoneName.js - var require_CanonicalizeTimeZoneName = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CanonicalizeTimeZoneName.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.CanonicalizeTimeZoneName = void 0; - function CanonicalizeTimeZoneName(tz, _a) { - var tzData = _a.tzData, uppercaseLinks = _a.uppercaseLinks; - var uppercasedTz = tz.toUpperCase(); - var uppercasedZones = Object.keys(tzData).reduce(function(all, z) { - all[z.toUpperCase()] = z; - return all; - }, {}); - var ianaTimeZone = uppercaseLinks[uppercasedTz] || uppercasedZones[uppercasedTz]; - if (ianaTimeZone === "Etc/UTC" || ianaTimeZone === "Etc/GMT") { - return "UTC"; - } - return ianaTimeZone; - } - exports.CanonicalizeTimeZoneName = CanonicalizeTimeZoneName; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/262.js - var require__ = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/262.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.msFromTime = exports.OrdinaryHasInstance = exports.SecFromTime = exports.MinFromTime = exports.HourFromTime = exports.DateFromTime = exports.MonthFromTime = exports.InLeapYear = exports.DayWithinYear = exports.DaysInYear = exports.YearFromTime = exports.TimeFromYear = exports.DayFromYear = exports.WeekDay = exports.Day = exports.Type = exports.HasOwnProperty = exports.ArrayCreate = exports.SameValue = exports.ToObject = exports.TimeClip = exports.ToNumber = exports.ToString = void 0; - function ToString(o) { - if (typeof o === "symbol") { - throw TypeError("Cannot convert a Symbol value to a string"); - } - return String(o); - } - exports.ToString = ToString; - function ToNumber(val) { - if (val === void 0) { - return NaN; - } - if (val === null) { - return 0; - } - if (typeof val === "boolean") { - return val ? 1 : 0; - } - if (typeof val === "number") { - return val; - } - if (typeof val === "symbol" || typeof val === "bigint") { - throw new TypeError("Cannot convert symbol/bigint to number"); - } - return Number(val); - } - exports.ToNumber = ToNumber; - function ToInteger(n) { - var number = ToNumber(n); - if (isNaN(number) || SameValue(number, -0)) { - return 0; - } - if (isFinite(number)) { - return number; - } - var integer = Math.floor(Math.abs(number)); - if (number < 0) { - integer = -integer; - } - if (SameValue(integer, -0)) { - return 0; - } - return integer; - } - function TimeClip(time) { - if (!isFinite(time)) { - return NaN; - } - if (Math.abs(time) > 8.64 * 1e15) { - return NaN; - } - return ToInteger(time); - } - exports.TimeClip = TimeClip; - function ToObject(arg) { - if (arg == null) { - throw new TypeError("undefined/null cannot be converted to object"); - } - return Object(arg); - } - exports.ToObject = ToObject; - function SameValue(x, y) { - if (Object.is) { - return Object.is(x, y); - } - if (x === y) { - return x !== 0 || 1 / x === 1 / y; - } - return x !== x && y !== y; - } - exports.SameValue = SameValue; - function ArrayCreate(len) { - return new Array(len); - } - exports.ArrayCreate = ArrayCreate; - function HasOwnProperty(o, prop) { - return Object.prototype.hasOwnProperty.call(o, prop); - } - exports.HasOwnProperty = HasOwnProperty; - function Type(x) { - if (x === null) { - return "Null"; - } - if (typeof x === "undefined") { - return "Undefined"; - } - if (typeof x === "function" || typeof x === "object") { - return "Object"; - } - if (typeof x === "number") { - return "Number"; - } - if (typeof x === "boolean") { - return "Boolean"; - } - if (typeof x === "string") { - return "String"; - } - if (typeof x === "symbol") { - return "Symbol"; - } - if (typeof x === "bigint") { - return "BigInt"; - } - } - exports.Type = Type; - var MS_PER_DAY = 864e5; - function mod(x, y) { - return x - Math.floor(x / y) * y; - } - function Day(t) { - return Math.floor(t / MS_PER_DAY); - } - exports.Day = Day; - function WeekDay(t) { - return mod(Day(t) + 4, 7); - } - exports.WeekDay = WeekDay; - function DayFromYear(y) { - return Date.UTC(y, 0) / MS_PER_DAY; - } - exports.DayFromYear = DayFromYear; - function TimeFromYear(y) { - return Date.UTC(y, 0); - } - exports.TimeFromYear = TimeFromYear; - function YearFromTime(t) { - return new Date(t).getUTCFullYear(); - } - exports.YearFromTime = YearFromTime; - function DaysInYear(y) { - if (y % 4 !== 0) { - return 365; - } - if (y % 100 !== 0) { - return 366; - } - if (y % 400 !== 0) { - return 365; - } - return 366; - } - exports.DaysInYear = DaysInYear; - function DayWithinYear(t) { - return Day(t) - DayFromYear(YearFromTime(t)); - } - exports.DayWithinYear = DayWithinYear; - function InLeapYear(t) { - return DaysInYear(YearFromTime(t)) === 365 ? 0 : 1; - } - exports.InLeapYear = InLeapYear; - function MonthFromTime(t) { - var dwy = DayWithinYear(t); - var leap = InLeapYear(t); - if (dwy >= 0 && dwy < 31) { - return 0; - } - if (dwy < 59 + leap) { - return 1; - } - if (dwy < 90 + leap) { - return 2; - } - if (dwy < 120 + leap) { - return 3; - } - if (dwy < 151 + leap) { - return 4; - } - if (dwy < 181 + leap) { - return 5; - } - if (dwy < 212 + leap) { - return 6; - } - if (dwy < 243 + leap) { - return 7; - } - if (dwy < 273 + leap) { - return 8; - } - if (dwy < 304 + leap) { - return 9; - } - if (dwy < 334 + leap) { - return 10; - } - if (dwy < 365 + leap) { - return 11; - } - throw new Error("Invalid time"); - } - exports.MonthFromTime = MonthFromTime; - function DateFromTime(t) { - var dwy = DayWithinYear(t); - var mft = MonthFromTime(t); - var leap = InLeapYear(t); - if (mft === 0) { - return dwy + 1; - } - if (mft === 1) { - return dwy - 30; - } - if (mft === 2) { - return dwy - 58 - leap; - } - if (mft === 3) { - return dwy - 89 - leap; - } - if (mft === 4) { - return dwy - 119 - leap; - } - if (mft === 5) { - return dwy - 150 - leap; - } - if (mft === 6) { - return dwy - 180 - leap; - } - if (mft === 7) { - return dwy - 211 - leap; - } - if (mft === 8) { - return dwy - 242 - leap; - } - if (mft === 9) { - return dwy - 272 - leap; - } - if (mft === 10) { - return dwy - 303 - leap; - } - if (mft === 11) { - return dwy - 333 - leap; - } - throw new Error("Invalid time"); - } - exports.DateFromTime = DateFromTime; - var HOURS_PER_DAY = 24; - var MINUTES_PER_HOUR = 60; - var SECONDS_PER_MINUTE = 60; - var MS_PER_SECOND = 1e3; - var MS_PER_MINUTE = MS_PER_SECOND * SECONDS_PER_MINUTE; - var MS_PER_HOUR = MS_PER_MINUTE * MINUTES_PER_HOUR; - function HourFromTime(t) { - return mod(Math.floor(t / MS_PER_HOUR), HOURS_PER_DAY); - } - exports.HourFromTime = HourFromTime; - function MinFromTime(t) { - return mod(Math.floor(t / MS_PER_MINUTE), MINUTES_PER_HOUR); - } - exports.MinFromTime = MinFromTime; - function SecFromTime(t) { - return mod(Math.floor(t / MS_PER_SECOND), SECONDS_PER_MINUTE); - } - exports.SecFromTime = SecFromTime; - function IsCallable(fn) { - return typeof fn === "function"; - } - function OrdinaryHasInstance(C, O, internalSlots) { - if (!IsCallable(C)) { - return false; - } - if (internalSlots === null || internalSlots === void 0 ? void 0 : internalSlots.boundTargetFunction) { - var BC = internalSlots === null || internalSlots === void 0 ? void 0 : internalSlots.boundTargetFunction; - return O instanceof BC; - } - if (typeof O !== "object") { - return false; - } - var P = C.prototype; - if (typeof P !== "object") { - throw new TypeError("OrdinaryHasInstance called on an object with an invalid prototype property."); - } - return Object.prototype.isPrototypeOf.call(P, O); - } - exports.OrdinaryHasInstance = OrdinaryHasInstance; - function msFromTime(t) { - return mod(t, MS_PER_SECOND); - } - exports.msFromTime = msFromTime; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CoerceOptionsToObject.js - var require_CoerceOptionsToObject = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/CoerceOptionsToObject.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.CoerceOptionsToObject = void 0; - var _262_1 = require__(); - function CoerceOptionsToObject(options) { - if (typeof options === "undefined") { - return /* @__PURE__ */ Object.create(null); - } - return (0, _262_1.ToObject)(options); - } - exports.CoerceOptionsToObject = CoerceOptionsToObject; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/DefaultNumberOption.js - var require_DefaultNumberOption = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/DefaultNumberOption.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.DefaultNumberOption = void 0; - function DefaultNumberOption(val, min, max, fallback) { - if (val !== void 0) { - val = Number(val); - if (isNaN(val) || val < min || val > max) { - throw new RangeError("".concat(val, " is outside of range [").concat(min, ", ").concat(max, "]")); - } - return Math.floor(val); - } - return fallback; - } - exports.DefaultNumberOption = DefaultNumberOption; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetNumberOption.js - var require_GetNumberOption = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetNumberOption.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.GetNumberOption = void 0; - var DefaultNumberOption_1 = require_DefaultNumberOption(); - function GetNumberOption(options, property, minimum, maximum, fallback) { - var val = options[property]; - return (0, DefaultNumberOption_1.DefaultNumberOption)(val, minimum, maximum, fallback); - } - exports.GetNumberOption = GetNumberOption; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetOption.js - var require_GetOption = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetOption.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.GetOption = void 0; - var _262_1 = require__(); - function GetOption(opts, prop, type, values, fallback) { - if (typeof opts !== "object") { - throw new TypeError("Options must be an object"); - } - var value = opts[prop]; - if (value !== void 0) { - if (type !== "boolean" && type !== "string") { - throw new TypeError("invalid type"); - } - if (type === "boolean") { - value = Boolean(value); - } - if (type === "string") { - value = (0, _262_1.ToString)(value); - } - if (values !== void 0 && !values.filter(function(val) { - return val == value; - }).length) { - throw new RangeError("".concat(value, " is not within ").concat(values.join(", "))); - } - return value; - } - return fallback; - } - exports.GetOption = GetOption; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetOptionsObject.js - var require_GetOptionsObject = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetOptionsObject.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.GetOptionsObject = void 0; - function GetOptionsObject(options) { - if (typeof options === "undefined") { - return /* @__PURE__ */ Object.create(null); - } - if (typeof options === "object") { - return options; - } - throw new TypeError("Options must be an object"); - } - exports.GetOptionsObject = GetOptionsObject; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetStringOrBooleanOption.js - var require_GetStringOrBooleanOption = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/GetStringOrBooleanOption.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.GetStringOrBooleanOption = void 0; - var _262_1 = require__(); - function GetStringOrBooleanOption(opts, prop, values, trueValue, falsyValue, fallback) { - var value = opts[prop]; - if (value === void 0) { - return fallback; - } - if (value === true) { - return trueValue; - } - var valueBoolean = Boolean(value); - if (valueBoolean === false) { - return falsyValue; - } - value = (0, _262_1.ToString)(value); - if (value === "true" || value === "false") { - return fallback; - } - if ((values || []).indexOf(value) === -1) { - throw new RangeError("Invalid value ".concat(value)); - } - return value; - } - exports.GetStringOrBooleanOption = GetStringOrBooleanOption; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsSanctionedSimpleUnitIdentifier.js - var require_IsSanctionedSimpleUnitIdentifier = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsSanctionedSimpleUnitIdentifier.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.IsSanctionedSimpleUnitIdentifier = exports.SIMPLE_UNITS = exports.removeUnitNamespace = exports.SANCTIONED_UNITS = void 0; - exports.SANCTIONED_UNITS = [ - "angle-degree", - "area-acre", - "area-hectare", - "concentr-percent", - "digital-bit", - "digital-byte", - "digital-gigabit", - "digital-gigabyte", - "digital-kilobit", - "digital-kilobyte", - "digital-megabit", - "digital-megabyte", - "digital-petabyte", - "digital-terabit", - "digital-terabyte", - "duration-day", - "duration-hour", - "duration-millisecond", - "duration-minute", - "duration-month", - "duration-second", - "duration-week", - "duration-year", - "length-centimeter", - "length-foot", - "length-inch", - "length-kilometer", - "length-meter", - "length-mile-scandinavian", - "length-mile", - "length-millimeter", - "length-yard", - "mass-gram", - "mass-kilogram", - "mass-ounce", - "mass-pound", - "mass-stone", - "temperature-celsius", - "temperature-fahrenheit", - "volume-fluid-ounce", - "volume-gallon", - "volume-liter", - "volume-milliliter" - ]; - function removeUnitNamespace(unit) { - return unit.slice(unit.indexOf("-") + 1); - } - exports.removeUnitNamespace = removeUnitNamespace; - exports.SIMPLE_UNITS = exports.SANCTIONED_UNITS.map(removeUnitNamespace); - function IsSanctionedSimpleUnitIdentifier(unitIdentifier) { - return exports.SIMPLE_UNITS.indexOf(unitIdentifier) > -1; - } - exports.IsSanctionedSimpleUnitIdentifier = IsSanctionedSimpleUnitIdentifier; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsValidTimeZoneName.js - var require_IsValidTimeZoneName = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsValidTimeZoneName.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.IsValidTimeZoneName = void 0; - function IsValidTimeZoneName(tz, _a) { - var tzData = _a.tzData, uppercaseLinks = _a.uppercaseLinks; - var uppercasedTz = tz.toUpperCase(); - var zoneNames = /* @__PURE__ */ new Set(); - var linkNames = /* @__PURE__ */ new Set(); - Object.keys(tzData).map(function(z) { - return z.toUpperCase(); - }).forEach(function(z) { - return zoneNames.add(z); - }); - Object.keys(uppercaseLinks).forEach(function(linkName) { - linkNames.add(linkName.toUpperCase()); - zoneNames.add(uppercaseLinks[linkName].toUpperCase()); - }); - return zoneNames.has(uppercasedTz) || linkNames.has(uppercasedTz); - } - exports.IsValidTimeZoneName = IsValidTimeZoneName; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsWellFormedCurrencyCode.js - var require_IsWellFormedCurrencyCode = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsWellFormedCurrencyCode.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.IsWellFormedCurrencyCode = void 0; - function toUpperCase(str) { - return str.replace(/([a-z])/g, function(_, c) { - return c.toUpperCase(); - }); - } - var NOT_A_Z_REGEX = /[^A-Z]/; - function IsWellFormedCurrencyCode(currency) { - currency = toUpperCase(currency); - if (currency.length !== 3) { - return false; - } - if (NOT_A_Z_REGEX.test(currency)) { - return false; - } - return true; - } - exports.IsWellFormedCurrencyCode = IsWellFormedCurrencyCode; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsWellFormedUnitIdentifier.js - var require_IsWellFormedUnitIdentifier = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/IsWellFormedUnitIdentifier.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.IsWellFormedUnitIdentifier = void 0; - var IsSanctionedSimpleUnitIdentifier_1 = require_IsSanctionedSimpleUnitIdentifier(); - function toLowerCase(str) { - return str.replace(/([A-Z])/g, function(_, c) { - return c.toLowerCase(); - }); - } - function IsWellFormedUnitIdentifier(unit) { - unit = toLowerCase(unit); - if ((0, IsSanctionedSimpleUnitIdentifier_1.IsSanctionedSimpleUnitIdentifier)(unit)) { - return true; - } - var units = unit.split("-per-"); - if (units.length !== 2) { - return false; - } - var numerator = units[0], denominator = units[1]; - if (!(0, IsSanctionedSimpleUnitIdentifier_1.IsSanctionedSimpleUnitIdentifier)(numerator) || !(0, IsSanctionedSimpleUnitIdentifier_1.IsSanctionedSimpleUnitIdentifier)(denominator)) { - return false; - } - return true; - } - exports.IsWellFormedUnitIdentifier = IsWellFormedUnitIdentifier; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ApplyUnsignedRoundingMode.js - var require_ApplyUnsignedRoundingMode = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ApplyUnsignedRoundingMode.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.ApplyUnsignedRoundingMode = void 0; - function ApplyUnsignedRoundingMode(x, r1, r2, unsignedRoundingMode) { - if (x === r1) - return r1; - if (unsignedRoundingMode === void 0) { - throw new Error("unsignedRoundingMode is mandatory"); - } - if (unsignedRoundingMode === "zero") { - return r1; - } - if (unsignedRoundingMode === "infinity") { - return r2; - } - var d1 = x - r1; - var d2 = r2 - x; - if (d1 < d2) { - return r1; - } - if (d2 < d1) { - return r2; - } - if (d1 !== d2) { - throw new Error("Unexpected error"); - } - if (unsignedRoundingMode === "half-zero") { - return r1; - } - if (unsignedRoundingMode === "half-infinity") { - return r2; - } - if (unsignedRoundingMode !== "half-even") { - throw new Error("Unexpected value for unsignedRoundingMode: ".concat(unsignedRoundingMode)); - } - var cardinality = r1 / (r2 - r1) % 2; - if (cardinality === 0) { - return r1; - } - return r2; - } - exports.ApplyUnsignedRoundingMode = ApplyUnsignedRoundingMode; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/CollapseNumberRange.js - var require_CollapseNumberRange = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/CollapseNumberRange.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.CollapseNumberRange = void 0; - function CollapseNumberRange(result) { - return result; - } - exports.CollapseNumberRange = CollapseNumberRange; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/utils.js - var require_utils = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/utils.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.invariant = exports.UNICODE_EXTENSION_SEQUENCE_REGEX = exports.defineProperty = exports.isLiteralPart = exports.getMultiInternalSlots = exports.getInternalSlot = exports.setMultiInternalSlots = exports.setInternalSlot = exports.repeat = exports.getMagnitude = void 0; - function getMagnitude(x) { - return Math.floor(Math.log(x) * Math.LOG10E); - } - exports.getMagnitude = getMagnitude; - function repeat(s, times) { - if (typeof s.repeat === "function") { - return s.repeat(times); - } - var arr = new Array(times); - for (var i = 0; i < arr.length; i++) { - arr[i] = s; - } - return arr.join(""); - } - exports.repeat = repeat; - function setInternalSlot(map, pl, field, value) { - if (!map.get(pl)) { - map.set(pl, /* @__PURE__ */ Object.create(null)); - } - var slots = map.get(pl); - slots[field] = value; - } - exports.setInternalSlot = setInternalSlot; - function setMultiInternalSlots(map, pl, props) { - for (var _i = 0, _a = Object.keys(props); _i < _a.length; _i++) { - var k = _a[_i]; - setInternalSlot(map, pl, k, props[k]); - } - } - exports.setMultiInternalSlots = setMultiInternalSlots; - function getInternalSlot(map, pl, field) { - return getMultiInternalSlots(map, pl, field)[field]; - } - exports.getInternalSlot = getInternalSlot; - function getMultiInternalSlots(map, pl) { - var fields = []; - for (var _i = 2; _i < arguments.length; _i++) { - fields[_i - 2] = arguments[_i]; - } - var slots = map.get(pl); - if (!slots) { - throw new TypeError("".concat(pl, " InternalSlot has not been initialized")); - } - return fields.reduce(function(all, f) { - all[f] = slots[f]; - return all; - }, /* @__PURE__ */ Object.create(null)); - } - exports.getMultiInternalSlots = getMultiInternalSlots; - function isLiteralPart(patternPart) { - return patternPart.type === "literal"; - } - exports.isLiteralPart = isLiteralPart; - function defineProperty(target, name, _a) { - var value = _a.value; - Object.defineProperty(target, name, { - configurable: true, - enumerable: false, - writable: true, - value - }); - } - exports.defineProperty = defineProperty; - exports.UNICODE_EXTENSION_SEQUENCE_REGEX = /-u(?:-[0-9a-z]{2,8})+/gi; - function invariant(condition, message, Err) { - if (Err === void 0) { - Err = Error; - } - if (!condition) { - throw new Err(message); - } - } - exports.invariant = invariant; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ComputeExponentForMagnitude.js - var require_ComputeExponentForMagnitude = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ComputeExponentForMagnitude.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.ComputeExponentForMagnitude = void 0; - function ComputeExponentForMagnitude(numberFormat, magnitude, _a) { - var getInternalSlots = _a.getInternalSlots; - var internalSlots = getInternalSlots(numberFormat); - var notation = internalSlots.notation, dataLocaleData = internalSlots.dataLocaleData, numberingSystem = internalSlots.numberingSystem; - switch (notation) { - case "standard": - return 0; - case "scientific": - return magnitude; - case "engineering": - return Math.floor(magnitude / 3) * 3; - default: { - var compactDisplay = internalSlots.compactDisplay, style = internalSlots.style, currencyDisplay = internalSlots.currencyDisplay; - var thresholdMap = void 0; - if (style === "currency" && currencyDisplay !== "name") { - var currency = dataLocaleData.numbers.currency[numberingSystem] || dataLocaleData.numbers.currency[dataLocaleData.numbers.nu[0]]; - thresholdMap = currency.short; - } else { - var decimal = dataLocaleData.numbers.decimal[numberingSystem] || dataLocaleData.numbers.decimal[dataLocaleData.numbers.nu[0]]; - thresholdMap = compactDisplay === "long" ? decimal.long : decimal.short; - } - if (!thresholdMap) { - return 0; - } - var num = String(Math.pow(10, magnitude)); - var thresholds = Object.keys(thresholdMap); - if (num < thresholds[0]) { - return 0; - } - if (num > thresholds[thresholds.length - 1]) { - return thresholds[thresholds.length - 1].length - 1; - } - var i = thresholds.indexOf(num); - if (i === -1) { - return 0; - } - var magnitudeKey = thresholds[i]; - var compactPattern = thresholdMap[magnitudeKey].other; - if (compactPattern === "0") { - return 0; - } - return magnitudeKey.length - thresholdMap[magnitudeKey].other.match(/0+/)[0].length; - } - } - } - exports.ComputeExponentForMagnitude = ComputeExponentForMagnitude; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ToRawPrecision.js - var require_ToRawPrecision = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ToRawPrecision.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.ToRawPrecision = void 0; - var utils_1 = require_utils(); - function ToRawPrecision(x, minPrecision, maxPrecision) { - var p = maxPrecision; - var m; - var e; - var xFinal; - if (x === 0) { - m = (0, utils_1.repeat)("0", p); - e = 0; - xFinal = 0; - } else { - var xToString = x.toString(); - var xToStringExponentIndex = xToString.indexOf("e"); - var _a = xToString.split("e"), xToStringMantissa = _a[0], xToStringExponent = _a[1]; - var xToStringMantissaWithoutDecimalPoint = xToStringMantissa.replace(".", ""); - if (xToStringExponentIndex >= 0 && xToStringMantissaWithoutDecimalPoint.length <= p) { - e = +xToStringExponent; - m = xToStringMantissaWithoutDecimalPoint + (0, utils_1.repeat)("0", p - xToStringMantissaWithoutDecimalPoint.length); - xFinal = x; - } else { - e = (0, utils_1.getMagnitude)(x); - var decimalPlaceOffset = e - p + 1; - var n = Math.round(adjustDecimalPlace(x, decimalPlaceOffset)); - if (adjustDecimalPlace(n, p - 1) >= 10) { - e = e + 1; - n = Math.floor(n / 10); - } - m = n.toString(); - xFinal = adjustDecimalPlace(n, p - 1 - e); - } - } - var int; - if (e >= p - 1) { - m = m + (0, utils_1.repeat)("0", e - p + 1); - int = e + 1; - } else if (e >= 0) { - m = "".concat(m.slice(0, e + 1), ".").concat(m.slice(e + 1)); - int = e + 1; - } else { - m = "0.".concat((0, utils_1.repeat)("0", -e - 1)).concat(m); - int = 1; - } - if (m.indexOf(".") >= 0 && maxPrecision > minPrecision) { - var cut = maxPrecision - minPrecision; - while (cut > 0 && m[m.length - 1] === "0") { - m = m.slice(0, -1); - cut--; - } - if (m[m.length - 1] === ".") { - m = m.slice(0, -1); - } - } - return { formattedString: m, roundedNumber: xFinal, integerDigitsCount: int }; - function adjustDecimalPlace(x2, magnitude) { - return magnitude < 0 ? x2 * Math.pow(10, -magnitude) : x2 / Math.pow(10, magnitude); - } - } - exports.ToRawPrecision = ToRawPrecision; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ToRawFixed.js - var require_ToRawFixed = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ToRawFixed.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.ToRawFixed = void 0; - var utils_1 = require_utils(); - function ToRawFixed(x, minFraction, maxFraction) { - var f = maxFraction; - var n = Math.round(x * Math.pow(10, f)); - var xFinal = n / Math.pow(10, f); - var m; - if (n < 1e21) { - m = n.toString(); - } else { - m = n.toString(); - var _a = m.split("e"), mantissa = _a[0], exponent = _a[1]; - m = mantissa.replace(".", ""); - m = m + (0, utils_1.repeat)("0", Math.max(+exponent - m.length + 1, 0)); - } - var int; - if (f !== 0) { - var k = m.length; - if (k <= f) { - var z = (0, utils_1.repeat)("0", f + 1 - k); - m = z + m; - k = f + 1; - } - var a = m.slice(0, k - f); - var b = m.slice(k - f); - m = "".concat(a, ".").concat(b); - int = a.length; - } else { - int = m.length; - } - var cut = maxFraction - minFraction; - while (cut > 0 && m[m.length - 1] === "0") { - m = m.slice(0, -1); - cut--; - } - if (m[m.length - 1] === ".") { - m = m.slice(0, -1); - } - return { formattedString: m, roundedNumber: xFinal, integerDigitsCount: int }; - } - exports.ToRawFixed = ToRawFixed; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatNumericToString.js - var require_FormatNumericToString = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatNumericToString.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.FormatNumericToString = void 0; - var _262_1 = require__(); - var ToRawPrecision_1 = require_ToRawPrecision(); - var utils_1 = require_utils(); - var ToRawFixed_1 = require_ToRawFixed(); - function FormatNumericToString(intlObject, x) { - var isNegative = x < 0 || (0, _262_1.SameValue)(x, -0); - if (isNegative) { - x = -x; - } - var result; - var rourndingType = intlObject.roundingType; - switch (rourndingType) { - case "significantDigits": - result = (0, ToRawPrecision_1.ToRawPrecision)(x, intlObject.minimumSignificantDigits, intlObject.maximumSignificantDigits); - break; - case "fractionDigits": - result = (0, ToRawFixed_1.ToRawFixed)(x, intlObject.minimumFractionDigits, intlObject.maximumFractionDigits); - break; - default: - result = (0, ToRawPrecision_1.ToRawPrecision)(x, 1, 2); - if (result.integerDigitsCount > 1) { - result = (0, ToRawFixed_1.ToRawFixed)(x, 0, 0); - } - break; - } - x = result.roundedNumber; - var string = result.formattedString; - var int = result.integerDigitsCount; - var minInteger = intlObject.minimumIntegerDigits; - if (int < minInteger) { - var forwardZeros = (0, utils_1.repeat)("0", minInteger - int); - string = forwardZeros + string; - } - if (isNegative) { - x = -x; - } - return { roundedNumber: x, formattedString: string }; - } - exports.FormatNumericToString = FormatNumericToString; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ComputeExponent.js - var require_ComputeExponent = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/ComputeExponent.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.ComputeExponent = void 0; - var utils_1 = require_utils(); - var ComputeExponentForMagnitude_1 = require_ComputeExponentForMagnitude(); - var FormatNumericToString_1 = require_FormatNumericToString(); - function ComputeExponent(numberFormat, x, _a) { - var getInternalSlots = _a.getInternalSlots; - if (x === 0) { - return [0, 0]; - } - if (x < 0) { - x = -x; - } - var magnitude = (0, utils_1.getMagnitude)(x); - var exponent = (0, ComputeExponentForMagnitude_1.ComputeExponentForMagnitude)(numberFormat, magnitude, { - getInternalSlots - }); - x = exponent < 0 ? x * Math.pow(10, -exponent) : x / Math.pow(10, exponent); - var formatNumberResult = (0, FormatNumericToString_1.FormatNumericToString)(getInternalSlots(numberFormat), x); - if (formatNumberResult.roundedNumber === 0) { - return [exponent, magnitude]; - } - var newMagnitude = (0, utils_1.getMagnitude)(formatNumberResult.roundedNumber); - if (newMagnitude === magnitude - exponent) { - return [exponent, magnitude]; - } - return [ - (0, ComputeExponentForMagnitude_1.ComputeExponentForMagnitude)(numberFormat, magnitude + 1, { - getInternalSlots - }), - magnitude + 1 - ]; - } - exports.ComputeExponent = ComputeExponent; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/CurrencyDigits.js - var require_CurrencyDigits = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/CurrencyDigits.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.CurrencyDigits = void 0; - var _262_1 = require__(); - function CurrencyDigits(c, _a) { - var currencyDigitsData = _a.currencyDigitsData; - return (0, _262_1.HasOwnProperty)(currencyDigitsData, c) ? currencyDigitsData[c] : 2; - } - exports.CurrencyDigits = CurrencyDigits; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatApproximately.js - var require_FormatApproximately = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatApproximately.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.FormatApproximately = void 0; - function FormatApproximately(numberFormat, result, _a) { - var getInternalSlots = _a.getInternalSlots; - var internalSlots = getInternalSlots(numberFormat); - var symbols = internalSlots.dataLocaleData.numbers.symbols[internalSlots.numberingSystem]; - var approximatelySign = symbols.approximatelySign; - result.push({ type: "approximatelySign", value: approximatelySign }); - return result; - } - exports.FormatApproximately = FormatApproximately; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/digit-mapping.generated.js - var require_digit_mapping_generated = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/digit-mapping.generated.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.digitMapping = void 0; - exports.digitMapping = { "adlm": ["\u{1E950}", "\u{1E951}", "\u{1E952}", "\u{1E953}", "\u{1E954}", "\u{1E955}", "\u{1E956}", "\u{1E957}", "\u{1E958}", "\u{1E959}"], "ahom": ["\u{11730}", "\u{11731}", "\u{11732}", "\u{11733}", "\u{11734}", "\u{11735}", "\u{11736}", "\u{11737}", "\u{11738}", "\u{11739}"], "arab": ["\u0660", "\u0661", "\u0662", "\u0663", "\u0664", "\u0665", "\u0666", "\u0667", "\u0668", "\u0669"], "arabext": ["\u06F0", "\u06F1", "\u06F2", "\u06F3", "\u06F4", "\u06F5", "\u06F6", "\u06F7", "\u06F8", "\u06F9"], "bali": ["\u1B50", "\u1B51", "\u1B52", "\u1B53", "\u1B54", "\u1B55", "\u1B56", "\u1B57", "\u1B58", "\u1B59"], "beng": ["\u09E6", "\u09E7", "\u09E8", "\u09E9", "\u09EA", "\u09EB", "\u09EC", "\u09ED", "\u09EE", "\u09EF"], "bhks": ["\u{11C50}", "\u{11C51}", "\u{11C52}", "\u{11C53}", "\u{11C54}", "\u{11C55}", "\u{11C56}", "\u{11C57}", "\u{11C58}", "\u{11C59}"], "brah": ["\u{11066}", "\u{11067}", "\u{11068}", "\u{11069}", "\u{1106A}", "\u{1106B}", "\u{1106C}", "\u{1106D}", "\u{1106E}", "\u{1106F}"], "cakm": ["\u{11136}", "\u{11137}", "\u{11138}", "\u{11139}", "\u{1113A}", "\u{1113B}", "\u{1113C}", "\u{1113D}", "\u{1113E}", "\u{1113F}"], "cham": ["\uAA50", "\uAA51", "\uAA52", "\uAA53", "\uAA54", "\uAA55", "\uAA56", "\uAA57", "\uAA58", "\uAA59"], "deva": ["\u0966", "\u0967", "\u0968", "\u0969", "\u096A", "\u096B", "\u096C", "\u096D", "\u096E", "\u096F"], "diak": ["\u{11950}", "\u{11951}", "\u{11952}", "\u{11953}", "\u{11954}", "\u{11955}", "\u{11956}", "\u{11957}", "\u{11958}", "\u{11959}"], "fullwide": ["\uFF10", "\uFF11", "\uFF12", "\uFF13", "\uFF14", "\uFF15", "\uFF16", "\uFF17", "\uFF18", "\uFF19"], "gong": ["\u{11DA0}", "\u{11DA1}", "\u{11DA2}", "\u{11DA3}", "\u{11DA4}", "\u{11DA5}", "\u{11DA6}", "\u{11DA7}", "\u{11DA8}", "\u{11DA9}"], "gonm": ["\u{11D50}", "\u{11D51}", "\u{11D52}", "\u{11D53}", "\u{11D54}", "\u{11D55}", "\u{11D56}", "\u{11D57}", "\u{11D58}", "\u{11D59}"], "gujr": ["\u0AE6", "\u0AE7", "\u0AE8", "\u0AE9", "\u0AEA", "\u0AEB", "\u0AEC", "\u0AED", "\u0AEE", "\u0AEF"], "guru": ["\u0A66", "\u0A67", "\u0A68", "\u0A69", "\u0A6A", "\u0A6B", "\u0A6C", "\u0A6D", "\u0A6E", "\u0A6F"], "hanidec": ["\u3007", "\u4E00", "\u4E8C", "\u4E09", "\u56DB", "\u4E94", "\u516D", "\u4E03", "\u516B", "\u4E5D"], "hmng": ["\u{16B50}", "\u{16B51}", "\u{16B52}", "\u{16B53}", "\u{16B54}", "\u{16B55}", "\u{16B56}", "\u{16B57}", "\u{16B58}", "\u{16B59}"], "hmnp": ["\u{1E140}", "\u{1E141}", "\u{1E142}", "\u{1E143}", "\u{1E144}", "\u{1E145}", "\u{1E146}", "\u{1E147}", "\u{1E148}", "\u{1E149}"], "java": ["\uA9D0", "\uA9D1", "\uA9D2", "\uA9D3", "\uA9D4", "\uA9D5", "\uA9D6", "\uA9D7", "\uA9D8", "\uA9D9"], "kali": ["\uA900", "\uA901", "\uA902", "\uA903", "\uA904", "\uA905", "\uA906", "\uA907", "\uA908", "\uA909"], "khmr": ["\u17E0", "\u17E1", "\u17E2", "\u17E3", "\u17E4", "\u17E5", "\u17E6", "\u17E7", "\u17E8", "\u17E9"], "knda": ["\u0CE6", "\u0CE7", "\u0CE8", "\u0CE9", "\u0CEA", "\u0CEB", "\u0CEC", "\u0CED", "\u0CEE", "\u0CEF"], "lana": ["\u1A80", "\u1A81", "\u1A82", "\u1A83", "\u1A84", "\u1A85", "\u1A86", "\u1A87", "\u1A88", "\u1A89"], "lanatham": ["\u1A90", "\u1A91", "\u1A92", "\u1A93", "\u1A94", "\u1A95", "\u1A96", "\u1A97", "\u1A98", "\u1A99"], "laoo": ["\u0ED0", "\u0ED1", "\u0ED2", "\u0ED3", "\u0ED4", "\u0ED5", "\u0ED6", "\u0ED7", "\u0ED8", "\u0ED9"], "lepc": ["\u1A90", "\u1A91", "\u1A92", "\u1A93", "\u1A94", "\u1A95", "\u1A96", "\u1A97", "\u1A98", "\u1A99"], "limb": ["\u1946", "\u1947", "\u1948", "\u1949", "\u194A", "\u194B", "\u194C", "\u194D", "\u194E", "\u194F"], "mathbold": ["\u{1D7CE}", "\u{1D7CF}", "\u{1D7D0}", "\u{1D7D1}", "\u{1D7D2}", "\u{1D7D3}", "\u{1D7D4}", "\u{1D7D5}", "\u{1D7D6}", "\u{1D7D7}"], "mathdbl": ["\u{1D7D8}", "\u{1D7D9}", "\u{1D7DA}", "\u{1D7DB}", "\u{1D7DC}", "\u{1D7DD}", "\u{1D7DE}", "\u{1D7DF}", "\u{1D7E0}", "\u{1D7E1}"], "mathmono": ["\u{1D7F6}", "\u{1D7F7}", "\u{1D7F8}", "\u{1D7F9}", "\u{1D7FA}", "\u{1D7FB}", "\u{1D7FC}", "\u{1D7FD}", "\u{1D7FE}", "\u{1D7FF}"], "mathsanb": ["\u{1D7EC}", "\u{1D7ED}", "\u{1D7EE}", "\u{1D7EF}", "\u{1D7F0}", "\u{1D7F1}", "\u{1D7F2}", "\u{1D7F3}", "\u{1D7F4}", "\u{1D7F5}"], "mathsans": ["\u{1D7E2}", "\u{1D7E3}", "\u{1D7E4}", "\u{1D7E5}", "\u{1D7E6}", "\u{1D7E7}", "\u{1D7E8}", "\u{1D7E9}", "\u{1D7EA}", "\u{1D7EB}"], "mlym": ["\u0D66", "\u0D67", "\u0D68", "\u0D69", "\u0D6A", "\u0D6B", "\u0D6C", "\u0D6D", "\u0D6E", "\u0D6F"], "modi": ["\u{11650}", "\u{11651}", "\u{11652}", "\u{11653}", "\u{11654}", "\u{11655}", "\u{11656}", "\u{11657}", "\u{11658}", "\u{11659}"], "mong": ["\u1810", "\u1811", "\u1812", "\u1813", "\u1814", "\u1815", "\u1816", "\u1817", "\u1818", "\u1819"], "mroo": ["\u{16A60}", "\u{16A61}", "\u{16A62}", "\u{16A63}", "\u{16A64}", "\u{16A65}", "\u{16A66}", "\u{16A67}", "\u{16A68}", "\u{16A69}"], "mtei": ["\uABF0", "\uABF1", "\uABF2", "\uABF3", "\uABF4", "\uABF5", "\uABF6", "\uABF7", "\uABF8", "\uABF9"], "mymr": ["\u1040", "\u1041", "\u1042", "\u1043", "\u1044", "\u1045", "\u1046", "\u1047", "\u1048", "\u1049"], "mymrshan": ["\u1090", "\u1091", "\u1092", "\u1093", "\u1094", "\u1095", "\u1096", "\u1097", "\u1098", "\u1099"], "mymrtlng": ["\uA9F0", "\uA9F1", "\uA9F2", "\uA9F3", "\uA9F4", "\uA9F5", "\uA9F6", "\uA9F7", "\uA9F8", "\uA9F9"], "newa": ["\u{11450}", "\u{11451}", "\u{11452}", "\u{11453}", "\u{11454}", "\u{11455}", "\u{11456}", "\u{11457}", "\u{11458}", "\u{11459}"], "nkoo": ["\u07C0", "\u07C1", "\u07C2", "\u07C3", "\u07C4", "\u07C5", "\u07C6", "\u07C7", "\u07C8", "\u07C9"], "olck": ["\u1C50", "\u1C51", "\u1C52", "\u1C53", "\u1C54", "\u1C55", "\u1C56", "\u1C57", "\u1C58", "\u1C59"], "orya": ["\u0B66", "\u0B67", "\u0B68", "\u0B69", "\u0B6A", "\u0B6B", "\u0B6C", "\u0B6D", "\u0B6E", "\u0B6F"], "osma": ["\u{104A0}", "\u{104A1}", "\u{104A2}", "\u{104A3}", "\u{104A4}", "\u{104A5}", "\u{104A6}", "\u{104A7}", "\u{104A8}", "\u{104A9}"], "rohg": ["\u{10D30}", "\u{10D31}", "\u{10D32}", "\u{10D33}", "\u{10D34}", "\u{10D35}", "\u{10D36}", "\u{10D37}", "\u{10D38}", "\u{10D39}"], "saur": ["\uA8D0", "\uA8D1", "\uA8D2", "\uA8D3", "\uA8D4", "\uA8D5", "\uA8D6", "\uA8D7", "\uA8D8", "\uA8D9"], "segment": ["\u{1FBF0}", "\u{1FBF1}", "\u{1FBF2}", "\u{1FBF3}", "\u{1FBF4}", "\u{1FBF5}", "\u{1FBF6}", "\u{1FBF7}", "\u{1FBF8}", "\u{1FBF9}"], "shrd": ["\u{111D0}", "\u{111D1}", "\u{111D2}", "\u{111D3}", "\u{111D4}", "\u{111D5}", "\u{111D6}", "\u{111D7}", "\u{111D8}", "\u{111D9}"], "sind": ["\u{112F0}", "\u{112F1}", "\u{112F2}", "\u{112F3}", "\u{112F4}", "\u{112F5}", "\u{112F6}", "\u{112F7}", "\u{112F8}", "\u{112F9}"], "sinh": ["\u0DE6", "\u0DE7", "\u0DE8", "\u0DE9", "\u0DEA", "\u0DEB", "\u0DEC", "\u0DED", "\u0DEE", "\u0DEF"], "sora": ["\u{110F0}", "\u{110F1}", "\u{110F2}", "\u{110F3}", "\u{110F4}", "\u{110F5}", "\u{110F6}", "\u{110F7}", "\u{110F8}", "\u{110F9}"], "sund": ["\u1BB0", "\u1BB1", "\u1BB2", "\u1BB3", "\u1BB4", "\u1BB5", "\u1BB6", "\u1BB7", "\u1BB8", "\u1BB9"], "takr": ["\u{116C0}", "\u{116C1}", "\u{116C2}", "\u{116C3}", "\u{116C4}", "\u{116C5}", "\u{116C6}", "\u{116C7}", "\u{116C8}", "\u{116C9}"], "talu": ["\u19D0", "\u19D1", "\u19D2", "\u19D3", "\u19D4", "\u19D5", "\u19D6", "\u19D7", "\u19D8", "\u19D9"], "tamldec": ["\u0BE6", "\u0BE7", "\u0BE8", "\u0BE9", "\u0BEA", "\u0BEB", "\u0BEC", "\u0BED", "\u0BEE", "\u0BEF"], "telu": ["\u0C66", "\u0C67", "\u0C68", "\u0C69", "\u0C6A", "\u0C6B", "\u0C6C", "\u0C6D", "\u0C6E", "\u0C6F"], "thai": ["\u0E50", "\u0E51", "\u0E52", "\u0E53", "\u0E54", "\u0E55", "\u0E56", "\u0E57", "\u0E58", "\u0E59"], "tibt": ["\u0F20", "\u0F21", "\u0F22", "\u0F23", "\u0F24", "\u0F25", "\u0F26", "\u0F27", "\u0F28", "\u0F29"], "tirh": ["\u{114D0}", "\u{114D1}", "\u{114D2}", "\u{114D3}", "\u{114D4}", "\u{114D5}", "\u{114D6}", "\u{114D7}", "\u{114D8}", "\u{114D9}"], "vaii": ["\u1620", "\u1621", "\u1622", "\u1623", "\u1624", "\u1625", "\u1626", "\u1627", "\u1628", "\u1629"], "wara": ["\u{118E0}", "\u{118E1}", "\u{118E2}", "\u{118E3}", "\u{118E4}", "\u{118E5}", "\u{118E6}", "\u{118E7}", "\u{118E8}", "\u{118E9}"], "wcho": ["\u{1E2F0}", "\u{1E2F1}", "\u{1E2F2}", "\u{1E2F3}", "\u{1E2F4}", "\u{1E2F5}", "\u{1E2F6}", "\u{1E2F7}", "\u{1E2F8}", "\u{1E2F9}"] }; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/regex.generated.js - var require_regex_generated = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/regex.generated.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.S_UNICODE_REGEX = void 0; - exports.S_UNICODE_REGEX = /[\$\+<->\^`\|~\xA2-\xA6\xA8\xA9\xAC\xAE-\xB1\xB4\xB8\xD7\xF7\u02C2-\u02C5\u02D2-\u02DF\u02E5-\u02EB\u02ED\u02EF-\u02FF\u0375\u0384\u0385\u03F6\u0482\u058D-\u058F\u0606-\u0608\u060B\u060E\u060F\u06DE\u06E9\u06FD\u06FE\u07F6\u07FE\u07FF\u09F2\u09F3\u09FA\u09FB\u0AF1\u0B70\u0BF3-\u0BFA\u0C7F\u0D4F\u0D79\u0E3F\u0F01-\u0F03\u0F13\u0F15-\u0F17\u0F1A-\u0F1F\u0F34\u0F36\u0F38\u0FBE-\u0FC5\u0FC7-\u0FCC\u0FCE\u0FCF\u0FD5-\u0FD8\u109E\u109F\u1390-\u1399\u166D\u17DB\u1940\u19DE-\u19FF\u1B61-\u1B6A\u1B74-\u1B7C\u1FBD\u1FBF-\u1FC1\u1FCD-\u1FCF\u1FDD-\u1FDF\u1FED-\u1FEF\u1FFD\u1FFE\u2044\u2052\u207A-\u207C\u208A-\u208C\u20A0-\u20BF\u2100\u2101\u2103-\u2106\u2108\u2109\u2114\u2116-\u2118\u211E-\u2123\u2125\u2127\u2129\u212E\u213A\u213B\u2140-\u2144\u214A-\u214D\u214F\u218A\u218B\u2190-\u2307\u230C-\u2328\u232B-\u2426\u2440-\u244A\u249C-\u24E9\u2500-\u2767\u2794-\u27C4\u27C7-\u27E5\u27F0-\u2982\u2999-\u29D7\u29DC-\u29FB\u29FE-\u2B73\u2B76-\u2B95\u2B97-\u2BFF\u2CE5-\u2CEA\u2E50\u2E51\u2E80-\u2E99\u2E9B-\u2EF3\u2F00-\u2FD5\u2FF0-\u2FFB\u3004\u3012\u3013\u3020\u3036\u3037\u303E\u303F\u309B\u309C\u3190\u3191\u3196-\u319F\u31C0-\u31E3\u3200-\u321E\u322A-\u3247\u3250\u3260-\u327F\u328A-\u32B0\u32C0-\u33FF\u4DC0-\u4DFF\uA490-\uA4C6\uA700-\uA716\uA720\uA721\uA789\uA78A\uA828-\uA82B\uA836-\uA839\uAA77-\uAA79\uAB5B\uAB6A\uAB6B\uFB29\uFBB2-\uFBC1\uFDFC\uFDFD\uFE62\uFE64-\uFE66\uFE69\uFF04\uFF0B\uFF1C-\uFF1E\uFF3E\uFF40\uFF5C\uFF5E\uFFE0-\uFFE6\uFFE8-\uFFEE\uFFFC\uFFFD]|\uD800[\uDD37-\uDD3F\uDD79-\uDD89\uDD8C-\uDD8E\uDD90-\uDD9C\uDDA0\uDDD0-\uDDFC]|\uD802[\uDC77\uDC78\uDEC8]|\uD805\uDF3F|\uD807[\uDFD5-\uDFF1]|\uD81A[\uDF3C-\uDF3F\uDF45]|\uD82F\uDC9C|\uD834[\uDC00-\uDCF5\uDD00-\uDD26\uDD29-\uDD64\uDD6A-\uDD6C\uDD83\uDD84\uDD8C-\uDDA9\uDDAE-\uDDE8\uDE00-\uDE41\uDE45\uDF00-\uDF56]|\uD835[\uDEC1\uDEDB\uDEFB\uDF15\uDF35\uDF4F\uDF6F\uDF89\uDFA9\uDFC3]|\uD836[\uDC00-\uDDFF\uDE37-\uDE3A\uDE6D-\uDE74\uDE76-\uDE83\uDE85\uDE86]|\uD838[\uDD4F\uDEFF]|\uD83B[\uDCAC\uDCB0\uDD2E\uDEF0\uDEF1]|\uD83C[\uDC00-\uDC2B\uDC30-\uDC93\uDCA0-\uDCAE\uDCB1-\uDCBF\uDCC1-\uDCCF\uDCD1-\uDCF5\uDD0D-\uDDAD\uDDE6-\uDE02\uDE10-\uDE3B\uDE40-\uDE48\uDE50\uDE51\uDE60-\uDE65\uDF00-\uDFFF]|\uD83D[\uDC00-\uDED7\uDEE0-\uDEEC\uDEF0-\uDEFC\uDF00-\uDF73\uDF80-\uDFD8\uDFE0-\uDFEB]|\uD83E[\uDC00-\uDC0B\uDC10-\uDC47\uDC50-\uDC59\uDC60-\uDC87\uDC90-\uDCAD\uDCB0\uDCB1\uDD00-\uDD78\uDD7A-\uDDCB\uDDCD-\uDE53\uDE60-\uDE6D\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6\uDF00-\uDF92\uDF94-\uDFCA]/; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/format_to_parts.js - var require_format_to_parts = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/format_to_parts.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var ToRawFixed_1 = require_ToRawFixed(); - var digit_mapping_generated_1 = require_digit_mapping_generated(); - var regex_generated_1 = require_regex_generated(); - var CARET_S_UNICODE_REGEX = new RegExp("^".concat(regex_generated_1.S_UNICODE_REGEX.source)); - var S_DOLLAR_UNICODE_REGEX = new RegExp("".concat(regex_generated_1.S_UNICODE_REGEX.source, "$")); - var CLDR_NUMBER_PATTERN = /[#0](?:[\.,][#0]+)*/g; - function formatToParts(numberResult, data, pl, options) { - var sign = numberResult.sign, exponent = numberResult.exponent, magnitude = numberResult.magnitude; - var notation = options.notation, style = options.style, numberingSystem = options.numberingSystem; - var defaultNumberingSystem = data.numbers.nu[0]; - var compactNumberPattern = null; - if (notation === "compact" && magnitude) { - compactNumberPattern = getCompactDisplayPattern(numberResult, pl, data, style, options.compactDisplay, options.currencyDisplay, numberingSystem); - } - var nonNameCurrencyPart; - if (style === "currency" && options.currencyDisplay !== "name") { - var byCurrencyDisplay = data.currencies[options.currency]; - if (byCurrencyDisplay) { - switch (options.currencyDisplay) { - case "code": - nonNameCurrencyPart = options.currency; - break; - case "symbol": - nonNameCurrencyPart = byCurrencyDisplay.symbol; - break; - default: - nonNameCurrencyPart = byCurrencyDisplay.narrow; - break; - } - } else { - nonNameCurrencyPart = options.currency; - } - } - var numberPattern; - if (!compactNumberPattern) { - if (style === "decimal" || style === "unit" || style === "currency" && options.currencyDisplay === "name") { - var decimalData = data.numbers.decimal[numberingSystem] || data.numbers.decimal[defaultNumberingSystem]; - numberPattern = getPatternForSign(decimalData.standard, sign); - } else if (style === "currency") { - var currencyData = data.numbers.currency[numberingSystem] || data.numbers.currency[defaultNumberingSystem]; - numberPattern = getPatternForSign(currencyData[options.currencySign], sign); - } else { - var percentPattern = data.numbers.percent[numberingSystem] || data.numbers.percent[defaultNumberingSystem]; - numberPattern = getPatternForSign(percentPattern, sign); - } - } else { - numberPattern = compactNumberPattern; - } - var decimalNumberPattern = CLDR_NUMBER_PATTERN.exec(numberPattern)[0]; - numberPattern = numberPattern.replace(CLDR_NUMBER_PATTERN, "{0}").replace(/'(.)'/g, "$1"); - if (style === "currency" && options.currencyDisplay !== "name") { - var currencyData = data.numbers.currency[numberingSystem] || data.numbers.currency[defaultNumberingSystem]; - var afterCurrency = currencyData.currencySpacing.afterInsertBetween; - if (afterCurrency && !S_DOLLAR_UNICODE_REGEX.test(nonNameCurrencyPart)) { - numberPattern = numberPattern.replace("\xA4{0}", "\xA4".concat(afterCurrency, "{0}")); - } - var beforeCurrency = currencyData.currencySpacing.beforeInsertBetween; - if (beforeCurrency && !CARET_S_UNICODE_REGEX.test(nonNameCurrencyPart)) { - numberPattern = numberPattern.replace("{0}\xA4", "{0}".concat(beforeCurrency, "\xA4")); - } - } - var numberPatternParts = numberPattern.split(/({c:[^}]+}|\{0\}|[¤%\-\+])/g); - var numberParts = []; - var symbols = data.numbers.symbols[numberingSystem] || data.numbers.symbols[defaultNumberingSystem]; - for (var _i = 0, numberPatternParts_1 = numberPatternParts; _i < numberPatternParts_1.length; _i++) { - var part = numberPatternParts_1[_i]; - if (!part) { - continue; - } - switch (part) { - case "{0}": { - numberParts.push.apply(numberParts, paritionNumberIntoParts( - symbols, - numberResult, - notation, - exponent, - numberingSystem, - // If compact number pattern exists, do not insert group separators. - !compactNumberPattern && Boolean(options.useGrouping), - decimalNumberPattern - )); - break; - } - case "-": - numberParts.push({ type: "minusSign", value: symbols.minusSign }); - break; - case "+": - numberParts.push({ type: "plusSign", value: symbols.plusSign }); - break; - case "%": - numberParts.push({ type: "percentSign", value: symbols.percentSign }); - break; - case "\xA4": - numberParts.push({ type: "currency", value: nonNameCurrencyPart }); - break; - default: - if (/^\{c:/.test(part)) { - numberParts.push({ - type: "compact", - value: part.substring(3, part.length - 1) - }); - } else { - numberParts.push({ type: "literal", value: part }); - } - break; - } - } - switch (style) { - case "currency": { - if (options.currencyDisplay === "name") { - var unitPattern = (data.numbers.currency[numberingSystem] || data.numbers.currency[defaultNumberingSystem]).unitPattern; - var unitName = void 0; - var currencyNameData = data.currencies[options.currency]; - if (currencyNameData) { - unitName = selectPlural(pl, numberResult.roundedNumber * Math.pow(10, exponent), currencyNameData.displayName); - } else { - unitName = options.currency; - } - var unitPatternParts = unitPattern.split(/(\{[01]\})/g); - var result = []; - for (var _a = 0, unitPatternParts_1 = unitPatternParts; _a < unitPatternParts_1.length; _a++) { - var part = unitPatternParts_1[_a]; - switch (part) { - case "{0}": - result.push.apply(result, numberParts); - break; - case "{1}": - result.push({ type: "currency", value: unitName }); - break; - default: - if (part) { - result.push({ type: "literal", value: part }); - } - break; - } - } - return result; - } else { - return numberParts; - } - } - case "unit": { - var unit = options.unit, unitDisplay = options.unitDisplay; - var unitData = data.units.simple[unit]; - var unitPattern = void 0; - if (unitData) { - unitPattern = selectPlural(pl, numberResult.roundedNumber * Math.pow(10, exponent), data.units.simple[unit][unitDisplay]); - } else { - var _b = unit.split("-per-"), numeratorUnit = _b[0], denominatorUnit = _b[1]; - unitData = data.units.simple[numeratorUnit]; - var numeratorUnitPattern = selectPlural(pl, numberResult.roundedNumber * Math.pow(10, exponent), data.units.simple[numeratorUnit][unitDisplay]); - var perUnitPattern = data.units.simple[denominatorUnit].perUnit[unitDisplay]; - if (perUnitPattern) { - unitPattern = perUnitPattern.replace("{0}", numeratorUnitPattern); - } else { - var perPattern = data.units.compound.per[unitDisplay]; - var denominatorPattern = selectPlural(pl, 1, data.units.simple[denominatorUnit][unitDisplay]); - unitPattern = unitPattern = perPattern.replace("{0}", numeratorUnitPattern).replace("{1}", denominatorPattern.replace("{0}", "")); - } - } - var result = []; - for (var _c = 0, _d = unitPattern.split(/(\s*\{0\}\s*)/); _c < _d.length; _c++) { - var part = _d[_c]; - var interpolateMatch = /^(\s*)\{0\}(\s*)$/.exec(part); - if (interpolateMatch) { - if (interpolateMatch[1]) { - result.push({ type: "literal", value: interpolateMatch[1] }); - } - result.push.apply(result, numberParts); - if (interpolateMatch[2]) { - result.push({ type: "literal", value: interpolateMatch[2] }); - } - } else if (part) { - result.push({ type: "unit", value: part }); - } - } - return result; - } - default: - return numberParts; - } - } - exports.default = formatToParts; - function paritionNumberIntoParts(symbols, numberResult, notation, exponent, numberingSystem, useGrouping, decimalNumberPattern) { - var result = []; - var n = numberResult.formattedString, x = numberResult.roundedNumber; - if (isNaN(x)) { - return [{ type: "nan", value: n }]; - } else if (!isFinite(x)) { - return [{ type: "infinity", value: n }]; - } - var digitReplacementTable = digit_mapping_generated_1.digitMapping[numberingSystem]; - if (digitReplacementTable) { - n = n.replace(/\d/g, function(digit) { - return digitReplacementTable[+digit] || digit; - }); - } - var decimalSepIndex = n.indexOf("."); - var integer; - var fraction; - if (decimalSepIndex > 0) { - integer = n.slice(0, decimalSepIndex); - fraction = n.slice(decimalSepIndex + 1); - } else { - integer = n; - } - if (useGrouping && (notation !== "compact" || x >= 1e4)) { - var groupSepSymbol = symbols.group; - var groups = []; - var integerNumberPattern = decimalNumberPattern.split(".")[0]; - var patternGroups = integerNumberPattern.split(","); - var primaryGroupingSize = 3; - var secondaryGroupingSize = 3; - if (patternGroups.length > 1) { - primaryGroupingSize = patternGroups[patternGroups.length - 1].length; - } - if (patternGroups.length > 2) { - secondaryGroupingSize = patternGroups[patternGroups.length - 2].length; - } - var i = integer.length - primaryGroupingSize; - if (i > 0) { - groups.push(integer.slice(i, i + primaryGroupingSize)); - for (i -= secondaryGroupingSize; i > 0; i -= secondaryGroupingSize) { - groups.push(integer.slice(i, i + secondaryGroupingSize)); - } - groups.push(integer.slice(0, i + secondaryGroupingSize)); - } else { - groups.push(integer); - } - while (groups.length > 0) { - var integerGroup = groups.pop(); - result.push({ type: "integer", value: integerGroup }); - if (groups.length > 0) { - result.push({ type: "group", value: groupSepSymbol }); - } - } - } else { - result.push({ type: "integer", value: integer }); - } - if (fraction !== void 0) { - result.push({ type: "decimal", value: symbols.decimal }, { type: "fraction", value: fraction }); - } - if ((notation === "scientific" || notation === "engineering") && isFinite(x)) { - result.push({ type: "exponentSeparator", value: symbols.exponential }); - if (exponent < 0) { - result.push({ type: "exponentMinusSign", value: symbols.minusSign }); - exponent = -exponent; - } - var exponentResult = (0, ToRawFixed_1.ToRawFixed)(exponent, 0, 0); - result.push({ - type: "exponentInteger", - value: exponentResult.formattedString - }); - } - return result; - } - function getPatternForSign(pattern, sign) { - if (pattern.indexOf(";") < 0) { - pattern = "".concat(pattern, ";-").concat(pattern); - } - var _a = pattern.split(";"), zeroPattern = _a[0], negativePattern = _a[1]; - switch (sign) { - case 0: - return zeroPattern; - case -1: - return negativePattern; - default: - return negativePattern.indexOf("-") >= 0 ? negativePattern.replace(/-/g, "+") : "+".concat(zeroPattern); - } - } - function getCompactDisplayPattern(numberResult, pl, data, style, compactDisplay, currencyDisplay, numberingSystem) { - var _a; - var roundedNumber = numberResult.roundedNumber, sign = numberResult.sign, magnitude = numberResult.magnitude; - var magnitudeKey = String(Math.pow(10, magnitude)); - var defaultNumberingSystem = data.numbers.nu[0]; - var pattern; - if (style === "currency" && currencyDisplay !== "name") { - var byNumberingSystem = data.numbers.currency; - var currencyData = byNumberingSystem[numberingSystem] || byNumberingSystem[defaultNumberingSystem]; - var compactPluralRules = (_a = currencyData.short) === null || _a === void 0 ? void 0 : _a[magnitudeKey]; - if (!compactPluralRules) { - return null; - } - pattern = selectPlural(pl, roundedNumber, compactPluralRules); - } else { - var byNumberingSystem = data.numbers.decimal; - var byCompactDisplay = byNumberingSystem[numberingSystem] || byNumberingSystem[defaultNumberingSystem]; - var compactPlaralRule = byCompactDisplay[compactDisplay][magnitudeKey]; - if (!compactPlaralRule) { - return null; - } - pattern = selectPlural(pl, roundedNumber, compactPlaralRule); - } - if (pattern === "0") { - return null; - } - pattern = getPatternForSign(pattern, sign).replace(/([^\s;\-\+\d¤]+)/g, "{c:$1}").replace(/0+/, "0"); - return pattern; - } - function selectPlural(pl, x, rules) { - return rules[pl.select(x)] || rules.other; - } - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/PartitionNumberPattern.js - var require_PartitionNumberPattern = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/PartitionNumberPattern.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.PartitionNumberPattern = void 0; - var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); - var FormatNumericToString_1 = require_FormatNumericToString(); - var _262_1 = require__(); - var ComputeExponent_1 = require_ComputeExponent(); - var format_to_parts_1 = tslib_1.__importDefault(require_format_to_parts()); - function PartitionNumberPattern(numberFormat, x, _a) { - var _b; - var getInternalSlots = _a.getInternalSlots; - var internalSlots = getInternalSlots(numberFormat); - var pl = internalSlots.pl, dataLocaleData = internalSlots.dataLocaleData, numberingSystem = internalSlots.numberingSystem; - var symbols = dataLocaleData.numbers.symbols[numberingSystem] || dataLocaleData.numbers.symbols[dataLocaleData.numbers.nu[0]]; - var magnitude = 0; - var exponent = 0; - var n; - if (isNaN(x)) { - n = symbols.nan; - } else if (x == Number.POSITIVE_INFINITY || x == Number.NEGATIVE_INFINITY) { - n = symbols.infinity; - } else { - if (!(0, _262_1.SameValue)(x, -0)) { - if (!isFinite(x)) { - throw new Error("Input must be a mathematical value"); - } - if (internalSlots.style == "percent") { - x *= 100; - } - ; - _b = (0, ComputeExponent_1.ComputeExponent)(numberFormat, x, { - getInternalSlots - }), exponent = _b[0], magnitude = _b[1]; - x = exponent < 0 ? x * Math.pow(10, -exponent) : x / Math.pow(10, exponent); - } - var formatNumberResult = (0, FormatNumericToString_1.FormatNumericToString)(internalSlots, x); - n = formatNumberResult.formattedString; - x = formatNumberResult.roundedNumber; - } - var sign; - var signDisplay = internalSlots.signDisplay; - switch (signDisplay) { - case "never": - sign = 0; - break; - case "auto": - if ((0, _262_1.SameValue)(x, 0) || x > 0 || isNaN(x)) { - sign = 0; - } else { - sign = -1; - } - break; - case "always": - if ((0, _262_1.SameValue)(x, 0) || x > 0 || isNaN(x)) { - sign = 1; - } else { - sign = -1; - } - break; - default: - if (x === 0 || isNaN(x)) { - sign = 0; - } else if (x > 0) { - sign = 1; - } else { - sign = -1; - } - } - return (0, format_to_parts_1.default)({ roundedNumber: x, formattedString: n, exponent, magnitude, sign }, internalSlots.dataLocaleData, pl, internalSlots); - } - exports.PartitionNumberPattern = PartitionNumberPattern; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatNumericToParts.js - var require_FormatNumericToParts = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/FormatNumericToParts.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.FormatNumericToParts = void 0; - var PartitionNumberPattern_1 = require_PartitionNumberPattern(); - var _262_1 = require__(); - function FormatNumericToParts(nf, x, implDetails) { - var parts = (0, PartitionNumberPattern_1.PartitionNumberPattern)(nf, x, implDetails); - var result = (0, _262_1.ArrayCreate)(0); - for (var _i = 0, parts_1 = parts; _i < parts_1.length; _i++) { - var part = parts_1[_i]; - result.push({ - type: part.type, - value: part.value - }); - } - return result; - } - exports.FormatNumericToParts = FormatNumericToParts; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/GetUnsignedRoundingMode.js - var require_GetUnsignedRoundingMode = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/GetUnsignedRoundingMode.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.GetUnsignedRoundingMode = void 0; - var negativeMapping = { - ceil: "zero", - floor: "infinity", - expand: "infinity", - trunc: "zero", - halfCeil: "half-zero", - halfFloor: "half-infinity", - halfExpand: "half-infinity", - halfTrunc: "half-zero", - halfEven: "half-even" - }; - var positiveMapping = { - ceil: "infinity", - floor: "zero", - expand: "infinity", - trunc: "zero", - halfCeil: "half-infinity", - halfFloor: "half-zero", - halfExpand: "half-infinity", - halfTrunc: "half-zero", - halfEven: "half-even" - }; - function GetUnsignedRoundingMode(roundingMode, isNegative) { - if (isNegative) { - return negativeMapping[roundingMode]; - } - return positiveMapping[roundingMode]; - } - exports.GetUnsignedRoundingMode = GetUnsignedRoundingMode; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/CanonicalizeLocaleList.js - var require_CanonicalizeLocaleList2 = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/CanonicalizeLocaleList.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.CanonicalizeLocaleList = void 0; - function CanonicalizeLocaleList(locales) { - return Intl.getCanonicalLocales(locales); - } - exports.CanonicalizeLocaleList = CanonicalizeLocaleList; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/utils.js - var require_utils2 = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/utils.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.invariant = exports.UNICODE_EXTENSION_SEQUENCE_REGEX = void 0; - exports.UNICODE_EXTENSION_SEQUENCE_REGEX = /-u(?:-[0-9a-z]{2,8})+/gi; - function invariant(condition, message, Err) { - if (Err === void 0) { - Err = Error; - } - if (!condition) { - throw new Err(message); - } - } - exports.invariant = invariant; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/BestAvailableLocale.js - var require_BestAvailableLocale = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/BestAvailableLocale.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.BestAvailableLocale = void 0; - function BestAvailableLocale(availableLocales, locale) { - var candidate = locale; - while (true) { - if (availableLocales.has(candidate)) { - return candidate; - } - var pos = candidate.lastIndexOf("-"); - if (!~pos) { - return void 0; - } - if (pos >= 2 && candidate[pos - 2] === "-") { - pos -= 2; - } - candidate = candidate.slice(0, pos); - } - } - exports.BestAvailableLocale = BestAvailableLocale; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/LookupMatcher.js - var require_LookupMatcher = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/LookupMatcher.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.LookupMatcher = void 0; - var utils_1 = require_utils2(); - var BestAvailableLocale_1 = require_BestAvailableLocale(); - function LookupMatcher(availableLocales, requestedLocales, getDefaultLocale) { - var result = { locale: "" }; - for (var _i = 0, requestedLocales_1 = requestedLocales; _i < requestedLocales_1.length; _i++) { - var locale = requestedLocales_1[_i]; - var noExtensionLocale = locale.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, ""); - var availableLocale = (0, BestAvailableLocale_1.BestAvailableLocale)(availableLocales, noExtensionLocale); - if (availableLocale) { - result.locale = availableLocale; - if (locale !== noExtensionLocale) { - result.extension = locale.slice(noExtensionLocale.length + 1, locale.length); - } - return result; - } - } - result.locale = getDefaultLocale(); - return result; - } - exports.LookupMatcher = LookupMatcher; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/BestFitMatcher.js - var require_BestFitMatcher = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/BestFitMatcher.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.BestFitMatcher = void 0; - var BestAvailableLocale_1 = require_BestAvailableLocale(); - var utils_1 = require_utils2(); - function BestFitMatcher(availableLocales, requestedLocales, getDefaultLocale) { - var minimizedAvailableLocaleMap = {}; - var availableLocaleMap = {}; - var canonicalizedLocaleMap = {}; - var minimizedAvailableLocales = /* @__PURE__ */ new Set(); - availableLocales.forEach(function(locale2) { - var minimizedLocale = new Intl.Locale(locale2).minimize().toString(); - var canonicalizedLocale = Intl.getCanonicalLocales(locale2)[0] || locale2; - minimizedAvailableLocaleMap[minimizedLocale] = locale2; - availableLocaleMap[locale2] = locale2; - canonicalizedLocaleMap[canonicalizedLocale] = locale2; - minimizedAvailableLocales.add(minimizedLocale); - minimizedAvailableLocales.add(locale2); - minimizedAvailableLocales.add(canonicalizedLocale); - }); - var foundLocale; - for (var _i = 0, requestedLocales_1 = requestedLocales; _i < requestedLocales_1.length; _i++) { - var l = requestedLocales_1[_i]; - if (foundLocale) { - break; - } - var noExtensionLocale = l.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, ""); - if (availableLocales.has(noExtensionLocale)) { - foundLocale = noExtensionLocale; - break; - } - if (minimizedAvailableLocales.has(noExtensionLocale)) { - foundLocale = noExtensionLocale; - break; - } - var locale = new Intl.Locale(noExtensionLocale); - var maximizedRequestedLocale = locale.maximize().toString(); - var minimizedRequestedLocale = locale.minimize().toString(); - if (minimizedAvailableLocales.has(minimizedRequestedLocale)) { - foundLocale = minimizedRequestedLocale; - break; - } - foundLocale = (0, BestAvailableLocale_1.BestAvailableLocale)(minimizedAvailableLocales, maximizedRequestedLocale); - } - if (!foundLocale) { - return { locale: getDefaultLocale() }; - } - return { - locale: availableLocaleMap[foundLocale] || canonicalizedLocaleMap[foundLocale] || minimizedAvailableLocaleMap[foundLocale] || foundLocale - }; - } - exports.BestFitMatcher = BestFitMatcher; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/UnicodeExtensionValue.js - var require_UnicodeExtensionValue = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/UnicodeExtensionValue.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.UnicodeExtensionValue = void 0; - var utils_1 = require_utils2(); - function UnicodeExtensionValue(extension, key) { - (0, utils_1.invariant)(key.length === 2, "key must have 2 elements"); - var size = extension.length; - var searchValue = "-".concat(key, "-"); - var pos = extension.indexOf(searchValue); - if (pos !== -1) { - var start = pos + 4; - var end = start; - var k = start; - var done = false; - while (!done) { - var e = extension.indexOf("-", k); - var len = void 0; - if (e === -1) { - len = size - k; - } else { - len = e - k; - } - if (len === 2) { - done = true; - } else if (e === -1) { - end = size; - done = true; - } else { - end = e; - k = e + 1; - } - } - return extension.slice(start, end); - } - searchValue = "-".concat(key); - pos = extension.indexOf(searchValue); - if (pos !== -1 && pos + 3 === size) { - return ""; - } - return void 0; - } - exports.UnicodeExtensionValue = UnicodeExtensionValue; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/ResolveLocale.js - var require_ResolveLocale = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/ResolveLocale.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.ResolveLocale = void 0; - var LookupMatcher_1 = require_LookupMatcher(); - var BestFitMatcher_1 = require_BestFitMatcher(); - var utils_1 = require_utils2(); - var UnicodeExtensionValue_1 = require_UnicodeExtensionValue(); - function ResolveLocale(availableLocales, requestedLocales, options, relevantExtensionKeys, localeData, getDefaultLocale) { - var matcher = options.localeMatcher; - var r; - if (matcher === "lookup") { - r = (0, LookupMatcher_1.LookupMatcher)(availableLocales, requestedLocales, getDefaultLocale); - } else { - r = (0, BestFitMatcher_1.BestFitMatcher)(availableLocales, requestedLocales, getDefaultLocale); - } - var foundLocale = r.locale; - var result = { locale: "", dataLocale: foundLocale }; - var supportedExtension = "-u"; - for (var _i = 0, relevantExtensionKeys_1 = relevantExtensionKeys; _i < relevantExtensionKeys_1.length; _i++) { - var key = relevantExtensionKeys_1[_i]; - (0, utils_1.invariant)(foundLocale in localeData, "Missing locale data for ".concat(foundLocale)); - var foundLocaleData = localeData[foundLocale]; - (0, utils_1.invariant)(typeof foundLocaleData === "object" && foundLocaleData !== null, "locale data ".concat(key, " must be an object")); - var keyLocaleData = foundLocaleData[key]; - (0, utils_1.invariant)(Array.isArray(keyLocaleData), "keyLocaleData for ".concat(key, " must be an array")); - var value = keyLocaleData[0]; - (0, utils_1.invariant)(typeof value === "string" || value === null, "value must be string or null but got ".concat(typeof value, " in key ").concat(key)); - var supportedExtensionAddition = ""; - if (r.extension) { - var requestedValue = (0, UnicodeExtensionValue_1.UnicodeExtensionValue)(r.extension, key); - if (requestedValue !== void 0) { - if (requestedValue !== "") { - if (~keyLocaleData.indexOf(requestedValue)) { - value = requestedValue; - supportedExtensionAddition = "-".concat(key, "-").concat(value); - } - } else if (~requestedValue.indexOf("true")) { - value = "true"; - supportedExtensionAddition = "-".concat(key); - } - } - } - if (key in options) { - var optionsValue = options[key]; - (0, utils_1.invariant)(typeof optionsValue === "string" || typeof optionsValue === "undefined" || optionsValue === null, "optionsValue must be String, Undefined or Null"); - if (~keyLocaleData.indexOf(optionsValue)) { - if (optionsValue !== value) { - value = optionsValue; - supportedExtensionAddition = ""; - } - } - } - result[key] = value; - supportedExtension += supportedExtensionAddition; - } - if (supportedExtension.length > 2) { - var privateIndex = foundLocale.indexOf("-x-"); - if (privateIndex === -1) { - foundLocale = foundLocale + supportedExtension; - } else { - var preExtension = foundLocale.slice(0, privateIndex); - var postExtension = foundLocale.slice(privateIndex, foundLocale.length); - foundLocale = preExtension + supportedExtension + postExtension; - } - foundLocale = Intl.getCanonicalLocales(foundLocale)[0]; - } - result.locale = foundLocale; - return result; - } - exports.ResolveLocale = ResolveLocale; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/LookupSupportedLocales.js - var require_LookupSupportedLocales = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/abstract/LookupSupportedLocales.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.LookupSupportedLocales = void 0; - var utils_1 = require_utils2(); - var BestAvailableLocale_1 = require_BestAvailableLocale(); - function LookupSupportedLocales(availableLocales, requestedLocales) { - var subset = []; - for (var _i = 0, requestedLocales_1 = requestedLocales; _i < requestedLocales_1.length; _i++) { - var locale = requestedLocales_1[_i]; - var noExtensionLocale = locale.replace(utils_1.UNICODE_EXTENSION_SEQUENCE_REGEX, ""); - var availableLocale = (0, BestAvailableLocale_1.BestAvailableLocale)(availableLocales, noExtensionLocale); - if (availableLocale) { - subset.push(availableLocale); - } - } - return subset; - } - exports.LookupSupportedLocales = LookupSupportedLocales; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/index.js - var require_intl_localematcher = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/intl-localematcher/index.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.ResolveLocale = exports.LookupSupportedLocales = exports.match = void 0; - var CanonicalizeLocaleList_1 = require_CanonicalizeLocaleList2(); - var ResolveLocale_1 = require_ResolveLocale(); - function match(requestedLocales, availableLocales, defaultLocale, opts) { - var locales = availableLocales.reduce(function(all, l) { - all.add(l); - return all; - }, /* @__PURE__ */ new Set()); - return (0, ResolveLocale_1.ResolveLocale)(locales, (0, CanonicalizeLocaleList_1.CanonicalizeLocaleList)(requestedLocales), { - localeMatcher: (opts === null || opts === void 0 ? void 0 : opts.algorithm) || "best fit" - }, [], {}, function() { - return defaultLocale; - }).locale; - } - exports.match = match; - var LookupSupportedLocales_1 = require_LookupSupportedLocales(); - Object.defineProperty(exports, "LookupSupportedLocales", { enumerable: true, get: function() { - return LookupSupportedLocales_1.LookupSupportedLocales; - } }); - var ResolveLocale_2 = require_ResolveLocale(); - Object.defineProperty(exports, "ResolveLocale", { enumerable: true, get: function() { - return ResolveLocale_2.ResolveLocale; - } }); - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/SetNumberFormatUnitOptions.js - var require_SetNumberFormatUnitOptions = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/SetNumberFormatUnitOptions.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.SetNumberFormatUnitOptions = void 0; - var GetOption_1 = require_GetOption(); - var IsWellFormedCurrencyCode_1 = require_IsWellFormedCurrencyCode(); - var IsWellFormedUnitIdentifier_1 = require_IsWellFormedUnitIdentifier(); - function SetNumberFormatUnitOptions(nf, options, _a) { - if (options === void 0) { - options = /* @__PURE__ */ Object.create(null); - } - var getInternalSlots = _a.getInternalSlots; - var internalSlots = getInternalSlots(nf); - var style = (0, GetOption_1.GetOption)(options, "style", "string", ["decimal", "percent", "currency", "unit"], "decimal"); - internalSlots.style = style; - var currency = (0, GetOption_1.GetOption)(options, "currency", "string", void 0, void 0); - if (currency !== void 0 && !(0, IsWellFormedCurrencyCode_1.IsWellFormedCurrencyCode)(currency)) { - throw RangeError("Malformed currency code"); - } - if (style === "currency" && currency === void 0) { - throw TypeError("currency cannot be undefined"); - } - var currencyDisplay = (0, GetOption_1.GetOption)(options, "currencyDisplay", "string", ["code", "symbol", "narrowSymbol", "name"], "symbol"); - var currencySign = (0, GetOption_1.GetOption)(options, "currencySign", "string", ["standard", "accounting"], "standard"); - var unit = (0, GetOption_1.GetOption)(options, "unit", "string", void 0, void 0); - if (unit !== void 0 && !(0, IsWellFormedUnitIdentifier_1.IsWellFormedUnitIdentifier)(unit)) { - throw RangeError("Invalid unit argument for Intl.NumberFormat()"); - } - if (style === "unit" && unit === void 0) { - throw TypeError("unit cannot be undefined"); - } - var unitDisplay = (0, GetOption_1.GetOption)(options, "unitDisplay", "string", ["short", "narrow", "long"], "short"); - if (style === "currency") { - internalSlots.currency = currency.toUpperCase(); - internalSlots.currencyDisplay = currencyDisplay; - internalSlots.currencySign = currencySign; - } - if (style === "unit") { - internalSlots.unit = unit; - internalSlots.unitDisplay = unitDisplay; - } - } - exports.SetNumberFormatUnitOptions = SetNumberFormatUnitOptions; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/SetNumberFormatDigitOptions.js - var require_SetNumberFormatDigitOptions = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/SetNumberFormatDigitOptions.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.SetNumberFormatDigitOptions = void 0; - var GetNumberOption_1 = require_GetNumberOption(); - var DefaultNumberOption_1 = require_DefaultNumberOption(); - var GetOption_1 = require_GetOption(); - function SetNumberFormatDigitOptions(internalSlots, opts, mnfdDefault, mxfdDefault, notation) { - var mnid = (0, GetNumberOption_1.GetNumberOption)(opts, "minimumIntegerDigits", 1, 21, 1); - var mnfd = opts.minimumFractionDigits; - var mxfd = opts.maximumFractionDigits; - var mnsd = opts.minimumSignificantDigits; - var mxsd = opts.maximumSignificantDigits; - internalSlots.minimumIntegerDigits = mnid; - var roundingPriority = (0, GetOption_1.GetOption)(opts, "roundingPriority", "string", ["auto", "morePrecision", "lessPrecision"], "auto"); - var hasSd = mnsd !== void 0 || mxsd !== void 0; - var hasFd = mnfd !== void 0 || mxfd !== void 0; - var needSd = true; - var needFd = true; - if (roundingPriority === "auto") { - needSd = hasSd; - if (hasSd || !hasFd && notation === "compact") { - needFd = false; - } - } - if (needSd) { - if (hasSd) { - mnsd = (0, DefaultNumberOption_1.DefaultNumberOption)(mnsd, 1, 21, 1); - mxsd = (0, DefaultNumberOption_1.DefaultNumberOption)(mxsd, mnsd, 21, 21); - internalSlots.minimumSignificantDigits = mnsd; - internalSlots.maximumSignificantDigits = mxsd; - } else { - internalSlots.minimumSignificantDigits = 1; - internalSlots.maximumSignificantDigits = 21; - } - } - if (needFd) { - if (hasFd) { - mnfd = (0, DefaultNumberOption_1.DefaultNumberOption)(mnfd, 0, 20, void 0); - mxfd = (0, DefaultNumberOption_1.DefaultNumberOption)(mxfd, 0, 20, void 0); - if (mnfd === void 0) { - mnfd = Math.min(mnfdDefault, mxfd); - } else if (mxfd === void 0) { - mxfd = Math.max(mxfdDefault, mnfd); - } else if (mnfd > mxfd) { - throw new RangeError("Invalid range, ".concat(mnfd, " > ").concat(mxfd)); - } - internalSlots.minimumFractionDigits = mnfd; - internalSlots.maximumFractionDigits = mxfd; - } else { - internalSlots.minimumFractionDigits = mnfdDefault; - internalSlots.maximumFractionDigits = mxfdDefault; - } - } - if (needSd || needFd) { - if (roundingPriority === "morePrecision") { - internalSlots.roundingType = "morePrecision"; - } else if (roundingPriority === "lessPrecision") { - internalSlots.roundingType = "lessPrecision"; - } else if (hasSd) { - internalSlots.roundingType = "significantDigits"; - } else { - internalSlots.roundingType = "fractionDigits"; - } - } else { - internalSlots.roundingType = "morePrecision"; - internalSlots.minimumFractionDigits = 0; - internalSlots.maximumFractionDigits = 0; - internalSlots.minimumSignificantDigits = 1; - internalSlots.maximumSignificantDigits = 2; - } - } - exports.SetNumberFormatDigitOptions = SetNumberFormatDigitOptions; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/InitializeNumberFormat.js - var require_InitializeNumberFormat = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/InitializeNumberFormat.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.InitializeNumberFormat = void 0; - var CanonicalizeLocaleList_1 = require_CanonicalizeLocaleList(); - var GetOption_1 = require_GetOption(); - var intl_localematcher_1 = require_intl_localematcher(); - var SetNumberFormatUnitOptions_1 = require_SetNumberFormatUnitOptions(); - var CurrencyDigits_1 = require_CurrencyDigits(); - var SetNumberFormatDigitOptions_1 = require_SetNumberFormatDigitOptions(); - var utils_1 = require_utils(); - var CoerceOptionsToObject_1 = require_CoerceOptionsToObject(); - var GetNumberOption_1 = require_GetNumberOption(); - var GetStringOrBooleanOption_1 = require_GetStringOrBooleanOption(); - var VALID_ROUND_INCREMENT_VALUES = [ - 1, - 2, - 5, - 10, - 20, - 25, - 50, - 100, - 200, - 250, - 500, - 1e3, - 2e3 - ]; - function InitializeNumberFormat(nf, locales, opts, _a) { - var getInternalSlots = _a.getInternalSlots, localeData = _a.localeData, availableLocales = _a.availableLocales, numberingSystemNames = _a.numberingSystemNames, getDefaultLocale = _a.getDefaultLocale, currencyDigitsData = _a.currencyDigitsData; - var requestedLocales = (0, CanonicalizeLocaleList_1.CanonicalizeLocaleList)(locales); - var options = (0, CoerceOptionsToObject_1.CoerceOptionsToObject)(opts); - var opt = /* @__PURE__ */ Object.create(null); - var matcher = (0, GetOption_1.GetOption)(options, "localeMatcher", "string", ["lookup", "best fit"], "best fit"); - opt.localeMatcher = matcher; - var numberingSystem = (0, GetOption_1.GetOption)(options, "numberingSystem", "string", void 0, void 0); - if (numberingSystem !== void 0 && numberingSystemNames.indexOf(numberingSystem) < 0) { - throw RangeError("Invalid numberingSystems: ".concat(numberingSystem)); - } - opt.nu = numberingSystem; - var r = (0, intl_localematcher_1.ResolveLocale)( - availableLocales, - requestedLocales, - opt, - // [[RelevantExtensionKeys]] slot, which is a constant - ["nu"], - localeData, - getDefaultLocale - ); - var dataLocaleData = localeData[r.dataLocale]; - (0, utils_1.invariant)(!!dataLocaleData, "Missing locale data for ".concat(r.dataLocale)); - var internalSlots = getInternalSlots(nf); - internalSlots.locale = r.locale; - internalSlots.dataLocale = r.dataLocale; - internalSlots.numberingSystem = r.nu; - internalSlots.dataLocaleData = dataLocaleData; - (0, SetNumberFormatUnitOptions_1.SetNumberFormatUnitOptions)(nf, options, { getInternalSlots }); - var style = internalSlots.style; - var mnfdDefault; - var mxfdDefault; - if (style === "currency") { - var currency = internalSlots.currency; - var cDigits = (0, CurrencyDigits_1.CurrencyDigits)(currency, { currencyDigitsData }); - mnfdDefault = cDigits; - mxfdDefault = cDigits; - } else { - mnfdDefault = 0; - mxfdDefault = style === "percent" ? 0 : 3; - } - var notation = (0, GetOption_1.GetOption)(options, "notation", "string", ["standard", "scientific", "engineering", "compact"], "standard"); - internalSlots.notation = notation; - (0, SetNumberFormatDigitOptions_1.SetNumberFormatDigitOptions)(internalSlots, options, mnfdDefault, mxfdDefault, notation); - var roundingIncrement = (0, GetNumberOption_1.GetNumberOption)(options, "roundingIncrement", 1, 5e3, 1); - if (VALID_ROUND_INCREMENT_VALUES.indexOf(roundingIncrement) === -1) { - throw new RangeError("Invalid rounding increment value: ".concat(roundingIncrement, ".\nValid values are ").concat(VALID_ROUND_INCREMENT_VALUES, ".")); - } - if (roundingIncrement !== 1 && internalSlots.roundingType !== "fractionDigits") { - throw new TypeError("For roundingIncrement > 1 only fractionDigits is a valid roundingType"); - } - if (roundingIncrement !== 1 && internalSlots.maximumFractionDigits !== internalSlots.minimumFractionDigits) { - throw new RangeError("With roundingIncrement > 1, maximumFractionDigits and minimumFractionDigits must be equal."); - } - internalSlots.roundingIncrement = roundingIncrement; - var trailingZeroDisplay = (0, GetOption_1.GetOption)(options, "trailingZeroDisplay", "string", ["auto", "stripIfInteger"], "auto"); - internalSlots.trailingZeroDisplay = trailingZeroDisplay; - var compactDisplay = (0, GetOption_1.GetOption)(options, "compactDisplay", "string", ["short", "long"], "short"); - var defaultUseGrouping = "auto"; - if (notation === "compact") { - internalSlots.compactDisplay = compactDisplay; - defaultUseGrouping = "min2"; - } - internalSlots.useGrouping = (0, GetStringOrBooleanOption_1.GetStringOrBooleanOption)(options, "useGrouping", ["min2", "auto", "always"], "always", false, defaultUseGrouping); - internalSlots.signDisplay = (0, GetOption_1.GetOption)(options, "signDisplay", "string", ["auto", "never", "always", "exceptZero", "negative"], "auto"); - internalSlots.roundingMode = (0, GetOption_1.GetOption)(options, "roundingMode", "string", [ - "ceil", - "floor", - "expand", - "trunc", - "halfCeil", - "halfFloor", - "halfExpand", - "halfTrunc", - "halfEven" - ], "halfExpand"); - return nf; - } - exports.InitializeNumberFormat = InitializeNumberFormat; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/PartitionNumberRangePattern.js - var require_PartitionNumberRangePattern = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/NumberFormat/PartitionNumberRangePattern.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.PartitionNumberRangePattern = void 0; - var _262_1 = require__(); - var PartitionNumberPattern_1 = require_PartitionNumberPattern(); - var CollapseNumberRange_1 = require_CollapseNumberRange(); - var FormatApproximately_1 = require_FormatApproximately(); - function PartitionNumberRangePattern(numberFormat, x, y, _a) { - var getInternalSlots = _a.getInternalSlots; - var internalSlots = getInternalSlots(numberFormat); - if (isNaN(x) || isNaN(y)) { - throw new RangeError("Input must be a number"); - } - if (isFinite(x)) { - if (isFinite(y) && y < x) { - throw new RangeError("Y input must be bigger than X"); - } else if (y == Number.NEGATIVE_INFINITY) { - throw new RangeError("Y input must not be NegativeInfinity"); - } else if ((0, _262_1.SameValue)(y, -0) && x >= 0) { - throw new RangeError("Y input must be bigger than X"); - } - } else if (x == Number.POSITIVE_INFINITY) { - if (isFinite(y) || y == Number.NEGATIVE_INFINITY || (0, _262_1.SameValue)(y, -0)) { - throw new RangeError("Y input must be bigger than X"); - } - } else if ((0, _262_1.SameValue)(x, -0)) { - if (isFinite(y) && y < 0) { - throw new RangeError("Y input must be bigger than X"); - } else if (y == Number.NEGATIVE_INFINITY) { - throw new RangeError("Y input must be bigger than X"); - } - } - var result = []; - var xResult = (0, PartitionNumberPattern_1.PartitionNumberPattern)(numberFormat, x, { getInternalSlots }); - var yResult = (0, PartitionNumberPattern_1.PartitionNumberPattern)(numberFormat, y, { getInternalSlots }); - if (xResult === yResult) { - return (0, FormatApproximately_1.FormatApproximately)(numberFormat, xResult, { getInternalSlots }); - } - for (var _i = 0, xResult_1 = xResult; _i < xResult_1.length; _i++) { - var r = xResult_1[_i]; - r.source = "startRange"; - } - result = result.concat(xResult); - var symbols = internalSlots.dataLocaleData.numbers.symbols[internalSlots.numberingSystem]; - var rangeSeparator = symbols.timeSeparator; - result.push({ type: "literal", value: rangeSeparator, source: "shared" }); - for (var _b = 0, yResult_1 = yResult; _b < yResult_1.length; _b++) { - var r = yResult_1[_b]; - r.source = "endRange"; - } - result = result.concat(yResult); - return (0, CollapseNumberRange_1.CollapseNumberRange)(result); - } - exports.PartitionNumberRangePattern = PartitionNumberRangePattern; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/PartitionPattern.js - var require_PartitionPattern = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/PartitionPattern.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.PartitionPattern = void 0; - var utils_1 = require_utils(); - function PartitionPattern(pattern) { - var result = []; - var beginIndex = pattern.indexOf("{"); - var endIndex = 0; - var nextIndex = 0; - var length = pattern.length; - while (beginIndex < pattern.length && beginIndex > -1) { - endIndex = pattern.indexOf("}", beginIndex); - (0, utils_1.invariant)(endIndex > beginIndex, "Invalid pattern ".concat(pattern)); - if (beginIndex > nextIndex) { - result.push({ - type: "literal", - value: pattern.substring(nextIndex, beginIndex) - }); - } - result.push({ - type: pattern.substring(beginIndex + 1, endIndex), - value: void 0 - }); - nextIndex = endIndex + 1; - beginIndex = pattern.indexOf("{", nextIndex); - } - if (nextIndex < length) { - result.push({ - type: "literal", - value: pattern.substring(nextIndex, length) - }); - } - return result; - } - exports.PartitionPattern = PartitionPattern; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/SupportedLocales.js - var require_SupportedLocales = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/SupportedLocales.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.SupportedLocales = void 0; - var _262_1 = require__(); - var GetOption_1 = require_GetOption(); - var intl_localematcher_1 = require_intl_localematcher(); - function SupportedLocales(availableLocales, requestedLocales, options) { - var matcher = "best fit"; - if (options !== void 0) { - options = (0, _262_1.ToObject)(options); - matcher = (0, GetOption_1.GetOption)(options, "localeMatcher", "string", ["lookup", "best fit"], "best fit"); - } - if (matcher === "best fit") { - return (0, intl_localematcher_1.LookupSupportedLocales)(availableLocales, requestedLocales); - } - return (0, intl_localematcher_1.LookupSupportedLocales)(availableLocales, requestedLocales); - } - exports.SupportedLocales = SupportedLocales; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/data.js - var require_data = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/data.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.isMissingLocaleDataError = void 0; - var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); - var MissingLocaleDataError = ( - /** @class */ - function(_super) { - tslib_1.__extends(MissingLocaleDataError2, _super); - function MissingLocaleDataError2() { - var _this = _super !== null && _super.apply(this, arguments) || this; - _this.type = "MISSING_LOCALE_DATA"; - return _this; - } - return MissingLocaleDataError2; - }(Error) - ); - function isMissingLocaleDataError(e) { - return e.type === "MISSING_LOCALE_DATA"; - } - exports.isMissingLocaleDataError = isMissingLocaleDataError; - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/relative-time.js - var require_relative_time = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/relative-time.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/date-time.js - var require_date_time = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/date-time.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.RangePatternType = void 0; - var RangePatternType; - (function(RangePatternType2) { - RangePatternType2["startRange"] = "startRange"; - RangePatternType2["shared"] = "shared"; - RangePatternType2["endRange"] = "endRange"; - })(RangePatternType = exports.RangePatternType || (exports.RangePatternType = {})); - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/list.js - var require_list = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/list.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/plural-rules.js - var require_plural_rules = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/plural-rules.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/number.js - var require_number = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/number.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/displaynames.js - var require_displaynames = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/types/displaynames.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - } - }); - - // node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/index.js - var require_ecma402_abstract = __commonJS({ - "node_modules/@formatjs/intl-locale/node_modules/@formatjs/ecma402-abstract/index.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.invariant = exports.isMissingLocaleDataError = exports.defineProperty = exports.getMagnitude = exports.setMultiInternalSlots = exports.setInternalSlot = exports.isLiteralPart = exports.getMultiInternalSlots = exports.getInternalSlot = exports._formatToParts = void 0; - var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); - tslib_1.__exportStar(require_CanonicalizeLocaleList(), exports); - tslib_1.__exportStar(require_CanonicalizeTimeZoneName(), exports); - tslib_1.__exportStar(require_CoerceOptionsToObject(), exports); - tslib_1.__exportStar(require_GetNumberOption(), exports); - tslib_1.__exportStar(require_GetOption(), exports); - tslib_1.__exportStar(require_GetOptionsObject(), exports); - tslib_1.__exportStar(require_GetStringOrBooleanOption(), exports); - tslib_1.__exportStar(require_IsSanctionedSimpleUnitIdentifier(), exports); - tslib_1.__exportStar(require_IsValidTimeZoneName(), exports); - tslib_1.__exportStar(require_IsWellFormedCurrencyCode(), exports); - tslib_1.__exportStar(require_IsWellFormedUnitIdentifier(), exports); - tslib_1.__exportStar(require_ApplyUnsignedRoundingMode(), exports); - tslib_1.__exportStar(require_CollapseNumberRange(), exports); - tslib_1.__exportStar(require_ComputeExponent(), exports); - tslib_1.__exportStar(require_ComputeExponentForMagnitude(), exports); - tslib_1.__exportStar(require_CurrencyDigits(), exports); - tslib_1.__exportStar(require_FormatApproximately(), exports); - tslib_1.__exportStar(require_FormatNumericToParts(), exports); - tslib_1.__exportStar(require_FormatNumericToString(), exports); - tslib_1.__exportStar(require_GetUnsignedRoundingMode(), exports); - tslib_1.__exportStar(require_InitializeNumberFormat(), exports); - tslib_1.__exportStar(require_PartitionNumberPattern(), exports); - tslib_1.__exportStar(require_PartitionNumberRangePattern(), exports); - tslib_1.__exportStar(require_SetNumberFormatDigitOptions(), exports); - tslib_1.__exportStar(require_SetNumberFormatUnitOptions(), exports); - tslib_1.__exportStar(require_ToRawFixed(), exports); - tslib_1.__exportStar(require_ToRawPrecision(), exports); - var format_to_parts_1 = require_format_to_parts(); - Object.defineProperty(exports, "_formatToParts", { enumerable: true, get: function() { - return tslib_1.__importDefault(format_to_parts_1).default; - } }); - tslib_1.__exportStar(require_PartitionPattern(), exports); - tslib_1.__exportStar(require_SupportedLocales(), exports); - var utils_1 = require_utils(); - Object.defineProperty(exports, "getInternalSlot", { enumerable: true, get: function() { - return utils_1.getInternalSlot; - } }); - Object.defineProperty(exports, "getMultiInternalSlots", { enumerable: true, get: function() { - return utils_1.getMultiInternalSlots; - } }); - Object.defineProperty(exports, "isLiteralPart", { enumerable: true, get: function() { - return utils_1.isLiteralPart; - } }); - Object.defineProperty(exports, "setInternalSlot", { enumerable: true, get: function() { - return utils_1.setInternalSlot; - } }); - Object.defineProperty(exports, "setMultiInternalSlots", { enumerable: true, get: function() { - return utils_1.setMultiInternalSlots; - } }); - Object.defineProperty(exports, "getMagnitude", { enumerable: true, get: function() { - return utils_1.getMagnitude; - } }); - Object.defineProperty(exports, "defineProperty", { enumerable: true, get: function() { - return utils_1.defineProperty; - } }); - var data_1 = require_data(); - Object.defineProperty(exports, "isMissingLocaleDataError", { enumerable: true, get: function() { - return data_1.isMissingLocaleDataError; - } }); - tslib_1.__exportStar(require_relative_time(), exports); - tslib_1.__exportStar(require_date_time(), exports); - tslib_1.__exportStar(require_list(), exports); - tslib_1.__exportStar(require_plural_rules(), exports); - tslib_1.__exportStar(require_number(), exports); - tslib_1.__exportStar(require_displaynames(), exports); - var utils_2 = require_utils(); - Object.defineProperty(exports, "invariant", { enumerable: true, get: function() { - return utils_2.invariant; - } }); - tslib_1.__exportStar(require__(), exports); - } - }); - - // node_modules/@formatjs/intl-getcanonicallocales/src/parser.js - var require_parser = __commonJS({ - "node_modules/@formatjs/intl-getcanonicallocales/src/parser.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.parseUnicodeLocaleId = exports.parseUnicodeLanguageId = exports.isUnicodeVariantSubtag = exports.isUnicodeScriptSubtag = exports.isUnicodeRegionSubtag = exports.isStructurallyValidLanguageTag = exports.isUnicodeLanguageSubtag = exports.SEPARATOR = void 0; - var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); - var ALPHANUM_1_8 = /^[a-z0-9]{1,8}$/i; - var ALPHANUM_2_8 = /^[a-z0-9]{2,8}$/i; - var ALPHANUM_3_8 = /^[a-z0-9]{3,8}$/i; - var KEY_REGEX = /^[a-z0-9][a-z]$/i; - var TYPE_REGEX = /^[a-z0-9]{3,8}$/i; - var ALPHA_4 = /^[a-z]{4}$/i; - var OTHER_EXTENSION_TYPE = /^[0-9a-svwyz]$/i; - var UNICODE_REGION_SUBTAG_REGEX = /^([a-z]{2}|[0-9]{3})$/i; - var UNICODE_VARIANT_SUBTAG_REGEX = /^([a-z0-9]{5,8}|[0-9][a-z0-9]{3})$/i; - var UNICODE_LANGUAGE_SUBTAG_REGEX = /^([a-z]{2,3}|[a-z]{5,8})$/i; - var TKEY_REGEX = /^[a-z][0-9]$/i; - exports.SEPARATOR = "-"; - function isUnicodeLanguageSubtag(lang) { - return UNICODE_LANGUAGE_SUBTAG_REGEX.test(lang); - } - exports.isUnicodeLanguageSubtag = isUnicodeLanguageSubtag; - function isStructurallyValidLanguageTag(tag) { - try { - parseUnicodeLanguageId(tag.split(exports.SEPARATOR)); - } catch (e) { - return false; - } - return true; - } - exports.isStructurallyValidLanguageTag = isStructurallyValidLanguageTag; - function isUnicodeRegionSubtag(region) { - return UNICODE_REGION_SUBTAG_REGEX.test(region); - } - exports.isUnicodeRegionSubtag = isUnicodeRegionSubtag; - function isUnicodeScriptSubtag(script) { - return ALPHA_4.test(script); - } - exports.isUnicodeScriptSubtag = isUnicodeScriptSubtag; - function isUnicodeVariantSubtag(variant) { - return UNICODE_VARIANT_SUBTAG_REGEX.test(variant); - } - exports.isUnicodeVariantSubtag = isUnicodeVariantSubtag; - function parseUnicodeLanguageId(chunks) { - if (typeof chunks === "string") { - chunks = chunks.split(exports.SEPARATOR); - } - var lang = chunks.shift(); - if (!lang) { - throw new RangeError("Missing unicode_language_subtag"); - } - if (lang === "root") { - return { lang: "root", variants: [] }; - } - if (!isUnicodeLanguageSubtag(lang)) { - throw new RangeError("Malformed unicode_language_subtag"); - } - var script; - if (chunks.length && isUnicodeScriptSubtag(chunks[0])) { - script = chunks.shift(); - } - var region; - if (chunks.length && isUnicodeRegionSubtag(chunks[0])) { - region = chunks.shift(); - } - var variants = {}; - while (chunks.length && isUnicodeVariantSubtag(chunks[0])) { - var variant = chunks.shift(); - if (variant in variants) { - throw new RangeError('Duplicate variant "'.concat(variant, '"')); - } - variants[variant] = 1; - } - return { - lang, - script, - region, - variants: Object.keys(variants) - }; - } - exports.parseUnicodeLanguageId = parseUnicodeLanguageId; - function parseUnicodeExtension(chunks) { - var keywords = []; - var keyword; - while (chunks.length && (keyword = parseKeyword(chunks))) { - keywords.push(keyword); - } - if (keywords.length) { - return { - type: "u", - keywords, - attributes: [] - }; - } - var attributes = []; - while (chunks.length && ALPHANUM_3_8.test(chunks[0])) { - attributes.push(chunks.shift()); - } - while (chunks.length && (keyword = parseKeyword(chunks))) { - keywords.push(keyword); - } - if (keywords.length || attributes.length) { - return { - type: "u", - attributes, - keywords - }; - } - throw new RangeError("Malformed unicode_extension"); - } - function parseKeyword(chunks) { - var key; - if (!KEY_REGEX.test(chunks[0])) { - return; - } - key = chunks.shift(); - var type = []; - while (chunks.length && TYPE_REGEX.test(chunks[0])) { - type.push(chunks.shift()); - } - var value = ""; - if (type.length) { - value = type.join(exports.SEPARATOR); - } - return [key, value]; - } - function parseTransformedExtension(chunks) { - var lang; - try { - lang = parseUnicodeLanguageId(chunks); - } catch (e) { - } - var fields = []; - while (chunks.length && TKEY_REGEX.test(chunks[0])) { - var key = chunks.shift(); - var value = []; - while (chunks.length && ALPHANUM_3_8.test(chunks[0])) { - value.push(chunks.shift()); - } - if (!value.length) { - throw new RangeError('Missing tvalue for tkey "'.concat(key, '"')); - } - fields.push([key, value.join(exports.SEPARATOR)]); - } - if (fields.length) { - return { - type: "t", - fields, - lang - }; - } - throw new RangeError("Malformed transformed_extension"); - } - function parsePuExtension(chunks) { - var exts = []; - while (chunks.length && ALPHANUM_1_8.test(chunks[0])) { - exts.push(chunks.shift()); - } - if (exts.length) { - return { - type: "x", - value: exts.join(exports.SEPARATOR) - }; - } - throw new RangeError("Malformed private_use_extension"); - } - function parseOtherExtensionValue(chunks) { - var exts = []; - while (chunks.length && ALPHANUM_2_8.test(chunks[0])) { - exts.push(chunks.shift()); - } - if (exts.length) { - return exts.join(exports.SEPARATOR); - } - return ""; - } - function parseExtensions(chunks) { - if (!chunks.length) { - return { extensions: [] }; - } - var extensions = []; - var unicodeExtension; - var transformedExtension; - var puExtension; - var otherExtensionMap = {}; - do { - var type = chunks.shift(); - switch (type) { - case "u": - case "U": - if (unicodeExtension) { - throw new RangeError("There can only be 1 -u- extension"); - } - unicodeExtension = parseUnicodeExtension(chunks); - extensions.push(unicodeExtension); - break; - case "t": - case "T": - if (transformedExtension) { - throw new RangeError("There can only be 1 -t- extension"); - } - transformedExtension = parseTransformedExtension(chunks); - extensions.push(transformedExtension); - break; - case "x": - case "X": - if (puExtension) { - throw new RangeError("There can only be 1 -x- extension"); - } - puExtension = parsePuExtension(chunks); - extensions.push(puExtension); - break; - default: - if (!OTHER_EXTENSION_TYPE.test(type)) { - throw new RangeError("Malformed extension type"); - } - if (type in otherExtensionMap) { - throw new RangeError("There can only be 1 -".concat(type, "- extension")); - } - var extension = { - type, - value: parseOtherExtensionValue(chunks) - }; - otherExtensionMap[extension.type] = extension; - extensions.push(extension); - break; - } - } while (chunks.length); - return { extensions }; - } - function parseUnicodeLocaleId(locale) { - var chunks = locale.split(exports.SEPARATOR); - var lang = parseUnicodeLanguageId(chunks); - return tslib_1.__assign({ lang }, parseExtensions(chunks)); - } - exports.parseUnicodeLocaleId = parseUnicodeLocaleId; - } - }); - - // node_modules/@formatjs/intl-getcanonicallocales/src/emitter.js - var require_emitter = __commonJS({ - "node_modules/@formatjs/intl-getcanonicallocales/src/emitter.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.emitUnicodeLocaleId = exports.emitUnicodeLanguageId = void 0; - var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); - function emitUnicodeLanguageId(lang) { - if (!lang) { - return ""; - } - return tslib_1.__spreadArray([lang.lang, lang.script, lang.region], lang.variants || [], true).filter(Boolean).join("-"); - } - exports.emitUnicodeLanguageId = emitUnicodeLanguageId; - function emitUnicodeLocaleId(_a) { - var lang = _a.lang, extensions = _a.extensions; - var chunks = [emitUnicodeLanguageId(lang)]; - for (var _i = 0, extensions_1 = extensions; _i < extensions_1.length; _i++) { - var ext = extensions_1[_i]; - chunks.push(ext.type); - switch (ext.type) { - case "u": - chunks.push.apply(chunks, tslib_1.__spreadArray(tslib_1.__spreadArray([], ext.attributes, false), ext.keywords.reduce(function(all, kv) { - return all.concat(kv); - }, []), false)); - break; - case "t": - chunks.push.apply(chunks, tslib_1.__spreadArray([emitUnicodeLanguageId(ext.lang)], ext.fields.reduce(function(all, kv) { - return all.concat(kv); - }, []), false)); - break; - default: - chunks.push(ext.value); - break; - } - } - return chunks.filter(Boolean).join("-"); - } - exports.emitUnicodeLocaleId = emitUnicodeLocaleId; - } - }); - - // node_modules/@formatjs/intl-getcanonicallocales/src/aliases.generated.js - var require_aliases_generated = __commonJS({ - "node_modules/@formatjs/intl-getcanonicallocales/src/aliases.generated.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.variantAlias = exports.scriptAlias = exports.territoryAlias = exports.languageAlias = void 0; - exports.languageAlias = { - "aa-saaho": "ssy", - "aam": "aas", - "aar": "aa", - "abk": "ab", - "adp": "dz", - "afr": "af", - "agp": "apf", - "ais": "ami", - "aju": "jrb", - "aka": "ak", - "alb": "sq", - "als": "sq", - "amh": "am", - "ara": "ar", - "arb": "ar", - "arg": "an", - "arm": "hy", - "art-lojban": "jbo", - "asd": "snz", - "asm": "as", - "aue": "ktz", - "ava": "av", - "ave": "ae", - "aym": "ay", - "ayr": "ay", - "ayx": "nun", - "aze": "az", - "azj": "az", - "bak": "ba", - "bam": "bm", - "baq": "eu", - "baz": "nvo", - "bcc": "bal", - "bcl": "bik", - "bel": "be", - "ben": "bn", - "bgm": "bcg", - "bh": "bho", - "bhk": "fbl", - "bic": "bir", - "bih": "bho", - "bis": "bi", - "bjd": "drl", - "bjq": "bzc", - "bkb": "ebk", - "blg": "iba", - "bod": "bo", - "bos": "bs", - "bre": "br", - "btb": "beb", - "bul": "bg", - "bur": "my", - "bxk": "luy", - "bxr": "bua", - "cat": "ca", - "ccq": "rki", - "cel-gaulish": "xtg", - "ces": "cs", - "cha": "ch", - "che": "ce", - "chi": "zh", - "chu": "cu", - "chv": "cv", - "cjr": "mom", - "cka": "cmr", - "cld": "syr", - "cmk": "xch", - "cmn": "zh", - "cnr": "sr-ME", - "cor": "kw", - "cos": "co", - "coy": "pij", - "cqu": "quh", - "cre": "cr", - "cwd": "cr", - "cym": "cy", - "cze": "cs", - "daf": "dnj", - "dan": "da", - "dap": "njz", - "deu": "de", - "dgo": "doi", - "dhd": "mwr", - "dik": "din", - "diq": "zza", - "dit": "dif", - "div": "dv", - "djl": "dze", - "dkl": "aqd", - "drh": "mn", - "drr": "kzk", - "drw": "fa-AF", - "dud": "uth", - "duj": "dwu", - "dut": "nl", - "dwl": "dbt", - "dzo": "dz", - "ekk": "et", - "ell": "el", - "elp": "amq", - "emk": "man", - "en-GB-oed": "en-GB-oxendict", - "eng": "en", - "epo": "eo", - "esk": "ik", - "est": "et", - "eus": "eu", - "ewe": "ee", - "fao": "fo", - "fas": "fa", - "fat": "ak", - "fij": "fj", - "fin": "fi", - "fra": "fr", - "fre": "fr", - "fry": "fy", - "fuc": "ff", - "ful": "ff", - "gav": "dev", - "gaz": "om", - "gbc": "wny", - "gbo": "grb", - "geo": "ka", - "ger": "de", - "gfx": "vaj", - "ggn": "gvr", - "ggo": "esg", - "ggr": "gtu", - "gio": "aou", - "gla": "gd", - "gle": "ga", - "glg": "gl", - "gli": "kzk", - "glv": "gv", - "gno": "gon", - "gre": "el", - "grn": "gn", - "gti": "nyc", - "gug": "gn", - "guj": "gu", - "guv": "duz", - "gya": "gba", - "hat": "ht", - "hau": "ha", - "hbs": "sr-Latn", - "hdn": "hai", - "hea": "hmn", - "heb": "he", - "her": "hz", - "him": "srx", - "hin": "hi", - "hmo": "ho", - "hrr": "jal", - "hrv": "hr", - "hun": "hu", - "hy-arevmda": "hyw", - "hye": "hy", - "i-ami": "ami", - "i-bnn": "bnn", - "i-default": "en-x-i-default", - "i-enochian": "und-x-i-enochian", - "i-hak": "hak", - "i-klingon": "tlh", - "i-lux": "lb", - "i-mingo": "see-x-i-mingo", - "i-navajo": "nv", - "i-pwn": "pwn", - "i-tao": "tao", - "i-tay": "tay", - "i-tsu": "tsu", - "ibi": "opa", - "ibo": "ig", - "ice": "is", - "ido": "io", - "iii": "ii", - "ike": "iu", - "iku": "iu", - "ile": "ie", - "ill": "ilm", - "ilw": "gal", - "in": "id", - "ina": "ia", - "ind": "id", - "ipk": "ik", - "isl": "is", - "ita": "it", - "iw": "he", - "izi": "eza", - "jar": "jgk", - "jav": "jv", - "jeg": "oyb", - "ji": "yi", - "jpn": "ja", - "jw": "jv", - "kal": "kl", - "kan": "kn", - "kas": "ks", - "kat": "ka", - "kau": "kr", - "kaz": "kk", - "kdv": "zkd", - "kgc": "tdf", - "kgd": "ncq", - "kgh": "kml", - "khk": "mn", - "khm": "km", - "kik": "ki", - "kin": "rw", - "kir": "ky", - "kmr": "ku", - "knc": "kr", - "kng": "kg", - "knn": "kok", - "koj": "kwv", - "kom": "kv", - "kon": "kg", - "kor": "ko", - "kpp": "jkm", - "kpv": "kv", - "krm": "bmf", - "ktr": "dtp", - "kua": "kj", - "kur": "ku", - "kvs": "gdj", - "kwq": "yam", - "kxe": "tvd", - "kxl": "kru", - "kzh": "dgl", - "kzj": "dtp", - "kzt": "dtp", - "lao": "lo", - "lat": "la", - "lav": "lv", - "lbk": "bnc", - "leg": "enl", - "lii": "raq", - "lim": "li", - "lin": "ln", - "lit": "lt", - "llo": "ngt", - "lmm": "rmx", - "ltz": "lb", - "lub": "lu", - "lug": "lg", - "lvs": "lv", - "mac": "mk", - "mah": "mh", - "mal": "ml", - "mao": "mi", - "mar": "mr", - "may": "ms", - "meg": "cir", - "mgx": "jbk", - "mhr": "chm", - "mkd": "mk", - "mlg": "mg", - "mlt": "mt", - "mnk": "man", - "mnt": "wnn", - "mo": "ro", - "mof": "xnt", - "mol": "ro", - "mon": "mn", - "mri": "mi", - "msa": "ms", - "mst": "mry", - "mup": "raj", - "mwd": "dmw", - "mwj": "vaj", - "mya": "my", - "myd": "aog", - "myt": "mry", - "nad": "xny", - "nau": "na", - "nav": "nv", - "nbf": "nru", - "nbl": "nr", - "nbx": "ekc", - "ncp": "kdz", - "nde": "nd", - "ndo": "ng", - "nep": "ne", - "nld": "nl", - "nln": "azd", - "nlr": "nrk", - "nno": "nn", - "nns": "nbr", - "nnx": "ngv", - "no-bok": "nb", - "no-bokmal": "nb", - "no-nyn": "nn", - "no-nynorsk": "nn", - "nob": "nb", - "noo": "dtd", - "nor": "no", - "npi": "ne", - "nts": "pij", - "nxu": "bpp", - "nya": "ny", - "oci": "oc", - "ojg": "oj", - "oji": "oj", - "ori": "or", - "orm": "om", - "ory": "or", - "oss": "os", - "oun": "vaj", - "pan": "pa", - "pat": "kxr", - "pbu": "ps", - "pcr": "adx", - "per": "fa", - "pes": "fa", - "pli": "pi", - "plt": "mg", - "pmc": "huw", - "pmu": "phr", - "pnb": "lah", - "pol": "pl", - "por": "pt", - "ppa": "bfy", - "ppr": "lcq", - "prs": "fa-AF", - "pry": "prt", - "pus": "ps", - "puz": "pub", - "que": "qu", - "quz": "qu", - "rmr": "emx", - "rmy": "rom", - "roh": "rm", - "ron": "ro", - "rum": "ro", - "run": "rn", - "rus": "ru", - "sag": "sg", - "san": "sa", - "sap": "aqt", - "sca": "hle", - "scc": "sr", - "scr": "hr", - "sgl": "isk", - "sgn-BE-FR": "sfb", - "sgn-BE-NL": "vgt", - "sgn-BR": "bzs", - "sgn-CH-DE": "sgg", - "sgn-CO": "csn", - "sgn-DE": "gsg", - "sgn-DK": "dsl", - "sgn-ES": "ssp", - "sgn-FR": "fsl", - "sgn-GB": "bfi", - "sgn-GR": "gss", - "sgn-IE": "isg", - "sgn-IT": "ise", - "sgn-JP": "jsl", - "sgn-MX": "mfs", - "sgn-NI": "ncs", - "sgn-NL": "dse", - "sgn-NO": "nsi", - "sgn-PT": "psr", - "sgn-SE": "swl", - "sgn-US": "ase", - "sgn-ZA": "sfs", - "sh": "sr-Latn", - "sin": "si", - "skk": "oyb", - "slk": "sk", - "slo": "sk", - "slv": "sl", - "sme": "se", - "smo": "sm", - "sna": "sn", - "snd": "sd", - "som": "so", - "sot": "st", - "spa": "es", - "spy": "kln", - "sqi": "sq", - "src": "sc", - "srd": "sc", - "srp": "sr", - "ssw": "ss", - "sul": "sgd", - "sum": "ulw", - "sun": "su", - "swa": "sw", - "swc": "sw-CD", - "swe": "sv", - "swh": "sw", - "tah": "ty", - "tam": "ta", - "tat": "tt", - "tdu": "dtp", - "tel": "te", - "tgg": "bjp", - "tgk": "tg", - "tgl": "fil", - "tha": "th", - "thc": "tpo", - "thw": "ola", - "thx": "oyb", - "tib": "bo", - "tid": "itd", - "tie": "ras", - "tir": "ti", - "tkk": "twm", - "tl": "fil", - "tlw": "weo", - "tmp": "tyj", - "tne": "kak", - "tnf": "fa-AF", - "ton": "to", - "tsf": "taj", - "tsn": "tn", - "tso": "ts", - "ttq": "tmh", - "tuk": "tk", - "tur": "tr", - "tw": "ak", - "twi": "ak", - "uig": "ug", - "ukr": "uk", - "umu": "del", - "und-aaland": "und-AX", - "und-arevela": "und", - "und-arevmda": "und", - "und-bokmal": "und", - "und-hakka": "und", - "und-hepburn-heploc": "und-alalc97", - "und-lojban": "und", - "und-nynorsk": "und", - "und-saaho": "und", - "und-xiang": "und", - "unp": "wro", - "uok": "ema", - "urd": "ur", - "uzb": "uz", - "uzn": "uz", - "ven": "ve", - "vie": "vi", - "vol": "vo", - "wel": "cy", - "wgw": "wgb", - "wit": "nol", - "wiw": "nwo", - "wln": "wa", - "wol": "wo", - "xba": "cax", - "xho": "xh", - "xia": "acn", - "xkh": "waw", - "xpe": "kpe", - "xrq": "dmw", - "xsj": "suj", - "xsl": "den", - "ybd": "rki", - "ydd": "yi", - "yen": "ynq", - "yid": "yi", - "yiy": "yrm", - "yma": "lrr", - "ymt": "mtm", - "yor": "yo", - "yos": "zom", - "yuu": "yug", - "zai": "zap", - "zh-cmn": "zh", - "zh-cmn-Hans": "zh-Hans", - "zh-cmn-Hant": "zh-Hant", - "zh-gan": "gan", - "zh-guoyu": "zh", - "zh-hakka": "hak", - "zh-min": "nan-x-zh-min", - "zh-min-nan": "nan", - "zh-wuu": "wuu", - "zh-xiang": "hsn", - "zh-yue": "yue", - "zha": "za", - "zho": "zh", - "zir": "scv", - "zsm": "ms", - "zul": "zu", - "zyb": "za" - }; - exports.territoryAlias = { - "100": "BG", - "104": "MM", - "108": "BI", - "112": "BY", - "116": "KH", - "120": "CM", - "124": "CA", - "132": "CV", - "136": "KY", - "140": "CF", - "144": "LK", - "148": "TD", - "152": "CL", - "156": "CN", - "158": "TW", - "162": "CX", - "166": "CC", - "170": "CO", - "172": "RU AM AZ BY GE KG KZ MD TJ TM UA UZ", - "174": "KM", - "175": "YT", - "178": "CG", - "180": "CD", - "184": "CK", - "188": "CR", - "191": "HR", - "192": "CU", - "196": "CY", - "200": "CZ SK", - "203": "CZ", - "204": "BJ", - "208": "DK", - "212": "DM", - "214": "DO", - "218": "EC", - "222": "SV", - "226": "GQ", - "230": "ET", - "231": "ET", - "232": "ER", - "233": "EE", - "234": "FO", - "238": "FK", - "239": "GS", - "242": "FJ", - "246": "FI", - "248": "AX", - "249": "FR", - "250": "FR", - "254": "GF", - "258": "PF", - "260": "TF", - "262": "DJ", - "266": "GA", - "268": "GE", - "270": "GM", - "275": "PS", - "276": "DE", - "278": "DE", - "280": "DE", - "288": "GH", - "292": "GI", - "296": "KI", - "300": "GR", - "304": "GL", - "308": "GD", - "312": "GP", - "316": "GU", - "320": "GT", - "324": "GN", - "328": "GY", - "332": "HT", - "334": "HM", - "336": "VA", - "340": "HN", - "344": "HK", - "348": "HU", - "352": "IS", - "356": "IN", - "360": "ID", - "364": "IR", - "368": "IQ", - "372": "IE", - "376": "IL", - "380": "IT", - "384": "CI", - "388": "JM", - "392": "JP", - "398": "KZ", - "400": "JO", - "404": "KE", - "408": "KP", - "410": "KR", - "414": "KW", - "417": "KG", - "418": "LA", - "422": "LB", - "426": "LS", - "428": "LV", - "430": "LR", - "434": "LY", - "438": "LI", - "440": "LT", - "442": "LU", - "446": "MO", - "450": "MG", - "454": "MW", - "458": "MY", - "462": "MV", - "466": "ML", - "470": "MT", - "474": "MQ", - "478": "MR", - "480": "MU", - "484": "MX", - "492": "MC", - "496": "MN", - "498": "MD", - "499": "ME", - "500": "MS", - "504": "MA", - "508": "MZ", - "512": "OM", - "516": "NA", - "520": "NR", - "524": "NP", - "528": "NL", - "530": "CW SX BQ", - "531": "CW", - "532": "CW SX BQ", - "533": "AW", - "534": "SX", - "535": "BQ", - "536": "SA IQ", - "540": "NC", - "548": "VU", - "554": "NZ", - "558": "NI", - "562": "NE", - "566": "NG", - "570": "NU", - "574": "NF", - "578": "NO", - "580": "MP", - "581": "UM", - "582": "FM MH MP PW", - "583": "FM", - "584": "MH", - "585": "PW", - "586": "PK", - "591": "PA", - "598": "PG", - "600": "PY", - "604": "PE", - "608": "PH", - "612": "PN", - "616": "PL", - "620": "PT", - "624": "GW", - "626": "TL", - "630": "PR", - "634": "QA", - "638": "RE", - "642": "RO", - "643": "RU", - "646": "RW", - "652": "BL", - "654": "SH", - "659": "KN", - "660": "AI", - "662": "LC", - "663": "MF", - "666": "PM", - "670": "VC", - "674": "SM", - "678": "ST", - "682": "SA", - "686": "SN", - "688": "RS", - "690": "SC", - "694": "SL", - "702": "SG", - "703": "SK", - "704": "VN", - "705": "SI", - "706": "SO", - "710": "ZA", - "716": "ZW", - "720": "YE", - "724": "ES", - "728": "SS", - "729": "SD", - "732": "EH", - "736": "SD", - "740": "SR", - "744": "SJ", - "748": "SZ", - "752": "SE", - "756": "CH", - "760": "SY", - "762": "TJ", - "764": "TH", - "768": "TG", - "772": "TK", - "776": "TO", - "780": "TT", - "784": "AE", - "788": "TN", - "792": "TR", - "795": "TM", - "796": "TC", - "798": "TV", - "800": "UG", - "804": "UA", - "807": "MK", - "810": "RU AM AZ BY EE GE KZ KG LV LT MD TJ TM UA UZ", - "818": "EG", - "826": "GB", - "830": "JE GG", - "831": "GG", - "832": "JE", - "833": "IM", - "834": "TZ", - "840": "US", - "850": "VI", - "854": "BF", - "858": "UY", - "860": "UZ", - "862": "VE", - "876": "WF", - "882": "WS", - "886": "YE", - "887": "YE", - "890": "RS ME SI HR MK BA", - "891": "RS ME", - "894": "ZM", - "958": "AA", - "959": "QM", - "960": "QN", - "962": "QP", - "963": "QQ", - "964": "QR", - "965": "QS", - "966": "QT", - "967": "EU", - "968": "QV", - "969": "QW", - "970": "QX", - "971": "QY", - "972": "QZ", - "973": "XA", - "974": "XB", - "975": "XC", - "976": "XD", - "977": "XE", - "978": "XF", - "979": "XG", - "980": "XH", - "981": "XI", - "982": "XJ", - "983": "XK", - "984": "XL", - "985": "XM", - "986": "XN", - "987": "XO", - "988": "XP", - "989": "XQ", - "990": "XR", - "991": "XS", - "992": "XT", - "993": "XU", - "994": "XV", - "995": "XW", - "996": "XX", - "997": "XY", - "998": "XZ", - "999": "ZZ", - "004": "AF", - "008": "AL", - "010": "AQ", - "012": "DZ", - "016": "AS", - "020": "AD", - "024": "AO", - "028": "AG", - "031": "AZ", - "032": "AR", - "036": "AU", - "040": "AT", - "044": "BS", - "048": "BH", - "050": "BD", - "051": "AM", - "052": "BB", - "056": "BE", - "060": "BM", - "062": "034 143", - "064": "BT", - "068": "BO", - "070": "BA", - "072": "BW", - "074": "BV", - "076": "BR", - "084": "BZ", - "086": "IO", - "090": "SB", - "092": "VG", - "096": "BN", - "AAA": "AA", - "ABW": "AW", - "AFG": "AF", - "AGO": "AO", - "AIA": "AI", - "ALA": "AX", - "ALB": "AL", - "AN": "CW SX BQ", - "AND": "AD", - "ANT": "CW SX BQ", - "ARE": "AE", - "ARG": "AR", - "ARM": "AM", - "ASC": "AC", - "ASM": "AS", - "ATA": "AQ", - "ATF": "TF", - "ATG": "AG", - "AUS": "AU", - "AUT": "AT", - "AZE": "AZ", - "BDI": "BI", - "BEL": "BE", - "BEN": "BJ", - "BES": "BQ", - "BFA": "BF", - "BGD": "BD", - "BGR": "BG", - "BHR": "BH", - "BHS": "BS", - "BIH": "BA", - "BLM": "BL", - "BLR": "BY", - "BLZ": "BZ", - "BMU": "BM", - "BOL": "BO", - "BRA": "BR", - "BRB": "BB", - "BRN": "BN", - "BTN": "BT", - "BU": "MM", - "BUR": "MM", - "BVT": "BV", - "BWA": "BW", - "CAF": "CF", - "CAN": "CA", - "CCK": "CC", - "CHE": "CH", - "CHL": "CL", - "CHN": "CN", - "CIV": "CI", - "CMR": "CM", - "COD": "CD", - "COG": "CG", - "COK": "CK", - "COL": "CO", - "COM": "KM", - "CPT": "CP", - "CPV": "CV", - "CRI": "CR", - "CS": "RS ME", - "CT": "KI", - "CUB": "CU", - "CUW": "CW", - "CXR": "CX", - "CYM": "KY", - "CYP": "CY", - "CZE": "CZ", - "DD": "DE", - "DDR": "DE", - "DEU": "DE", - "DGA": "DG", - "DJI": "DJ", - "DMA": "DM", - "DNK": "DK", - "DOM": "DO", - "DY": "BJ", - "DZA": "DZ", - "ECU": "EC", - "EGY": "EG", - "ERI": "ER", - "ESH": "EH", - "ESP": "ES", - "EST": "EE", - "ETH": "ET", - "FIN": "FI", - "FJI": "FJ", - "FLK": "FK", - "FQ": "AQ TF", - "FRA": "FR", - "FRO": "FO", - "FSM": "FM", - "FX": "FR", - "FXX": "FR", - "GAB": "GA", - "GBR": "GB", - "GEO": "GE", - "GGY": "GG", - "GHA": "GH", - "GIB": "GI", - "GIN": "GN", - "GLP": "GP", - "GMB": "GM", - "GNB": "GW", - "GNQ": "GQ", - "GRC": "GR", - "GRD": "GD", - "GRL": "GL", - "GTM": "GT", - "GUF": "GF", - "GUM": "GU", - "GUY": "GY", - "HKG": "HK", - "HMD": "HM", - "HND": "HN", - "HRV": "HR", - "HTI": "HT", - "HUN": "HU", - "HV": "BF", - "IDN": "ID", - "IMN": "IM", - "IND": "IN", - "IOT": "IO", - "IRL": "IE", - "IRN": "IR", - "IRQ": "IQ", - "ISL": "IS", - "ISR": "IL", - "ITA": "IT", - "JAM": "JM", - "JEY": "JE", - "JOR": "JO", - "JPN": "JP", - "JT": "UM", - "KAZ": "KZ", - "KEN": "KE", - "KGZ": "KG", - "KHM": "KH", - "KIR": "KI", - "KNA": "KN", - "KOR": "KR", - "KWT": "KW", - "LAO": "LA", - "LBN": "LB", - "LBR": "LR", - "LBY": "LY", - "LCA": "LC", - "LIE": "LI", - "LKA": "LK", - "LSO": "LS", - "LTU": "LT", - "LUX": "LU", - "LVA": "LV", - "MAC": "MO", - "MAF": "MF", - "MAR": "MA", - "MCO": "MC", - "MDA": "MD", - "MDG": "MG", - "MDV": "MV", - "MEX": "MX", - "MHL": "MH", - "MI": "UM", - "MKD": "MK", - "MLI": "ML", - "MLT": "MT", - "MMR": "MM", - "MNE": "ME", - "MNG": "MN", - "MNP": "MP", - "MOZ": "MZ", - "MRT": "MR", - "MSR": "MS", - "MTQ": "MQ", - "MUS": "MU", - "MWI": "MW", - "MYS": "MY", - "MYT": "YT", - "NAM": "NA", - "NCL": "NC", - "NER": "NE", - "NFK": "NF", - "NGA": "NG", - "NH": "VU", - "NIC": "NI", - "NIU": "NU", - "NLD": "NL", - "NOR": "NO", - "NPL": "NP", - "NQ": "AQ", - "NRU": "NR", - "NT": "SA IQ", - "NTZ": "SA IQ", - "NZL": "NZ", - "OMN": "OM", - "PAK": "PK", - "PAN": "PA", - "PC": "FM MH MP PW", - "PCN": "PN", - "PER": "PE", - "PHL": "PH", - "PLW": "PW", - "PNG": "PG", - "POL": "PL", - "PRI": "PR", - "PRK": "KP", - "PRT": "PT", - "PRY": "PY", - "PSE": "PS", - "PU": "UM", - "PYF": "PF", - "PZ": "PA", - "QAT": "QA", - "QMM": "QM", - "QNN": "QN", - "QPP": "QP", - "QQQ": "QQ", - "QRR": "QR", - "QSS": "QS", - "QTT": "QT", - "QU": "EU", - "QUU": "EU", - "QVV": "QV", - "QWW": "QW", - "QXX": "QX", - "QYY": "QY", - "QZZ": "QZ", - "REU": "RE", - "RH": "ZW", - "ROU": "RO", - "RUS": "RU", - "RWA": "RW", - "SAU": "SA", - "SCG": "RS ME", - "SDN": "SD", - "SEN": "SN", - "SGP": "SG", - "SGS": "GS", - "SHN": "SH", - "SJM": "SJ", - "SLB": "SB", - "SLE": "SL", - "SLV": "SV", - "SMR": "SM", - "SOM": "SO", - "SPM": "PM", - "SRB": "RS", - "SSD": "SS", - "STP": "ST", - "SU": "RU AM AZ BY EE GE KZ KG LV LT MD TJ TM UA UZ", - "SUN": "RU AM AZ BY EE GE KZ KG LV LT MD TJ TM UA UZ", - "SUR": "SR", - "SVK": "SK", - "SVN": "SI", - "SWE": "SE", - "SWZ": "SZ", - "SXM": "SX", - "SYC": "SC", - "SYR": "SY", - "TAA": "TA", - "TCA": "TC", - "TCD": "TD", - "TGO": "TG", - "THA": "TH", - "TJK": "TJ", - "TKL": "TK", - "TKM": "TM", - "TLS": "TL", - "TMP": "TL", - "TON": "TO", - "TP": "TL", - "TTO": "TT", - "TUN": "TN", - "TUR": "TR", - "TUV": "TV", - "TWN": "TW", - "TZA": "TZ", - "UGA": "UG", - "UK": "GB", - "UKR": "UA", - "UMI": "UM", - "URY": "UY", - "USA": "US", - "UZB": "UZ", - "VAT": "VA", - "VCT": "VC", - "VD": "VN", - "VEN": "VE", - "VGB": "VG", - "VIR": "VI", - "VNM": "VN", - "VUT": "VU", - "WK": "UM", - "WLF": "WF", - "WSM": "WS", - "XAA": "XA", - "XBB": "XB", - "XCC": "XC", - "XDD": "XD", - "XEE": "XE", - "XFF": "XF", - "XGG": "XG", - "XHH": "XH", - "XII": "XI", - "XJJ": "XJ", - "XKK": "XK", - "XLL": "XL", - "XMM": "XM", - "XNN": "XN", - "XOO": "XO", - "XPP": "XP", - "XQQ": "XQ", - "XRR": "XR", - "XSS": "XS", - "XTT": "XT", - "XUU": "XU", - "XVV": "XV", - "XWW": "XW", - "XXX": "XX", - "XYY": "XY", - "XZZ": "XZ", - "YD": "YE", - "YEM": "YE", - "YMD": "YE", - "YU": "RS ME", - "YUG": "RS ME", - "ZAF": "ZA", - "ZAR": "CD", - "ZMB": "ZM", - "ZR": "CD", - "ZWE": "ZW", - "ZZZ": "ZZ" - }; - exports.scriptAlias = { - "Qaai": "Zinh" - }; - exports.variantAlias = { - "heploc": "alalc97", - "polytoni": "polyton" - }; - } - }); - - // node_modules/@formatjs/intl-getcanonicallocales/src/likelySubtags.generated.js - var require_likelySubtags_generated = __commonJS({ - "node_modules/@formatjs/intl-getcanonicallocales/src/likelySubtags.generated.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.likelySubtags = void 0; - exports.likelySubtags = { - "aa": "aa-Latn-ET", - "aai": "aai-Latn-ZZ", - "aak": "aak-Latn-ZZ", - "aau": "aau-Latn-ZZ", - "ab": "ab-Cyrl-GE", - "abi": "abi-Latn-ZZ", - "abq": "abq-Cyrl-ZZ", - "abr": "abr-Latn-GH", - "abt": "abt-Latn-ZZ", - "aby": "aby-Latn-ZZ", - "acd": "acd-Latn-ZZ", - "ace": "ace-Latn-ID", - "ach": "ach-Latn-UG", - "ada": "ada-Latn-GH", - "ade": "ade-Latn-ZZ", - "adj": "adj-Latn-ZZ", - "adp": "adp-Tibt-BT", - "ady": "ady-Cyrl-RU", - "adz": "adz-Latn-ZZ", - "ae": "ae-Avst-IR", - "aeb": "aeb-Arab-TN", - "aey": "aey-Latn-ZZ", - "af": "af-Latn-ZA", - "agc": "agc-Latn-ZZ", - "agd": "agd-Latn-ZZ", - "agg": "agg-Latn-ZZ", - "agm": "agm-Latn-ZZ", - "ago": "ago-Latn-ZZ", - "agq": "agq-Latn-CM", - "aha": "aha-Latn-ZZ", - "ahl": "ahl-Latn-ZZ", - "aho": "aho-Ahom-IN", - "ajg": "ajg-Latn-ZZ", - "ak": "ak-Latn-GH", - "akk": "akk-Xsux-IQ", - "ala": "ala-Latn-ZZ", - "ali": "ali-Latn-ZZ", - "aln": "aln-Latn-XK", - "alt": "alt-Cyrl-RU", - "am": "am-Ethi-ET", - "amm": "amm-Latn-ZZ", - "amn": "amn-Latn-ZZ", - "amo": "amo-Latn-NG", - "amp": "amp-Latn-ZZ", - "an": "an-Latn-ES", - "anc": "anc-Latn-ZZ", - "ank": "ank-Latn-ZZ", - "ann": "ann-Latn-ZZ", - "any": "any-Latn-ZZ", - "aoj": "aoj-Latn-ZZ", - "aom": "aom-Latn-ZZ", - "aoz": "aoz-Latn-ID", - "apc": "apc-Arab-ZZ", - "apd": "apd-Arab-TG", - "ape": "ape-Latn-ZZ", - "apr": "apr-Latn-ZZ", - "aps": "aps-Latn-ZZ", - "apz": "apz-Latn-ZZ", - "ar": "ar-Arab-EG", - "arc": "arc-Armi-IR", - "arc-Nbat": "arc-Nbat-JO", - "arc-Palm": "arc-Palm-SY", - "arh": "arh-Latn-ZZ", - "arn": "arn-Latn-CL", - "aro": "aro-Latn-BO", - "arq": "arq-Arab-DZ", - "ars": "ars-Arab-SA", - "ary": "ary-Arab-MA", - "arz": "arz-Arab-EG", - "as": "as-Beng-IN", - "asa": "asa-Latn-TZ", - "ase": "ase-Sgnw-US", - "asg": "asg-Latn-ZZ", - "aso": "aso-Latn-ZZ", - "ast": "ast-Latn-ES", - "ata": "ata-Latn-ZZ", - "atg": "atg-Latn-ZZ", - "atj": "atj-Latn-CA", - "auy": "auy-Latn-ZZ", - "av": "av-Cyrl-RU", - "avl": "avl-Arab-ZZ", - "avn": "avn-Latn-ZZ", - "avt": "avt-Latn-ZZ", - "avu": "avu-Latn-ZZ", - "awa": "awa-Deva-IN", - "awb": "awb-Latn-ZZ", - "awo": "awo-Latn-ZZ", - "awx": "awx-Latn-ZZ", - "ay": "ay-Latn-BO", - "ayb": "ayb-Latn-ZZ", - "az": "az-Latn-AZ", - "az-Arab": "az-Arab-IR", - "az-IQ": "az-Arab-IQ", - "az-IR": "az-Arab-IR", - "az-RU": "az-Cyrl-RU", - "ba": "ba-Cyrl-RU", - "bal": "bal-Arab-PK", - "ban": "ban-Latn-ID", - "bap": "bap-Deva-NP", - "bar": "bar-Latn-AT", - "bas": "bas-Latn-CM", - "bav": "bav-Latn-ZZ", - "bax": "bax-Bamu-CM", - "bba": "bba-Latn-ZZ", - "bbb": "bbb-Latn-ZZ", - "bbc": "bbc-Latn-ID", - "bbd": "bbd-Latn-ZZ", - "bbj": "bbj-Latn-CM", - "bbp": "bbp-Latn-ZZ", - "bbr": "bbr-Latn-ZZ", - "bcf": "bcf-Latn-ZZ", - "bch": "bch-Latn-ZZ", - "bci": "bci-Latn-CI", - "bcm": "bcm-Latn-ZZ", - "bcn": "bcn-Latn-ZZ", - "bco": "bco-Latn-ZZ", - "bcq": "bcq-Ethi-ZZ", - "bcu": "bcu-Latn-ZZ", - "bdd": "bdd-Latn-ZZ", - "be": "be-Cyrl-BY", - "bef": "bef-Latn-ZZ", - "beh": "beh-Latn-ZZ", - "bej": "bej-Arab-SD", - "bem": "bem-Latn-ZM", - "bet": "bet-Latn-ZZ", - "bew": "bew-Latn-ID", - "bex": "bex-Latn-ZZ", - "bez": "bez-Latn-TZ", - "bfd": "bfd-Latn-CM", - "bfq": "bfq-Taml-IN", - "bft": "bft-Arab-PK", - "bfy": "bfy-Deva-IN", - "bg": "bg-Cyrl-BG", - "bgc": "bgc-Deva-IN", - "bgn": "bgn-Arab-PK", - "bgx": "bgx-Grek-TR", - "bhb": "bhb-Deva-IN", - "bhg": "bhg-Latn-ZZ", - "bhi": "bhi-Deva-IN", - "bhl": "bhl-Latn-ZZ", - "bho": "bho-Deva-IN", - "bhy": "bhy-Latn-ZZ", - "bi": "bi-Latn-VU", - "bib": "bib-Latn-ZZ", - "big": "big-Latn-ZZ", - "bik": "bik-Latn-PH", - "bim": "bim-Latn-ZZ", - "bin": "bin-Latn-NG", - "bio": "bio-Latn-ZZ", - "biq": "biq-Latn-ZZ", - "bjh": "bjh-Latn-ZZ", - "bji": "bji-Ethi-ZZ", - "bjj": "bjj-Deva-IN", - "bjn": "bjn-Latn-ID", - "bjo": "bjo-Latn-ZZ", - "bjr": "bjr-Latn-ZZ", - "bjt": "bjt-Latn-SN", - "bjz": "bjz-Latn-ZZ", - "bkc": "bkc-Latn-ZZ", - "bkm": "bkm-Latn-CM", - "bkq": "bkq-Latn-ZZ", - "bku": "bku-Latn-PH", - "bkv": "bkv-Latn-ZZ", - "blg": "blg-Latn-MY", - "blt": "blt-Tavt-VN", - "bm": "bm-Latn-ML", - "bmh": "bmh-Latn-ZZ", - "bmk": "bmk-Latn-ZZ", - "bmq": "bmq-Latn-ML", - "bmu": "bmu-Latn-ZZ", - "bn": "bn-Beng-BD", - "bng": "bng-Latn-ZZ", - "bnm": "bnm-Latn-ZZ", - "bnp": "bnp-Latn-ZZ", - "bo": "bo-Tibt-CN", - "boj": "boj-Latn-ZZ", - "bom": "bom-Latn-ZZ", - "bon": "bon-Latn-ZZ", - "bpy": "bpy-Beng-IN", - "bqc": "bqc-Latn-ZZ", - "bqi": "bqi-Arab-IR", - "bqp": "bqp-Latn-ZZ", - "bqv": "bqv-Latn-CI", - "br": "br-Latn-FR", - "bra": "bra-Deva-IN", - "brh": "brh-Arab-PK", - "brx": "brx-Deva-IN", - "brz": "brz-Latn-ZZ", - "bs": "bs-Latn-BA", - "bsj": "bsj-Latn-ZZ", - "bsq": "bsq-Bass-LR", - "bss": "bss-Latn-CM", - "bst": "bst-Ethi-ZZ", - "bto": "bto-Latn-PH", - "btt": "btt-Latn-ZZ", - "btv": "btv-Deva-PK", - "bua": "bua-Cyrl-RU", - "buc": "buc-Latn-YT", - "bud": "bud-Latn-ZZ", - "bug": "bug-Latn-ID", - "buk": "buk-Latn-ZZ", - "bum": "bum-Latn-CM", - "buo": "buo-Latn-ZZ", - "bus": "bus-Latn-ZZ", - "buu": "buu-Latn-ZZ", - "bvb": "bvb-Latn-GQ", - "bwd": "bwd-Latn-ZZ", - "bwr": "bwr-Latn-ZZ", - "bxh": "bxh-Latn-ZZ", - "bye": "bye-Latn-ZZ", - "byn": "byn-Ethi-ER", - "byr": "byr-Latn-ZZ", - "bys": "bys-Latn-ZZ", - "byv": "byv-Latn-CM", - "byx": "byx-Latn-ZZ", - "bza": "bza-Latn-ZZ", - "bze": "bze-Latn-ML", - "bzf": "bzf-Latn-ZZ", - "bzh": "bzh-Latn-ZZ", - "bzw": "bzw-Latn-ZZ", - "ca": "ca-Latn-ES", - "cad": "cad-Latn-US", - "can": "can-Latn-ZZ", - "cbj": "cbj-Latn-ZZ", - "cch": "cch-Latn-NG", - "ccp": "ccp-Cakm-BD", - "ce": "ce-Cyrl-RU", - "ceb": "ceb-Latn-PH", - "cfa": "cfa-Latn-ZZ", - "cgg": "cgg-Latn-UG", - "ch": "ch-Latn-GU", - "chk": "chk-Latn-FM", - "chm": "chm-Cyrl-RU", - "cho": "cho-Latn-US", - "chp": "chp-Latn-CA", - "chr": "chr-Cher-US", - "cic": "cic-Latn-US", - "cja": "cja-Arab-KH", - "cjm": "cjm-Cham-VN", - "cjv": "cjv-Latn-ZZ", - "ckb": "ckb-Arab-IQ", - "ckl": "ckl-Latn-ZZ", - "cko": "cko-Latn-ZZ", - "cky": "cky-Latn-ZZ", - "cla": "cla-Latn-ZZ", - "cme": "cme-Latn-ZZ", - "cmg": "cmg-Soyo-MN", - "co": "co-Latn-FR", - "cop": "cop-Copt-EG", - "cps": "cps-Latn-PH", - "cr": "cr-Cans-CA", - "crh": "crh-Cyrl-UA", - "crj": "crj-Cans-CA", - "crk": "crk-Cans-CA", - "crl": "crl-Cans-CA", - "crm": "crm-Cans-CA", - "crs": "crs-Latn-SC", - "cs": "cs-Latn-CZ", - "csb": "csb-Latn-PL", - "csw": "csw-Cans-CA", - "ctd": "ctd-Pauc-MM", - "cu": "cu-Cyrl-RU", - "cu-Glag": "cu-Glag-BG", - "cv": "cv-Cyrl-RU", - "cy": "cy-Latn-GB", - "da": "da-Latn-DK", - "dad": "dad-Latn-ZZ", - "daf": "daf-Latn-CI", - "dag": "dag-Latn-ZZ", - "dah": "dah-Latn-ZZ", - "dak": "dak-Latn-US", - "dar": "dar-Cyrl-RU", - "dav": "dav-Latn-KE", - "dbd": "dbd-Latn-ZZ", - "dbq": "dbq-Latn-ZZ", - "dcc": "dcc-Arab-IN", - "ddn": "ddn-Latn-ZZ", - "de": "de-Latn-DE", - "ded": "ded-Latn-ZZ", - "den": "den-Latn-CA", - "dga": "dga-Latn-ZZ", - "dgh": "dgh-Latn-ZZ", - "dgi": "dgi-Latn-ZZ", - "dgl": "dgl-Arab-ZZ", - "dgr": "dgr-Latn-CA", - "dgz": "dgz-Latn-ZZ", - "dia": "dia-Latn-ZZ", - "dje": "dje-Latn-NE", - "dmf": "dmf-Medf-NG", - "dnj": "dnj-Latn-CI", - "dob": "dob-Latn-ZZ", - "doi": "doi-Deva-IN", - "dop": "dop-Latn-ZZ", - "dow": "dow-Latn-ZZ", - "drh": "drh-Mong-CN", - "dri": "dri-Latn-ZZ", - "drs": "drs-Ethi-ZZ", - "dsb": "dsb-Latn-DE", - "dtm": "dtm-Latn-ML", - "dtp": "dtp-Latn-MY", - "dts": "dts-Latn-ZZ", - "dty": "dty-Deva-NP", - "dua": "dua-Latn-CM", - "duc": "duc-Latn-ZZ", - "dud": "dud-Latn-ZZ", - "dug": "dug-Latn-ZZ", - "dv": "dv-Thaa-MV", - "dva": "dva-Latn-ZZ", - "dww": "dww-Latn-ZZ", - "dyo": "dyo-Latn-SN", - "dyu": "dyu-Latn-BF", - "dz": "dz-Tibt-BT", - "dzg": "dzg-Latn-ZZ", - "ebu": "ebu-Latn-KE", - "ee": "ee-Latn-GH", - "efi": "efi-Latn-NG", - "egl": "egl-Latn-IT", - "egy": "egy-Egyp-EG", - "eka": "eka-Latn-ZZ", - "eky": "eky-Kali-MM", - "el": "el-Grek-GR", - "ema": "ema-Latn-ZZ", - "emi": "emi-Latn-ZZ", - "en": "en-Latn-US", - "en-Shaw": "en-Shaw-GB", - "enn": "enn-Latn-ZZ", - "enq": "enq-Latn-ZZ", - "eo": "eo-Latn-001", - "eri": "eri-Latn-ZZ", - "es": "es-Latn-ES", - "esg": "esg-Gonm-IN", - "esu": "esu-Latn-US", - "et": "et-Latn-EE", - "etr": "etr-Latn-ZZ", - "ett": "ett-Ital-IT", - "etu": "etu-Latn-ZZ", - "etx": "etx-Latn-ZZ", - "eu": "eu-Latn-ES", - "ewo": "ewo-Latn-CM", - "ext": "ext-Latn-ES", - "eza": "eza-Latn-ZZ", - "fa": "fa-Arab-IR", - "faa": "faa-Latn-ZZ", - "fab": "fab-Latn-ZZ", - "fag": "fag-Latn-ZZ", - "fai": "fai-Latn-ZZ", - "fan": "fan-Latn-GQ", - "ff": "ff-Latn-SN", - "ff-Adlm": "ff-Adlm-GN", - "ffi": "ffi-Latn-ZZ", - "ffm": "ffm-Latn-ML", - "fi": "fi-Latn-FI", - "fia": "fia-Arab-SD", - "fil": "fil-Latn-PH", - "fit": "fit-Latn-SE", - "fj": "fj-Latn-FJ", - "flr": "flr-Latn-ZZ", - "fmp": "fmp-Latn-ZZ", - "fo": "fo-Latn-FO", - "fod": "fod-Latn-ZZ", - "fon": "fon-Latn-BJ", - "for": "for-Latn-ZZ", - "fpe": "fpe-Latn-ZZ", - "fqs": "fqs-Latn-ZZ", - "fr": "fr-Latn-FR", - "frc": "frc-Latn-US", - "frp": "frp-Latn-FR", - "frr": "frr-Latn-DE", - "frs": "frs-Latn-DE", - "fub": "fub-Arab-CM", - "fud": "fud-Latn-WF", - "fue": "fue-Latn-ZZ", - "fuf": "fuf-Latn-GN", - "fuh": "fuh-Latn-ZZ", - "fuq": "fuq-Latn-NE", - "fur": "fur-Latn-IT", - "fuv": "fuv-Latn-NG", - "fuy": "fuy-Latn-ZZ", - "fvr": "fvr-Latn-SD", - "fy": "fy-Latn-NL", - "ga": "ga-Latn-IE", - "gaa": "gaa-Latn-GH", - "gaf": "gaf-Latn-ZZ", - "gag": "gag-Latn-MD", - "gah": "gah-Latn-ZZ", - "gaj": "gaj-Latn-ZZ", - "gam": "gam-Latn-ZZ", - "gan": "gan-Hans-CN", - "gaw": "gaw-Latn-ZZ", - "gay": "gay-Latn-ID", - "gba": "gba-Latn-ZZ", - "gbf": "gbf-Latn-ZZ", - "gbm": "gbm-Deva-IN", - "gby": "gby-Latn-ZZ", - "gbz": "gbz-Arab-IR", - "gcr": "gcr-Latn-GF", - "gd": "gd-Latn-GB", - "gde": "gde-Latn-ZZ", - "gdn": "gdn-Latn-ZZ", - "gdr": "gdr-Latn-ZZ", - "geb": "geb-Latn-ZZ", - "gej": "gej-Latn-ZZ", - "gel": "gel-Latn-ZZ", - "gez": "gez-Ethi-ET", - "gfk": "gfk-Latn-ZZ", - "ggn": "ggn-Deva-NP", - "ghs": "ghs-Latn-ZZ", - "gil": "gil-Latn-KI", - "gim": "gim-Latn-ZZ", - "gjk": "gjk-Arab-PK", - "gjn": "gjn-Latn-ZZ", - "gju": "gju-Arab-PK", - "gkn": "gkn-Latn-ZZ", - "gkp": "gkp-Latn-ZZ", - "gl": "gl-Latn-ES", - "glk": "glk-Arab-IR", - "gmm": "gmm-Latn-ZZ", - "gmv": "gmv-Ethi-ZZ", - "gn": "gn-Latn-PY", - "gnd": "gnd-Latn-ZZ", - "gng": "gng-Latn-ZZ", - "god": "god-Latn-ZZ", - "gof": "gof-Ethi-ZZ", - "goi": "goi-Latn-ZZ", - "gom": "gom-Deva-IN", - "gon": "gon-Telu-IN", - "gor": "gor-Latn-ID", - "gos": "gos-Latn-NL", - "got": "got-Goth-UA", - "grb": "grb-Latn-ZZ", - "grc": "grc-Cprt-CY", - "grc-Linb": "grc-Linb-GR", - "grt": "grt-Beng-IN", - "grw": "grw-Latn-ZZ", - "gsw": "gsw-Latn-CH", - "gu": "gu-Gujr-IN", - "gub": "gub-Latn-BR", - "guc": "guc-Latn-CO", - "gud": "gud-Latn-ZZ", - "gur": "gur-Latn-GH", - "guw": "guw-Latn-ZZ", - "gux": "gux-Latn-ZZ", - "guz": "guz-Latn-KE", - "gv": "gv-Latn-IM", - "gvf": "gvf-Latn-ZZ", - "gvr": "gvr-Deva-NP", - "gvs": "gvs-Latn-ZZ", - "gwc": "gwc-Arab-ZZ", - "gwi": "gwi-Latn-CA", - "gwt": "gwt-Arab-ZZ", - "gyi": "gyi-Latn-ZZ", - "ha": "ha-Latn-NG", - "ha-CM": "ha-Arab-CM", - "ha-SD": "ha-Arab-SD", - "hag": "hag-Latn-ZZ", - "hak": "hak-Hans-CN", - "ham": "ham-Latn-ZZ", - "haw": "haw-Latn-US", - "haz": "haz-Arab-AF", - "hbb": "hbb-Latn-ZZ", - "hdy": "hdy-Ethi-ZZ", - "he": "he-Hebr-IL", - "hhy": "hhy-Latn-ZZ", - "hi": "hi-Deva-IN", - "hia": "hia-Latn-ZZ", - "hif": "hif-Latn-FJ", - "hig": "hig-Latn-ZZ", - "hih": "hih-Latn-ZZ", - "hil": "hil-Latn-PH", - "hla": "hla-Latn-ZZ", - "hlu": "hlu-Hluw-TR", - "hmd": "hmd-Plrd-CN", - "hmt": "hmt-Latn-ZZ", - "hnd": "hnd-Arab-PK", - "hne": "hne-Deva-IN", - "hnj": "hnj-Hmnp-US", - "hnn": "hnn-Latn-PH", - "hno": "hno-Arab-PK", - "ho": "ho-Latn-PG", - "hoc": "hoc-Deva-IN", - "hoj": "hoj-Deva-IN", - "hot": "hot-Latn-ZZ", - "hr": "hr-Latn-HR", - "hsb": "hsb-Latn-DE", - "hsn": "hsn-Hans-CN", - "ht": "ht-Latn-HT", - "hu": "hu-Latn-HU", - "hui": "hui-Latn-ZZ", - "hy": "hy-Armn-AM", - "hz": "hz-Latn-NA", - "ia": "ia-Latn-001", - "ian": "ian-Latn-ZZ", - "iar": "iar-Latn-ZZ", - "iba": "iba-Latn-MY", - "ibb": "ibb-Latn-NG", - "iby": "iby-Latn-ZZ", - "ica": "ica-Latn-ZZ", - "ich": "ich-Latn-ZZ", - "id": "id-Latn-ID", - "idd": "idd-Latn-ZZ", - "idi": "idi-Latn-ZZ", - "idu": "idu-Latn-ZZ", - "ife": "ife-Latn-TG", - "ig": "ig-Latn-NG", - "igb": "igb-Latn-ZZ", - "ige": "ige-Latn-ZZ", - "ii": "ii-Yiii-CN", - "ijj": "ijj-Latn-ZZ", - "ik": "ik-Latn-US", - "ikk": "ikk-Latn-ZZ", - "ikt": "ikt-Latn-CA", - "ikw": "ikw-Latn-ZZ", - "ikx": "ikx-Latn-ZZ", - "ilo": "ilo-Latn-PH", - "imo": "imo-Latn-ZZ", - "in": "in-Latn-ID", - "inh": "inh-Cyrl-RU", - "io": "io-Latn-001", - "iou": "iou-Latn-ZZ", - "iri": "iri-Latn-ZZ", - "is": "is-Latn-IS", - "it": "it-Latn-IT", - "iu": "iu-Cans-CA", - "iw": "iw-Hebr-IL", - "iwm": "iwm-Latn-ZZ", - "iws": "iws-Latn-ZZ", - "izh": "izh-Latn-RU", - "izi": "izi-Latn-ZZ", - "ja": "ja-Jpan-JP", - "jab": "jab-Latn-ZZ", - "jam": "jam-Latn-JM", - "jar": "jar-Latn-ZZ", - "jbo": "jbo-Latn-001", - "jbu": "jbu-Latn-ZZ", - "jen": "jen-Latn-ZZ", - "jgk": "jgk-Latn-ZZ", - "jgo": "jgo-Latn-CM", - "ji": "ji-Hebr-UA", - "jib": "jib-Latn-ZZ", - "jmc": "jmc-Latn-TZ", - "jml": "jml-Deva-NP", - "jra": "jra-Latn-ZZ", - "jut": "jut-Latn-DK", - "jv": "jv-Latn-ID", - "jw": "jw-Latn-ID", - "ka": "ka-Geor-GE", - "kaa": "kaa-Cyrl-UZ", - "kab": "kab-Latn-DZ", - "kac": "kac-Latn-MM", - "kad": "kad-Latn-ZZ", - "kai": "kai-Latn-ZZ", - "kaj": "kaj-Latn-NG", - "kam": "kam-Latn-KE", - "kao": "kao-Latn-ML", - "kbd": "kbd-Cyrl-RU", - "kbm": "kbm-Latn-ZZ", - "kbp": "kbp-Latn-ZZ", - "kbq": "kbq-Latn-ZZ", - "kbx": "kbx-Latn-ZZ", - "kby": "kby-Arab-NE", - "kcg": "kcg-Latn-NG", - "kck": "kck-Latn-ZW", - "kcl": "kcl-Latn-ZZ", - "kct": "kct-Latn-ZZ", - "kde": "kde-Latn-TZ", - "kdh": "kdh-Latn-TG", - "kdl": "kdl-Latn-ZZ", - "kdt": "kdt-Thai-TH", - "kea": "kea-Latn-CV", - "ken": "ken-Latn-CM", - "kez": "kez-Latn-ZZ", - "kfo": "kfo-Latn-CI", - "kfr": "kfr-Deva-IN", - "kfy": "kfy-Deva-IN", - "kg": "kg-Latn-CD", - "kge": "kge-Latn-ID", - "kgf": "kgf-Latn-ZZ", - "kgp": "kgp-Latn-BR", - "kha": "kha-Latn-IN", - "khb": "khb-Talu-CN", - "khn": "khn-Deva-IN", - "khq": "khq-Latn-ML", - "khs": "khs-Latn-ZZ", - "kht": "kht-Mymr-IN", - "khw": "khw-Arab-PK", - "khz": "khz-Latn-ZZ", - "ki": "ki-Latn-KE", - "kij": "kij-Latn-ZZ", - "kiu": "kiu-Latn-TR", - "kiw": "kiw-Latn-ZZ", - "kj": "kj-Latn-NA", - "kjd": "kjd-Latn-ZZ", - "kjg": "kjg-Laoo-LA", - "kjs": "kjs-Latn-ZZ", - "kjy": "kjy-Latn-ZZ", - "kk": "kk-Cyrl-KZ", - "kk-AF": "kk-Arab-AF", - "kk-Arab": "kk-Arab-CN", - "kk-CN": "kk-Arab-CN", - "kk-IR": "kk-Arab-IR", - "kk-MN": "kk-Arab-MN", - "kkc": "kkc-Latn-ZZ", - "kkj": "kkj-Latn-CM", - "kl": "kl-Latn-GL", - "kln": "kln-Latn-KE", - "klq": "klq-Latn-ZZ", - "klt": "klt-Latn-ZZ", - "klx": "klx-Latn-ZZ", - "km": "km-Khmr-KH", - "kmb": "kmb-Latn-AO", - "kmh": "kmh-Latn-ZZ", - "kmo": "kmo-Latn-ZZ", - "kms": "kms-Latn-ZZ", - "kmu": "kmu-Latn-ZZ", - "kmw": "kmw-Latn-ZZ", - "kn": "kn-Knda-IN", - "knf": "knf-Latn-GW", - "knp": "knp-Latn-ZZ", - "ko": "ko-Kore-KR", - "koi": "koi-Cyrl-RU", - "kok": "kok-Deva-IN", - "kol": "kol-Latn-ZZ", - "kos": "kos-Latn-FM", - "koz": "koz-Latn-ZZ", - "kpe": "kpe-Latn-LR", - "kpf": "kpf-Latn-ZZ", - "kpo": "kpo-Latn-ZZ", - "kpr": "kpr-Latn-ZZ", - "kpx": "kpx-Latn-ZZ", - "kqb": "kqb-Latn-ZZ", - "kqf": "kqf-Latn-ZZ", - "kqs": "kqs-Latn-ZZ", - "kqy": "kqy-Ethi-ZZ", - "kr": "kr-Latn-ZZ", - "krc": "krc-Cyrl-RU", - "kri": "kri-Latn-SL", - "krj": "krj-Latn-PH", - "krl": "krl-Latn-RU", - "krs": "krs-Latn-ZZ", - "kru": "kru-Deva-IN", - "ks": "ks-Arab-IN", - "ksb": "ksb-Latn-TZ", - "ksd": "ksd-Latn-ZZ", - "ksf": "ksf-Latn-CM", - "ksh": "ksh-Latn-DE", - "ksj": "ksj-Latn-ZZ", - "ksr": "ksr-Latn-ZZ", - "ktb": "ktb-Ethi-ZZ", - "ktm": "ktm-Latn-ZZ", - "kto": "kto-Latn-ZZ", - "ktr": "ktr-Latn-MY", - "ku": "ku-Latn-TR", - "ku-Arab": "ku-Arab-IQ", - "ku-LB": "ku-Arab-LB", - "ku-Yezi": "ku-Yezi-GE", - "kub": "kub-Latn-ZZ", - "kud": "kud-Latn-ZZ", - "kue": "kue-Latn-ZZ", - "kuj": "kuj-Latn-ZZ", - "kum": "kum-Cyrl-RU", - "kun": "kun-Latn-ZZ", - "kup": "kup-Latn-ZZ", - "kus": "kus-Latn-ZZ", - "kv": "kv-Cyrl-RU", - "kvg": "kvg-Latn-ZZ", - "kvr": "kvr-Latn-ID", - "kvx": "kvx-Arab-PK", - "kw": "kw-Latn-GB", - "kwj": "kwj-Latn-ZZ", - "kwo": "kwo-Latn-ZZ", - "kwq": "kwq-Latn-ZZ", - "kxa": "kxa-Latn-ZZ", - "kxc": "kxc-Ethi-ZZ", - "kxe": "kxe-Latn-ZZ", - "kxl": "kxl-Deva-IN", - "kxm": "kxm-Thai-TH", - "kxp": "kxp-Arab-PK", - "kxw": "kxw-Latn-ZZ", - "kxz": "kxz-Latn-ZZ", - "ky": "ky-Cyrl-KG", - "ky-Arab": "ky-Arab-CN", - "ky-CN": "ky-Arab-CN", - "ky-Latn": "ky-Latn-TR", - "ky-TR": "ky-Latn-TR", - "kye": "kye-Latn-ZZ", - "kyx": "kyx-Latn-ZZ", - "kzh": "kzh-Arab-ZZ", - "kzj": "kzj-Latn-MY", - "kzr": "kzr-Latn-ZZ", - "kzt": "kzt-Latn-MY", - "la": "la-Latn-VA", - "lab": "lab-Lina-GR", - "lad": "lad-Hebr-IL", - "lag": "lag-Latn-TZ", - "lah": "lah-Arab-PK", - "laj": "laj-Latn-UG", - "las": "las-Latn-ZZ", - "lb": "lb-Latn-LU", - "lbe": "lbe-Cyrl-RU", - "lbu": "lbu-Latn-ZZ", - "lbw": "lbw-Latn-ID", - "lcm": "lcm-Latn-ZZ", - "lcp": "lcp-Thai-CN", - "ldb": "ldb-Latn-ZZ", - "led": "led-Latn-ZZ", - "lee": "lee-Latn-ZZ", - "lem": "lem-Latn-ZZ", - "lep": "lep-Lepc-IN", - "leq": "leq-Latn-ZZ", - "leu": "leu-Latn-ZZ", - "lez": "lez-Cyrl-RU", - "lg": "lg-Latn-UG", - "lgg": "lgg-Latn-ZZ", - "li": "li-Latn-NL", - "lia": "lia-Latn-ZZ", - "lid": "lid-Latn-ZZ", - "lif": "lif-Deva-NP", - "lif-Limb": "lif-Limb-IN", - "lig": "lig-Latn-ZZ", - "lih": "lih-Latn-ZZ", - "lij": "lij-Latn-IT", - "lis": "lis-Lisu-CN", - "ljp": "ljp-Latn-ID", - "lki": "lki-Arab-IR", - "lkt": "lkt-Latn-US", - "lle": "lle-Latn-ZZ", - "lln": "lln-Latn-ZZ", - "lmn": "lmn-Telu-IN", - "lmo": "lmo-Latn-IT", - "lmp": "lmp-Latn-ZZ", - "ln": "ln-Latn-CD", - "lns": "lns-Latn-ZZ", - "lnu": "lnu-Latn-ZZ", - "lo": "lo-Laoo-LA", - "loj": "loj-Latn-ZZ", - "lok": "lok-Latn-ZZ", - "lol": "lol-Latn-CD", - "lor": "lor-Latn-ZZ", - "los": "los-Latn-ZZ", - "loz": "loz-Latn-ZM", - "lrc": "lrc-Arab-IR", - "lt": "lt-Latn-LT", - "ltg": "ltg-Latn-LV", - "lu": "lu-Latn-CD", - "lua": "lua-Latn-CD", - "luo": "luo-Latn-KE", - "luy": "luy-Latn-KE", - "luz": "luz-Arab-IR", - "lv": "lv-Latn-LV", - "lwl": "lwl-Thai-TH", - "lzh": "lzh-Hans-CN", - "lzz": "lzz-Latn-TR", - "mad": "mad-Latn-ID", - "maf": "maf-Latn-CM", - "mag": "mag-Deva-IN", - "mai": "mai-Deva-IN", - "mak": "mak-Latn-ID", - "man": "man-Latn-GM", - "man-GN": "man-Nkoo-GN", - "man-Nkoo": "man-Nkoo-GN", - "mas": "mas-Latn-KE", - "maw": "maw-Latn-ZZ", - "maz": "maz-Latn-MX", - "mbh": "mbh-Latn-ZZ", - "mbo": "mbo-Latn-ZZ", - "mbq": "mbq-Latn-ZZ", - "mbu": "mbu-Latn-ZZ", - "mbw": "mbw-Latn-ZZ", - "mci": "mci-Latn-ZZ", - "mcp": "mcp-Latn-ZZ", - "mcq": "mcq-Latn-ZZ", - "mcr": "mcr-Latn-ZZ", - "mcu": "mcu-Latn-ZZ", - "mda": "mda-Latn-ZZ", - "mde": "mde-Arab-ZZ", - "mdf": "mdf-Cyrl-RU", - "mdh": "mdh-Latn-PH", - "mdj": "mdj-Latn-ZZ", - "mdr": "mdr-Latn-ID", - "mdx": "mdx-Ethi-ZZ", - "med": "med-Latn-ZZ", - "mee": "mee-Latn-ZZ", - "mek": "mek-Latn-ZZ", - "men": "men-Latn-SL", - "mer": "mer-Latn-KE", - "met": "met-Latn-ZZ", - "meu": "meu-Latn-ZZ", - "mfa": "mfa-Arab-TH", - "mfe": "mfe-Latn-MU", - "mfn": "mfn-Latn-ZZ", - "mfo": "mfo-Latn-ZZ", - "mfq": "mfq-Latn-ZZ", - "mg": "mg-Latn-MG", - "mgh": "mgh-Latn-MZ", - "mgl": "mgl-Latn-ZZ", - "mgo": "mgo-Latn-CM", - "mgp": "mgp-Deva-NP", - "mgy": "mgy-Latn-TZ", - "mh": "mh-Latn-MH", - "mhi": "mhi-Latn-ZZ", - "mhl": "mhl-Latn-ZZ", - "mi": "mi-Latn-NZ", - "mif": "mif-Latn-ZZ", - "min": "min-Latn-ID", - "miw": "miw-Latn-ZZ", - "mk": "mk-Cyrl-MK", - "mki": "mki-Arab-ZZ", - "mkl": "mkl-Latn-ZZ", - "mkp": "mkp-Latn-ZZ", - "mkw": "mkw-Latn-ZZ", - "ml": "ml-Mlym-IN", - "mle": "mle-Latn-ZZ", - "mlp": "mlp-Latn-ZZ", - "mls": "mls-Latn-SD", - "mmo": "mmo-Latn-ZZ", - "mmu": "mmu-Latn-ZZ", - "mmx": "mmx-Latn-ZZ", - "mn": "mn-Cyrl-MN", - "mn-CN": "mn-Mong-CN", - "mn-Mong": "mn-Mong-CN", - "mna": "mna-Latn-ZZ", - "mnf": "mnf-Latn-ZZ", - "mni": "mni-Beng-IN", - "mnw": "mnw-Mymr-MM", - "mo": "mo-Latn-RO", - "moa": "moa-Latn-ZZ", - "moe": "moe-Latn-CA", - "moh": "moh-Latn-CA", - "mos": "mos-Latn-BF", - "mox": "mox-Latn-ZZ", - "mpp": "mpp-Latn-ZZ", - "mps": "mps-Latn-ZZ", - "mpt": "mpt-Latn-ZZ", - "mpx": "mpx-Latn-ZZ", - "mql": "mql-Latn-ZZ", - "mr": "mr-Deva-IN", - "mrd": "mrd-Deva-NP", - "mrj": "mrj-Cyrl-RU", - "mro": "mro-Mroo-BD", - "ms": "ms-Latn-MY", - "ms-CC": "ms-Arab-CC", - "mt": "mt-Latn-MT", - "mtc": "mtc-Latn-ZZ", - "mtf": "mtf-Latn-ZZ", - "mti": "mti-Latn-ZZ", - "mtr": "mtr-Deva-IN", - "mua": "mua-Latn-CM", - "mur": "mur-Latn-ZZ", - "mus": "mus-Latn-US", - "mva": "mva-Latn-ZZ", - "mvn": "mvn-Latn-ZZ", - "mvy": "mvy-Arab-PK", - "mwk": "mwk-Latn-ML", - "mwr": "mwr-Deva-IN", - "mwv": "mwv-Latn-ID", - "mww": "mww-Hmnp-US", - "mxc": "mxc-Latn-ZW", - "mxm": "mxm-Latn-ZZ", - "my": "my-Mymr-MM", - "myk": "myk-Latn-ZZ", - "mym": "mym-Ethi-ZZ", - "myv": "myv-Cyrl-RU", - "myw": "myw-Latn-ZZ", - "myx": "myx-Latn-UG", - "myz": "myz-Mand-IR", - "mzk": "mzk-Latn-ZZ", - "mzm": "mzm-Latn-ZZ", - "mzn": "mzn-Arab-IR", - "mzp": "mzp-Latn-ZZ", - "mzw": "mzw-Latn-ZZ", - "mzz": "mzz-Latn-ZZ", - "na": "na-Latn-NR", - "nac": "nac-Latn-ZZ", - "naf": "naf-Latn-ZZ", - "nak": "nak-Latn-ZZ", - "nan": "nan-Hans-CN", - "nap": "nap-Latn-IT", - "naq": "naq-Latn-NA", - "nas": "nas-Latn-ZZ", - "nb": "nb-Latn-NO", - "nca": "nca-Latn-ZZ", - "nce": "nce-Latn-ZZ", - "ncf": "ncf-Latn-ZZ", - "nch": "nch-Latn-MX", - "nco": "nco-Latn-ZZ", - "ncu": "ncu-Latn-ZZ", - "nd": "nd-Latn-ZW", - "ndc": "ndc-Latn-MZ", - "nds": "nds-Latn-DE", - "ne": "ne-Deva-NP", - "neb": "neb-Latn-ZZ", - "new": "new-Deva-NP", - "nex": "nex-Latn-ZZ", - "nfr": "nfr-Latn-ZZ", - "ng": "ng-Latn-NA", - "nga": "nga-Latn-ZZ", - "ngb": "ngb-Latn-ZZ", - "ngl": "ngl-Latn-MZ", - "nhb": "nhb-Latn-ZZ", - "nhe": "nhe-Latn-MX", - "nhw": "nhw-Latn-MX", - "nif": "nif-Latn-ZZ", - "nii": "nii-Latn-ZZ", - "nij": "nij-Latn-ID", - "nin": "nin-Latn-ZZ", - "niu": "niu-Latn-NU", - "niy": "niy-Latn-ZZ", - "niz": "niz-Latn-ZZ", - "njo": "njo-Latn-IN", - "nkg": "nkg-Latn-ZZ", - "nko": "nko-Latn-ZZ", - "nl": "nl-Latn-NL", - "nmg": "nmg-Latn-CM", - "nmz": "nmz-Latn-ZZ", - "nn": "nn-Latn-NO", - "nnf": "nnf-Latn-ZZ", - "nnh": "nnh-Latn-CM", - "nnk": "nnk-Latn-ZZ", - "nnm": "nnm-Latn-ZZ", - "nnp": "nnp-Wcho-IN", - "no": "no-Latn-NO", - "nod": "nod-Lana-TH", - "noe": "noe-Deva-IN", - "non": "non-Runr-SE", - "nop": "nop-Latn-ZZ", - "nou": "nou-Latn-ZZ", - "nqo": "nqo-Nkoo-GN", - "nr": "nr-Latn-ZA", - "nrb": "nrb-Latn-ZZ", - "nsk": "nsk-Cans-CA", - "nsn": "nsn-Latn-ZZ", - "nso": "nso-Latn-ZA", - "nss": "nss-Latn-ZZ", - "nst": "nst-Tnsa-IN", - "ntm": "ntm-Latn-ZZ", - "ntr": "ntr-Latn-ZZ", - "nui": "nui-Latn-ZZ", - "nup": "nup-Latn-ZZ", - "nus": "nus-Latn-SS", - "nuv": "nuv-Latn-ZZ", - "nux": "nux-Latn-ZZ", - "nv": "nv-Latn-US", - "nwb": "nwb-Latn-ZZ", - "nxq": "nxq-Latn-CN", - "nxr": "nxr-Latn-ZZ", - "ny": "ny-Latn-MW", - "nym": "nym-Latn-TZ", - "nyn": "nyn-Latn-UG", - "nzi": "nzi-Latn-GH", - "oc": "oc-Latn-FR", - "ogc": "ogc-Latn-ZZ", - "okr": "okr-Latn-ZZ", - "okv": "okv-Latn-ZZ", - "om": "om-Latn-ET", - "ong": "ong-Latn-ZZ", - "onn": "onn-Latn-ZZ", - "ons": "ons-Latn-ZZ", - "opm": "opm-Latn-ZZ", - "or": "or-Orya-IN", - "oro": "oro-Latn-ZZ", - "oru": "oru-Arab-ZZ", - "os": "os-Cyrl-GE", - "osa": "osa-Osge-US", - "ota": "ota-Arab-ZZ", - "otk": "otk-Orkh-MN", - "oui": "oui-Ougr-143", - "ozm": "ozm-Latn-ZZ", - "pa": "pa-Guru-IN", - "pa-Arab": "pa-Arab-PK", - "pa-PK": "pa-Arab-PK", - "pag": "pag-Latn-PH", - "pal": "pal-Phli-IR", - "pal-Phlp": "pal-Phlp-CN", - "pam": "pam-Latn-PH", - "pap": "pap-Latn-AW", - "pau": "pau-Latn-PW", - "pbi": "pbi-Latn-ZZ", - "pcd": "pcd-Latn-FR", - "pcm": "pcm-Latn-NG", - "pdc": "pdc-Latn-US", - "pdt": "pdt-Latn-CA", - "ped": "ped-Latn-ZZ", - "peo": "peo-Xpeo-IR", - "pex": "pex-Latn-ZZ", - "pfl": "pfl-Latn-DE", - "phl": "phl-Arab-ZZ", - "phn": "phn-Phnx-LB", - "pil": "pil-Latn-ZZ", - "pip": "pip-Latn-ZZ", - "pka": "pka-Brah-IN", - "pko": "pko-Latn-KE", - "pl": "pl-Latn-PL", - "pla": "pla-Latn-ZZ", - "pms": "pms-Latn-IT", - "png": "png-Latn-ZZ", - "pnn": "pnn-Latn-ZZ", - "pnt": "pnt-Grek-GR", - "pon": "pon-Latn-FM", - "ppa": "ppa-Deva-IN", - "ppo": "ppo-Latn-ZZ", - "pra": "pra-Khar-PK", - "prd": "prd-Arab-IR", - "prg": "prg-Latn-001", - "ps": "ps-Arab-AF", - "pss": "pss-Latn-ZZ", - "pt": "pt-Latn-BR", - "ptp": "ptp-Latn-ZZ", - "puu": "puu-Latn-GA", - "pwa": "pwa-Latn-ZZ", - "qu": "qu-Latn-PE", - "quc": "quc-Latn-GT", - "qug": "qug-Latn-EC", - "rai": "rai-Latn-ZZ", - "raj": "raj-Deva-IN", - "rao": "rao-Latn-ZZ", - "rcf": "rcf-Latn-RE", - "rej": "rej-Latn-ID", - "rel": "rel-Latn-ZZ", - "res": "res-Latn-ZZ", - "rgn": "rgn-Latn-IT", - "rhg": "rhg-Rohg-MM", - "ria": "ria-Latn-IN", - "rif": "rif-Tfng-MA", - "rif-NL": "rif-Latn-NL", - "rjs": "rjs-Deva-NP", - "rkt": "rkt-Beng-BD", - "rm": "rm-Latn-CH", - "rmf": "rmf-Latn-FI", - "rmo": "rmo-Latn-CH", - "rmt": "rmt-Arab-IR", - "rmu": "rmu-Latn-SE", - "rn": "rn-Latn-BI", - "rna": "rna-Latn-ZZ", - "rng": "rng-Latn-MZ", - "ro": "ro-Latn-RO", - "rob": "rob-Latn-ID", - "rof": "rof-Latn-TZ", - "roo": "roo-Latn-ZZ", - "rro": "rro-Latn-ZZ", - "rtm": "rtm-Latn-FJ", - "ru": "ru-Cyrl-RU", - "rue": "rue-Cyrl-UA", - "rug": "rug-Latn-SB", - "rw": "rw-Latn-RW", - "rwk": "rwk-Latn-TZ", - "rwo": "rwo-Latn-ZZ", - "ryu": "ryu-Kana-JP", - "sa": "sa-Deva-IN", - "saf": "saf-Latn-GH", - "sah": "sah-Cyrl-RU", - "saq": "saq-Latn-KE", - "sas": "sas-Latn-ID", - "sat": "sat-Olck-IN", - "sav": "sav-Latn-SN", - "saz": "saz-Saur-IN", - "sba": "sba-Latn-ZZ", - "sbe": "sbe-Latn-ZZ", - "sbp": "sbp-Latn-TZ", - "sc": "sc-Latn-IT", - "sck": "sck-Deva-IN", - "scl": "scl-Arab-ZZ", - "scn": "scn-Latn-IT", - "sco": "sco-Latn-GB", - "scs": "scs-Latn-CA", - "sd": "sd-Arab-PK", - "sd-Deva": "sd-Deva-IN", - "sd-Khoj": "sd-Khoj-IN", - "sd-Sind": "sd-Sind-IN", - "sdc": "sdc-Latn-IT", - "sdh": "sdh-Arab-IR", - "se": "se-Latn-NO", - "sef": "sef-Latn-CI", - "seh": "seh-Latn-MZ", - "sei": "sei-Latn-MX", - "ses": "ses-Latn-ML", - "sg": "sg-Latn-CF", - "sga": "sga-Ogam-IE", - "sgs": "sgs-Latn-LT", - "sgw": "sgw-Ethi-ZZ", - "sgz": "sgz-Latn-ZZ", - "shi": "shi-Tfng-MA", - "shk": "shk-Latn-ZZ", - "shn": "shn-Mymr-MM", - "shu": "shu-Arab-ZZ", - "si": "si-Sinh-LK", - "sid": "sid-Latn-ET", - "sig": "sig-Latn-ZZ", - "sil": "sil-Latn-ZZ", - "sim": "sim-Latn-ZZ", - "sjr": "sjr-Latn-ZZ", - "sk": "sk-Latn-SK", - "skc": "skc-Latn-ZZ", - "skr": "skr-Arab-PK", - "sks": "sks-Latn-ZZ", - "sl": "sl-Latn-SI", - "sld": "sld-Latn-ZZ", - "sli": "sli-Latn-PL", - "sll": "sll-Latn-ZZ", - "sly": "sly-Latn-ID", - "sm": "sm-Latn-WS", - "sma": "sma-Latn-SE", - "smj": "smj-Latn-SE", - "smn": "smn-Latn-FI", - "smp": "smp-Samr-IL", - "smq": "smq-Latn-ZZ", - "sms": "sms-Latn-FI", - "sn": "sn-Latn-ZW", - "snc": "snc-Latn-ZZ", - "snk": "snk-Latn-ML", - "snp": "snp-Latn-ZZ", - "snx": "snx-Latn-ZZ", - "sny": "sny-Latn-ZZ", - "so": "so-Latn-SO", - "sog": "sog-Sogd-UZ", - "sok": "sok-Latn-ZZ", - "soq": "soq-Latn-ZZ", - "sou": "sou-Thai-TH", - "soy": "soy-Latn-ZZ", - "spd": "spd-Latn-ZZ", - "spl": "spl-Latn-ZZ", - "sps": "sps-Latn-ZZ", - "sq": "sq-Latn-AL", - "sr": "sr-Cyrl-RS", - "sr-ME": "sr-Latn-ME", - "sr-RO": "sr-Latn-RO", - "sr-RU": "sr-Latn-RU", - "sr-TR": "sr-Latn-TR", - "srb": "srb-Sora-IN", - "srn": "srn-Latn-SR", - "srr": "srr-Latn-SN", - "srx": "srx-Deva-IN", - "ss": "ss-Latn-ZA", - "ssd": "ssd-Latn-ZZ", - "ssg": "ssg-Latn-ZZ", - "ssy": "ssy-Latn-ER", - "st": "st-Latn-ZA", - "stk": "stk-Latn-ZZ", - "stq": "stq-Latn-DE", - "su": "su-Latn-ID", - "sua": "sua-Latn-ZZ", - "sue": "sue-Latn-ZZ", - "suk": "suk-Latn-TZ", - "sur": "sur-Latn-ZZ", - "sus": "sus-Latn-GN", - "sv": "sv-Latn-SE", - "sw": "sw-Latn-TZ", - "swb": "swb-Arab-YT", - "swc": "swc-Latn-CD", - "swg": "swg-Latn-DE", - "swp": "swp-Latn-ZZ", - "swv": "swv-Deva-IN", - "sxn": "sxn-Latn-ID", - "sxw": "sxw-Latn-ZZ", - "syl": "syl-Beng-BD", - "syr": "syr-Syrc-IQ", - "szl": "szl-Latn-PL", - "ta": "ta-Taml-IN", - "taj": "taj-Deva-NP", - "tal": "tal-Latn-ZZ", - "tan": "tan-Latn-ZZ", - "taq": "taq-Latn-ZZ", - "tbc": "tbc-Latn-ZZ", - "tbd": "tbd-Latn-ZZ", - "tbf": "tbf-Latn-ZZ", - "tbg": "tbg-Latn-ZZ", - "tbo": "tbo-Latn-ZZ", - "tbw": "tbw-Latn-PH", - "tbz": "tbz-Latn-ZZ", - "tci": "tci-Latn-ZZ", - "tcy": "tcy-Knda-IN", - "tdd": "tdd-Tale-CN", - "tdg": "tdg-Deva-NP", - "tdh": "tdh-Deva-NP", - "tdu": "tdu-Latn-MY", - "te": "te-Telu-IN", - "ted": "ted-Latn-ZZ", - "tem": "tem-Latn-SL", - "teo": "teo-Latn-UG", - "tet": "tet-Latn-TL", - "tfi": "tfi-Latn-ZZ", - "tg": "tg-Cyrl-TJ", - "tg-Arab": "tg-Arab-PK", - "tg-PK": "tg-Arab-PK", - "tgc": "tgc-Latn-ZZ", - "tgo": "tgo-Latn-ZZ", - "tgu": "tgu-Latn-ZZ", - "th": "th-Thai-TH", - "thl": "thl-Deva-NP", - "thq": "thq-Deva-NP", - "thr": "thr-Deva-NP", - "ti": "ti-Ethi-ET", - "tif": "tif-Latn-ZZ", - "tig": "tig-Ethi-ER", - "tik": "tik-Latn-ZZ", - "tim": "tim-Latn-ZZ", - "tio": "tio-Latn-ZZ", - "tiv": "tiv-Latn-NG", - "tk": "tk-Latn-TM", - "tkl": "tkl-Latn-TK", - "tkr": "tkr-Latn-AZ", - "tkt": "tkt-Deva-NP", - "tl": "tl-Latn-PH", - "tlf": "tlf-Latn-ZZ", - "tlx": "tlx-Latn-ZZ", - "tly": "tly-Latn-AZ", - "tmh": "tmh-Latn-NE", - "tmy": "tmy-Latn-ZZ", - "tn": "tn-Latn-ZA", - "tnh": "tnh-Latn-ZZ", - "to": "to-Latn-TO", - "tof": "tof-Latn-ZZ", - "tog": "tog-Latn-MW", - "toq": "toq-Latn-ZZ", - "tpi": "tpi-Latn-PG", - "tpm": "tpm-Latn-ZZ", - "tpz": "tpz-Latn-ZZ", - "tqo": "tqo-Latn-ZZ", - "tr": "tr-Latn-TR", - "tru": "tru-Latn-TR", - "trv": "trv-Latn-TW", - "trw": "trw-Arab-PK", - "ts": "ts-Latn-ZA", - "tsd": "tsd-Grek-GR", - "tsf": "tsf-Deva-NP", - "tsg": "tsg-Latn-PH", - "tsj": "tsj-Tibt-BT", - "tsw": "tsw-Latn-ZZ", - "tt": "tt-Cyrl-RU", - "ttd": "ttd-Latn-ZZ", - "tte": "tte-Latn-ZZ", - "ttj": "ttj-Latn-UG", - "ttr": "ttr-Latn-ZZ", - "tts": "tts-Thai-TH", - "ttt": "ttt-Latn-AZ", - "tuh": "tuh-Latn-ZZ", - "tul": "tul-Latn-ZZ", - "tum": "tum-Latn-MW", - "tuq": "tuq-Latn-ZZ", - "tvd": "tvd-Latn-ZZ", - "tvl": "tvl-Latn-TV", - "tvu": "tvu-Latn-ZZ", - "twh": "twh-Latn-ZZ", - "twq": "twq-Latn-NE", - "txg": "txg-Tang-CN", - "txo": "txo-Toto-IN", - "ty": "ty-Latn-PF", - "tya": "tya-Latn-ZZ", - "tyv": "tyv-Cyrl-RU", - "tzm": "tzm-Latn-MA", - "ubu": "ubu-Latn-ZZ", - "udi": "udi-Aghb-RU", - "udm": "udm-Cyrl-RU", - "ug": "ug-Arab-CN", - "ug-Cyrl": "ug-Cyrl-KZ", - "ug-KZ": "ug-Cyrl-KZ", - "ug-MN": "ug-Cyrl-MN", - "uga": "uga-Ugar-SY", - "uk": "uk-Cyrl-UA", - "uli": "uli-Latn-FM", - "umb": "umb-Latn-AO", - "und": "en-Latn-US", - "und-002": "en-Latn-NG", - "und-003": "en-Latn-US", - "und-005": "pt-Latn-BR", - "und-009": "en-Latn-AU", - "und-011": "en-Latn-NG", - "und-013": "es-Latn-MX", - "und-014": "sw-Latn-TZ", - "und-015": "ar-Arab-EG", - "und-017": "sw-Latn-CD", - "und-018": "en-Latn-ZA", - "und-019": "en-Latn-US", - "und-021": "en-Latn-US", - "und-029": "es-Latn-CU", - "und-030": "zh-Hans-CN", - "und-034": "hi-Deva-IN", - "und-035": "id-Latn-ID", - "und-039": "it-Latn-IT", - "und-053": "en-Latn-AU", - "und-054": "en-Latn-PG", - "und-057": "en-Latn-GU", - "und-061": "sm-Latn-WS", - "und-142": "zh-Hans-CN", - "und-143": "uz-Latn-UZ", - "und-145": "ar-Arab-SA", - "und-150": "ru-Cyrl-RU", - "und-151": "ru-Cyrl-RU", - "und-154": "en-Latn-GB", - "und-155": "de-Latn-DE", - "und-202": "en-Latn-NG", - "und-419": "es-Latn-419", - "und-AD": "ca-Latn-AD", - "und-Adlm": "ff-Adlm-GN", - "und-AE": "ar-Arab-AE", - "und-AF": "fa-Arab-AF", - "und-Aghb": "udi-Aghb-RU", - "und-Ahom": "aho-Ahom-IN", - "und-AL": "sq-Latn-AL", - "und-AM": "hy-Armn-AM", - "und-AO": "pt-Latn-AO", - "und-AQ": "und-Latn-AQ", - "und-AR": "es-Latn-AR", - "und-Arab": "ar-Arab-EG", - "und-Arab-CC": "ms-Arab-CC", - "und-Arab-CN": "ug-Arab-CN", - "und-Arab-GB": "ks-Arab-GB", - "und-Arab-ID": "ms-Arab-ID", - "und-Arab-IN": "ur-Arab-IN", - "und-Arab-KH": "cja-Arab-KH", - "und-Arab-MM": "rhg-Arab-MM", - "und-Arab-MN": "kk-Arab-MN", - "und-Arab-MU": "ur-Arab-MU", - "und-Arab-NG": "ha-Arab-NG", - "und-Arab-PK": "ur-Arab-PK", - "und-Arab-TG": "apd-Arab-TG", - "und-Arab-TH": "mfa-Arab-TH", - "und-Arab-TJ": "fa-Arab-TJ", - "und-Arab-TR": "az-Arab-TR", - "und-Arab-YT": "swb-Arab-YT", - "und-Armi": "arc-Armi-IR", - "und-Armn": "hy-Armn-AM", - "und-AS": "sm-Latn-AS", - "und-AT": "de-Latn-AT", - "und-Avst": "ae-Avst-IR", - "und-AW": "nl-Latn-AW", - "und-AX": "sv-Latn-AX", - "und-AZ": "az-Latn-AZ", - "und-BA": "bs-Latn-BA", - "und-Bali": "ban-Bali-ID", - "und-Bamu": "bax-Bamu-CM", - "und-Bass": "bsq-Bass-LR", - "und-Batk": "bbc-Batk-ID", - "und-BD": "bn-Beng-BD", - "und-BE": "nl-Latn-BE", - "und-Beng": "bn-Beng-BD", - "und-BF": "fr-Latn-BF", - "und-BG": "bg-Cyrl-BG", - "und-BH": "ar-Arab-BH", - "und-Bhks": "sa-Bhks-IN", - "und-BI": "rn-Latn-BI", - "und-BJ": "fr-Latn-BJ", - "und-BL": "fr-Latn-BL", - "und-BN": "ms-Latn-BN", - "und-BO": "es-Latn-BO", - "und-Bopo": "zh-Bopo-TW", - "und-BQ": "pap-Latn-BQ", - "und-BR": "pt-Latn-BR", - "und-Brah": "pka-Brah-IN", - "und-Brai": "fr-Brai-FR", - "und-BT": "dz-Tibt-BT", - "und-Bugi": "bug-Bugi-ID", - "und-Buhd": "bku-Buhd-PH", - "und-BV": "und-Latn-BV", - "und-BY": "be-Cyrl-BY", - "und-Cakm": "ccp-Cakm-BD", - "und-Cans": "cr-Cans-CA", - "und-Cari": "xcr-Cari-TR", - "und-CD": "sw-Latn-CD", - "und-CF": "fr-Latn-CF", - "und-CG": "fr-Latn-CG", - "und-CH": "de-Latn-CH", - "und-Cham": "cjm-Cham-VN", - "und-Cher": "chr-Cher-US", - "und-Chrs": "xco-Chrs-UZ", - "und-CI": "fr-Latn-CI", - "und-CL": "es-Latn-CL", - "und-CM": "fr-Latn-CM", - "und-CN": "zh-Hans-CN", - "und-CO": "es-Latn-CO", - "und-Copt": "cop-Copt-EG", - "und-CP": "und-Latn-CP", - "und-Cpmn": "und-Cpmn-CY", - "und-Cpmn-CY": "und-Cpmn-CY", - "und-Cprt": "grc-Cprt-CY", - "und-CR": "es-Latn-CR", - "und-CU": "es-Latn-CU", - "und-CV": "pt-Latn-CV", - "und-CW": "pap-Latn-CW", - "und-CY": "el-Grek-CY", - "und-Cyrl": "ru-Cyrl-RU", - "und-Cyrl-AL": "mk-Cyrl-AL", - "und-Cyrl-BA": "sr-Cyrl-BA", - "und-Cyrl-GE": "os-Cyrl-GE", - "und-Cyrl-GR": "mk-Cyrl-GR", - "und-Cyrl-MD": "uk-Cyrl-MD", - "und-Cyrl-RO": "bg-Cyrl-RO", - "und-Cyrl-SK": "uk-Cyrl-SK", - "und-Cyrl-TR": "kbd-Cyrl-TR", - "und-Cyrl-XK": "sr-Cyrl-XK", - "und-CZ": "cs-Latn-CZ", - "und-DE": "de-Latn-DE", - "und-Deva": "hi-Deva-IN", - "und-Deva-BT": "ne-Deva-BT", - "und-Deva-FJ": "hif-Deva-FJ", - "und-Deva-MU": "bho-Deva-MU", - "und-Deva-PK": "btv-Deva-PK", - "und-Diak": "dv-Diak-MV", - "und-DJ": "aa-Latn-DJ", - "und-DK": "da-Latn-DK", - "und-DO": "es-Latn-DO", - "und-Dogr": "doi-Dogr-IN", - "und-Dupl": "fr-Dupl-FR", - "und-DZ": "ar-Arab-DZ", - "und-EA": "es-Latn-EA", - "und-EC": "es-Latn-EC", - "und-EE": "et-Latn-EE", - "und-EG": "ar-Arab-EG", - "und-Egyp": "egy-Egyp-EG", - "und-EH": "ar-Arab-EH", - "und-Elba": "sq-Elba-AL", - "und-Elym": "arc-Elym-IR", - "und-ER": "ti-Ethi-ER", - "und-ES": "es-Latn-ES", - "und-ET": "am-Ethi-ET", - "und-Ethi": "am-Ethi-ET", - "und-EU": "en-Latn-IE", - "und-EZ": "de-Latn-EZ", - "und-FI": "fi-Latn-FI", - "und-FO": "fo-Latn-FO", - "und-FR": "fr-Latn-FR", - "und-GA": "fr-Latn-GA", - "und-GE": "ka-Geor-GE", - "und-Geor": "ka-Geor-GE", - "und-GF": "fr-Latn-GF", - "und-GH": "ak-Latn-GH", - "und-GL": "kl-Latn-GL", - "und-Glag": "cu-Glag-BG", - "und-GN": "fr-Latn-GN", - "und-Gong": "wsg-Gong-IN", - "und-Gonm": "esg-Gonm-IN", - "und-Goth": "got-Goth-UA", - "und-GP": "fr-Latn-GP", - "und-GQ": "es-Latn-GQ", - "und-GR": "el-Grek-GR", - "und-Gran": "sa-Gran-IN", - "und-Grek": "el-Grek-GR", - "und-Grek-TR": "bgx-Grek-TR", - "und-GS": "und-Latn-GS", - "und-GT": "es-Latn-GT", - "und-Gujr": "gu-Gujr-IN", - "und-Guru": "pa-Guru-IN", - "und-GW": "pt-Latn-GW", - "und-Hanb": "zh-Hanb-TW", - "und-Hang": "ko-Hang-KR", - "und-Hani": "zh-Hani-CN", - "und-Hano": "hnn-Hano-PH", - "und-Hans": "zh-Hans-CN", - "und-Hant": "zh-Hant-TW", - "und-Hebr": "he-Hebr-IL", - "und-Hebr-CA": "yi-Hebr-CA", - "und-Hebr-GB": "yi-Hebr-GB", - "und-Hebr-SE": "yi-Hebr-SE", - "und-Hebr-UA": "yi-Hebr-UA", - "und-Hebr-US": "yi-Hebr-US", - "und-Hira": "ja-Hira-JP", - "und-HK": "zh-Hant-HK", - "und-Hluw": "hlu-Hluw-TR", - "und-HM": "und-Latn-HM", - "und-Hmng": "hnj-Hmng-LA", - "und-Hmnp": "hnj-Hmnp-US", - "und-HN": "es-Latn-HN", - "und-HR": "hr-Latn-HR", - "und-HT": "ht-Latn-HT", - "und-HU": "hu-Latn-HU", - "und-Hung": "hu-Hung-HU", - "und-IC": "es-Latn-IC", - "und-ID": "id-Latn-ID", - "und-IL": "he-Hebr-IL", - "und-IN": "hi-Deva-IN", - "und-IQ": "ar-Arab-IQ", - "und-IR": "fa-Arab-IR", - "und-IS": "is-Latn-IS", - "und-IT": "it-Latn-IT", - "und-Ital": "ett-Ital-IT", - "und-Jamo": "ko-Jamo-KR", - "und-Java": "jv-Java-ID", - "und-JO": "ar-Arab-JO", - "und-JP": "ja-Jpan-JP", - "und-Jpan": "ja-Jpan-JP", - "und-Kali": "eky-Kali-MM", - "und-Kana": "ja-Kana-JP", - "und-KE": "sw-Latn-KE", - "und-KG": "ky-Cyrl-KG", - "und-KH": "km-Khmr-KH", - "und-Khar": "pra-Khar-PK", - "und-Khmr": "km-Khmr-KH", - "und-Khoj": "sd-Khoj-IN", - "und-Kits": "zkt-Kits-CN", - "und-KM": "ar-Arab-KM", - "und-Knda": "kn-Knda-IN", - "und-Kore": "ko-Kore-KR", - "und-KP": "ko-Kore-KP", - "und-KR": "ko-Kore-KR", - "und-Kthi": "bho-Kthi-IN", - "und-KW": "ar-Arab-KW", - "und-KZ": "ru-Cyrl-KZ", - "und-LA": "lo-Laoo-LA", - "und-Lana": "nod-Lana-TH", - "und-Laoo": "lo-Laoo-LA", - "und-Latn-AF": "tk-Latn-AF", - "und-Latn-AM": "ku-Latn-AM", - "und-Latn-CN": "za-Latn-CN", - "und-Latn-CY": "tr-Latn-CY", - "und-Latn-DZ": "fr-Latn-DZ", - "und-Latn-ET": "en-Latn-ET", - "und-Latn-GE": "ku-Latn-GE", - "und-Latn-IR": "tk-Latn-IR", - "und-Latn-KM": "fr-Latn-KM", - "und-Latn-MA": "fr-Latn-MA", - "und-Latn-MK": "sq-Latn-MK", - "und-Latn-MM": "kac-Latn-MM", - "und-Latn-MO": "pt-Latn-MO", - "und-Latn-MR": "fr-Latn-MR", - "und-Latn-RU": "krl-Latn-RU", - "und-Latn-SY": "fr-Latn-SY", - "und-Latn-TN": "fr-Latn-TN", - "und-Latn-TW": "trv-Latn-TW", - "und-Latn-UA": "pl-Latn-UA", - "und-LB": "ar-Arab-LB", - "und-Lepc": "lep-Lepc-IN", - "und-LI": "de-Latn-LI", - "und-Limb": "lif-Limb-IN", - "und-Lina": "lab-Lina-GR", - "und-Linb": "grc-Linb-GR", - "und-Lisu": "lis-Lisu-CN", - "und-LK": "si-Sinh-LK", - "und-LS": "st-Latn-LS", - "und-LT": "lt-Latn-LT", - "und-LU": "fr-Latn-LU", - "und-LV": "lv-Latn-LV", - "und-LY": "ar-Arab-LY", - "und-Lyci": "xlc-Lyci-TR", - "und-Lydi": "xld-Lydi-TR", - "und-MA": "ar-Arab-MA", - "und-Mahj": "hi-Mahj-IN", - "und-Maka": "mak-Maka-ID", - "und-Mand": "myz-Mand-IR", - "und-Mani": "xmn-Mani-CN", - "und-Marc": "bo-Marc-CN", - "und-MC": "fr-Latn-MC", - "und-MD": "ro-Latn-MD", - "und-ME": "sr-Latn-ME", - "und-Medf": "dmf-Medf-NG", - "und-Mend": "men-Mend-SL", - "und-Merc": "xmr-Merc-SD", - "und-Mero": "xmr-Mero-SD", - "und-MF": "fr-Latn-MF", - "und-MG": "mg-Latn-MG", - "und-MK": "mk-Cyrl-MK", - "und-ML": "bm-Latn-ML", - "und-Mlym": "ml-Mlym-IN", - "und-MM": "my-Mymr-MM", - "und-MN": "mn-Cyrl-MN", - "und-MO": "zh-Hant-MO", - "und-Modi": "mr-Modi-IN", - "und-Mong": "mn-Mong-CN", - "und-MQ": "fr-Latn-MQ", - "und-MR": "ar-Arab-MR", - "und-Mroo": "mro-Mroo-BD", - "und-MT": "mt-Latn-MT", - "und-Mtei": "mni-Mtei-IN", - "und-MU": "mfe-Latn-MU", - "und-Mult": "skr-Mult-PK", - "und-MV": "dv-Thaa-MV", - "und-MX": "es-Latn-MX", - "und-MY": "ms-Latn-MY", - "und-Mymr": "my-Mymr-MM", - "und-Mymr-IN": "kht-Mymr-IN", - "und-Mymr-TH": "mnw-Mymr-TH", - "und-MZ": "pt-Latn-MZ", - "und-NA": "af-Latn-NA", - "und-Nand": "sa-Nand-IN", - "und-Narb": "xna-Narb-SA", - "und-Nbat": "arc-Nbat-JO", - "und-NC": "fr-Latn-NC", - "und-NE": "ha-Latn-NE", - "und-Newa": "new-Newa-NP", - "und-NI": "es-Latn-NI", - "und-Nkoo": "man-Nkoo-GN", - "und-NL": "nl-Latn-NL", - "und-NO": "nb-Latn-NO", - "und-NP": "ne-Deva-NP", - "und-Nshu": "zhx-Nshu-CN", - "und-Ogam": "sga-Ogam-IE", - "und-Olck": "sat-Olck-IN", - "und-OM": "ar-Arab-OM", - "und-Orkh": "otk-Orkh-MN", - "und-Orya": "or-Orya-IN", - "und-Osge": "osa-Osge-US", - "und-Osma": "so-Osma-SO", - "und-Ougr": "oui-Ougr-143", - "und-PA": "es-Latn-PA", - "und-Palm": "arc-Palm-SY", - "und-Pauc": "ctd-Pauc-MM", - "und-PE": "es-Latn-PE", - "und-Perm": "kv-Perm-RU", - "und-PF": "fr-Latn-PF", - "und-PG": "tpi-Latn-PG", - "und-PH": "fil-Latn-PH", - "und-Phag": "lzh-Phag-CN", - "und-Phli": "pal-Phli-IR", - "und-Phlp": "pal-Phlp-CN", - "und-Phnx": "phn-Phnx-LB", - "und-PK": "ur-Arab-PK", - "und-PL": "pl-Latn-PL", - "und-Plrd": "hmd-Plrd-CN", - "und-PM": "fr-Latn-PM", - "und-PR": "es-Latn-PR", - "und-Prti": "xpr-Prti-IR", - "und-PS": "ar-Arab-PS", - "und-PT": "pt-Latn-PT", - "und-PW": "pau-Latn-PW", - "und-PY": "gn-Latn-PY", - "und-QA": "ar-Arab-QA", - "und-QO": "en-Latn-DG", - "und-RE": "fr-Latn-RE", - "und-Rjng": "rej-Rjng-ID", - "und-RO": "ro-Latn-RO", - "und-Rohg": "rhg-Rohg-MM", - "und-RS": "sr-Cyrl-RS", - "und-RU": "ru-Cyrl-RU", - "und-Runr": "non-Runr-SE", - "und-RW": "rw-Latn-RW", - "und-SA": "ar-Arab-SA", - "und-Samr": "smp-Samr-IL", - "und-Sarb": "xsa-Sarb-YE", - "und-Saur": "saz-Saur-IN", - "und-SC": "fr-Latn-SC", - "und-SD": "ar-Arab-SD", - "und-SE": "sv-Latn-SE", - "und-Sgnw": "ase-Sgnw-US", - "und-Shaw": "en-Shaw-GB", - "und-Shrd": "sa-Shrd-IN", - "und-SI": "sl-Latn-SI", - "und-Sidd": "sa-Sidd-IN", - "und-Sind": "sd-Sind-IN", - "und-Sinh": "si-Sinh-LK", - "und-SJ": "nb-Latn-SJ", - "und-SK": "sk-Latn-SK", - "und-SM": "it-Latn-SM", - "und-SN": "fr-Latn-SN", - "und-SO": "so-Latn-SO", - "und-Sogd": "sog-Sogd-UZ", - "und-Sogo": "sog-Sogo-UZ", - "und-Sora": "srb-Sora-IN", - "und-Soyo": "cmg-Soyo-MN", - "und-SR": "nl-Latn-SR", - "und-ST": "pt-Latn-ST", - "und-Sund": "su-Sund-ID", - "und-SV": "es-Latn-SV", - "und-SY": "ar-Arab-SY", - "und-Sylo": "syl-Sylo-BD", - "und-Syrc": "syr-Syrc-IQ", - "und-Tagb": "tbw-Tagb-PH", - "und-Takr": "doi-Takr-IN", - "und-Tale": "tdd-Tale-CN", - "und-Talu": "khb-Talu-CN", - "und-Taml": "ta-Taml-IN", - "und-Tang": "txg-Tang-CN", - "und-Tavt": "blt-Tavt-VN", - "und-TD": "fr-Latn-TD", - "und-Telu": "te-Telu-IN", - "und-TF": "fr-Latn-TF", - "und-Tfng": "zgh-Tfng-MA", - "und-TG": "fr-Latn-TG", - "und-Tglg": "fil-Tglg-PH", - "und-TH": "th-Thai-TH", - "und-Thaa": "dv-Thaa-MV", - "und-Thai": "th-Thai-TH", - "und-Thai-CN": "lcp-Thai-CN", - "und-Thai-KH": "kdt-Thai-KH", - "und-Thai-LA": "kdt-Thai-LA", - "und-Tibt": "bo-Tibt-CN", - "und-Tirh": "mai-Tirh-IN", - "und-TJ": "tg-Cyrl-TJ", - "und-TK": "tkl-Latn-TK", - "und-TL": "pt-Latn-TL", - "und-TM": "tk-Latn-TM", - "und-TN": "ar-Arab-TN", - "und-Tnsa": "nst-Tnsa-IN", - "und-TO": "to-Latn-TO", - "und-Toto": "txo-Toto-IN", - "und-TR": "tr-Latn-TR", - "und-TV": "tvl-Latn-TV", - "und-TW": "zh-Hant-TW", - "und-TZ": "sw-Latn-TZ", - "und-UA": "uk-Cyrl-UA", - "und-UG": "sw-Latn-UG", - "und-Ugar": "uga-Ugar-SY", - "und-UY": "es-Latn-UY", - "und-UZ": "uz-Latn-UZ", - "und-VA": "it-Latn-VA", - "und-Vaii": "vai-Vaii-LR", - "und-VE": "es-Latn-VE", - "und-Vith": "sq-Vith-AL", - "und-VN": "vi-Latn-VN", - "und-VU": "bi-Latn-VU", - "und-Wara": "hoc-Wara-IN", - "und-Wcho": "nnp-Wcho-IN", - "und-WF": "fr-Latn-WF", - "und-WS": "sm-Latn-WS", - "und-XK": "sq-Latn-XK", - "und-Xpeo": "peo-Xpeo-IR", - "und-Xsux": "akk-Xsux-IQ", - "und-YE": "ar-Arab-YE", - "und-Yezi": "ku-Yezi-GE", - "und-Yiii": "ii-Yiii-CN", - "und-YT": "fr-Latn-YT", - "und-Zanb": "cmg-Zanb-MN", - "und-ZW": "sn-Latn-ZW", - "unr": "unr-Beng-IN", - "unr-Deva": "unr-Deva-NP", - "unr-NP": "unr-Deva-NP", - "unx": "unx-Beng-IN", - "uok": "uok-Latn-ZZ", - "ur": "ur-Arab-PK", - "uri": "uri-Latn-ZZ", - "urt": "urt-Latn-ZZ", - "urw": "urw-Latn-ZZ", - "usa": "usa-Latn-ZZ", - "uth": "uth-Latn-ZZ", - "utr": "utr-Latn-ZZ", - "uvh": "uvh-Latn-ZZ", - "uvl": "uvl-Latn-ZZ", - "uz": "uz-Latn-UZ", - "uz-AF": "uz-Arab-AF", - "uz-Arab": "uz-Arab-AF", - "uz-CN": "uz-Cyrl-CN", - "vag": "vag-Latn-ZZ", - "vai": "vai-Vaii-LR", - "van": "van-Latn-ZZ", - "ve": "ve-Latn-ZA", - "vec": "vec-Latn-IT", - "vep": "vep-Latn-RU", - "vi": "vi-Latn-VN", - "vic": "vic-Latn-SX", - "viv": "viv-Latn-ZZ", - "vls": "vls-Latn-BE", - "vmf": "vmf-Latn-DE", - "vmw": "vmw-Latn-MZ", - "vo": "vo-Latn-001", - "vot": "vot-Latn-RU", - "vro": "vro-Latn-EE", - "vun": "vun-Latn-TZ", - "vut": "vut-Latn-ZZ", - "wa": "wa-Latn-BE", - "wae": "wae-Latn-CH", - "waj": "waj-Latn-ZZ", - "wal": "wal-Ethi-ET", - "wan": "wan-Latn-ZZ", - "war": "war-Latn-PH", - "wbp": "wbp-Latn-AU", - "wbq": "wbq-Telu-IN", - "wbr": "wbr-Deva-IN", - "wci": "wci-Latn-ZZ", - "wer": "wer-Latn-ZZ", - "wgi": "wgi-Latn-ZZ", - "whg": "whg-Latn-ZZ", - "wib": "wib-Latn-ZZ", - "wiu": "wiu-Latn-ZZ", - "wiv": "wiv-Latn-ZZ", - "wja": "wja-Latn-ZZ", - "wji": "wji-Latn-ZZ", - "wls": "wls-Latn-WF", - "wmo": "wmo-Latn-ZZ", - "wnc": "wnc-Latn-ZZ", - "wni": "wni-Arab-KM", - "wnu": "wnu-Latn-ZZ", - "wo": "wo-Latn-SN", - "wob": "wob-Latn-ZZ", - "wos": "wos-Latn-ZZ", - "wrs": "wrs-Latn-ZZ", - "wsg": "wsg-Gong-IN", - "wsk": "wsk-Latn-ZZ", - "wtm": "wtm-Deva-IN", - "wuu": "wuu-Hans-CN", - "wuv": "wuv-Latn-ZZ", - "wwa": "wwa-Latn-ZZ", - "xav": "xav-Latn-BR", - "xbi": "xbi-Latn-ZZ", - "xco": "xco-Chrs-UZ", - "xcr": "xcr-Cari-TR", - "xes": "xes-Latn-ZZ", - "xh": "xh-Latn-ZA", - "xla": "xla-Latn-ZZ", - "xlc": "xlc-Lyci-TR", - "xld": "xld-Lydi-TR", - "xmf": "xmf-Geor-GE", - "xmn": "xmn-Mani-CN", - "xmr": "xmr-Merc-SD", - "xna": "xna-Narb-SA", - "xnr": "xnr-Deva-IN", - "xog": "xog-Latn-UG", - "xon": "xon-Latn-ZZ", - "xpr": "xpr-Prti-IR", - "xrb": "xrb-Latn-ZZ", - "xsa": "xsa-Sarb-YE", - "xsi": "xsi-Latn-ZZ", - "xsm": "xsm-Latn-ZZ", - "xsr": "xsr-Deva-NP", - "xwe": "xwe-Latn-ZZ", - "yam": "yam-Latn-ZZ", - "yao": "yao-Latn-MZ", - "yap": "yap-Latn-FM", - "yas": "yas-Latn-ZZ", - "yat": "yat-Latn-ZZ", - "yav": "yav-Latn-CM", - "yay": "yay-Latn-ZZ", - "yaz": "yaz-Latn-ZZ", - "yba": "yba-Latn-ZZ", - "ybb": "ybb-Latn-CM", - "yby": "yby-Latn-ZZ", - "yer": "yer-Latn-ZZ", - "ygr": "ygr-Latn-ZZ", - "ygw": "ygw-Latn-ZZ", - "yi": "yi-Hebr-001", - "yko": "yko-Latn-ZZ", - "yle": "yle-Latn-ZZ", - "ylg": "ylg-Latn-ZZ", - "yll": "yll-Latn-ZZ", - "yml": "yml-Latn-ZZ", - "yo": "yo-Latn-NG", - "yon": "yon-Latn-ZZ", - "yrb": "yrb-Latn-ZZ", - "yre": "yre-Latn-ZZ", - "yrl": "yrl-Latn-BR", - "yss": "yss-Latn-ZZ", - "yua": "yua-Latn-MX", - "yue": "yue-Hant-HK", - "yue-CN": "yue-Hans-CN", - "yue-Hans": "yue-Hans-CN", - "yuj": "yuj-Latn-ZZ", - "yut": "yut-Latn-ZZ", - "yuw": "yuw-Latn-ZZ", - "za": "za-Latn-CN", - "zag": "zag-Latn-SD", - "zdj": "zdj-Arab-KM", - "zea": "zea-Latn-NL", - "zgh": "zgh-Tfng-MA", - "zh": "zh-Hans-CN", - "zh-AU": "zh-Hant-AU", - "zh-BN": "zh-Hant-BN", - "zh-Bopo": "zh-Bopo-TW", - "zh-GB": "zh-Hant-GB", - "zh-GF": "zh-Hant-GF", - "zh-Hanb": "zh-Hanb-TW", - "zh-Hant": "zh-Hant-TW", - "zh-HK": "zh-Hant-HK", - "zh-ID": "zh-Hant-ID", - "zh-MO": "zh-Hant-MO", - "zh-PA": "zh-Hant-PA", - "zh-PF": "zh-Hant-PF", - "zh-PH": "zh-Hant-PH", - "zh-SR": "zh-Hant-SR", - "zh-TH": "zh-Hant-TH", - "zh-TW": "zh-Hant-TW", - "zh-US": "zh-Hant-US", - "zh-VN": "zh-Hant-VN", - "zhx": "zhx-Nshu-CN", - "zia": "zia-Latn-ZZ", - "zkt": "zkt-Kits-CN", - "zlm": "zlm-Latn-TG", - "zmi": "zmi-Latn-MY", - "zne": "zne-Latn-ZZ", - "zu": "zu-Latn-ZA", - "zza": "zza-Latn-TR" - }; - } - }); - - // node_modules/@formatjs/intl-getcanonicallocales/src/canonicalizer.js - var require_canonicalizer = __commonJS({ - "node_modules/@formatjs/intl-getcanonicallocales/src/canonicalizer.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.canonicalizeUnicodeLocaleId = exports.canonicalizeUnicodeLanguageId = void 0; - var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); - var aliases_generated_1 = require_aliases_generated(); - var parser_1 = require_parser(); - var likelySubtags_generated_1 = require_likelySubtags_generated(); - var emitter_1 = require_emitter(); - function canonicalizeAttrs(strs) { - return Object.keys(strs.reduce(function(all, str) { - all[str.toLowerCase()] = 1; - return all; - }, {})).sort(); - } - function canonicalizeKVs(arr) { - var all = {}; - var result = []; - for (var _i = 0, arr_1 = arr; _i < arr_1.length; _i++) { - var kv = arr_1[_i]; - if (kv[0] in all) { - continue; - } - all[kv[0]] = 1; - if (!kv[1] || kv[1] === "true") { - result.push([kv[0].toLowerCase()]); - } else { - result.push([kv[0].toLowerCase(), kv[1].toLowerCase()]); - } - } - return result.sort(compareKV); - } - function compareKV(t1, t2) { - return t1[0] < t2[0] ? -1 : t1[0] > t2[0] ? 1 : 0; - } - function compareExtension(e1, e2) { - return e1.type < e2.type ? -1 : e1.type > e2.type ? 1 : 0; - } - function mergeVariants(v1, v2) { - var result = tslib_1.__spreadArray([], v1, true); - for (var _i = 0, v2_1 = v2; _i < v2_1.length; _i++) { - var v = v2_1[_i]; - if (v1.indexOf(v) < 0) { - result.push(v); - } - } - return result; - } - function canonicalizeUnicodeLanguageId(unicodeLanguageId) { - var finalLangAst = unicodeLanguageId; - if (unicodeLanguageId.variants.length) { - var replacedLang_1 = ""; - for (var _i = 0, _a = unicodeLanguageId.variants; _i < _a.length; _i++) { - var variant = _a[_i]; - if (replacedLang_1 = aliases_generated_1.languageAlias[(0, emitter_1.emitUnicodeLanguageId)({ - lang: unicodeLanguageId.lang, - variants: [variant] - })]) { - var replacedLangAst = (0, parser_1.parseUnicodeLanguageId)(replacedLang_1.split(parser_1.SEPARATOR)); - finalLangAst = { - lang: replacedLangAst.lang, - script: finalLangAst.script || replacedLangAst.script, - region: finalLangAst.region || replacedLangAst.region, - variants: mergeVariants(finalLangAst.variants, replacedLangAst.variants) - }; - break; - } - } - } - if (finalLangAst.script && finalLangAst.region) { - var replacedLang_2 = aliases_generated_1.languageAlias[(0, emitter_1.emitUnicodeLanguageId)({ - lang: finalLangAst.lang, - script: finalLangAst.script, - region: finalLangAst.region, - variants: [] - })]; - if (replacedLang_2) { - var replacedLangAst = (0, parser_1.parseUnicodeLanguageId)(replacedLang_2.split(parser_1.SEPARATOR)); - finalLangAst = { - lang: replacedLangAst.lang, - script: replacedLangAst.script, - region: replacedLangAst.region, - variants: finalLangAst.variants - }; - } - } - if (finalLangAst.region) { - var replacedLang_3 = aliases_generated_1.languageAlias[(0, emitter_1.emitUnicodeLanguageId)({ - lang: finalLangAst.lang, - region: finalLangAst.region, - variants: [] - })]; - if (replacedLang_3) { - var replacedLangAst = (0, parser_1.parseUnicodeLanguageId)(replacedLang_3.split(parser_1.SEPARATOR)); - finalLangAst = { - lang: replacedLangAst.lang, - script: finalLangAst.script || replacedLangAst.script, - region: replacedLangAst.region, - variants: finalLangAst.variants - }; - } - } - var replacedLang = aliases_generated_1.languageAlias[(0, emitter_1.emitUnicodeLanguageId)({ - lang: finalLangAst.lang, - variants: [] - })]; - if (replacedLang) { - var replacedLangAst = (0, parser_1.parseUnicodeLanguageId)(replacedLang.split(parser_1.SEPARATOR)); - finalLangAst = { - lang: replacedLangAst.lang, - script: finalLangAst.script || replacedLangAst.script, - region: finalLangAst.region || replacedLangAst.region, - variants: finalLangAst.variants - }; - } - if (finalLangAst.region) { - var region = finalLangAst.region.toUpperCase(); - var regionAlias = aliases_generated_1.territoryAlias[region]; - var replacedRegion = void 0; - if (regionAlias) { - var regions = regionAlias.split(" "); - replacedRegion = regions[0]; - var likelySubtag = likelySubtags_generated_1.likelySubtags[(0, emitter_1.emitUnicodeLanguageId)({ - lang: finalLangAst.lang, - script: finalLangAst.script, - variants: [] - })]; - if (likelySubtag) { - var likelyRegion = (0, parser_1.parseUnicodeLanguageId)(likelySubtag.split(parser_1.SEPARATOR)).region; - if (likelyRegion && regions.indexOf(likelyRegion) > -1) { - replacedRegion = likelyRegion; - } - } - } - if (replacedRegion) { - finalLangAst.region = replacedRegion; - } - finalLangAst.region = finalLangAst.region.toUpperCase(); - } - if (finalLangAst.script) { - finalLangAst.script = finalLangAst.script[0].toUpperCase() + finalLangAst.script.slice(1).toLowerCase(); - if (aliases_generated_1.scriptAlias[finalLangAst.script]) { - finalLangAst.script = aliases_generated_1.scriptAlias[finalLangAst.script]; - } - } - if (finalLangAst.variants.length) { - for (var i = 0; i < finalLangAst.variants.length; i++) { - var variant = finalLangAst.variants[i].toLowerCase(); - if (aliases_generated_1.variantAlias[variant]) { - var alias = aliases_generated_1.variantAlias[variant]; - if ((0, parser_1.isUnicodeVariantSubtag)(alias)) { - finalLangAst.variants[i] = alias; - } else if ((0, parser_1.isUnicodeLanguageSubtag)(alias)) { - finalLangAst.lang = alias; - } - } - } - finalLangAst.variants.sort(); - } - return finalLangAst; - } - exports.canonicalizeUnicodeLanguageId = canonicalizeUnicodeLanguageId; - function canonicalizeUnicodeLocaleId(locale) { - locale.lang = canonicalizeUnicodeLanguageId(locale.lang); - if (locale.extensions) { - for (var _i = 0, _a = locale.extensions; _i < _a.length; _i++) { - var extension = _a[_i]; - switch (extension.type) { - case "u": - extension.keywords = canonicalizeKVs(extension.keywords); - if (extension.attributes) { - extension.attributes = canonicalizeAttrs(extension.attributes); - } - break; - case "t": - if (extension.lang) { - extension.lang = canonicalizeUnicodeLanguageId(extension.lang); - } - extension.fields = canonicalizeKVs(extension.fields); - break; - default: - extension.value = extension.value.toLowerCase(); - break; - } - } - locale.extensions.sort(compareExtension); - } - return locale; - } - exports.canonicalizeUnicodeLocaleId = canonicalizeUnicodeLocaleId; - } - }); - - // node_modules/@formatjs/intl-getcanonicallocales/src/types.js - var require_types = __commonJS({ - "node_modules/@formatjs/intl-getcanonicallocales/src/types.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - } - }); - - // node_modules/@formatjs/intl-getcanonicallocales/index.js - var require_intl_getcanonicallocales = __commonJS({ - "node_modules/@formatjs/intl-getcanonicallocales/index.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.isUnicodeLanguageSubtag = exports.isUnicodeScriptSubtag = exports.isUnicodeRegionSubtag = exports.isStructurallyValidLanguageTag = exports.parseUnicodeLanguageId = exports.parseUnicodeLocaleId = exports.getCanonicalLocales = void 0; - var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); - var parser_1 = require_parser(); - var emitter_1 = require_emitter(); - var canonicalizer_1 = require_canonicalizer(); - function CanonicalizeLocaleList(locales) { - if (locales === void 0) { - return []; - } - var seen = []; - if (typeof locales === "string") { - locales = [locales]; - } - for (var _i = 0, locales_1 = locales; _i < locales_1.length; _i++) { - var locale = locales_1[_i]; - var canonicalizedTag = (0, emitter_1.emitUnicodeLocaleId)((0, canonicalizer_1.canonicalizeUnicodeLocaleId)((0, parser_1.parseUnicodeLocaleId)(locale))); - if (seen.indexOf(canonicalizedTag) < 0) { - seen.push(canonicalizedTag); - } - } - return seen; - } - function getCanonicalLocales(locales) { - return CanonicalizeLocaleList(locales); - } - exports.getCanonicalLocales = getCanonicalLocales; - var parser_2 = require_parser(); - Object.defineProperty(exports, "parseUnicodeLocaleId", { enumerable: true, get: function() { - return parser_2.parseUnicodeLocaleId; - } }); - Object.defineProperty(exports, "parseUnicodeLanguageId", { enumerable: true, get: function() { - return parser_2.parseUnicodeLanguageId; - } }); - Object.defineProperty(exports, "isStructurallyValidLanguageTag", { enumerable: true, get: function() { - return parser_2.isStructurallyValidLanguageTag; - } }); - Object.defineProperty(exports, "isUnicodeRegionSubtag", { enumerable: true, get: function() { - return parser_2.isUnicodeRegionSubtag; - } }); - Object.defineProperty(exports, "isUnicodeScriptSubtag", { enumerable: true, get: function() { - return parser_2.isUnicodeScriptSubtag; - } }); - Object.defineProperty(exports, "isUnicodeLanguageSubtag", { enumerable: true, get: function() { - return parser_2.isUnicodeLanguageSubtag; - } }); - tslib_1.__exportStar(require_types(), exports); - tslib_1.__exportStar(require_emitter(), exports); - tslib_1.__exportStar(require_likelySubtags_generated(), exports); - } - }); - - // node_modules/@formatjs/intl-locale/get_internal_slots.js - var require_get_internal_slots = __commonJS({ - "node_modules/@formatjs/intl-locale/get_internal_slots.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var internalSlotMap = /* @__PURE__ */ new WeakMap(); - function getInternalSlots(x) { - var internalSlots = internalSlotMap.get(x); - if (!internalSlots) { - internalSlots = /* @__PURE__ */ Object.create(null); - internalSlotMap.set(x, internalSlots); - } - return internalSlots; - } - exports.default = getInternalSlots; - } - }); - - // node_modules/@formatjs/intl-locale/index.js - var require_intl_locale = __commonJS({ - "node_modules/@formatjs/intl-locale/index.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.Locale = void 0; - var tslib_1 = (init_tslib_es6(), __toCommonJS(tslib_es6_exports)); - var ecma402_abstract_1 = require_ecma402_abstract(); - var intl_getcanonicallocales_1 = require_intl_getcanonicallocales(); - var get_internal_slots_1 = tslib_1.__importDefault(require_get_internal_slots()); - var RELEVANT_EXTENSION_KEYS = ["ca", "co", "hc", "kf", "kn", "nu"]; - var UNICODE_TYPE_REGEX = /^[a-z0-9]{3,8}(-[a-z0-9]{3,8})*$/i; - function applyOptionsToTag(tag, options) { - (0, ecma402_abstract_1.invariant)(typeof tag === "string", "language tag must be a string"); - (0, ecma402_abstract_1.invariant)((0, intl_getcanonicallocales_1.isStructurallyValidLanguageTag)(tag), "malformed language tag", RangeError); - var language = (0, ecma402_abstract_1.GetOption)(options, "language", "string", void 0, void 0); - if (language !== void 0) { - (0, ecma402_abstract_1.invariant)((0, intl_getcanonicallocales_1.isUnicodeLanguageSubtag)(language), "Malformed unicode_language_subtag", RangeError); - } - var script = (0, ecma402_abstract_1.GetOption)(options, "script", "string", void 0, void 0); - if (script !== void 0) { - (0, ecma402_abstract_1.invariant)((0, intl_getcanonicallocales_1.isUnicodeScriptSubtag)(script), "Malformed unicode_script_subtag", RangeError); - } - var region = (0, ecma402_abstract_1.GetOption)(options, "region", "string", void 0, void 0); - if (region !== void 0) { - (0, ecma402_abstract_1.invariant)((0, intl_getcanonicallocales_1.isUnicodeRegionSubtag)(region), "Malformed unicode_region_subtag", RangeError); - } - var languageId = (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(tag); - if (language !== void 0) { - languageId.lang = language; - } - if (script !== void 0) { - languageId.script = script; - } - if (region !== void 0) { - languageId.region = region; - } - return Intl.getCanonicalLocales((0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(tslib_1.__assign(tslib_1.__assign({}, (0, intl_getcanonicallocales_1.parseUnicodeLocaleId)(tag)), { lang: languageId })))[0]; - } - function applyUnicodeExtensionToTag(tag, options, relevantExtensionKeys) { - var unicodeExtension; - var keywords = []; - var ast = (0, intl_getcanonicallocales_1.parseUnicodeLocaleId)(tag); - for (var _i = 0, _a = ast.extensions; _i < _a.length; _i++) { - var ext = _a[_i]; - if (ext.type === "u") { - unicodeExtension = ext; - if (Array.isArray(ext.keywords)) - keywords = ext.keywords; - } - } - var result = /* @__PURE__ */ Object.create(null); - for (var _b = 0, relevantExtensionKeys_1 = relevantExtensionKeys; _b < relevantExtensionKeys_1.length; _b++) { - var key = relevantExtensionKeys_1[_b]; - var value = void 0, entry = void 0; - for (var _c = 0, keywords_1 = keywords; _c < keywords_1.length; _c++) { - var keyword = keywords_1[_c]; - if (keyword[0] === key) { - entry = keyword; - value = entry[1]; - } - } - (0, ecma402_abstract_1.invariant)(key in options, "".concat(key, " must be in options")); - var optionsValue = options[key]; - if (optionsValue !== void 0) { - (0, ecma402_abstract_1.invariant)(typeof optionsValue === "string", "Value for ".concat(key, " must be a string")); - value = optionsValue; - if (entry) { - entry[1] = value; - } else { - keywords.push([key, value]); - } - } - result[key] = value; - } - if (!unicodeExtension) { - if (keywords.length) { - ast.extensions.push({ - type: "u", - keywords, - attributes: [] - }); - } - } else { - unicodeExtension.keywords = keywords; - } - result.locale = Intl.getCanonicalLocales((0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(ast))[0]; - return result; - } - function mergeUnicodeLanguageId(lang, script, region, variants, replacement) { - if (variants === void 0) { - variants = []; - } - if (!replacement) { - return { - lang: lang || "und", - script, - region, - variants - }; - } - return { - lang: !lang || lang === "und" ? replacement.lang : lang, - script: script || replacement.script, - region: region || replacement.region, - variants: tslib_1.__spreadArray(tslib_1.__spreadArray([], variants, true), replacement.variants, true) - }; - } - function addLikelySubtags(tag) { - var ast = (0, intl_getcanonicallocales_1.parseUnicodeLocaleId)(tag); - var unicodeLangId = ast.lang; - var lang = unicodeLangId.lang, script = unicodeLangId.script, region = unicodeLangId.region, variants = unicodeLangId.variants; - if (script && region) { - var match_1 = intl_getcanonicallocales_1.likelySubtags[(0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, script, region, variants: [] })]; - if (match_1) { - var parts_1 = (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(match_1); - ast.lang = mergeUnicodeLanguageId(void 0, void 0, void 0, variants, parts_1); - return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(ast); - } - } - if (script) { - var match_2 = intl_getcanonicallocales_1.likelySubtags[(0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, script, variants: [] })]; - if (match_2) { - var parts_2 = (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(match_2); - ast.lang = mergeUnicodeLanguageId(void 0, void 0, region, variants, parts_2); - return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(ast); - } - } - if (region) { - var match_3 = intl_getcanonicallocales_1.likelySubtags[(0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, region, variants: [] })]; - if (match_3) { - var parts_3 = (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(match_3); - ast.lang = mergeUnicodeLanguageId(void 0, script, void 0, variants, parts_3); - return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(ast); - } - } - var match = intl_getcanonicallocales_1.likelySubtags[lang] || intl_getcanonicallocales_1.likelySubtags[(0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang: "und", script, variants: [] })]; - if (!match) { - throw new Error("No match for addLikelySubtags"); - } - var parts = (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(match); - ast.lang = mergeUnicodeLanguageId(void 0, script, region, variants, parts); - return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(ast); - } - function removeLikelySubtags(tag) { - var maxLocale = addLikelySubtags(tag); - if (!maxLocale) { - return tag; - } - maxLocale = (0, intl_getcanonicallocales_1.emitUnicodeLanguageId)(tslib_1.__assign(tslib_1.__assign({}, (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(maxLocale)), { variants: [] })); - var ast = (0, intl_getcanonicallocales_1.parseUnicodeLocaleId)(tag); - var _a = ast.lang, lang = _a.lang, script = _a.script, region = _a.region, variants = _a.variants; - var trial = addLikelySubtags((0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, variants: [] })); - if (trial === maxLocale) { - return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(tslib_1.__assign(tslib_1.__assign({}, ast), { lang: mergeUnicodeLanguageId(lang, void 0, void 0, variants) })); - } - if (region) { - var trial_1 = addLikelySubtags((0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, region, variants: [] })); - if (trial_1 === maxLocale) { - return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(tslib_1.__assign(tslib_1.__assign({}, ast), { lang: mergeUnicodeLanguageId(lang, void 0, region, variants) })); - } - } - if (script) { - var trial_2 = addLikelySubtags((0, intl_getcanonicallocales_1.emitUnicodeLanguageId)({ lang, script, variants: [] })); - if (trial_2 === maxLocale) { - return (0, intl_getcanonicallocales_1.emitUnicodeLocaleId)(tslib_1.__assign(tslib_1.__assign({}, ast), { lang: mergeUnicodeLanguageId(lang, script, void 0, variants) })); - } - } - return tag; - } - var Locale = ( - /** @class */ - function() { - function Locale2(tag, opts) { - var newTarget = this && this instanceof Locale2 ? this.constructor : void 0; - if (!newTarget) { - throw new TypeError("Intl.Locale must be called with 'new'"); - } - var relevantExtensionKeys = Locale2.relevantExtensionKeys; - var internalSlotsList = [ - "initializedLocale", - "locale", - "calendar", - "collation", - "hourCycle", - "numberingSystem" - ]; - if (relevantExtensionKeys.indexOf("kf") > -1) { - internalSlotsList.push("caseFirst"); - } - if (relevantExtensionKeys.indexOf("kn") > -1) { - internalSlotsList.push("numeric"); - } - if (tag === void 0) { - throw new TypeError("First argument to Intl.Locale constructor can't be empty or missing"); - } - if (typeof tag !== "string" && typeof tag !== "object") { - throw new TypeError("tag must be a string or object"); - } - var internalSlots; - if (typeof tag === "object" && (internalSlots = (0, get_internal_slots_1.default)(tag)) && internalSlots.initializedLocale) { - tag = internalSlots.locale; - } else { - tag = tag.toString(); - } - internalSlots = (0, get_internal_slots_1.default)(this); - var options = (0, ecma402_abstract_1.CoerceOptionsToObject)(opts); - tag = applyOptionsToTag(tag, options); - var opt = /* @__PURE__ */ Object.create(null); - var calendar = (0, ecma402_abstract_1.GetOption)(options, "calendar", "string", void 0, void 0); - if (calendar !== void 0) { - if (!UNICODE_TYPE_REGEX.test(calendar)) { - throw new RangeError("invalid calendar"); - } - } - opt.ca = calendar; - var collation = (0, ecma402_abstract_1.GetOption)(options, "collation", "string", void 0, void 0); - if (collation !== void 0) { - if (!UNICODE_TYPE_REGEX.test(collation)) { - throw new RangeError("invalid collation"); - } - } - opt.co = collation; - var hc = (0, ecma402_abstract_1.GetOption)(options, "hourCycle", "string", ["h11", "h12", "h23", "h24"], void 0); - opt.hc = hc; - var kf = (0, ecma402_abstract_1.GetOption)(options, "caseFirst", "string", ["upper", "lower", "false"], void 0); - opt.kf = kf; - var _kn = (0, ecma402_abstract_1.GetOption)(options, "numeric", "boolean", void 0, void 0); - var kn; - if (_kn !== void 0) { - kn = String(_kn); - } - opt.kn = kn; - var numberingSystem = (0, ecma402_abstract_1.GetOption)(options, "numberingSystem", "string", void 0, void 0); - if (numberingSystem !== void 0) { - if (!UNICODE_TYPE_REGEX.test(numberingSystem)) { - throw new RangeError("Invalid numberingSystem"); - } - } - opt.nu = numberingSystem; - var r = applyUnicodeExtensionToTag(tag, opt, relevantExtensionKeys); - internalSlots.locale = r.locale; - internalSlots.calendar = r.ca; - internalSlots.collation = r.co; - internalSlots.hourCycle = r.hc; - if (relevantExtensionKeys.indexOf("kf") > -1) { - internalSlots.caseFirst = r.kf; - } - if (relevantExtensionKeys.indexOf("kn") > -1) { - internalSlots.numeric = (0, ecma402_abstract_1.SameValue)(r.kn, "true"); - } - internalSlots.numberingSystem = r.nu; - } - Locale2.prototype.maximize = function() { - var locale = (0, get_internal_slots_1.default)(this).locale; - try { - var maximizedLocale = addLikelySubtags(locale); - return new Locale2(maximizedLocale); - } catch (e) { - return new Locale2(locale); - } - }; - Locale2.prototype.minimize = function() { - var locale = (0, get_internal_slots_1.default)(this).locale; - try { - var minimizedLocale = removeLikelySubtags(locale); - return new Locale2(minimizedLocale); - } catch (e) { - return new Locale2(locale); - } - }; - Locale2.prototype.toString = function() { - return (0, get_internal_slots_1.default)(this).locale; - }; - Object.defineProperty(Locale2.prototype, "baseName", { - get: function() { - var locale = (0, get_internal_slots_1.default)(this).locale; - return (0, intl_getcanonicallocales_1.emitUnicodeLanguageId)((0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(locale)); - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "calendar", { - get: function() { - return (0, get_internal_slots_1.default)(this).calendar; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "collation", { - get: function() { - return (0, get_internal_slots_1.default)(this).collation; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "hourCycle", { - get: function() { - return (0, get_internal_slots_1.default)(this).hourCycle; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "caseFirst", { - get: function() { - return (0, get_internal_slots_1.default)(this).caseFirst; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "numeric", { - get: function() { - return (0, get_internal_slots_1.default)(this).numeric; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "numberingSystem", { - get: function() { - return (0, get_internal_slots_1.default)(this).numberingSystem; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "language", { - /** - * https://tc39.es/proposal-intl-locale/#sec-Intl.Locale.prototype.language - */ - get: function() { - var locale = (0, get_internal_slots_1.default)(this).locale; - return (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(locale).lang; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "script", { - /** - * https://tc39.es/proposal-intl-locale/#sec-Intl.Locale.prototype.script - */ - get: function() { - var locale = (0, get_internal_slots_1.default)(this).locale; - return (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(locale).script; - }, - enumerable: false, - configurable: true - }); - Object.defineProperty(Locale2.prototype, "region", { - /** - * https://tc39.es/proposal-intl-locale/#sec-Intl.Locale.prototype.region - */ - get: function() { - var locale = (0, get_internal_slots_1.default)(this).locale; - return (0, intl_getcanonicallocales_1.parseUnicodeLanguageId)(locale).region; - }, - enumerable: false, - configurable: true - }); - Locale2.relevantExtensionKeys = RELEVANT_EXTENSION_KEYS; - return Locale2; - }() - ); - exports.Locale = Locale; - try { - if (typeof Symbol !== "undefined") { - Object.defineProperty(Locale.prototype, Symbol.toStringTag, { - value: "Intl.Locale", - writable: false, - enumerable: false, - configurable: true - }); - } - Object.defineProperty(Locale.prototype.constructor, "length", { - value: 1, - writable: false, - enumerable: false, - configurable: true - }); - } catch (e) { - } - exports.default = Locale; - } - }); - - // node_modules/@formatjs/intl-locale/should-polyfill.js - var require_should_polyfill = __commonJS({ - "node_modules/@formatjs/intl-locale/should-polyfill.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - exports.shouldPolyfill = void 0; - function hasIntlGetCanonicalLocalesBug() { - try { - return new Intl.Locale("und-x-private").toString() === "x-private"; - } catch (e) { - return true; - } - } - function shouldPolyfill() { - return !("Locale" in Intl) || hasIntlGetCanonicalLocalesBug(); - } - exports.shouldPolyfill = shouldPolyfill; - } - }); - - // node_modules/@formatjs/intl-locale/polyfill.js - var require_polyfill = __commonJS({ - "node_modules/@formatjs/intl-locale/polyfill.js"(exports) { - "use strict"; - Object.defineProperty(exports, "__esModule", { value: true }); - var _1 = require_intl_locale(); - var should_polyfill_1 = require_should_polyfill(); - if ((0, should_polyfill_1.shouldPolyfill)()) { - Object.defineProperty(Intl, "Locale", { - value: _1.Locale, - writable: true, - enumerable: false, - configurable: true - }); - } - } - }); - - // shared/js/polyfill.js - var import_polyfill = __toESM(require_polyfill()); -})(); diff --git a/package-lock.json b/package-lock.json index f331e7509a7f..3dbb4812b8bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,10 +9,10 @@ "version": "1.0.0", "dependencies": { "@duckduckgo/autoconsent": "^12.3.0", - "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#15.1.0", - "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.41.0", + "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.1.0", + "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.43.0", "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#7.3.0", - "@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1724449523" + "@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1734514764" }, "devDependencies": { "@rollup/plugin-json": "^4.1.0", @@ -58,12 +58,12 @@ } }, "node_modules/@duckduckgo/autofill": { - "resolved": "git+ssh://git@github.com/duckduckgo/duckduckgo-autofill.git#c992041d16ec10d790e6204dce9abf9966d1363c", + "resolved": "git+ssh://git@github.com/duckduckgo/duckduckgo-autofill.git#47c26dc32b94cdbcef3e6157497147917678c25c", "hasInstallScript": true, "license": "Apache-2.0" }, "node_modules/@duckduckgo/content-scope-scripts": { - "resolved": "git+ssh://git@github.com/duckduckgo/content-scope-scripts.git#c4bb146afdf0c7a93fb9a7d95b1cb255708a470d", + "resolved": "git+ssh://git@github.com/duckduckgo/content-scope-scripts.git#bc808eb735d9eb72d5c54cf2452b104b6a370e25", "license": "Apache-2.0", "workspaces": [ "injected", @@ -76,24 +76,24 @@ } }, "node_modules/@duckduckgo/privacy-dashboard": { - "resolved": "git+ssh://git@github.com/duckduckgo/privacy-dashboard.git#597bffc321a8f4b8d23b13aa0145406c393c0d8e", + "resolved": "git+ssh://git@github.com/duckduckgo/privacy-dashboard.git#e1ec13370ac302307e7d5cb172f45106da911c9e", "engines": { - "node": ">=18.0.0", + "node": ">=22.0.0", "npm": ">=9.0.0" } }, "node_modules/@duckduckgo/privacy-reference-tests": { - "resolved": "git+ssh://git@github.com/duckduckgo/privacy-reference-tests.git#6133e7d9d9cd5f1b925cab1971b4d785dc639df7", + "resolved": "git+ssh://git@github.com/duckduckgo/privacy-reference-tests.git#a75e09ff6bfff0709e6a457f1c3478326cbb3dc5", "license": "Apache-2.0" }, "node_modules/@ghostery/adblocker": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@ghostery/adblocker/-/adblocker-2.1.1.tgz", - "integrity": "sha512-FL4yWrpNTCmtbAfeLotUoo94ZyNqHdZpZRo4Qlk0guPzDGcOtW4/c84UzS9D/Z9Z4H3nWSCrW0q38pjwAbDykA==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@ghostery/adblocker/-/adblocker-2.3.1.tgz", + "integrity": "sha512-6k8ZFHjYII54a32qrKwhnTbrPfR+KPgM6GlyAiEm8OCZoewN1cfBfSw5GVpzaAB2yJ4DzazmP8Wq/UBvEk5mHg==", "license": "MPL-2.0", "dependencies": { - "@ghostery/adblocker-content": "^2.1.1", - "@ghostery/adblocker-extended-selectors": "^2.1.1", + "@ghostery/adblocker-content": "^2.3.1", + "@ghostery/adblocker-extended-selectors": "^2.3.1", "@remusao/guess-url-type": "^1.3.0", "@remusao/small": "^1.2.1", "@remusao/smaz": "^1.9.1", @@ -101,24 +101,24 @@ } }, "node_modules/@ghostery/adblocker-content": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@ghostery/adblocker-content/-/adblocker-content-2.1.1.tgz", - "integrity": "sha512-1DKHmPnlQleXapaL36xZOwwZmpdbjMP/IcWdTTzyriyCDIFlSwBDT1DJ3xg0TK61ahZMEwz1MnTGM6X99z/5rQ==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@ghostery/adblocker-content/-/adblocker-content-2.3.1.tgz", + "integrity": "sha512-8ZTY1sEE218b0EMk3Q9fv/cWwUxunSCyBOaKuviEmJY5EyvPa1VbGPuTq/Qdvo1kduD8nLEzCwgWhcT3F3TT0Q==", "license": "MPL-2.0", "dependencies": { - "@ghostery/adblocker-extended-selectors": "^2.1.1" + "@ghostery/adblocker-extended-selectors": "^2.3.1" } }, "node_modules/@ghostery/adblocker-extended-selectors": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@ghostery/adblocker-extended-selectors/-/adblocker-extended-selectors-2.1.1.tgz", - "integrity": "sha512-jEHjU2CarS2MtRYfm/6iTKMS1DVzepuwXSMKg1zTyHl+u4ZKvKNYFK7plD0nUlL5a8akyRkYwLheXnKsW3nChQ==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@ghostery/adblocker-extended-selectors/-/adblocker-extended-selectors-2.3.1.tgz", + "integrity": "sha512-hDNiOd/1V4b6NTkNnMkZUUmhMwwo8+5rpSUtQUFzCCCzy+v5izHt4rBr2RGeK5L1pNq0NbFxZJjBHFDbiQiS1A==", "license": "MPL-2.0" }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", - "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", + "version": "0.3.8", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.8.tgz", + "integrity": "sha512-imAbBGkb+ebQyxKgzv5Hu2nmROxoDOXHh80evxdoXNOrvAnVx7zimzc1Oo5h9RlfV4vPXaE2iM5pOFbvOCClWA==", "dev": true, "license": "MIT", "dependencies": { @@ -282,9 +282,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "22.10.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz", - "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==", + "version": "22.10.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.2.tgz", + "integrity": "sha512-Xxr6BBRCAOQixvonOye19wnzyDiUtTeqldOOmj3CkeblonbccA12PFwlufvRdrpjXxqnmUaeiU5EOA+7s5diUQ==", "dev": true, "license": "MIT", "dependencies": { @@ -429,9 +429,9 @@ } }, "node_modules/is-core-module": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.15.1.tgz", - "integrity": "sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==", + "version": "2.16.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.0.tgz", + "integrity": "sha512-urTSINYfAYgcbLb0yDQ6egFm6h3Mo1DcF9EkyXSRjjzdHbsulg01qhwWuXdOoUBuTkbQ80KDboXa0vFJ+BDH+g==", "dev": true, "license": "MIT", "dependencies": { @@ -518,13 +518,13 @@ } }, "node_modules/resolve": { - "version": "1.22.8", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", - "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "version": "1.22.9", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.9.tgz", + "integrity": "sha512-QxrmX1DzraFIi9PxdG5VkRfRwIgjwyud+z/iBwfRRrVmHc+P9Q7u2lSSpQ6bjr2gy5lrqIiU9vb6iAeGf2400A==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.13.0", + "is-core-module": "^2.16.0", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -647,9 +647,9 @@ } }, "node_modules/terser": { - "version": "5.36.0", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.36.0.tgz", - "integrity": "sha512-IYV9eNMuFAV4THUspIRXkLakHnV6XO7FEdtKjf/mDyrnqUg9LnlOn6/RwRvM9SZjR4GUq8Nk8zj67FzVARr74w==", + "version": "5.37.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.37.0.tgz", + "integrity": "sha512-B8wRRkmre4ERucLM/uXx4MOV5cbnOlVAqUst+1+iLKPI0dOgFO28f84ptoQt9HEI537PMzfYa/d+GEPKTRXmYA==", "dev": true, "license": "BSD-2-Clause", "dependencies": { @@ -666,18 +666,18 @@ } }, "node_modules/tldts-core": { - "version": "6.1.64", - "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.64.tgz", - "integrity": "sha512-uqnl8vGV16KsyflHOzqrYjjArjfXaU6rMPXYy2/ZWoRKCkXtghgB4VwTDXUG+t0OTGeSewNAG31/x1gCTfLt+Q==", + "version": "6.1.68", + "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.68.tgz", + "integrity": "sha512-85TdlS/DLW/gVdf2oyyzqp3ocS30WxjaL4la85EArl9cHUR/nizifKAJPziWewSZjDZS71U517/i6ciUeqtB5Q==", "license": "MIT" }, "node_modules/tldts-experimental": { - "version": "6.1.64", - "resolved": "https://registry.npmjs.org/tldts-experimental/-/tldts-experimental-6.1.64.tgz", - "integrity": "sha512-Lm6dwThCCmUecyvOJwTfZgYRP9JB6UDam//96OSvZffBtBA3GuwucIiycLT5yO5nz0ZAGV37FF1hef2HE0K8BQ==", + "version": "6.1.68", + "resolved": "https://registry.npmjs.org/tldts-experimental/-/tldts-experimental-6.1.68.tgz", + "integrity": "sha512-cQ7OdvIpATiNKu3bdyaDzn2bLqg6Ln3BpyGLyLwYfEcaNY3rXsXi+5apxtzfH/+KT30+gzN3gswdsdF+KFHflw==", "license": "MIT", "dependencies": { - "tldts-core": "^6.1.64" + "tldts-core": "^6.1.68" } }, "node_modules/undici-types": { diff --git a/package.json b/package.json index 52aeff559b23..82ee56ef9cc0 100644 --- a/package.json +++ b/package.json @@ -14,9 +14,9 @@ }, "dependencies": { "@duckduckgo/autoconsent": "^12.3.0", - "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#15.1.0", - "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.41.0", + "@duckduckgo/autofill": "github:duckduckgo/duckduckgo-autofill#16.1.0", + "@duckduckgo/content-scope-scripts": "github:duckduckgo/content-scope-scripts#6.43.0", "@duckduckgo/privacy-dashboard": "github:duckduckgo/privacy-dashboard#7.3.0", - "@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1724449523" + "@duckduckgo/privacy-reference-tests": "github:duckduckgo/privacy-reference-tests#1734514764" } } diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ProductSubscriptionManager.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ProductSubscriptionManager.kt new file mode 100644 index 000000000000..cafb99a84e7b --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/ProductSubscriptionManager.kt @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * Licensed 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 com.duckduckgo.subscriptions.impl + +import com.duckduckgo.di.scopes.AppScope +import com.duckduckgo.subscriptions.api.Product +import com.duckduckgo.subscriptions.api.SubscriptionStatus +import com.duckduckgo.subscriptions.api.Subscriptions +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus +import com.squareup.anvil.annotations.ContributesBinding +import javax.inject.Inject +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.map + +interface ProductSubscriptionManager { + + fun entitlementStatus(vararg products: Product): Flow + + enum class ProductStatus { + ACTIVE, + EXPIRED, + SIGNED_OUT, + INACTIVE, + WAITING, + INELIGIBLE, + } +} + +@ContributesBinding(AppScope::class) +class RealProductSubscriptionManager @Inject constructor( + private val subscriptions: Subscriptions, +) : ProductSubscriptionManager { + + override fun entitlementStatus(vararg products: Product): Flow = + hasEntitlement(*products).map { getEntitlementStatusInternal(it) } + + private fun hasEntitlement(vararg products: Product): Flow = + subscriptions.getEntitlementStatus().map { entitledProducts -> entitledProducts.any { products.contains(it) } } + + private suspend fun getEntitlementStatusInternal(hasValidEntitlement: Boolean): ProductStatus = when { + !hasValidEntitlement -> ProductStatus.INELIGIBLE + else -> when (subscriptions.getSubscriptionStatus()) { + SubscriptionStatus.INACTIVE, SubscriptionStatus.EXPIRED -> ProductStatus.EXPIRED + SubscriptionStatus.UNKNOWN -> ProductStatus.SIGNED_OUT + SubscriptionStatus.AUTO_RENEWABLE, SubscriptionStatus.NOT_AUTO_RENEWABLE, SubscriptionStatus.GRACE_PERIOD -> ProductStatus.ACTIVE + SubscriptionStatus.WAITING -> ProductStatus.WAITING + } + } +} diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/plugins/SubsSettingsPlugins.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/plugins/SubsSettingsPlugins.kt index 53c521b7532c..9e15531d821d 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/plugins/SubsSettingsPlugins.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/plugins/SubsSettingsPlugins.kt @@ -25,6 +25,8 @@ import com.duckduckgo.settings.api.NewSettingsFeature import com.duckduckgo.settings.api.ProSettingsPlugin import com.duckduckgo.subscriptions.impl.R import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingView +import com.duckduckgo.subscriptions.impl.settings.views.LegacyItrSettingView +import com.duckduckgo.subscriptions.impl.settings.views.LegacyPirSettingView import com.duckduckgo.subscriptions.impl.settings.views.LegacyProSettingView import com.duckduckgo.subscriptions.impl.settings.views.PirSettingView import com.duckduckgo.subscriptions.impl.settings.views.ProSettingView @@ -55,16 +57,24 @@ class ProSettings @Inject constructor(private val newSettingsFeature: NewSetting @ContributesMultibinding(scope = ActivityScope::class) @PriorityKey(300) -class PIRSettings @Inject constructor() : ProSettingsPlugin { +class PIRSettings @Inject constructor(private val newSettingsFeature: NewSettingsFeature) : ProSettingsPlugin { override fun getView(context: Context): View { - return PirSettingView(context) + return if (newSettingsFeature.self().isEnabled()) { + PirSettingView(context) + } else { + LegacyPirSettingView(context) + } } } @ContributesMultibinding(scope = ActivityScope::class) @PriorityKey(400) -class ITRSettings @Inject constructor() : ProSettingsPlugin { +class ITRSettings @Inject constructor(private val newSettingsFeature: NewSettingsFeature) : ProSettingsPlugin { override fun getView(context: Context): View { - return ItrSettingView(context) + return if (newSettingsFeature.self().isEnabled()) { + ItrSettingView(context) + } else { + LegacyItrSettingView(context) + } } } diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingView.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingView.kt index 264ef1afae4e..3029d9c278a0 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingView.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingView.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 DuckDuckGo + * Copyright (c) 2024 DuckDuckGo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,22 +20,24 @@ import android.annotation.SuppressLint import android.content.Context import android.util.AttributeSet import android.widget.FrameLayout +import androidx.core.view.isGone +import androidx.core.view.isVisible import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.lifecycle.findViewTreeViewModelStoreOwner import com.duckduckgo.anvil.annotations.InjectWith -import com.duckduckgo.common.ui.view.gone -import com.duckduckgo.common.ui.view.show import com.duckduckgo.common.ui.viewbinding.viewBinding import com.duckduckgo.common.utils.ConflatedJob import com.duckduckgo.common.utils.ViewViewModelFactory import com.duckduckgo.di.scopes.ViewScope import com.duckduckgo.navigation.api.GlobalActivityStarter +import com.duckduckgo.subscriptions.impl.R import com.duckduckgo.subscriptions.impl.SubscriptionsConstants import com.duckduckgo.subscriptions.impl.databinding.ViewItrSettingsBinding import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingViewModel.Command import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingViewModel.Command.OpenItr import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingViewModel.ViewState +import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingViewModel.ViewState.ItrState import com.duckduckgo.subscriptions.impl.ui.SubscriptionsWebViewActivityWithParams import dagger.android.support.AndroidSupportInjection import javax.inject.Inject @@ -75,10 +77,6 @@ class ItrSettingView @JvmOverloads constructor( findViewTreeLifecycleOwner()?.lifecycle?.addObserver(viewModel) - binding.itrSettings.setClickListener { - viewModel.onItr() - } - @SuppressLint("NoHardcodedCoroutineDispatcher") coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) @@ -100,10 +98,23 @@ class ItrSettingView @JvmOverloads constructor( } private fun renderView(viewState: ViewState) { - if (viewState.hasSubscription) { - binding.itrSettings.show() - } else { - binding.itrSettings.gone() + with(binding.itrSettings) { + when (viewState.itrState) { + is ItrState.Subscribed -> { + isVisible = true + setStatus(isOn = true) + setLeadingIconResource(R.drawable.ic_identity_theft_restoration_color_24) + isClickable = true + setClickListener { viewModel.onItr() } + } + ItrState.Expired, ItrState.Activating -> { + isVisible = true + isClickable = false + setStatus(isOn = false) + setLeadingIconResource(R.drawable.ic_identity_theft_restoration_grayscale_color_24) + } + ItrState.Hidden -> isGone = true + } } } diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingViewModel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingViewModel.kt index c44ce366ee81..ec91328297ca 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingViewModel.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingViewModel.kt @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023 DuckDuckGo + * Copyright (c) 2024 DuckDuckGo * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,9 +25,16 @@ import com.duckduckgo.anvil.annotations.ContributesViewModel import com.duckduckgo.di.scopes.ViewScope import com.duckduckgo.subscriptions.api.Product.ITR import com.duckduckgo.subscriptions.api.Product.ROW_ITR -import com.duckduckgo.subscriptions.api.Subscriptions +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.ACTIVE +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.EXPIRED +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.INACTIVE +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.INELIGIBLE +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.SIGNED_OUT +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.WAITING import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingViewModel.Command.OpenItr +import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingViewModel.ViewState.ItrState import javax.inject.Inject import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.Channel @@ -37,12 +44,13 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @SuppressLint("NoLifecycleObserver") // we don't observe app lifecycle @ContributesViewModel(ViewScope::class) class ItrSettingViewModel @Inject constructor( - private val subscriptions: Subscriptions, + private val productSubscriptionManager: ProductSubscriptionManager, private val pixelSender: SubscriptionPixelSender, ) : ViewModel(), DefaultLifecycleObserver { @@ -52,7 +60,16 @@ class ItrSettingViewModel @Inject constructor( private val command = Channel(1, BufferOverflow.DROP_OLDEST) internal fun commands(): Flow = command.receiveAsFlow() - data class ViewState(val hasSubscription: Boolean = false) + data class ViewState(val itrState: ItrState = ItrState.Hidden) { + + sealed class ItrState { + + data object Hidden : ItrState() + data object Subscribed : ItrState() + data object Expired : ItrState() + data object Activating : ItrState() + } + } private val _viewState = MutableStateFlow(ViewState()) val viewState = _viewState.asStateFlow() @@ -64,8 +81,16 @@ class ItrSettingViewModel @Inject constructor( override fun onCreate(owner: LifecycleOwner) { super.onCreate(owner) - subscriptions.getEntitlementStatus().onEach { - _viewState.emit(viewState.value.copy(hasSubscription = ITR in it || ROW_ITR in it)) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).onEach { status -> + val itrState = when (status) { + ACTIVE -> ItrState.Subscribed + INACTIVE, EXPIRED -> ItrState.Expired + WAITING -> ItrState.Activating + SIGNED_OUT, INELIGIBLE -> ItrState.Hidden + } + + _viewState.update { it.copy(itrState = itrState) } }.launchIn(viewModelScope) } diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingView.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingView.kt new file mode 100644 index 000000000000..bb1c9b53b093 --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingView.kt @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2023 DuckDuckGo + * + * Licensed 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 com.duckduckgo.subscriptions.impl.settings.views + +import android.annotation.SuppressLint +import android.content.Context +import android.util.AttributeSet +import android.widget.FrameLayout +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.findViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeViewModelStoreOwner +import com.duckduckgo.anvil.annotations.InjectWith +import com.duckduckgo.common.ui.view.gone +import com.duckduckgo.common.ui.view.show +import com.duckduckgo.common.ui.viewbinding.viewBinding +import com.duckduckgo.common.utils.ConflatedJob +import com.duckduckgo.common.utils.ViewViewModelFactory +import com.duckduckgo.di.scopes.ViewScope +import com.duckduckgo.navigation.api.GlobalActivityStarter +import com.duckduckgo.subscriptions.impl.SubscriptionsConstants +import com.duckduckgo.subscriptions.impl.databinding.LegacyViewItrSettingsBinding +import com.duckduckgo.subscriptions.impl.settings.views.LegacyItrSettingViewModel.Command +import com.duckduckgo.subscriptions.impl.settings.views.LegacyItrSettingViewModel.Command.OpenItr +import com.duckduckgo.subscriptions.impl.settings.views.LegacyItrSettingViewModel.ViewState +import com.duckduckgo.subscriptions.impl.ui.SubscriptionsWebViewActivityWithParams +import dagger.android.support.AndroidSupportInjection +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach + +@InjectWith(ViewScope::class) +class LegacyItrSettingView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyle: Int = 0, +) : FrameLayout(context, attrs, defStyle) { + + @Inject + lateinit var viewModelFactory: ViewViewModelFactory + + @Inject + lateinit var globalActivityStarter: GlobalActivityStarter + + private var coroutineScope: CoroutineScope? = null + + private val binding: LegacyViewItrSettingsBinding by viewBinding() + + private val viewModel: LegacyItrSettingViewModel by lazy { + ViewModelProvider(findViewTreeViewModelStoreOwner()!!, viewModelFactory)[LegacyItrSettingViewModel::class.java] + } + + private var job: ConflatedJob = ConflatedJob() + + override fun onAttachedToWindow() { + AndroidSupportInjection.inject(this) + super.onAttachedToWindow() + + findViewTreeLifecycleOwner()?.lifecycle?.addObserver(viewModel) + + binding.itrSettings.setClickListener { + viewModel.onItr() + } + + @SuppressLint("NoHardcodedCoroutineDispatcher") + coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) + + job += viewModel.commands() + .onEach { processCommands(it) } + .launchIn(coroutineScope!!) + + viewModel.viewState + .onEach { renderView(it) } + .launchIn(coroutineScope!!) + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + findViewTreeLifecycleOwner()?.lifecycle?.removeObserver(viewModel) + coroutineScope?.cancel() + job.cancel() + coroutineScope = null + } + + private fun renderView(viewState: ViewState) { + if (viewState.hasSubscription) { + binding.itrSettings.show() + } else { + binding.itrSettings.gone() + } + } + + private fun processCommands(command: Command) { + when (command) { + is OpenItr -> { + globalActivityStarter.start( + context, + SubscriptionsWebViewActivityWithParams( + url = SubscriptionsConstants.ITR_URL, + ), + ) + } + } + } +} diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingViewModel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingViewModel.kt new file mode 100644 index 000000000000..4c766866c5ed --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingViewModel.kt @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2023 DuckDuckGo + * + * Licensed 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 com.duckduckgo.subscriptions.impl.settings.views + +import android.annotation.SuppressLint +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.duckduckgo.anvil.annotations.ContributesViewModel +import com.duckduckgo.di.scopes.ViewScope +import com.duckduckgo.subscriptions.api.Product.ITR +import com.duckduckgo.subscriptions.api.Product.ROW_ITR +import com.duckduckgo.subscriptions.api.Subscriptions +import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender +import com.duckduckgo.subscriptions.impl.settings.views.LegacyItrSettingViewModel.Command.OpenItr +import javax.inject.Inject +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.launch + +@SuppressLint("NoLifecycleObserver") // we don't observe app lifecycle +@ContributesViewModel(ViewScope::class) +class LegacyItrSettingViewModel @Inject constructor( + private val subscriptions: Subscriptions, + private val pixelSender: SubscriptionPixelSender, +) : ViewModel(), DefaultLifecycleObserver { + + sealed class Command { + data object OpenItr : Command() + } + + private val command = Channel(1, BufferOverflow.DROP_OLDEST) + internal fun commands(): Flow = command.receiveAsFlow() + data class ViewState(val hasSubscription: Boolean = false) + + private val _viewState = MutableStateFlow(ViewState()) + val viewState = _viewState.asStateFlow() + + fun onItr() { + pixelSender.reportAppSettingsIdtrClick() + sendCommand(OpenItr) + } + + override fun onCreate(owner: LifecycleOwner) { + super.onCreate(owner) + subscriptions.getEntitlementStatus().onEach { + _viewState.emit(viewState.value.copy(hasSubscription = ITR in it || ROW_ITR in it)) + }.launchIn(viewModelScope) + } + + private fun sendCommand(newCommand: Command) { + viewModelScope.launch { + command.send(newCommand) + } + } +} diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingView.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingView.kt new file mode 100644 index 000000000000..9acc53b3c04f --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingView.kt @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2023 DuckDuckGo + * + * Licensed 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 com.duckduckgo.subscriptions.impl.settings.views + +import android.annotation.SuppressLint +import android.content.Context +import android.util.AttributeSet +import android.widget.FrameLayout +import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.findViewTreeLifecycleOwner +import androidx.lifecycle.findViewTreeViewModelStoreOwner +import com.duckduckgo.anvil.annotations.InjectWith +import com.duckduckgo.common.ui.view.gone +import com.duckduckgo.common.ui.view.show +import com.duckduckgo.common.ui.viewbinding.viewBinding +import com.duckduckgo.common.utils.ConflatedJob +import com.duckduckgo.common.utils.ViewViewModelFactory +import com.duckduckgo.di.scopes.ViewScope +import com.duckduckgo.navigation.api.GlobalActivityStarter +import com.duckduckgo.subscriptions.impl.databinding.LegacyViewPirSettingsBinding +import com.duckduckgo.subscriptions.impl.pir.PirActivity.Companion.PirScreenWithEmptyParams +import com.duckduckgo.subscriptions.impl.settings.views.LegacyPirSettingViewModel.Command +import com.duckduckgo.subscriptions.impl.settings.views.LegacyPirSettingViewModel.Command.OpenPir +import com.duckduckgo.subscriptions.impl.settings.views.LegacyPirSettingViewModel.ViewState +import dagger.android.support.AndroidSupportInjection +import javax.inject.Inject +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.SupervisorJob +import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach + +@InjectWith(ViewScope::class) +class LegacyPirSettingView @JvmOverloads constructor( + context: Context, + attrs: AttributeSet? = null, + defStyle: Int = 0, +) : FrameLayout(context, attrs, defStyle) { + + @Inject + lateinit var viewModelFactory: ViewViewModelFactory + + @Inject + lateinit var globalActivityStarter: GlobalActivityStarter + + private var coroutineScope: CoroutineScope? = null + + private val binding: LegacyViewPirSettingsBinding by viewBinding() + + private val viewModel: LegacyPirSettingViewModel by lazy { + ViewModelProvider(findViewTreeViewModelStoreOwner()!!, viewModelFactory)[LegacyPirSettingViewModel::class.java] + } + + private var job: ConflatedJob = ConflatedJob() + + override fun onAttachedToWindow() { + AndroidSupportInjection.inject(this) + super.onAttachedToWindow() + + findViewTreeLifecycleOwner()?.lifecycle?.addObserver(viewModel) + + binding.pirSettings.setClickListener { + viewModel.onPir() + } + + @SuppressLint("NoHardcodedCoroutineDispatcher") + coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) + + job += viewModel.commands() + .onEach { processCommands(it) } + .launchIn(coroutineScope!!) + + viewModel.viewState + .onEach { renderView(it) } + .launchIn(coroutineScope!!) + } + + override fun onDetachedFromWindow() { + super.onDetachedFromWindow() + findViewTreeLifecycleOwner()?.lifecycle?.removeObserver(viewModel) + coroutineScope?.cancel() + job.cancel() + coroutineScope = null + } + + private fun renderView(viewState: ViewState) { + if (viewState.hasSubscription) { + binding.pirSettings.show() + } else { + binding.pirSettings.gone() + } + } + + private fun processCommands(command: Command) { + when (command) { + is OpenPir -> { + globalActivityStarter.start(context, PirScreenWithEmptyParams) + } + } + } +} diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingViewModel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingViewModel.kt new file mode 100644 index 000000000000..873b9efacbe8 --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingViewModel.kt @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2023 DuckDuckGo + * + * Licensed 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 com.duckduckgo.subscriptions.impl.settings.views + +import android.annotation.SuppressLint +import androidx.lifecycle.DefaultLifecycleObserver +import androidx.lifecycle.LifecycleOwner +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.duckduckgo.anvil.annotations.ContributesViewModel +import com.duckduckgo.di.scopes.ViewScope +import com.duckduckgo.subscriptions.api.Product.PIR +import com.duckduckgo.subscriptions.api.Subscriptions +import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender +import com.duckduckgo.subscriptions.impl.settings.views.LegacyPirSettingViewModel.Command.OpenPir +import javax.inject.Inject +import kotlinx.coroutines.channels.BufferOverflow +import kotlinx.coroutines.channels.Channel +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.asStateFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.launch + +@SuppressLint("NoLifecycleObserver") // we don't observe app lifecycle +@ContributesViewModel(ViewScope::class) +class LegacyPirSettingViewModel @Inject constructor( + private val subscriptions: Subscriptions, + private val pixelSender: SubscriptionPixelSender, +) : ViewModel(), DefaultLifecycleObserver { + + sealed class Command { + data object OpenPir : Command() + } + + private val command = Channel(1, BufferOverflow.DROP_OLDEST) + internal fun commands(): Flow = command.receiveAsFlow() + data class ViewState(val hasSubscription: Boolean = false) + + private val _viewState = MutableStateFlow(ViewState()) + val viewState = _viewState.asStateFlow() + + fun onPir() { + pixelSender.reportAppSettingsPirClick() + sendCommand(OpenPir) + } + + override fun onCreate(owner: LifecycleOwner) { + super.onCreate(owner) + subscriptions.getEntitlementStatus().onEach { + _viewState.emit(viewState.value.copy(hasSubscription = it.contains(PIR))) + }.launchIn(viewModelScope) + } + + private fun sendCommand(newCommand: Command) { + viewModelScope.launch { + command.send(newCommand) + } + } +} diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingView.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingView.kt index 17c9316993ec..620e7172f5e7 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingView.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingView.kt @@ -20,22 +20,27 @@ import android.annotation.SuppressLint import android.content.Context import android.util.AttributeSet import android.widget.FrameLayout +import androidx.core.view.isGone +import androidx.core.view.isVisible import androidx.lifecycle.ViewModelProvider import androidx.lifecycle.findViewTreeLifecycleOwner import androidx.lifecycle.findViewTreeViewModelStoreOwner import com.duckduckgo.anvil.annotations.InjectWith -import com.duckduckgo.common.ui.view.gone -import com.duckduckgo.common.ui.view.show import com.duckduckgo.common.ui.viewbinding.viewBinding import com.duckduckgo.common.utils.ConflatedJob import com.duckduckgo.common.utils.ViewViewModelFactory import com.duckduckgo.di.scopes.ViewScope import com.duckduckgo.navigation.api.GlobalActivityStarter +import com.duckduckgo.subscriptions.impl.R import com.duckduckgo.subscriptions.impl.databinding.ViewPirSettingsBinding import com.duckduckgo.subscriptions.impl.pir.PirActivity.Companion.PirScreenWithEmptyParams import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.Command import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.Command.OpenPir import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.ViewState +import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.ViewState.PirState.Activating +import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.ViewState.PirState.Expired +import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.ViewState.PirState.Hidden +import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.ViewState.PirState.Subscribed import dagger.android.support.AndroidSupportInjection import javax.inject.Inject import kotlinx.coroutines.CoroutineScope @@ -74,10 +79,6 @@ class PirSettingView @JvmOverloads constructor( findViewTreeLifecycleOwner()?.lifecycle?.addObserver(viewModel) - binding.pirSettings.setClickListener { - viewModel.onPir() - } - @SuppressLint("NoHardcodedCoroutineDispatcher") coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main) @@ -99,10 +100,23 @@ class PirSettingView @JvmOverloads constructor( } private fun renderView(viewState: ViewState) { - if (viewState.hasSubscription) { - binding.pirSettings.show() - } else { - binding.pirSettings.gone() + with(binding.pirSettings) { + when (viewState.pirState) { + is Subscribed -> { + isVisible = true + setStatus(isOn = true) + setLeadingIconResource(R.drawable.ic_identity_blocked_pir_color_24) + isClickable = true + binding.pirSettings.setClickListener { viewModel.onPir() } + } + Expired, Activating -> { + isVisible = true + isClickable = false + setStatus(isOn = false) + setLeadingIconResource(R.drawable.ic_identity_blocked_pir_grayscale_color_24) + } + Hidden -> isGone = true + } } } diff --git a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModel.kt b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModel.kt index 43ae9e425988..ab54d099eba8 100644 --- a/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModel.kt +++ b/subscriptions/subscriptions-impl/src/main/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModel.kt @@ -24,9 +24,16 @@ import androidx.lifecycle.viewModelScope import com.duckduckgo.anvil.annotations.ContributesViewModel import com.duckduckgo.di.scopes.ViewScope import com.duckduckgo.subscriptions.api.Product.PIR -import com.duckduckgo.subscriptions.api.Subscriptions +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.ACTIVE +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.EXPIRED +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.INACTIVE +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.INELIGIBLE +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.SIGNED_OUT +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.WAITING import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.Command.OpenPir +import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.ViewState.PirState import javax.inject.Inject import kotlinx.coroutines.channels.BufferOverflow import kotlinx.coroutines.channels.Channel @@ -36,12 +43,13 @@ import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.receiveAsFlow +import kotlinx.coroutines.flow.update import kotlinx.coroutines.launch @SuppressLint("NoLifecycleObserver") // we don't observe app lifecycle @ContributesViewModel(ViewScope::class) class PirSettingViewModel @Inject constructor( - private val subscriptions: Subscriptions, + private val productSubscriptionManager: ProductSubscriptionManager, private val pixelSender: SubscriptionPixelSender, ) : ViewModel(), DefaultLifecycleObserver { @@ -51,7 +59,16 @@ class PirSettingViewModel @Inject constructor( private val command = Channel(1, BufferOverflow.DROP_OLDEST) internal fun commands(): Flow = command.receiveAsFlow() - data class ViewState(val hasSubscription: Boolean = false) + data class ViewState(val pirState: PirState = PirState.Hidden) { + + sealed class PirState { + + data object Hidden : PirState() + data object Subscribed : PirState() + data object Expired : PirState() + data object Activating : PirState() + } + } private val _viewState = MutableStateFlow(ViewState()) val viewState = _viewState.asStateFlow() @@ -63,8 +80,16 @@ class PirSettingViewModel @Inject constructor( override fun onCreate(owner: LifecycleOwner) { super.onCreate(owner) - subscriptions.getEntitlementStatus().onEach { - _viewState.emit(viewState.value.copy(hasSubscription = it.contains(PIR))) + + productSubscriptionManager.entitlementStatus(PIR).onEach { status -> + val pirState = when (status) { + ACTIVE -> PirState.Subscribed + INACTIVE, EXPIRED -> PirState.Expired + WAITING -> PirState.Activating + SIGNED_OUT, INELIGIBLE -> PirState.Hidden + } + + _viewState.update { it.copy(pirState = pirState) } }.launchIn(viewModelScope) } diff --git a/subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_itr_settings.xml b/subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_itr_settings.xml new file mode 100644 index 000000000000..bc64f3a43aa1 --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_itr_settings.xml @@ -0,0 +1,26 @@ + + + \ No newline at end of file diff --git a/subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_pir_settings.xml b/subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_pir_settings.xml new file mode 100644 index 000000000000..93a12f1a12d0 --- /dev/null +++ b/subscriptions/subscriptions-impl/src/main/res/layout/legacy_view_pir_settings.xml @@ -0,0 +1,26 @@ + + + \ No newline at end of file diff --git a/subscriptions/subscriptions-impl/src/main/res/layout/view_itr_settings.xml b/subscriptions/subscriptions-impl/src/main/res/layout/view_itr_settings.xml index bc64f3a43aa1..7f61756c4bd0 100644 --- a/subscriptions/subscriptions-impl/src/main/res/layout/view_itr_settings.xml +++ b/subscriptions/subscriptions-impl/src/main/res/layout/view_itr_settings.xml @@ -1,5 +1,5 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/subscriptions/subscriptions-impl/src/main/res/layout/view_pir_settings.xml b/subscriptions/subscriptions-impl/src/main/res/layout/view_pir_settings.xml index 93a12f1a12d0..3dacac16be47 100644 --- a/subscriptions/subscriptions-impl/src/main/res/layout/view_pir_settings.xml +++ b/subscriptions/subscriptions-impl/src/main/res/layout/view_pir_settings.xml @@ -14,13 +14,11 @@ ~ limitations under the License. --> - \ No newline at end of file + \ No newline at end of file diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealProductSubscriptionManagerTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealProductSubscriptionManagerTest.kt new file mode 100644 index 000000000000..82bacb20f2dc --- /dev/null +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/RealProductSubscriptionManagerTest.kt @@ -0,0 +1,278 @@ +/* + * Copyright (c) 2024 DuckDuckGo + * + * Licensed 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 com.duckduckgo.subscriptions.impl + +import android.content.Context +import android.net.Uri +import app.cash.turbine.test +import com.duckduckgo.common.test.CoroutineTestRule +import com.duckduckgo.subscriptions.api.Product +import com.duckduckgo.subscriptions.api.Product.* +import com.duckduckgo.subscriptions.api.SubscriptionStatus +import com.duckduckgo.subscriptions.api.SubscriptionStatus.* +import com.duckduckgo.subscriptions.api.Subscriptions +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.ACTIVE +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.EXPIRED +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.INELIGIBLE +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.SIGNED_OUT +import com.duckduckgo.subscriptions.impl.ProductSubscriptionManager.ProductStatus.WAITING +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flowOf +import kotlinx.coroutines.test.runTest +import org.junit.Assert.assertEquals +import org.junit.Rule +import org.junit.Test + +class RealProductSubscriptionManagerTest { + + @get:Rule + var coroutineRule = CoroutineTestRule() + + @Test + fun `when user does not have entitlement then status returns ineligible`() = runTest { + val subscriptions: Subscriptions = FakeSubscriptions(UNKNOWN) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(PIR).test { + assertEquals(INELIGIBLE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when multiple entitlement status requested and is not entitled then returns ineligible`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(UNKNOWN) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).test { + assertEquals(INELIGIBLE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has entitlement but subscription is inactive then status returns expired`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(INACTIVE, listOf(PIR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(PIR).test { + assertEquals(EXPIRED, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when multiple entitlement status requested and has single entitlement with status inactive then status returns expired`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(INACTIVE, listOf(ROW_ITR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).test { + assertEquals(EXPIRED, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has entitlement but subscription is expired then status returns expired`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.EXPIRED, listOf(PIR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(PIR).test { + assertEquals(EXPIRED, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when multiple entitlement status requested and has single entitlement with status expired then status returns expired`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.EXPIRED, listOf(ROW_ITR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).test { + assertEquals(EXPIRED, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has entitlement but subscription is unknown then status returns signed out`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(UNKNOWN, listOf(PIR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(PIR).test { + assertEquals(SIGNED_OUT, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when multiple entitlement status requested and has single entitlement with status unknown then status returns signed out`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(UNKNOWN, listOf(ROW_ITR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).test { + assertEquals(SIGNED_OUT, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has entitlement and subscription is auto renewable then status returns active`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(AUTO_RENEWABLE, listOf(PIR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(PIR).test { + assertEquals(ACTIVE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when multiple entitlement status requested and has single entitlement with status auto renewable then status returns active`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(AUTO_RENEWABLE, listOf(ROW_ITR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).test { + assertEquals(ACTIVE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has entitlement and subscription is not auto renewable then status returns active`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(NOT_AUTO_RENEWABLE, listOf(PIR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(PIR).test { + assertEquals(ACTIVE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when multiple entitlement status requested and has single entitlement with status not auto renewable then status returns active`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(NOT_AUTO_RENEWABLE, listOf(ROW_ITR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).test { + assertEquals(ACTIVE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has entitlement and subscription is grace period then status returns active`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(GRACE_PERIOD, listOf(PIR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(PIR).test { + assertEquals(ACTIVE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when multiple entitlement status requested and has single entitlement with status grace period then status returns active`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(GRACE_PERIOD, listOf(ROW_ITR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).test { + assertEquals(ACTIVE, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when user has entitlement and subscription is waiting then status returns waiting`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.WAITING, listOf(PIR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(PIR).test { + assertEquals(WAITING, awaitItem()) + awaitComplete() + } + } + + @Test + fun `when multiple entitlement status requested and has single entitlement with status waiting then status returns waiting`() = + runTest { + val subscriptions: Subscriptions = FakeSubscriptions(SubscriptionStatus.WAITING, listOf(ROW_ITR)) + + val productSubscriptionManager = RealProductSubscriptionManager(subscriptions) + + productSubscriptionManager.entitlementStatus(ITR, ROW_ITR).test { + assertEquals(WAITING, awaitItem()) + awaitComplete() + } + } +} + +private class FakeSubscriptions( + private val subscriptionStatus: SubscriptionStatus, + private val entitlements: List = emptyList(), +) : Subscriptions { + + override suspend fun isSignedIn(): Boolean = true + + override suspend fun getAccessToken(): String = "fake_access_token" + + override fun getEntitlementStatus(): Flow> = flowOf(entitlements) + + override suspend fun isEligible(): Boolean = true + + override suspend fun getSubscriptionStatus(): SubscriptionStatus = subscriptionStatus + + override fun shouldLaunchPrivacyProForUrl(url: String): Boolean = false + + override fun launchPrivacyPro( + context: Context, + uri: Uri?, + ) { + // no-op + } + + override fun isPrivacyProUrl(uri: Uri): Boolean = false +} diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingViewModelTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingViewModelTest.kt similarity index 88% rename from subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingViewModelTest.kt rename to subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingViewModelTest.kt index e738cb4971f6..bd3a2c83cfe4 100644 --- a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/ItrSettingViewModelTest.kt +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyItrSettingViewModelTest.kt @@ -5,7 +5,7 @@ import com.duckduckgo.common.test.CoroutineTestRule import com.duckduckgo.subscriptions.api.Product.ITR import com.duckduckgo.subscriptions.api.Subscriptions import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender -import com.duckduckgo.subscriptions.impl.settings.views.ItrSettingViewModel.Command.OpenItr +import com.duckduckgo.subscriptions.impl.settings.views.LegacyItrSettingViewModel.Command.OpenItr import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest @@ -18,17 +18,17 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.whenever @ExperimentalCoroutinesApi -class ItrSettingViewModelTest { +class LegacyItrSettingViewModelTest { @get:Rule val coroutineTestRule: CoroutineTestRule = CoroutineTestRule() private val subscriptions: Subscriptions = mock() private val pixelSender: SubscriptionPixelSender = mock() - private lateinit var viewModel: ItrSettingViewModel + private lateinit var viewModel: LegacyItrSettingViewModel @Before fun before() { - viewModel = ItrSettingViewModel(subscriptions, pixelSender) + viewModel = LegacyItrSettingViewModel(subscriptions, pixelSender) } @Test diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModelTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingViewModelTest.kt similarity index 87% rename from subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModelTest.kt rename to subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingViewModelTest.kt index ed5b5010d19e..78f7f1d26fc1 100644 --- a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/PirSettingViewModelTest.kt +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyPirSettingViewModelTest.kt @@ -5,7 +5,7 @@ import com.duckduckgo.common.test.CoroutineTestRule import com.duckduckgo.subscriptions.api.Product.PIR import com.duckduckgo.subscriptions.api.Subscriptions import com.duckduckgo.subscriptions.impl.pixels.SubscriptionPixelSender -import com.duckduckgo.subscriptions.impl.settings.views.PirSettingViewModel.Command.OpenPir +import com.duckduckgo.subscriptions.impl.settings.views.LegacyPirSettingViewModel.Command.OpenPir import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runTest @@ -18,17 +18,17 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.whenever @ExperimentalCoroutinesApi -class PirSettingViewModelTest { +class LegacyPirSettingViewModelTest { @get:Rule val coroutineTestRule: CoroutineTestRule = CoroutineTestRule() private val subscriptions: Subscriptions = mock() private val pixelSender: SubscriptionPixelSender = mock() - private lateinit var viewModel: PirSettingViewModel + private lateinit var viewModel: LegacyPirSettingViewModel @Before fun before() { - viewModel = PirSettingViewModel(subscriptions, pixelSender) + viewModel = LegacyPirSettingViewModel(subscriptions, pixelSender) } @Test diff --git a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyLegacyProSettingViewModelTest.kt b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModelTest.kt similarity index 98% rename from subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyLegacyProSettingViewModelTest.kt rename to subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModelTest.kt index f1587dca900b..5cac8f322433 100644 --- a/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyLegacyProSettingViewModelTest.kt +++ b/subscriptions/subscriptions-impl/src/test/java/com/duckduckgo/subscriptions/impl/settings/views/LegacyProSettingViewModelTest.kt @@ -19,7 +19,7 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.verifyNoMoreInteractions import org.mockito.kotlin.whenever -class LegacyLegacyProSettingViewModelTest { +class LegacyProSettingViewModelTest { @get:Rule val coroutineTestRule: CoroutineTestRule = CoroutineTestRule()