diff --git a/Cargo.toml b/Cargo.toml index f01c2681..5b8f3bfe 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -263,6 +263,9 @@ depends = "$auto, passwd, libssl3, adduser" [package.metadata.deb.variants.ubuntu-noble] depends = "$auto, passwd, libssl3" +[package.metadata.deb.variants.ubuntu-resolute] +depends = "$auto, passwd, libssl3" + # Cross compilation variants: # Note: we have to specifiy dependencies manually because we don't run cargo-deb # on the target platform and so it cannot determine the dependencies correctly diff --git a/Changelog.md b/Changelog.md index 9406e5d4..1a5744bc 100644 --- a/Changelog.md +++ b/Changelog.md @@ -4,14 +4,32 @@ Breaking changes +* The `storage_uri` (aliased as `data_dir`) configuration file option is + now mandatory and will not default to `./data` or the content of an + environment variable any more. ([#1383]) + New +* Support for Ubuntu Resolute Raccoon (26.04). ([#1378]) + Improvements +* TLS keys are now stored with the mode set to 0600 on Unix systems. + ([#1376]) + Bug fixes Other changes +* Upgraded the bundled Krill UI to [version 0.10.0][krill-ui 0.1.0]. + This primarily adds a new ASPA UI. ([#1373]) + +[#1373]: https://github.com/NLnetLabs/krill/pull/1373 +[#1376]: https://github.com/NLnetLabs/krill/pull/1376 +[#1378]: https://github.com/NLnetLabs/krill/pull/1378 +[#1383]: https://github.com/NLnetLabs/krill/pull/1383 +[krill-ui 0.10.0]: https://github.com/NLnetLabs/krill-ui/releases/tag/v0.10.0 + ## 0.16.0 ‘Früher war mehr Lametta’ diff --git a/defaults/krill-testbed.conf b/defaults/krill-testbed.conf index b4ebcf4a..825790b6 100644 --- a/defaults/krill-testbed.conf +++ b/defaults/krill-testbed.conf @@ -52,7 +52,7 @@ # For backward compatibility 'data_dir' is accepted as an # alternative to 'storage_uri'. # -### storage_uri = "./data" +storage_uri = "file:///var/lib/krill/data" # TLS Keys Dir # diff --git a/defaults/krill.conf b/defaults/krill.conf index b3c3eab3..06ade830 100644 --- a/defaults/krill.conf +++ b/defaults/krill.conf @@ -22,7 +22,7 @@ # For backward compatibility 'data_dir' is accepted as an # alternative to 'storage_uri'. # -### storage_uri = "./data" +storage_uri = "file:///var/lib/krill/data" # TLS Keys Dir # diff --git a/doc/manual/source/cli.rst b/doc/manual/source/cli.rst index 20a972bb..21834410 100644 --- a/doc/manual/source/cli.rst +++ b/doc/manual/source/cli.rst @@ -136,13 +136,12 @@ krillc config ------------- This subcommand is implemented on the CLI only and is intended to help -generate a configuration file which can be used for your Krill server. +manage the configuration file used for your Krill server. -We currently support two subcommands for this: ``krillc config simple`` and -``krillc config user``. The first can be used to generate general server -configuration. The second can be used to generate user (``id``) entries to -use if you want to have multiple local users access the Krill UI by their own -name and password. +The command ``krillc config user --id ``, will prompt you for a +password, and generates a string that can be added to your krill.conf +file to enable local multi-user login as described in the +:ref:`multi-user config file provider documentation<_doc_krill_multi_user_config_file_provider>`. .. _cmd_krillc_health: diff --git a/doc/manual/source/install-and-run.rst b/doc/manual/source/install-and-run.rst index 9b02f770..10949247 100644 --- a/doc/manual/source/install-and-run.rst +++ b/doc/manual/source/install-and-run.rst @@ -111,9 +111,10 @@ public rsyncd and HTTPS web server available. .. group-tab:: Ubuntu - To install a Routinator package, you need the 64-bit version of one of + To install a Krill package, you need the 64-bit version of one of these Ubuntu versions: + - Ubuntu Noble 26.04 (LTS) - Ubuntu Noble 24.04 (LTS) - Ubuntu Jammy 22.04 (LTS) - Ubuntu Focal 20.04 (LTS) diff --git a/doc/manual/source/multi-user/openid-connect-provider.rst b/doc/manual/source/multi-user/openid-connect-provider.rst index e82c29ed..0a07d729 100644 --- a/doc/manual/source/multi-user/openid-connect-provider.rst +++ b/doc/manual/source/multi-user/openid-connect-provider.rst @@ -370,8 +370,10 @@ steps must be taken: configuration settings that Krill offers. For example to use the Amazon Cognito logout endpoint you have to configure that manually. - .. tip:: The ``krill.conf`` file contains example configurations for - providers that Krill has been tested with. + .. tip:: The ``krill-multi-user.conf`` file contains example configurations for + providers that Krill has been tested with. If you installed krill using + a binary package, it can be found on github under the `defaults + directory `_. Using Keycloak """""""""""""" diff --git a/pkg/rules/packages-to-build.yml b/pkg/rules/packages-to-build.yml index 411bc702..823ffd4f 100644 --- a/pkg/rules/packages-to-build.yml +++ b/pkg/rules/packages-to-build.yml @@ -7,6 +7,7 @@ pkg: image: - "ubuntu:jammy" # ubuntu/22.04 - "ubuntu:noble" # ubuntu/24.04 + - "ubuntu:resolute" # ubuntu/26.04 - "debian:bullseye" # debian/11 - "debian:bookworm" # debian/12 - "debian:trixie" # debian/13 diff --git a/pkg/rules/packages-to-test.yml b/pkg/rules/packages-to-test.yml index 228cb09e..e5383673 100644 --- a/pkg/rules/packages-to-test.yml +++ b/pkg/rules/packages-to-test.yml @@ -5,9 +5,9 @@ pkg: - "krillup" - "krillta" image: - - "ubuntu:focal" # ubuntu/20.04 - "ubuntu:jammy" # ubuntu/22.04 - "ubuntu:noble" # ubuntu/24.04 + - "ubuntu:resolute" # ubuntu/26.04 - "debian:bullseye" # debian/11 - "debian:bookworm" # debian/12 - "debian:trixie" # debian/13 @@ -48,11 +48,7 @@ include: image: "debian:bullseye" target: "armv7-unknown-linux-gnueabihf" -# Exclude upgrade testing on Ubuntu Noble as no prior released versions exist to upgrade from. +# Exclude upgrade testing on Ubuntu Resolute as no prior released versions exist to upgrade from. exclude: - - image: "almalinux:9" - mode: "upgrade-from-published" - - image: "ubuntu:noble" - mode: "upgrade-from-published" - - image: "debian:trixie" + - image: "ubuntu:resolute" mode: "upgrade-from-published" diff --git a/src/api/ca.rs b/src/api/ca.rs index 33ac0682..2cb2908c 100644 --- a/src/api/ca.rs +++ b/src/api/ca.rs @@ -2231,7 +2231,7 @@ mod test { use bytes::Bytes; use rpki::crypto::PublicKeyFormat; use crate::api::ta::TrustAnchorLocator; - use crate::commons::crypto::OpenSslSigner; + use crate::commons::crypto::{OpenSslSigner, OpenSslSignerConfig}; use crate::commons::test; use super::*; @@ -2255,9 +2255,10 @@ mod test { #[test] fn mft_uri() { - test::test_in_memory(|storage_uri| { - let signer = - OpenSslSigner::build(storage_uri, "dummy", None).unwrap(); + test::test_in_memory(|storage| { + let signer = OpenSslSigner::build( + storage, &OpenSslSignerConfig::default(), "dummy", None + ).unwrap(); let key_id = signer.create_key(PublicKeyFormat::Rsa).unwrap(); let pub_key = signer.get_key_info(&key_id).unwrap(); diff --git a/src/api/roa.rs b/src/api/roa.rs index 8eb7dedd..4de4924f 100644 --- a/src/api/roa.rs +++ b/src/api/roa.rs @@ -223,7 +223,7 @@ impl fmt::Display for RoaPayload { impl fmt::Debug for RoaPayload { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "RoaPayload({})", &self) + write!(f, "RoaPayload({})", self) } } @@ -558,8 +558,8 @@ impl From for RoaConfigurationUpdates { for announcement in suggestion.not_found .into_iter() - .chain(suggestion.invalid_asn.into_iter()) - .chain(suggestion.invalid_length.into_iter()) + .chain(suggestion.invalid_asn) + .chain(suggestion.invalid_length) { added.push(RoaConfiguration { payload: announcement.into(), @@ -793,7 +793,7 @@ impl fmt::Display for TypedPrefix { impl fmt::Debug for TypedPrefix { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", &self) + write!(f, "{}", self) } } @@ -906,7 +906,7 @@ impl fmt::Display for Ipv4Prefix { impl fmt::Debug for Ipv4Prefix { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", &self) + write!(f, "{}", self) } } @@ -1011,7 +1011,7 @@ impl fmt::Display for Ipv6Prefix { impl fmt::Debug for Ipv6Prefix { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", &self) + write!(f, "{}", self) } } @@ -1080,7 +1080,7 @@ impl fmt::Display for AsNumber { impl fmt::Debug for AsNumber { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", &self) + write!(f, "{}", self) } } diff --git a/src/api/rta.rs b/src/api/rta.rs index 88b5c39b..b05d1dfc 100644 --- a/src/api/rta.rs +++ b/src/api/rta.rs @@ -38,7 +38,7 @@ pub struct RtaContentRequest { impl fmt::Display for RtaContentRequest { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - writeln!(f, "resources: {}", &self.resources)?; + writeln!(f, "resources: {}", self.resources)?; writeln!( f, "validity, {}-{}", diff --git a/src/api/status.rs b/src/api/status.rs index d3a63bf1..065c237f 100644 --- a/src/api/status.rs +++ b/src/api/status.rs @@ -151,7 +151,7 @@ impl From<(&'static str, &'static str)> for ErrorResponse { impl fmt::Display for ErrorResponse { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{}", &serde_json::to_string(&self).unwrap()) + write!(f, "{}", serde_json::to_string(&self).unwrap()) } } diff --git a/src/bin/krillup.rs b/src/bin/krillup.rs index 965cf0ec..792fae16 100644 --- a/src/bin/krillup.rs +++ b/src/bin/krillup.rs @@ -5,8 +5,8 @@ use std::path::PathBuf; use clap::Parser; use log::info; use log::LevelFilter; -use url::Url; use krill::constants; +use krill::commons::storage::{StorageSystem, StorageUri}; use krill::config::{Config, LogType}; use krill::server::properties::PropertiesManager; use krill::upgrades::{prepare_upgrade_data_migrations, UpgradeMode}; @@ -33,9 +33,9 @@ fn main() { match options.command { Command::Prepare(_prepare) => { + let storage = StorageSystem::new(config.storage_uri.clone()); let properties_manager = match PropertiesManager::create( - &config.storage_uri, - config.use_history_cache, + &storage, config.use_history_cache, ) { Ok(mgr) => mgr, Err(e) => { @@ -57,6 +57,7 @@ fn main() { match prepare_upgrade_data_migrations( UpgradeMode::PrepareOnly, + &storage, &config, &properties_manager, ) { @@ -93,7 +94,9 @@ fn main() { } } Command::Migrate(cmd) => { - if let Err(e) = migrate(config, cmd.target) { + let storage = StorageSystem::new(cmd.target); + + if let Err(e) = migrate(config, &storage) { eprintln!("*** Error Migrating DATA ***"); eprintln!("{e}"); eprintln!(); @@ -153,6 +156,6 @@ pub struct Prepare; pub struct Migrate { /// The storage target as a URI string. #[arg(short, long, value_name = "URI")] - pub target: Url, + pub target: StorageUri, } diff --git a/src/cli/ta/signer.rs b/src/cli/ta/signer.rs index 725f2299..4b5b43a5 100644 --- a/src/cli/ta/signer.rs +++ b/src/cli/ta/signer.rs @@ -15,7 +15,7 @@ use crate::commons::crypto::KrillSigner; use crate::commons::actor::Actor; use crate::commons::error::Error as KrillError; use crate::commons::eventsourcing::{AggregateStore, AggregateStoreError}; -use crate::commons::storage::Ident; +use crate::commons::storage::{Ident, StorageSystem}; use crate::commons::httpclient; use crate::tasigner::{ Config, TrustAnchorProxySignerExchanges, @@ -122,13 +122,14 @@ pub struct TrustAnchorSignerManager { impl TrustAnchorSignerManager { pub fn create(config: Config) -> Result { + let storage = StorageSystem::new(config.storage_uri.clone()); let store = AggregateStore::create( - &config.storage_uri, + &storage, const { Ident::make("signer") }, config.use_history_cache, ).map_err(SignerClientError::other)?; let ta_handle = CaHandle::new("ta".into()); - let signer = config.signer()?; + let signer = config.signer(&storage)?; let actor = crate::constants::ACTOR_DEF_KRILLTA; Ok(TrustAnchorSignerManager { diff --git a/src/commons/crypto/signing/dispatch/krillsigner.rs b/src/commons/crypto/signing/dispatch/krillsigner.rs index 005a1016..982f7d7c 100644 --- a/src/commons/crypto/signing/dispatch/krillsigner.rs +++ b/src/commons/crypto/signing/dispatch/krillsigner.rs @@ -26,7 +26,6 @@ use rpki::{ Cert, Crl, Manifest, Roa, }, }; -use url::Url; use crate::{ commons::{ @@ -40,6 +39,7 @@ use crate::{ CryptoResult, OpenSslSigner, SignSupport, }, error::Error, + storage::StorageSystem, KrillResult, }, constants::ID_CERTIFICATE_VALIDITY_YEARS, @@ -83,7 +83,7 @@ use crate::commons::crypto::{ type SignerBuilderFn = fn( &SignerType, SignerFlags, - &Url, + &StorageSystem, &str, std::time::Duration, &Option>, @@ -91,7 +91,7 @@ type SignerBuilderFn = fn( #[derive(Debug)] pub struct KrillSignerBuilder<'a> { - storage_uri: Url, + storage: &'a StorageSystem, probe_interval: Duration, signer_configs: &'a [SignerConfig], default_signer: Option<&'a SignerConfig>, @@ -100,12 +100,12 @@ pub struct KrillSignerBuilder<'a> { impl<'a> KrillSignerBuilder<'a> { pub fn new( - storage_uri: &Url, + storage: &'a StorageSystem, probe_interval: Duration, signer_configs: &'a [SignerConfig], ) -> Self { Self { - storage_uri: storage_uri.clone(), + storage, probe_interval, signer_configs, default_signer: None, @@ -174,7 +174,7 @@ impl<'a> KrillSignerBuilder<'a> { } KrillSigner::build( - &self.storage_uri, + self.storage, self.probe_interval, self.signer_configs, default_signer, @@ -190,7 +190,7 @@ pub struct KrillSigner { impl KrillSigner { fn build( - storage_uri: &Url, + storage: &StorageSystem, probe_interval: Duration, signer_configs: &[SignerConfig], default_signer: &SignerConfig, @@ -199,10 +199,10 @@ impl KrillSigner { #[cfg(not(feature = "hsm"))] let signer_mapper = None; #[cfg(feature = "hsm")] - let signer_mapper = Some(Arc::new(SignerMapper::build(storage_uri)?)); + let signer_mapper = Some(Arc::new(SignerMapper::build(storage)?)); let signers = Self::build_signers( signer_builder, - storage_uri, + storage, probe_interval, &signer_mapper, signer_configs, @@ -420,7 +420,7 @@ impl KrillSigner { impl KrillSigner { fn build_signers( signer_builder: SignerBuilderFn, - storage_uri: &Url, + storage: &StorageSystem, probe_interval: std::time::Duration, mapper: &Option>, configs: &[SignerConfig], @@ -450,7 +450,7 @@ impl KrillSigner { let signer = (signer_builder)( &config.signer_type, flags, - storage_uri, + storage, &config.name, probe_interval, mapper, @@ -466,7 +466,7 @@ impl KrillSigner { fn signer_builder( r#type: &SignerType, flags: SignerFlags, - storage_uri: &Url, + storage: &StorageSystem, name: &str, #[cfg(feature = "hsm")] probe_interval: Duration, #[cfg(not(feature = "hsm"))] _probe_interval: Duration, @@ -474,10 +474,9 @@ fn signer_builder( ) -> KrillResult { match r#type { SignerType::OpenSsl(conf) => { - let storage_uri = - conf.keys_storage_uri.as_ref().unwrap_or(storage_uri); - let signer = - OpenSslSigner::build(storage_uri, name, mapper.clone())?; + let signer = OpenSslSigner::build( + storage, conf, name, mapper.clone() + )?; Ok(SignerProvider::OpenSsl(flags, signer)) } #[cfg(feature = "hsm")] @@ -517,6 +516,7 @@ pub mod tests { commons::crypto::signers::mocksigner::{ MockSigner, MockSignerCallCounts, }, + commons::storage::StorageSystem, commons::test, config::Config, }; @@ -528,7 +528,7 @@ pub mod tests { fn mock_signer_builder( r#type: &SignerType, flags: SignerFlags, - _storage_uri: &Url, + _storage: &StorageSystem, name: &str, _probe_interval: Duration, mapper: &Option>, @@ -549,14 +549,15 @@ pub mod tests { fn config_fragment_to_config_object( fragment: &str, ) -> Result { - let mut config_str = r#"admin_token = "***""#.to_string(); + let mut config_str = + "admin_token = \"***\"\nstorage_uri = \"/tmp/krill\"".to_string(); config_str.push_str(fragment); toml::from_str(&config_str) } fn build_krill_signer_from_config( signers_config_fragment: &str, - storage_uri: &Url, + storage: &StorageSystem, mapper: Arc, ) -> KrillResult> { let mut config = @@ -569,7 +570,7 @@ pub mod tests { let probe_interval = std::time::Duration::from_secs(1); KrillSigner::build_signers( mock_signer_builder, - storage_uri, + storage, probe_interval, &mapper, &config.signers, @@ -612,10 +613,10 @@ pub mod tests { /// it was before HSM support was added. #[test] pub fn no_signers_equals_one_openssl_signer_for_backward_compatibility() { - test::test_in_memory(|storage_uri| { - let mapper = Arc::new(SignerMapper::build(storage_uri).unwrap()); + test::test_in_memory(|storage| { + let mapper = Arc::new(SignerMapper::build(storage).unwrap()); let signers = - build_krill_signer_from_config("", storage_uri, mapper) + build_krill_signer_from_config("", storage, mapper) .unwrap(); assert_eq!(signers.len(), 1); let signer = &signers[0]; @@ -627,8 +628,8 @@ pub mod tests { #[test] pub fn signer_name_is_respected() { - test::test_in_memory(|storage_uri| { - let mapper = Arc::new(SignerMapper::build(storage_uri).unwrap()); + test::test_in_memory(|storage| { + let mapper = Arc::new(SignerMapper::build(storage).unwrap()); let signers_config_fragment = r#" [[signers]] type = "OpenSSL" @@ -636,7 +637,7 @@ pub mod tests { "#; let signers = build_krill_signer_from_config( signers_config_fragment, - storage_uri, + storage, mapper, ) .unwrap(); @@ -657,8 +658,8 @@ pub mod tests { /// signer. #[test] pub fn single_openssl_signer_is_made_the_default_all_signer() { - test::test_in_memory(|storage_uri| { - let mapper = Arc::new(SignerMapper::build(storage_uri).unwrap()); + test::test_in_memory(|storage| { + let mapper = Arc::new(SignerMapper::build(storage).unwrap()); let signers_config_fragment = r#" [[signers]] type = "OpenSSL" @@ -666,7 +667,7 @@ pub mod tests { "#; let signers = build_krill_signer_from_config( signers_config_fragment, - storage_uri, + storage, mapper, ) .unwrap(); @@ -679,8 +680,8 @@ pub mod tests { #[test] pub fn create_openssl_signer_for_one_off_signing() { - test::test_in_memory(|storage_uri| { - let mapper = Arc::new(SignerMapper::build(storage_uri).unwrap()); + test::test_in_memory(|storage| { + let mapper = Arc::new(SignerMapper::build(storage).unwrap()); let signer_config_fragment = r#" [[signers]] @@ -690,7 +691,7 @@ pub mod tests { "#; let signers = build_krill_signer_from_config( signer_config_fragment, - storage_uri, + storage, mapper.clone(), ) .unwrap(); @@ -715,7 +716,7 @@ pub mod tests { "#; let signers = build_krill_signer_from_config( signer_config_fragment, - storage_uri, + storage, mapper, ) .unwrap(); @@ -733,8 +734,8 @@ pub mod tests { #[test] pub fn one_off_signer_is_respected() { - test::test_in_memory(|storage_uri| { - let mapper = Arc::new(SignerMapper::build(storage_uri).unwrap()); + test::test_in_memory(|storage| { + let mapper = Arc::new(SignerMapper::build(storage).unwrap()); let signer_config_fragment = r#" one_off_signer = "KMIP" @@ -746,7 +747,7 @@ pub mod tests { "#; let signers = build_krill_signer_from_config( signer_config_fragment, - storage_uri, + storage, mapper.clone(), ) .unwrap(); @@ -768,7 +769,7 @@ pub mod tests { "#; let signers = build_krill_signer_from_config( signer_config_fragment, - storage_uri, + storage, mapper, ) .unwrap(); @@ -781,8 +782,8 @@ pub mod tests { #[test] pub fn default_signer_is_respected() { - test::test_in_memory(|storage_uri| { - let mapper = Arc::new(SignerMapper::build(storage_uri).unwrap()); + test::test_in_memory(|storage| { + let mapper = Arc::new(SignerMapper::build(storage).unwrap()); let signer_config_fragment = r#" default_signer = "Signer 2" @@ -798,7 +799,7 @@ pub mod tests { "#; let signers = build_krill_signer_from_config( signer_config_fragment, - storage_uri, + storage, mapper, ) .unwrap(); @@ -818,8 +819,8 @@ pub mod tests { #[test] pub fn default_signer_and_one_off_signer_are_respected() { - test::test_in_memory(|storage_uri| { - let mapper = Arc::new(SignerMapper::build(storage_uri).unwrap()); + test::test_in_memory(|storage| { + let mapper = Arc::new(SignerMapper::build(storage).unwrap()); let signer_config_fragment = r#" default_signer = "Signer 2" @@ -836,7 +837,7 @@ pub mod tests { "#; let signers = build_krill_signer_from_config( signer_config_fragment, - storage_uri, + storage, mapper, ) .unwrap(); @@ -856,8 +857,8 @@ pub mod tests { #[test] pub fn historic_signers_are_permitted() { - test::test_in_memory(|storage_uri| { - let mapper = Arc::new(SignerMapper::build(storage_uri).unwrap()); + test::test_in_memory(|storage| { + let mapper = Arc::new(SignerMapper::build(storage).unwrap()); let signer_config_fragment = r#" default_signer = "Signer 2" @@ -880,7 +881,7 @@ pub mod tests { "#; let signers = build_krill_signer_from_config( signer_config_fragment, - storage_uri, + storage, mapper, ) .unwrap(); diff --git a/src/commons/crypto/signing/dispatch/signerinfo.rs b/src/commons/crypto/signing/dispatch/signerinfo.rs index 89b508b5..1341484f 100644 --- a/src/commons/crypto/signing/dispatch/signerinfo.rs +++ b/src/commons/crypto/signing/dispatch/signerinfo.rs @@ -8,7 +8,6 @@ use rpki::{ crypto::{KeyIdentifier, PublicKey}, }; use serde::{Deserialize, Serialize}; -use url::Url; use crate::{ commons::{ @@ -19,6 +18,7 @@ use crate::{ InitCommandDetails, InitEvent, SentCommand, SentInitCommand, WithStorableDetails, }, + storage::StorageSystem, KrillResult, }, constants::{ACTOR_DEF_KRILL, SIGNERS_NS}, @@ -446,11 +446,9 @@ impl std::fmt::Debug for SignerMapper { impl SignerMapper { /// Build a SignerMapper that will read/write its data in a subdirectory /// of the given work dir. - pub fn build(storage_uri: &Url) -> KrillResult { + pub fn build(storage: &StorageSystem) -> KrillResult { let store = AggregateStore::::create( - storage_uri, - SIGNERS_NS, - true, + storage, SIGNERS_NS, true, )?; Ok(SignerMapper { store }) } diff --git a/src/commons/crypto/signing/signers/kmip/signer.rs b/src/commons/crypto/signing/signers/kmip/signer.rs index 71146edd..4c99d6ea 100644 --- a/src/commons/crypto/signing/signers/kmip/signer.rs +++ b/src/commons/crypto/signing/signers/kmip/signer.rs @@ -713,7 +713,7 @@ impl KmipSigner { if !matches!(algorithm, PublicKeyFormat::Rsa) { return Err(SignerError::KmipError(format!( "Algorithm {:?} not supported while creating key", - &algorithm + algorithm ))); } @@ -924,7 +924,7 @@ impl KmipSigner { if let Err(err) = &res { warn!( "[{}] Failed to destroy KMIP public key '{}': {}", - self.name, &kmip_key_pair_ids.public_key_id, err + self.name, kmip_key_pair_ids.public_key_id, err ); } @@ -942,7 +942,7 @@ impl KmipSigner { deactivated = false; warn!( "[{}] Failed to revoke KMIP private key '{}': {}", - self.name, &kmip_key_pair_ids.private_key_id, err + self.name, kmip_key_pair_ids.private_key_id, err ); } @@ -966,7 +966,7 @@ impl KmipSigner { if let Err(err) = &res3 { warn!( "[{}] Failed to destroy KMIP private key '{}': {}", - self.name, &kmip_key_pair_ids.private_key_id, err + self.name, kmip_key_pair_ids.private_key_id, err ); } diff --git a/src/commons/crypto/signing/signers/pkcs11/signer.rs b/src/commons/crypto/signing/signers/pkcs11/signer.rs index 6a0fe3d8..c6a37031 100644 --- a/src/commons/crypto/signing/signers/pkcs11/signer.rs +++ b/src/commons/crypto/signing/signers/pkcs11/signer.rs @@ -938,8 +938,8 @@ impl Pkcs11Signer { if !matches!(algorithm, PublicKeyFormat::Rsa) { return Err(SignerError::Pkcs11Error(format!( "Algorithm {:?} not supported while creating key", - &algorithm - )))?; + algorithm + )).into()); } let mech = Mechanism::RsaPkcsKeyPairGen; @@ -1135,7 +1135,7 @@ impl Pkcs11Signer { 1 => Ok(results[0]), _ => Err(KeyError::Signer(SignerError::Pkcs11Error(format!( "More than one {} found with id {}", - &human_key_class, cka_id_hex_str + human_key_class, cka_id_hex_str )))), } } diff --git a/src/commons/crypto/signing/signers/softsigner.rs b/src/commons/crypto/signing/signers/softsigner.rs index 3a7a5d6f..82d5498e 100644 --- a/src/commons/crypto/signing/signers/softsigner.rs +++ b/src/commons/crypto/signing/signers/softsigner.rs @@ -19,7 +19,6 @@ use rpki::crypto::{ RpkiSignatureAlgorithm, Signature, SignatureAlgorithm, SigningError, }; use serde::{de, ser, Deserialize, Deserializer, Serialize, Serializer}; -use url::Url; use crate::{ commons::{ @@ -27,21 +26,23 @@ use crate::{ dispatch::signerinfo::SignerMapper, signers::error::SignerError, SignerHandle, }, - storage::{Ident, KeyValueStore}, + storage::{ + Ident, KeyValueStore, StorageSystem, StorageUri, OpenStoreError, + }, }, constants::KEYS_NS, }; //------------ OpenSslSigner ------------------------------------------------- -#[derive(Clone, Debug, Default, Deserialize, Hash, PartialEq, Eq)] +#[derive(Clone, Debug, Default, Deserialize, PartialEq)] pub struct OpenSslSignerConfig { #[serde(default)] - pub keys_storage_uri: Option, + pub keys_storage_uri: Option, } impl OpenSslSignerConfig { - pub fn new(storage_uri: Url) -> Self { + pub fn new(storage_uri: StorageUri) -> Self { Self { keys_storage_uri: Some(storage_uri), } @@ -69,18 +70,19 @@ impl OpenSslSigner { /// SignerMapper only knows about keys created by the OpenSslSigner if /// the OpenSslSigner registers the new keys in the mapper. pub fn build( - storage_uri: &Url, + storage: &StorageSystem, + conf: &OpenSslSignerConfig, name: &str, mapper: Option>, - ) -> Result { - let keys_store = Self::init_keys_store(storage_uri)?; + ) -> Result { + let keys_store = Self::init_keys_store(storage, conf)?; let s = OpenSslSigner { name: name.to_string(), info: Some(format!( "OpenSSL Soft Signer [version: {}, keys store: {}]", openssl::version::version(), - storage_uri, + storage.default_uri(), )), handle: RwLock::new(None), // will be set later mapper, @@ -137,11 +139,13 @@ impl OpenSslSigner { impl OpenSslSigner { fn init_keys_store( - storage_uri: &Url, - ) -> Result { - let store = KeyValueStore::create(storage_uri, KEYS_NS) - .map_err(|_| SignerError::InvalidStorage(storage_uri.clone()))?; - Ok(store) + storage: &StorageSystem, + conf: &OpenSslSignerConfig, + ) -> Result { + match &conf.keys_storage_uri { + Some(uri) => storage.open_uri(uri, KEYS_NS), + None => storage.open(KEYS_NS) + } } fn build_key(&self) -> Result { @@ -385,10 +389,19 @@ pub mod tests { use super::*; + fn build_signer(storage: &StorageSystem) -> OpenSslSigner { + OpenSslSigner::build( + storage, + &OpenSslSignerConfig::default(), + "dummy", + None + ).unwrap() + } + #[test] fn should_return_subject_public_key_info() { - test::test_in_memory(|storage_uri| { - let s = OpenSslSigner::build(storage_uri, "dummy", None).unwrap(); + test::test_in_memory(|storage| { + let s = build_signer(storage); let ki = s.create_key(PublicKeyFormat::Rsa).unwrap(); s.get_key_info(&ki).unwrap(); s.destroy_key(&ki).unwrap(); @@ -410,14 +423,13 @@ pub mod tests { #[test] fn import_existing_pkcs1_openssl_key() { - test::test_in_memory(|storage_uri| { + test::test_in_memory(|storage| { // The following key was generated using OpenSSL on the command // line let pem = include_str!( "../../../../../test-resources/ta/example-pkcs1.pem" ); - let signer = - OpenSslSigner::build(storage_uri, "dummy", None).unwrap(); + let signer = build_signer(storage); let ki = signer.import_key(pem).unwrap(); signer.get_key_info(&ki).unwrap(); @@ -427,14 +439,13 @@ pub mod tests { #[test] fn import_existing_pkcs8_openssl_key() { - test::test_in_memory(|storage_uri| { + test::test_in_memory(|storage| { // The following key was generated using OpenSSL on the command // line let pem = include_str!( "../../../../../test-resources/ta/example-pkcs8.pem" ); - let signer = - OpenSslSigner::build(storage_uri, "dummy", None).unwrap(); + let signer = build_signer(storage); let ki = signer.import_key(pem).unwrap(); signer.get_key_info(&ki).unwrap(); diff --git a/src/commons/error.rs b/src/commons/error.rs index 505c0dae..2a0b2fbd 100644 --- a/src/commons/error.rs +++ b/src/commons/error.rs @@ -163,7 +163,7 @@ impl Display for ApiAuthError { | ApiAuthError::ApiAuthTransientError(err) | ApiAuthError::ApiAuthSessionExpired(err) | ApiAuthError::ApiInsufficientRights(err) => { - write!(f, "{}", &err) + write!(f, "{err}") } } } diff --git a/src/commons/eventsourcing/store.rs b/src/commons/eventsourcing/store.rs index a188e8b5..288a2ec8 100644 --- a/src/commons/eventsourcing/store.rs +++ b/src/commons/eventsourcing/store.rs @@ -12,12 +12,13 @@ use rpki::ca::idexchange::MyHandle; use rpki::repository::x509::Time; use serde::Serialize; use serde::de::DeserializeOwned; -use url::Url; use crate::api::history::{ CommandHistory, CommandHistoryCriteria, CommandHistoryRecord }; use crate::commons::error::KrillIoError; -use crate::commons::storage::{Ident, KeyValueError, KeyValueStore}; +use crate::commons::storage::{ + Ident, KeyValueError, KeyValueStore, OpenStoreError, StorageSystem, +}; use super::agg::{Aggregate, Command, InitCommand, StoredCommand}; @@ -67,12 +68,12 @@ impl AggregateStore { /// If `use_history_cache` is `true`, the new store will cache any /// history cache record created for any instance. pub fn create( - storage_uri: &Url, + storage: &StorageSystem, namespace: &Ident, use_history_cache: bool, - ) -> Result { + ) -> Result { Ok(Self::create_from_kv( - KeyValueStore::create(storage_uri, namespace)?, use_history_cache + storage.open(namespace)?, use_history_cache )) } @@ -81,13 +82,12 @@ impl AggregateStore { /// If `use_history_cache` is `true`, the new store will cache any /// history cache record created for any instance. pub fn create_upgrade_store( - storage_uri: &Url, + storage: &StorageSystem, namespace: &Ident, use_history_cache: bool, - ) -> Result { + ) -> Result { Ok(Self::create_from_kv( - KeyValueStore::create_upgrade_store(storage_uri, namespace)?, - use_history_cache, + storage.open_upgrade(namespace)?, use_history_cache, )) } diff --git a/src/commons/eventsourcing/wal.rs b/src/commons/eventsourcing/wal.rs index 6439194b..a56969c1 100644 --- a/src/commons/eventsourcing/wal.rs +++ b/src/commons/eventsourcing/wal.rs @@ -10,8 +10,9 @@ use std::sync::{Arc, RwLock}; use log::{error, warn, trace}; use rpki::ca::idexchange::MyHandle; use serde::{Deserialize, Serialize}; -use url::Url; -use crate::commons::storage::{Ident, KeyValueError, KeyValueStore}; +use crate::commons::storage::{ + Ident, KeyValueError, KeyValueStore, OpenStoreError, StorageSystem, +}; use super::store::Storable; @@ -135,11 +136,11 @@ pub struct WalStore { impl WalStore { /// Creates a new store using the given storage URL and namespace. pub fn create( - storage_uri: &Url, + storage: &StorageSystem, namespace: &Ident, - ) -> Result { + ) -> Result { Ok(WalStore { - kv: KeyValueStore::create(storage_uri, namespace)?, + kv: storage.open(namespace)?, cache: RwLock::new(HashMap::new()), }) } diff --git a/src/commons/file.rs b/src/commons/file.rs index 8ffa66a5..5706889b 100644 --- a/src/commons/file.rs +++ b/src/commons/file.rs @@ -4,8 +4,10 @@ use std::{fmt, fs, io}; use std::borrow::Cow; -use std::fs::File; +use std::fs::{File, OpenOptions}; use std::io::{Read, Write}; +#[cfg(unix)] +use std::os::unix::fs::OpenOptionsExt; use std::path::{Path, PathBuf}; use std::str::FromStr; use bytes::Bytes; @@ -55,6 +57,19 @@ pub fn remove_dir_all(dir: &Path) -> Result<(), KrillIoError> { /// Creates a new File or opens an exiting one. If the file did not exist, the /// path will be created if it did not exist yet. pub fn create_file_with_path(path: &Path) -> Result { + create_file(path, false) +} + +/// Creates a new File or opens an exiting one. If the file did not exist, the +/// path will be created if it did not exist yet. +pub fn create_private_file_with_path(path: &Path) -> Result { + create_file(path, true) +} + +/// Creates a file. +/// +/// If `private` is `true`, will set the file mode to `0o600` on Unix. +fn create_file(path: &Path, private: bool) -> Result { if !path.exists() && let Some(parent) = path.parent() @@ -70,7 +85,15 @@ pub fn create_file_with_path(path: &Path) -> Result { ) })?; } - File::create(path).map_err(|e| { + let mut options = OpenOptions::new(); + options.create(true); + options.read(true); + options.write(true); + #[cfg(unix)] + if private { + options.mode(0o600); + } + options.open(path).map_err(|e| { KrillIoError::new( format!("Could not create file: {}", path.to_string_lossy()), e, @@ -99,6 +122,21 @@ pub fn save(content: &[u8], full_path: &Path) -> Result<(), KrillIoError> { Ok(()) } +/// Saves a file, creating parent dirs as needed +pub fn save_private(content: &[u8], full_path: &Path) -> Result<(), KrillIoError> { + let mut f = create_private_file_with_path(full_path)?; + + f.write_all(content).map_err(|e| { + KrillIoError::new( + format!("Could not write to: {}", full_path.to_string_lossy()), + e, + ) + })?; + + trace!("Saved file: {}", full_path.to_string_lossy()); + Ok(()) +} + /// Saves an object to json - unwraps any json errors! pub fn save_json( object: &O, diff --git a/src/commons/queue.rs b/src/commons/queue.rs index d646415d..a8a5028b 100644 --- a/src/commons/queue.rs +++ b/src/commons/queue.rs @@ -2,9 +2,9 @@ use std::{cmp, error, fmt}; use std::time::{Duration, SystemTime, UNIX_EPOCH}; -use url::Url; use crate::commons::storage::{ - Ident, KeyValueError, KeyValueStore, Transaction + Ident, KeyValueError, KeyValueStore, OpenStoreError, StorageSystem, + Transaction, }; //------------ Configuration ------------------------------------------------- @@ -51,11 +51,11 @@ impl Queue { impl Queue { /// Creates a new queue. pub fn create( - storage_uri: &Url, + storage: &StorageSystem, namespace: &Ident, - ) -> Result { + ) -> Result { Ok(Queue { - store: KeyValueStore::create(storage_uri, namespace)?, + store: storage.open(namespace)?, }) } @@ -452,14 +452,14 @@ mod tests { use std::thread; use std::time::Duration; use serde_json::Value; - use url::Url; use super::*; - fn queue_store(ns: &str) -> Queue { - Queue::create( - &Url::parse("memory://").unwrap(), - Ident::from_str(ns).unwrap() - ).unwrap() + fn storage_system() -> StorageSystem { + StorageSystem::new_memory(None) + } + + fn queue_store(storage: &StorageSystem, ns: &str) -> Queue { + Queue::create(storage, Ident::from_str(ns).unwrap()).unwrap() } #[test] @@ -479,12 +479,13 @@ mod tests { #[test] fn queue_thread_workers() { - let queue = queue_store("queue_thread_workers"); + let storage = storage_system(); + let queue = queue_store(&storage, "queue_thread_workers"); queue.store.wipe().unwrap(); thread::scope(|s| { - let create = s.spawn(|| { - let queue = queue_store("queue_thread_workers"); + s.spawn(|| { + let queue = queue_store(&storage, "queue_thread_workers"); for i in 1..=10 { let name = Ident::builder( @@ -498,19 +499,20 @@ mod tests { None, ScheduleMode::FinishOrReplaceExisting, ).unwrap(); - println!("> Scheduled job {}", &name); + println!("> Scheduled job {}", name); } }); - create.join().unwrap(); + }); - let keys = queue.store.execute(None, |tran| { - tran.list_keys(Queue::pending_scope()) - }).unwrap(); - assert_eq!(keys.len(), 10); + let keys = queue.store.execute(None, |tran| { + tran.list_keys(Queue::pending_scope()) + }).unwrap(); + assert_eq!(keys.len(), 10); + thread::scope(|s| { for _ in 1..=10 { - s.spawn(move || { - let queue = queue_store("queue_thread_workers"); + s.spawn(|| { + let queue = queue_store(&storage, "queue_thread_workers"); while queue.pending_tasks_remaining().unwrap() > 0 { if let Some((task_name, _)) @@ -535,7 +537,8 @@ mod tests { #[test] fn test_reschedule_long_running() { - let queue = queue_store("test_reschedule_long_running"); + let storage = storage_system(); + let queue = queue_store(&storage, "test_reschedule_long_running"); queue.store.wipe().unwrap(); let name = const { Ident::make("job") }; @@ -570,7 +573,8 @@ mod tests { #[test] fn test_reschedule_finished_task() { - let queue = queue_store("test_reschedule_finished_task"); + let storage = storage_system(); + let queue = queue_store(&storage, "test_reschedule_finished_task"); queue.store.wipe().unwrap(); let name = const { Ident::make("task") }; @@ -611,7 +615,8 @@ mod tests { #[test] fn test_schedule_with_existing_task() { - let queue = queue_store("test_schedule_with_existing_task"); + let storage = storage_system(); + let queue = queue_store(&storage, "test_reschedule_finished_task"); queue.store.wipe().unwrap(); let name = const { Ident::make("task") }; diff --git a/src/commons/storage/backends/disk.rs b/src/commons/storage/backends/disk.rs index 9c13ceaa..235c5154 100644 --- a/src/commons/storage/backends/disk.rs +++ b/src/commons/storage/backends/disk.rs @@ -1,6 +1,6 @@ //! Filesystem-based storage. -use std::{fmt, fs, io}; +use std::{error, fmt, fs, io}; use std::borrow::Cow; use std::fs::{File, OpenOptions}; use std::path::{Path, PathBuf}; @@ -28,6 +28,98 @@ const LOCK_FILE_DIR: &str = ".locks"; pub const LOCK_FILE_NAME: &str = "lockfile.lock"; +//------------ System -------------------------------------------------------- + +#[derive(Debug, Default)] +pub struct System(()); + +impl System { + pub fn location(&self, uri: &Uri) -> Result { + Ok(Location { base: uri.path.clone() }) + } +} + + +//------------ Location ------------------------------------------------------ + +#[derive(Debug)] +pub struct Location { + /// The base directory. + /// + /// All the namespaces plus a few extra repositories are under this + /// directory. + base: PathBuf, +} + +impl Location { + pub fn open( + &self, namespace: &Ident, + ) -> Result { + Store::new(&self.base, namespace) + } + + pub fn is_empty( + &self, namespace: &Ident, + ) -> Result { + self.open(namespace)?.is_empty() + } + + pub fn migrate( + &self, src_ns: &Ident, dst_ns: &Ident + ) -> Result<(), Error> { + let src_store = self.open(src_ns)?; + let dst_root = self.base.join(dst_ns.as_str()); + + // Try removing the destination directory. If it isn’t there, that’s + // fine. Otherwise we error out. + if let Err(err) = fs::remove_dir(&dst_root) + && err.kind() != io::ErrorKind::NotFound + { + return Err(Error::other(format!( + "target dir {} exists and cannot be removed ({})", + dst_root.display(), err + ))); + } + + // The source store must not have any lock files. + #[allow(clippy::collapsible_if)] + if src_store.locks.exists() { + if src_store.locks + .read_dir() + .map_err(|err| { + Error::io( + format!( + "cannot read directory '{}'", + src_store.locks.display(), + ), + err + ) + })? + .next() + .is_some() + { + return Err(Error::other(format!( + "store at '{}' has pending locks", + src_store.root.display(), + ))); + } + } + + fs::rename(&src_store.root, &dst_root).map_err(|err| { + Error::io( + format!( + "cannot rename dir from {} to {}", + src_store.root.display(), + dst_root.display(), + ), + err + ) + })?; + + Ok(()) + } +} + //------------ Store --------------------------------------------------------- @@ -75,16 +167,9 @@ pub struct Store { } impl Store { - pub fn from_uri( - uri: &Url, namespace: &Ident, - ) -> Result, Error> { - if uri.scheme() != "local" { - return Ok(None) - } - - let path = PathBuf::from(format!( - "{}{}", uri.host_str().unwrap_or_default(), uri.path() - )); + fn new( + path: &Path, namespace: &Ident, + ) -> Result { let root = path.join(namespace.as_str()); let tmp = path.join(TMP_FILE_DIR); let mut locks = path.join(LOCK_FILE_DIR); @@ -100,7 +185,7 @@ impl Store { ) })?; - Ok(Some(Self { root, tmp, locks })) + Ok(Self { root, tmp, locks }) } pub fn execute( @@ -109,9 +194,18 @@ impl Store { where F: for<'a> Fn(&mut SuperTransaction<'a>) -> Result { - let mut file_lock = FileLock::create(self.scope_lock_path(scope))?; - let _write_lock = file_lock.write()?; - op(&mut SuperTransaction::from(self)) + if scope.is_none() { + let mut file_lock = FileLock::create(self.scope_lock_path(scope))?; + let _write_lock = file_lock.write()?; + op(&mut SuperTransaction::from(self)) + } + else { + let mut root_lock = FileLock::create(self.scope_lock_path(None))?; + let _root_lock = root_lock.read()?; + let mut file_lock = FileLock::create(self.scope_lock_path(scope))?; + let _write_lock = file_lock.write()?; + op(&mut SuperTransaction::from(self)) + } } /// Returns the path for the given key. @@ -263,8 +357,7 @@ impl Store { )); } }; - if - file_type.is_file() + if file_type.is_file() && let Some(name) = item.file_name().into_string().ok().and_then(|name| { Ident::boxed_from_string(name).ok() @@ -320,8 +413,7 @@ impl Store { )); } }; - if - file_type.is_dir() + if file_type.is_dir() && let Some(name) = item.file_name().into_string().ok().and_then(|name| { Ident::boxed_from_string(name).ok() @@ -500,54 +592,6 @@ impl Store { Ok(()) } - pub fn migrate_namespace( - &mut self, namespace: &Ident, - ) -> Result<(), Error> { - let root_parent = self.root.parent().ok_or_else(|| { - Error::other( - format!("cannot get parent dir for: {}", self.root.display()) - ) - })?; - - let new_root = root_parent.join(namespace.as_str()); - - if new_root.exists() { - // If the target directory already exists, then it must be empty. - if new_root - .read_dir() - .map_err(|err| { - Error::io( - format!( - "cannot read directory '{}'", - new_root.display(), - ), - err - ) - })? - .next() - .is_some() - { - return Err(Error::other(format!( - "target dir {} already exists and is not empty", - new_root.display(), - ))); - } - } - - fs::rename(&self.root, &new_root).map_err(|err| { - Error::io( - format!( - "cannot rename dir from {} to {}", - self.root.display(), - new_root.display(), - ), - err - ) - })?; - self.root = new_root; - Ok(()) - } - /// Creates the given directory if necessary. fn create_dirs(path: Option<&Path>) -> Result<(), Error> { if let Some(path) = path { @@ -609,6 +653,12 @@ impl FileLock { Ok(FileLock { lock: fd_lock::RwLock::new(lock_file) }) } + fn read(&mut self) -> Result, Error> { + self.lock + .read() + .map_err(|e| Error::other(format!("Cannot get file lock: {e}"))) + } + fn write(&mut self) -> Result, Error> { self.lock .write() @@ -617,6 +667,50 @@ impl FileLock { } +//------------ Uri ----------------------------------------------------------- + +#[derive(Clone, Debug, PartialEq)] +pub struct Uri { + path: PathBuf, +} + +impl Uri { + pub fn new(path: PathBuf) -> Self { + Self { path } + } + + pub fn parse_uri(uri: &Url) -> Result, UriError> { + if uri.scheme() != "file" && uri.scheme() != "local" { + return Ok(None) + } + + if !uri.authority().is_empty() { + return Err(UriError::HasAuthority(uri.authority().into())) + } + + Self::parse_str(uri.path()).map(Some) + } + + pub fn parse_str(s: &str) -> Result { + let path = PathBuf::from(s); + if !path.is_absolute() { + return Err(UriError::RelativePath(path)) + } + Ok(Self { path }) + } + + pub fn path(&self) -> &Path { + &self.path + } +} + +impl fmt::Display for Uri { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "file://{}", self.path.display()) + } +} + + //------------ Error --------------------------------------------------------- #[derive(Debug)] @@ -711,3 +805,33 @@ impl fmt::Display for Error { } } +impl error::Error for Error { } + + +//------------ UriError ------------------------------------------------------ + +#[derive(Debug)] +pub enum UriError { + HasAuthority(String), + MissingPath, + RelativePath(PathBuf), +} + +impl fmt::Display for UriError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::HasAuthority(host) => { + write!(f, "non-local path with host '{host}'") + } + Self::MissingPath => { + write!(f, "missing path") + } + Self::RelativePath(path) => { + write!(f, "{} is not absolute.", path.display()) + } + } + } +} + +impl error::Error for UriError { } + diff --git a/src/commons/storage/backends/memory.rs b/src/commons/storage/backends/memory.rs index 29706234..d5038416 100644 --- a/src/commons/storage/backends/memory.rs +++ b/src/commons/storage/backends/memory.rs @@ -1,11 +1,10 @@ //! In-memory storage. -use std::{error, fmt, mem, thread}; -use std::collections::{HashMap, HashSet}; +use std::{error, fmt, mem}; +use std::collections::HashMap; use std::ops::DerefMut; -use std::sync::{Arc, Mutex, MutexGuard}; -use std::time::Duration; -use lazy_static::lazy_static; +use std::str::FromStr; +use std::sync::{Arc, Mutex, MutexGuard, RwLock}; use serde::de::DeserializeOwned; use serde::ser::Serialize; use serde_json::Value; @@ -17,6 +16,77 @@ use super::{ }; +//------------ System -------------------------------------------------------- + +#[derive(Debug, Default)] +pub struct System { + locations: Mutex, Location>>, +} + +impl System { + pub fn location(&self, uri: &Uri) -> Result { + let mut locations = self.locations.lock().expect("poisoned lock"); + Ok(locations.entry(uri.path).or_default().clone()) + } +} + + +//------------ Location ------------------------------------------------------ + +#[derive(Clone, Debug, Default)] +pub struct Location { + namespaces: Arc, Arc>>>, +} + +impl Location { + pub fn open( + &self, namespace: &Ident, + ) -> Result { + let mut namespaces = self.namespaces.lock().expect("poisoned lock"); + Ok(Store::new( + namespaces.entry(namespace.into()).or_default().clone() + )) + } + + pub fn is_empty( + &self, namespace: &Ident, + ) -> Result { + let namespaces = self.namespaces.lock().expect("poisoned lock"); + let Some(namespace) = namespaces.get(namespace) else { + return Ok(true) + }; + Ok(namespace.scopes().is_empty()) + } + + pub fn migrate( + &self, src_ns: &Ident, dst_ns: &Ident + ) -> Result<(), Error> { + let mut namespaces = self.namespaces.lock().expect("poisoned lock"); + { + let Some(src) = namespaces.get(src_ns).cloned() else { + return Err(Error::MissingSourceNamespace(src_ns.into())) + }; + + src.try_clear_locks()?; + + let dst = namespaces.entry(dst_ns.into()).or_default().clone(); + dst.try_clear_locks()?; + + let mut dst_scopes = dst.scopes(); + if !dst_scopes.is_empty() { + return Err(Error::NonemptyTargetNamespace(dst_ns.into())) + } + + mem::swap(dst_scopes.deref_mut(), src.scopes().deref_mut()); + } + + namespaces.remove(src_ns); + + Ok(()) + } +} + + //------------ Store --------------------------------------------------------- #[derive(Debug)] @@ -25,23 +95,8 @@ pub struct Store { } impl Store { - pub fn wipe_all() { - MEMORY.wipe_all() - } - - pub fn from_uri( - uri: &Url, namespace: &Ident, - ) -> Result, Error> { - if uri.scheme() != "memory" { - return Ok(None) - } - - Ok(Some(Store { - namespace: MEMORY.get_namespace( - uri.host_str().unwrap_or_default().into(), - namespace.into() - ) - })) + fn new(namespace: Arc) -> Self { + Store { namespace } } pub fn execute( @@ -50,25 +105,34 @@ impl Store { where F: for<'a> Fn(&mut SuperTransaction<'a>) -> Result { - let wait = Duration::from_millis(10); - let tries = 1000; - - for i in 0..tries { - if self.namespace.locks().insert(scope.map(Into::into)) { - // The scope was not yet present. We’ve won and can go on. - break - } - else if i >= tries { - return Err(Error::ScopeLocked(scope.map(Into::into)).into()) - } - thread::sleep(wait); + match scope { + Some(scope) => self.execute_scoped(scope.into(), op), + None => self.execute_global(op), } + } - let res = op(&mut SuperTransaction::from(self)); + fn execute_global( + &self, op: F + ) -> Result + where + F: for<'a> Fn(&mut SuperTransaction<'a>) -> Result + { + let _lock = self.namespace.get_lock(None); + let _lock = _lock.write().expect("poisoned lock"); + op(&mut SuperTransaction::from(self)) + } - self.namespace.locks().remove(&scope.map(Into::into)); - - res + fn execute_scoped( + &self, scope: Box, op: F + ) -> Result + where + F: for<'a> Fn(&mut SuperTransaction<'a>) -> Result + { + let _root_lock = self.namespace.get_lock(None); + let _root_lock = _root_lock.read().expect("poisoned lock"); + let _lock = self.namespace.get_lock(Some(scope)); + let _lock = _lock.write().expect("poisoned lock"); + op(&mut SuperTransaction::from(self)) } } @@ -211,34 +275,6 @@ impl Store { self.namespace.scopes().clear(); Ok(()) } - - pub fn migrate_namespace( - &mut self, target: &Ident - ) -> Result<(), Error> { - if !self.namespace.locks().is_empty() { - return Err(Error::PendingLocks); - } - let mut namespaces = MEMORY.namespaces.lock().expect("poisoned lock"); - let new_key = (self.namespace.ns_key.0.clone(), target.into()); - let new = namespaces.entry(new_key.clone()).or_insert_with(|| { - MemoryNamespace::new(new_key).into() - }).clone(); - - // Check that new is empty. - let mut new_values = new.scopes(); - if !new_values.is_empty() { - return Err(Error::NonemptyTargetNamespace(target.into())) - } - - // Swap out the values. - mem::swap(new_values.deref_mut(), self.namespace.scopes().deref_mut()); - - // Delete our namespace - namespaces.remove(&self.namespace.ns_key); - - self.namespace = new.clone(); - Ok(()) - } } @@ -341,71 +377,77 @@ impl MemoryScopes { //------------ MemoryNamespace ----------------------------------------------- -#[derive(Debug)] +#[derive(Debug, Default)] struct MemoryNamespace { - ns_key: NsKey, scopes: Mutex, - locks: Mutex>>>, + #[allow(clippy::type_complexity)] + locks: Mutex>, Arc>>>, } impl MemoryNamespace { - fn new(ns_key: NsKey) -> Self { - Self { - ns_key, - scopes: Default::default(), - locks: Default::default(), - } - } - fn scopes(&self) -> MutexGuard<'_, MemoryScopes> { self.scopes.lock().expect("poisoned lock") } - fn locks(&self) -> MutexGuard<'_, HashSet>>> { + fn get_lock(&self, scope: Option>) -> Arc> { + self.locks().entry(scope).or_default().clone() + } + + #[allow(clippy::type_complexity)] + fn locks( + &self + ) -> MutexGuard<'_, HashMap>, Arc>>> { self.locks.lock().expect("poisoned lock") } -} + fn try_clear_locks(&self) -> Result<(), Error> { + // Try to get a write lock on every present lock. If that succeeds, + // clear the hash map. -//------------ NsKey --------------------------------------------------------- - -/// The key for a store. -/// -/// The first component is the URI, the second the namespace within that URI. -type NsKey = (String, Box); - - -//------------ Memory -------------------------------------------------------- - -/// The place where data is actually stored. -#[derive(Debug, Default)] -struct Memory { - namespaces: Mutex>>, -} - -impl Memory { - fn wipe_all(&self) { - self.namespaces.lock().expect("poisoned lock").clear(); - } - - fn get_namespace( - &self, - prefix: String, - namespace: Box, - ) -> Arc { - let ns_key = (prefix, namespace); - let mut namespaces = self.namespaces.lock().expect("poisoned lock"); - namespaces.entry(ns_key.clone()).or_insert_with(|| { - MemoryNamespace::new(ns_key).into() - }).clone() + let mut locks = self.locks(); + for lock in locks.values() { + drop(lock.try_write().map_err(|_| Error::PendingLocks)?); + } + locks.clear(); + Ok(()) } } -//------------ MEMORY -------------------------------------------------------- +//------------ Uri ----------------------------------------------------------- -lazy_static! { - static ref MEMORY: Memory = Memory::default(); +#[derive(Clone, Debug, PartialEq)] +pub struct Uri { + path: Option, +} + +impl Uri { + pub fn new(seed: Option) -> Self { + Uri { path: seed } + } + + pub fn parse_uri(uri: &Url) -> Result, UriError> { + if uri.scheme() != "memory" { + return Ok(None) + } + if uri.path().is_empty() { + return Ok(Some(Uri { path: None })) + } + if let Ok(path) = u64::from_str(uri.path()) { + return Ok(Some(Uri { path: Some(path) })) + } + Err(UriError::BadPath(uri.path().into())) + } +} + +impl fmt::Display for Uri { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.write_str("memory:")?; + if let Some(path) = self.path { + write!(f, "{path}")? + } + Ok(()) + } } @@ -430,6 +472,7 @@ pub enum Error { }, NoScope(Box), TargetScopeExists(Box), + MissingSourceNamespace(Box), NonemptyTargetNamespace(Box), PendingLocks, } @@ -511,6 +554,9 @@ impl fmt::Display for Error { Error::TargetScopeExists(scope) => { write!(f, "target scope '{scope}' exists") } + Error::MissingSourceNamespace(ns) => { + write!(f, "missing source namespace '{ns}'") + } Error::NonemptyTargetNamespace(ns) => { write!(f, "non-empty target namespace '{ns}'") } @@ -523,3 +569,21 @@ impl fmt::Display for Error { impl error::Error for Error { } + +//------------ UriError ------------------------------------------------------ + +#[derive(Debug)] +pub enum UriError { + BadPath(String), +} + +impl fmt::Display for UriError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match self { + Self::BadPath(path) => write!(f, "invalid memory path '{path}'"), + } + } +} + +impl error::Error for UriError { } + diff --git a/src/commons/storage/backends/mod.rs b/src/commons/storage/backends/mod.rs index 94a65f0b..19caa7e2 100644 --- a/src/commons/storage/backends/mod.rs +++ b/src/commons/storage/backends/mod.rs @@ -12,15 +12,117 @@ pub(super) mod memory; // Test code wants to access the Store directly. //============ Backend Enum ================================================== -use std::fmt; +use std::{error, fmt}; +use std::path::{Path, PathBuf}; +use std::str::FromStr; use serde::de::DeserializeOwned; use serde::ser::Serialize; use url::Url; -use super::Ident; +use super::{Ident, KeyValueError}; macro_rules! store { ( $( ( $variant:ident, $module:ident ) )* ) => { + //------------ BackendSystem ----------------------------------------- + + #[derive(Debug, Default)] + pub struct BackendSystem { + $( + $module: self::$module::System, + )* + } + + impl BackendSystem { + fn location( + &self, uri: &StorageUri + ) -> Result { + match &uri.0 { + $( + UriInner::$variant(uri) => { + Ok(Location::$variant( + self.$module.location(uri).map_err(|err| { + KeyValueError::Inner( + Error(ErrorInner::$variant(err)) + ) + })? + )) + } + )* + } + } + + pub fn open( + &self, storage_uri: &StorageUri, namespace: &Ident, + ) -> Result { + Ok(self.location(storage_uri)?.open(namespace)?) + } + + pub fn is_empty( + &self, storage_uri: &StorageUri, namespace: &Ident, + ) -> Result { + Ok(self.location(storage_uri)?.is_empty(namespace)?) + } + + pub fn migrate( + &self, + storage_uri: &StorageUri, + src_ns: &Ident, + dst_ns: &Ident + ) -> Result<(), KeyValueError> { + Ok(self.location(storage_uri)?.migrate(src_ns, dst_ns)?) + } + } + + + //------------ Location ---------------------------------------------- + + #[derive(Debug)] + enum Location { + $( + $variant( self::$module::Location ), + )* + } + + impl Location { + fn open( + &self, namespace: &Ident, + ) -> Result { + match self { + $( + Self::$variant(inner) => { + Ok(Backend(StoreInner::$variant( + inner.open(namespace)? + ))) + } + )* + } + } + + fn is_empty( + &self, namespace: &Ident, + ) -> Result { + match self { + $( + Self::$variant(inner) => { + Ok(inner.is_empty(namespace)?) + } + )* + } + } + + fn migrate( + &self, src_ns: &Ident, dst_ns: &Ident + ) -> Result<(), Error> { + match self { + $( + Self::$variant(inner) => { + Ok(inner.migrate(src_ns, dst_ns)?) + } + )* + } + } + } + //------------ Backend ----------------------------------------------- @@ -35,21 +137,6 @@ macro_rules! store { } impl Backend { - pub fn new( - storage_uri: &Url, namespace: &Ident, - ) -> Result, Error> { - $( - if let Some(inner) = - self::$module::Store::from_uri( - storage_uri, namespace - )? { - return Ok(Some(Backend(StoreInner::$variant(inner)))) - } - )* - - Ok(None) - } - pub fn execute( &self, scope: Option<&Ident>, op: F ) -> Result @@ -98,18 +185,6 @@ macro_rules! store { )* } } - - pub fn migrate_namespace( - &mut self, to: &Ident, - ) -> Result<(), Error> { - match &mut self.0 { - $( - StoreInner::$variant(inner) => { - Ok(inner.migrate_namespace(to)?) - } - )* - } - } } @@ -295,6 +370,89 @@ macro_rules! store { pub type Value = serde_json::Value; + //------------ StorageUri -------------------------------------------- + + #[derive(Clone, Debug, PartialEq)] + pub struct StorageUri(UriInner); + + #[derive(Clone, Debug, PartialEq)] + enum UriInner { + $( + $variant(self::$module::Uri), + )* + } + + impl StorageUri { + pub fn memory(seed: Option) -> Self { + Self(UriInner::Memory(self::memory::Uri::new(seed))) + } + + pub fn disk(path: PathBuf) -> Self { + Self(UriInner::Disk(self::disk::Uri::new(path))) + } + + pub fn data_dir(&self) -> Option<&Path> { + if let UriInner::Disk(inner) = &self.0 { + Some(inner.path()) + } + else { + None + } + } + } + + impl<'de> serde::Deserialize<'de> for StorageUri { + fn deserialize>( + deserializer: D + ) -> Result { + Self::from_str(&String::deserialize(deserializer)?).map_err( + serde::de::Error::custom + ) + } + } + + impl FromStr for StorageUri { + type Err = ParseStorageUriError; + + fn from_str(s: &str) -> Result { + match Url::parse(s) { + Ok(url) => { + $( + if let Some(res) = + self::$module::Uri::parse_uri(&url)? + { + return Ok(StorageUri(UriInner::$variant(res))) + } + )* + + Err(ParseStorageUriError( + UriErrorInner::UnknownScheme( + url.scheme().into() + ) + )) + } + Err(_) => { + self::disk::Uri::parse_str(s).map(|disk| { + Self(UriInner::Disk(disk)) + }).map_err(|err| { + ParseStorageUriError(UriErrorInner::Disk(err)) + }) + } + } + } + } + + impl fmt::Display for StorageUri { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match &self.0 { + $( + UriInner::$variant(inner) => inner.fmt(f), + )* + } + } + } + + //------------ Error ------------------------------------------------- #[derive(Debug)] @@ -324,6 +482,45 @@ macro_rules! store { } } } + + impl error::Error for Error { } + + + //------------ ParseStorageUriError ---------------------------------- + + #[derive(Debug)] + pub struct ParseStorageUriError(UriErrorInner); + + #[derive(Debug)] + enum UriErrorInner { + UnknownScheme(String), + $( + $variant(self::$module::UriError), + )* + } + + $( + impl From for ParseStorageUriError { + fn from(src: self::$module::UriError) -> Self { + Self(UriErrorInner::$variant(src)) + } + } + )* + + impl fmt::Display for ParseStorageUriError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match &self.0 { + UriErrorInner::UnknownScheme(scheme) => { + write!(f, "unknown scheme '{scheme}'") + } + $( + UriErrorInner::$variant(err) => err.fmt(f), + )* + } + } + } + + impl error::Error for ParseStorageUriError { } } } diff --git a/src/commons/storage/mod.rs b/src/commons/storage/mod.rs index f54be028..e8ba856e 100644 --- a/src/commons/storage/mod.rs +++ b/src/commons/storage/mod.rs @@ -1,8 +1,14 @@ //! Persistent storage of data. -pub use self::backends::{Backend, Transaction, Error}; +pub use self::backends::{ + StorageUri, ParseStorageUriError, Transaction, Error, +}; pub use self::ident::{Ident, IdentBuilder, IdentError}; -pub use self::store::{KeyValueStore, KeyValueError}; +pub use self::store::{ + KeyValueStore, KeyValueError, OpenStoreError, StorageSystem, +}; + +use self::backends::{Backend, BackendSystem}; mod backends; mod ident; diff --git a/src/commons/storage/store.rs b/src/commons/storage/store.rs index 9c62af56..f33b8c61 100644 --- a/src/commons/storage/store.rs +++ b/src/commons/storage/store.rs @@ -1,12 +1,152 @@ //! The publicly exposed key-value store. -use std::fmt; +use std::{error, fmt}; +use std::path::PathBuf; use serde::de::DeserializeOwned; use serde::ser::Serialize; -use url::Url; - use crate::commons::storage; -use crate::commons::storage::{Backend, Ident, Transaction}; +use crate::commons::error::Error; +use crate::commons::storage::{ + Backend, BackendSystem, Ident, StorageUri, Transaction +}; + + +//------------ StorageSystem ------------------------------------------------- + +/// The system that provides the key-value stores. +#[derive(Debug)] +pub struct StorageSystem { + /// The storage URI to use by default. + default_uri: StorageUri, + + /// The storage systems of the various supported backends. + backend: BackendSystem, +} + +impl StorageSystem { + /// Creates a new storage system. + /// + /// The provided URI will be used as the default storage URI. + pub fn new( + default_uri: StorageUri + ) -> Self { + Self { + default_uri, + backend: Default::default(), + } + } + + /// Creates a new memory storage system using the given seed. + /// + /// This is primarily used for testing. + pub fn new_memory(seed: Option) -> Self { + Self::new(StorageUri::memory(seed)) + } + + /// Creates a new disk storage system using the given path. + pub fn new_disk(path: PathBuf) -> Self { + Self::new(StorageUri::disk(path)) + } + + /// Opens the default store with the given namespace. + pub fn open( + &self, namespace: &Ident + ) -> Result { + self.open_uri(&self.default_uri, namespace) + } + + /// Opens a store for upgrades for the given namespace. + /// + /// Prefixes the namespace with `"upgrade_"`. + pub fn open_upgrade( + &self, namespace: &Ident + ) -> Result { + self.open_uri( + &self.default_uri, + &KeyValueStore::prefixed_namespace( + namespace, const { Ident::make("upgrade") } + ) + ) + } + + /// Opens a store with the given storage URI and namespace. + pub fn open_uri( + &self, storage_uri: &StorageUri, namespace: &Ident + ) -> Result { + Ok(KeyValueStore { + inner: self.backend.open( + storage_uri, namespace + ).map_err(|err| { + OpenStoreError(err) + })? + }) + } + + /// Returns the default URI of the storage system. + pub fn default_uri(&self) -> &StorageUri { + &self.default_uri + } + + /// Checks whether the given namespace is empty. + pub fn is_empty(&self, namespace: &Ident) -> Result { + self.backend.is_empty(&self.default_uri, namespace) + } + + /// Checks whether the upgrade store for the given namespace is empty. + pub fn is_upgrade_empty( + &self, namespace: &Ident + ) -> Result { + self.is_empty( + &KeyValueStore::prefixed_namespace( + namespace, const { Ident::make("upgrade") } + ) + ) + } + + /// Archives the given namespace. + /// + /// The namespace is moved to a namespace prefixed with `"archive"`. If + /// such a namespace already exists, it is removed. + pub fn migrate_to_archive( + &self, namespace: &Ident + ) -> Result<(), KeyValueError> { + let archive_ns = KeyValueStore::prefixed_namespace( + namespace, const { Ident::make("archive") } + ); + + // Wipe any existing archive, before archiving this store. + // We don't want to keep too much old data. See issue: #1088. + self.open(&archive_ns)?.wipe()?; + + self.backend.migrate( + &self.default_uri, namespace, &archive_ns + )?; + Ok(()) + } + + /// Migrates an upgrade namespace to the normal namespace. + /// + /// This moves the namespace prefixed by `"upgrade"` to the namespace. + /// Fails if the given namespace is not empty. + pub fn migrate_to_current( + &self, namespace: &Ident + ) -> Result<(), KeyValueError> { + if !self.is_empty(namespace)? { + return Err(KeyValueError::Other(format!( + "Abort migrate upgraded store for {namespace} to current. \ + The current store was not archived." + ))) + } + + let upgrade_ns = KeyValueStore::prefixed_namespace( + namespace, const { Ident::make("upgrade") } + ); + self.backend.migrate( + &self.default_uri, &upgrade_ns, namespace + )?; + Ok(()) + } +} //------------ KeyValueStore ------------------------------------------------- @@ -27,18 +167,6 @@ pub struct KeyValueStore { } impl KeyValueStore { - /// Creates a new store. - pub fn create( - storage_uri: &Url, - namespace: &Ident, - ) -> Result { - Ok(Self { - inner: Backend::new(storage_uri, namespace)?.ok_or_else(|| { - KeyValueError::UnknownScheme(storage_uri.scheme().into()) - })? - }) - } - /// Returns whether the store has no entries. pub fn is_empty(&self) -> Result { // NOTE: this is not done using `self.execute` as this would result @@ -171,21 +299,6 @@ impl KeyValueStore { // # Migration Support impl KeyValueStore { - /// Creates a new KeyValueStore for upgrades. - /// - /// Adds the implicit prefix "upgrade_" to the given namespace. - pub fn create_upgrade_store( - storage_uri: &Url, - namespace: &Ident, - ) -> Result { - Self::create( - storage_uri, - &Self::prefixed_namespace( - namespace, const { Ident::make("upgrade") } - ) - ) - } - fn prefixed_namespace( namespace: &Ident, prefix: &Ident, @@ -197,44 +310,6 @@ impl KeyValueStore { ).finish() } - /// Archive this store (i.e. for this namespace). Deletes - /// any existing archive for this namespace if present. - pub fn migrate_to_archive( - &mut self, - storage_uri: &Url, - namespace: &Ident, - ) -> Result<(), KeyValueError> { - let archive_ns = Self::prefixed_namespace( - namespace, const { Ident::make("archive") } - ); - - // Wipe any existing archive, before archiving this store. - // We don't want to keep too much old data. See issue: #1088. - KeyValueStore::create(storage_uri, &archive_ns)?.wipe()?; - self.inner.migrate_namespace(&archive_ns)?; - Ok(()) - } - - /// Make this (upgrade) store the current store. - /// - /// Fails if there is a non-empty current store. - pub fn migrate_to_current( - &mut self, - storage_uri: &Url, - namespace: &Ident, - ) -> Result<(), KeyValueError> { - let current_store = KeyValueStore::create(storage_uri, namespace)?; - if !current_store.is_empty()? { - Err(KeyValueError::Other(format!( - "Abort migrate upgraded store for {namespace} to current. The current store was not archived." - ))) - } else { - self.inner - .migrate_namespace(namespace) - .map_err(KeyValueError::Inner) - } - } - /// Import all data from the given KV store into this /// /// The closure `keep` is given each scope and decides whether it should @@ -269,6 +344,32 @@ impl KeyValueStore { } +//============ Error Types =================================================== +// +// These need cleaning up. + + +//------------ OpenStoreError ------------------------------------------------ + +/// An error occured while opening a store. +#[derive(Debug)] +pub struct OpenStoreError(KeyValueError); + +impl fmt::Display for OpenStoreError{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + self.0.fmt(f) + } +} + +impl error::Error for OpenStoreError { } + +impl From for Error { + fn from(src: OpenStoreError) -> Error { + Error::custom(format_args!("{}", src)) + } +} + + //------------ KeyValueError ------------------------------------------------- /// This type defines possible Errors for KeyStore @@ -292,6 +393,12 @@ impl From for KeyValueError { } } +impl From for KeyValueError { + fn from(src: OpenStoreError) -> Self { + src.0 + } +} + impl fmt::Display for KeyValueError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match self { diff --git a/src/commons/storage/test.rs b/src/commons/storage/test.rs index a5a4ada2..aead9caf 100644 --- a/src/commons/storage/test.rs +++ b/src/commons/storage/test.rs @@ -4,11 +4,8 @@ //! requires a wee bit of macro magic. #![cfg(test)] -use std::sync::{Mutex, MutexGuard}; -use lazy_static::lazy_static; use tempfile::{TempDir, tempdir}; -use url::Url; -use super::{Ident, KeyValueStore}; +use super::{Ident, KeyValueStore, StorageSystem, StorageUri}; //------------ Macro to Construct Tests -------------------------------------- @@ -73,7 +70,7 @@ const CONTENT_4: u32 = 45; // All the test functions. // -// The all need to have the same signature taking one argument as an +// They all need to have the same signature taking one argument as an // `impl Harness` and return unit. Each function will be transformed into a // test function for each of the backends (currently memory and disk). The // harness will give it access to a temporary test store atop that given @@ -130,12 +127,9 @@ testfns! { fn drop_global_key(harness: impl Harness) { let store = harness.store(NAMESPACE); - assert!(store.drop_key(None, KEY).is_err()); - store.store(None, KEY, &CONTENT).unwrap(); assert!(store.has(None, KEY).unwrap()); - store.drop_key(None, KEY).unwrap(); assert!(!store.has(None, KEY).unwrap()); } @@ -301,7 +295,7 @@ testfns! { trait Harness { /// Returns the URL of the backend. #[allow(dead_code)] - fn url(&self) -> Url; + fn uri(&self) -> &StorageUri; /// Creates a new store for the given namespace. fn store(&self, namespace: &Ident) -> KeyValueStore; @@ -311,48 +305,25 @@ trait Harness { //------------ MemoryHarness ------------------------------------------------- /// The test harness for the memory backend. -/// -/// Because there is only a single shared memory store for the whole process, -/// we can only run a single test using it at the same time and need to wipe -/// it clean before the test. This is why there are a lock and a guard here. -struct MemoryHarness<'a> { - _guard: MutexGuard<'a, ()>, +struct MemoryHarness { + storage: StorageSystem, } -lazy_static! { - static ref MEMORY_LOCK: Mutex<()> = Mutex::new(()); -} - -impl<'a> MemoryHarness<'a> { +impl MemoryHarness { fn new() -> Self { - loop { - let _guard = match MEMORY_LOCK.lock() { - Ok(guard) => guard, - Err(_) => { - // If a thread panicked, the lock gets poisoned. But we - // know that a panicked thread (and its test) has ended, - // so we can clear the poison and try to acquire the - // lock again. - MEMORY_LOCK.clear_poison(); - continue; - } - }; - super::backends::memory::Store::wipe_all(); - return Self { _guard } + Self { + storage: StorageSystem::new_memory(None) } } } -impl<'a> Harness for MemoryHarness<'a> { - fn url(&self) -> Url { - Url::parse("memory:").unwrap() +impl Harness for MemoryHarness { + fn uri(&self) -> &StorageUri { + self.storage.default_uri() } fn store(&self, namespace: &Ident) -> KeyValueStore { - KeyValueStore::create( - &Url::parse("memory:").unwrap(), - namespace, - ).unwrap() + self.storage.open(namespace).unwrap() } } @@ -365,25 +336,25 @@ impl<'a> Harness for MemoryHarness<'a> { /// removed automatically when the harness is dropped. struct DiskHarness { _dir: TempDir, - url: Url, + storage: StorageSystem, } impl DiskHarness { fn new() -> Self { let _dir = tempdir().unwrap(); - let url = format!("local://{}", _dir.path().display()); - let url = Url::parse(&url).unwrap(); - Self { _dir, url } + let storage = StorageSystem::new_disk(_dir.path().into()); + + Self { _dir, storage } } } impl Harness for DiskHarness { - fn url(&self) -> Url { - self.url.clone() + fn uri(&self) -> &StorageUri { + self.storage.default_uri() } fn store(&self, namespace: &Ident) -> KeyValueStore { - KeyValueStore::create(&self.url, namespace).unwrap() + self.storage.open(namespace).unwrap() } } diff --git a/src/commons/test.rs b/src/commons/test.rs index 931a13d6..f72b02d2 100644 --- a/src/commons/test.rs +++ b/src/commons/test.rs @@ -6,19 +6,19 @@ use std::str::FromStr; use bytes::Bytes; use rpki::uri; use rpki::ca::idcert::IdCert; -use url::Url; use crate::api::roa::{ConfiguredRoa, RoaConfiguration, RoaPayload}; +use crate::commons::storage::StorageSystem; /// This method returns an in-memory Key-Value store and then runs the test /// provided in the closure using it pub fn test_in_memory(op: F) where - F: FnOnce(&Url), + F: FnOnce(&StorageSystem), { - let storage_uri = mem_storage(); + let storage = mem_storage(); - op(&storage_uri); + op(&storage); } /// This method sets up a test directory with a random name (a number) @@ -35,17 +35,8 @@ where op(dir.path().into()); } -fn random_hex_string() -> String { - let mut bytes = [0; 8]; - openssl::rand::rand_bytes(&mut bytes).unwrap(); - hex::encode(bytes) -} - -pub fn mem_storage() -> Url { - let mut bytes = [0; 8]; - openssl::rand::rand_bytes(&mut bytes).unwrap(); - - Url::parse(&format!("memory://{}", random_hex_string())).unwrap() +pub fn mem_storage() -> StorageSystem { + StorageSystem::new_memory(Some(rand::random())) } pub fn rsync(s: &str) -> uri::Rsync { diff --git a/src/config.rs b/src/config.rs index d0f2b759..b30817ab 100644 --- a/src/config.rs +++ b/src/config.rs @@ -18,7 +18,6 @@ use rpki::{ }; use serde::de; use serde::{Deserialize, Deserializer, Serialize}; -use url::Url; #[cfg(unix)] use std::collections::HashMap; @@ -30,9 +29,8 @@ use crate::{ commons::{ ext_serde, crypto::{OpenSslSignerConfig, SignSupport}, - error::{Error, KrillIoError}, - storage::{Ident, KeyValueStore}, - KrillResult, + error::KrillIoError, + storage::StorageUri, }, constants::*, daemon::{ @@ -91,13 +89,6 @@ impl ConfigDefaults { users } - pub fn storage_uri() -> Url { - env::var(KRILL_ENV_STORAGE_URI) - .ok() - .and_then(|s| Url::parse(&s).ok()) - .unwrap_or_else(|| Url::parse("local://./data").unwrap()) - } - pub fn log_level() -> LevelFilter { match env::var(KRILL_ENV_LOG_LEVEL) { Ok(level) => match LevelFilter::from_str(&level) { @@ -473,21 +464,6 @@ where ).map(|oom| oom.into()) } -pub fn deserialize_storage_uri<'de, D>( - deserializer: D, -) -> Result -where - D: Deserializer<'de>, -{ - let url = String::deserialize(deserializer)?; - match Url::parse(&url) { - Ok(url) => Ok(url), - Err(_) => { - Url::parse(&format!("local://{url}/")).map_err(de::Error::custom) - } - } -} - fn deserialize_minutes_duration<'de, D: Deserializer<'de>>( deserializer: D ) -> Result { @@ -530,10 +506,8 @@ pub struct Config { // Deserialize this field from data_dir or storage_uri #[serde( alias = "data_dir", - default = "ConfigDefaults::storage_uri", - deserialize_with = "deserialize_storage_uri" )] - pub storage_uri: Url, + pub storage_uri: StorageUri, #[serde(default = "ConfigDefaults::dflt_true")] pub use_history_cache: bool, @@ -948,36 +922,10 @@ pub struct Benchmark { /// # Accessors impl Config { - /// General purpose KV store, can be used to track server settings - /// etc not specific to any Aggregate or WalSupport type - pub fn general_key_value_store(&self) -> KrillResult { - KeyValueStore::create(&self.storage_uri, PROPERTIES_NS) - .map_err(Error::KeyValueError) - } - - pub fn key_value_store( - &self, - namespace: &Ident, - ) -> KrillResult { - KeyValueStore::create(&self.storage_uri, namespace) - .map_err(Error::KeyValueError) - } - /// Returns the data directory if disk was used for storage. /// This will always be true for upgrades of pre 0.14.0 versions - fn data_dir(&self) -> Option { - if self.storage_uri.scheme() != "local" { - None - } else { - Some( - Path::new(&format!( - "{}{}", - self.storage_uri.host_str().unwrap_or(""), - self.storage_uri.path() - )) - .to_path_buf(), - ) - } + fn data_dir(&self) -> Option<&Path> { + self.storage_uri.data_dir() } pub fn tls_keys_dir(&self) -> &PathBuf { @@ -1156,7 +1104,7 @@ impl Config { impl Config { #[cfg(test)] fn test_config( - storage_uri: &Url, + storage_uri: &StorageUri, data_dir: Option<&Path>, enable_testbed: bool, enable_ca_refresh: bool, @@ -1347,7 +1295,7 @@ impl Config { #[cfg(test)] pub fn test( - test_storage: &Url, + test_storage: &StorageUri, test_dir: Option<&Path>, enable_testbed: bool, enable_ca_refresh: bool, @@ -1367,7 +1315,9 @@ impl Config { } #[cfg(test)] - pub fn pubd_test(storage_uri: &Url, data_dir: Option<&Path>) -> Self { + pub fn pubd_test( + storage_uri: &StorageUri, data_dir: Option<&Path> + ) -> Self { let mut config = Self::test_config( storage_uri, data_dir, @@ -1439,29 +1389,26 @@ impl Config { } if self.tls_keys_dir.is_none() { - if let Some(mut data_dir) = self.data_dir() { - data_dir.push(HTTPS_SUB_DIR); - self.tls_keys_dir = Some(data_dir); + if let Some(data_dir) = self.data_dir() { + self.tls_keys_dir = Some(data_dir.join(HTTPS_SUB_DIR)); } else { - return Err(ConfigError::other("'tls_keys_dir' is not configured, but 'storage_uri' is not a local directory, please configure an 'tls_keys_dir'")); + return Err(ConfigError::other("'tls_keys_dir' is not configured, but 'storage_uri' is not a local directory, please configure a 'tls_keys_dir'")); } } if self.repo_dir.is_none() { - if let Some(mut data_dir) = self.data_dir() { - data_dir.push(REPOSITORY_DIR); - self.repo_dir = Some(data_dir); + if let Some(data_dir) = self.data_dir() { + self.repo_dir = Some(data_dir.join(REPOSITORY_DIR)); } else { - return Err(ConfigError::other("'repo_dir' is not configured, but 'storage_uri' is not a local directory, please configure an 'repo_dir'")); + return Err(ConfigError::other("'repo_dir' is not configured, but 'storage_uri' is not a local directory, please configure a 'repo_dir'")); } } if self.pid_file.is_none() { - if let Some(mut data_dir) = self.data_dir() { - data_dir.push("krill.pid"); - self.pid_file = Some(data_dir); + if let Some(data_dir) = self.data_dir() { + self.pid_file = Some(data_dir.join("krill.pid")); } else { - return Err(ConfigError::other("'pid_file' is not configured, but 'storage_uri' is not a local directory, please configure an 'pid_file'")); + return Err(ConfigError::other("'pid_file' is not configured, but 'storage_uri' is not a local directory, please configure a 'pid_file'")); } } @@ -2183,7 +2130,10 @@ mod tests { use log::Level as LL; fn void_logger_from_krill_config(config: &str) -> Box { - let c: Config = toml::from_str(config).unwrap(); + let config = format!( + "storage_uri = \"file:///tmp\"\n{}", config + ); + let c: Config = toml::from_str(&config).unwrap(); let void_output = fern::Output::writer(Box::new(io::sink()), ""); let (_, void_logger) = c.fern_logger().chain(void_output).into_log(); @@ -2317,7 +2267,10 @@ mod tests { fn parse_and_process_config_str( config_str: &str, ) -> Result { - let mut c: Config = toml::from_str(config_str).unwrap(); + let config_str = format!( + "storage_uri = \"local:///tmp/\"\n{config_str}" + ); + let mut c: Config = toml::from_str(&config_str).unwrap(); c.process()?; Ok(c) } @@ -2526,7 +2479,8 @@ mod tests { #[test] fn data_dir_for_storage() { fn test_uri(uri: &str, expected_path: &str) { - let storage_uri = Url::parse(uri).unwrap(); + eprintln!("{uri}"); + let storage_uri = StorageUri::from_str(uri).unwrap(); let config = Config::test_config( &storage_uri, None, @@ -2541,9 +2495,9 @@ mod tests { } test_uri("local:///tmp/test", "/tmp/test"); - test_uri("local://./data", "./data"); - test_uri("local://data", "data"); - test_uri("local://data/test", "data/test"); - test_uri("local:///tmp/test", "/tmp/test"); + assert!(StorageUri::from_str("local://tmp/data").is_err()); + assert!(StorageUri::from_str("local://./data").is_err()); + test_uri("local:/data", "/data"); + test_uri("local:/data/test", "/data/test"); } } diff --git a/src/daemon/http/auth/authorizer.rs b/src/daemon/http/auth/authorizer.rs index 38842296..bb2bb32e 100644 --- a/src/daemon/http/auth/authorizer.rs +++ b/src/daemon/http/auth/authorizer.rs @@ -9,6 +9,7 @@ use crate::api::admin::Token; use crate::commons::KrillResult; use crate::commons::actor::Actor; use crate::commons::error::ApiAuthError; +use crate::commons::storage::StorageSystem; use crate::config::{AuthType, Config}; #[cfg(unix)] use crate::daemon::http::auth::providers::unix_user; @@ -203,7 +204,11 @@ impl Authorizer { /// /// The authorizer will be created according to information provided via /// `config`. - pub fn new(config: &Config) -> KrillResult { + #[allow(unused_variables)] + pub fn new( + storage: &StorageSystem, + config: &Config, + ) -> KrillResult { let (primary_provider, legacy_provider) = match config.auth_type { AuthType::AdminToken => { (admin_token::AuthProvider::new(config).into(), None) @@ -211,14 +216,16 @@ impl Authorizer { #[cfg(feature = "multi-user")] AuthType::ConfigFile => { ( - config_file::AuthProvider::new(config)?.into(), + config_file::AuthProvider::new(storage, config)?.into(), Some(admin_token::AuthProvider::new(config)) ) } #[cfg(feature = "multi-user")] AuthType::OpenIDConnect => { ( - openid_connect::AuthProvider::new(config)?.into(), + openid_connect::AuthProvider::new( + storage, config + )?.into(), Some(admin_token::AuthProvider::new(config)) ) } @@ -248,7 +255,7 @@ impl Authorizer { pub async fn authenticate_request( &self, request: &HyperRequest ) -> (AuthInfo, Option) { - trace!("Determining actor for request {:?}", &request); + trace!("Determining actor for request {:?}", request); // Try the legacy provider first, if any. let authenticate_res = match &self.legacy_provider { @@ -300,7 +307,7 @@ impl Authorizer { let user = self.primary_provider.login(request).await?; if log_enabled!(log::Level::Trace) { - trace!("User logged in: {:?}", &user); + trace!("User logged in: {:?}", user); } else { info!("User logged in: {}, role: {}", user.id(), user.role()); } diff --git a/src/daemon/http/auth/crypt.rs b/src/daemon/http/auth/crypt.rs index 4044d299..199aec27 100644 --- a/src/daemon/http/auth/crypt.rs +++ b/src/daemon/http/auth/crypt.rs @@ -26,8 +26,7 @@ use serde::{Deserialize, Serialize}; use crate::commons::ext_serde; use crate::commons::KrillResult; use crate::commons::error::{ApiAuthError, Error}; -use crate::commons::storage::Ident; -use crate::config::Config; +use crate::commons::storage::{Ident, StorageSystem}; const CHACHA20_KEY_BIT_LEN: usize = 256; const CHACHA20_KEY_BYTE_LEN: usize = CHACHA20_KEY_BIT_LEN / 8; @@ -58,8 +57,7 @@ impl NonceState { let mut sender_unique: [u8; 4] = [0; 4]; openssl::rand::rand_bytes(&mut sender_unique).map_err(|err| { Error::Custom(format!( - "Unable to generate a random sender id: {}", - &err + "Unable to generate a random sender id: {}", err )) })?; @@ -121,7 +119,7 @@ pub(crate) fn encrypt( plaintext, &mut tag, ) - .map_err(|err| Error::Custom(format!("Encryption error: {}", &err)))?; + .map_err(|err| Error::Custom(format!("Encryption error: {}", err)))?; let mut payload = Vec::with_capacity(nonce.len() + tag.len() + cipher_text.len()); @@ -159,13 +157,13 @@ pub(crate) fn decrypt( ) .map_err(|err| { ApiAuthError::ApiInvalidCredentials( - format!("Decryption error: {}", &err) + format!("Decryption error: {}", err) ) }) } -pub(crate) fn crypt_init(config: &Config) -> KrillResult { - let store = config.key_value_store(CRYPT_STATE_NS)?; +pub(crate) fn crypt_init(storage: &StorageSystem) -> KrillResult { + let store = storage.open(CRYPT_STATE_NS)?; if let Some(state) = store.get(None, CRYPT_STATE_KEY)? { Ok(state) diff --git a/src/daemon/http/auth/providers/config_file.rs b/src/daemon/http/auth/providers/config_file.rs index 371c320c..4a224d41 100644 --- a/src/daemon/http/auth/providers/config_file.rs +++ b/src/daemon/http/auth/providers/config_file.rs @@ -12,6 +12,7 @@ use crate::api::admin::Token; use crate::commons::httpclient; use crate::commons::KrillResult; use crate::commons::error::{ApiAuthError, Error}; +use crate::commons::storage::StorageSystem; use crate::constants::{PW_HASH_LOG_N, PW_HASH_P, PW_HASH_R}; use crate::config::Config; use crate::daemon::http::auth::crypt; @@ -56,13 +57,14 @@ pub struct AuthProvider { impl AuthProvider { /// Creates an auth provider from the given config. pub fn new( + storage: &StorageSystem, config: &Config, ) -> KrillResult { let users = config.auth_users.as_ref().ok_or_else(|| { Error::ConfigError("Missing [auth_users] config section!".into()) })?.clone(); let roles = config.auth_roles.clone(); - let session_key = Self::init_session_key(config)?; + let session_key = Self::init_session_key(storage)?; Ok(Self { users, @@ -78,9 +80,11 @@ impl AuthProvider { } - fn init_session_key(config: &Config) -> KrillResult { + fn init_session_key( + storage: &StorageSystem + ) -> KrillResult { debug!("Initializing login session encryption key"); - crypt::crypt_init(config) + crypt::crypt_init(storage) } /// Parse HTTP Basic Authorization header diff --git a/src/daemon/http/auth/providers/openid_connect/provider.rs b/src/daemon/http/auth/providers/openid_connect/provider.rs index 09aab216..5bcc3846 100644 --- a/src/daemon/http/auth/providers/openid_connect/provider.rs +++ b/src/daemon/http/auth/providers/openid_connect/provider.rs @@ -62,6 +62,7 @@ use crate::{ commons::{ httpclient, error::{ApiAuthError, Error}, + storage::StorageSystem, util::sha256, KrillResult, }, @@ -183,8 +184,11 @@ pub struct AuthProvider { } impl AuthProvider { - pub fn new(config: &Config) -> KrillResult { - let session_key = Self::init_session_key(config)?; + pub fn new( + storage: &StorageSystem, + config: &Config, + ) -> KrillResult { + let session_key = Self::init_session_key(storage)?; let Some(oidc_conf) = config.auth_openidconnect.as_ref() else { return Err(Error::ConfigError( @@ -259,7 +263,7 @@ impl AuthProvider { info!( "OpenID Connect: Discovering provider details using issuer {}", - &issuer.as_str() + issuer.as_str() ); // Contact the OpenID Connect: identity provider discovery endpoint to @@ -579,7 +583,7 @@ impl AuthProvider { trace!( "OpenID Connect: Revoking token for user: \"{}\"", - &session.user_id + session.user_id ); trace!("OpenID Connect: Submitting RFC-7009 section 2 Token Revocation request"); let lock_guard = self.get_connection().await.map_err(|err| { @@ -664,7 +668,7 @@ impl AuthProvider { debug!( "OpenID Connect: Refreshing token for user: \"{}\"", - &session.user_id + session.user_id ); trace!("OpenID Connect: Submitting RFC-6749 section 6 Access Token Refresh request"); @@ -754,9 +758,9 @@ impl AuthProvider { } } - fn init_session_key(config: &Config) -> KrillResult { + fn init_session_key(storage: &StorageSystem) -> KrillResult { debug!("Initializing session encryption key"); - crypt::crypt_init(config) + crypt::crypt_init(storage) } fn extract_cookie( @@ -785,7 +789,7 @@ impl AuthProvider { Ok(parsed_cookies) => { trace!( "OpenID Connect: parsed cookies={:?}", - &parsed_cookies + parsed_cookies ); // Even with the helper crate we have to do some // work... Why doesn't it @@ -921,7 +925,7 @@ impl AuthProvider { "OpenID Connect: CSRF token mismatch", Some(&format!( "cookie CSRF hash={:?}, request CSRF hash={:?}", - &cookie_csrf_hash, + cookie_csrf_hash, request_csrf_hash.to_vec() )), )), @@ -1461,7 +1465,7 @@ impl AuthProvider { let (authorize_url, _csrf_state, _nonce) = request.url(); - debug!("OpenID Connect: Login URL will be {:?}", &authorize_url); + debug!("OpenID Connect: Login URL will be {:?}", authorize_url); let res_body = authorize_url.as_str().as_bytes().to_vec(); let mut res = HttpResponse::text_no_cache(res_body).into_response(); @@ -1868,7 +1872,7 @@ impl AuthProvider { trace!( "Telling Lagosta to direct the user to logout at: {}", - &go_to_url + go_to_url ); Ok(HttpResponse::text_no_cache(go_to_url.into())) } diff --git a/src/daemon/http/auth/session.rs b/src/daemon/http/auth/session.rs index 1e3fb79d..9e995e98 100644 --- a/src/daemon/http/auth/session.rs +++ b/src/daemon/http/auth/session.rs @@ -65,7 +65,7 @@ impl ClientSession { trace!( "Login session status check: user_id={}, \ status={:?}, max age={} secs, cur age={} secs", - &self.user_id, &status, max_age_secs, cur_age_secs + self.user_id, status, max_age_secs, cur_age_secs ); return status; @@ -166,7 +166,7 @@ impl LoginSessionCache { secrets }; - debug!("Creating token for session: {:?}", &session); + debug!("Creating token for session: {:?}", session); let session_json_str = serde_json::to_string(&session).map_err(|err| { @@ -231,7 +231,7 @@ impl LoginSessionCache { ) -> Result, ApiAuthError> where S: Clone + DeserializeOwned { if let Some(session) = self.lookup_session(&token).await { - trace!("Session cache hit for session id {}", &session.user_id); + trace!("Session cache hit for session id {}", session.user_id); return Ok(session); } else { @@ -262,7 +262,7 @@ impl LoginSessionCache { trace!( "Session cache miss, deserialized session id {}", - &session.user_id + session.user_id ); if add_to_cache { diff --git a/src/daemon/http/dispatch/auth.rs b/src/daemon/http/dispatch/auth.rs index e73c8b1e..763ece0c 100644 --- a/src/daemon/http/dispatch/auth.rs +++ b/src/daemon/http/dispatch/auth.rs @@ -74,7 +74,7 @@ mod multi_user { request.check_get()?; trace!( - "Authentication callback invoked: {:?}", &request.hyper() + "Authentication callback invoked: {:?}", request.hyper() ); let (server, request) = request.proceed_raw(); @@ -121,9 +121,9 @@ mod multi_user { Ok(format!( "/ui/login?token={}&id={}&attributes={}", - &url_encode(user.token())?, - &url_encode(user.id())?, - &url_encode(attributes)?, + url_encode(user.token())?, + url_encode(user.id())?, + url_encode(attributes)?, )) } } diff --git a/src/daemon/http/response.rs b/src/daemon/http/response.rs index 9db768b8..8981d324 100644 --- a/src/daemon/http/response.rs +++ b/src/daemon/http/response.rs @@ -360,7 +360,7 @@ impl HttpResponse { ) { let header_name = const { HeaderName::from_static("authorization") }; let header_value = match HeaderValue::from_maybe_shared( - Bytes::from(format!("Bearer {}", &token)) + Bytes::from(format!("Bearer {}", token)) ) { Ok(value) => value, Err(_) => { diff --git a/src/daemon/http/server.rs b/src/daemon/http/server.rs index c6b89b06..d563cc04 100644 --- a/src/daemon/http/server.rs +++ b/src/daemon/http/server.rs @@ -41,7 +41,7 @@ impl HttpServer { krill: KrillManager, runtime: &runtime::Handle, ) -> KrillResult> { - let authorizer = Authorizer::new(krill.config())?; + let authorizer = Authorizer::new(krill.storage(), krill.config())?; authorizer.spawn_sweep(runtime); Ok(Self { krill, @@ -136,9 +136,7 @@ impl RequestLogger { trace!( "Request: method={} path={} headers={:?}", - &req_method, - &req_path, - &req.headers() + req_method, req_path, req.headers() ); RequestLogger { diff --git a/src/daemon/http/tls_keys.rs b/src/daemon/http/tls_keys.rs index 1e59525b..d7d43bfd 100644 --- a/src/daemon/http/tls_keys.rs +++ b/src/daemon/http/tls_keys.rs @@ -128,7 +128,7 @@ impl HttpsSigner { fn save_private_key(&self, tls_keys_dir: &Path) -> Result<(), Error> { let key_file_path = key_file_path(tls_keys_dir); let bytes = Bytes::from(self.private.private_key_to_pem_pkcs8()?); - file::save(&bytes, &key_file_path)?; + file::save_private(&bytes, &key_file_path)?; Ok(()) } diff --git a/src/daemon/start.rs b/src/daemon/start.rs index c219cac4..e5ea7280 100644 --- a/src/daemon/start.rs +++ b/src/daemon/start.rs @@ -22,6 +22,7 @@ use tokio::task::JoinSet; use tokio_rustls::TlsAcceptor; use crate::commons::file; use crate::commons::error::{Error, Error as KrillError}; +use crate::commons::storage::StorageSystem; use crate::commons::version::KrillVersion; use crate::config::Config; use crate::constants::{KRILL_ENV_UPGRADE_ONLY, KRILL_SERVER_APP}; @@ -61,16 +62,17 @@ pub fn start_krill_daemon( write_pid_file_or_die(&config); test_data_dirs_or_die(&config); + let storage = StorageSystem::new(config.storage_uri.clone()); + // Set up the runtime properties manager, so that we can check // the version used for the current data in storage let properties_manager = PropertiesManager::create( - &config.storage_uri, - config.use_history_cache, + &storage, config.use_history_cache, )?; // Call upgrade, this will only do actual work if needed. let upgrade_report = prepare_upgrade_data_migrations( - UpgradeMode::PrepareToFinalise, &config, &properties_manager + UpgradeMode::PrepareToFinalise, &storage, &config, &properties_manager ).map_err(|e| { match e { UpgradeError::CodeOlderThanData(_,_) => { @@ -88,7 +90,7 @@ pub fn start_krill_daemon( if let Some(report) = &upgrade_report { finalise_data_migration( - report.versions(), &config, &properties_manager + report.versions(), &storage, &properties_manager ).map_err(|e| { Error::Custom(format!( "Finishing prepared migration failed unexpectedly. Please \ @@ -116,7 +118,9 @@ pub fn start_krill_daemon( ) })?; - let mut krill = StartupManager::new(config, tokio.handle().clone())?; + let mut krill = StartupManager::new( + config, storage, tokio.handle().clone() + )?; // Setup testbed if necessary. krill.prepare_testbed()?; @@ -234,14 +238,6 @@ fn single_http_listener( "Failed to configure TCP socket '{addr}': {err}" ))); } - let listener = match TokioTcpListener::from_std(listener) { - Ok(listener) => listener, - Err(err) => { - return Err(Error::Custom(format!( - "Failed to prepare TCP socket '{addr}': {err}" - ))); - } - }; let tls = if server.config().https_mode().is_disable_https() { None @@ -271,6 +267,15 @@ fn single_http_listener( join.spawn_on( async move { + let listener = match TokioTcpListener::from_std(listener) { + Ok(listener) => listener, + Err(err) => { + error!( + "Failed to prepare TCP socket '{addr}': {err}" + ); + return; + } + }; loop { // Break here already if `signal_exit` is true. if *signal_exit.borrow_and_update() { @@ -388,15 +393,6 @@ fn single_unix_listener( path.display(), err, ))); } - let listener = match TokioUnixListener::from_std(listener) { - Ok(listener) => listener, - Err(err) => { - return Err(Error::Custom(format!( - "Failed to prepare Unix socket '{}': {}", - path.display(), err, - ))); - } - }; let conn_builder = conn::auto::Builder::new(TokioExecutor::new()); let graceful = GracefulShutdown::new(); @@ -410,6 +406,16 @@ fn single_unix_listener( join.spawn_on( async move { + let listener = match TokioUnixListener::from_std(listener) { + Ok(listener) => listener, + Err(err) => { + error!( + "Failed to prepare Unix socket '{}': {}", + path.display(), err, + ); + return; + } + }; loop { // Break here already if `signal_exit` is true. if *signal_exit.borrow_and_update() { diff --git a/src/server/ca/certauth.rs b/src/server/ca/certauth.rs index 587d8224..90c92e03 100644 --- a/src/server/ca/certauth.rs +++ b/src/server/ca/certauth.rs @@ -1306,7 +1306,7 @@ impl CertAuth { "Updating resource class name mapping for\ child '{}, but parent does not have any resource class \ called '{}', or at least not yet.", - child_handle, &mapping.name_in_parent + child_handle, mapping.name_in_parent ); } @@ -1907,7 +1907,7 @@ impl CertAuth { info!( "Updating Entitlements for CA: {}, Removing RC: {}", - &self.handle, &rcn + self.handle, rcn ); res.push(CertAuthEvent::ResourceClassRemoved { @@ -2079,7 +2079,7 @@ impl CertAuth { )? { info!( "Started key roll for ca: {}, rc: {}, under parent: {}", - &self.handle, + self.handle, rcn, rc.parent_handle() ); @@ -2104,7 +2104,7 @@ impl CertAuth { )? { info!( "Activated key for ca: {}, rc: {}, under parent: {}", - &self.handle, + self.handle, rcn, rc.parent_handle() ); @@ -2128,7 +2128,7 @@ impl CertAuth { info!( "Finished key roll for ca: {}, rc: {}, under parent: {}", - &self.handle, + self.handle, rcn, my_rc.parent_handle() ); diff --git a/src/server/ca/manager.rs b/src/server/ca/manager.rs index 53078821..50db837e 100644 --- a/src/server/ca/manager.rs +++ b/src/server/ca/manager.rs @@ -53,6 +53,7 @@ use crate::commons::actor::Actor; use crate::commons::cmslogger::CmsLogger; use crate::commons::error::{Error, Error as KrillError}; use crate::commons::eventsourcing::{Aggregate, AggregateStore, SentCommand}; +use crate::commons::storage::StorageSystem; use crate::constants::{ CASERVER_NS, STATUS_NS, TA_PROXY_SERVER_NS, TA_SIGNER_SERVER_NS, TA_NAME, ta_handle, @@ -116,13 +117,12 @@ impl CaManager { /// Return an error if any of the various stores cannot be initialized. pub fn new( config: &Config, + storage: &StorageSystem, ) -> KrillResult { // Create the AggregateStore for the event-sourced `CertAuth` // structures that handle most CA functions. let ca_store = AggregateStore::::create( - &config.storage_uri, - CASERVER_NS, - config.use_history_cache, + storage, CASERVER_NS, config.use_history_cache, )?; if let Err(e) = ca_store.warm() { @@ -151,16 +151,13 @@ impl CaManager { // and issued certificates from the `CertAuth` and is responsible // for manifests and CRL generation. let ca_objects_store = Arc::new(CaObjectsStore::create( - &config.storage_uri, - config.issuance_timing, + storage, config.issuance_timing, )?); // Create TA proxy store if we need it. let ta_proxy_store = if config.ta_proxy_enabled() { Some(AggregateStore::::create( - &config.storage_uri, - TA_PROXY_SERVER_NS, - config.use_history_cache, + storage, TA_PROXY_SERVER_NS, config.use_history_cache, )?) } else { @@ -169,9 +166,7 @@ impl CaManager { let ta_signer_store = if config.ta_signer_enabled() { Some(AggregateStore::create( - &config.storage_uri, - TA_SIGNER_SERVER_NS, - config.use_history_cache, + storage, TA_SIGNER_SERVER_NS, config.use_history_cache, )?) } else { @@ -181,9 +176,7 @@ impl CaManager { // Create the status store which will maintain the last known // connection status between each CA and their parent(s) and // repository. - let status_store = CaStatusStore::create( - &config.storage_uri, STATUS_NS - )?; + let status_store = CaStatusStore::create(storage, STATUS_NS)?; Ok(CaManager { ca_store, @@ -782,7 +775,7 @@ impl CaManager { actor: &Actor, krill: &KrillRuntime, ) -> KrillResult { - info!("CA '{}' process add child request: {}", &ca, &req); + info!("CA '{}' process add child request: {}", ca, req); if ca.as_str() != TA_NAME { self.process_ca_command(ca.clone(), actor, CertAuthCommandDetails::ChildAdd( diff --git a/src/server/ca/publishing.rs b/src/server/ca/publishing.rs index d7425512..e87a3e07 100644 --- a/src/server/ca/publishing.rs +++ b/src/server/ca/publishing.rs @@ -14,7 +14,6 @@ use rpki::repository::manifest::{FileAndHash, Manifest, ManifestContent}; use rpki::repository::sigobj::SignedObjectBuilder; use rpki::repository::x509::{Name, Serial, Time, Validity}; use serde::{Deserialize, Serialize}; -use url::Url; use crate::api::admin::{PublishedFile, RepositoryContact}; use crate::api::ca::{ CertInfo, IssuedCertificate, ObjectName, ReceivedCert, Revocation, @@ -24,7 +23,7 @@ use crate::api::roa::RoaInfo; use crate::commons::KrillResult; use crate::commons::crypto::KrillSigner; use crate::commons::error::Error; -use crate::commons::storage::{Ident, KeyValueStore}; +use crate::commons::storage::{Ident, KeyValueStore, StorageSystem}; use crate::constants::CA_OBJECTS_NS; use crate::config::IssuanceTimingConfig; use crate::server::runtime::KrillRuntime; @@ -70,10 +69,10 @@ pub struct CaObjectsStore { impl CaObjectsStore { /// Creates a new CA objects store using the given configuration. pub fn create( - storage_uri: &Url, + storage: &StorageSystem, issuance_timing: IssuanceTimingConfig, ) -> KrillResult { - let store = KeyValueStore::create(storage_uri, CA_OBJECTS_NS)?; + let store = storage.open(CA_OBJECTS_NS)?; Ok(CaObjectsStore { store, issuance_timing, @@ -573,7 +572,7 @@ impl CaObjects { let hours = timing.publish_hours_before_next(); let mut required = false; - for (_, resource_class_objects) in self.classes.iter_mut() { + for resource_class_objects in self.classes.values_mut() { if force || resource_class_objects.requires_re_issuance(hours) { required = true; resource_class_objects.reissue(timing, signer)?; diff --git a/src/server/ca/status.rs b/src/server/ca/status.rs index 435662b6..d572ca73 100644 --- a/src/server/ca/status.rs +++ b/src/server/ca/status.rs @@ -9,7 +9,6 @@ use rpki::ca::idexchange::{CaHandle, ChildHandle, ParentHandle, ServiceUri}; use rpki::ca::provisioning::ResourceClassListResponse as Entitlements; use rpki::ca::publication::PublishDelta; use serde::{Deserialize, Serialize}; -use url::Url; use crate::api::ca::{ ChildConnectionStats, ChildStatus, ChildrenConnectionStats, ParentStatus, ParentStatuses, RepoStatus, @@ -18,7 +17,7 @@ use crate::api::status::ErrorResponse; use crate::commons::httpclient; use crate::commons::KrillResult; use crate::commons::error::Error; -use crate::commons::storage::{Ident, KeyValueStore}; +use crate::commons::storage::{Ident, KeyValueStore, StorageSystem}; const PARENTS_PREFIX: &Ident = Ident::make("parents-"); const CHILDREN_PREFIX: &Ident = Ident::make("children-"); @@ -64,10 +63,10 @@ pub struct CaStatusStore { impl CaStatusStore { /// Creates a new status store with the givn storage URI and namespace. pub fn create( - storage_uri: &Url, + storage: &StorageSystem, namespace: &Ident, ) -> KrillResult { - let store = KeyValueStore::create(storage_uri, namespace)?; + let store = storage.open(namespace)?; let cache = RwLock::new(HashMap::new()); let store = Self { store, cache }; diff --git a/src/server/ca/upgrades/data_migration.rs b/src/server/ca/upgrades/data_migration.rs index 1630ae0f..7cd66a61 100644 --- a/src/server/ca/upgrades/data_migration.rs +++ b/src/server/ca/upgrades/data_migration.rs @@ -1,4 +1,5 @@ use log::{debug, warn}; +use crate::commons::storage::StorageSystem; use crate::constants::CASERVER_NS; use crate::server::ca::certauth::CertAuth; use crate::server::ca::publishing::CaObjectsStore; @@ -7,12 +8,13 @@ use crate::upgrades::UpgradeResult; use crate::upgrades::data_migration::check_agg_store; -pub fn check_ca_objects(config: &Config) -> UpgradeResult<()> { - let ca_store = check_agg_store::(config, CASERVER_NS, "CAs")?; +pub fn check_ca_objects( + storage: &StorageSystem, config: &Config +) -> UpgradeResult<()> { + let ca_store = check_agg_store::(storage, CASERVER_NS, "CAs")?; let ca_objects_store = CaObjectsStore::create( - &config.storage_uri, - config.issuance_timing, + storage, config.issuance_timing, )?; let cas_with_objects = ca_objects_store.cas()?; diff --git a/src/server/ca/upgrades/pre_0_10_0/migration.rs b/src/server/ca/upgrades/pre_0_10_0/migration.rs index ee520a33..acef2b19 100644 --- a/src/server/ca/upgrades/pre_0_10_0/migration.rs +++ b/src/server/ca/upgrades/pre_0_10_0/migration.rs @@ -7,13 +7,12 @@ use crate::api::aspa::ProviderAsn; use crate::commons::eventsourcing::{ AggregateStore, StoredCommand, StoredCommandBuilder }; -use crate::commons::storage::{Ident, KeyValueStore}; +use crate::commons::storage::{Ident, KeyValueStore, StorageSystem}; use crate::constants::{CASERVER_NS, CA_OBJECTS_NS}; use crate::server::ca::certauth::CertAuth; use crate::server::ca::commands::CertAuthStorableCommand; use crate::server::ca::events::{CertAuthEvent, CertAuthInitEvent}; use crate::server::ca::publishing::CaObjects; -use crate::config::Config; use crate::upgrades::{ AspaMigrationConfigUpdates, AspaMigrationConfigs, CommandMigrationEffect, UpgradeAggregateStorePre0_14, UpgradeError, UpgradeMode, UpgradeResult, @@ -50,22 +49,15 @@ impl CasMigration { /// Upgrades the CAs based on the upgrade mode and config. pub fn upgrade( mode: UpgradeMode, - config: &Config, + storage: &StorageSystem, ) -> UpgradeResult { Self { - current_kv_store: KeyValueStore::create( - &config.storage_uri, CASERVER_NS - )?, - new_kv_store: KeyValueStore::create_upgrade_store( - &config.storage_uri, - CASERVER_NS, - )?, + current_kv_store: storage.open(CASERVER_NS)?, + new_kv_store: storage.open_upgrade(CASERVER_NS)?, new_agg_store: AggregateStore::::create_upgrade_store( - &config.storage_uri, - CASERVER_NS, - config.use_history_cache, + storage, CASERVER_NS, false, )?, - ca_objects_migration: CaObjectsMigration::create(config)?, + ca_objects_migration: CaObjectsMigration::create(storage)?, } .upgrade(mode) } @@ -253,15 +245,10 @@ struct CaObjectsMigration { impl CaObjectsMigration { /// Creates a new migration from the configuration. - fn create(config: &Config) -> Result { + fn create(storage: &StorageSystem) -> Result { Ok(CaObjectsMigration { - current_store: KeyValueStore::create( - &config.storage_uri, CA_OBJECTS_NS - )?, - new_store: KeyValueStore::create_upgrade_store( - &config.storage_uri, - CA_OBJECTS_NS, - )? + current_store: storage.open(CA_OBJECTS_NS)?, + new_store: storage.open_upgrade(CA_OBJECTS_NS)? }) } diff --git a/src/server/ca/upgrades/pre_0_14_0/migration.rs b/src/server/ca/upgrades/pre_0_14_0/migration.rs index 37927dc8..8632cc16 100644 --- a/src/server/ca/upgrades/pre_0_14_0/migration.rs +++ b/src/server/ca/upgrades/pre_0_14_0/migration.rs @@ -10,10 +10,9 @@ use crate::upgrades::{ use crate::{ commons::{ eventsourcing::AggregateStore, - storage::KeyValueStore, + storage::{KeyValueStore, StorageSystem}, }, constants::CASERVER_NS, - config::Config, upgrades::UpgradeResult, }; @@ -36,19 +35,13 @@ pub struct CasMigration { impl CasMigration { pub fn upgrade( mode: UpgradeMode, - config: &Config, + storage: &StorageSystem, ) -> UpgradeResult { - let current_kv_store = - KeyValueStore::create(&config.storage_uri, CASERVER_NS)?; - let new_kv_store = KeyValueStore::create_upgrade_store( - &config.storage_uri, - CASERVER_NS, - )?; + let current_kv_store = storage.open(CASERVER_NS)?; + let new_kv_store = storage.open_upgrade(CASERVER_NS)?; let new_agg_store = AggregateStore::::create_upgrade_store( - &config.storage_uri, - CASERVER_NS, - config.use_history_cache, + storage, CASERVER_NS, false )?; CasMigration { diff --git a/src/server/manager.rs b/src/server/manager.rs index 9a6b55b0..d271fadf 100644 --- a/src/server/manager.rs +++ b/src/server/manager.rs @@ -18,6 +18,7 @@ use crate::api::status::ErrorResponse; use crate::commons::actor::Actor; use crate::commons::error::KrillError; use crate::commons::eventsourcing::AggregateStoreError; +use crate::commons::storage::StorageSystem; use crate::config::Config; use crate::constants::{TA_NAME, ta_handle, testbed_ca_handle}; use crate::server::ca::CaStatus; @@ -45,11 +46,11 @@ impl StartupManager { /// While the Tokio runtime provided isn’t used, we need the handle /// already to pass it to the Krill runtime. pub fn new( - config: Config, tokio: TokioHandle + config: Config, storage: StorageSystem, tokio: TokioHandle ) -> Result { Ok(Self { thread_pool: ThreadPool::new(&config)?, - runtime: KrillRuntime::new(config, tokio)?, + runtime: KrillRuntime::new(config, storage, tokio)?, }) } @@ -225,6 +226,11 @@ impl KrillManager { self.krill_runtime.config() } + /// Returns a reference to the storage system. + pub fn storage(&self) -> &StorageSystem { + self.krill_runtime.storage() + } + /// Returns the system actor. pub fn system_actor(&self) -> &Actor { self.krill_runtime.system_actor() diff --git a/src/server/mq.rs b/src/server/mq.rs index 8608bb8b..1c564731 100644 --- a/src/server/mq.rs +++ b/src/server/mq.rs @@ -10,12 +10,11 @@ use rpki::ca::idexchange::{CaHandle, ParentHandle}; use rpki::ca::provisioning::{ResourceClassName, RevocationRequest}; use rpki::repository::x509::Time; use serde::{Deserialize, Serialize}; -use url::Url; use crate::api::ca::Timestamp; use crate::commons::{Error, KrillResult}; use crate::commons::eventsourcing::Aggregate; use crate::commons::queue::{Queue, ScheduleMode}; -use crate::commons::storage::Ident; +use crate::commons::storage::{Ident, StorageSystem}; use crate::constants::{TASK_QUEUE_NS, ta_handle}; use crate::server::ca::{CertAuth, CertAuthEvent}; use crate::server::taproxy::{TrustAnchorProxy, TrustAnchorProxyEvent}; @@ -285,9 +284,9 @@ pub struct TaskQueue { } impl TaskQueue { - pub fn new(storage_uri: &Url) -> KrillResult { + pub fn new(storage: &StorageSystem) -> KrillResult { Ok(TaskQueue { - q: Queue::create(storage_uri, TASK_QUEUE_NS)?, + q: Queue::create(storage, TASK_QUEUE_NS)?, }) } } diff --git a/src/server/properties/mod.rs b/src/server/properties/mod.rs index 27d4c3b0..a2d42df4 100644 --- a/src/server/properties/mod.rs +++ b/src/server/properties/mod.rs @@ -20,7 +20,6 @@ use std::{fmt, str::FromStr, sync::Arc}; use log::{log_enabled, trace}; use rpki::ca::idexchange::MyHandle; use serde::{Deserialize, Serialize}; -use url::Url; use crate::{ commons::{ @@ -30,6 +29,7 @@ use crate::{ self, Aggregate, AggregateStore, Event, InitCommandDetails, InitEvent, SentCommand, SentInitCommand, WithStorableDetails, }, + storage::StorageSystem, version::KrillVersion, KrillResult, }, @@ -300,17 +300,19 @@ pub struct PropertiesManager { impl PropertiesManager { pub fn create( - storage_uri: &Url, + storage: &StorageSystem, use_history_cache: bool, ) -> KrillResult { let main_key = MyHandle::from_str(PROPERTIES_DFLT_NAME).unwrap(); - AggregateStore::create(storage_uri, PROPERTIES_NS, use_history_cache) - .map(|store| PropertiesManager { - store, - main_key, - system_actor: ACTOR_DEF_KRILL, - }) - .map_err(Error::AggregateStoreError) + let store = AggregateStore::create( + storage, PROPERTIES_NS, use_history_cache + )?; + + Ok(PropertiesManager { + store, + main_key, + system_actor: ACTOR_DEF_KRILL, + }) } pub fn is_initialized(&self) -> bool { diff --git a/src/server/pubd/access.rs b/src/server/pubd/access.rs index 197deebb..7800391a 100644 --- a/src/server/pubd/access.rs +++ b/src/server/pubd/access.rs @@ -25,10 +25,10 @@ use crate::commons::eventsourcing::{ Aggregate, AggregateStore, CommandDetails, Event, InitCommandDetails, InitEvent, SentCommand, SentInitCommand, WithStorableDetails, }; +use crate::commons::storage::StorageSystem; use crate::constants::{ ACTOR_DEF_KRILL, PUBSERVER_DFLT, PUBSERVER_NS, TA_NAME }; -use crate::config::Config; use super::publishers::Publisher; @@ -50,12 +50,13 @@ pub struct RepositoryAccessProxy { } impl RepositoryAccessProxy { - /// Creates a new repository access proxy from the config. - pub fn create(config: &Config) -> KrillResult { + /// Creates a new repository access proxy + pub fn create( + storage: &StorageSystem, + use_history_cache: bool + ) -> KrillResult { let store = AggregateStore::::create( - &config.storage_uri, - PUBSERVER_NS, - config.use_history_cache, + storage, PUBSERVER_NS, use_history_cache, )?; let key = MyHandle::from_str(PUBSERVER_DFLT).unwrap(); diff --git a/src/server/pubd/content.rs b/src/server/pubd/content.rs index e02a9e5c..9eecbed6 100644 --- a/src/server/pubd/content.rs +++ b/src/server/pubd/content.rs @@ -16,8 +16,9 @@ use crate::commons::error::Error; use crate::commons::eventsourcing::{ WalChange, WalCommand, WalSet, WalStore, WalSupport, }; +use crate::commons::storage::StorageSystem; use crate::constants::PUBSERVER_CONTENT_NS; -use crate::config::{Config, RrdpUpdatesConfig}; +use crate::config::RrdpUpdatesConfig; use super::rrdp::{ CurrentObjects, DeltaElements, RrdpServer, RrdpSession, RrdpSessionReset, RrdpUpdated, RrdpUpdateNeeded, @@ -46,9 +47,9 @@ pub struct RepositoryContentProxy { impl RepositoryContentProxy { /// Creates a new repository content proxy. - pub fn create(config: &Config) -> KrillResult { + pub fn create(storage: &StorageSystem) -> KrillResult { let store = Arc::new(WalStore::create( - &config.storage_uri, PUBSERVER_CONTENT_NS, + storage, PUBSERVER_CONTENT_NS, )?); store.warm()?; diff --git a/src/server/pubd/manager.rs b/src/server/pubd/manager.rs index 61f8cf41..cf47e2a5 100644 --- a/src/server/pubd/manager.rs +++ b/src/server/pubd/manager.rs @@ -17,6 +17,7 @@ use crate::commons::KrillResult; use crate::commons::actor::Actor; use crate::commons::cmslogger::CmsLogger; use crate::commons::error::Error; +use crate::commons::storage::StorageSystem; use crate::config::{Config, RrdpUpdatesConfig}; use crate::server::mq::{now, Task}; use crate::server::runtime::KrillRuntime; @@ -43,10 +44,15 @@ pub struct RepositoryManager { impl RepositoryManager { /// Builds the repository manager. - pub fn new(config: &Config) -> Result { + pub fn new( + config: &Config, + storage: &StorageSystem, + ) -> Result { Ok(RepositoryManager { - access: RepositoryAccessProxy::create(config)?, - content: RepositoryContentProxy::create(config)?, + access: RepositoryAccessProxy::create( + storage, config.use_history_cache + )?, + content: RepositoryContentProxy::create(storage)?, rrdp_updates_config: config.rrdp_updates_config, }) } @@ -356,6 +362,7 @@ mod tests { use crate::commons::file; use crate::commons::crypto::{KrillSignerBuilder, OpenSslSignerConfig}; use crate::commons::file::CurrentFile; + use crate::commons::storage::StorageUri; use crate::commons::test::{self, https, rsync}; use crate::constants::{ ACTOR_DEF_TEST, RRDP_FIRST_SERIAL, enable_test_mode @@ -365,36 +372,6 @@ mod tests { use crate::server::pubd::rrdp::{PublicationDeltaError, RrdpServer}; use super::*; - fn publisher_alice(storage_uri: &Url) -> Publisher { - // When the "hsm" feature is enabled we could be running the tests - // with PKCS#11 as the default signer type. In that case, if - // the backend signer is SoftHSMv2, attempting to create a second - // instance of KrillSigner in the same process will fail - // because it will attempt to login to SoftHSMv2 a second time which - // SoftHSMv2 does not support. To work around this issue we - // therefore explicitly request that the second KrillSigner instance - // that we create here uses OpenSSL as its backend signer. - let signer = { - let signer_type = - SignerType::OpenSsl(OpenSslSignerConfig::default()); - let signer_config = - SignerConfig::new("Alice".to_string(), signer_type); - let signer_configs = &[signer_config]; - KrillSignerBuilder::new( - storage_uri, - Duration::from_secs(1), - signer_configs, - ) - .build() - .unwrap() - }; - - let id_cert = signer.create_self_signed_id_cert().unwrap(); - let base_uri = - uri::Rsync::from_str("rsync://localhost/repo/alice/").unwrap(); - - Publisher::new(id_cert.into(), base_uri) - } fn make_publisher_req( handle: &str, @@ -410,20 +387,19 @@ mod tests { struct TestServer { krill: KrillRuntime, - storage_uri: Url, data_dir: tempfile::TempDir, tokio: tokio::runtime::Runtime, } impl TestServer { fn new() -> Self { - let storage_uri = test::mem_storage(); + let storage = test::mem_storage(); let data_dir = tempfile::tempdir().unwrap(); let tokio = tokio::runtime::Runtime::new().unwrap(); enable_test_mode(); let mut config = Config::test( - &storage_uri, + storage.default_uri(), Some(data_dir.path()), true, false, @@ -434,7 +410,7 @@ mod tests { config.process().unwrap(); let krill = KrillRuntime::new( - config, tokio.handle().clone() + config, storage, tokio.handle().clone() ).unwrap(); let uris = PublicationServerUris { rrdp_base_uri: https("https://localhost/repo/rrdp/"), @@ -443,19 +419,50 @@ mod tests { krill.repo_manager().init(uris, &krill).unwrap(); - Self { krill, storage_uri, data_dir, tokio } + Self { krill, data_dir, tokio } } fn repo(&self) -> &RepositoryManager { self.krill.repo_manager() } + + fn publisher_alice(&self) -> Publisher { + // When the "hsm" feature is enabled we could be running the tests + // with PKCS#11 as the default signer type. In that case, if + // the backend signer is SoftHSMv2, attempting to create a second + // instance of KrillSigner in the same process will fail + // because it will attempt to login to SoftHSMv2 a second time which + // SoftHSMv2 does not support. To work around this issue we + // therefore explicitly request that the second KrillSigner instance + // that we create here uses OpenSSL as its backend signer. + let signer = { + let signer_type = + SignerType::OpenSsl(OpenSslSignerConfig::default()); + let signer_config = + SignerConfig::new("Alice".to_string(), signer_type); + let signer_configs = &[signer_config]; + KrillSignerBuilder::new( + self.krill.storage(), + Duration::from_secs(1), + signer_configs, + ) + .build() + .unwrap() + }; + + let id_cert = signer.create_self_signed_id_cert().unwrap(); + let base_uri = + uri::Rsync::from_str("rsync://localhost/repo/alice/").unwrap(); + + Publisher::new(id_cert.into(), base_uri) + } } #[test] fn should_add_publisher() { let server = TestServer::new(); - let alice = publisher_alice(&server.storage_uri); + let alice = server.publisher_alice(); let alice_handle = Handle::from_str("alice").unwrap(); let publisher_req = @@ -477,7 +484,7 @@ mod tests { fn should_not_add_publisher_twice() { let server = TestServer::new(); - let alice = publisher_alice(&server.storage_uri); + let alice = server.publisher_alice(); let alice_handle = Handle::from_str("alice").unwrap(); let publisher_req = @@ -500,7 +507,7 @@ mod tests { fn should_list_files() { let server = TestServer::new(); - let alice = publisher_alice(&server.storage_uri); + let alice = server.publisher_alice(); let alice_handle = Handle::from_str("alice").unwrap(); let publisher_req = @@ -525,7 +532,7 @@ mod tests { assert!(session_dir_contains_serial(&session, RRDP_FIRST_SERIAL)); // set up server with default repository, and publisher alice - let alice = publisher_alice(&server.storage_uri); + let alice = server.publisher_alice(); let alice_handle = Handle::from_str("alice").unwrap(); let publisher_req = @@ -762,7 +769,7 @@ mod tests { let server = TestServer::new(); // set up server with default repository, and publisher alice - let alice = publisher_alice(&server.storage_uri); + let alice = server.publisher_alice(); let alice_handle = Handle::from_str("alice").unwrap(); let publisher_req = diff --git a/src/server/pubd/upgrades/mod.rs b/src/server/pubd/upgrades/mod.rs index 9bf7a815..bad34bc8 100644 --- a/src/server/pubd/upgrades/mod.rs +++ b/src/server/pubd/upgrades/mod.rs @@ -9,18 +9,19 @@ use log::info; use rpki::ca::idexchange::MyHandle; use crate::commons::KrillResult; use crate::commons::eventsourcing::WalStore; -use crate::commons::storage::{Ident, KeyValueStore}; +use crate::commons::storage::{Ident, StorageSystem}; use crate::constants::PUBSERVER_CONTENT_NS; -use crate::config::Config; use crate::server::pubd::content::RepositoryContent; use self::pre_0_13_0::OldRepositoryContent; /// Migrate v0.12.x RepositoryContent to the new 0.13.0+ format. /// Apply any open WAL changes to the source first. -pub fn migrate_0_12_pubd_objects(config: &Config) -> KrillResult { +pub fn migrate_0_12_pubd_objects( + storage: &StorageSystem +) -> KrillResult { let old_store: WalStore = WalStore::create( - &config.storage_uri, PUBSERVER_CONTENT_NS + storage, PUBSERVER_CONTENT_NS )?; let repo_content_handle = MyHandle::new("0".into()); @@ -29,10 +30,7 @@ pub fn migrate_0_12_pubd_objects(config: &Config) -> KrillResult { old_store.get_latest(&repo_content_handle)?.as_ref().clone(); let repo_content: RepositoryContent = old_repo_content.try_into()?; - let upgrade_store = KeyValueStore::create_upgrade_store( - &config.storage_uri, - PUBSERVER_CONTENT_NS, - )?; + let upgrade_store = storage.open_upgrade( PUBSERVER_CONTENT_NS)?; upgrade_store.store( Some(const { Ident::make("0") }), const { Ident::make("snapshot.json") }, @@ -46,10 +44,10 @@ pub fn migrate_0_12_pubd_objects(config: &Config) -> KrillResult { /// The format of the RepositoryContent did not change in 0.12, but /// the location and way of storing it did. So, migrate if present. -pub fn migrate_pre_0_12_pubd_objects(config: &Config) -> KrillResult<()> { - let old_store = KeyValueStore::create( - &config.storage_uri, PUBSERVER_CONTENT_NS - )?; +pub fn migrate_pre_0_12_pubd_objects( + storage: &StorageSystem +) -> KrillResult<()> { + let old_store = storage.open(PUBSERVER_CONTENT_NS)?; if let Ok(Some(old_repo_content)) = old_store.get::( None, const { Ident::make("0.json") } @@ -58,9 +56,7 @@ pub fn migrate_pre_0_12_pubd_objects(config: &Config) -> KrillResult<()> { info!("Found pre 0.12.0 RC2 publication server data. Migrating.."); let repo_content: RepositoryContent = old_repo_content.try_into()?; - let upgrade_store = KeyValueStore::create_upgrade_store( - &config.storage_uri, PUBSERVER_CONTENT_NS, - )?; + let upgrade_store = storage.open_upgrade(PUBSERVER_CONTENT_NS)?; upgrade_store.store( Some(const { Ident::make("0") }), const { Ident::make("snapshot.json") }, diff --git a/src/server/pubd/upgrades/pre_0_10_0/migration.rs b/src/server/pubd/upgrades/pre_0_10_0/migration.rs index cec62fa1..88e8b6a4 100644 --- a/src/server/pubd/upgrades/pre_0_10_0/migration.rs +++ b/src/server/pubd/upgrades/pre_0_10_0/migration.rs @@ -1,10 +1,9 @@ use rpki::ca::idexchange::MyHandle; use rpki::repository::x509::Time; use crate::commons::eventsourcing::{AggregateStore, StoredCommandBuilder}; -use crate::commons::storage::{Ident, KeyValueStore}; +use crate::commons::storage::{Ident, KeyValueStore, StorageSystem}; use crate::commons::version::KrillVersion; use crate::constants::PUBSERVER_NS; -use crate::config::Config; use crate::server::pubd::access::{ RepositoryAccess, RepositoryAccessEvent, RepositoryAccessInitEvent, StorableRepositoryCommand, @@ -32,19 +31,15 @@ pub struct PublicationServerRepositoryAccessMigration { impl PublicationServerRepositoryAccessMigration { pub fn upgrade( mode: UpgradeMode, - config: &Config, + storage: &StorageSystem, versions: &UpgradeVersions, ) -> UpgradeResult<()> { - let current_kv_store = - KeyValueStore::create(&config.storage_uri, PUBSERVER_NS)?; - let new_kv_store = KeyValueStore::create_upgrade_store( - &config.storage_uri, - PUBSERVER_NS, - )?; + let current_kv_store = storage.open(PUBSERVER_NS)?; + let new_kv_store = storage.open_upgrade(PUBSERVER_NS)?; let new_agg_store = AggregateStore::create_upgrade_store( - &config.storage_uri, + storage, PUBSERVER_NS, - config.use_history_cache, + false, )?; let store_migration = PublicationServerRepositoryAccessMigration { diff --git a/src/server/runtime.rs b/src/server/runtime.rs index 1f01305f..68b4c004 100644 --- a/src/server/runtime.rs +++ b/src/server/runtime.rs @@ -19,6 +19,7 @@ use tokio::sync::{mpsc as tokio_mpsc, oneshot}; use crate::commons::actor::Actor; use crate::commons::crypto::{KrillSigner, KrillSignerBuilder}; use crate::commons::error::KrillError; +use crate::commons::storage::StorageSystem; use crate::config::Config; use crate::constants::{ACTOR_DEF_KRILL, KRILL_SERVER_APP}; use super::bgp::BgpAnalyser; @@ -49,6 +50,7 @@ impl KrillRuntime { /// async tasks onto. pub fn new( config: Config, + storage: StorageSystem, tokio: runtime::Handle, ) -> Result { let service_uri = config.service_uri(); @@ -60,7 +62,7 @@ impl KrillRuntime { // used to update signer name references to resolve to the // corresponding signer configurations. let signer = KrillSignerBuilder::new( - &config.storage_uri, + &storage, Duration::from_secs(config.signer_probe_retry_seconds), &config.signers, ).with_default_signer( @@ -69,14 +71,15 @@ impl KrillRuntime { config.one_off_signer() ).build()?; - let tasks = TaskQueue::new(&config.storage_uri)?; - let repo_manager = RepositoryManager::new(&config)?; - let ca_manager = CaManager::new(&config)?; + let tasks = TaskQueue::new(&storage)?; + let repo_manager = RepositoryManager::new(&config, &storage)?; + let ca_manager = CaManager::new(&config, &storage)?; let bgp_analyser = BgpAnalyser::new(&config); Ok(Self(Arc::new(Components { config, service_uri, + storage, repo_manager, ca_manager, tasks, @@ -97,6 +100,11 @@ impl KrillRuntime { &self.0.service_uri } + /// Returns a reference to the storage system. + pub fn storage(&self) -> &StorageSystem { + &self.0.storage + } + /// Returns the repository manager. pub fn repo_manager(&self) -> &RepositoryManager { &self.0.repo_manager @@ -165,6 +173,11 @@ impl SlowKrillRuntime { self.runtime().service_uri() } + /// Returns a reference to the storage system. + pub fn storage(&self) -> &StorageSystem { + self.runtime().storage() + } + /// Returns the repository manager. pub fn repo_manager(&self) -> &RepositoryManager { self.runtime().repo_manager() @@ -235,6 +248,9 @@ struct Components { /// value which may be missing. service_uri: uri::Https, + /// The storage system used by all components. + storage: StorageSystem, + /// Publication server with configured publishers repo_manager: RepositoryManager, diff --git a/src/server/scheduler.rs b/src/server/scheduler.rs index b03b1de2..82d76d9d 100644 --- a/src/server/scheduler.rs +++ b/src/server/scheduler.rs @@ -7,7 +7,6 @@ use std::time::Duration; use log::{debug, error, info, warn}; use rpki::ca::idexchange::{CaHandle, ParentHandle}; use rpki::ca::provisioning::{ResourceClassName, RevocationRequest}; -use url::Url; use crate::{ api::ca::Timestamp, @@ -15,7 +14,7 @@ use crate::{ crypto::dispatch::signerinfo::SignerInfo, error::{Error, FatalError}, eventsourcing::{Aggregate, AggregateStore, WalStore, WalSupport}, - storage::Ident, + storage::{Ident, StorageSystem}, version::KrillVersion, }, constants::{ @@ -524,10 +523,10 @@ fn renew_objects_if_needed( // Call update_snapshots on all AggregateStores and WalStores fn update_snapshots(krill: &KrillRuntime) -> Result { fn update_aggregate_store_snapshots( - storage_uri: &Url, + storage: &StorageSystem, namespace: &Ident, ) { - match AggregateStore::::create(storage_uri, namespace, false) { + match AggregateStore::::create(storage, namespace, false) { Err(e) => { // Note: this is highly unlikely.. probably something else // is broken and Krill would @@ -555,10 +554,10 @@ fn update_snapshots(krill: &KrillRuntime) -> Result { } fn update_wal_store_snapshots( - storage_uri: &Url, + storage: &StorageSystem, namespace: &Ident, ) { - match WalStore::::create(storage_uri, namespace) { + match WalStore::::create(storage, namespace) { Err(e) => { // Note: this is highly unlikely.. probably something else // is broken and Krill would @@ -583,19 +582,19 @@ fn update_snapshots(krill: &KrillRuntime) -> Result { } update_aggregate_store_snapshots::( - &krill.config().storage_uri, CASERVER_NS, + krill.storage(), CASERVER_NS, ); update_aggregate_store_snapshots::( - &krill.config().storage_uri, SIGNERS_NS, + krill.storage(), SIGNERS_NS, ); update_aggregate_store_snapshots::( - &krill.config().storage_uri, PROPERTIES_NS, + krill.storage(), PROPERTIES_NS, ); update_aggregate_store_snapshots::( - &krill.config().storage_uri, PUBSERVER_NS, + krill.storage(), PUBSERVER_NS, ); update_wal_store_snapshots::( - &krill.config().storage_uri, PUBSERVER_CONTENT_NS, + krill.storage(), PUBSERVER_CONTENT_NS, ); Ok(TaskResult::FollowUp(Task::UpdateSnapshots, in_hours(24))) diff --git a/src/tasigner/config.rs b/src/tasigner/config.rs index 44089c8d..4dcad833 100644 --- a/src/tasigner/config.rs +++ b/src/tasigner/config.rs @@ -6,10 +6,10 @@ use std::{ use log::LevelFilter; use serde::Deserialize; -use url::Url; use crate::{ commons::crypto::{KrillSigner, KrillSignerBuilder, OpenSslSignerConfig}, + commons::storage::{StorageSystem, StorageUri}, constants::OPENSSL_ONE_OFF_SIGNER_NAME, config::{LogType, SignerConfig, SignerReference, SignerType}, }; @@ -93,9 +93,8 @@ impl TaTimingConfig { pub struct Config { #[serde( alias = "data_dir", - deserialize_with = "crate::config::deserialize_storage_uri" )] - pub storage_uri: Url, + pub storage_uri: StorageUri, #[serde(default)] pub use_history_cache: bool, @@ -228,7 +227,9 @@ impl Config { } // Signer support - pub fn signer(&self) -> Result { + pub fn signer( + &self, storage: &StorageSystem + ) -> Result { // Assumes that Config::verify() has already ensured that the signer // configuration is valid and that Config::resolve() has been // used to update signer name references to resolve to the @@ -236,7 +237,7 @@ impl Config { let probe_interval = std::time::Duration::from_secs(self.signer_probe_retry_seconds); let signer = KrillSignerBuilder::new( - &self.storage_uri, + storage, probe_interval, &self.signers, ) @@ -381,7 +382,8 @@ mod tests { let config_string = include_str!("../../test-resources/ta/ta.conf"); let config = Config::parse_str(config_string).unwrap(); - config.signer().unwrap(); + let storage = StorageSystem::new(config.storage_uri.clone()); + config.signer(&storage).unwrap(); }) } } diff --git a/src/upgrades/data_migration.rs b/src/upgrades/data_migration.rs index cd61dec2..b9f6f894 100644 --- a/src/upgrades/data_migration.rs +++ b/src/upgrades/data_migration.rs @@ -4,18 +4,17 @@ use std::{str::FromStr}; use log::info; use rpki::crypto::KeyIdentifier; -use url::Url; use crate::{ commons::{ crypto::{ dispatch::signerinfo::SignerInfo, - OpenSslSigner, + OpenSslSigner, OpenSslSignerConfig, }, eventsourcing::{ Aggregate, AggregateStore, WalStore, WalSupport, }, - storage::{Ident, KeyValueStore}, + storage::{Ident, StorageSystem, StorageUri}, }, constants::{ KEYS_NS, PROPERTIES_NS, PUBSERVER_CONTENT_NS, @@ -37,7 +36,9 @@ use crate::{ use super::UpgradeResult; -pub fn migrate(mut config: Config, target_storage: Url) -> UpgradeResult<()> { +pub fn migrate( + config: Config, target_storage: &StorageSystem +) -> UpgradeResult<()> { // Copy the source data from config unmodified into the target_storage info!("-----------------------------------------------------------"); info!(" Krill Data Migration"); @@ -46,19 +47,19 @@ pub fn migrate(mut config: Config, target_storage: Url) -> UpgradeResult<()> { info!("-----------------------------------------------------------"); info!("STEP 1: Copy data"); info!(""); - info!("From: {}", &config.storage_uri); - info!(" To: {}", &target_storage); + info!("From: {}", config.storage_uri); + info!(" To: {}", target_storage.default_uri()); info!("-----------------------------------------------------------"); info!(""); - copy_data_for_migration(&config, &target_storage)?; + copy_data_for_migration(target_storage, &config.storage_uri)?; // Update the config file with the new target_storage // and perform a normal data migration - the source data // could be for an older version of Krill. - config.storage_uri = target_storage; - let properties_manager = - PropertiesManager::create(&config.storage_uri, false)?; + let properties_manager = PropertiesManager::create( + target_storage, false + )?; info!("-----------------------------------------------------------"); info!("STEP 2: Upgrade data to current Krill version (if needed)"); @@ -66,12 +67,13 @@ pub fn migrate(mut config: Config, target_storage: Url) -> UpgradeResult<()> { info!(""); if let Some(upgrade) = prepare_upgrade_data_migrations( crate::upgrades::UpgradeMode::PrepareToFinalise, + target_storage, &config, &properties_manager, )? { finalise_data_migration( upgrade.versions(), - &config, + target_storage, &properties_manager, )?; } @@ -92,53 +94,53 @@ pub fn migrate(mut config: Config, target_storage: Url) -> UpgradeResult<()> { // That said, it's a pretty easy check to perform and it kind of makes // sense to do it to now, even if it would be to point users at deeper // source data issues. - verify_target_data(&config) + verify_target_data(target_storage, &config) } -fn verify_target_data(config: &Config) -> UpgradeResult<()> { - check_agg_store::(config, PROPERTIES_NS, "Properties")?; - check_agg_store::(config, SIGNERS_NS, "Signer")?; +fn verify_target_data( + storage: &StorageSystem, config: &Config +) -> UpgradeResult<()> { + check_agg_store::(storage, PROPERTIES_NS, "Properties")?; + check_agg_store::(storage, SIGNERS_NS, "Signer")?; - check_ca_objects(config)?; + check_ca_objects(storage, config)?; check_agg_store::( - config, + storage, PUBSERVER_NS, "Publication Server Access", )?; check_wal_store::( - config, + storage, PUBSERVER_CONTENT_NS, "Publication Server Objects", )?; check_agg_store::( - config, + storage, TA_PROXY_SERVER_NS, "TA Proxy", )?; check_agg_store::( - config, + storage, TA_SIGNER_SERVER_NS, "TA Signer", )?; - check_openssl_keys(config)?; + check_openssl_keys(storage)?; Ok(()) } -fn check_openssl_keys(config: &Config) -> UpgradeResult<()> { +fn check_openssl_keys(storage: &StorageSystem) -> UpgradeResult<()> { info!(""); info!("Verify: OpenSSL keys"); let open_ssl_signer = OpenSslSigner::build( - &config.storage_uri, - "test", - None, + storage, &OpenSslSignerConfig::default(), "test", None, ) .map_err(|e| { UpgradeError::Custom(format!("Cannot create openssl signer: {e}")) })?; - let keys_key_store = KeyValueStore::create(&config.storage_uri, KEYS_NS)?; + let keys_key_store = storage.open(KEYS_NS)?; for key in keys_key_store.keys(None, "")? { let key_id = @@ -159,14 +161,14 @@ fn check_openssl_keys(config: &Config) -> UpgradeResult<()> { } pub fn check_agg_store( - config: &Config, + storage: &StorageSystem, ns: &Ident, name: &str, ) -> UpgradeResult> { info!(""); info!("Verify: {name}"); let store: AggregateStore = - AggregateStore::create(&config.storage_uri, ns, false)?; + AggregateStore::create(storage, ns, false)?; if !store.list()?.is_empty() { store.warm()?; info!("Ok"); @@ -177,13 +179,13 @@ pub fn check_agg_store( } fn check_wal_store( - config: &Config, + storage: &StorageSystem, ns: &Ident, name: &str, ) -> UpgradeResult<()> { info!(""); info!("Verify: {name}"); - let store: WalStore = WalStore::create(&config.storage_uri, ns)?; + let store: WalStore = WalStore::create(storage, ns)?; if !store.list()?.is_empty() { store.warm()?; info!("Ok"); @@ -194,8 +196,8 @@ fn check_wal_store( } fn copy_data_for_migration( - config: &Config, - target_storage: &Url, + target_storage: &StorageSystem, + source_storage: &StorageUri, ) -> UpgradeResult<()> { const NAMESPACES: &[&Ident] = &[ Ident::make("ca_objects"), @@ -209,13 +211,11 @@ fn copy_data_for_migration( Ident::make("ta_signer"), ]; for namespace in NAMESPACES { - let source_kv_store = KeyValueStore::create( - &config.storage_uri, namespace + let source_kv_store = target_storage.open_uri( + source_storage, namespace )?; if !source_kv_store.is_empty()? { - let target_kv_store = KeyValueStore::create( - target_storage, namespace - )?; + let target_kv_store = target_storage.open(namespace)?; target_kv_store.import(&source_kv_store)?; } } @@ -225,6 +225,7 @@ fn copy_data_for_migration( #[cfg(test)] pub mod tests { + use std::env; use std::path::PathBuf; use log::LevelFilter; use crate::commons::test; @@ -232,10 +233,11 @@ pub mod tests { #[test] fn test_data_migration() { - // Create a config file that uses test data for its storage_uri - let test_sources_base = "test-resources/migrations/v0_9_5/"; - let test_sources_url = - Url::parse(&format!("local://{test_sources_base}")).unwrap(); + let test_sources_url = StorageUri::disk( + env::current_dir().unwrap().join( + "test-resources/migrations/v0_9_5/" + ) + ); let bogus_path = PathBuf::from("/dev/null"); // needed for tls_dir etc, but will be ignored here let mut config = Config::test( @@ -253,7 +255,7 @@ pub mod tests { // Create an in-memory target store to migrate to let target_store = test::mem_storage(); - migrate(config, target_store).unwrap(); + migrate(config, &target_store).unwrap(); } } diff --git a/src/upgrades/mod.rs b/src/upgrades/mod.rs index 3cca8e6a..f23eda6e 100644 --- a/src/upgrades/mod.rs +++ b/src/upgrades/mod.rs @@ -23,7 +23,10 @@ use crate::{ Storable, StoredCommand, WalStoreError, WithStorableDetails, }, - storage::{Ident, KeyValueError, KeyValueStore}, + storage::{ + Ident, KeyValueError, KeyValueStore, OpenStoreError, + StorageSystem, + }, version::KrillVersion, KrillResult, }, @@ -222,6 +225,12 @@ impl From for UpgradeError { } } +impl From for UpgradeError { + fn from(e: OpenStoreError) -> Self { + UpgradeError::custom(e) + } +} + impl From for UpgradeError { fn from(e: WalStoreError) -> Self { UpgradeError::WalStoreError(e) @@ -570,7 +579,7 @@ pub trait UpgradeAggregateStorePre0_14 { // Verify migration info!( "Will verify the migration by rebuilding '{}' from migrated commands", - &scope + scope ); let _latest = self.preparation_aggregate_store().save_snapshot(&handle).map_err(|e| { UpgradeError::Custom(format!( @@ -810,8 +819,10 @@ pub trait UpgradeAggregateStorePre0_14 { /// started, it will call this again - to do the final preparation for a /// migration - knowing that no changes are added to the event history at this /// time. After this, the migration will be finalised. +#[allow(unused_variables)] pub fn prepare_upgrade_data_migrations( mode: UpgradeMode, + storage: &StorageSystem, config: &Config, properties_manager: &PropertiesManager, ) -> UpgradeResult> { @@ -824,9 +835,9 @@ pub fn prepare_upgrade_data_migrations( // just do at startup. It is done here, because in effect it *is* a data // migration. #[cfg(feature = "hsm")] - record_preexisting_openssl_keys_in_signer_mapper(config)?; + record_preexisting_openssl_keys_in_signer_mapper(storage, config)?; - match upgrade_versions(config, properties_manager)? { + match upgrade_versions(storage, properties_manager)? { None => Ok(None), Some(versions) => { info!( @@ -841,9 +852,7 @@ pub fn prepare_upgrade_data_migrations( // easily be migrated to the new setup in 0.13.0. // Well.. it could be done, if there would be a strong use // case to put in the effort, but there really isn't. - let ca_kv_store = KeyValueStore::create( - &config.storage_uri, CASERVER_NS - )?; + let ca_kv_store = storage.open(CASERVER_NS)?; if ca_kv_store.has_scope(const { Ident::make("ta") })? { return Err(UpgradeError::OldTaMigration); } @@ -860,19 +869,19 @@ pub fn prepare_upgrade_data_migrations( } else if versions.from < KrillVersion::candidate(0, 10, 0, 1) { // Complex migrations involving command / event conversions - pubd::pre_0_10_0::PublicationServerRepositoryAccessMigration::upgrade(mode, config, &versions)?; + pubd::pre_0_10_0::PublicationServerRepositoryAccessMigration::upgrade(mode, storage, &versions)?; let aspa_configs = - ca::pre_0_10_0::CasMigration::upgrade(mode, config)?; + ca::pre_0_10_0::CasMigration::upgrade(mode, storage)?; // The way that pubd objects were stored was changed as well // (since 0.13.0) - pubd::migrate_pre_0_12_pubd_objects(config)?; + pubd::migrate_pre_0_12_pubd_objects(storage)?; // Migrate remaining aggregate stores used in < 0.10.0 to the // new format in 0.14.0 where we combine // commands and events into a single key-value pair. pre_0_14_0::UpgradeAggregateStoreSignerInfo::upgrade( - SIGNERS_NS, mode, config, + SIGNERS_NS, mode, storage, )?; Ok(Some(UpgradeReport::new(aspa_configs, true, versions))) @@ -888,38 +897,38 @@ pub fn prepare_upgrade_data_migrations( ); // The pubd objects storage changed in 0.13.0 - pubd::migrate_pre_0_12_pubd_objects(config)?; + pubd::migrate_pre_0_12_pubd_objects(storage)?; // Migrate aggregate stores used in < 0.12.0 to the new format // in 0.14.0 where we combine commands and // events into a single key-value pair. pre_0_14_0::UpgradeAggregateStoreSignerInfo::upgrade( - SIGNERS_NS, mode, config, + SIGNERS_NS, mode, storage, )?; let aspa_configs = - ca::pre_0_14_0::CasMigration::upgrade(mode, config)?; + ca::pre_0_14_0::CasMigration::upgrade(mode, storage)?; pubd::pre_0_14_0::UpgradeAggregateStoreRepositoryAccess::upgrade( PUBSERVER_NS, mode, - config, + storage )?; Ok(Some(UpgradeReport::new(aspa_configs, true, versions))) } else if versions.from < KrillVersion::candidate(0, 13, 0, 0) { - pubd::migrate_0_12_pubd_objects(config)?; + pubd::migrate_0_12_pubd_objects(storage)?; // Migrate aggregate stores used in < 0.13.0 to the new format // in 0.14.0 where we combine commands and // events into a single key-value pair. pre_0_14_0::UpgradeAggregateStoreSignerInfo::upgrade( - SIGNERS_NS, mode, config, + SIGNERS_NS, mode, storage, )?; let aspa_configs = - ca::pre_0_14_0::CasMigration::upgrade(mode, config)?; + ca::pre_0_14_0::CasMigration::upgrade(mode, storage)?; pubd::pre_0_14_0::UpgradeAggregateStoreRepositoryAccess::upgrade( PUBSERVER_NS, mode, - config, + storage, )?; Ok(Some(UpgradeReport::new(aspa_configs, true, versions))) @@ -928,24 +937,24 @@ pub fn prepare_upgrade_data_migrations( // in 0.14.0 where we combine commands and // events into a single key-value pair. let aspa_configs = - ca::pre_0_14_0::CasMigration::upgrade(mode, config)?; + ca::pre_0_14_0::CasMigration::upgrade(mode, storage)?; pubd::pre_0_14_0::UpgradeAggregateStoreRepositoryAccess::upgrade( PUBSERVER_NS, mode, - config, + storage, )?; pre_0_14_0::UpgradeAggregateStoreSignerInfo::upgrade( - SIGNERS_NS, mode, config, + SIGNERS_NS, mode, storage, )?; pre_0_14_0::UpgradeAggregateStoreTrustAnchorSigner::upgrade( TA_SIGNER_SERVER_NS, mode, - config, + storage, )?; pre_0_14_0::UpgradeAggregateStoreTrustAnchorProxy::upgrade( TA_PROXY_SERVER_NS, mode, - config, + storage, )?; Ok(Some(UpgradeReport::new(aspa_configs, true, versions))) @@ -967,7 +976,7 @@ pub fn prepare_upgrade_data_migrations( /// - make the prepared data current pub fn finalise_data_migration( upgrade: &UpgradeVersions, - config: &Config, + storage: &StorageSystem, properties_manager: &PropertiesManager, ) -> KrillResult<()> { // For each NS @@ -998,24 +1007,19 @@ pub fn finalise_data_migration( ] { // Check if there is a non-empty upgrade store for this namespace // that would need to be migrated. - let mut upgrade_store = - KeyValueStore::create_upgrade_store(&config.storage_uri, ns)?; - if !upgrade_store.is_empty()? { - info!("Migrate new data for {ns} and archive old"); - let mut current_store = - KeyValueStore::create(&config.storage_uri, ns)?; - if !current_store.is_empty()? { - current_store.migrate_to_archive(&config.storage_uri, ns)?; + if !storage.is_upgrade_empty(ns)? { + if !storage.is_empty(ns)? { + info!("Archiving old data for {ns}."); + storage.migrate_to_archive(ns)?; } - upgrade_store.migrate_to_current(&config.storage_uri, ns)?; + info!("Migrate new data for {ns}."); + storage.migrate_to_current(ns)?; } else { // No migration needed, but check if we have a current store // for this namespace that still includes a version file. If // so, remove it. - let current_store = KeyValueStore::create( - &config.storage_uri, ns - )?; + let current_store = storage.open(ns)?; if current_store.has(None, VERSION_KEY)? { debug!("Removing excess version key in ns: {ns}"); current_store.drop_key(None, VERSION_KEY)?; @@ -1052,10 +1056,10 @@ pub fn finalise_data_migration( /// adding the keys one by one to the mapping in the signer store, if any. #[cfg(feature = "hsm")] fn record_preexisting_openssl_keys_in_signer_mapper( + storage: &StorageSystem, config: &Config, ) -> Result<(), UpgradeError> { - let signers_key_store = - KeyValueStore::create(&config.storage_uri, SIGNERS_NS)?; + let signers_key_store = storage.open(SIGNERS_NS)?; if signers_key_store.is_empty()? { let mut num_recorded_keys = 0; // If the key value store for the "signers" namespace is empty, then @@ -1063,19 +1067,16 @@ fn record_preexisting_openssl_keys_in_signer_mapper( // from a previous krill installation (earlier version, or a custom // build that has the hsm feature disabled.) - let keys_key_store = - KeyValueStore::create(&config.storage_uri, KEYS_NS)?; + let keys_key_store = storage.open(KEYS_NS)?; info!( "Mapping OpenSSL signer keys, using uri: {}", - config.storage_uri + storage.default_uri() ); let probe_interval = std::time::Duration::from_secs(config.signer_probe_retry_seconds); let krill_signer = crate::commons::crypto::KrillSignerBuilder::new( - &config.storage_uri, - probe_interval, - &config.signers, + storage, probe_interval, &config.signers, ) .with_default_signer(config.default_signer()) .with_one_off_signer(config.one_off_signer()) @@ -1180,7 +1181,7 @@ pub fn post_start_upgrade( /// - if the code is the same version then we do not upgrade /// - if the code is older then we need to error out fn upgrade_versions( - config: &Config, + storage: &StorageSystem, properties_manager: &PropertiesManager, ) -> Result, UpgradeError> { if properties_manager.is_initialized() { @@ -1217,7 +1218,7 @@ fn upgrade_versions( PUBSERVER_NS, PUBSERVER_CONTENT_NS, ] { - let kv_store = KeyValueStore::create(&config.storage_uri, ns)?; + let kv_store = storage.open(ns)?; if let Some(key_store_version) = kv_store.get::(None, VERSION_KEY)? { @@ -1254,8 +1255,7 @@ mod tests { use std::path::PathBuf; use log::LevelFilter; use tempfile::tempdir; - use url::Url; - use crate::commons::storage::Ident; + use crate::commons::storage::{Ident, StorageUri}; use crate::commons::test; use crate::server::ca::{CaStatus, CaStatusStore}; use super::*; @@ -1282,42 +1282,39 @@ mod tests { copy_folder(base_dir, &temp_dir); // Copy data for the given names spaces into memory for testing. - let mem_storage_base_uri = test::mem_storage(); + let mem_storage = test::mem_storage(); // This is needed for tls_dir etc, but will be ignored here. let bogus_path = PathBuf::from("/dev/null"); let mut config = Config::test( - &mem_storage_base_uri, + mem_storage.default_uri(), Some(&bogus_path), false, false, false, false, ); config.log_level = LevelFilter::Trace; let _ = config.init_logging(); - let source_url = Url::parse(&format!( - "local://{}", temp_dir.path().to_str().unwrap() - )).unwrap(); + let source_url = StorageUri::disk(temp_dir.path().into()); for ns in namespaces { let namespace = Ident::from_str(ns).unwrap(); - let source_store = KeyValueStore::create( + let source_store = mem_storage.open_uri( &source_url, namespace ).unwrap(); - let target_store = KeyValueStore::create( - &mem_storage_base_uri, namespace - ).unwrap(); + let target_store = mem_storage.open(namespace).unwrap(); target_store.import(&source_store).unwrap(); } let properties_manager = PropertiesManager::create( - &config.storage_uri, + &mem_storage, config.use_history_cache, ).unwrap(); prepare_upgrade_data_migrations( UpgradeMode::PrepareOnly, + &mem_storage, &config, &properties_manager, ).unwrap().unwrap(); @@ -1326,13 +1323,14 @@ mod tests { // again. let report = prepare_upgrade_data_migrations( UpgradeMode::PrepareToFinalise, + &mem_storage, &config, &properties_manager, ).unwrap().unwrap(); finalise_data_migration( report.versions(), - &config, + &mem_storage, &properties_manager, ).unwrap(); } @@ -1461,25 +1459,19 @@ mod tests { ).unwrap(); // Copy test data into test storage - let mem_storage_base_uri = test::mem_storage(); + let mem_storage = test::mem_storage(); - let source_url = Url::parse(&format!( - "local://{}", temp_dir.path().to_str().unwrap() - )).unwrap(); - let source_store = KeyValueStore::create( - &source_url, KEYS_NS - ).unwrap(); + let source_storage = StorageSystem::new_disk(temp_dir.path().into()); + let source_store = source_storage.open(KEYS_NS).unwrap(); - let target_store = KeyValueStore::create( - &mem_storage_base_uri, KEYS_NS - ).unwrap(); + let target_store = mem_storage.open(KEYS_NS).unwrap(); target_store.import(&source_store).unwrap(); // This is needed for tls_dir etc, but will be ignored here. let bogus_path = PathBuf::from("/dev/null"); let mut config = Config::test( - &mem_storage_base_uri, + mem_storage.default_uri(), Some(&bogus_path), false, false, false, false, ); @@ -1488,7 +1480,7 @@ mod tests { if do_upgrade { record_preexisting_openssl_keys_in_signer_mapper( - &config + &mem_storage, &config, ).unwrap(); } @@ -1500,7 +1492,7 @@ mod tests { config.signer_probe_retry_seconds ); let krill_signer = crate::commons::crypto::KrillSignerBuilder::new( - &mem_storage_base_uri, + &mem_storage, probe_interval, &config.signers, ).with_default_signer( @@ -1554,16 +1546,15 @@ mod tests { "test-resources/status_store/migration-0.9.5/"; let temp_dir = tempdir().unwrap(); copy_folder(source_dir_path_str, &temp_dir); - let source_dir_url = Url::parse( - &format!("local://{}", &temp_dir.path().to_str().unwrap())) - .unwrap(); + let source_dir_url = StorageUri::disk(temp_dir.path().into()); - let source_store = - KeyValueStore::create(&source_dir_url, STATUS_NS).unwrap(); + let test_storage = test::mem_storage(); - let test_storage_uri = test::mem_storage(); - let status_kv_store = - KeyValueStore::create(&test_storage_uri, STATUS_NS).unwrap(); + let source_store = test_storage.open_uri( + &source_dir_url, STATUS_NS + ).unwrap(); + + let status_kv_store = test_storage.open(STATUS_NS).unwrap(); // copy the source KV store (files) into the test KV store (in memory) status_kv_store.import(&source_store).unwrap(); @@ -1578,8 +1569,7 @@ mod tests { // Initialise the StatusStore using the new (in memory) storage, // and migrate the data. - let store = - CaStatusStore::create(&test_storage_uri, STATUS_NS).unwrap(); + let store = CaStatusStore::create(&test_storage, STATUS_NS).unwrap(); let testbed = CaHandle::from_str("testbed").unwrap(); // Get the migrated status for testbed and verify that it's equivalent diff --git a/src/upgrades/pre_0_14_0.rs b/src/upgrades/pre_0_14_0.rs index 4d3f1088..38549344 100644 --- a/src/upgrades/pre_0_14_0.rs +++ b/src/upgrades/pre_0_14_0.rs @@ -17,9 +17,8 @@ use crate::{ Aggregate, AggregateStore, Storable, StoredCommand, StoredCommandBuilder, WithStorableDetails, }, - storage::{Ident, KeyValueStore}, + storage::{Ident, KeyValueStore, StorageSystem}, }, - config::Config, server::{ properties::Properties, }, @@ -299,23 +298,19 @@ impl GenericUpgradeAggregateStore { pub fn upgrade( name_space: &Ident, mode: UpgradeMode, - config: &Config, + storage: &StorageSystem, ) -> UpgradeResult { - let current_kv_store = - KeyValueStore::create(&config.storage_uri, name_space)?; + let current_kv_store = storage.open(name_space)?; if current_kv_store.scopes()?.is_empty() { // nothing to do here Ok(AspaMigrationConfigs::default()) } else { - let new_kv_store = KeyValueStore::create_upgrade_store( - &config.storage_uri, - name_space, - )?; + let new_kv_store = storage.open_upgrade(name_space)?; let new_agg_store = AggregateStore::::create_upgrade_store( - &config.storage_uri, + storage, name_space, - config.use_history_cache, + false, )?; let store_migration = GenericUpgradeAggregateStore { diff --git a/tests/common.rs b/tests/common.rs index d96a7c7a..78e7d7bc 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -5,7 +5,6 @@ use std::collections::HashMap; use std::env; use std::str::FromStr; use std::time::Duration; -use url::Url; use log::LevelFilter; use log::{debug, error}; use reqwest::StatusCode; @@ -23,6 +22,7 @@ use krill::api; use krill::api::admin::Token; use krill::commons::httpclient; use krill::commons::crypto::OpenSslSignerConfig; +use krill::commons::storage::StorageUri; use krill::cli::client::{KrillClient, ServerUri}; use krill::constants::REPOSITORY_DIR; use krill::config::{ @@ -39,7 +39,7 @@ use krill::tasigner::TaTimingConfig; /// A test config builder. pub struct TestConfig { - storage_uri: Url, + storage_uri: StorageUri, data_dir: TempDir, port: u16, enable_testbed: bool, @@ -52,7 +52,7 @@ impl TestConfig { pub fn mem_storage() -> Self { let data_dir = TempDir::new().unwrap(); Self::new( - Url::parse( + StorageUri::from_str( &format!( "memory://{}", hex::encode(rand::random::<[u8; 8]>()) ) @@ -64,14 +64,14 @@ impl TestConfig { pub fn file_storage() -> Self { let data_dir = TempDir::new().unwrap(); Self::new( - Url::parse( + StorageUri::from_str( &format!("local://{}/data/", data_dir.path().display()) ).unwrap() , data_dir, ) } - fn new(storage_uri: Url, data_dir: TempDir) -> Self { + fn new(storage_uri: StorageUri, data_dir: TempDir) -> Self { Self { storage_uri, data_dir, @@ -889,8 +889,8 @@ pub async fn sleep_seconds(secs: u64) { sleep(Duration::from_secs(secs)).await } -pub async fn sleep_millis(secs: u64) { - sleep(Duration::from_millis(secs)).await +pub async fn sleep_millis(millisecs: u64) { + sleep(Duration::from_millis(millisecs)).await } /// Checks if a result has certain non-200 HTTP status code. diff --git a/tests/functional_old_data.rs b/tests/functional_old_data.rs index fa1f9c9a..7c7d6166 100644 --- a/tests/functional_old_data.rs +++ b/tests/functional_old_data.rs @@ -56,17 +56,19 @@ async fn functional_old_data() { // XXX Wait for Krill to process pending tasks. eprintln!(">>>> Wait a bit for Krill to catch up."); - common::sleep_millis(1000).await; + common::sleep_millis(3000).await; eprintln!(">>>> Make TA proxy signer request."); let request = server.client().ta_proxy_signer_make_request().await.unwrap(); assert_eq!(request.ta_renew_time.unwrap().year(), 2026); assert_eq!(request.renew_times[0].1.year(), 2039); + common::sleep_millis(1000).await; eprintln!(">>>> Sign TA proxy signer request."); let response = signer.process(request.into(), None).unwrap(); assert_eq!(response.content().child_responses.len(), 1); + common::sleep_millis(1000).await; eprintln!(">>>> Process TA proxy signer response."); server.client().ta_proxy_signer_response(response).await.unwrap(); diff --git a/ui/VERSION b/ui/VERSION index 9a7d84f2..78bc1abd 100644 --- a/ui/VERSION +++ b/ui/VERSION @@ -1 +1 @@ -0.9 \ No newline at end of file +0.10.0 diff --git a/ui/assets/de-960468cc.js b/ui/assets/de-960468cc.js new file mode 100644 index 00000000..327ffdb1 --- /dev/null +++ b/ui/assets/de-960468cc.js @@ -0,0 +1 @@ +const e={common:{readthedocs:"Lesen Sie die Dokumentation",report:"Ein Problem melden",confirm:"Bestätigen",cancel:"Abbruch",ok:"OK",error:"Error",success:"Erfolgreich!",copy:"In die Zwischenablage kopieren",download:"Download",dropOrClick:"Die Datei hierhin ziehen oder zum Hochladen hier klicken",started:"Krill läuft seit",newversion:"Es gibt eine neue Version!",supportcontracts:"Support Verträge",warning:"Warnung",idle:"Sie wurden aufgrund von Inaktivität ausgeloggt.",nodata:"Keine Daten",copySuccess:"XML in die Zwischenablage kopiert",edit:"Ändern",page:"page",userInfo:{title:"Login Details",user:"Benutzer"}},login:{password:"Passwort",placeholder:"Ihr Passwort",signin:"Einloggen",required:"Bitte geben Sie Ihr Passwort ein",error:"Das eingegebene Passwort ist falsch",copied:"Nutzen Sie kein Passwort von https://xkcd.com/936/",id:"Benutzer",idPlaceholder:"Ihr Benutzername",idRequired:"Bitte Ihren Benutzernamen eingeben",retry:"Klicken Sie {0} um zurück zum Login zu gelangen.",here:"hier"},onboarding:{welcome:"Willkommen zu Krill",welcomeHtml:"Starten wir mit der Erstellung Ihrer RPKI Zertifizierungsstelle (CA). Diese wird zur Konfiguration von delegierter RPKI mit übergeordneten Zertifizierungsstellen benötigt. Im Normalfall ist dies Ihre Regionale oder Nationale Internet Registrierungsstelle.

Der von Ihnen gewählte Name wird zur Identifizierung Ihrer Zertifizierungsstelle gegenüber den über- und untergeordneten Zertifizierungsstellen genutzt. Der Name selbst wird nicht in der RPKI veröffentlicht. Bitte wählen Sie einen Namen, der es anderen erlaubt Ihre Organisation zu identifizieren. Dieser Name kann nachträglich nicht mehr geändert werden.",addCAForm:{required:"Dies ist ein Pflichtfeld",format:"Ungültiger Name für eine Zertifizierungsstelle",confirm:"Zertifizierungsstelle erstellen",confirmation:{title:"Warnung",message:"Dieser Name kann nicht nachträglich geändert werden. Fortfahren?"}}},cas:{loading:"Lade Zertifizierungsstellen",ca:"Zertifizierungsstelle",cas:"Zertifizierungsstellen",search:"Suche Zertifizierungsstellen...",noCas:"Aktuell sind keine Zertifizierungsstellen festgelegt."},caDetails:{loading:"Lade {handle}",refresh:"Aktualisiere {handle}. Dies kann einige Minuten dauern",current:"Aktuelle Zertifizierungsstelle",download:"Download PEM",noRoas:"Keine ROAs gefunden.",noResources:"Sie haben noch keine Ressourcen erhalten",noChildren:"Keine untergeordneten Zertifizierungsstellen gefunden.",addRoa:"ROA hinzufügen",addAspa:"ASPA hinzufügen",editAspa:"ASPA ändern",roas:"ROAs",aspas:"ASPAs",resources:"Ressourcen",parents:"Übergeordnete CAs",repo:"Repository",type:"Typ",properties:"Eigenschaften",property:"Eigenschaft",value:"Wert",kind:"Art",resource:"Ressource",children:"Untergeordnete CAs",handle:"Name",comment:"Anmerkung",maxLength:"MaxLength",maxLengthTooltip:"Wenn maxLength nicht angegeben wird, wird die Präfixlänge genutzt.",confirmation:{title:"Warnung",message:"Diese Aktion entfernt das ROA '{prefix}-{max_length} => {asn}'. Fortfahren?",added:"ROA hinzugefügt",retired:"ROA entfernt",retiredSuccess:"Das ROA wurde entfernt",addedSuccess:"Das ROA wurde hinzugefügt",commentUpdatedSuccess:"Die Anmerkung des ROAs wurde aktualisiert"},addROAForm:{required:"Dies ist ein Pflichtfeld",asn_format:"Dies ist kein gültiges ASN",prefix_format:"Bitte geben Sie ein gültiges IPv4 oder IPv6 Präfix ein"},onboardingWarning:"Um Ihr Zertifikat und Ihre ROAs zu veröffentlichen müssen Sie Ihre Zertifizierungsstelle mit einer öffentlichen RPKI Datenbank (Repository) verbinden. Sobald die Konfiguration der Eltern-Zertifizierungsstelle abgeschlossen ist, wird die Relying Party Software mit dem Herunterladen Ihres Zertifikates sowie Ihrer ROAs, welche in dieser Datenbank veröffentlicht wurden, beginnen.",initializeRepository:"Sie müssen die RPKI Datenbank (Repository) konfigurieren bevor Ihre Zertifizierungsstelle die Resourcen-Zertifikate von der Eltern-Zertifizierungsstelle anfordern kann.",initialize:"Bitte initialisieren Sie die RPKI Datenbank (Repository) und/oder die Eltern-Zertifizierungsstelle zuerst.",noResourcesYet:"Sie haben noch keine Ressourcen erhalten",clickToRefresh:"Klicken Sie hier, um neu zu laden",parentsTab:{request:"Anfrage der untergeordneten Zertifizierungsstelle",response:"Antwort der übergeordneten Zertifizierungsstelle",addParent:"Eine zusätzliche übergeordnete Zertifizierungsstelle hinzufügen",addParentSuccess:"Übergeordnete Zertifizierungsstelle erfolgreich hinzugefügt",name:"Name der übergeordneten Zertifizierungsstelle",namerequired:"Ein Name für die übergeordnete Zertifizierungsstelle ist erforderlich",nameformat:"Dies ist kein gültiger Name"},repoTab:{request:"Anfrage des Publishers",response:"Antwort der Datenbank (Repository)",addRepo:"Eine Datenbank (Repository) hinzufügen",addRepoSuccess:"Datenbank (Repository) hinzugefügt"},analyseThis:"Meine ROAs analysieren",analysis:"ROA Analyse",suggestions:{following:"Bitte überprüfen Sie die folgenden vorgeschlagenen Änderungen an Ihren ROAs.",readMore:"Weitere Informationen...",nochanges:"Keine Änderungsvorschläge im Moment",adding:"Hinzufügen",removing:"Entfernen des ROA",keep:"Alles beibehalten.",willResult:"Wird resultieren in",yourChoice:"Ihre Auswahl",ourSuggestion:"Unser Vorschlag",ourSuggestionHelp:"Unser Vorschlag basiert auf der RIPE RIS Routing Information, bitte überprüfen!",addThis:"Dieses hinzufügen",removeThis:"Dieses entfernen",willAdd:"Fügt dieses ROA hinzu",willRemove:"Entfernt dieses ROA",reasons:{not_found:"Nicht gefunden",not_held:"Das Präfix ist nicht länger in einem Ihrer Zertifikate enthalten. Das ROA wird nicht veröffentlicht",invalid_asn:"Ungültiges ASN",invalid_length:"Ungültige Länge",stale:"Nicht sichtbar",disallowing:"ROA führt zu ungültigen Ankündigungen. Die Nutzung eines AS0 ROA wird stattdessen empfohlen.",as0_redundant:"Redundantes ROA",redundant:"Redundantes ROA",too_permissive:"Nicht restriktiv genug",specific:"Spezifische Ankündigungen im ROA erlauben welches nicht restriktiv genug wäre",new:"Neu"}},syncParents:"Synchronisiere mit übergeordneter Zertifizierungsstelle",syncRepo:"Repository aktualisieren",lastExchange:"Letzte Synchronisierung",exchangeUri:"URI",nextExchange:"Nächste Synchronisierung vor",allResources:"Ihre zertifizierten IP- und ASN-Adressen",entitlements:"Berechtigte Adressen",showEntitlements:"Zeige Details",parentCertificate:"Eltern-Zertifikat",published:"Veröffentlicht"},aspas:{customer:"Customer",providers:"Providers",search:"Search for customer, provider...",confirmation:{title:"Warning",message:"This will remove the ASPA '{customer} => {providers}'. Continue?",added:"ASPA added",retired:"ASPA removed",retiredSuccess:"The ASPA has been removed",addedSuccess:"The ASPA has been added",commentUpdatedSuccess:"The ASPA comment has been updated"},customer_validation_format:"The customer format is invalid or already exists",providers_validation_format:"The providers format is invalid",add:"Add ASPA",edit:"Edit ASPA",analyse:"Analyse providers",detected_providers:"Declared providers",providers_missing:"ASNs observed in RIS but not in the provider list. Please verify that none of these ASNs act as your provider.",no_aspas:"Krill did not find any ASNs. You need an ASN to be able to create an ASPA for it."},announcements:{noRoasOrAnnouncements:"Keine ROAs oder BGP-Ankündigung gefunden.",search:"Suche nach ASN, Präfix, Status...",authorizes:"Autorisiert {number} BGP-Ankündigungen",disallows:"Verweigert {number} BGP-Ankündigungen",asn:"ASN",prefix:"Präfix",stateLabel:"Status",state:{roa_seen:"SICHTBAR",roa_seen_help:"Dieses ROA stimmt mit BGP Ankündigungen überein",roa_unseen:"NICHT SICHTBAR",roa_unseen_help:"Wir sehen keine BGP Ankündigungen welche mit dem ROA übereinstimmen",roa_not_held:"PRÄFIX ENTFERNT",roa_not_held_help:"Das Präfix ist nicht länger in einem Ihrer Zertifikate enthalten. Das ROA wird nicht veröffentlicht",roa_no_announcement_info:"KEINE BGP-ANKÜNDIGUNG INFORMATION",roa_too_permissive:"NICHT RESTRIKTIV GENUG",roa_too_permissive_help:"Dieses ROA stimmt mit BGP Ankündigungen überein, erlaubt darüber hinaus aber auch noch weitere BGP Ankündigungen",roa_disallowing:"Verursacht ungültige Ankündigungen",roa_disallowing_help:"Dieses ROA führt ausschließlich zu ungültigen Ankündigungen. Falls dies beabsichtigt ist, wird die Nutzung eines AS0 ROAs empfohlen.",roa_redundant:"REDUNDANT",roa_redundant_help:"Dieses ROA ist redundant da ein oder mehrere andere ROAs das Präfix, die Länge und das ASN bereits einschließen",roa_as0:"AS0",roa_as0_help:"Dieses ROA dient dazu alle BGP Ankündigungen für dieses Präfix zu verbieten",roa_as0_redundant:"REDUNDANT",roa_as0_redundant_help:"Dieses AS0 ROA ist redundant da ein oder mehrere andere ROAs das Präfix bereits einschließen",announcement_not_found:"NICHT GEFUNDEN",announcement_not_found_help:"Diese BGP Ankündigung wird von keinem Ihrer ROAs geschützt",announcement_invalid_length:"UNGÜLTIGE LÄNGE",announcement_invalid_length_help:"Diese BGP Ankündigung ist nicht erlaubt, da es spezifischer ist als das Präfix und die MaxLength welche Sie für dieses ASN autorisiert haben",announcement_invalid_asn:"UNGÜLTIGES ASN",announcement_invalid_asn_help:"Diese BGP Ankündigung ist nicht erlaubt, da Sie nur das Präfix für ein anderes ASN autorisiert haben",announcement_disallowed:"DISALLOWED BY AS0",announcement_disallowed_help:"This announcement is not allowed because you have an AS0 ROA that disallows it"},download:"CSV herunterladen"},deltaErrors:{duplicates:"ROA existiert bereits",covered:"Überlappendes ROA existiert",notheld:"Nicht Ihr Präfix",unknowns:"ROA existiert nicht",invalid_length:"Ungültige Länge",covering:"Überlappt mit bestehendem ROA",as0_exists:"Überlappendes AS0 ROA besteht bereits",as0_overlaps:"Überlappt bestehendes ROA"},errors:{repo_not_set:"Sie müssen erst eine Datenbank (Repository) konfigurieren",pub_unknown:"Publisher '{publisher}' unbekannt",pub_duplicate:"Publisher '{publisher}' wurde bereits initialisiert",pub_outside_jail:"Publisher uri '{uri}' außerhalb der Datenbank (Repository) uri '{sia_base}'",pub_uri_no_slash:"Publisher uri '{uri}' muss mit einen Slash enden",pub_no_embedded_repo:"Keine integrierte Datenbank (Repository) konfiguriert",ca_duplicate:"Die Zertifizierungsstelle '{ca}' wurde bereits initialisiert",ca_unknown:"Die Zertifizierungsstelle '{ca}' ist unbekannt",ca_repo_same:"Diese Datenbank (Repository) ist bereits in Benutzung",ca_repo_issue:"Die Datenbank (Repository) hat folgenden Error zurückgeliefert: {cause}",ca_repo_response_invalid_xml:"Datenbank (Repository) Antwort ist ungültig",ca_repo_response_wrong_xml:"Antwort der übergeordneten Zertifizierungsstelle anstatt der Datenbank (Repository) erhalten",ca_parent_duplicate:"Es existiert bereits eine übergeordnete Zertifizierungsstelle mit dem Namen '{parent}'",ca_parent_xml_duplicate:"Diese Antwort XML ist bereits in Gebrauch von einer übergeordneten Zertifizierungsstelle mit dem Namen '{parent}'",ca_parent_unknown:"Es existiert keine übergeordnete Zertifizierungsstelle mit dem Namen '{parent}'",ca_parent_issue:"Error von übergeordneter Zertifizierungsstelle '{parent}' empfangen: {cause}",ca_parent_response_invalid_xml:"Ungültiges XML von übergeordneter Zertifizierungsstelle empfangen",ca_parent_response_wrong_xml:"Datenbank (Repository) Antwort während des Hinzufügens der übergeordneten Zertifizierungsstelle erhalten",ca_child_duplicate:"Es existiert bereits eine untergeordnete Zertifizierungsstelle mit dem Namen '{child}'",ca_child_unknown:"Es existiert keine untergeordnete Zertifizierungsstelle mit dem Namen '{child}'",ca_child_resources_required:"Sie müssen Ressourcen für die untergeordnete Zertifizierungsstelle angeben '{child}'",ca_roa_unknown:"Unbekanntes ROA kann nicht entfernt werden '{prefix}-{max_length} => {asn}'",ca_roa_duplicate:"ROA existiert bereits '{prefix}-{max_length} => {asn}'",ca_roa_invalid_max_length:"Ungültige maxLength in ROA '{prefix}-{max_length} => {asn}'",ca_roa_not_entitled:"Das ROA Präfix '{prefix}' ist in keinem Ihrer aktuellen Zertifikate zu finden",ta_not_allowed:"Diese Funktionalität wird vom Test Vertrauensanker nicht unterstützt",ta_name_reserved:"Name reserviert",ca_roa_delta_error:"Das ROA wurde aus den folgenden Gründen zurückgewiesen",api_insufficient_rights:"Ihr Benutzer hat keine ausreichenden Rechte um die Aktion durchzuführen. Bitte kontaktieren Sie Ihren Administrator.",api_invalid_credentials:"Die eingegebenen Benutzerdaten waren inkorrekt.",api_login_error:"Während des Logins ist ein Fehler aufgetreten: {cause}",api_auth_transient_error:"Bei der Authentifizierung Ihrer Anfrage ist ein (temporärer) Fehler aufgetreten. Bitte versuchen Sie es später erneut.",api_auth_permanent_error:"Bei der Authentifizierung Ihrer Anfrage ist ein Fehler aufgetreten. Bitte kontaktieren Sie Ihren Administrator.",api_auth_session_expired:"Ihre Sitzung ist abgelaufen. Bitte loggen Sie sich erneut ein..",general_error:"Es ist ein Fehler aufgetreten. Bitte kontaktieren Sie Ihren Administrator."},testbed:{welcome:"Willkommen zur RPKI Testumgebung",disclaimer:{heading:"Haftungsausschluss",body:"Diese Testumgebung stellt eine komplett unabhängige RPKI Hierarchie zu Evaluierungszwecken zu Verfügung. Sie erlaubt Ihnen die Registrierung jedweder Ressourcen für Ihre Kinder-Zertifizierungsstelle. Es werden keinerlei Garantien bezüglich der Verfügbarkeit des Dienstes gegeben. Falls Probleme auftreten, melden Sie diese bitte."},rpconfighelp:{heading:"Testumgebungs TAL",body:"Um die Daten für diese Testumgebung zu laden, starten Sie bitte den Download von diesem Trust Anchor Locator (TAL) und konfigurieren Sie diesen in Ihrer Relying Party Software. Bitte beachten Sie, dass Sie diesen TAL NIEMALS in einer Produktivumgebung einsetzen sollten. Er wird ausschließlich zu Testzwecken zur Verfügung gestellt."},regunreg:{heading:"(De-)Registrieren",body:"

Nutzen Sie das Formular um Ihre RPKI Zertifizierungsstelle als Kind der Testumgebung zu registrieren. Danach können Sie Route Origin Authorisations (ROAs) für Ihre Ressourcen erstellen.

Falls Sie nicht Ihre eigenen Rsync und RRDP Datenbanken bereitstellen wollen, können Sie das Publisher Registrierungsformular nutzen um Ihre ROAs in der Datenbank der Testumgebung zu veröffentlichen. Nutzen Sie das Deregistrierungsformular um bestehende Beziehungen aufzulösen (sogar die von anderen Nutzern der Testumgebung!).

"},rfcdoclink:"Klicken Sie hier um die RFC-8183 Dokumentation für dieses XML zu sehen",childhandle:"Kind Handle",publisherhandle:"Publisher Handle",responseXML:"Testumgebung Antwort XML",addChild:{heading:"Zertifizierungsstelle registrieren",requestXML:{label:"Kind Anfrage XML",placeholder:"Fügen Sie Ihr XML hier ein"},asnresources:{label:"ASN Ressourcen",placeholder:"Die AS Ressourcen: z.B. AS1, AS3-4"},ipv4resources:{label:"IPv4 Ressourcen",placeholder:"Die IPv4 Ressourcen: z.B. 192.168.0.0/16"},ipv6resources:{label:"IPv6 Ressourcen",placeholder:"Die IPv6 Ressourcen: z.B. 2001:db8::/32"},confirm:"Kinder-Zertifizierungsstelle registrieren",format:"Dies ist keine valide Kind XML Anfrage",required:"Fügen Sie eine Kind XML Anfrage hinzu",confirmation:{title:"Warnung",message:"Sind Sie sicher, dass Sie diese Kinder-Zertifizierungsstelle in der Testumgebung registrieren wollen?"},success:"Kinder-Zertifizierungsstelle '{child_handle}' wurde der Testumgebung hinzugefügt.",registeranother:"Eine andere Zertifizierungsstelle hinzufügen"},removeChild:{heading:"Zertifizierungsstelle entfernen",placeholder:"Geben Sie den Namen der Zertifizierungsstelle ein welche entfernt werden soll",confirm:"Kinder-Zertifizierungsstelle entfernen",confirmation:{title:"Warnung",message:"Sind Sie sicher, dass Sie diese Kinder-Zertifizierungsstelle aus der Testumgebung entfernen wollen?"},success:"Kinder-Zertifizierungsstelle '{child_handle}' wurde aus der Testumgebung entfernt."},addPublisher:{heading:"Publisher registrieren",requestXML:{label:"Publisher Anfrage XML",placeholder:"Fügen Sie Ihr XML hier ein"},confirm:"Publisher registrieren",format:"Dies ist keine valide Publisher XML Anfrage",required:"Fügen Sie eine Publisher XML Anfrage hinzu",confirmation:{title:"Warnung",message:"Sind Sie sicher, dass Sie diesen Publisher in der Testumgebung registrieren wollen?"},success:"Publisher '{publisher_handle}' wurde der Testumgebung hinzugefügt.",registeranother:"Einen anderen Publisher hinzufügen"},removePublisher:{heading:"Publisher entfernen",placeholder:"Geben Sie den Namen des Publishers ein welcher entfernt werden soll",confirm:"Publisher entfernen",confirmation:{title:"Warnung",message:"Sind Sie sicher, dass Sie diesen Publisher aus der Testumgebung entfernen wollen?"},success:"Publisher '{publisher_handle}' wurde aus der Testumgebung entfernt."},errors:{invalid_xml:"Ungültiges XML: {err}",missing_xml_el:"Fehlendes Element {el}",missing_xml_child_el:"Fehlendes Kind-Element {el} vom Element {parent}",missing_xml_attr:"Fehlendes Attribut {attr} vom Element {el}",empty_xml_el:"Element {el} darf nicht leer sein",empty_xml_attr:"Attribut {attr} vom Element {el} darf nicht leer sein",non_ascii_xml_el:"Element {el} darf nur ASCII-Zeichen enthalten",child_handle_required:"Kind Handle wird benötigt",publisher_handle_required:"Publisher Handle wird benötigt",non_base64_certificate_xml_el:"Element {el} muss ein korrektes Base64 encodiertes selbst-signiertes X.509 BPKI Zertifikat enthalten",invalid_registration_data:"Ihre Registrierungsdaten konnten nicht korrekt verarbeitet werden"}}};export{e as translations}; diff --git a/ui/assets/de-e4495468.js b/ui/assets/de-e4495468.js deleted file mode 100644 index 5abb819b..00000000 --- a/ui/assets/de-e4495468.js +++ /dev/null @@ -1 +0,0 @@ -const e={common:{readthedocs:"Lesen Sie die Dokumentation",report:"Ein Problem melden",confirm:"Bestätigen",cancel:"Abbruch",ok:"OK",error:"Error",success:"Erfolgreich!",copy:"In die Zwischenablage kopieren",download:"Download",dropOrClick:"Die Datei hierhin ziehen oder zum Hochladen hier klicken",started:"Krill läuft seit",newversion:"Es gibt eine neue Version!",supportcontracts:"Support Verträge",warning:"Warnung",idle:"Sie wurden aufgrund von Inaktivität ausgeloggt.",nodata:"Keine Daten",copySuccess:"XML in die Zwischenablage kopiert",edit:"Ändern",page:"page",userInfo:{title:"Login Details",user:"Benutzer"}},login:{password:"Passwort",placeholder:"Ihr Passwort",signin:"Einloggen",required:"Bitte geben Sie Ihr Passwort ein",error:"Das eingegebene Passwort ist falsch",copied:"Nutzen Sie kein Passwort von https://xkcd.com/936/",id:"Benutzer",idPlaceholder:"Ihr Benutzername",idRequired:"Bitte Ihren Benutzernamen eingeben",retry:"Klicken Sie {0} um zurück zum Login zu gelangen.",here:"hier"},onboarding:{welcome:"Willkommen zu Krill",welcomeHtml:"Starten wir mit der Erstellung Ihrer RPKI Zertifizierungsstelle (CA). Diese wird zur Konfiguration von delegierter RPKI mit übergeordneten Zertifizierungsstellen benötigt. Im Normalfall ist dies Ihre Regionale oder Nationale Internet Registrierungsstelle.

Der von Ihnen gewählte Name wird zur Identifizierung Ihrer Zertifizierungsstelle gegenüber den über- und untergeordneten Zertifizierungsstellen genutzt. Der Name selbst wird nicht in der RPKI veröffentlicht. Bitte wählen Sie einen Namen, der es anderen erlaubt Ihre Organisation zu identifizieren. Dieser Name kann nachträglich nicht mehr geändert werden.",addCAForm:{required:"Dies ist ein Pflichtfeld",format:"Ungültiger Name für eine Zertifizierungsstelle",confirm:"Zertifizierungsstelle erstellen",confirmation:{title:"Warnung",message:"Dieser Name kann nicht nachträglich geändert werden. Fortfahren?"}}},cas:{loading:"Lade Zertifizierungsstellen",ca:"Zertifizierungsstelle",cas:"Zertifizierungsstellen",search:"Suche Zertifizierungsstellen...",noCas:"Aktuell sind keine Zertifizierungsstellen festgelegt."},caDetails:{loading:"Lade {handle}",refresh:"Aktualisiere {handle}. Dies kann einige Minuten dauern",current:"Aktuelle Zertifizierungsstelle",download:"Download PEM",noRoas:"Keine ROAs gefunden.",noResources:"Sie haben noch keine Ressourcen erhalten",noChildren:"Keine untergeordneten Zertifizierungsstellen gefunden.",addRoa:"ROA hinzufügen",addAspa:"ASPA hinzufügen",editAspa:"ASPA ändern",roas:"ROAs",aspas:"ASPAs",resources:"Ressourcen",parents:"Übergeordnete CAs",repo:"Repository",type:"Typ",properties:"Eigenschaften",property:"Eigenschaft",value:"Wert",kind:"Art",resource:"Ressource",children:"Untergeordnete CAs",handle:"Name",comment:"Anmerkung",maxLength:"MaxLength",maxLengthTooltip:"Wenn maxLength nicht angegeben wird, wird die Präfixlänge genutzt.",confirmation:{title:"Warnung",message:"Diese Aktion entfernt das ROA '{prefix}-{max_length} => {asn}'. Fortfahren?",added:"ROA hinzugefügt",retired:"ROA entfernt",retiredSuccess:"Das ROA wurde entfernt",addedSuccess:"Das ROA wurde hinzugefügt",commentUpdatedSuccess:"Die Anmerkung des ROAs wurde aktualisiert"},addROAForm:{required:"Dies ist ein Pflichtfeld",asn_format:"Dies ist kein gültiges ASN",prefix_format:"Bitte geben Sie ein gültiges IPv4 oder IPv6 Präfix ein"},onboardingWarning:"Um Ihr Zertifikat und Ihre ROAs zu veröffentlichen müssen Sie Ihre Zertifizierungsstelle mit einer öffentlichen RPKI Datenbank (Repository) verbinden. Sobald die Konfiguration der Eltern-Zertifizierungsstelle abgeschlossen ist, wird die Relying Party Software mit dem Herunterladen Ihres Zertifikates sowie Ihrer ROAs, welche in dieser Datenbank veröffentlicht wurden, beginnen.",initializeRepository:"Sie müssen die RPKI Datenbank (Repository) konfigurieren bevor Ihre Zertifizierungsstelle die Resourcen-Zertifikate von der Eltern-Zertifizierungsstelle anfordern kann.",initialize:"Bitte initialisieren Sie die RPKI Datenbank (Repository) und/oder die Eltern-Zertifizierungsstelle zuerst.",noResourcesYet:"Sie haben noch keine Ressourcen erhalten",clickToRefresh:"Klicken Sie hier, um neu zu laden",parentsTab:{request:"Anfrage der untergeordneten Zertifizierungsstelle",response:"Antwort der übergeordneten Zertifizierungsstelle",addParent:"Eine zusätzliche übergeordnete Zertifizierungsstelle hinzufügen",addParentSuccess:"Übergeordnete Zertifizierungsstelle erfolgreich hinzugefügt",name:"Name der übergeordneten Zertifizierungsstelle",namerequired:"Ein Name für die übergeordnete Zertifizierungsstelle ist erforderlich",nameformat:"Dies ist kein gültiger Name"},repoTab:{request:"Anfrage des Publishers",response:"Antwort der Datenbank (Repository)",addRepo:"Eine Datenbank (Repository) hinzufügen",addRepoSuccess:"Datenbank (Repository) hinzugefügt"},analyseThis:"Meine ROAs analysieren",analysis:"ROA Analyse",suggestions:{following:"Bitte überprüfen Sie die folgenden vorgeschlagenen Änderungen an Ihren ROAs.",readMore:"Weitere Informationen...",nochanges:"Keine Änderungsvorschläge im Moment",adding:"Hinzufügen",removing:"Entfernen des ROA",keep:"Alles beibehalten.",willResult:"Wird resultieren in",yourChoice:"Ihre Auswahl",ourSuggestion:"Unser Vorschlag",ourSuggestionHelp:"Unser Vorschlag basiert auf der RIPE RIS Routing Information, bitte überprüfen!",addThis:"Dieses hinzufügen",removeThis:"Dieses entfernen",willAdd:"Fügt dieses ROA hinzu",willRemove:"Entfernt dieses ROA",reasons:{not_found:"Nicht gefunden",not_held:"Das Präfix ist nicht länger in einem Ihrer Zertifikate enthalten. Das ROA wird nicht veröffentlicht",invalid_asn:"Ungültiges ASN",invalid_length:"Ungültige Länge",stale:"Nicht sichtbar",disallowing:"ROA führt zu ungültigen Ankündigungen. Die Nutzung eines AS0 ROA wird stattdessen empfohlen.",as0_redundant:"Redundantes ROA",redundant:"Redundantes ROA",too_permissive:"Nicht restriktiv genug",specific:"Spezifische Ankündigungen im ROA erlauben welches nicht restriktiv genug wäre",new:"Neu"}},syncParents:"Synchronisiere mit übergeordneter Zertifizierungsstelle",syncRepo:"Repository aktualisieren",lastExchange:"Letzte Synchronisierung",exchangeUri:"URI",nextExchange:"Nächste Synchronisierung vor",allResources:"Ihre zertifizierten IP- und ASN-Adressen",entitlements:"Berechtigte Adressen",showEntitlements:"Zeige Details",parentCertificate:"Eltern-Zertifikat",published:"Veröffentlicht"},aspas:{customer:"Customer",providers:"Providers",search:"Search for customer, provider...",confirmation:{title:"Warning",message:"This will remove the ASPA '{customer} => {providers}'. Continue?",added:"ASPA added",retired:"ASPA removed",retiredSuccess:"The ASPA has been removed",addedSuccess:"The ASPA has been added",commentUpdatedSuccess:"The ASPA comment has been updated"},customer_validation_format:"The customer format is invalid or already exists",providers_validation_format:"The providers format is invalid"},announcements:{noRoasOrAnnouncements:"Keine ROAs oder BGP-Ankündigung gefunden.",search:"Suche nach ASN, Präfix, Status...",authorizes:"Autorisiert {number} BGP-Ankündigungen",disallows:"Verweigert {number} BGP-Ankündigungen",asn:"ASN",prefix:"Präfix",stateLabel:"Status",state:{roa_seen:"SICHTBAR",roa_seen_help:"Dieses ROA stimmt mit BGP Ankündigungen überein",roa_unseen:"NICHT SICHTBAR",roa_unseen_help:"Wir sehen keine BGP Ankündigungen welche mit dem ROA übereinstimmen",roa_not_held:"PRÄFIX ENTFERNT",roa_not_held_help:"Das Präfix ist nicht länger in einem Ihrer Zertifikate enthalten. Das ROA wird nicht veröffentlicht",roa_no_announcement_info:"KEINE BGP-ANKÜNDIGUNG INFORMATION",roa_too_permissive:"NICHT RESTRIKTIV GENUG",roa_too_permissive_help:"Dieses ROA stimmt mit BGP Ankündigungen überein, erlaubt darüber hinaus aber auch noch weitere BGP Ankündigungen",roa_disallowing:"Verursacht ungültige Ankündigungen",roa_disallowing_help:"Dieses ROA führt ausschließlich zu ungültigen Ankündigungen. Falls dies beabsichtigt ist, wird die Nutzung eines AS0 ROAs empfohlen.",roa_redundant:"REDUNDANT",roa_redundant_help:"Dieses ROA ist redundant da ein oder mehrere andere ROAs das Präfix, die Länge und das ASN bereits einschließen",roa_as0:"AS0",roa_as0_help:"Dieses ROA dient dazu alle BGP Ankündigungen für dieses Präfix zu verbieten",roa_as0_redundant:"REDUNDANT",roa_as0_redundant_help:"Dieses AS0 ROA ist redundant da ein oder mehrere andere ROAs das Präfix bereits einschließen",announcement_not_found:"NICHT GEFUNDEN",announcement_not_found_help:"Diese BGP Ankündigung wird von keinem Ihrer ROAs geschützt",announcement_invalid_length:"UNGÜLTIGE LÄNGE",announcement_invalid_length_help:"Diese BGP Ankündigung ist nicht erlaubt, da es spezifischer ist als das Präfix und die MaxLength welche Sie für dieses ASN autorisiert haben",announcement_invalid_asn:"UNGÜLTIGES ASN",announcement_invalid_asn_help:"Diese BGP Ankündigung ist nicht erlaubt, da Sie nur das Präfix für ein anderes ASN autorisiert haben",announcement_disallowed:"DISALLOWED BY AS0",announcement_disallowed_help:"This announcement is not allowed because you have an AS0 ROA that disallows it"},download:"CSV herunterladen"},deltaErrors:{duplicates:"ROA existiert bereits",covered:"Überlappendes ROA existiert",notheld:"Nicht Ihr Präfix",unknowns:"ROA existiert nicht",invalid_length:"Ungültige Länge",covering:"Überlappt mit bestehendem ROA",as0_exists:"Überlappendes AS0 ROA besteht bereits",as0_overlaps:"Überlappt bestehendes ROA"},errors:{repo_not_set:"Sie müssen erst eine Datenbank (Repository) konfigurieren",pub_unknown:"Publisher '{publisher}' unbekannt",pub_duplicate:"Publisher '{publisher}' wurde bereits initialisiert",pub_outside_jail:"Publisher uri '{uri}' außerhalb der Datenbank (Repository) uri '{sia_base}'",pub_uri_no_slash:"Publisher uri '{uri}' muss mit einen Slash enden",pub_no_embedded_repo:"Keine integrierte Datenbank (Repository) konfiguriert",ca_duplicate:"Die Zertifizierungsstelle '{ca}' wurde bereits initialisiert",ca_unknown:"Die Zertifizierungsstelle '{ca}' ist unbekannt",ca_repo_same:"Diese Datenbank (Repository) ist bereits in Benutzung",ca_repo_issue:"Die Datenbank (Repository) hat folgenden Error zurückgeliefert: {cause}",ca_repo_response_invalid_xml:"Datenbank (Repository) Antwort ist ungültig",ca_repo_response_wrong_xml:"Antwort der übergeordneten Zertifizierungsstelle anstatt der Datenbank (Repository) erhalten",ca_parent_duplicate:"Es existiert bereits eine übergeordnete Zertifizierungsstelle mit dem Namen '{parent}'",ca_parent_xml_duplicate:"Diese Antwort XML ist bereits in Gebrauch von einer übergeordneten Zertifizierungsstelle mit dem Namen '{parent}'",ca_parent_unknown:"Es existiert keine übergeordnete Zertifizierungsstelle mit dem Namen '{parent}'",ca_parent_issue:"Error von übergeordneter Zertifizierungsstelle '{parent}' empfangen: {cause}",ca_parent_response_invalid_xml:"Ungültiges XML von übergeordneter Zertifizierungsstelle empfangen",ca_parent_response_wrong_xml:"Datenbank (Repository) Antwort während des Hinzufügens der übergeordneten Zertifizierungsstelle erhalten",ca_child_duplicate:"Es existiert bereits eine untergeordnete Zertifizierungsstelle mit dem Namen '{child}'",ca_child_unknown:"Es existiert keine untergeordnete Zertifizierungsstelle mit dem Namen '{child}'",ca_child_resources_required:"Sie müssen Ressourcen für die untergeordnete Zertifizierungsstelle angeben '{child}'",ca_roa_unknown:"Unbekanntes ROA kann nicht entfernt werden '{prefix}-{max_length} => {asn}'",ca_roa_duplicate:"ROA existiert bereits '{prefix}-{max_length} => {asn}'",ca_roa_invalid_max_length:"Ungültige maxLength in ROA '{prefix}-{max_length} => {asn}'",ca_roa_not_entitled:"Das ROA Präfix '{prefix}' ist in keinem Ihrer aktuellen Zertifikate zu finden",ta_not_allowed:"Diese Funktionalität wird vom Test Vertrauensanker nicht unterstützt",ta_name_reserved:"Name reserviert",ca_roa_delta_error:"Das ROA wurde aus den folgenden Gründen zurückgewiesen",api_insufficient_rights:"Ihr Benutzer hat keine ausreichenden Rechte um die Aktion durchzuführen. Bitte kontaktieren Sie Ihren Administrator.",api_invalid_credentials:"Die eingegebenen Benutzerdaten waren inkorrekt.",api_login_error:"Während des Logins ist ein Fehler aufgetreten: {cause}",api_auth_transient_error:"Bei der Authentifizierung Ihrer Anfrage ist ein (temporärer) Fehler aufgetreten. Bitte versuchen Sie es später erneut.",api_auth_permanent_error:"Bei der Authentifizierung Ihrer Anfrage ist ein Fehler aufgetreten. Bitte kontaktieren Sie Ihren Administrator.",api_auth_session_expired:"Ihre Sitzung ist abgelaufen. Bitte loggen Sie sich erneut ein..",general_error:"Es ist ein Fehler aufgetreten. Bitte kontaktieren Sie Ihren Administrator."},testbed:{welcome:"Willkommen zur RPKI Testumgebung",disclaimer:{heading:"Haftungsausschluss",body:"Diese Testumgebung stellt eine komplett unabhängige RPKI Hierarchie zu Evaluierungszwecken zu Verfügung. Sie erlaubt Ihnen die Registrierung jedweder Ressourcen für Ihre Kinder-Zertifizierungsstelle. Es werden keinerlei Garantien bezüglich der Verfügbarkeit des Dienstes gegeben. Falls Probleme auftreten, melden Sie diese bitte."},rpconfighelp:{heading:"Testumgebungs TAL",body:"Um die Daten für diese Testumgebung zu laden, starten Sie bitte den Download von diesem Trust Anchor Locator (TAL) und konfigurieren Sie diesen in Ihrer Relying Party Software. Bitte beachten Sie, dass Sie diesen TAL NIEMALS in einer Produktivumgebung einsetzen sollten. Er wird ausschließlich zu Testzwecken zur Verfügung gestellt."},regunreg:{heading:"(De-)Registrieren",body:"

Nutzen Sie das Formular um Ihre RPKI Zertifizierungsstelle als Kind der Testumgebung zu registrieren. Danach können Sie Route Origin Authorisations (ROAs) für Ihre Ressourcen erstellen.

Falls Sie nicht Ihre eigenen Rsync und RRDP Datenbanken bereitstellen wollen, können Sie das Publisher Registrierungsformular nutzen um Ihre ROAs in der Datenbank der Testumgebung zu veröffentlichen. Nutzen Sie das Deregistrierungsformular um bestehende Beziehungen aufzulösen (sogar die von anderen Nutzern der Testumgebung!).

"},rfcdoclink:"Klicken Sie hier um die RFC-8183 Dokumentation für dieses XML zu sehen",childhandle:"Kind Handle",publisherhandle:"Publisher Handle",responseXML:"Testumgebung Antwort XML",addChild:{heading:"Zertifizierungsstelle registrieren",requestXML:{label:"Kind Anfrage XML",placeholder:"Fügen Sie Ihr XML hier ein"},asnresources:{label:"ASN Ressourcen",placeholder:"Die AS Ressourcen: z.B. AS1, AS3-4"},ipv4resources:{label:"IPv4 Ressourcen",placeholder:"Die IPv4 Ressourcen: z.B. 192.168.0.0/16"},ipv6resources:{label:"IPv6 Ressourcen",placeholder:"Die IPv6 Ressourcen: z.B. 2001:db8::/32"},confirm:"Kinder-Zertifizierungsstelle registrieren",format:"Dies ist keine valide Kind XML Anfrage",required:"Fügen Sie eine Kind XML Anfrage hinzu",confirmation:{title:"Warnung",message:"Sind Sie sicher, dass Sie diese Kinder-Zertifizierungsstelle in der Testumgebung registrieren wollen?"},success:"Kinder-Zertifizierungsstelle '{child_handle}' wurde der Testumgebung hinzugefügt.",registeranother:"Eine andere Zertifizierungsstelle hinzufügen"},removeChild:{heading:"Zertifizierungsstelle entfernen",placeholder:"Geben Sie den Namen der Zertifizierungsstelle ein welche entfernt werden soll",confirm:"Kinder-Zertifizierungsstelle entfernen",confirmation:{title:"Warnung",message:"Sind Sie sicher, dass Sie diese Kinder-Zertifizierungsstelle aus der Testumgebung entfernen wollen?"},success:"Kinder-Zertifizierungsstelle '{child_handle}' wurde aus der Testumgebung entfernt."},addPublisher:{heading:"Publisher registrieren",requestXML:{label:"Publisher Anfrage XML",placeholder:"Fügen Sie Ihr XML hier ein"},confirm:"Publisher registrieren",format:"Dies ist keine valide Publisher XML Anfrage",required:"Fügen Sie eine Publisher XML Anfrage hinzu",confirmation:{title:"Warnung",message:"Sind Sie sicher, dass Sie diesen Publisher in der Testumgebung registrieren wollen?"},success:"Publisher '{publisher_handle}' wurde der Testumgebung hinzugefügt.",registeranother:"Einen anderen Publisher hinzufügen"},removePublisher:{heading:"Publisher entfernen",placeholder:"Geben Sie den Namen des Publishers ein welcher entfernt werden soll",confirm:"Publisher entfernen",confirmation:{title:"Warnung",message:"Sind Sie sicher, dass Sie diesen Publisher aus der Testumgebung entfernen wollen?"},success:"Publisher '{publisher_handle}' wurde aus der Testumgebung entfernt."},errors:{invalid_xml:"Ungültiges XML: {err}",missing_xml_el:"Fehlendes Element {el}",missing_xml_child_el:"Fehlendes Kind-Element {el} vom Element {parent}",missing_xml_attr:"Fehlendes Attribut {attr} vom Element {el}",empty_xml_el:"Element {el} darf nicht leer sein",empty_xml_attr:"Attribut {attr} vom Element {el} darf nicht leer sein",non_ascii_xml_el:"Element {el} darf nur ASCII-Zeichen enthalten",child_handle_required:"Kind Handle wird benötigt",publisher_handle_required:"Publisher Handle wird benötigt",non_base64_certificate_xml_el:"Element {el} muss ein korrektes Base64 encodiertes selbst-signiertes X.509 BPKI Zertifikat enthalten",invalid_registration_data:"Ihre Registrierungsdaten konnten nicht korrekt verarbeitet werden"}}};export{e as translations}; diff --git a/ui/assets/edit-white-a808b3e3.svg b/ui/assets/edit-white-a808b3e3.svg deleted file mode 100644 index 07a3bf26..00000000 --- a/ui/assets/edit-white-a808b3e3.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/ui/assets/en-1f317977.js b/ui/assets/en-1f317977.js new file mode 100644 index 00000000..80ce1d68 --- /dev/null +++ b/ui/assets/en-1f317977.js @@ -0,0 +1 @@ +const e={common:{readthedocs:"Read the Docs",report:"Report a problem",confirm:"Confirm",cancel:"Cancel",ok:"OK",error:"Error",success:"Success!",copy:"Copy to clipboard",download:"Download",dropOrClick:"Drop file here or click to upload",started:"Krill has been running since",newversion:"New version available!",supportcontracts:"Support contracts",warning:"Warning",idle:"You have been logged out because of inactivity.",nodata:"No data",copySuccess:"XML copied to your clipboard",edit:"Edit",page:"page",userInfo:{title:"Login Details",user:"User"}},login:{password:"Password",placeholder:"Your password",signin:"Sign In",required:"Please enter your password",error:"The credentials you specified are wrong",copied:"You should not get your passwords from https://xkcd.com/936/",id:"Username",idPlaceholder:"Your username",idRequired:"Please enter your username",retry:"Click {0} to return to the login page.",here:"here"},onboarding:{welcome:"Welcome to Krill",welcomeHtml:"Let's start by creating your RPKI Certificate Authority (CA). It will be used to configure Delegated RPKI with one or multiple parent CAs, usually your Regional or National Internet Registry.

The handle you choose will identify your CA in interactions with parent and child CAs. It will not be published in the RPKI. Please choose a handle that helps others recognise your organisation. Once set, the handle cannot be changed.",addCAForm:{required:"This field is required",format:"This is not a valid CA name",confirm:"Create CA",confirmation:{title:"Warning",message:"Once set, the handle cannot be changed. Continue?"}}},cas:{loading:"Loading Certificate Authorities",ca:"Certificate Authority",cas:"Certificate Authorities",search:"Search CAs...",noCas:"There are currently no Certificate Authorities defined."},caDetails:{loading:"Loading {handle}",refresh:"Refreshing {handle}, this can take a while",current:"Current Certificate Authority",download:"Download PEM",noRoas:"No ROAs found.",noResources:"You have not received any resources yet",noChildren:"No children found.",addRoa:"Add ROA",addAspa:"Add ASPA",editAspa:"Edit ASPA",roas:"ROAs",aspas:"ASPAs",resources:"Resources",parents:"Parents",repo:"Repository",type:"Type",properties:"Properties",property:"Property",value:"Value",kind:"Kind",resource:"Resource",children:"Children",handle:"Handle",comment:"Comment",maxLength:"Max Length",maxLengthTooltip:"If max length is not specified, it defaults to the prefix length.",confirmation:{title:"Warning",message:"This will remove the ROA '{prefix}-{max_length} => {asn}'. Continue?",added:"ROA added",retired:"ROA removed",retiredSuccess:"The ROA has been removed",addedSuccess:"The ROA has been added",commentUpdatedSuccess:"The ROA comment has been updated"},addROAForm:{required:"This field is required",asn_format:"This is not a valid ASN",prefix_format:"Please enter a valid IPv4 or IPv6 prefix"},onboardingWarning:"You will need to connect your CA to a public RPKI repository where it can publish your certificate and ROAs. As soon as the parent configuration is completed, relying party software will immediately start fetching your certificate and the ROAs you create from this repository.",initializeRepository:"You still need to configure a repository for your CA before it can request resource certificate(s) from its parent(s)",initialize:"Please initialize the RPKI repository and/or the parent first.",noResourcesYet:"You have not received any resources yet",clickToRefresh:"Click here to refresh",parentsTab:{request:"Child Request",response:"Parent Response",addParent:"Add an additional parent",addParentSuccess:"Parent added",name:"Parent Name",namerequired:"The parent name is required",nameformat:"This is not a valid parent name"},repoTab:{request:"Publisher Request",addRepo:"Add a repository",response:"Repository Response",addRepoSuccess:"Repository added"},analyseThis:"Analyse my ROAs",analysis:"ROA Analysis",suggestions:{following:"Please verify the following suggested changes to your ROAs.",readMore:"Read more..",nochanges:"We suggest no changes at this time",adding:"Adding",removing:"Removing ROA",keep:"Keep everything as is.",willResult:"Will result in",yourChoice:"Your choice",ourSuggestion:"Our Suggestion",ourSuggestionHelp:"Our suggestion is based on RIPE RIS Routing information, please verify!",addThis:"Add this",removeThis:"Remove this",willAdd:"Will add this ROA",willRemove:"Will remove this ROA",reasons:{not_found:"Allow announcement not covered by any of your ROAs",not_held:"ROA cannot be published, its prefix is no longer on your certificate(s)",invalid_asn:"Allow announcement from new ASN",invalid_length:"Allow more specific announcement for ASN",stale:"No announcements seen for ROA",disallowing:"This ROA disallows announcements only. If this is intentional you may want to use an AS0 ROA instead.",as0_redundant:"Redundant ROA",redundant:"Redundant ROA",too_permissive:"ROA permits extra announcements and may be abused for path spoofing hijacks",specific:"Allow specific announcement in a ROA which may be too permissive",new:"New"}},syncParents:"Refresh Parents",syncRepo:"Refresh Repository",lastExchange:"Last Exchange",exchangeUri:"URI",nextExchange:"Next Exchange Before",allResources:"All Resources",entitlements:"Entitlements",showEntitlements:"Show Detailed Entitlements",parentCertificate:"Parent Certificate",published:"Published"},aspas:{customer:"Customer ASN",providers:"Providers ASNs",search:"Search for customer, provider...",confirmation:{title:"Warning",message:"This will remove the ASPA '{customer} => {providers}'. Continue?",added:"ASPA added",retired:"ASPA removed",retiredSuccess:"The ASPA has been removed",addedSuccess:"The ASPA has been added",commentUpdatedSuccess:"The ASPA comment has been updated"},customer_validation_format:"The customer ASN is invalid or already exists",providers_validation_format:"The provider ASN list is invalid",add:"Add ASPA",edit:"Edit ASPA",analyse:"Analyse providers",detected_providers:"Declared providers",providers_missing:"ASNs observed in RIS but not in the provider list. Please verify that none of these ASNs act as your provider",no_aspas:"Krill did not find any ASNs. You need an ASN to be able to create an ASPA for it."},announcements:{noRoasOrAnnouncements:"No ROAs or Announcements found.",search:"Search for ASN, prefix, state...",authorizes:"Authorizes {number} announcements",disallows:"Disallows {number} announcements",asn:"ASN",prefix:"Prefix",stateLabel:"State",state:{roa_seen:"SEEN",roa_seen_help:"This ROA matches announcements seen in BGP",roa_unseen:"NOT SEEN",roa_unseen_help:"We do not see any BGP announcements matching this ROA",roa_not_held:"PREFIX REMOVED",roa_not_held_help:"The prefix is no longer on your certificate(s), the ROA will not be published",roa_no_announcement_info:"NO ANNOUNCEMENT INFO",roa_too_permissive:"TOO PERMISSIVE",roa_too_permissive_help:"This ROA matches announcements in BGP, but also allows unseen announcements",roa_disallowing:"DISALLOWING",roa_disallowing_help:"This ROA disallows announcements only. If this is intentional you may want to use an AS0 ROA instead.",roa_redundant:"REDUNDANT",roa_redundant_help:"This ROA is redundant because there are one or more other ROAs covering its prefix, length and ASN",roa_as0:"AS0",roa_as0_help:"This ROA serves to disallow all announcements for a prefix",roa_as0_redundant:"REDUNDANT",roa_as0_redundant_help:"This AS0 ROA is redundant because there are one or more other ROAs covering its prefix",announcement_not_found:"NOT FOUND",announcement_not_found_help:"This announcement is not covered by any of your ROAs",announcement_invalid_length:"INVALID LENGTH",announcement_invalid_length_help:"This announcement is not allowed because it is more specific than the prefix and max length you authorized for this ASN",announcement_invalid_asn:"INVALID ASN",announcement_invalid_asn_help:"This announcement is not allowed because you only authorized the prefix from another ASN",announcement_disallowed:"DISALLOWED BY AS0",announcement_disallowed_help:"This announcement is not allowed because you have an AS0 ROA that disallows it"},download:"Download CSV"},deltaErrors:{duplicates:"Duplicates",covered:"Covered",notheld:"Notheld",unknowns:"Unknowns",invalid_length:"Invalid Length",covering:"Covering",as0_exists:"AS0 Exists",as0_overlaps:"AS0 Overlaps"},errors:{repo_not_set:"You must configure a repository first",pub_unknown:"Publisher '{publisher}' is unknown",pub_duplicate:"Publisher '{publisher}' was already initialised",pub_outside_jail:"Publisher uri '{uri}' outside repository uri '{sia_base}'",pub_uri_no_slash:"Publisher uri '{uri}' must have a trailing slash",pub_no_embedded_repo:"No embedded repository configured",ca_duplicate:"CA '{ca}' was already initialised",ca_unknown:"CA '{ca}' is unknown",ca_repo_same:"This repository is already in use",ca_repo_issue:"Received error from repository: {cause}",ca_repo_response_invalid_xml:"Got invalid repository response xml",ca_repo_response_wrong_xml:"Got parent instead of repository response",ca_parent_duplicate:"You already have a parent named '{parent}'",ca_parent_xml_duplicate:"This response is already used by a parent named '{parent}'",ca_parent_unknown:"You do not have a parent named '{parent}'",ca_parent_issue:"Received error from parent '{parent}': {cause}",ca_parent_response_invalid_xml:"Got invalid parent response xml",ca_parent_response_wrong_xml:"Got repository response when adding parent",ca_child_duplicate:"You already have a child CA named '{child}'",ca_child_unknown:"You do not have a child CA named '{child}'",ca_child_resources_required:"You must specify resources for Child CA '{child}'",ca_roa_unknown:"Cannot remove unknown ROA '{prefix}-{max_length} => {asn}'",ca_roa_duplicate:"Duplicate ROA '{prefix}-{max_length} => {asn}'",ca_roa_invalid_max_length:"Invalid max length in ROA '{prefix}-{max_length} => {asn}'",ca_roa_not_entitled:"ROA prefix '{prefix}' is not on any of your current certificates",ta_not_allowed:"This functionality is not supported by the test Trust Anchor",ta_name_reserved:"Name reserved",ca_roa_delta_error:"ROA rejected because of the following issue(s)",api_insufficient_rights:"Your user does not have sufficient rights to perform this action. Please contact your administrator.",api_invalid_credentials:"The supplied login credentials were incorrect.",api_login_error:"An error occurred while logging you in: {cause}",api_auth_transient_error:"A (temporary) error occured while trying to authenticate your request. Please try again later.",api_auth_permanent_error:"An error occurred while trying to authenticate your request. Please contact your administrator.",api_auth_session_expired:"Your login session has expired. Please login again..",general_error:"Something went wrong. Please contact your administrator."},testbed:{welcome:"Welcome to this RPKI testbed",disclaimer:{heading:"Disclaimer",body:"This testbed offers a completely independent RPKI hierarchy, which can be used for evaluation purposes. It allows you to register any resources for your Child CA. No guarantees are given concerning the availability of this service. If you find any issues, please let us know."},rpconfighelp:{heading:"Testbed TAL",body:"To fetch the data published by this testbed, please download this Trust Anchor Locator (TAL) and configure it in your Relying Party Software. Note that you should NEVER use this TAL in a production environment. This is provided for testing only."},regunreg:{heading:"Register/Unregister",body:"

Use the form to register your RPKI Certificate Authority as a child of the testbed so you can create Route Origin Authorisations (ROAs) for the resources that you claim.

If you do not wish to host your own Rsync and RRDP repositories you can use the Register Publisher form to configure publishing your ROAs in the respository hosted by the testbed. Use the Unregister forms to cancel previously established relationships (even those of other testbed users!).

"},rfcdoclink:"Click to view the RFC-8183 documentation for this XML",childhandle:"Child Handle",publisherhandle:"Publisher Handle",responseXML:"Testbed response XML",addChild:{heading:"Register CA",requestXML:{label:"Child Request XML",placeholder:"Paste your XML here"},asnresources:{label:"ASN Resources",placeholder:"The AS resources: e.g. AS1, AS3-4"},ipv4resources:{label:"IPv4 Resources",placeholder:"The IPv4 resources: e.g. 192.168.0.0/16"},ipv6resources:{label:"IPv6 Resources",placeholder:"The IPv6 resources: e.g. 2001:db8::/32"},confirm:"Register child CA",format:"This is not a valid child request XML",required:"Please provide the child request XML",confirmation:{title:"Warning",message:"Are you sure you want to register this child with the testbed?"},success:"Child CA '{child_handle}' has been added to the testbed.",registeranother:"Register another CA"},removeChild:{heading:"Unregister CA",placeholder:"Enter the CA name to remove",confirm:"Remove child CA",confirmation:{title:"Warning",message:"Are you sure you want to unregister this child with the testbed?"},success:"Child CA '{child_handle}' has been removed from the testbed."},addPublisher:{heading:"Register Publisher",requestXML:{label:"Publisher Request XML",placeholder:"Paste your XML here"},confirm:"Register publisher",format:"This is not a valid publisher request XML",required:"Please provide the publisher request XML",confirmation:{title:"Warning",message:"Are you sure you want to register this publisher with the testbed?"},success:"Publisher '{publisher_handle}' has been added to the testbed.",registeranother:"Register another Publisher"},removePublisher:{heading:"Unregister Publisher",placeholder:"Enter the Publisher name to remove",confirm:"Remove publisher",confirmation:{title:"Warning",message:"Are you sure you want to unregister this publisher with the testbed?"},success:"Publisher '{publisher_handle}' has been removed from the testbed."},errors:{invalid_xml:"Invalid XML: {err}",missing_xml_el:"Missing element {el}",missing_xml_child_el:"Missing child element {el} of element {parent}",missing_xml_attr:"Missing attribute {attr} on element {el}",empty_xml_el:"Element {el} cannot be empty",empty_xml_attr:"Attribute {attr} on element {el} cannot be empty",non_ascii_xml_el:"Element {el} cannot contain non-ASCII characters",child_handle_required:"Child Handle is required",publisher_handle_required:"Publisher Handle is required",non_base64_certificate_xml_el:"Element {el} must contain a correctly Base64 encoded self-signed X.509 BPKI certificate",invalid_registration_data:"Your registration details could not be parsed correctly"}}};export{e as translations}; diff --git a/ui/assets/en-893c19c3.js b/ui/assets/en-893c19c3.js deleted file mode 100644 index 3ded2d64..00000000 --- a/ui/assets/en-893c19c3.js +++ /dev/null @@ -1 +0,0 @@ -const e={common:{readthedocs:"Read the Docs",report:"Report a problem",confirm:"Confirm",cancel:"Cancel",ok:"OK",error:"Error",success:"Success!",copy:"Copy to clipboard",download:"Download",dropOrClick:"Drop file here or click to upload",started:"Krill has been running since",newversion:"New version available!",supportcontracts:"Support contracts",warning:"Warning",idle:"You have been logged out because of inactivity.",nodata:"No data",copySuccess:"XML copied to your clipboard",edit:"Edit",page:"page",userInfo:{title:"Login Details",user:"User"}},login:{password:"Password",placeholder:"Your password",signin:"Sign In",required:"Please enter your password",error:"The credentials you specified are wrong",copied:"You should not get your passwords from https://xkcd.com/936/",id:"Username",idPlaceholder:"Your username",idRequired:"Please enter your username",retry:"Click {0} to return to the login page.",here:"here"},onboarding:{welcome:"Welcome to Krill",welcomeHtml:"Let's start by creating your RPKI Certificate Authority (CA). It will be used to configure Delegated RPKI with one or multiple parent CAs, usually your Regional or National Internet Registry.

The handle you choose will identify your CA in interactions with parent and child CAs. It will not be published in the RPKI. Please choose a handle that helps others recognise your organisation. Once set, the handle cannot be changed.",addCAForm:{required:"This field is required",format:"This is not a valid CA name",confirm:"Create CA",confirmation:{title:"Warning",message:"Once set, the handle cannot be changed. Continue?"}}},cas:{loading:"Loading Certificate Authorities",ca:"Certificate Authority",cas:"Certificate Authorities",search:"Search CAs...",noCas:"There are currently no Certificate Authorities defined."},caDetails:{loading:"Loading {handle}",refresh:"Refreshing {handle}, this can take a while",current:"Current Certificate Authority",download:"Download PEM",noRoas:"No ROAs found.",noResources:"You have not received any resources yet",noChildren:"No children found.",addRoa:"Add ROA",addAspa:"Add ASPA",editAspa:"Edit ASPA",roas:"ROAs",aspas:"ASPAs",resources:"Resources",parents:"Parents",repo:"Repository",type:"Type",properties:"Properties",property:"Property",value:"Value",kind:"Kind",resource:"Resource",children:"Children",handle:"Handle",comment:"Comment",maxLength:"Max Length",maxLengthTooltip:"If max length is not specified, it defaults to the prefix length.",confirmation:{title:"Warning",message:"This will remove the ROA '{prefix}-{max_length} => {asn}'. Continue?",added:"ROA added",retired:"ROA removed",retiredSuccess:"The ROA has been removed",addedSuccess:"The ROA has been added",commentUpdatedSuccess:"The ROA comment has been updated"},addROAForm:{required:"This field is required",asn_format:"This is not a valid ASN",prefix_format:"Please enter a valid IPv4 or IPv6 prefix"},onboardingWarning:"You will need to connect your CA to a public RPKI repository where it can publish your certificate and ROAs. As soon as the parent configuration is completed, relying party software will immediately start fetching your certificate and the ROAs you create from this repository.",initializeRepository:"You still need to configure a repository for your CA before it can request resource certificate(s) from its parent(s)",initialize:"Please initialize the RPKI repository and/or the parent first.",noResourcesYet:"You have not received any resources yet",clickToRefresh:"Click here to refresh",parentsTab:{request:"Child Request",response:"Parent Response",addParent:"Add an additional parent",addParentSuccess:"Parent added",name:"Parent Name",namerequired:"The parent name is required",nameformat:"This is not a valid parent name"},repoTab:{request:"Publisher Request",addRepo:"Add a repository",response:"Repository Response",addRepoSuccess:"Repository added"},analyseThis:"Analyse my ROAs",analysis:"ROA Analysis",suggestions:{following:"Please verify the following suggested changes to your ROAs.",readMore:"Read more..",nochanges:"We suggest no changes at this time",adding:"Adding",removing:"Removing ROA",keep:"Keep everything as is.",willResult:"Will result in",yourChoice:"Your choice",ourSuggestion:"Our Suggestion",ourSuggestionHelp:"Our suggestion is based on RIPE RIS Routing information, please verify!",addThis:"Add this",removeThis:"Remove this",willAdd:"Will add this ROA",willRemove:"Will remove this ROA",reasons:{not_found:"Allow announcement not covered by any of your ROAs",not_held:"ROA cannot be published, its prefix is no longer on your certificate(s)",invalid_asn:"Allow announcement from new ASN",invalid_length:"Allow more specific announcement for ASN",stale:"No announcements seen for ROA",disallowing:"This ROA disallows announcements only. If this is intentional you may want to use an AS0 ROA instead.",as0_redundant:"Redundant ROA",redundant:"Redundant ROA",too_permissive:"ROA permits extra announcements and may be abused for path spoofing hijacks",specific:"Allow specific announcement in a ROA which may be too permissive",new:"New"}},syncParents:"Refresh Parents",syncRepo:"Refresh Repository",lastExchange:"Last Exchange",exchangeUri:"URI",nextExchange:"Next Exchange Before",allResources:"All Resources",entitlements:"Entitlements",showEntitlements:"Show Detailed Entitlements",parentCertificate:"Parent Certificate",published:"Published"},aspas:{customer:"Customer ASN",providers:"Providers ASNs",search:"Search for customer, provider...",confirmation:{title:"Warning",message:"This will remove the ASPA '{customer} => {providers}'. Continue?",added:"ASPA added",retired:"ASPA removed",retiredSuccess:"The ASPA has been removed",addedSuccess:"The ASPA has been added",commentUpdatedSuccess:"The ASPA comment has been updated"},customer_validation_format:"The customer ASN is invalid or already exists",providers_validation_format:"The provider ASN list is invalid"},announcements:{noRoasOrAnnouncements:"No ROAs or Announcements found.",search:"Search for ASN, prefix, state...",authorizes:"Authorizes {number} announcements",disallows:"Disallows {number} announcements",asn:"ASN",prefix:"Prefix",stateLabel:"State",state:{roa_seen:"SEEN",roa_seen_help:"This ROA matches announcements seen in BGP",roa_unseen:"NOT SEEN",roa_unseen_help:"We do not see any BGP announcements matching this ROA",roa_not_held:"PREFIX REMOVED",roa_not_held_help:"The prefix is no longer on your certificate(s), the ROA will not be published",roa_no_announcement_info:"NO ANNOUNCEMENT INFO",roa_too_permissive:"TOO PERMISSIVE",roa_too_permissive_help:"This ROA matches announcements in BGP, but also allows unseen announcements",roa_disallowing:"DISALLOWING",roa_disallowing_help:"This ROA disallows announcements only. If this is intentional you may want to use an AS0 ROA instead.",roa_redundant:"REDUNDANT",roa_redundant_help:"This ROA is redundant because there are one or more other ROAs covering its prefix, length and ASN",roa_as0:"AS0",roa_as0_help:"This ROA serves to disallow all announcements for a prefix",roa_as0_redundant:"REDUNDANT",roa_as0_redundant_help:"This AS0 ROA is redundant because there are one or more other ROAs covering its prefix",announcement_not_found:"NOT FOUND",announcement_not_found_help:"This announcement is not covered by any of your ROAs",announcement_invalid_length:"INVALID LENGTH",announcement_invalid_length_help:"This announcement is not allowed because it is more specific than the prefix and max length you authorized for this ASN",announcement_invalid_asn:"INVALID ASN",announcement_invalid_asn_help:"This announcement is not allowed because you only authorized the prefix from another ASN",announcement_disallowed:"DISALLOWED BY AS0",announcement_disallowed_help:"This announcement is not allowed because you have an AS0 ROA that disallows it"},download:"Download CSV"},deltaErrors:{duplicates:"Duplicates",covered:"Covered",notheld:"Notheld",unknowns:"Unknowns",invalid_length:"Invalid Length",covering:"Covering",as0_exists:"AS0 Exists",as0_overlaps:"AS0 Overlaps"},errors:{repo_not_set:"You must configure a repository first",pub_unknown:"Publisher '{publisher}' is unknown",pub_duplicate:"Publisher '{publisher}' was already initialised",pub_outside_jail:"Publisher uri '{uri}' outside repository uri '{sia_base}'",pub_uri_no_slash:"Publisher uri '{uri}' must have a trailing slash",pub_no_embedded_repo:"No embedded repository configured",ca_duplicate:"CA '{ca}' was already initialised",ca_unknown:"CA '{ca}' is unknown",ca_repo_same:"This repository is already in use",ca_repo_issue:"Received error from repository: {cause}",ca_repo_response_invalid_xml:"Got invalid repository response xml",ca_repo_response_wrong_xml:"Got parent instead of repository response",ca_parent_duplicate:"You already have a parent named '{parent}'",ca_parent_xml_duplicate:"This response is already used by a parent named '{parent}'",ca_parent_unknown:"You do not have a parent named '{parent}'",ca_parent_issue:"Received error from parent '{parent}': {cause}",ca_parent_response_invalid_xml:"Got invalid parent response xml",ca_parent_response_wrong_xml:"Got repository response when adding parent",ca_child_duplicate:"You already have a child CA named '{child}'",ca_child_unknown:"You do not have a child CA named '{child}'",ca_child_resources_required:"You must specify resources for Child CA '{child}'",ca_roa_unknown:"Cannot remove unknown ROA '{prefix}-{max_length} => {asn}'",ca_roa_duplicate:"Duplicate ROA '{prefix}-{max_length} => {asn}'",ca_roa_invalid_max_length:"Invalid max length in ROA '{prefix}-{max_length} => {asn}'",ca_roa_not_entitled:"ROA prefix '{prefix}' is not on any of your current certificates",ta_not_allowed:"This functionality is not supported by the test Trust Anchor",ta_name_reserved:"Name reserved",ca_roa_delta_error:"ROA rejected because of the following issue(s)",api_insufficient_rights:"Your user does not have sufficient rights to perform this action. Please contact your administrator.",api_invalid_credentials:"The supplied login credentials were incorrect.",api_login_error:"An error occurred while logging you in: {cause}",api_auth_transient_error:"A (temporary) error occured while trying to authenticate your request. Please try again later.",api_auth_permanent_error:"An error occurred while trying to authenticate your request. Please contact your administrator.",api_auth_session_expired:"Your login session has expired. Please login again..",general_error:"Something went wrong. Please contact your administrator."},testbed:{welcome:"Welcome to this RPKI testbed",disclaimer:{heading:"Disclaimer",body:"This testbed offers a completely independent RPKI hierarchy, which can be used for evaluation purposes. It allows you to register any resources for your Child CA. No guarantees are given concerning the availability of this service. If you find any issues, please let us know."},rpconfighelp:{heading:"Testbed TAL",body:"To fetch the data published by this testbed, please download this Trust Anchor Locator (TAL) and configure it in your Relying Party Software. Note that you should NEVER use this TAL in a production environment. This is provided for testing only."},regunreg:{heading:"Register/Unregister",body:"

Use the form to register your RPKI Certificate Authority as a child of the testbed so you can create Route Origin Authorisations (ROAs) for the resources that you claim.

If you do not wish to host your own Rsync and RRDP repositories you can use the Register Publisher form to configure publishing your ROAs in the respository hosted by the testbed. Use the Unregister forms to cancel previously established relationships (even those of other testbed users!).

"},rfcdoclink:"Click to view the RFC-8183 documentation for this XML",childhandle:"Child Handle",publisherhandle:"Publisher Handle",responseXML:"Testbed response XML",addChild:{heading:"Register CA",requestXML:{label:"Child Request XML",placeholder:"Paste your XML here"},asnresources:{label:"ASN Resources",placeholder:"The AS resources: e.g. AS1, AS3-4"},ipv4resources:{label:"IPv4 Resources",placeholder:"The IPv4 resources: e.g. 192.168.0.0/16"},ipv6resources:{label:"IPv6 Resources",placeholder:"The IPv6 resources: e.g. 2001:db8::/32"},confirm:"Register child CA",format:"This is not a valid child request XML",required:"Please provide the child request XML",confirmation:{title:"Warning",message:"Are you sure you want to register this child with the testbed?"},success:"Child CA '{child_handle}' has been added to the testbed.",registeranother:"Register another CA"},removeChild:{heading:"Unregister CA",placeholder:"Enter the CA name to remove",confirm:"Remove child CA",confirmation:{title:"Warning",message:"Are you sure you want to unregister this child with the testbed?"},success:"Child CA '{child_handle}' has been removed from the testbed."},addPublisher:{heading:"Register Publisher",requestXML:{label:"Publisher Request XML",placeholder:"Paste your XML here"},confirm:"Register publisher",format:"This is not a valid publisher request XML",required:"Please provide the publisher request XML",confirmation:{title:"Warning",message:"Are you sure you want to register this publisher with the testbed?"},success:"Publisher '{publisher_handle}' has been added to the testbed.",registeranother:"Register another Publisher"},removePublisher:{heading:"Unregister Publisher",placeholder:"Enter the Publisher name to remove",confirm:"Remove publisher",confirmation:{title:"Warning",message:"Are you sure you want to unregister this publisher with the testbed?"},success:"Publisher '{publisher_handle}' has been removed from the testbed."},errors:{invalid_xml:"Invalid XML: {err}",missing_xml_el:"Missing element {el}",missing_xml_child_el:"Missing child element {el} of element {parent}",missing_xml_attr:"Missing attribute {attr} on element {el}",empty_xml_el:"Element {el} cannot be empty",empty_xml_attr:"Attribute {attr} on element {el} cannot be empty",non_ascii_xml_el:"Element {el} cannot contain non-ASCII characters",child_handle_required:"Child Handle is required",publisher_handle_required:"Publisher Handle is required",non_base64_certificate_xml_el:"Element {el} must contain a correctly Base64 encoded self-signed X.509 BPKI certificate",invalid_registration_data:"Your registration details could not be parsed correctly"}}};export{e as translations}; diff --git a/ui/assets/es-9044ec29.js b/ui/assets/es-9044ec29.js new file mode 100644 index 00000000..141edbed --- /dev/null +++ b/ui/assets/es-9044ec29.js @@ -0,0 +1 @@ +const e={common:{readthedocs:"Leer los documentos",report:"Reportar un problema",confirm:"Confirmar",cancel:"Cancelar",ok:"OK",error:"Error",success:"Éxito!",copy:"Copiar al portapapeles",download:"Descargar",dropOrClick:"Colocar el archivo aquí o hacer clic para cargarlo",started:"Krill está corriendo desde",newversion:"¡Hay una nueva versión disponible!",supportcontracts:"Contratos de soporte y mantenimiento",warning:"Advertencia",idle:"Tu sesion ha caducado debido a inactividad.",nodata:"Sin datos",copySuccess:"El XML se copió a su portapapeles",edit:"Edit",page:"page",userInfo:{title:"Login Details",user:"User"}},login:{password:"Contraseña",placeholder:"Su contraseña",signin:"Iniciar sesión",required:"Ingrese su contraseña",error:"La contraseña que ingresó es incorrecta",copied:"NO deberías crear tus claves como en https://xkcd.com/936/",id:"Nombre de usuario",idPlaceholder:"Su nombre de usuario",idRequired:"Por favor ingrese su nombre de usuario",retry:"Haga click en {0} para volver a la pagina de login.",here:"aqui"},onboarding:{welcome:"Bienvenido a Krill",welcomeHtml:"Empecemos por crear su Autoridad de Certificación (CA) RPKI. Esta se usará para configurar el RPKI Delegado con una o múltiples CA padre, generalmente su Registro Regional o Nacional de Internet.

El identificador que escoja identificará a su CA en sus interacciones con las CA padres e hijos. No se publicará en el RPKI. Escoja un identificador que ayude a los demás a reconocer a su organización. Una vez guardado, el identificador no se puede cambiar. Más información...",addCAForm:{required:"Este campo es obligatorio",format:"Este no es un nombre de CA válido",confirm:"Crear CA",confirmation:{title:"Advertencia",message:"Una vez guardado, el identificador no se puede cambiar. żDesea continuar?"}}},cas:{loading:"Cargando Autoridades de Certificación",ca:"Autoridad de Certificación",cas:"Autoridades de Certificación",search:"Buscar CAs...",noCas:"No hay ninguna autoridad de certificación definida."},caDetails:{loading:"Cargando {handle}",refresh:"Actualizando {handle}, esto puede tomar varios minutos",current:"Autoridad de Certificación actual",download:"Descargar PEM",noRoas:"No se encontró ningún ROA.",noResources:"Todavía no ha recibido ningún recurso",noChildren:"No se encontraron hijos.",addRoa:"Agregar ROA",addAspa:"Add ASPA",editAspa:"Edit ASPA",roas:"ROAs",aspas:"ASPAs",resources:"Recursos",parents:"Padres",repo:"Repositorio",type:"Tipo",properties:"Propiedades",property:"Propiedad",value:"Valor",kind:"Clase",resource:"Recurso",children:"Hijos",handle:"Identificador",comment:"Comentario",maxLength:"Largo máx",maxLengthTooltip:"Si el largo máximo no es especificado, se toma por defecto el largo del prefijo.",confirmation:{title:"Advertencia",message:"Esto eliminará el ROA '{prefix}-{max_length} => {asn}'. żDesea continuar?",added:"ROA agregado",retired:"ROA eliminado",retiredSuccess:"El ROA se ha eliminado",addedSuccess:"El ROA se ha agregado",commentUpdatedSuccess:"El comentario del ROA se ha actualizado"},addROAForm:{required:"Este campo es obligatorio",asn_format:"Este no es un ASN válido",prefix_format:"Ingrese un prefijo IPv4 o IPv6 válido"},onboardingWarning:"Deberá conectar su CA a un repositorio RPKI público donde pueda publicar su certificado y sus ROA. Tan pronto como se complete la configuración del padre, el software de validación comenzará a recuperar su certificado y los ROA que cree a partir de este repositorio.",initializeRepository:"Es necesario configurar un repositorio para su CA antes que pueda solicitar certificado(s) de recursos a su padre(s)",initialize:"Primero inicialice el repositorio RPKI y/o el padre.",noResourcesYet:"Todavía no ha recibido ningún recurso",clickToRefresh:"Haga clic aquí para actualizar",parentsTab:{request:"Solicitud padre",response:"Respuesta padre",addParent:"Agregar otro padre",addParentSuccess:"Se agregó el padre",name:"Nombre del padre",namerequired:"El nombre del padre es un dato necesario",nameformat:"Este nombre de padre no es válido"},repoTab:{request:"Solicitud repositorio",response:"Respuesta repositorio",addRepo:"Agregar repositorio",addRepoSuccess:"Se agregó el repositorio"},analyseThis:"Análisis de mis ROAs",analysis:"Análisis de ROAs",suggestions:{following:"Por favor verifique que estos cambios a sus ROAs sean correctos.",readMore:"Read more..",nochanges:"No encontramos cambios a sugerir en este momento",adding:"Agregando",removing:"Eliminando ROA",keep:"Mantener todo en su estado actual.",willResult:"Producirá",yourChoice:"Su selección",ourSuggestion:"Nuestra sugerencias",ourSuggestionHelp:"Nuestras sugerencias se basan en los datos de tablas de enrutamiento de RIPE RIS, ¡ por favor verifique esto sea correcto !",addThis:"Agregar esto",removeThis:"Eliminar esto",willAdd:"Agregaremos este ROA",willRemove:"Eliminaremos este ROA",reasons:{not_found:"No encontrado",not_held:"El prefijo ya no se encuentra en sus certificado(s). Los ROAs correspondientes no serán publicados",invalid_asn:"ASN Invalido",invalid_length:"Largo de prefijo inválido",stale:"rancio/viejo",disallowing:"Este ROA prohibe todo anuncio y no autoriza ninguno. ¿Quizá sería mejor utilizar AS0?",as0_redundant:"Redundante en AS0",redundant:"Redundante",too_permissive:"Demasiado permisivo",specific:"Permitir anuncios muy específicos en un ROA puede ser demasiado permisivo.",new:"Nuevo"}},syncParents:"Refrescar padres",syncRepo:"Refrescar respositorios",lastExchange:"Último intercambio",exchangeUri:"URI",nextExchange:"Próximo intercambio antes de",allResources:"Todos los recursos",entitlements:"Derechos de uso",showEntitlements:"Mostrar detalle sobre los derechos de uso",parentCertificate:"Certificado padre",published:"Publicado"},aspas:{customer:"Customer",providers:"Providers",search:"Search for customer, provider...",confirmation:{title:"Warning",message:"This will remove the ASPA '{customer} => {providers}'. Continue?",added:"ASPA added",retired:"ASPA removed",retiredSuccess:"The ASPA has been removed",addedSuccess:"The ASPA has been added",commentUpdatedSuccess:"The ASPA comment has been updated"},customer_validation_format:"The customer format is invalid or already exists",providers_validation_format:"The providers format is invalid",add:"Add ASPA",edit:"Edit ASPA",analyse:"Analyse providers",detected_providers:"Declared providers",providers_missing:"ASNs observed in RIS but not in the provider list. Please verify that none of these ASNs act as your provider.",no_aspas:"Krill did not find any ASNs. You need an ASN to be able to create an ASPA for it."},announcements:{noRoasOrAnnouncements:"ROAs no encontrados.",search:"Busquedas por ASNs, IPs o estados...",authorizes:" {number} anuncios autorizados",disallows:"{number} anuncios no autorizados",asn:"ASN",prefix:"Bloques IPs",stateLabel:"Estado",state:{roa_seen:"VISTO",roa_seen_help:"Este ROA se corresponde con los anuncios vistos en BGP",roa_unseen:"NO VISTO",roa_unseen_help:"No vemos que existan anuncios BGP que se correspondan con este ROA",roa_not_held:"PREFIJO ELIMINADO",roa_not_held_help:"El prefijo ya no se encuentra en sus certificado(s). Los ROAs correspondientes no serán publicados",roa_no_announcement_info:"NO HAY INFORMACIÓN DEL ANUNCIO",roa_too_permissive:"DEMASIADO PERMISIVO",roa_too_permissive_help:"Este ROA se corresponde con anuncios vistos en BGP pero tambien permite anuncios invisibles.",roa_disallowing:"PROHIBIENDO",roa_disallowing_help:"Este ROA únicamente prohibe anuncios. Si esto es intencional, quizás le sea mejor utililizar AS0.",roa_redundant:"REDUNDANTE",roa_redundant_help:"Este ROA es redundante porque existen uno o mas ROAs que ya cubren esta combinación de prefijo, largo y ASN de origen.",roa_as0:"AS0",roa_as0_help:"Este ROA perimte inhabilitar todo anuncio para un prefijo.",roa_as0_redundant:"REDUNDANTE",roa_as0_redundant_help:"Este ROA con AS0 es redundante porque ya existen uno o mas ROAs que cubren este prefijo.",announcement_not_found:"NO ENCONTRADO",announcement_not_found_help:"Este anuncio no está cubierto por ninguno de sus ROAs",announcement_invalid_length:"LARGO INVÁLIDO",announcement_invalid_length_help:"Este anuncio no es permitido debido a ser mas especifico que el prefijo y el largo máximo autorizado para este ASN",announcement_invalid_asn:"ASN INVÁLIDO",announcement_invalid_asn_help:"Este anuncio no es permitido debido a que el anuncio esta permitido solamente desde otro ASN",announcement_disallowed:"DISALLOWED BY AS0",announcement_disallowed_help:"This announcement is not allowed because you have an AS0 ROA that disallows it"},download:"Descargar como CSV"},deltaErrors:{duplicates:"Duplicados",covered:"Cubierto",notheld:"Notheld",unknowns:"Desconocidos",invalid_length:"Largo inválido",covering:"Covertura",as0_exists:"Existe un AS0",as0_overlaps:"Existe un AS0 superpuesto"},errors:{repo_not_set:"Primero debe configurar su repositorio",pub_unknown:"El publicador '{publisher}' es desconocido",pub_duplicate:"El publicador '{publisher}' ya se inicializó",pub_outside_jail:"Publicador uri '{uri}' fuera del repositorio uri '{sia_base}'",pub_uri_no_slash:"El publicador uri '{uri}' debe tener una barra diagonal al final",pub_no_embedded_repo:"No se configuró ningún repositorio integrado",ca_duplicate:"La CA '{ca}' ya se inicializó",ca_unknown:"La CA '{ca}' es desconocida",ca_repo_same:"Este repositorio ya está en uso",ca_repo_issue:"Se recibió un error del repositorio: {cause}",ca_repo_response_invalid_xml:"Se obtuvo un response xml inválido del repositorio",ca_repo_response_wrong_xml:"Se obtuvo una respuesta de padre, no de repositorio",ca_parent_duplicate:"Ya tiene un padre con el nombre '{parent}'",ca_parent_xml_duplicate:"Esta respuesta ya esta siendo utilizada por un padre llamado '{parent}'",ca_parent_unknown:"No tiene ningún padre con el nombre '{parent}'",ca_parent_issue:"Se recibió un error del padre '{parent}': {cause}",ca_parent_response_invalid_xml:"Se obtuvo un response xml inválido del padre",ca_parent_response_wrong_xml:"Se obtuvo una respuesta del repositorio al agregar el padre",ca_child_duplicate:"Ya tiene una CA hijo con el nombre '{child}'",ca_child_unknown:"No tiene ninguna CA hijo con el nombre '{child}'",ca_child_resources_required:"Debe especificar los recursos para la CA hijo '{child}'",ca_roa_unknown:"No se puede eliminar el ROA desconocido '{prefix}-{max_length} => {asn}'",ca_roa_duplicate:"ROA duplicado '{prefix}-{max_length} => {asn}'",ca_roa_invalid_max_length:"Largo máximo inválido en ROA '{prefix}-{max_length} => {asn}'",ca_roa_not_entitled:"El prefijo '{prefix}' contenido en el ROA no está en ninguno de sus certificados actuales",ta_not_allowed:"Esta funcionalidad no es compatible con el ancla de confianza de prueba",ta_name_reserved:"Nombre reservado",ca_roa_delta_error:"Este ROA ha sido rechazado debido a los siguientes errores",api_insufficient_rights:"Usted no posee privilegios suficientes para realizar esta accion. Ponganse en contacto con el administrador.",api_invalid_credentials:"Las credenciales suministradas son incorrectas.",api_login_error:"Ocurrio un error durante el proceso de login: {cause}",api_auth_transient_error:"Ocurrio un error (quizas temporario) mientras se autenticaba su solicitud. Por favor intente mas tarde.",api_auth_permanent_error:"Ocurrio un error mientras se intentaba autenticar su solicitud. Pongase en contacto con el administrador.",api_auth_session_expired:"Su sesion ha caducado. Por favor ingrese nuevamente..",general_error:"Ocurrio un error inesperado. Por favor pongase en contacto con el administrador."},testbed:{welcome:"Bienvenido a este testbed de RPKI",disclaimer:{heading:"Atencion",body:"Este testbed implementa una jerarquia de RPKI completamente independiente, la cual puede ser utilizada con propositos de expermientacion. En el se permite registrar cualquier recurso para ser utilizado por las CA hijas. No existen garantias acerca de la disponibilidad de este servicio. Si se encuentra con cualquier problema, por faovr haganoslo saber.."},rpconfighelp:{heading:"TAL del testbed.",body:"Para obtener los datos publicados en este testbed por favor descarge este Trust Anchor Locator (TAL) y configure su software de validacion para que lo utilice. Tenga en cuenta que usted NUNCA deberia utilizar este TAL en un ambiente de produccion. Solo se brinda este con objetivos de testeo."},regunreg:{heading:"Registrar/Deregistraro",body:"

Utilice este formulario para registrar su autoridad certificadora RPKI como hija de este testbed, paara que de esa manera usted pueda crear ROAs para los recursos que usted dice poseer.

Si no desea alojar sus propios repositorios rsync y RRDP repositories es posible utlizar el formulario de registro de publicadores para configurar publicacion para sus ROAs en el repositorio alojado por el testbed. Utilice el formulario de deregistro para dar de baja relaciones previamente establecidas. (incluso las de otros usuarios del testbed!).

"},rfcdoclink:"Haga click aqui para visualizar la documentacion de RFC-8183 de este XML.",childhandle:"Identificador (handle) del hijo",publisherhandle:"Identificador (handle) del publicador",responseXML:"Respuesta XML del Testbed",addChild:{heading:"Registrar CA",requestXML:{label:"XML de la solicitud del hijo.",placeholder:"Pegue su XML aqui"},asnresources:{label:"Recursos ASN",placeholder:"Los bloques de ASN: p.ej. AS1, AS3-4"},ipv4resources:{label:"Recrusos IPv4",placeholder:"Los recursos IPv4: p.ej. 192.168.0.0/16"},ipv6resources:{label:"IPv6 Resources",placeholder:"Los recursos IPv6: p.ej. 2001:db8::/32"},confirm:"Registrar CA hija",format:"Este XML no es una solicitud de hijo valida.",required:"Por favor ingrese la solicitud en XML",confirmation:{title:"Atencion",message:"Esta seguro de que desea registrar este hijo con el testbed ? "},success:"La CA hija '{child_handle}' ha sido agregada al testbed.",registeranother:"Registrar otra CA"},removeChild:{heading:"Deregistrar CA",placeholder:"Ingrese el nobre de la CA que desea remover",confirm:"Elminiar CA hija",confirmation:{title:"Atencion",message:"Esta seguro de que desea deregistrar este hijo de este testbed?"},success:"La CA hija '{child_handle}' ha sido eliminada de este testbed."},addPublisher:{heading:"Registrar publicador",requestXML:{label:"XML de solicitud de publicador",placeholder:"Pegue su XML aqui"},confirm:"Registrar publicador",format:"Este no es un XML de solicitud de publicador valido.",required:"Por favor ingrese el XML de solicitud de publicador",confirmation:{title:"Atencion",message:"Esta seguro de que desea registrar este publicador con este testbed?"},success:"El publicador '{publisher_handle}' ha sido registrado en este testbed.",registeranother:"Registre otro publicador."},removePublisher:{heading:"De registrar publicador",placeholder:"Ingrese el nombre del publicador a remover",confirm:"Remove publisher",confirmation:{title:"Atencion",message:"Esta usted seguro de que quiere eliminar este publicador del testbed? "},success:"El publicador '{publisher_handle}' ha sido eliminado del testbed."},errors:{invalid_xml:"XML inválido: {err}",missing_xml_el:"Elemento ausente {el}",missing_xml_child_el:"Elemento hijo ausente {el} del elemento {parent}",missing_xml_attr:"Atributo ausente {attr} en el elemento {el}",empty_xml_el:"Elemento {el} no puede estar vacío",empty_xml_attr:"Atributo {attr} en el elemento {el} no puede estar vacío",non_ascii_xml_el:"Elemento {el} no puede contener caracteres no ASCII",child_handle_required:"El identificador del hijo es requerido",publisher_handle_required:"El identificador del publicador es requerido",non_base64_certificate_xml_el:"Elemento {el} debe contener un certificado X.509 BPKI auto firmado codificado correctamente en Base64",invalid_registration_data:"Los detalles de tu registro no pudieron ser analizados correctamente"}}};export{e as translations}; diff --git a/ui/assets/es-bf4361b1.js b/ui/assets/es-bf4361b1.js deleted file mode 100644 index 36d1301b..00000000 --- a/ui/assets/es-bf4361b1.js +++ /dev/null @@ -1 +0,0 @@ -const e={common:{readthedocs:"Leer los documentos",report:"Reportar un problema",confirm:"Confirmar",cancel:"Cancelar",ok:"OK",error:"Error",success:"Éxito!",copy:"Copiar al portapapeles",download:"Descargar",dropOrClick:"Colocar el archivo aquí o hacer clic para cargarlo",started:"Krill está corriendo desde",newversion:"¡Hay una nueva versión disponible!",supportcontracts:"Contratos de soporte y mantenimiento",warning:"Advertencia",idle:"Tu sesion ha caducado debido a inactividad.",nodata:"Sin datos",copySuccess:"El XML se copió a su portapapeles",edit:"Edit",page:"page",userInfo:{title:"Login Details",user:"User"}},login:{password:"Contraseña",placeholder:"Su contraseña",signin:"Iniciar sesión",required:"Ingrese su contraseña",error:"La contraseña que ingresó es incorrecta",copied:"NO deberías crear tus claves como en https://xkcd.com/936/",id:"Nombre de usuario",idPlaceholder:"Su nombre de usuario",idRequired:"Por favor ingrese su nombre de usuario",retry:"Haga click en {0} para volver a la pagina de login.",here:"aqui"},onboarding:{welcome:"Bienvenido a Krill",welcomeHtml:"Empecemos por crear su Autoridad de Certificación (CA) RPKI. Esta se usará para configurar el RPKI Delegado con una o múltiples CA padre, generalmente su Registro Regional o Nacional de Internet.

El identificador que escoja identificará a su CA en sus interacciones con las CA padres e hijos. No se publicará en el RPKI. Escoja un identificador que ayude a los demás a reconocer a su organización. Una vez guardado, el identificador no se puede cambiar. Más información...",addCAForm:{required:"Este campo es obligatorio",format:"Este no es un nombre de CA válido",confirm:"Crear CA",confirmation:{title:"Advertencia",message:"Una vez guardado, el identificador no se puede cambiar. żDesea continuar?"}}},cas:{loading:"Cargando Autoridades de Certificación",ca:"Autoridad de Certificación",cas:"Autoridades de Certificación",search:"Buscar CAs...",noCas:"No hay ninguna autoridad de certificación definida."},caDetails:{loading:"Cargando {handle}",refresh:"Actualizando {handle}, esto puede tomar varios minutos",current:"Autoridad de Certificación actual",download:"Descargar PEM",noRoas:"No se encontró ningún ROA.",noResources:"Todavía no ha recibido ningún recurso",noChildren:"No se encontraron hijos.",addRoa:"Agregar ROA",addAspa:"Add ASPA",editAspa:"Edit ASPA",roas:"ROAs",aspas:"ASPAs",resources:"Recursos",parents:"Padres",repo:"Repositorio",type:"Tipo",properties:"Propiedades",property:"Propiedad",value:"Valor",kind:"Clase",resource:"Recurso",children:"Hijos",handle:"Identificador",comment:"Comentario",maxLength:"Largo máx",maxLengthTooltip:"Si el largo máximo no es especificado, se toma por defecto el largo del prefijo.",confirmation:{title:"Advertencia",message:"Esto eliminará el ROA '{prefix}-{max_length} => {asn}'. żDesea continuar?",added:"ROA agregado",retired:"ROA eliminado",retiredSuccess:"El ROA se ha eliminado",addedSuccess:"El ROA se ha agregado",commentUpdatedSuccess:"El comentario del ROA se ha actualizado"},addROAForm:{required:"Este campo es obligatorio",asn_format:"Este no es un ASN válido",prefix_format:"Ingrese un prefijo IPv4 o IPv6 válido"},onboardingWarning:"Deberá conectar su CA a un repositorio RPKI público donde pueda publicar su certificado y sus ROA. Tan pronto como se complete la configuración del padre, el software de validación comenzará a recuperar su certificado y los ROA que cree a partir de este repositorio.",initializeRepository:"Es necesario configurar un repositorio para su CA antes que pueda solicitar certificado(s) de recursos a su padre(s)",initialize:"Primero inicialice el repositorio RPKI y/o el padre.",noResourcesYet:"Todavía no ha recibido ningún recurso",clickToRefresh:"Haga clic aquí para actualizar",parentsTab:{request:"Solicitud padre",response:"Respuesta padre",addParent:"Agregar otro padre",addParentSuccess:"Se agregó el padre",name:"Nombre del padre",namerequired:"El nombre del padre es un dato necesario",nameformat:"Este nombre de padre no es válido"},repoTab:{request:"Solicitud repositorio",response:"Respuesta repositorio",addRepo:"Agregar repositorio",addRepoSuccess:"Se agregó el repositorio"},analyseThis:"Análisis de mis ROAs",analysis:"Análisis de ROAs",suggestions:{following:"Por favor verifique que estos cambios a sus ROAs sean correctos.",readMore:"Read more..",nochanges:"No encontramos cambios a sugerir en este momento",adding:"Agregando",removing:"Eliminando ROA",keep:"Mantener todo en su estado actual.",willResult:"Producirá",yourChoice:"Su selección",ourSuggestion:"Nuestra sugerencias",ourSuggestionHelp:"Nuestras sugerencias se basan en los datos de tablas de enrutamiento de RIPE RIS, ¡ por favor verifique esto sea correcto !",addThis:"Agregar esto",removeThis:"Eliminar esto",willAdd:"Agregaremos este ROA",willRemove:"Eliminaremos este ROA",reasons:{not_found:"No encontrado",not_held:"El prefijo ya no se encuentra en sus certificado(s). Los ROAs correspondientes no serán publicados",invalid_asn:"ASN Invalido",invalid_length:"Largo de prefijo inválido",stale:"rancio/viejo",disallowing:"Este ROA prohibe todo anuncio y no autoriza ninguno. ¿Quizá sería mejor utilizar AS0?",as0_redundant:"Redundante en AS0",redundant:"Redundante",too_permissive:"Demasiado permisivo",specific:"Permitir anuncios muy específicos en un ROA puede ser demasiado permisivo.",new:"Nuevo"}},syncParents:"Refrescar padres",syncRepo:"Refrescar respositorios",lastExchange:"Último intercambio",exchangeUri:"URI",nextExchange:"Próximo intercambio antes de",allResources:"Todos los recursos",entitlements:"Derechos de uso",showEntitlements:"Mostrar detalle sobre los derechos de uso",parentCertificate:"Certificado padre",published:"Publicado"},aspas:{customer:"Customer",providers:"Providers",search:"Search for customer, provider...",confirmation:{title:"Warning",message:"This will remove the ASPA '{customer} => {providers}'. Continue?",added:"ASPA added",retired:"ASPA removed",retiredSuccess:"The ASPA has been removed",addedSuccess:"The ASPA has been added",commentUpdatedSuccess:"The ASPA comment has been updated"},customer_validation_format:"The customer format is invalid or already exists",providers_validation_format:"The providers format is invalid"},announcements:{noRoasOrAnnouncements:"ROAs no encontrados.",search:"Busquedas por ASNs, IPs o estados...",authorizes:" {number} anuncios autorizados",disallows:"{number} anuncios no autorizados",asn:"ASN",prefix:"Bloques IPs",stateLabel:"Estado",state:{roa_seen:"VISTO",roa_seen_help:"Este ROA se corresponde con los anuncios vistos en BGP",roa_unseen:"NO VISTO",roa_unseen_help:"No vemos que existan anuncios BGP que se correspondan con este ROA",roa_not_held:"PREFIJO ELIMINADO",roa_not_held_help:"El prefijo ya no se encuentra en sus certificado(s). Los ROAs correspondientes no serán publicados",roa_no_announcement_info:"NO HAY INFORMACIÓN DEL ANUNCIO",roa_too_permissive:"DEMASIADO PERMISIVO",roa_too_permissive_help:"Este ROA se corresponde con anuncios vistos en BGP pero tambien permite anuncios invisibles.",roa_disallowing:"PROHIBIENDO",roa_disallowing_help:"Este ROA únicamente prohibe anuncios. Si esto es intencional, quizás le sea mejor utililizar AS0.",roa_redundant:"REDUNDANTE",roa_redundant_help:"Este ROA es redundante porque existen uno o mas ROAs que ya cubren esta combinación de prefijo, largo y ASN de origen.",roa_as0:"AS0",roa_as0_help:"Este ROA perimte inhabilitar todo anuncio para un prefijo.",roa_as0_redundant:"REDUNDANTE",roa_as0_redundant_help:"Este ROA con AS0 es redundante porque ya existen uno o mas ROAs que cubren este prefijo.",announcement_not_found:"NO ENCONTRADO",announcement_not_found_help:"Este anuncio no está cubierto por ninguno de sus ROAs",announcement_invalid_length:"LARGO INVÁLIDO",announcement_invalid_length_help:"Este anuncio no es permitido debido a ser mas especifico que el prefijo y el largo máximo autorizado para este ASN",announcement_invalid_asn:"ASN INVÁLIDO",announcement_invalid_asn_help:"Este anuncio no es permitido debido a que el anuncio esta permitido solamente desde otro ASN",announcement_disallowed:"DISALLOWED BY AS0",announcement_disallowed_help:"This announcement is not allowed because you have an AS0 ROA that disallows it"},download:"Descargar como CSV"},deltaErrors:{duplicates:"Duplicados",covered:"Cubierto",notheld:"Notheld",unknowns:"Desconocidos",invalid_length:"Largo inválido",covering:"Covertura",as0_exists:"Existe un AS0",as0_overlaps:"Existe un AS0 superpuesto"},errors:{repo_not_set:"Primero debe configurar su repositorio",pub_unknown:"El publicador '{publisher}' es desconocido",pub_duplicate:"El publicador '{publisher}' ya se inicializó",pub_outside_jail:"Publicador uri '{uri}' fuera del repositorio uri '{sia_base}'",pub_uri_no_slash:"El publicador uri '{uri}' debe tener una barra diagonal al final",pub_no_embedded_repo:"No se configuró ningún repositorio integrado",ca_duplicate:"La CA '{ca}' ya se inicializó",ca_unknown:"La CA '{ca}' es desconocida",ca_repo_same:"Este repositorio ya está en uso",ca_repo_issue:"Se recibió un error del repositorio: {cause}",ca_repo_response_invalid_xml:"Se obtuvo un response xml inválido del repositorio",ca_repo_response_wrong_xml:"Se obtuvo una respuesta de padre, no de repositorio",ca_parent_duplicate:"Ya tiene un padre con el nombre '{parent}'",ca_parent_xml_duplicate:"Esta respuesta ya esta siendo utilizada por un padre llamado '{parent}'",ca_parent_unknown:"No tiene ningún padre con el nombre '{parent}'",ca_parent_issue:"Se recibió un error del padre '{parent}': {cause}",ca_parent_response_invalid_xml:"Se obtuvo un response xml inválido del padre",ca_parent_response_wrong_xml:"Se obtuvo una respuesta del repositorio al agregar el padre",ca_child_duplicate:"Ya tiene una CA hijo con el nombre '{child}'",ca_child_unknown:"No tiene ninguna CA hijo con el nombre '{child}'",ca_child_resources_required:"Debe especificar los recursos para la CA hijo '{child}'",ca_roa_unknown:"No se puede eliminar el ROA desconocido '{prefix}-{max_length} => {asn}'",ca_roa_duplicate:"ROA duplicado '{prefix}-{max_length} => {asn}'",ca_roa_invalid_max_length:"Largo máximo inválido en ROA '{prefix}-{max_length} => {asn}'",ca_roa_not_entitled:"El prefijo '{prefix}' contenido en el ROA no está en ninguno de sus certificados actuales",ta_not_allowed:"Esta funcionalidad no es compatible con el ancla de confianza de prueba",ta_name_reserved:"Nombre reservado",ca_roa_delta_error:"Este ROA ha sido rechazado debido a los siguientes errores",api_insufficient_rights:"Usted no posee privilegios suficientes para realizar esta accion. Ponganse en contacto con el administrador.",api_invalid_credentials:"Las credenciales suministradas son incorrectas.",api_login_error:"Ocurrio un error durante el proceso de login: {cause}",api_auth_transient_error:"Ocurrio un error (quizas temporario) mientras se autenticaba su solicitud. Por favor intente mas tarde.",api_auth_permanent_error:"Ocurrio un error mientras se intentaba autenticar su solicitud. Pongase en contacto con el administrador.",api_auth_session_expired:"Su sesion ha caducado. Por favor ingrese nuevamente..",general_error:"Ocurrio un error inesperado. Por favor pongase en contacto con el administrador."},testbed:{welcome:"Bienvenido a este testbed de RPKI",disclaimer:{heading:"Atencion",body:"Este testbed implementa una jerarquia de RPKI completamente independiente, la cual puede ser utilizada con propositos de expermientacion. En el se permite registrar cualquier recurso para ser utilizado por las CA hijas. No existen garantias acerca de la disponibilidad de este servicio. Si se encuentra con cualquier problema, por faovr haganoslo saber.."},rpconfighelp:{heading:"TAL del testbed.",body:"Para obtener los datos publicados en este testbed por favor descarge este Trust Anchor Locator (TAL) y configure su software de validacion para que lo utilice. Tenga en cuenta que usted NUNCA deberia utilizar este TAL en un ambiente de produccion. Solo se brinda este con objetivos de testeo."},regunreg:{heading:"Registrar/Deregistraro",body:"

Utilice este formulario para registrar su autoridad certificadora RPKI como hija de este testbed, paara que de esa manera usted pueda crear ROAs para los recursos que usted dice poseer.

Si no desea alojar sus propios repositorios rsync y RRDP repositories es posible utlizar el formulario de registro de publicadores para configurar publicacion para sus ROAs en el repositorio alojado por el testbed. Utilice el formulario de deregistro para dar de baja relaciones previamente establecidas. (incluso las de otros usuarios del testbed!).

"},rfcdoclink:"Haga click aqui para visualizar la documentacion de RFC-8183 de este XML.",childhandle:"Identificador (handle) del hijo",publisherhandle:"Identificador (handle) del publicador",responseXML:"Respuesta XML del Testbed",addChild:{heading:"Registrar CA",requestXML:{label:"XML de la solicitud del hijo.",placeholder:"Pegue su XML aqui"},asnresources:{label:"Recursos ASN",placeholder:"Los bloques de ASN: p.ej. AS1, AS3-4"},ipv4resources:{label:"Recrusos IPv4",placeholder:"Los recursos IPv4: p.ej. 192.168.0.0/16"},ipv6resources:{label:"IPv6 Resources",placeholder:"Los recursos IPv6: p.ej. 2001:db8::/32"},confirm:"Registrar CA hija",format:"Este XML no es una solicitud de hijo valida.",required:"Por favor ingrese la solicitud en XML",confirmation:{title:"Atencion",message:"Esta seguro de que desea registrar este hijo con el testbed ? "},success:"La CA hija '{child_handle}' ha sido agregada al testbed.",registeranother:"Registrar otra CA"},removeChild:{heading:"Deregistrar CA",placeholder:"Ingrese el nobre de la CA que desea remover",confirm:"Elminiar CA hija",confirmation:{title:"Atencion",message:"Esta seguro de que desea deregistrar este hijo de este testbed?"},success:"La CA hija '{child_handle}' ha sido eliminada de este testbed."},addPublisher:{heading:"Registrar publicador",requestXML:{label:"XML de solicitud de publicador",placeholder:"Pegue su XML aqui"},confirm:"Registrar publicador",format:"Este no es un XML de solicitud de publicador valido.",required:"Por favor ingrese el XML de solicitud de publicador",confirmation:{title:"Atencion",message:"Esta seguro de que desea registrar este publicador con este testbed?"},success:"El publicador '{publisher_handle}' ha sido registrado en este testbed.",registeranother:"Registre otro publicador."},removePublisher:{heading:"De registrar publicador",placeholder:"Ingrese el nombre del publicador a remover",confirm:"Remove publisher",confirmation:{title:"Atencion",message:"Esta usted seguro de que quiere eliminar este publicador del testbed? "},success:"El publicador '{publisher_handle}' ha sido eliminado del testbed."},errors:{invalid_xml:"XML inválido: {err}",missing_xml_el:"Elemento ausente {el}",missing_xml_child_el:"Elemento hijo ausente {el} del elemento {parent}",missing_xml_attr:"Atributo ausente {attr} en el elemento {el}",empty_xml_el:"Elemento {el} no puede estar vacío",empty_xml_attr:"Atributo {attr} en el elemento {el} no puede estar vacío",non_ascii_xml_el:"Elemento {el} no puede contener caracteres no ASCII",child_handle_required:"El identificador del hijo es requerido",publisher_handle_required:"El identificador del publicador es requerido",non_base64_certificate_xml_el:"Elemento {el} debe contener un certificado X.509 BPKI auto firmado codificado correctamente en Base64",invalid_registration_data:"Los detalles de tu registro no pudieron ser analizados correctamente"}}};export{e as translations}; diff --git a/ui/assets/fr-87fd8a67.js b/ui/assets/fr-87fd8a67.js new file mode 100644 index 00000000..7012e111 --- /dev/null +++ b/ui/assets/fr-87fd8a67.js @@ -0,0 +1 @@ +const e={common:{readthedocs:"Read the Docs",report:"Signaler un problème",confirm:"Confirmer",cancel:"Annuler",ok:"OK",error:"Erreur",success:"Succès!",copy:"Copier dans le presse-papier",download:"Télécharger",dropOrClick:"Déposer le fichier ici ou cliquer pour téléverser",started:"Krill est en cours d'exécution depuis",newversion:"Nouvelle version disponible!",supportcontracts:"Contrats de support et de maintenance",warning:"Attention",idle:"Vous avez été déconnecté de suite d'inactivité.",nodata:"No data",copySuccess:"XML copié dans votre presse-papier",edit:"Edit",page:"page",userInfo:{title:"Login Details",user:"User"}},login:{password:"Mot de passe",placeholder:"Votre mot de passe",signin:"S'authentifier",required:"SVP entrez votre mot de passe",error:"Le mot de passe spécifié est incorrect",copied:"Vous ne devriez pas obtenir votre mot de passe depuis https://xkcd.com/936/",id:"Nom d'utilisateur",idPlaceholder:"Votre nom d'utilisateur",idRequired:"Veuillez entrer votre nom d'utilisateur",retry:"Cliquer {0} pour revenir à la page de connexion.",here:"ici"},onboarding:{welcome:"Bienvenue sur Krill",welcomeHtml:"Commençons par créer votre propre Autorité de Certification RPKI (AC). Elle sera utilisée pour configurer la délégation RPKI avec une ou plusieurs ACs parent; le plus souvent votre Registre Internet Régional ou National.

L'identifiant que vous choisirez sera utilisé pour identifier votre AC lors des interactions avec le parent et les ACs enfant. Il ne sera pas publié dans le système RPKI. S'il vous plaît choisissez un identifiant qui permettra aux autres à reconnaître votre organisation. Une fois défini, votre identifiant ne pourra plus être changé.",addCAForm:{required:"Ce champ est requis",format:"Ce n'est pas un nom d'AC valide",confirm:"Créez une AC",confirmation:{title:"Attention",message:"Une fois défini, l'identifiant ne pourra être changé. Continuer?"}}},cas:{loading:"Chargement en cours des Autorités de Certification",ca:"Autorité de certification",cas:"Autorités de certification",search:"Recherche d'ACs...",noCas:"Il n'y a pas d'Autorités de Certifications définies actuellement."},caDetails:{loading:"En cours de chargement {handle}",refresh:"Rafraichissement de {handle}, ceci peut prendre plusieurs minutes",current:"Autorité de Certification actuelle",download:"Télécharger le PEM",noRoas:"Pas de ROAs trouvé.",noResources:"Vous n'avez pas encore reçu de ressources",noChildren:"Pas d'enfant trouvé.",addRoa:"Ajouter un ROA",addAspa:"Add ASPA",editAspa:"Edit ASPA",roas:"ROAs",aspas:"ASPAs",resources:"Ressources",parents:"Parents",repo:"Dépôt",type:"Type",properties:"Propriétés",property:"Propriété",value:"Valeur",kind:"Genre",resource:"Ressource",children:"Enfant",handle:"Identifiant",comment:"Commentaire",maxLength:"Longueur maximum",maxLengthTooltip:"Si la longueur maximum n'est pas spécifiée, elle sera initialisée à la longueur du préfixe.",confirmation:{title:"Attention",message:"Cette action va enlever le ROA '{prefix}-{max_length} => {asn}'. Continuez?",added:"ROA ajouté",retired:"ROA enlevé",retiredSuccess:"Le ROA a été enlevé",addedSuccess:"Le ROA a été ajouté",commentUpdatedSuccess:"Le commentaire ROA a été mis à jour"},addROAForm:{required:"Ce champ est requis",asn_format:"Ceci n'est pas un ASN valide",prefix_format:"SVP entrez un préfixe IPv4 ou IPv6 valide"},onboardingWarning:"Veuillez connecter votre AC à un dépôt RPKI publique pour publier votre certificat et vos ROAs. Dès que la configuration côté parent est complète, le 'relying party' (logiciel validateur) commencera immédiatement à récupérer votre certificat et les ROAs que vous avez créés depuis ce dépôt.",initializeRepository:"Vous devez toujours configurer un entrepôt pour votre AC avant de pouvoir demander un ou plusieurs certificats de ressources à votre parent.",initialize:"SVP initialisez le dépôt RPKI et/ou le parent en premier lieu.",noResourcesYet:"Vous n'avez pas encore reçu de ressources",clickToRefresh:"Cliquer ici pour rafraîchir",parentsTab:{request:"Requête enfant",response:"Réponse du parent",addParent:"Ajouter un autre parent",addParentSuccess:"Parent ajouté",name:"Nom du parent",namerequired:"Le nom du parent est requis",nameformat:"Nom de parent invalide"},repoTab:{request:"Requête du Publisher",response:"Réponse du dépôt",addRepo:"Ajouter un dépôt",addRepoSuccess:"Dépôt ajouté"},analyseThis:"Analyser mes ROAs",analysis:"Analyse des ROA",suggestions:{following:"Veuillez vérifier les changements proposés de vos ROAs",readMore:"Read more..",nochanges:"Nous ne suggérons aucun changement pour le moment",adding:"En cours d'ajout",removing:"Retirer le ROA",keep:"Aucun changement",willResult:"Résultera en",yourChoice:"Votre choix",ourSuggestion:"Notre Suggestion",ourSuggestionHelp:"Notre suggestion est basée sur les informations de routage de RIPE RIS, veuillez svp vérifier !!",addThis:"Ajouter ceci",removeThis:"Retirer ceci",willAdd:"Ajoutera ce ROA",willRemove:"Retirera ce ROA",reasons:{not_found:"Pas trouvé",not_held:"ROA cannot be published, its prefix is no longer on your certificate(s)",invalid_asn:"ASN invalide",invalid_length:"longueur invalide",stale:"Obsolète",disallowing:"Ce ROA invalide les annonces mais en autorise aucun. Considérez un AS0 à la place?",as0_redundant:"AS0 redondant",redundant:"Redondant",too_permissive:"Trop permissif",specific:"Autoriser une annonce spécifique dans un ROA qui pourrait être trop permissif",new:"Nouveau"}},syncParents:"Rafraîchir les Parents",syncRepo:"Rafraîchir le Dépôt",lastExchange:"Dernier Échange",exchangeUri:"URI",nextExchange:"Dernier Échange Avant",allResources:"Toutes les Ressources",entitlements:"Ressources Dues",showEntitlements:"Montrer les Ressources Dues en détail",parentCertificate:"Certificat Parent",published:"Publié"},aspas:{customer:"Customer",providers:"Providers",search:"Search for customer, provider...",confirmation:{title:"Warning",message:"This will remove the ASPA '{customer} => {providers}'. Continue?",added:"ASPA added",retired:"ASPA removed",retiredSuccess:"The ASPA has been removed",addedSuccess:"The ASPA has been added",commentUpdatedSuccess:"The ASPA comment has been updated"},customer_validation_format:"The customer format is invalid or already exists",providers_validation_format:"The providers format is invalid",add:"Add ASPA",edit:"Edit ASPA",analyse:"Analyse providers",detected_providers:"Declared providers",providers_missing:"ASNs observed in RIS but not in the provider list. Please verify that none of these ASNs act as your provider.",no_aspas:"Krill did not find any ASNs. You need an ASN to be able to create an ASPA for it."},announcements:{noRoasOrAnnouncements:"Aucun ROAs ou Annonces trouvés.",search:"Rechercher un ASN, préfixe, statut...",authorizes:"Autoriser {number} annonces",disallows:"Refuser {number} annonces",asn:"ASN",prefix:"Préfixe",stateLabel:"Statut",state:{roa_seen:"TROUVÉ",roa_seen_help:"Ce ROA correspond aux annonces vues dans BGP",roa_unseen:"INTROUVABLE",roa_unseen_help:"Aucune annonce BGP correspondant à ce ROA trouvée",roa_not_held:"PREFIX REMOVED",roa_not_held_help:"The prefix is no longer on your certificate(s), the ROA will not be published",roa_no_announcement_info:"AUCUNE INFORMATION D'ANNONCE",roa_too_permissive:"TROP PERMISSIF",roa_too_permissive_help:"Ce ROA correspond aux annonces en BGP, mais aussi à des annonces introuvables",roa_disallowing:"INVALIDANT",roa_disallowing_help:"Ce ROA invalide les annonces seulement. Si c’est intentionnel, vous devriez plutôt utiliser un AS0 à la place",roa_redundant:"REDONDANT",roa_redundant_help:"Ce ROA est redondant parce qu’il y a au moins un ROA existant qui couvre ce préfixe, longueur et numéro d'AS",roa_as0:"AS0",roa_as0_help:"Ce ROA sert à invalider toutes les annonces pour un préfixe",roa_as0_redundant:"REDONDANT",roa_as0_redundant_help:"Ce ROA AS0 est redondant parce qu’il y a au moins un ROA existant qui couvre ce préfixe",announcement_not_found:"NON TROUVÉ",announcement_not_found_help:"Cette announce n'est couverte par aucun de vos ROAs",announcement_invalid_length:"LONGUEUR INVALIDE",announcement_invalid_length_help:"Cette annonce n'est pas permise parce qu'elle est plus spécifique que la longueur du préfixe et la taille maximum autorisées pour cet ASN",announcement_invalid_asn:"ASN INVALIDE",announcement_invalid_asn_help:"Cette annonce n'est pas permise parce que vous autorisez seulement le préfixe depuis un autre ASN",announcement_disallowed:"DISALLOWED BY AS0",announcement_disallowed_help:"This announcement is not allowed because you have an AS0 ROA that disallows it"},download:"Télécharger le fichier au format CSV"},deltaErrors:{duplicates:"Doublons",covered:"Couvert",notheld:"Pas Considéré",unknowns:"Inconnus",invalid_length:"Longueur Invalide",covering:"Recouvrant",as0_exists:"AS0 Existe",as0_overlaps:"Chevauchement du AS0"},errors:{repo_not_set:"Vous devez d'abord configurer un dépôt",pub_unknown:"Publisher '{publisher}' est inconnu",pub_duplicate:"Publisher '{publisher}' était déjà initialisé",pub_outside_jail:"Publisher uri '{uri}' en dehors du dépôt uri '{sia_base}'",pub_uri_no_slash:"Publisher uri '{uri}' doit avoir une barre oblique à la fin",pub_no_embedded_repo:"Pas de dépôt imbriqué configuré",ca_duplicate:"AC '{ca}' déjà initialisée",ca_unknown:"AC '{ca}' est inconnue",ca_repo_same:"Ce dépôt est déjà utilisé",ca_repo_issue:"Erreur provenant du dépôt: {cause}",ca_repo_response_invalid_xml:"Réponse xml du dépôt invalide",ca_repo_response_wrong_xml:"Réponse du parent reçue au lieu du dépôt",ca_parent_duplicate:"Vous avez déjà un parent nommé '{parent}'",ca_parent_xml_duplicate:"Cette réponse est déjà utilisée par le parent '{parent}'",ca_parent_unknown:"Vous n'avez pas un parent nommé '{parent}'",ca_parent_issue:"Erreur reçue du parent '{parent}': {cause}",ca_parent_response_invalid_xml:"Réponse xml du parent invalide",ca_parent_response_wrong_xml:"Réponse du dépôt obtenue lors de l'ajout du parent",ca_child_duplicate:"Vous avez déjà une AC enfant nommée '{child}'",ca_child_unknown:"Vous n'avez pas une AC enfant nommée '{child}'",ca_child_resources_required:"Vous devez spécifier les ressources pour l'AC enfant '{child}'",ca_roa_unknown:"Impossible d'enlever un ROA inconnu '{prefix}-{max_length} => {asn}'",ca_roa_duplicate:"ROA en doublon '{prefix}-{max_length} => {asn}'",ca_roa_invalid_max_length:"Longueur max invalide dans le ROA '{prefix}-{max_length} => {asn}'",ca_roa_not_entitled:"Le préfixe du ROA '{prefix}' ne figure dans aucun de vos certificats actuels",ta_not_allowed:"Cette fonctionnalité n'est pas supportée par l'ancre de confiance de test",ta_name_reserved:"Nom reservé",ca_roa_delta_error:"ROA rejeté pour la/les raison(s) suivante(s)",api_insufficient_rights:"Votre utilisateur n'a pas les droits suffisants pour effectuer cette action.",api_invalid_credentials:"Les identifiants fournis sont invalides.",api_login_error:"Une erreur est survenue pendant votre connexion: {cause}",api_auth_transient_error:"Une erreur temporaire est survenue pendant votre connexion. Veuillez essayer à nouveau dans quelques instants",api_auth_permanent_error:"Une erreur est survenue pendant l'authentification de votre connexion. Veuillez contacter votre administrateur.",api_auth_session_expired:"Votre session a expirée,",general_error:"Une erreur est survenue. Veuillez contacter votre administrateur."},testbed:{welcome:"Bienvenue sur ce banc d'essai pour RPKI",disclaimer:{heading:"Avertissement",body:"Ce banc d'essai offre une hiérarchie complètement différente pour RPKI; il peut être utilisé pour des besoins d'évaluation. Il vous permet d'inscrire n'importe quelles ressources pour votre AC enfant. Aucune garantie n'est donnée concernant la disponibilité de ce service. Si vous décelez un problème, merci de nous le faire savoir."},rpconfighelp:{heading:"Banc d'essai TAL",body:"Pour récupérer les données publiées par ce banc d'essai, veuillez svp télécharger ce Trust Anchor Locator (TAL) et le configurer dans votre logiciel validateur, le Relying Pary. Noter que vous ne devriez JAMAIS utiliser ce TAL dans un environnement de production. Il est mis à disposition uniquement pour des tests."},regunreg:{heading:"Inscrire/Désinscrire",body:"

Utiliser le formulaire pour inscrire votre autorité de certification RPKI comme un enfant de ce banc d'essai ainsi vous pourrez créer les 'Route Origin Authorisations' (ROAs) pour les resources que vous revendiquez.

Si vous ne voulez pas héberger vos propres dépôts Rsync et RRDP vous pouvez utiliser le formulaire du Register Publisher pour configurer la publication de vos ROAs dans le dépôt hébergé par le banc d'essai. Utilisez les formulaires 'Se désinscrire' pour annuler les relations précédemment établies (même celles des autres utilisateurs du banc d'essai!).

"},rfcdoclink:"Cliquer pour voir la documentation de ce XML dans le RFC-8183",childhandle:"Identifiant enfant",publisherhandle:"Identifiant Publisher",responseXML:"réponse banc d'essai au format XML",addChild:{heading:"Inscrire l'AC",requestXML:{label:"Requête XML enfant",placeholder:"Coller votre XML ici"},asnresources:{label:"Ressources ASN",placeholder:"Les ressources AS: e.g. AS1, AS3-4"},ipv4resources:{label:"Ressources IPv4",placeholder:"Les ressources IPv4: e.g. 192.168.0.0/16"},ipv6resources:{label:"Ressources IPv6",placeholder:"Les ressources IPv6: e.g. 2001:db8::/32"},confirm:"Inscrire l'AC enfant",format:"Ce n'est pas une requête enfant XML valide",required:"Veuillez svp fournir la requête XML enfant",confirmation:{title:"Attention",message:"Êtes-vous sûr de vouloir inscrire cet enfant dans le banc d'essai ?"},success:"L'AC enfant '{child_handle}' a été ajoutée au banc d'essai.",registeranother:"Inscrire une autre AC"},removeChild:{heading:"Désinscrire l'AC",placeholder:"Entrer le nom de l'AC à retirer",confirm:"Retirer l'AC enfant",confirmation:{title:"Attention",message:"Êtes-vous sûr de vouloir désinscrire cet enfant du banc d'essai ?"},success:"L'AC enfant '{child_handle}' a été retirée du banc d'essai."},addPublisher:{heading:"Inscrire le Publisher",requestXML:{label:"Requête XML de type Publisher",placeholder:"Coller votre XML ici"},confirm:"Inscrire le Publisher",format:"Ceci n'est pas une requête XML de type Publisher valide",required:"Veuillez svp fournir la requête XML de type Publisher",confirmation:{title:"Attention",message:"Êtes-vous sûr de vouloir inscrire ce Publisher avec le banc d'essai?"},success:"Le Publisher '{publisher_handle}' a été ajouté au banc d'essai.",registeranother:"Inscrire un autre Publisher"},removePublisher:{heading:"Désinscrire le Publisher",placeholder:"Entrer le nom du Publisher à retirer",confirm:"Retirer le publisher",confirmation:{title:"Attention",message:"Etes-vous sûr de vouloir désinscrire ce Publisher avec le banc d'essai ?"},success:"Le Publisher '{publisher_handle}' a été retiré du banc d'essai."},errors:{invalid_xml:"XML invalide: {err}",missing_xml_el:"Element manquant {el}",missing_xml_child_el:"Elément enfant {el} de l'élément {parent} manquant",missing_xml_attr:"Attribut {attr} sur l'élement {el} manquant",empty_xml_el:"Elément {el} ne peut pas être vide",empty_xml_attr:"Attribut {attr} de l'élément {el} ne peut pas être vide",non_ascii_xml_el:"L'élement {el} ne peut pas contenir de caractères non-ASCII",child_handle_required:"L'identifiant Enfant est requis",publisher_handle_required:"L'identifiant Publisher est requis",non_base64_certificate_xml_el:"L'élement {el} doit contenir un certificat BKPI X.509 auto signé et correctement encodé en base64",invalid_registration_data:"Vos données d'inscription n'ont pas pu être analysées correctement"}}};export{e as translations}; diff --git a/ui/assets/fr-fd67af37.js b/ui/assets/fr-fd67af37.js deleted file mode 100644 index dda77a62..00000000 --- a/ui/assets/fr-fd67af37.js +++ /dev/null @@ -1 +0,0 @@ -const e={common:{readthedocs:"Read the Docs",report:"Signaler un problème",confirm:"Confirmer",cancel:"Annuler",ok:"OK",error:"Erreur",success:"Succès!",copy:"Copier dans le presse-papier",download:"Télécharger",dropOrClick:"Déposer le fichier ici ou cliquer pour téléverser",started:"Krill est en cours d'exécution depuis",newversion:"Nouvelle version disponible!",supportcontracts:"Contrats de support et de maintenance",warning:"Attention",idle:"Vous avez été déconnecté de suite d'inactivité.",nodata:"No data",copySuccess:"XML copié dans votre presse-papier",edit:"Edit",page:"page",userInfo:{title:"Login Details",user:"User"}},login:{password:"Mot de passe",placeholder:"Votre mot de passe",signin:"S'authentifier",required:"SVP entrez votre mot de passe",error:"Le mot de passe spécifié est incorrect",copied:"Vous ne devriez pas obtenir votre mot de passe depuis https://xkcd.com/936/",id:"Nom d'utilisateur",idPlaceholder:"Votre nom d'utilisateur",idRequired:"Veuillez entrer votre nom d'utilisateur",retry:"Cliquer {0} pour revenir à la page de connexion.",here:"ici"},onboarding:{welcome:"Bienvenue sur Krill",welcomeHtml:"Commençons par créer votre propre Autorité de Certification RPKI (AC). Elle sera utilisée pour configurer la délégation RPKI avec une ou plusieurs ACs parent; le plus souvent votre Registre Internet Régional ou National.

L'identifiant que vous choisirez sera utilisé pour identifier votre AC lors des interactions avec le parent et les ACs enfant. Il ne sera pas publié dans le système RPKI. S'il vous plaît choisissez un identifiant qui permettra aux autres à reconnaître votre organisation. Une fois défini, votre identifiant ne pourra plus être changé.",addCAForm:{required:"Ce champ est requis",format:"Ce n'est pas un nom d'AC valide",confirm:"Créez une AC",confirmation:{title:"Attention",message:"Une fois défini, l'identifiant ne pourra être changé. Continuer?"}}},cas:{loading:"Chargement en cours des Autorités de Certification",ca:"Autorité de certification",cas:"Autorités de certification",search:"Recherche d'ACs...",noCas:"Il n'y a pas d'Autorités de Certifications définies actuellement."},caDetails:{loading:"En cours de chargement {handle}",refresh:"Rafraichissement de {handle}, ceci peut prendre plusieurs minutes",current:"Autorité de Certification actuelle",download:"Télécharger le PEM",noRoas:"Pas de ROAs trouvé.",noResources:"Vous n'avez pas encore reçu de ressources",noChildren:"Pas d'enfant trouvé.",addRoa:"Ajouter un ROA",addAspa:"Add ASPA",editAspa:"Edit ASPA",roas:"ROAs",aspas:"ASPAs",resources:"Ressources",parents:"Parents",repo:"Dépôt",type:"Type",properties:"Propriétés",property:"Propriété",value:"Valeur",kind:"Genre",resource:"Ressource",children:"Enfant",handle:"Identifiant",comment:"Commentaire",maxLength:"Longueur maximum",maxLengthTooltip:"Si la longueur maximum n'est pas spécifiée, elle sera initialisée à la longueur du préfixe.",confirmation:{title:"Attention",message:"Cette action va enlever le ROA '{prefix}-{max_length} => {asn}'. Continuez?",added:"ROA ajouté",retired:"ROA enlevé",retiredSuccess:"Le ROA a été enlevé",addedSuccess:"Le ROA a été ajouté",commentUpdatedSuccess:"Le commentaire ROA a été mis à jour"},addROAForm:{required:"Ce champ est requis",asn_format:"Ceci n'est pas un ASN valide",prefix_format:"SVP entrez un préfixe IPv4 ou IPv6 valide"},onboardingWarning:"Veuillez connecter votre AC à un dépôt RPKI publique pour publier votre certificat et vos ROAs. Dès que la configuration côté parent est complète, le 'relying party' (logiciel validateur) commencera immédiatement à récupérer votre certificat et les ROAs que vous avez créés depuis ce dépôt.",initializeRepository:"Vous devez toujours configurer un entrepôt pour votre AC avant de pouvoir demander un ou plusieurs certificats de ressources à votre parent.",initialize:"SVP initialisez le dépôt RPKI et/ou le parent en premier lieu.",noResourcesYet:"Vous n'avez pas encore reçu de ressources",clickToRefresh:"Cliquer ici pour rafraîchir",parentsTab:{request:"Requête enfant",response:"Réponse du parent",addParent:"Ajouter un autre parent",addParentSuccess:"Parent ajouté",name:"Nom du parent",namerequired:"Le nom du parent est requis",nameformat:"Nom de parent invalide"},repoTab:{request:"Requête du Publisher",response:"Réponse du dépôt",addRepo:"Ajouter un dépôt",addRepoSuccess:"Dépôt ajouté"},analyseThis:"Analyser mes ROAs",analysis:"Analyse des ROA",suggestions:{following:"Veuillez vérifier les changements proposés de vos ROAs",readMore:"Read more..",nochanges:"Nous ne suggérons aucun changement pour le moment",adding:"En cours d'ajout",removing:"Retirer le ROA",keep:"Aucun changement",willResult:"Résultera en",yourChoice:"Votre choix",ourSuggestion:"Notre Suggestion",ourSuggestionHelp:"Notre suggestion est basée sur les informations de routage de RIPE RIS, veuillez svp vérifier !!",addThis:"Ajouter ceci",removeThis:"Retirer ceci",willAdd:"Ajoutera ce ROA",willRemove:"Retirera ce ROA",reasons:{not_found:"Pas trouvé",not_held:"ROA cannot be published, its prefix is no longer on your certificate(s)",invalid_asn:"ASN invalide",invalid_length:"longueur invalide",stale:"Obsolète",disallowing:"Ce ROA invalide les annonces mais en autorise aucun. Considérez un AS0 à la place?",as0_redundant:"AS0 redondant",redundant:"Redondant",too_permissive:"Trop permissif",specific:"Autoriser une annonce spécifique dans un ROA qui pourrait être trop permissif",new:"Nouveau"}},syncParents:"Rafraîchir les Parents",syncRepo:"Rafraîchir le Dépôt",lastExchange:"Dernier Échange",exchangeUri:"URI",nextExchange:"Dernier Échange Avant",allResources:"Toutes les Ressources",entitlements:"Ressources Dues",showEntitlements:"Montrer les Ressources Dues en détail",parentCertificate:"Certificat Parent",published:"Publié"},aspas:{customer:"Customer",providers:"Providers",search:"Search for customer, provider...",confirmation:{title:"Warning",message:"This will remove the ASPA '{customer} => {providers}'. Continue?",added:"ASPA added",retired:"ASPA removed",retiredSuccess:"The ASPA has been removed",addedSuccess:"The ASPA has been added",commentUpdatedSuccess:"The ASPA comment has been updated"},customer_validation_format:"The customer format is invalid or already exists",providers_validation_format:"The providers format is invalid"},announcements:{noRoasOrAnnouncements:"Aucun ROAs ou Annonces trouvés.",search:"Rechercher un ASN, préfixe, statut...",authorizes:"Autoriser {number} annonces",disallows:"Refuser {number} annonces",asn:"ASN",prefix:"Préfixe",stateLabel:"Statut",state:{roa_seen:"TROUVÉ",roa_seen_help:"Ce ROA correspond aux annonces vues dans BGP",roa_unseen:"INTROUVABLE",roa_unseen_help:"Aucune annonce BGP correspondant à ce ROA trouvée",roa_not_held:"PREFIX REMOVED",roa_not_held_help:"The prefix is no longer on your certificate(s), the ROA will not be published",roa_no_announcement_info:"AUCUNE INFORMATION D'ANNONCE",roa_too_permissive:"TROP PERMISSIF",roa_too_permissive_help:"Ce ROA correspond aux annonces en BGP, mais aussi à des annonces introuvables",roa_disallowing:"INVALIDANT",roa_disallowing_help:"Ce ROA invalide les annonces seulement. Si c’est intentionnel, vous devriez plutôt utiliser un AS0 à la place",roa_redundant:"REDONDANT",roa_redundant_help:"Ce ROA est redondant parce qu’il y a au moins un ROA existant qui couvre ce préfixe, longueur et numéro d'AS",roa_as0:"AS0",roa_as0_help:"Ce ROA sert à invalider toutes les annonces pour un préfixe",roa_as0_redundant:"REDONDANT",roa_as0_redundant_help:"Ce ROA AS0 est redondant parce qu’il y a au moins un ROA existant qui couvre ce préfixe",announcement_not_found:"NON TROUVÉ",announcement_not_found_help:"Cette announce n'est couverte par aucun de vos ROAs",announcement_invalid_length:"LONGUEUR INVALIDE",announcement_invalid_length_help:"Cette annonce n'est pas permise parce qu'elle est plus spécifique que la longueur du préfixe et la taille maximum autorisées pour cet ASN",announcement_invalid_asn:"ASN INVALIDE",announcement_invalid_asn_help:"Cette annonce n'est pas permise parce que vous autorisez seulement le préfixe depuis un autre ASN",announcement_disallowed:"DISALLOWED BY AS0",announcement_disallowed_help:"This announcement is not allowed because you have an AS0 ROA that disallows it"},download:"Télécharger le fichier au format CSV"},deltaErrors:{duplicates:"Doublons",covered:"Couvert",notheld:"Pas Considéré",unknowns:"Inconnus",invalid_length:"Longueur Invalide",covering:"Recouvrant",as0_exists:"AS0 Existe",as0_overlaps:"Chevauchement du AS0"},errors:{repo_not_set:"Vous devez d'abord configurer un dépôt",pub_unknown:"Publisher '{publisher}' est inconnu",pub_duplicate:"Publisher '{publisher}' était déjà initialisé",pub_outside_jail:"Publisher uri '{uri}' en dehors du dépôt uri '{sia_base}'",pub_uri_no_slash:"Publisher uri '{uri}' doit avoir une barre oblique à la fin",pub_no_embedded_repo:"Pas de dépôt imbriqué configuré",ca_duplicate:"AC '{ca}' déjà initialisée",ca_unknown:"AC '{ca}' est inconnue",ca_repo_same:"Ce dépôt est déjà utilisé",ca_repo_issue:"Erreur provenant du dépôt: {cause}",ca_repo_response_invalid_xml:"Réponse xml du dépôt invalide",ca_repo_response_wrong_xml:"Réponse du parent reçue au lieu du dépôt",ca_parent_duplicate:"Vous avez déjà un parent nommé '{parent}'",ca_parent_xml_duplicate:"Cette réponse est déjà utilisée par le parent '{parent}'",ca_parent_unknown:"Vous n'avez pas un parent nommé '{parent}'",ca_parent_issue:"Erreur reçue du parent '{parent}': {cause}",ca_parent_response_invalid_xml:"Réponse xml du parent invalide",ca_parent_response_wrong_xml:"Réponse du dépôt obtenue lors de l'ajout du parent",ca_child_duplicate:"Vous avez déjà une AC enfant nommée '{child}'",ca_child_unknown:"Vous n'avez pas une AC enfant nommée '{child}'",ca_child_resources_required:"Vous devez spécifier les ressources pour l'AC enfant '{child}'",ca_roa_unknown:"Impossible d'enlever un ROA inconnu '{prefix}-{max_length} => {asn}'",ca_roa_duplicate:"ROA en doublon '{prefix}-{max_length} => {asn}'",ca_roa_invalid_max_length:"Longueur max invalide dans le ROA '{prefix}-{max_length} => {asn}'",ca_roa_not_entitled:"Le préfixe du ROA '{prefix}' ne figure dans aucun de vos certificats actuels",ta_not_allowed:"Cette fonctionnalité n'est pas supportée par l'ancre de confiance de test",ta_name_reserved:"Nom reservé",ca_roa_delta_error:"ROA rejeté pour la/les raison(s) suivante(s)",api_insufficient_rights:"Votre utilisateur n'a pas les droits suffisants pour effectuer cette action.",api_invalid_credentials:"Les identifiants fournis sont invalides.",api_login_error:"Une erreur est survenue pendant votre connexion: {cause}",api_auth_transient_error:"Une erreur temporaire est survenue pendant votre connexion. Veuillez essayer à nouveau dans quelques instants",api_auth_permanent_error:"Une erreur est survenue pendant l'authentification de votre connexion. Veuillez contacter votre administrateur.",api_auth_session_expired:"Votre session a expirée,",general_error:"Une erreur est survenue. Veuillez contacter votre administrateur."},testbed:{welcome:"Bienvenue sur ce banc d'essai pour RPKI",disclaimer:{heading:"Avertissement",body:"Ce banc d'essai offre une hiérarchie complètement différente pour RPKI; il peut être utilisé pour des besoins d'évaluation. Il vous permet d'inscrire n'importe quelles ressources pour votre AC enfant. Aucune garantie n'est donnée concernant la disponibilité de ce service. Si vous décelez un problème, merci de nous le faire savoir."},rpconfighelp:{heading:"Banc d'essai TAL",body:"Pour récupérer les données publiées par ce banc d'essai, veuillez svp télécharger ce Trust Anchor Locator (TAL) et le configurer dans votre logiciel validateur, le Relying Pary. Noter que vous ne devriez JAMAIS utiliser ce TAL dans un environnement de production. Il est mis à disposition uniquement pour des tests."},regunreg:{heading:"Inscrire/Désinscrire",body:"

Utiliser le formulaire pour inscrire votre autorité de certification RPKI comme un enfant de ce banc d'essai ainsi vous pourrez créer les 'Route Origin Authorisations' (ROAs) pour les resources que vous revendiquez.

Si vous ne voulez pas héberger vos propres dépôts Rsync et RRDP vous pouvez utiliser le formulaire du Register Publisher pour configurer la publication de vos ROAs dans le dépôt hébergé par le banc d'essai. Utilisez les formulaires 'Se désinscrire' pour annuler les relations précédemment établies (même celles des autres utilisateurs du banc d'essai!).

"},rfcdoclink:"Cliquer pour voir la documentation de ce XML dans le RFC-8183",childhandle:"Identifiant enfant",publisherhandle:"Identifiant Publisher",responseXML:"réponse banc d'essai au format XML",addChild:{heading:"Inscrire l'AC",requestXML:{label:"Requête XML enfant",placeholder:"Coller votre XML ici"},asnresources:{label:"Ressources ASN",placeholder:"Les ressources AS: e.g. AS1, AS3-4"},ipv4resources:{label:"Ressources IPv4",placeholder:"Les ressources IPv4: e.g. 192.168.0.0/16"},ipv6resources:{label:"Ressources IPv6",placeholder:"Les ressources IPv6: e.g. 2001:db8::/32"},confirm:"Inscrire l'AC enfant",format:"Ce n'est pas une requête enfant XML valide",required:"Veuillez svp fournir la requête XML enfant",confirmation:{title:"Attention",message:"Êtes-vous sûr de vouloir inscrire cet enfant dans le banc d'essai ?"},success:"L'AC enfant '{child_handle}' a été ajoutée au banc d'essai.",registeranother:"Inscrire une autre AC"},removeChild:{heading:"Désinscrire l'AC",placeholder:"Entrer le nom de l'AC à retirer",confirm:"Retirer l'AC enfant",confirmation:{title:"Attention",message:"Êtes-vous sûr de vouloir désinscrire cet enfant du banc d'essai ?"},success:"L'AC enfant '{child_handle}' a été retirée du banc d'essai."},addPublisher:{heading:"Inscrire le Publisher",requestXML:{label:"Requête XML de type Publisher",placeholder:"Coller votre XML ici"},confirm:"Inscrire le Publisher",format:"Ceci n'est pas une requête XML de type Publisher valide",required:"Veuillez svp fournir la requête XML de type Publisher",confirmation:{title:"Attention",message:"Êtes-vous sûr de vouloir inscrire ce Publisher avec le banc d'essai?"},success:"Le Publisher '{publisher_handle}' a été ajouté au banc d'essai.",registeranother:"Inscrire un autre Publisher"},removePublisher:{heading:"Désinscrire le Publisher",placeholder:"Entrer le nom du Publisher à retirer",confirm:"Retirer le publisher",confirmation:{title:"Attention",message:"Etes-vous sûr de vouloir désinscrire ce Publisher avec le banc d'essai ?"},success:"Le Publisher '{publisher_handle}' a été retiré du banc d'essai."},errors:{invalid_xml:"XML invalide: {err}",missing_xml_el:"Element manquant {el}",missing_xml_child_el:"Elément enfant {el} de l'élément {parent} manquant",missing_xml_attr:"Attribut {attr} sur l'élement {el} manquant",empty_xml_el:"Elément {el} ne peut pas être vide",empty_xml_attr:"Attribut {attr} de l'élément {el} ne peut pas être vide",non_ascii_xml_el:"L'élement {el} ne peut pas contenir de caractères non-ASCII",child_handle_required:"L'identifiant Enfant est requis",publisher_handle_required:"L'identifiant Publisher est requis",non_base64_certificate_xml_el:"L'élement {el} doit contenir un certificat BKPI X.509 auto signé et correctement encodé en base64",invalid_registration_data:"Vos données d'inscription n'ont pas pu être analysées correctement"}}};export{e as translations}; diff --git a/ui/assets/gr-85b90120.js b/ui/assets/gr-85b90120.js new file mode 100644 index 00000000..23ebc248 --- /dev/null +++ b/ui/assets/gr-85b90120.js @@ -0,0 +1 @@ +const e={common:{readthedocs:"Read the Docs",report:"Αναφορά προβλήματος",confirm:"Επιβεβαίωση",cancel:"Ακύρωση",ok:"OK",error:"Σφάλμα",success:"Επιτυχία!",copy:"Αντιγραφή στο πρόχειρο",download:"Λήψη",dropOrClick:"Σύρετε το αρχείο εδώ ή κάντε κλίκ για μεταφόρτωση",started:"Το Krill τρέχει από",newversion:"Νέα έκδοση διαθέσιμη!",supportcontracts:"Συμβάσεις Υποστήριξης",warning:"Προειδοποίηση",idle:"Έχετε αποσυνδεθεί λόγω αδράνειας.",nodata:"Δεν υπάρχουν δεδομένα",copySuccess:"To XML αρχείο αντιγράφηκε στο πρόχειρο",edit:"Επεξεργασία",page:"σελίδα",userInfo:{title:"Στοιχεία Σύνδεσης",user:"Χρήστης"}},login:{password:"Κωδικός",placeholder:"Ο κωδικός σας",signin:"Είσοδος",required:"Παρακαλώ εισάγετε τον κωδικό σας",error:"Ο κωδικός που χρησιμοποιήσατε δεν είναι σωστός",copied:"Ο κωδικός σας δεν πρέπει να προέρχεται από https://xkcd.com/936/",id:"Όνομα χρήστη",idPlaceholder:"Το όνομα χρήστη σας",idRequired:"Παρακαλώ εισάγετε το όνομα χρήστη σας",retry:"Επιλέξτε {0} για επιστροφή στη σελίδα σύνδεσης.",here:"εδώ"},onboarding:{welcome:"Καλωσήρθατε στο Krill",welcomeHtml:"Ας αρχήσουμε δημιουργώντας τη δικιά σας Αρχή Πιστοποίησης RPKI (CA). Θα χρησιμοποιηθεί για να διαμορφώσουμε εξουσιοδοτημένο RPKI με έναν ή περισσότερους CA-γονείς, συνήθως τον Τοπικό (RIR) ή Εθνικό (NIR) Οργανισμό Διαχείρισης Πόρων Διαδικτύου.

Η επιλεγμένη ονομασία θα ταυτοποιεί την Αρχή Πιστοποίησής (CA) σας σε αλληλεπιδράσεις με CA-γονείς και CA-παιδιά. Η ονομασία δεν δημοσιεύεται στο RPKI. Παρακαλώ διαλέξτε μία ονομασία που θα βοηθάει στην αναγνώριση του οργανισμού σας από άλλους. Η ονομασία δεν μπορεί να αλλάξει αφού οριστεί.",addCAForm:{required:"Το πεδίο είναι υποχρεωτικό",format:"Το όνομα της Αρχής Πιστοποίησης (CA) δεν είναι έγκυρο",confirm:"Δημιουργία Αρχής Πιστοποίησης (CA)",confirmation:{title:"Προειδοποίηση",message:"Η ονομασία δεν μπορεί να αλλάξει αφού οριστεί. Συνέχεια;"}}},cas:{loading:"Φόρτωση Αρχών Πιστοποίησης (CAs)",ca:"Αρχή Πιστοποίησης (CA)",cas:"Αρχές Πιστοποίησης (CAs)",search:"Αναζήτηση Αρχών Πιστοποίησης (CAs)...",noCas:"Δεν έχουν οριστεί Αρχές Πιστοποίησης (CAs) ακόμα."},caDetails:{loading:"Φόρτωση {handle}",refresh:"Ανανέωση {handle}, μπορεί να διαρκέσει αρκετά λεπτά",current:"Τρέχουσα Αρχή Πιστοποίησης (CA)",download:"Λήψη PEM",noRoas:"Δεν βρέθηκαν ROA.",noResources:"Δεν έχετε λάβει κανέναν πόρο ακόμα",noChildren:"Δεν βρέθηκαν CA-παιδιά.",addRoa:"Προσθήκη ROA",addAspa:"Προσθήκη ASPA",editAspa:"Επεξεργασία ASPA",roas:"ROA",aspas:"ASPA",resources:"Πόροι",parents:"CA-γονείς",repo:"Αποθετήριο (repository)",type:"Τύπος",properties:"Ιδιότητες",property:"Ιδιότητα",value:"Τιμή",kind:"Είδος",resource:"Πόρος",children:"CA-παιδιά",handle:"Ονομασία",comment:"Σχόλιο",maxLength:"Μέγιστο μήκος",maxLengthTooltip:"Εάν το μέγιστο μήκος δεν οριστεί, το μήκος του προθέματος προεπιλέγεται ως το μέγιστο μήκος.",confirmation:{title:"Προειδοποίηση",message:"Αυτή η ενέργεια θα αφαιρέσει το ROA '{prefix}-{max_length} => {asn}'. Συνέχεια;",added:"Το ROA προστέθηκε",retired:"Το ROA αφαιρέθηκε",retiredSuccess:"Το ROA έχει αφαιρεθεί",addedSuccess:"Το ROA έχει προστεθεί",commentUpdatedSuccess:"Το σχόλιο του ROA ενημερώθηκε"},addROAForm:{required:"Το πεδίο είναι υποχρεωτικό",asn_format:"Το ASN δεν είναι έγκυρο",prefix_format:"Παρακαλώ εισάγετε ένα έγκυρο IPv4 ή IPv6 πρόθεμα"},onboardingWarning:"Θα χρειαστεί να συνδέσετε την Αρχή Πιστοποίησής (CA) σας σε ένα δημόσιο αποθετήριο (repository) RPKI που θα μπορεί να δημοσιεύσει το πιστοποιητικό και τα ROA σας. Με το που ολοκληρωθεί η ρύθμιση του CA-πατέρα, λογισμικά επικύρωσης (relying party) θα αρχίσουν να ανακτούν το πιστοποιητικό και τα ROA σας από αυτό το αποθετήριο (repository).",initializeRepository:"Ακόμη χρειάζεται να ρυθμίσετε ένα αποθετήριο (repository) για την Αρχή Πιστοποίησής (CA) σας πριν μπορέσει να ζητήσει πιστοποιητικά πόρων από τους γονείς της",initialize:"Παρακαλώ αρχικοποιήστε ένα αποθετήριο (repository) RPKI και/ή τον CA-γονέα πρώτα.",noResourcesYet:"Δεν έχετε λάβει κανέναν πόρο ακόμα",clickToRefresh:"Κάντε κλίκ εδώ για ανανέωση",parentsTab:{request:"Αίτημα CA-παιδιού",response:"Απάντηση CA-γονέα",addParent:"Προσθήκη επιπλέον CA-γονέα",addParentSuccess:"Ο CA-γονέας προστέθηκε",name:"Όνομα CA-γονέα",namerequired:"Το όνομα CA-γονέα είναι υποχρεωτικό",nameformat:"Το όνομα CA-γονέα δεν είναι έγκυρο"},repoTab:{request:"Αίτημα Εκδότη",response:"Απάντηση Αποθετηρίου (Repository)",addRepo:"Πρόσθεση Αποθετηρίου (Repository)",addRepoSuccess:"Το Αποθετήριο (Repository) προστέθηκε"},analyseThis:"Ανέλυσε τα ROA",analysis:"Ανάλυση ROA",suggestions:{following:"Παρακαλώ επαληθεύστε τις ακόλουθες προτεινόμενες αλλαγές στα ROA σας.",readMore:"Διαβάστε περισσότερα...",nochanges:"Δεν προτείνουμε αλλαγές αυτή τη στιγμή",adding:"Προσθήκη",removing:"Αφαίρεση ROA",keep:"Κρατήστε την κατάσταση ως έχει",willResult:"Θα έχει ως αποτέλεσμα",yourChoice:"Επιλογή σας",ourSuggestion:"Η πρότασή μας",ourSuggestionHelp:"Η πρότασή μας βασίζεται στις πληροφορίες του RIPE RIS Routing, παρακαλώ επιβεβαιώστε!",addThis:"Προσθέστε αυτό",removeThis:"Αφαιρέστε αυτό",willAdd:"Πρόσθεση αυτού του ROA",willRemove:"Αφαίρεση αυτού του ROA",reasons:{not_found:"Δεν βρέθηκε",not_held:"Το ROA δεν μπορεί να δημοσιευθεί, το αντίστοιχο πρόθεμα δεν είναι πλέον μέρος κανενός πιστοποιητικού σας",invalid_asn:"Άκυρο ASN",invalid_length:"Άκυρο μήκος",stale:"Δεν υπάρχουν ορατές ανακοινώσεις για το ROA",disallowing:"Αυτό το ROA μόνο απαγορεύει ανακοινώσεις. Αν αυτό είναι σκόπιμο μπορείτε να χρησιμοποιήσετε ένα AS0 ROA αντί αυτού.",as0_redundant:"Περιττό ROA",redundant:"Περιττό ROA",too_permissive:"Το ROA επιτρέπει επιπλέον ανακοινώσεις που μπορεί να καταχραστούν για επιθέσεις τύπου path spoofing hijacks",specific:"Επιτρέψτε συγκεκριμένη ανακοίνωση σε ένα ROA που μπορεί να είναι πολύ επιτρεπτικό",new:"Νέο"}},syncParents:"Ανανέωση CA-γονέων",syncRepo:"Ανανέωση Αποθετηρίου (Repository)",lastExchange:"Τελευταία ανταλλαγή",exchangeUri:"URI",nextExchange:"Επόμενη ανταλλαγή πρίν από",allResources:"Όλοι οι πόροι",entitlements:"Δικαιοδοσίες",showEntitlements:"Εμφάνιση Λεπτομερών Δικαιοδοσιών",parentCertificate:"Πιστοποιητικό CA-γονέα",published:"Δημοσιευμένο"},aspas:{customer:"Πελάτης",providers:"Πάροχοι",search:"Αναζήτηση για πελάτη, πάροχο...",confirmation:{title:"Προειδοποίηση",message:"Η ASPA '{customer} => {providers}' θα αφαιρεθεί. Συνέχεια;",added:"Η ASPA προστέθηκε",retired:"Η ASPA αφαιρέθηκε",retiredSuccess:"Η ASPA αφαιρέθηκε",addedSuccess:"Η ASPA προστέθηκε",commentUpdatedSuccess:"Το σχόλιο της ASPA ανανεώθηκε"},customer_validation_format:"Το ASN του πελάτη είναι άκυρο ή ήδη υπάρχον",providers_validation_format:"Η λίστα με τα ASN των παρόχων είναι άκυρη",add:"Add ASPA",edit:"Edit ASPA",analyse:"Analyse providers",detected_providers:"Declared providers",providers_missing:"ASNs observed in RIS but not in the provider list. Please verify that none of these ASNs act as your provider.",no_aspas:"Krill did not find any ASNs. You need an ASN to be able to create an ASPA for it."},announcements:{noRoasOrAnnouncements:"Δεν βρέθηκαν ROA ή Ανακοινώσεις.",search:"Αναζήτηση για ASN, πρόθεμα, κατάσταση...",authorizes:"Εξουσιοδοτεί {number} ανακοινώσεις",disallows:"Απαγορεύει {number} ανακοινώσεις",asn:"ASN",prefix:"Πρόθεμα",stateLabel:"Κατάσταση",state:{roa_seen:"ΟΡΑΤΟ",roa_seen_help:"Υπάρχουν ταιριαστές ανακοινώσεις στο BGP για αυτό το ROA",roa_unseen:"ΑΦΑΝΕΣ",roa_unseen_help:"Δεν βλέπουμε καμμία BGP ανακοίνωση που να ταιριάζει με αυτό το ROA",roa_not_held:"ΑΦΑΙΡΕΜΕΝΟ ΠΡΟΘΕΜΑ",roa_not_held_help:"Το πρόθεμα δεν είναι πλέον μέρος κανενός πιστοποιητικού σας, το ROA δεν θα δημοσιευθεί",roa_no_announcement_info:"ΚΑΜΜΙΑ ΠΛΗΡΟΦΟΡΙΑ ΑΝΑΚΟΙΝΩΣΗΣ",roa_too_permissive:"ΠΟΛΥ ΕΠΙΤΡΕΠΤΙΚΟ",roa_too_permissive_help:"Αυτό το ROA ταιριάζει με ανακοινώσεις στο BGP, αλλά επίσης επιτρέπει αφανείς ανακοινώσεις",roa_disallowing:"ΑΠΑΓΟΡΕΥΤΙΚΟ",roa_disallowing_help:"Αυτό το ROA μόνο απαγορεύει ανακοινώσεις. Αν αυτό είναι σκόπιμο μπορείτε να χρησιμοποιήσετε ένα AS0 ROA αντί αυτού.",roa_redundant:"ΠΕΡΙΤΤΟ",roa_redundant_help:"Αυτό το ROA είναι περιττό καθώς υπάρχουν ένα ή περισσότερα ROA που καλύπτουν το πρόθεμα, μήκος και ASN",roa_as0:"AS0",roa_as0_help:"Αυτό το ROA χρησιμεύει για να αποτρέπει όλες τις ανακοινώσεις για ένα πρόθεμα",roa_as0_redundant:"ΠΕΡΙΤΤΟ",roa_as0_redundant_help:"Αυτό το AS0 ROA είναι περιττό καθώς υπάρχουν ένα ή περισσότερα ROA που καλύπτουν το πρόθεμα",announcement_not_found:"ΔΕΝ ΒΡΕΘΗΚΕ",announcement_not_found_help:"Αυτή η ανακοίνωση δεν καλύπτεται από κανένα ROA σας",announcement_invalid_length:"ΑΚΥΡΟ ΜΗΚΟΣ",announcement_invalid_length_help:"Αυτή η ανακοίνωση δεν είναι επιτρεπτή καθώς είναι πιο συγκεκριμένη από το πρόθεμα και το μέγιστο μήκος που έχετε εξουσιοδοτήσει για αυτό το ASN",announcement_invalid_asn:"ΑΚΥΡΟ ASN",announcement_invalid_asn_help:"Αυτή η ανακοίνωση δεν είναι επιτρεπτή καθώς έχετε εξουσιοδοτήσει το πρόθεμα μόνο από άλλο ASN",announcement_disallowed:"ΑΠAΓΟΡΕΥΕΤΑΙ ΑΠΟ AS0",announcement_disallowed_help:"Αυτή η ανακοίνωση δεν είναι επιτρεπτή καθώς ένα υπάρχον AS0 ROA την αποτρέπει"},download:"Λήψη CSV"},deltaErrors:{duplicates:"Διπλότυπα",covered:"Καλύπτεται",notheld:"Δεν Κατέχεται",unknowns:"Άγνωστα",invalid_length:"Άκυρο Μήκος",covering:"Καλύπτει",as0_exists:"Το AS0 Υπάρχει",as0_overlaps:"Το AS0 Υπερκαλύπτει"},errors:{repo_not_set:"Πρώτα πρέπει να ρυθμιστεί ένα αποθετήριο (repository)",pub_unknown:"Ο εκδότης '{publisher}' είναι άγνωστος",pub_duplicate:"Ο εκδότης '{publisher}' έχει ήδη αρχικοποιηθεί",pub_outside_jail:"Το URI '{uri}' του εκδότη είναι εκτός του URI '{sia_base}' του αποθετηρίου (repository)",pub_uri_no_slash:"Το URI '{uri}' του εκδότη πρέπει να τελειώνει με '/'",pub_no_embedded_repo:"Δεν έχει ρυθμιστεί ενσωματωμένο αποθετήριο (repository)",ca_duplicate:"Η Αρχή Πιστοποίησης (CA) '{ca}' έχει ήδη αρχικοποιηθεί",ca_unknown:"Η Αρχή Πιστοποίησης (CA) '{ca}' είναι άγνωστη",ca_repo_same:"Αυτό το αποθετήριο (repository) χρησιμοποιείται ήδη",ca_repo_issue:"Μήνυμα σφάλματος απο αποθετήριο (repository): {cause}",ca_repo_response_invalid_xml:"Άκυρη απάντηση XML από το αποθετήριο (repository)",ca_repo_response_wrong_xml:"Λήφθηκε απάντηση CA-γονέα αντί για απάντηση αποθετηρίου (repository)",ca_parent_duplicate:"Έχετε ήδη έναν CA-γονέα με το όνομα '{parent}'",ca_parent_xml_duplicate:"Αυτή η απάντηση χρησιμοποιείται ήδη από έναν CA-γονέα με όνομα '{parent}'",ca_parent_unknown:"Δεν έχετε CA-γονέα με το όνομα '{parent}'",ca_parent_issue:"Μήνυμα σφάλματος από CA-γονέα '{parent}': {cause}",ca_parent_response_invalid_xml:"Άκυρη απάντηση XML από CA-γονέα",ca_parent_response_wrong_xml:"Λήφθηκε απάντηση αποθετηρίου (repository) ενώ προστιθόταν CA-γονέας",ca_child_duplicate:"Έχετε ήδη ένα CA-παιδί με το όνομα '{child}'",ca_child_unknown:"Δεν έχετε CA-παιδί με το όνομα '{child}'",ca_child_resources_required:"Πρέπει να προσδιορίσετε πόρους για το CA-παιδί '{child}'",ca_roa_unknown:"Δεν είναι δυνατή η αφαίρεση άγνωστου ROA '{prefix}-{max_length} => {asn}'",ca_roa_duplicate:"Διπλότυπο ROA '{prefix}-{max_length} => {asn}'",ca_roa_invalid_max_length:"Μη έγκυρο μέγιστο μήκος στο ROA '{prefix}-{max_length} => {asn}'",ca_roa_not_entitled:"Το πρόθεμα ROA '{prefix}' δεν είναι σε κανένα από τα τρέχοντα πιστοποιητικά σας",ta_not_allowed:"Αυτή η λειτουργικότητα δεν υποστηρίζεται από τη δοκιμαστική Άγκυρα Εμπιστοσύνης (Trust Anchor)",ta_name_reserved:"Κατοχυρωμένο όνομα",ca_roa_delta_error:"Το ROA απορρίφθηκε για τους ακόλουθους λόγους",api_insufficient_rights:"Ο χρήστης σας δεν έχει επαρκή δικαιώματα για να εκτελέσει αυτή την ενέργεια. Παρακαλώ επικοινωνείστε με το διαχειριστή σας.",api_invalid_credentials:"Τα παρεχόμενα στοιχεία σύνδεσης είναι λάθος.",api_login_error:"Προέκυψε σφάλμα κατά τη σύνδεση: {cause}",api_auth_transient_error:"Προέκυψε (προσωρινό) σφάλμα κατά τη διαδικασία πιστοποίησης της αίτησης. Παρακαλώ προσπαθήστε αργότερα.",api_auth_permanent_error:"Προέκυψε σφάλμα κατά τη διαδικασία πιστοποίησης της αίτησης. Παρακαλώ επικοινωνείστε με το διαχειριστή σας.",api_auth_session_expired:"Η συνεδρία σας έχει λήξει. Παρακαλώ συνδεθείτε ξανά...",general_error:"Κάτι πήγε λάθος. Παρακαλώ επικοινωνείστε με το διαχειριστή σας."},testbed:{welcome:"Καλωσήρθατε σε αυτή την πλατφόρμα δοκιμών RPKI",disclaimer:{heading:"Αποποίηση Ευθύνης",body:"Αυτή η πλατφόρμα δοκιμών προσφέρει μία εντελώς ανεξάρτητη RPKI ιεραρχία που μπορεί να χρησιμοποιηθεί για σκοπούς αξιολόγησης. Επιτρέπει την εγγραφή οποιουδήποτε πόρου για το CA-παιδί σας. Δεν παρέχονται εγγυήσεις όσον αφορά την διαθεσιμότητα αυτής της υπηρεσίας. Για τυχόν προβλήματα, παρακαλείσθε να μας ενημερώσετε."},rpconfighelp:{heading:"TAL για την πλατφόρμα δοκιμών",body:"Για να ανακτείσετε τα δεδομένα που εκδίδονται από αυτή την πλατφόρμα δοκιμών, παρακαλείσθε να κατεβάσετε αυτόν τον Εντοπιστή Άγκυρας Εμπιστοσύνης (TAL) και να τον ρυθμίσετε στο λογισμικό επικύρωσής (Relying Party Software) σας. Σημειώστε ότι ΟΥΔΕΠΟΤΕ δεν πρέπει να χρησιμοποιήσετε αυτό το TAL σε περιβάλλον παραγωγής. Η χρήση του παρέχεται μόνο για δοκιμές."},regunreg:{heading:"Εγγραφή/Διαγραφή",body:"

Χρησιμοποιήστε τη φόρμα για την εγγραφή της δικής σας Αρχής Πιστοποίησης RPKI ως CA-παιδιού της πλατφόρμας δοκιμών για τη δημιουργία ROA για τους πόρους που κατέχετε.

Εάν δεν επιθυμείτε να φιλοξενήσετε τα δικά σας Rsync και RRDP αποθετήρια (repositories) μπορείτε να χρησιμοποιήσετε τη φόρμα Εγγραφής Εκδότη για να ρυθμίσετε την έκδοση των ROA σας στο αποθετήριο (respository) που παρέχεται από την πλατφόρμα δοκιμών. Χρησιμοποιήστε τις φόρμες Διαγραφής για να ακυρώσετε προηγούμενες σχέσεις (ακόμα και σχέσεις από άλλους χρήστες της πλατφόρμας δοκιμών!).

"},rfcdoclink:"Κάντε κλίκ για να δείτε το RFC-8183 έγγραφο για αυτό το XML",childhandle:"Ονομασία CA-παιδιού",publisherhandle:"Ονομασία Εκδότη",responseXML:"Απάντηση XML της πλατφόρμας δοκιμών",addChild:{heading:"Εγγραφή Αρχής Πιστοποίησης (CA)",requestXML:{label:"Αίτημα XML CA-παιδιού",placeholder:"Επικολλήστε το XML εδώ"},asnresources:{label:"Πόροι ASN",placeholder:"Οι AS πόροι: π.χ. AS1, AS3-4"},ipv4resources:{label:"Πόροι IPv4",placeholder:"Οι IPv4 πόροι: π.χ. 192.168.0.0/16"},ipv6resources:{label:"Πόροι IPv6",placeholder:"Οι IPv6 πόροι: π.χ. 2001:db8::/32"},confirm:"Εγγραφή CA-παιδιού",format:"Μη έγκυρο αίτημα XML CA-παιδού",required:"Παρακαλώ παραχωρήστε το αίτημα XML CA-παιδιού",confirmation:{title:"Προειδοποίηση",message:"Είστε σίγουροι ότι επιθυμείτε την εγγραφή αυτού του CA-παιδιού με την πλατφόρμα δοκιμών;"},success:"Το CA-παιδί '{child_handle}' προστέθηκε στην πλατφόρμα δοκιμών.",registeranother:"Εγγραφή άλλης Αρχής Πιστοποίησης (CA)"},removeChild:{heading:"Διαγραφή Αρχής Πιστοποίησης (CA)",placeholder:"Εισάγετε το όνομα της Αρχής Πιστοποίησης (CA) προς αφαίρεση",confirm:"Αφαίρεση CA-παιδιού",confirmation:{title:"Προειδοποίηση",message:"Είστε σίγουροι ότι επιθυμείτε την διαγραφή αυτού του CA-παιδιού από την πλατφόρμα δοκιμών;"},success:"Το CA-παιδί '{child_handle}' αφαιρέθηκε από την πλατφόρμα δοκιμών."},addPublisher:{heading:"Εγγραφή Εκδότη",requestXML:{label:"Αίτημα XML Εκδότη",placeholder:"Επικολλήστε το XML εδώ"},confirm:"Εγγραφή Εκδότη",format:"Μη έγκυρο αίτημα XML Εκδότη",required:"Παρακαλώ παραχωρήστε το αίτημα XML Εκδότη",confirmation:{title:"Προειδοποίηση",message:"Είστε σίγουροι ότι επιθυμείτε την εγγραφή αυτού του Εκδότη με την πλατφόρμα δοκιμών;"},success:"Ο Εκδότης '{publisher_handle}' προστέθηκε στην πλατφόρμα δοκιμών.",registeranother:"Εγγραφή άλλου Εκδότη"},removePublisher:{heading:"Διαγραφή Εκδότη",placeholder:"Εισάγετε το όνομα Εκδότη προς αφαίρεση",confirm:"Αφαίρεση Εκδότη",confirmation:{title:"Προειδοποίηση",message:"Είστε σίγουροι ότι επιθυμείτε την διαγραφή αυτού του Εκδότη από την πλατφόρμα δοκιμών;"},success:"Ο Εκδότης '{publisher_handle}' αφαιρέθηκε από την πλατφόρμα δοκιμών."},errors:{invalid_xml:"Άκυρο XML: {err}",missing_xml_el:"Έλλειψη στοιχείου {el}",missing_xml_child_el:"Έλλειψη υποστοιχείου {el} του στοιχείου {parent}",missing_xml_attr:"Έλλειψη χαρακτηριστικού {attr} στο στοιχείο {el}",empty_xml_el:"Το στοιχείο {el} δεν μπορεί να είναι άδειο",empty_xml_attr:"Το χαρακτηριστικό {attr} στο στοιχείο {el} δεν μπορεί να είναι άδειο",non_ascii_xml_el:"Το στοιχείο {el} δεν μπορεί να περιέχει χαρακτήρες που δεν είναι ASCII",child_handle_required:"Η ονομασία CA-παιδιού είναι υποχρεωτική",publisher_handle_required:"Η ονομασία Εκδότη είναι υποχρεωτική",non_base64_certificate_xml_el:"Το στοιχείο {el} πρέπει να περιέχει ένα αυτο-υπογεγραμμένο X.509 BPKI πιστοποιητικό με σωστή κωδικοποίηση Base64",invalid_registration_data:"Τα στοιχεία εγγραφής σας δεν μπόρεσαν να αναλυθούν σωστά"}}};export{e as translations}; diff --git a/ui/assets/gr-9c53613e.js b/ui/assets/gr-9c53613e.js deleted file mode 100644 index d7a69d34..00000000 --- a/ui/assets/gr-9c53613e.js +++ /dev/null @@ -1 +0,0 @@ -const e={common:{readthedocs:"Read the Docs",report:"Αναφορά προβλήματος",confirm:"Επιβεβαίωση",cancel:"Ακύρωση",ok:"OK",error:"Σφάλμα",success:"Επιτυχία!",copy:"Αντιγραφή στο πρόχειρο",download:"Λήψη",dropOrClick:"Σύρετε το αρχείο εδώ ή κάντε κλίκ για μεταφόρτωση",started:"Το Krill τρέχει από",newversion:"Νέα έκδοση διαθέσιμη!",supportcontracts:"Συμβάσεις Υποστήριξης",warning:"Προειδοποίηση",idle:"Έχετε αποσυνδεθεί λόγω αδράνειας.",nodata:"Δεν υπάρχουν δεδομένα",copySuccess:"To XML αρχείο αντιγράφηκε στο πρόχειρο",edit:"Επεξεργασία",page:"σελίδα",userInfo:{title:"Στοιχεία Σύνδεσης",user:"Χρήστης"}},login:{password:"Κωδικός",placeholder:"Ο κωδικός σας",signin:"Είσοδος",required:"Παρακαλώ εισάγετε τον κωδικό σας",error:"Ο κωδικός που χρησιμοποιήσατε δεν είναι σωστός",copied:"Ο κωδικός σας δεν πρέπει να προέρχεται από https://xkcd.com/936/",id:"Όνομα χρήστη",idPlaceholder:"Το όνομα χρήστη σας",idRequired:"Παρακαλώ εισάγετε το όνομα χρήστη σας",retry:"Επιλέξτε {0} για επιστροφή στη σελίδα σύνδεσης.",here:"εδώ"},onboarding:{welcome:"Καλωσήρθατε στο Krill",welcomeHtml:"Ας αρχήσουμε δημιουργώντας τη δικιά σας Αρχή Πιστοποίησης RPKI (CA). Θα χρησιμοποιηθεί για να διαμορφώσουμε εξουσιοδοτημένο RPKI με έναν ή περισσότερους CA-γονείς, συνήθως τον Τοπικό (RIR) ή Εθνικό (NIR) Οργανισμό Διαχείρισης Πόρων Διαδικτύου.

Η επιλεγμένη ονομασία θα ταυτοποιεί την Αρχή Πιστοποίησής (CA) σας σε αλληλεπιδράσεις με CA-γονείς και CA-παιδιά. Η ονομασία δεν δημοσιεύεται στο RPKI. Παρακαλώ διαλέξτε μία ονομασία που θα βοηθάει στην αναγνώριση του οργανισμού σας από άλλους. Η ονομασία δεν μπορεί να αλλάξει αφού οριστεί.",addCAForm:{required:"Το πεδίο είναι υποχρεωτικό",format:"Το όνομα της Αρχής Πιστοποίησης (CA) δεν είναι έγκυρο",confirm:"Δημιουργία Αρχής Πιστοποίησης (CA)",confirmation:{title:"Προειδοποίηση",message:"Η ονομασία δεν μπορεί να αλλάξει αφού οριστεί. Συνέχεια;"}}},cas:{loading:"Φόρτωση Αρχών Πιστοποίησης (CAs)",ca:"Αρχή Πιστοποίησης (CA)",cas:"Αρχές Πιστοποίησης (CAs)",search:"Αναζήτηση Αρχών Πιστοποίησης (CAs)...",noCas:"Δεν έχουν οριστεί Αρχές Πιστοποίησης (CAs) ακόμα."},caDetails:{loading:"Φόρτωση {handle}",refresh:"Ανανέωση {handle}, μπορεί να διαρκέσει αρκετά λεπτά",current:"Τρέχουσα Αρχή Πιστοποίησης (CA)",download:"Λήψη PEM",noRoas:"Δεν βρέθηκαν ROA.",noResources:"Δεν έχετε λάβει κανέναν πόρο ακόμα",noChildren:"Δεν βρέθηκαν CA-παιδιά.",addRoa:"Προσθήκη ROA",addAspa:"Προσθήκη ASPA",editAspa:"Επεξεργασία ASPA",roas:"ROA",aspas:"ASPA",resources:"Πόροι",parents:"CA-γονείς",repo:"Αποθετήριο (repository)",type:"Τύπος",properties:"Ιδιότητες",property:"Ιδιότητα",value:"Τιμή",kind:"Είδος",resource:"Πόρος",children:"CA-παιδιά",handle:"Ονομασία",comment:"Σχόλιο",maxLength:"Μέγιστο μήκος",maxLengthTooltip:"Εάν το μέγιστο μήκος δεν οριστεί, το μήκος του προθέματος προεπιλέγεται ως το μέγιστο μήκος.",confirmation:{title:"Προειδοποίηση",message:"Αυτή η ενέργεια θα αφαιρέσει το ROA '{prefix}-{max_length} => {asn}'. Συνέχεια;",added:"Το ROA προστέθηκε",retired:"Το ROA αφαιρέθηκε",retiredSuccess:"Το ROA έχει αφαιρεθεί",addedSuccess:"Το ROA έχει προστεθεί",commentUpdatedSuccess:"Το σχόλιο του ROA ενημερώθηκε"},addROAForm:{required:"Το πεδίο είναι υποχρεωτικό",asn_format:"Το ASN δεν είναι έγκυρο",prefix_format:"Παρακαλώ εισάγετε ένα έγκυρο IPv4 ή IPv6 πρόθεμα"},onboardingWarning:"Θα χρειαστεί να συνδέσετε την Αρχή Πιστοποίησής (CA) σας σε ένα δημόσιο αποθετήριο (repository) RPKI που θα μπορεί να δημοσιεύσει το πιστοποιητικό και τα ROA σας. Με το που ολοκληρωθεί η ρύθμιση του CA-πατέρα, λογισμικά επικύρωσης (relying party) θα αρχίσουν να ανακτούν το πιστοποιητικό και τα ROA σας από αυτό το αποθετήριο (repository).",initializeRepository:"Ακόμη χρειάζεται να ρυθμίσετε ένα αποθετήριο (repository) για την Αρχή Πιστοποίησής (CA) σας πριν μπορέσει να ζητήσει πιστοποιητικά πόρων από τους γονείς της",initialize:"Παρακαλώ αρχικοποιήστε ένα αποθετήριο (repository) RPKI και/ή τον CA-γονέα πρώτα.",noResourcesYet:"Δεν έχετε λάβει κανέναν πόρο ακόμα",clickToRefresh:"Κάντε κλίκ εδώ για ανανέωση",parentsTab:{request:"Αίτημα CA-παιδιού",response:"Απάντηση CA-γονέα",addParent:"Προσθήκη επιπλέον CA-γονέα",addParentSuccess:"Ο CA-γονέας προστέθηκε",name:"Όνομα CA-γονέα",namerequired:"Το όνομα CA-γονέα είναι υποχρεωτικό",nameformat:"Το όνομα CA-γονέα δεν είναι έγκυρο"},repoTab:{request:"Αίτημα Εκδότη",response:"Απάντηση Αποθετηρίου (Repository)",addRepo:"Πρόσθεση Αποθετηρίου (Repository)",addRepoSuccess:"Το Αποθετήριο (Repository) προστέθηκε"},analyseThis:"Ανέλυσε τα ROA",analysis:"Ανάλυση ROA",suggestions:{following:"Παρακαλώ επαληθεύστε τις ακόλουθες προτεινόμενες αλλαγές στα ROA σας.",readMore:"Διαβάστε περισσότερα...",nochanges:"Δεν προτείνουμε αλλαγές αυτή τη στιγμή",adding:"Προσθήκη",removing:"Αφαίρεση ROA",keep:"Κρατήστε την κατάσταση ως έχει",willResult:"Θα έχει ως αποτέλεσμα",yourChoice:"Επιλογή σας",ourSuggestion:"Η πρότασή μας",ourSuggestionHelp:"Η πρότασή μας βασίζεται στις πληροφορίες του RIPE RIS Routing, παρακαλώ επιβεβαιώστε!",addThis:"Προσθέστε αυτό",removeThis:"Αφαιρέστε αυτό",willAdd:"Πρόσθεση αυτού του ROA",willRemove:"Αφαίρεση αυτού του ROA",reasons:{not_found:"Δεν βρέθηκε",not_held:"Το ROA δεν μπορεί να δημοσιευθεί, το αντίστοιχο πρόθεμα δεν είναι πλέον μέρος κανενός πιστοποιητικού σας",invalid_asn:"Άκυρο ASN",invalid_length:"Άκυρο μήκος",stale:"Δεν υπάρχουν ορατές ανακοινώσεις για το ROA",disallowing:"Αυτό το ROA μόνο απαγορεύει ανακοινώσεις. Αν αυτό είναι σκόπιμο μπορείτε να χρησιμοποιήσετε ένα AS0 ROA αντί αυτού.",as0_redundant:"Περιττό ROA",redundant:"Περιττό ROA",too_permissive:"Το ROA επιτρέπει επιπλέον ανακοινώσεις που μπορεί να καταχραστούν για επιθέσεις τύπου path spoofing hijacks",specific:"Επιτρέψτε συγκεκριμένη ανακοίνωση σε ένα ROA που μπορεί να είναι πολύ επιτρεπτικό",new:"Νέο"}},syncParents:"Ανανέωση CA-γονέων",syncRepo:"Ανανέωση Αποθετηρίου (Repository)",lastExchange:"Τελευταία ανταλλαγή",exchangeUri:"URI",nextExchange:"Επόμενη ανταλλαγή πρίν από",allResources:"Όλοι οι πόροι",entitlements:"Δικαιοδοσίες",showEntitlements:"Εμφάνιση Λεπτομερών Δικαιοδοσιών",parentCertificate:"Πιστοποιητικό CA-γονέα",published:"Δημοσιευμένο"},aspas:{customer:"Πελάτης",providers:"Πάροχοι",search:"Αναζήτηση για πελάτη, πάροχο...",confirmation:{title:"Προειδοποίηση",message:"Η ASPA '{customer} => {providers}' θα αφαιρεθεί. Συνέχεια;",added:"Η ASPA προστέθηκε",retired:"Η ASPA αφαιρέθηκε",retiredSuccess:"Η ASPA αφαιρέθηκε",addedSuccess:"Η ASPA προστέθηκε",commentUpdatedSuccess:"Το σχόλιο της ASPA ανανεώθηκε"},customer_validation_format:"Το ASN του πελάτη είναι άκυρο ή ήδη υπάρχον",providers_validation_format:"Η λίστα με τα ASN των παρόχων είναι άκυρη"},announcements:{noRoasOrAnnouncements:"Δεν βρέθηκαν ROA ή Ανακοινώσεις.",search:"Αναζήτηση για ASN, πρόθεμα, κατάσταση...",authorizes:"Εξουσιοδοτεί {number} ανακοινώσεις",disallows:"Απαγορεύει {number} ανακοινώσεις",asn:"ASN",prefix:"Πρόθεμα",stateLabel:"Κατάσταση",state:{roa_seen:"ΟΡΑΤΟ",roa_seen_help:"Υπάρχουν ταιριαστές ανακοινώσεις στο BGP για αυτό το ROA",roa_unseen:"ΑΦΑΝΕΣ",roa_unseen_help:"Δεν βλέπουμε καμμία BGP ανακοίνωση που να ταιριάζει με αυτό το ROA",roa_not_held:"ΑΦΑΙΡΕΜΕΝΟ ΠΡΟΘΕΜΑ",roa_not_held_help:"Το πρόθεμα δεν είναι πλέον μέρος κανενός πιστοποιητικού σας, το ROA δεν θα δημοσιευθεί",roa_no_announcement_info:"ΚΑΜΜΙΑ ΠΛΗΡΟΦΟΡΙΑ ΑΝΑΚΟΙΝΩΣΗΣ",roa_too_permissive:"ΠΟΛΥ ΕΠΙΤΡΕΠΤΙΚΟ",roa_too_permissive_help:"Αυτό το ROA ταιριάζει με ανακοινώσεις στο BGP, αλλά επίσης επιτρέπει αφανείς ανακοινώσεις",roa_disallowing:"ΑΠΑΓΟΡΕΥΤΙΚΟ",roa_disallowing_help:"Αυτό το ROA μόνο απαγορεύει ανακοινώσεις. Αν αυτό είναι σκόπιμο μπορείτε να χρησιμοποιήσετε ένα AS0 ROA αντί αυτού.",roa_redundant:"ΠΕΡΙΤΤΟ",roa_redundant_help:"Αυτό το ROA είναι περιττό καθώς υπάρχουν ένα ή περισσότερα ROA που καλύπτουν το πρόθεμα, μήκος και ASN",roa_as0:"AS0",roa_as0_help:"Αυτό το ROA χρησιμεύει για να αποτρέπει όλες τις ανακοινώσεις για ένα πρόθεμα",roa_as0_redundant:"ΠΕΡΙΤΤΟ",roa_as0_redundant_help:"Αυτό το AS0 ROA είναι περιττό καθώς υπάρχουν ένα ή περισσότερα ROA που καλύπτουν το πρόθεμα",announcement_not_found:"ΔΕΝ ΒΡΕΘΗΚΕ",announcement_not_found_help:"Αυτή η ανακοίνωση δεν καλύπτεται από κανένα ROA σας",announcement_invalid_length:"ΑΚΥΡΟ ΜΗΚΟΣ",announcement_invalid_length_help:"Αυτή η ανακοίνωση δεν είναι επιτρεπτή καθώς είναι πιο συγκεκριμένη από το πρόθεμα και το μέγιστο μήκος που έχετε εξουσιοδοτήσει για αυτό το ASN",announcement_invalid_asn:"ΑΚΥΡΟ ASN",announcement_invalid_asn_help:"Αυτή η ανακοίνωση δεν είναι επιτρεπτή καθώς έχετε εξουσιοδοτήσει το πρόθεμα μόνο από άλλο ASN",announcement_disallowed:"ΑΠAΓΟΡΕΥΕΤΑΙ ΑΠΟ AS0",announcement_disallowed_help:"Αυτή η ανακοίνωση δεν είναι επιτρεπτή καθώς ένα υπάρχον AS0 ROA την αποτρέπει"},download:"Λήψη CSV"},deltaErrors:{duplicates:"Διπλότυπα",covered:"Καλύπτεται",notheld:"Δεν Κατέχεται",unknowns:"Άγνωστα",invalid_length:"Άκυρο Μήκος",covering:"Καλύπτει",as0_exists:"Το AS0 Υπάρχει",as0_overlaps:"Το AS0 Υπερκαλύπτει"},errors:{repo_not_set:"Πρώτα πρέπει να ρυθμιστεί ένα αποθετήριο (repository)",pub_unknown:"Ο εκδότης '{publisher}' είναι άγνωστος",pub_duplicate:"Ο εκδότης '{publisher}' έχει ήδη αρχικοποιηθεί",pub_outside_jail:"Το URI '{uri}' του εκδότη είναι εκτός του URI '{sia_base}' του αποθετηρίου (repository)",pub_uri_no_slash:"Το URI '{uri}' του εκδότη πρέπει να τελειώνει με '/'",pub_no_embedded_repo:"Δεν έχει ρυθμιστεί ενσωματωμένο αποθετήριο (repository)",ca_duplicate:"Η Αρχή Πιστοποίησης (CA) '{ca}' έχει ήδη αρχικοποιηθεί",ca_unknown:"Η Αρχή Πιστοποίησης (CA) '{ca}' είναι άγνωστη",ca_repo_same:"Αυτό το αποθετήριο (repository) χρησιμοποιείται ήδη",ca_repo_issue:"Μήνυμα σφάλματος απο αποθετήριο (repository): {cause}",ca_repo_response_invalid_xml:"Άκυρη απάντηση XML από το αποθετήριο (repository)",ca_repo_response_wrong_xml:"Λήφθηκε απάντηση CA-γονέα αντί για απάντηση αποθετηρίου (repository)",ca_parent_duplicate:"Έχετε ήδη έναν CA-γονέα με το όνομα '{parent}'",ca_parent_xml_duplicate:"Αυτή η απάντηση χρησιμοποιείται ήδη από έναν CA-γονέα με όνομα '{parent}'",ca_parent_unknown:"Δεν έχετε CA-γονέα με το όνομα '{parent}'",ca_parent_issue:"Μήνυμα σφάλματος από CA-γονέα '{parent}': {cause}",ca_parent_response_invalid_xml:"Άκυρη απάντηση XML από CA-γονέα",ca_parent_response_wrong_xml:"Λήφθηκε απάντηση αποθετηρίου (repository) ενώ προστιθόταν CA-γονέας",ca_child_duplicate:"Έχετε ήδη ένα CA-παιδί με το όνομα '{child}'",ca_child_unknown:"Δεν έχετε CA-παιδί με το όνομα '{child}'",ca_child_resources_required:"Πρέπει να προσδιορίσετε πόρους για το CA-παιδί '{child}'",ca_roa_unknown:"Δεν είναι δυνατή η αφαίρεση άγνωστου ROA '{prefix}-{max_length} => {asn}'",ca_roa_duplicate:"Διπλότυπο ROA '{prefix}-{max_length} => {asn}'",ca_roa_invalid_max_length:"Μη έγκυρο μέγιστο μήκος στο ROA '{prefix}-{max_length} => {asn}'",ca_roa_not_entitled:"Το πρόθεμα ROA '{prefix}' δεν είναι σε κανένα από τα τρέχοντα πιστοποιητικά σας",ta_not_allowed:"Αυτή η λειτουργικότητα δεν υποστηρίζεται από τη δοκιμαστική Άγκυρα Εμπιστοσύνης (Trust Anchor)",ta_name_reserved:"Κατοχυρωμένο όνομα",ca_roa_delta_error:"Το ROA απορρίφθηκε για τους ακόλουθους λόγους",api_insufficient_rights:"Ο χρήστης σας δεν έχει επαρκή δικαιώματα για να εκτελέσει αυτή την ενέργεια. Παρακαλώ επικοινωνείστε με το διαχειριστή σας.",api_invalid_credentials:"Τα παρεχόμενα στοιχεία σύνδεσης είναι λάθος.",api_login_error:"Προέκυψε σφάλμα κατά τη σύνδεση: {cause}",api_auth_transient_error:"Προέκυψε (προσωρινό) σφάλμα κατά τη διαδικασία πιστοποίησης της αίτησης. Παρακαλώ προσπαθήστε αργότερα.",api_auth_permanent_error:"Προέκυψε σφάλμα κατά τη διαδικασία πιστοποίησης της αίτησης. Παρακαλώ επικοινωνείστε με το διαχειριστή σας.",api_auth_session_expired:"Η συνεδρία σας έχει λήξει. Παρακαλώ συνδεθείτε ξανά...",general_error:"Κάτι πήγε λάθος. Παρακαλώ επικοινωνείστε με το διαχειριστή σας."},testbed:{welcome:"Καλωσήρθατε σε αυτή την πλατφόρμα δοκιμών RPKI",disclaimer:{heading:"Αποποίηση Ευθύνης",body:"Αυτή η πλατφόρμα δοκιμών προσφέρει μία εντελώς ανεξάρτητη RPKI ιεραρχία που μπορεί να χρησιμοποιηθεί για σκοπούς αξιολόγησης. Επιτρέπει την εγγραφή οποιουδήποτε πόρου για το CA-παιδί σας. Δεν παρέχονται εγγυήσεις όσον αφορά την διαθεσιμότητα αυτής της υπηρεσίας. Για τυχόν προβλήματα, παρακαλείσθε να μας ενημερώσετε."},rpconfighelp:{heading:"TAL για την πλατφόρμα δοκιμών",body:"Για να ανακτείσετε τα δεδομένα που εκδίδονται από αυτή την πλατφόρμα δοκιμών, παρακαλείσθε να κατεβάσετε αυτόν τον Εντοπιστή Άγκυρας Εμπιστοσύνης (TAL) και να τον ρυθμίσετε στο λογισμικό επικύρωσής (Relying Party Software) σας. Σημειώστε ότι ΟΥΔΕΠΟΤΕ δεν πρέπει να χρησιμοποιήσετε αυτό το TAL σε περιβάλλον παραγωγής. Η χρήση του παρέχεται μόνο για δοκιμές."},regunreg:{heading:"Εγγραφή/Διαγραφή",body:"

Χρησιμοποιήστε τη φόρμα για την εγγραφή της δικής σας Αρχής Πιστοποίησης RPKI ως CA-παιδιού της πλατφόρμας δοκιμών για τη δημιουργία ROA για τους πόρους που κατέχετε.

Εάν δεν επιθυμείτε να φιλοξενήσετε τα δικά σας Rsync και RRDP αποθετήρια (repositories) μπορείτε να χρησιμοποιήσετε τη φόρμα Εγγραφής Εκδότη για να ρυθμίσετε την έκδοση των ROA σας στο αποθετήριο (respository) που παρέχεται από την πλατφόρμα δοκιμών. Χρησιμοποιήστε τις φόρμες Διαγραφής για να ακυρώσετε προηγούμενες σχέσεις (ακόμα και σχέσεις από άλλους χρήστες της πλατφόρμας δοκιμών!).

"},rfcdoclink:"Κάντε κλίκ για να δείτε το RFC-8183 έγγραφο για αυτό το XML",childhandle:"Ονομασία CA-παιδιού",publisherhandle:"Ονομασία Εκδότη",responseXML:"Απάντηση XML της πλατφόρμας δοκιμών",addChild:{heading:"Εγγραφή Αρχής Πιστοποίησης (CA)",requestXML:{label:"Αίτημα XML CA-παιδιού",placeholder:"Επικολλήστε το XML εδώ"},asnresources:{label:"Πόροι ASN",placeholder:"Οι AS πόροι: π.χ. AS1, AS3-4"},ipv4resources:{label:"Πόροι IPv4",placeholder:"Οι IPv4 πόροι: π.χ. 192.168.0.0/16"},ipv6resources:{label:"Πόροι IPv6",placeholder:"Οι IPv6 πόροι: π.χ. 2001:db8::/32"},confirm:"Εγγραφή CA-παιδιού",format:"Μη έγκυρο αίτημα XML CA-παιδού",required:"Παρακαλώ παραχωρήστε το αίτημα XML CA-παιδιού",confirmation:{title:"Προειδοποίηση",message:"Είστε σίγουροι ότι επιθυμείτε την εγγραφή αυτού του CA-παιδιού με την πλατφόρμα δοκιμών;"},success:"Το CA-παιδί '{child_handle}' προστέθηκε στην πλατφόρμα δοκιμών.",registeranother:"Εγγραφή άλλης Αρχής Πιστοποίησης (CA)"},removeChild:{heading:"Διαγραφή Αρχής Πιστοποίησης (CA)",placeholder:"Εισάγετε το όνομα της Αρχής Πιστοποίησης (CA) προς αφαίρεση",confirm:"Αφαίρεση CA-παιδιού",confirmation:{title:"Προειδοποίηση",message:"Είστε σίγουροι ότι επιθυμείτε την διαγραφή αυτού του CA-παιδιού από την πλατφόρμα δοκιμών;"},success:"Το CA-παιδί '{child_handle}' αφαιρέθηκε από την πλατφόρμα δοκιμών."},addPublisher:{heading:"Εγγραφή Εκδότη",requestXML:{label:"Αίτημα XML Εκδότη",placeholder:"Επικολλήστε το XML εδώ"},confirm:"Εγγραφή Εκδότη",format:"Μη έγκυρο αίτημα XML Εκδότη",required:"Παρακαλώ παραχωρήστε το αίτημα XML Εκδότη",confirmation:{title:"Προειδοποίηση",message:"Είστε σίγουροι ότι επιθυμείτε την εγγραφή αυτού του Εκδότη με την πλατφόρμα δοκιμών;"},success:"Ο Εκδότης '{publisher_handle}' προστέθηκε στην πλατφόρμα δοκιμών.",registeranother:"Εγγραφή άλλου Εκδότη"},removePublisher:{heading:"Διαγραφή Εκδότη",placeholder:"Εισάγετε το όνομα Εκδότη προς αφαίρεση",confirm:"Αφαίρεση Εκδότη",confirmation:{title:"Προειδοποίηση",message:"Είστε σίγουροι ότι επιθυμείτε την διαγραφή αυτού του Εκδότη από την πλατφόρμα δοκιμών;"},success:"Ο Εκδότης '{publisher_handle}' αφαιρέθηκε από την πλατφόρμα δοκιμών."},errors:{invalid_xml:"Άκυρο XML: {err}",missing_xml_el:"Έλλειψη στοιχείου {el}",missing_xml_child_el:"Έλλειψη υποστοιχείου {el} του στοιχείου {parent}",missing_xml_attr:"Έλλειψη χαρακτηριστικού {attr} στο στοιχείο {el}",empty_xml_el:"Το στοιχείο {el} δεν μπορεί να είναι άδειο",empty_xml_attr:"Το χαρακτηριστικό {attr} στο στοιχείο {el} δεν μπορεί να είναι άδειο",non_ascii_xml_el:"Το στοιχείο {el} δεν μπορεί να περιέχει χαρακτήρες που δεν είναι ASCII",child_handle_required:"Η ονομασία CA-παιδιού είναι υποχρεωτική",publisher_handle_required:"Η ονομασία Εκδότη είναι υποχρεωτική",non_base64_certificate_xml_el:"Το στοιχείο {el} πρέπει να περιέχει ένα αυτο-υπογεγραμμένο X.509 BPKI πιστοποιητικό με σωστή κωδικοποίηση Base64",invalid_registration_data:"Τα στοιχεία εγγραφής σας δεν μπόρεσαν να αναλυθούν σωστά"}}};export{e as translations}; diff --git a/ui/assets/index-17d9117e.js b/ui/assets/index-17d9117e.js deleted file mode 100644 index e83b6cfe..00000000 --- a/ui/assets/index-17d9117e.js +++ /dev/null @@ -1,114 +0,0 @@ -var $m=Object.defineProperty;var bm=(t,e,n)=>e in t?$m(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var Um=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var oe=(t,e,n)=>(bm(t,typeof e!="symbol"?e+"":e,n),n);var Kw=Um((Jw,rl)=>{(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const i of s)if(i.type==="childList")for(const a of i.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&r(a)}).observe(document,{childList:!0,subtree:!0});function n(s){const i={};return s.integrity&&(i.integrity=s.integrity),s.referrerPolicy&&(i.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?i.credentials="include":s.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function r(s){if(s.ep)return;s.ep=!0;const i=n(s);fetch(s.href,i)}})();function Vm(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var rd={exports:{}},Vi={},sd={exports:{}},F={};/** - * @license React - * react.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var fs=Symbol.for("react.element"),Hm=Symbol.for("react.portal"),Wm=Symbol.for("react.fragment"),qm=Symbol.for("react.strict_mode"),Bm=Symbol.for("react.profiler"),Zm=Symbol.for("react.provider"),Qm=Symbol.for("react.context"),Ym=Symbol.for("react.forward_ref"),Km=Symbol.for("react.suspense"),Gm=Symbol.for("react.memo"),Jm=Symbol.for("react.lazy"),uu=Symbol.iterator;function Xm(t){return t===null||typeof t!="object"?null:(t=uu&&t[uu]||t["@@iterator"],typeof t=="function"?t:null)}var id={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},ad=Object.assign,od={};function hr(t,e,n){this.props=t,this.context=e,this.refs=od,this.updater=n||id}hr.prototype.isReactComponent={};hr.prototype.setState=function(t,e){if(typeof t!="object"&&typeof t!="function"&&t!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,t,e,"setState")};hr.prototype.forceUpdate=function(t){this.updater.enqueueForceUpdate(this,t,"forceUpdate")};function ld(){}ld.prototype=hr.prototype;function sl(t,e,n){this.props=t,this.context=e,this.refs=od,this.updater=n||id}var il=sl.prototype=new ld;il.constructor=sl;ad(il,hr.prototype);il.isPureReactComponent=!0;var cu=Array.isArray,ud=Object.prototype.hasOwnProperty,al={current:null},cd={key:!0,ref:!0,__self:!0,__source:!0};function dd(t,e,n){var r,s={},i=null,a=null;if(e!=null)for(r in e.ref!==void 0&&(a=e.ref),e.key!==void 0&&(i=""+e.key),e)ud.call(e,r)&&!cd.hasOwnProperty(r)&&(s[r]=e[r]);var o=arguments.length-2;if(o===1)s.children=n;else if(1>>1,pe=O[se];if(0>>1;ses(ma,L))hns(Ts,ma)?(O[se]=Ts,O[hn]=L,se=hn):(O[se]=ma,O[fn]=L,se=fn);else if(hns(Ts,L))O[se]=Ts,O[hn]=L,se=hn;else break e}}return I}function s(O,I){var L=O.sortIndex-I.sortIndex;return L!==0?L:O.id-I.id}if(typeof performance=="object"&&typeof performance.now=="function"){var i=performance;t.unstable_now=function(){return i.now()}}else{var a=Date,o=a.now();t.unstable_now=function(){return a.now()-o}}var u=[],c=[],f=1,d=null,p=3,y=!1,w=!1,g=!1,k=typeof setTimeout=="function"?setTimeout:null,m=typeof clearTimeout=="function"?clearTimeout:null,h=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function v(O){for(var I=n(c);I!==null;){if(I.callback===null)r(c);else if(I.startTime<=O)r(c),I.sortIndex=I.expirationTime,e(u,I);else break;I=n(c)}}function x(O){if(g=!1,v(O),!w)if(n(u)!==null)w=!0,fa(S);else{var I=n(c);I!==null&&ha(x,I.startTime-O)}}function S(O,I){w=!1,g&&(g=!1,m(j),j=-1),y=!0;var L=p;try{for(v(I),d=n(u);d!==null&&(!(d.expirationTime>I)||O&&!q());){var se=d.callback;if(typeof se=="function"){d.callback=null,p=d.priorityLevel;var pe=se(d.expirationTime<=I);I=t.unstable_now(),typeof pe=="function"?d.callback=pe:d===n(u)&&r(u),v(I)}else r(u);d=n(u)}if(d!==null)var ks=!0;else{var fn=n(c);fn!==null&&ha(x,fn.startTime-I),ks=!1}return ks}finally{d=null,p=L,y=!1}}var E=!1,N=null,j=-1,D=5,R=-1;function q(){return!(t.unstable_now()-RO||125se?(O.sortIndex=L,e(c,O),n(u)===null&&O===n(c)&&(g?(m(j),j=-1):g=!0,ha(x,L-se))):(O.sortIndex=pe,e(u,O),w||y||(w=!0,fa(S))),O},t.unstable_shouldYield=q,t.unstable_wrapCallback=function(O){var I=p;return function(){var L=p;p=I;try{return O.apply(this,arguments)}finally{p=L}}}})(pd);md.exports=pd;var cp=md.exports;/** - * @license React - * react-dom.production.min.js - * - * Copyright (c) Facebook, Inc. and its affiliates. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */var vd=P,We=cp;function T(t){for(var e="https://reactjs.org/docs/error-decoder.html?invariant="+t,n=1;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Xa=Object.prototype.hasOwnProperty,dp=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,fu={},hu={};function fp(t){return Xa.call(hu,t)?!0:Xa.call(fu,t)?!1:dp.test(t)?hu[t]=!0:(fu[t]=!0,!1)}function hp(t,e,n,r){if(n!==null&&n.type===0)return!1;switch(typeof e){case"function":case"symbol":return!0;case"boolean":return r?!1:n!==null?!n.acceptsBooleans:(t=t.toLowerCase().slice(0,5),t!=="data-"&&t!=="aria-");default:return!1}}function mp(t,e,n,r){if(e===null||typeof e>"u"||hp(t,e,n,r))return!0;if(r)return!1;if(n!==null)switch(n.type){case 3:return!e;case 4:return e===!1;case 5:return isNaN(e);case 6:return isNaN(e)||1>e}return!1}function De(t,e,n,r,s,i,a){this.acceptsBooleans=e===2||e===3||e===4,this.attributeName=r,this.attributeNamespace=s,this.mustUseProperty=n,this.propertyName=t,this.type=e,this.sanitizeURL=i,this.removeEmptyString=a}var xe={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(t){xe[t]=new De(t,0,!1,t,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(t){var e=t[0];xe[e]=new De(e,1,!1,t[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(t){xe[t]=new De(t,2,!1,t.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(t){xe[t]=new De(t,2,!1,t,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(t){xe[t]=new De(t,3,!1,t.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(t){xe[t]=new De(t,3,!0,t,null,!1,!1)});["capture","download"].forEach(function(t){xe[t]=new De(t,4,!1,t,null,!1,!1)});["cols","rows","size","span"].forEach(function(t){xe[t]=new De(t,6,!1,t,null,!1,!1)});["rowSpan","start"].forEach(function(t){xe[t]=new De(t,5,!1,t.toLowerCase(),null,!1,!1)});var ll=/[\-:]([a-z])/g;function ul(t){return t[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(t){var e=t.replace(ll,ul);xe[e]=new De(e,1,!1,t,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(t){var e=t.replace(ll,ul);xe[e]=new De(e,1,!1,t,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(t){var e=t.replace(ll,ul);xe[e]=new De(e,1,!1,t,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(t){xe[t]=new De(t,1,!1,t.toLowerCase(),null,!1,!1)});xe.xlinkHref=new De("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(t){xe[t]=new De(t,1,!1,t.toLowerCase(),null,!0,!0)});function cl(t,e,n,r){var s=xe.hasOwnProperty(e)?xe[e]:null;(s!==null?s.type!==0:r||!(2o||s[a]!==i[o]){var u=` -`+s[a].replace(" at new "," at ");return t.displayName&&u.includes("")&&(u=u.replace("",t.displayName)),u}while(1<=a&&0<=o);break}}}finally{ga=!1,Error.prepareStackTrace=n}return(t=t?t.displayName||t.name:"")?Dr(t):""}function pp(t){switch(t.tag){case 5:return Dr(t.type);case 16:return Dr("Lazy");case 13:return Dr("Suspense");case 19:return Dr("SuspenseList");case 0:case 2:case 15:return t=ya(t.type,!1),t;case 11:return t=ya(t.type.render,!1),t;case 1:return t=ya(t.type,!0),t;default:return""}}function ro(t){if(t==null)return null;if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t;switch(t){case zn:return"Fragment";case Fn:return"Portal";case eo:return"Profiler";case dl:return"StrictMode";case to:return"Suspense";case no:return"SuspenseList"}if(typeof t=="object")switch(t.$$typeof){case wd:return(t.displayName||"Context")+".Consumer";case yd:return(t._context.displayName||"Context")+".Provider";case fl:var e=t.render;return t=t.displayName,t||(t=e.displayName||e.name||"",t=t!==""?"ForwardRef("+t+")":"ForwardRef"),t;case hl:return e=t.displayName||null,e!==null?e:ro(t.type)||"Memo";case bt:e=t._payload,t=t._init;try{return ro(t(e))}catch{}}return null}function vp(t){var e=t.type;switch(t.tag){case 24:return"Cache";case 9:return(e.displayName||"Context")+".Consumer";case 10:return(e._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return t=e.render,t=t.displayName||t.name||"",e.displayName||(t!==""?"ForwardRef("+t+")":"ForwardRef");case 7:return"Fragment";case 5:return e;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return ro(e);case 8:return e===dl?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e}return null}function sn(t){switch(typeof t){case"boolean":case"number":case"string":case"undefined":return t;case"object":return t;default:return""}}function Sd(t){var e=t.type;return(t=t.nodeName)&&t.toLowerCase()==="input"&&(e==="checkbox"||e==="radio")}function gp(t){var e=Sd(t)?"checked":"value",n=Object.getOwnPropertyDescriptor(t.constructor.prototype,e),r=""+t[e];if(!t.hasOwnProperty(e)&&typeof n<"u"&&typeof n.get=="function"&&typeof n.set=="function"){var s=n.get,i=n.set;return Object.defineProperty(t,e,{configurable:!0,get:function(){return s.call(this)},set:function(a){r=""+a,i.call(this,a)}}),Object.defineProperty(t,e,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(a){r=""+a},stopTracking:function(){t._valueTracker=null,delete t[e]}}}}function Cs(t){t._valueTracker||(t._valueTracker=gp(t))}function kd(t){if(!t)return!1;var e=t._valueTracker;if(!e)return!0;var n=e.getValue(),r="";return t&&(r=Sd(t)?t.checked?"true":"false":t.value),t=r,t!==n?(e.setValue(t),!0):!1}function di(t){if(t=t||(typeof document<"u"?document:void 0),typeof t>"u")return null;try{return t.activeElement||t.body}catch{return t.body}}function so(t,e){var n=e.checked;return te({},e,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n??t._wrapperState.initialChecked})}function pu(t,e){var n=e.defaultValue==null?"":e.defaultValue,r=e.checked!=null?e.checked:e.defaultChecked;n=sn(e.value!=null?e.value:n),t._wrapperState={initialChecked:r,initialValue:n,controlled:e.type==="checkbox"||e.type==="radio"?e.checked!=null:e.value!=null}}function Td(t,e){e=e.checked,e!=null&&cl(t,"checked",e,!1)}function io(t,e){Td(t,e);var n=sn(e.value),r=e.type;if(n!=null)r==="number"?(n===0&&t.value===""||t.value!=n)&&(t.value=""+n):t.value!==""+n&&(t.value=""+n);else if(r==="submit"||r==="reset"){t.removeAttribute("value");return}e.hasOwnProperty("value")?ao(t,e.type,n):e.hasOwnProperty("defaultValue")&&ao(t,e.type,sn(e.defaultValue)),e.checked==null&&e.defaultChecked!=null&&(t.defaultChecked=!!e.defaultChecked)}function vu(t,e,n){if(e.hasOwnProperty("value")||e.hasOwnProperty("defaultValue")){var r=e.type;if(!(r!=="submit"&&r!=="reset"||e.value!==void 0&&e.value!==null))return;e=""+t._wrapperState.initialValue,n||e===t.value||(t.value=e),t.defaultValue=e}n=t.name,n!==""&&(t.name=""),t.defaultChecked=!!t._wrapperState.initialChecked,n!==""&&(t.name=n)}function ao(t,e,n){(e!=="number"||di(t.ownerDocument)!==t)&&(n==null?t.defaultValue=""+t._wrapperState.initialValue:t.defaultValue!==""+n&&(t.defaultValue=""+n))}var Ir=Array.isArray;function Kn(t,e,n,r){if(t=t.options,e){e={};for(var s=0;s"+e.valueOf().toString()+"",e=js.firstChild;t.firstChild;)t.removeChild(t.firstChild);for(;e.firstChild;)t.appendChild(e.firstChild)}});function Kr(t,e){if(e){var n=t.firstChild;if(n&&n===t.lastChild&&n.nodeType===3){n.nodeValue=e;return}}t.textContent=e}var zr={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},yp=["Webkit","ms","Moz","O"];Object.keys(zr).forEach(function(t){yp.forEach(function(e){e=e+t.charAt(0).toUpperCase()+t.substring(1),zr[e]=zr[t]})});function jd(t,e,n){return e==null||typeof e=="boolean"||e===""?"":n||typeof e!="number"||e===0||zr.hasOwnProperty(t)&&zr[t]?(""+e).trim():e+"px"}function _d(t,e){t=t.style;for(var n in e)if(e.hasOwnProperty(n)){var r=n.indexOf("--")===0,s=jd(n,e[n],r);n==="float"&&(n="cssFloat"),r?t.setProperty(n,s):t[n]=s}}var wp=te({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function uo(t,e){if(e){if(wp[t]&&(e.children!=null||e.dangerouslySetInnerHTML!=null))throw Error(T(137,t));if(e.dangerouslySetInnerHTML!=null){if(e.children!=null)throw Error(T(60));if(typeof e.dangerouslySetInnerHTML!="object"||!("__html"in e.dangerouslySetInnerHTML))throw Error(T(61))}if(e.style!=null&&typeof e.style!="object")throw Error(T(62))}}function co(t,e){if(t.indexOf("-")===-1)return typeof e.is=="string";switch(t){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var fo=null;function ml(t){return t=t.target||t.srcElement||window,t.correspondingUseElement&&(t=t.correspondingUseElement),t.nodeType===3?t.parentNode:t}var ho=null,Gn=null,Jn=null;function wu(t){if(t=ps(t)){if(typeof ho!="function")throw Error(T(280));var e=t.stateNode;e&&(e=Zi(e),ho(t.stateNode,t.type,e))}}function Od(t){Gn?Jn?Jn.push(t):Jn=[t]:Gn=t}function Pd(){if(Gn){var t=Gn,e=Jn;if(Jn=Gn=null,wu(t),e)for(t=0;t>>=0,t===0?32:31-(Pp(t)/Rp|0)|0}var _s=64,Os=4194304;function Mr(t){switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return t&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return t}}function pi(t,e){var n=t.pendingLanes;if(n===0)return 0;var r=0,s=t.suspendedLanes,i=t.pingedLanes,a=n&268435455;if(a!==0){var o=a&~s;o!==0?r=Mr(o):(i&=a,i!==0&&(r=Mr(i)))}else a=n&~s,a!==0?r=Mr(a):i!==0&&(r=Mr(i));if(r===0)return 0;if(e!==0&&e!==r&&!(e&s)&&(s=r&-r,i=e&-e,s>=i||s===16&&(i&4194240)!==0))return e;if(r&4&&(r|=n&16),e=t.entangledLanes,e!==0)for(t=t.entanglements,e&=r;0n;n++)e.push(t);return e}function hs(t,e,n){t.pendingLanes|=e,e!==536870912&&(t.suspendedLanes=0,t.pingedLanes=0),t=t.eventTimes,e=31-dt(e),t[e]=n}function Lp(t,e){var n=t.pendingLanes&~e;t.pendingLanes=e,t.suspendedLanes=0,t.pingedLanes=0,t.expiredLanes&=e,t.mutableReadLanes&=e,t.entangledLanes&=e,e=t.entanglements;var r=t.eventTimes;for(t=t.expirationTimes;0=br),_u=String.fromCharCode(32),Ou=!1;function Kd(t,e){switch(t){case"keyup":return uv.indexOf(e.keyCode)!==-1;case"keydown":return e.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Gd(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var $n=!1;function dv(t,e){switch(t){case"compositionend":return Gd(e);case"keypress":return e.which!==32?null:(Ou=!0,_u);case"textInput":return t=e.data,t===_u&&Ou?null:t;default:return null}}function fv(t,e){if($n)return t==="compositionend"||!kl&&Kd(t,e)?(t=Qd(),ei=wl=Bt=null,$n=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(e.ctrlKey||e.altKey||e.metaKey)||e.ctrlKey&&e.altKey){if(e.char&&1=e)return{node:n,offset:e-t};t=r}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=Iu(n)}}function tf(t,e){return t&&e?t===e?!0:t&&t.nodeType===3?!1:e&&e.nodeType===3?tf(t,e.parentNode):"contains"in t?t.contains(e):t.compareDocumentPosition?!!(t.compareDocumentPosition(e)&16):!1:!1}function nf(){for(var t=window,e=di();e instanceof t.HTMLIFrameElement;){try{var n=typeof e.contentWindow.location.href=="string"}catch{n=!1}if(n)t=e.contentWindow;else break;e=di(t.document)}return e}function Tl(t){var e=t&&t.nodeName&&t.nodeName.toLowerCase();return e&&(e==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||e==="textarea"||t.contentEditable==="true")}function Sv(t){var e=nf(),n=t.focusedElem,r=t.selectionRange;if(e!==n&&n&&n.ownerDocument&&tf(n.ownerDocument.documentElement,n)){if(r!==null&&Tl(n)){if(e=r.start,t=r.end,t===void 0&&(t=e),"selectionStart"in n)n.selectionStart=e,n.selectionEnd=Math.min(t,n.value.length);else if(t=(e=n.ownerDocument||document)&&e.defaultView||window,t.getSelection){t=t.getSelection();var s=n.textContent.length,i=Math.min(r.start,s);r=r.end===void 0?i:Math.min(r.end,s),!t.extend&&i>r&&(s=r,r=i,i=s),s=Mu(n,i);var a=Mu(n,r);s&&a&&(t.rangeCount!==1||t.anchorNode!==s.node||t.anchorOffset!==s.offset||t.focusNode!==a.node||t.focusOffset!==a.offset)&&(e=e.createRange(),e.setStart(s.node,s.offset),t.removeAllRanges(),i>r?(t.addRange(e),t.extend(a.node,a.offset)):(e.setEnd(a.node,a.offset),t.addRange(e)))}}for(e=[],t=n;t=t.parentNode;)t.nodeType===1&&e.push({element:t,left:t.scrollLeft,top:t.scrollTop});for(typeof n.focus=="function"&&n.focus(),n=0;n=document.documentMode,bn=null,wo=null,Vr=null,xo=!1;function Lu(t,e,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;xo||bn==null||bn!==di(r)||(r=bn,"selectionStart"in r&&Tl(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Vr&&ns(Vr,r)||(Vr=r,r=yi(wo,"onSelect"),0Hn||(t.current=Co[Hn],Co[Hn]=null,Hn--)}function Q(t,e){Hn++,Co[Hn]=t.current,t.current=e}var an={},Ce=ln(an),Fe=ln(!1),En=an;function sr(t,e){var n=t.type.contextTypes;if(!n)return an;var r=t.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===e)return r.__reactInternalMemoizedMaskedChildContext;var s={},i;for(i in n)s[i]=e[i];return r&&(t=t.stateNode,t.__reactInternalMemoizedUnmaskedChildContext=e,t.__reactInternalMemoizedMaskedChildContext=s),s}function ze(t){return t=t.childContextTypes,t!=null}function xi(){G(Fe),G(Ce)}function Vu(t,e,n){if(Ce.current!==an)throw Error(T(168));Q(Ce,e),Q(Fe,n)}function ff(t,e,n){var r=t.stateNode;if(e=e.childContextTypes,typeof r.getChildContext!="function")return n;r=r.getChildContext();for(var s in r)if(!(s in e))throw Error(T(108,vp(t)||"Unknown",s));return te({},n,r)}function Si(t){return t=(t=t.stateNode)&&t.__reactInternalMemoizedMergedChildContext||an,En=Ce.current,Q(Ce,t),Q(Fe,Fe.current),!0}function Hu(t,e,n){var r=t.stateNode;if(!r)throw Error(T(169));n?(t=ff(t,e,En),r.__reactInternalMemoizedMergedChildContext=t,G(Fe),G(Ce),Q(Ce,t)):G(Fe),Q(Fe,n)}var Nt=null,Qi=!1,Da=!1;function hf(t){Nt===null?Nt=[t]:Nt.push(t)}function Iv(t){Qi=!0,hf(t)}function un(){if(!Da&&Nt!==null){Da=!0;var t=0,e=W;try{var n=Nt;for(W=1;t>=a,s-=a,Ct=1<<32-dt(e)+s|n<j?(D=N,N=null):D=N.sibling;var R=p(m,N,v[j],x);if(R===null){N===null&&(N=D);break}t&&N&&R.alternate===null&&e(m,N),h=i(R,h,j),E===null?S=R:E.sibling=R,E=R,N=D}if(j===v.length)return n(m,N),J&&pn(m,j),S;if(N===null){for(;jj?(D=N,N=null):D=N.sibling;var q=p(m,N,R.value,x);if(q===null){N===null&&(N=D);break}t&&N&&q.alternate===null&&e(m,N),h=i(q,h,j),E===null?S=q:E.sibling=q,E=q,N=D}if(R.done)return n(m,N),J&&pn(m,j),S;if(N===null){for(;!R.done;j++,R=v.next())R=d(m,R.value,x),R!==null&&(h=i(R,h,j),E===null?S=R:E.sibling=R,E=R);return J&&pn(m,j),S}for(N=r(m,N);!R.done;j++,R=v.next())R=y(N,m,j,R.value,x),R!==null&&(t&&R.alternate!==null&&N.delete(R.key===null?j:R.key),h=i(R,h,j),E===null?S=R:E.sibling=R,E=R);return t&&N.forEach(function(me){return e(m,me)}),J&&pn(m,j),S}function k(m,h,v,x){if(typeof v=="object"&&v!==null&&v.type===zn&&v.key===null&&(v=v.props.children),typeof v=="object"&&v!==null){switch(v.$$typeof){case Ns:e:{for(var S=v.key,E=h;E!==null;){if(E.key===S){if(S=v.type,S===zn){if(E.tag===7){n(m,E.sibling),h=s(E,v.props.children),h.return=m,m=h;break e}}else if(E.elementType===S||typeof S=="object"&&S!==null&&S.$$typeof===bt&&Ku(S)===E.type){n(m,E.sibling),h=s(E,v.props),h.ref=Cr(m,E,v),h.return=m,m=h;break e}n(m,E);break}else e(m,E);E=E.sibling}v.type===zn?(h=kn(v.props.children,m.mode,x,v.key),h.return=m,m=h):(x=li(v.type,v.key,v.props,null,m.mode,x),x.ref=Cr(m,h,v),x.return=m,m=x)}return a(m);case Fn:e:{for(E=v.key;h!==null;){if(h.key===E)if(h.tag===4&&h.stateNode.containerInfo===v.containerInfo&&h.stateNode.implementation===v.implementation){n(m,h.sibling),h=s(h,v.children||[]),h.return=m,m=h;break e}else{n(m,h);break}else e(m,h);h=h.sibling}h=ba(v,m.mode,x),h.return=m,m=h}return a(m);case bt:return E=v._init,k(m,h,E(v._payload),x)}if(Ir(v))return w(m,h,v,x);if(Sr(v))return g(m,h,v,x);As(m,v)}return typeof v=="string"&&v!==""||typeof v=="number"?(v=""+v,h!==null&&h.tag===6?(n(m,h.sibling),h=s(h,v),h.return=m,m=h):(n(m,h),h=$a(v,m.mode,x),h.return=m,m=h),a(m)):n(m,h)}return k}var ar=Sf(!0),kf=Sf(!1),vs={},St=ln(vs),as=ln(vs),os=ln(vs);function xn(t){if(t===vs)throw Error(T(174));return t}function Dl(t,e){switch(Q(os,e),Q(as,t),Q(St,vs),t=e.nodeType,t){case 9:case 11:e=(e=e.documentElement)?e.namespaceURI:lo(null,"");break;default:t=t===8?e.parentNode:e,e=t.namespaceURI||null,t=t.tagName,e=lo(e,t)}G(St),Q(St,e)}function or(){G(St),G(as),G(os)}function Tf(t){xn(os.current);var e=xn(St.current),n=lo(e,t.type);e!==n&&(Q(as,t),Q(St,n))}function Il(t){as.current===t&&(G(St),G(as))}var X=ln(0);function ji(t){for(var e=t;e!==null;){if(e.tag===13){var n=e.memoizedState;if(n!==null&&(n=n.dehydrated,n===null||n.data==="$?"||n.data==="$!"))return e}else if(e.tag===19&&e.memoizedProps.revealOrder!==void 0){if(e.flags&128)return e}else if(e.child!==null){e.child.return=e,e=e.child;continue}if(e===t)break;for(;e.sibling===null;){if(e.return===null||e.return===t)return null;e=e.return}e.sibling.return=e.return,e=e.sibling}return null}var Ia=[];function Ml(){for(var t=0;tn?n:4,t(!0);var r=Ma.transition;Ma.transition={};try{t(!1),e()}finally{W=n,Ma.transition=r}}function $f(){return rt().memoizedState}function Fv(t,e,n){var r=nn(t);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},bf(t))Uf(e,n);else if(n=gf(t,e,n,r),n!==null){var s=Pe();ft(n,t,r,s),Vf(n,e,r)}}function zv(t,e,n){var r=nn(t),s={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(bf(t))Uf(e,s);else{var i=t.alternate;if(t.lanes===0&&(i===null||i.lanes===0)&&(i=e.lastRenderedReducer,i!==null))try{var a=e.lastRenderedState,o=i(a,n);if(s.hasEagerState=!0,s.eagerState=o,ht(o,a)){var u=e.interleaved;u===null?(s.next=s,Pl(e)):(s.next=u.next,u.next=s),e.interleaved=s;return}}catch{}finally{}n=gf(t,e,s,r),n!==null&&(s=Pe(),ft(n,t,r,s),Vf(n,e,r))}}function bf(t){var e=t.alternate;return t===ee||e!==null&&e===ee}function Uf(t,e){Hr=_i=!0;var n=t.pending;n===null?e.next=e:(e.next=n.next,n.next=e),t.pending=e}function Vf(t,e,n){if(n&4194240){var r=e.lanes;r&=t.pendingLanes,n|=r,e.lanes=n,vl(t,n)}}var Oi={readContext:nt,useCallback:Se,useContext:Se,useEffect:Se,useImperativeHandle:Se,useInsertionEffect:Se,useLayoutEffect:Se,useMemo:Se,useReducer:Se,useRef:Se,useState:Se,useDebugValue:Se,useDeferredValue:Se,useTransition:Se,useMutableSource:Se,useSyncExternalStore:Se,useId:Se,unstable_isNewReconciler:!1},$v={readContext:nt,useCallback:function(t,e){return gt().memoizedState=[t,e===void 0?null:e],t},useContext:nt,useEffect:Ju,useImperativeHandle:function(t,e,n){return n=n!=null?n.concat([t]):null,si(4194308,4,Mf.bind(null,e,t),n)},useLayoutEffect:function(t,e){return si(4194308,4,t,e)},useInsertionEffect:function(t,e){return si(4,2,t,e)},useMemo:function(t,e){var n=gt();return e=e===void 0?null:e,t=t(),n.memoizedState=[t,e],t},useReducer:function(t,e,n){var r=gt();return e=n!==void 0?n(e):e,r.memoizedState=r.baseState=e,t={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:e},r.queue=t,t=t.dispatch=Fv.bind(null,ee,t),[r.memoizedState,t]},useRef:function(t){var e=gt();return t={current:t},e.memoizedState=t},useState:Gu,useDebugValue:$l,useDeferredValue:function(t){return gt().memoizedState=t},useTransition:function(){var t=Gu(!1),e=t[0];return t=Av.bind(null,t[1]),gt().memoizedState=t,[e,t]},useMutableSource:function(){},useSyncExternalStore:function(t,e,n){var r=ee,s=gt();if(J){if(n===void 0)throw Error(T(407));n=n()}else{if(n=e(),ge===null)throw Error(T(349));Cn&30||Cf(r,e,n)}s.memoizedState=n;var i={value:n,getSnapshot:e};return s.queue=i,Ju(_f.bind(null,r,i,t),[t]),r.flags|=2048,cs(9,jf.bind(null,r,i,n,e),void 0,null),n},useId:function(){var t=gt(),e=ge.identifierPrefix;if(J){var n=jt,r=Ct;n=(r&~(1<<32-dt(r)-1)).toString(32)+n,e=":"+e+"R"+n,n=ls++,0<\/script>",t=t.removeChild(t.firstChild)):typeof r.is=="string"?t=a.createElement(n,{is:r.is}):(t=a.createElement(n),n==="select"&&(a=t,r.multiple?a.multiple=!0:r.size&&(a.size=r.size))):t=a.createElementNS(t,n),t[wt]=e,t[is]=r,Gf(t,e,!1,!1),e.stateNode=t;e:{switch(a=co(n,r),n){case"dialog":Y("cancel",t),Y("close",t),s=r;break;case"iframe":case"object":case"embed":Y("load",t),s=r;break;case"video":case"audio":for(s=0;sur&&(e.flags|=128,r=!0,jr(i,!1),e.lanes=4194304)}else{if(!r)if(t=ji(a),t!==null){if(e.flags|=128,r=!0,n=t.updateQueue,n!==null&&(e.updateQueue=n,e.flags|=4),jr(i,!0),i.tail===null&&i.tailMode==="hidden"&&!a.alternate&&!J)return ke(e),null}else 2*ie()-i.renderingStartTime>ur&&n!==1073741824&&(e.flags|=128,r=!0,jr(i,!1),e.lanes=4194304);i.isBackwards?(a.sibling=e.child,e.child=a):(n=i.last,n!==null?n.sibling=a:e.child=a,i.last=a)}return i.tail!==null?(e=i.tail,i.rendering=e,i.tail=e.sibling,i.renderingStartTime=ie(),e.sibling=null,n=X.current,Q(X,r?n&1|2:n&1),e):(ke(e),null);case 22:case 23:return ql(),r=e.memoizedState!==null,t!==null&&t.memoizedState!==null!==r&&(e.flags|=8192),r&&e.mode&1?be&1073741824&&(ke(e),e.subtreeFlags&6&&(e.flags|=8192)):ke(e),null;case 24:return null;case 25:return null}throw Error(T(156,e.tag))}function Zv(t,e){switch(Nl(e),e.tag){case 1:return ze(e.type)&&xi(),t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 3:return or(),G(Fe),G(Ce),Ml(),t=e.flags,t&65536&&!(t&128)?(e.flags=t&-65537|128,e):null;case 5:return Il(e),null;case 13:if(G(X),t=e.memoizedState,t!==null&&t.dehydrated!==null){if(e.alternate===null)throw Error(T(340));ir()}return t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 19:return G(X),null;case 4:return or(),null;case 10:return Ol(e.type._context),null;case 22:case 23:return ql(),null;case 24:return null;default:return null}}var zs=!1,Te=!1,Qv=typeof WeakSet=="function"?WeakSet:Set,_=null;function Zn(t,e){var n=t.ref;if(n!==null)if(typeof n=="function")try{n(null)}catch(r){re(t,e,r)}else n.current=null}function zo(t,e,n){try{n()}catch(r){re(t,e,r)}}var oc=!1;function Yv(t,e){if(So=vi,t=nf(),Tl(t)){if("selectionStart"in t)var n={start:t.selectionStart,end:t.selectionEnd};else e:{n=(n=t.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var s=r.anchorOffset,i=r.focusNode;r=r.focusOffset;try{n.nodeType,i.nodeType}catch{n=null;break e}var a=0,o=-1,u=-1,c=0,f=0,d=t,p=null;t:for(;;){for(var y;d!==n||s!==0&&d.nodeType!==3||(o=a+s),d!==i||r!==0&&d.nodeType!==3||(u=a+r),d.nodeType===3&&(a+=d.nodeValue.length),(y=d.firstChild)!==null;)p=d,d=y;for(;;){if(d===t)break t;if(p===n&&++c===s&&(o=a),p===i&&++f===r&&(u=a),(y=d.nextSibling)!==null)break;d=p,p=d.parentNode}d=y}n=o===-1||u===-1?null:{start:o,end:u}}else n=null}n=n||{start:0,end:0}}else n=null;for(ko={focusedElem:t,selectionRange:n},vi=!1,_=e;_!==null;)if(e=_,t=e.child,(e.subtreeFlags&1028)!==0&&t!==null)t.return=e,_=t;else for(;_!==null;){e=_;try{var w=e.alternate;if(e.flags&1024)switch(e.tag){case 0:case 11:case 15:break;case 1:if(w!==null){var g=w.memoizedProps,k=w.memoizedState,m=e.stateNode,h=m.getSnapshotBeforeUpdate(e.elementType===e.type?g:ot(e.type,g),k);m.__reactInternalSnapshotBeforeUpdate=h}break;case 3:var v=e.stateNode.containerInfo;v.nodeType===1?v.textContent="":v.nodeType===9&&v.documentElement&&v.removeChild(v.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(T(163))}}catch(x){re(e,e.return,x)}if(t=e.sibling,t!==null){t.return=e.return,_=t;break}_=e.return}return w=oc,oc=!1,w}function Wr(t,e,n){var r=e.updateQueue;if(r=r!==null?r.lastEffect:null,r!==null){var s=r=r.next;do{if((s.tag&t)===t){var i=s.destroy;s.destroy=void 0,i!==void 0&&zo(e,n,i)}s=s.next}while(s!==r)}}function Gi(t,e){if(e=e.updateQueue,e=e!==null?e.lastEffect:null,e!==null){var n=e=e.next;do{if((n.tag&t)===t){var r=n.create;n.destroy=r()}n=n.next}while(n!==e)}}function $o(t){var e=t.ref;if(e!==null){var n=t.stateNode;switch(t.tag){case 5:t=n;break;default:t=n}typeof e=="function"?e(t):e.current=t}}function eh(t){var e=t.alternate;e!==null&&(t.alternate=null,eh(e)),t.child=null,t.deletions=null,t.sibling=null,t.tag===5&&(e=t.stateNode,e!==null&&(delete e[wt],delete e[is],delete e[No],delete e[Rv],delete e[Dv])),t.stateNode=null,t.return=null,t.dependencies=null,t.memoizedProps=null,t.memoizedState=null,t.pendingProps=null,t.stateNode=null,t.updateQueue=null}function th(t){return t.tag===5||t.tag===3||t.tag===4}function lc(t){e:for(;;){for(;t.sibling===null;){if(t.return===null||th(t.return))return null;t=t.return}for(t.sibling.return=t.return,t=t.sibling;t.tag!==5&&t.tag!==6&&t.tag!==18;){if(t.flags&2||t.child===null||t.tag===4)continue e;t.child.return=t,t=t.child}if(!(t.flags&2))return t.stateNode}}function bo(t,e,n){var r=t.tag;if(r===5||r===6)t=t.stateNode,e?n.nodeType===8?n.parentNode.insertBefore(t,e):n.insertBefore(t,e):(n.nodeType===8?(e=n.parentNode,e.insertBefore(t,n)):(e=n,e.appendChild(t)),n=n._reactRootContainer,n!=null||e.onclick!==null||(e.onclick=wi));else if(r!==4&&(t=t.child,t!==null))for(bo(t,e,n),t=t.sibling;t!==null;)bo(t,e,n),t=t.sibling}function Uo(t,e,n){var r=t.tag;if(r===5||r===6)t=t.stateNode,e?n.insertBefore(t,e):n.appendChild(t);else if(r!==4&&(t=t.child,t!==null))for(Uo(t,e,n),t=t.sibling;t!==null;)Uo(t,e,n),t=t.sibling}var ye=null,lt=!1;function Ft(t,e,n){for(n=n.child;n!==null;)nh(t,e,n),n=n.sibling}function nh(t,e,n){if(xt&&typeof xt.onCommitFiberUnmount=="function")try{xt.onCommitFiberUnmount(Hi,n)}catch{}switch(n.tag){case 5:Te||Zn(n,e);case 6:var r=ye,s=lt;ye=null,Ft(t,e,n),ye=r,lt=s,ye!==null&&(lt?(t=ye,n=n.stateNode,t.nodeType===8?t.parentNode.removeChild(n):t.removeChild(n)):ye.removeChild(n.stateNode));break;case 18:ye!==null&&(lt?(t=ye,n=n.stateNode,t.nodeType===8?Ra(t.parentNode,n):t.nodeType===1&&Ra(t,n),es(t)):Ra(ye,n.stateNode));break;case 4:r=ye,s=lt,ye=n.stateNode.containerInfo,lt=!0,Ft(t,e,n),ye=r,lt=s;break;case 0:case 11:case 14:case 15:if(!Te&&(r=n.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){s=r=r.next;do{var i=s,a=i.destroy;i=i.tag,a!==void 0&&(i&2||i&4)&&zo(n,e,a),s=s.next}while(s!==r)}Ft(t,e,n);break;case 1:if(!Te&&(Zn(n,e),r=n.stateNode,typeof r.componentWillUnmount=="function"))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(o){re(n,e,o)}Ft(t,e,n);break;case 21:Ft(t,e,n);break;case 22:n.mode&1?(Te=(r=Te)||n.memoizedState!==null,Ft(t,e,n),Te=r):Ft(t,e,n);break;default:Ft(t,e,n)}}function uc(t){var e=t.updateQueue;if(e!==null){t.updateQueue=null;var n=t.stateNode;n===null&&(n=t.stateNode=new Qv),e.forEach(function(r){var s=sg.bind(null,t,r);n.has(r)||(n.add(r),r.then(s,s))})}}function st(t,e){var n=e.deletions;if(n!==null)for(var r=0;rs&&(s=a),r&=~i}if(r=s,r=ie()-r,r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*Gv(r/1960))-r,10t?16:t,Zt===null)var r=!1;else{if(t=Zt,Zt=null,Di=0,V&6)throw Error(T(331));var s=V;for(V|=4,_=t.current;_!==null;){var i=_,a=i.child;if(_.flags&16){var o=i.deletions;if(o!==null){for(var u=0;uie()-Hl?Sn(t,0):Vl|=n),$e(t,e)}function ch(t,e){e===0&&(t.mode&1?(e=Os,Os<<=1,!(Os&130023424)&&(Os=4194304)):e=1);var n=Pe();t=Dt(t,e),t!==null&&(hs(t,e,n),$e(t,n))}function rg(t){var e=t.memoizedState,n=0;e!==null&&(n=e.retryLane),ch(t,n)}function sg(t,e){var n=0;switch(t.tag){case 13:var r=t.stateNode,s=t.memoizedState;s!==null&&(n=s.retryLane);break;case 19:r=t.stateNode;break;default:throw Error(T(314))}r!==null&&r.delete(e),ch(t,n)}var dh;dh=function(t,e,n){if(t!==null)if(t.memoizedProps!==e.pendingProps||Fe.current)Ae=!0;else{if(!(t.lanes&n)&&!(e.flags&128))return Ae=!1,qv(t,e,n);Ae=!!(t.flags&131072)}else Ae=!1,J&&e.flags&1048576&&mf(e,Ti,e.index);switch(e.lanes=0,e.tag){case 2:var r=e.type;ii(t,e),t=e.pendingProps;var s=sr(e,Ce.current);er(e,n),s=Al(null,e,r,t,s,n);var i=Fl();return e.flags|=1,typeof s=="object"&&s!==null&&typeof s.render=="function"&&s.$$typeof===void 0?(e.tag=1,e.memoizedState=null,e.updateQueue=null,ze(r)?(i=!0,Si(e)):i=!1,e.memoizedState=s.state!==null&&s.state!==void 0?s.state:null,Rl(e),s.updater=Yi,e.stateNode=s,s._reactInternals=e,Ro(e,r,t,n),e=Mo(null,e,r,!0,i,n)):(e.tag=0,J&&i&&El(e),_e(null,e,s,n),e=e.child),e;case 16:r=e.elementType;e:{switch(ii(t,e),t=e.pendingProps,s=r._init,r=s(r._payload),e.type=r,s=e.tag=ag(r),t=ot(r,t),s){case 0:e=Io(null,e,r,t,n);break e;case 1:e=sc(null,e,r,t,n);break e;case 11:e=nc(null,e,r,t,n);break e;case 14:e=rc(null,e,r,ot(r.type,t),n);break e}throw Error(T(306,r,""))}return e;case 0:return r=e.type,s=e.pendingProps,s=e.elementType===r?s:ot(r,s),Io(t,e,r,s,n);case 1:return r=e.type,s=e.pendingProps,s=e.elementType===r?s:ot(r,s),sc(t,e,r,s,n);case 3:e:{if(Qf(e),t===null)throw Error(T(387));r=e.pendingProps,i=e.memoizedState,s=i.element,yf(t,e),Ci(e,r,null,n);var a=e.memoizedState;if(r=a.element,i.isDehydrated)if(i={element:r,isDehydrated:!1,cache:a.cache,pendingSuspenseBoundaries:a.pendingSuspenseBoundaries,transitions:a.transitions},e.updateQueue.baseState=i,e.memoizedState=i,e.flags&256){s=lr(Error(T(423)),e),e=ic(t,e,r,n,s);break e}else if(r!==s){s=lr(Error(T(424)),e),e=ic(t,e,r,n,s);break e}else for(Ue=Xt(e.stateNode.containerInfo.firstChild),Ve=e,J=!0,ut=null,n=kf(e,null,r,n),e.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling;else{if(ir(),r===s){e=It(t,e,n);break e}_e(t,e,r,n)}e=e.child}return e;case 5:return Tf(e),t===null&&_o(e),r=e.type,s=e.pendingProps,i=t!==null?t.memoizedProps:null,a=s.children,To(r,s)?a=null:i!==null&&To(r,i)&&(e.flags|=32),Zf(t,e),_e(t,e,a,n),e.child;case 6:return t===null&&_o(e),null;case 13:return Yf(t,e,n);case 4:return Dl(e,e.stateNode.containerInfo),r=e.pendingProps,t===null?e.child=ar(e,null,r,n):_e(t,e,r,n),e.child;case 11:return r=e.type,s=e.pendingProps,s=e.elementType===r?s:ot(r,s),nc(t,e,r,s,n);case 7:return _e(t,e,e.pendingProps,n),e.child;case 8:return _e(t,e,e.pendingProps.children,n),e.child;case 12:return _e(t,e,e.pendingProps.children,n),e.child;case 10:e:{if(r=e.type._context,s=e.pendingProps,i=e.memoizedProps,a=s.value,Q(Ei,r._currentValue),r._currentValue=a,i!==null)if(ht(i.value,a)){if(i.children===s.children&&!Fe.current){e=It(t,e,n);break e}}else for(i=e.child,i!==null&&(i.return=e);i!==null;){var o=i.dependencies;if(o!==null){a=i.child;for(var u=o.firstContext;u!==null;){if(u.context===r){if(i.tag===1){u=Ot(-1,n&-n),u.tag=2;var c=i.updateQueue;if(c!==null){c=c.shared;var f=c.pending;f===null?u.next=u:(u.next=f.next,f.next=u),c.pending=u}}i.lanes|=n,u=i.alternate,u!==null&&(u.lanes|=n),Oo(i.return,n,e),o.lanes|=n;break}u=u.next}}else if(i.tag===10)a=i.type===e.type?null:i.child;else if(i.tag===18){if(a=i.return,a===null)throw Error(T(341));a.lanes|=n,o=a.alternate,o!==null&&(o.lanes|=n),Oo(a,n,e),a=i.sibling}else a=i.child;if(a!==null)a.return=i;else for(a=i;a!==null;){if(a===e){a=null;break}if(i=a.sibling,i!==null){i.return=a.return,a=i;break}a=a.return}i=a}_e(t,e,s.children,n),e=e.child}return e;case 9:return s=e.type,r=e.pendingProps.children,er(e,n),s=nt(s),r=r(s),e.flags|=1,_e(t,e,r,n),e.child;case 14:return r=e.type,s=ot(r,e.pendingProps),s=ot(r.type,s),rc(t,e,r,s,n);case 15:return qf(t,e,e.type,e.pendingProps,n);case 17:return r=e.type,s=e.pendingProps,s=e.elementType===r?s:ot(r,s),ii(t,e),e.tag=1,ze(r)?(t=!0,Si(e)):t=!1,er(e,n),xf(e,r,s),Ro(e,r,s,n),Mo(null,e,r,!0,t,n);case 19:return Kf(t,e,n);case 22:return Bf(t,e,n)}throw Error(T(156,e.tag))};function fh(t,e){return Fd(t,e)}function ig(t,e,n,r){this.tag=t,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=e,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Je(t,e,n,r){return new ig(t,e,n,r)}function Zl(t){return t=t.prototype,!(!t||!t.isReactComponent)}function ag(t){if(typeof t=="function")return Zl(t)?1:0;if(t!=null){if(t=t.$$typeof,t===fl)return 11;if(t===hl)return 14}return 2}function rn(t,e){var n=t.alternate;return n===null?(n=Je(t.tag,e,t.key,t.mode),n.elementType=t.elementType,n.type=t.type,n.stateNode=t.stateNode,n.alternate=t,t.alternate=n):(n.pendingProps=e,n.type=t.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=t.flags&14680064,n.childLanes=t.childLanes,n.lanes=t.lanes,n.child=t.child,n.memoizedProps=t.memoizedProps,n.memoizedState=t.memoizedState,n.updateQueue=t.updateQueue,e=t.dependencies,n.dependencies=e===null?null:{lanes:e.lanes,firstContext:e.firstContext},n.sibling=t.sibling,n.index=t.index,n.ref=t.ref,n}function li(t,e,n,r,s,i){var a=2;if(r=t,typeof t=="function")Zl(t)&&(a=1);else if(typeof t=="string")a=5;else e:switch(t){case zn:return kn(n.children,s,i,e);case dl:a=8,s|=8;break;case eo:return t=Je(12,n,e,s|2),t.elementType=eo,t.lanes=i,t;case to:return t=Je(13,n,e,s),t.elementType=to,t.lanes=i,t;case no:return t=Je(19,n,e,s),t.elementType=no,t.lanes=i,t;case xd:return Xi(n,s,i,e);default:if(typeof t=="object"&&t!==null)switch(t.$$typeof){case yd:a=10;break e;case wd:a=9;break e;case fl:a=11;break e;case hl:a=14;break e;case bt:a=16,r=null;break e}throw Error(T(130,t==null?t:typeof t,""))}return e=Je(a,n,e,s),e.elementType=t,e.type=r,e.lanes=i,e}function kn(t,e,n,r){return t=Je(7,t,r,e),t.lanes=n,t}function Xi(t,e,n,r){return t=Je(22,t,r,e),t.elementType=xd,t.lanes=n,t.stateNode={isHidden:!1},t}function $a(t,e,n){return t=Je(6,t,null,e),t.lanes=n,t}function ba(t,e,n){return e=Je(4,t.children!==null?t.children:[],t.key,e),e.lanes=n,e.stateNode={containerInfo:t.containerInfo,pendingChildren:null,implementation:t.implementation},e}function og(t,e,n,r,s){this.tag=e,this.containerInfo=t,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=xa(0),this.expirationTimes=xa(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=xa(0),this.identifierPrefix=r,this.onRecoverableError=s,this.mutableSourceEagerHydrationData=null}function Ql(t,e,n,r,s,i,a,o,u){return t=new og(t,e,n,o,u),e===1?(e=1,i===!0&&(e|=8)):e=0,i=Je(3,null,null,e),t.current=i,i.stateNode=t,i.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Rl(i),t}function lg(t,e,n){var r=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(vh)}catch(t){console.error(t)}}vh(),hd.exports=qe;var hg=hd.exports,gh,gc=hg;gh=gc.createRoot,gc.hydrateRoot;var Bo=function(t){return t.split(".").reduce(function(e,n){return e.concat(e.length?e[e.length-1]+"."+n:n)},[])},mg=function(t){return t!=null},Zo=function(t){return t&&t.meta&&t.meta.params},yc=function(t,e){return!Zo(e)||!mg(e.meta.params[t])?{}:Object.keys(e.meta.params[t]).reduce(function(n,r){return n[r]=e.params[r],n},{})};function yh(t,e){var n=t.meta&&t.meta&&t.meta.options||{},r=e?Bo(e.name):[],s=Bo(t.name),i=Math.min(r.length,s.length);function a(){var d,p=function(){var w=r[d],g=s[d];if(w!==g)return{value:d};var k=yc(w,t),m=yc(g,e);if(Object.keys(k).length!==Object.keys(m).length)return{value:d};if(Object.keys(k).length===0)return"continue";var h=Object.keys(k).some(function(v){return m[v]!==k[v]});if(h)return{value:d}};for(d=0;d0?r[o-1]:"";return{intersection:f,toDeactivate:u,toActivate:c}}/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -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 - -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */function pg(){for(var t=0,e=0,n=arguments.length;e(t.success="success",t.warning="warning",t.error="error",t))(U||{}),Ie=(t=>(t.RoaSeen="roa_seen",t.RoaUnseen="roa_unseen",t.RoaNotHeld="roa_not_held",t.RoaNoAnnouncementInfo="roa_no_announcement_info",t.RoaTooPermissive="roa_too_permissive",t.RoaDisallowing="roa_disallowing",t.RoaRedundant="roa_redundant",t.RoaAs0="roa_as0",t.RoaAs0Redundant="roa_as0_redundant",t.AnnouncementNotFound="announcement_not_found",t.AnnouncementInvalidLength="announcement_invalid_length",t.AnnouncementInvalidAsn="announcement_invalid_asn",t.AnnouncementDisallowedAs0="announcement_disallowed",t))(Ie||{}),Yn=(t=>(t.asn="asn",t.comment="comment",t.prefix="prefix",t.state="state",t))(Yn||{}),Li=(t=>(t.customer="customer",t.providers="providers",t))(Li||{}),Ne=(t=>(t.asc="asc",t.desc="desc",t))(Ne||{}),vt=(t=>(t.notFound="not_found",t.invalidAsn="invalid_asn",t.invalidLength="invalid_length",t.tooPermissive="too_permissive",t.disallowing="disallowing",t.stale="stale",t.redundant="redundant",t.as0Redundant="as0_redundant",t.specific="specific",t))(vt||{}),yt=(t=>(t[t.unchecked=0]="unchecked",t[t.checked=1]="checked",t[t.intermediate=2]="intermediate",t))(yt||{}),Ai=(t=>(t.action="action",t.reason="reason",t.asn="asn",t.maxLength="max_length",t.prefix="prefix",t))(Ai||{});class Rn extends Error{}class Tg extends Rn{constructor(e){super(`Invalid DateTime: ${e.toMessage()}`)}}class Eg extends Rn{constructor(e){super(`Invalid Interval: ${e.toMessage()}`)}}class Ng extends Rn{constructor(e){super(`Invalid Duration: ${e.toMessage()}`)}}class Ar extends Rn{}class Sh extends Rn{constructor(e){super(`Invalid unit ${e}`)}}class Ge extends Rn{}class zt extends Rn{constructor(){super("Zone is an abstract class")}}const C="numeric",mt="short",He="long",Fi={year:C,month:C,day:C},kh={year:C,month:mt,day:C},Cg={year:C,month:mt,day:C,weekday:mt},Th={year:C,month:He,day:C},Eh={year:C,month:He,day:C,weekday:He},Nh={hour:C,minute:C},Ch={hour:C,minute:C,second:C},jh={hour:C,minute:C,second:C,timeZoneName:mt},_h={hour:C,minute:C,second:C,timeZoneName:He},Oh={hour:C,minute:C,hourCycle:"h23"},Ph={hour:C,minute:C,second:C,hourCycle:"h23"},Rh={hour:C,minute:C,second:C,hourCycle:"h23",timeZoneName:mt},Dh={hour:C,minute:C,second:C,hourCycle:"h23",timeZoneName:He},Ih={year:C,month:C,day:C,hour:C,minute:C},Mh={year:C,month:C,day:C,hour:C,minute:C,second:C},Lh={year:C,month:mt,day:C,hour:C,minute:C},Ah={year:C,month:mt,day:C,hour:C,minute:C,second:C},jg={year:C,month:mt,day:C,weekday:mt,hour:C,minute:C},Fh={year:C,month:He,day:C,hour:C,minute:C,timeZoneName:mt},zh={year:C,month:He,day:C,hour:C,minute:C,second:C,timeZoneName:mt},$h={year:C,month:He,day:C,weekday:He,hour:C,minute:C,timeZoneName:He},bh={year:C,month:He,day:C,weekday:He,hour:C,minute:C,second:C,timeZoneName:He};class gs{get type(){throw new zt}get name(){throw new zt}get ianaName(){return this.name}get isUniversal(){throw new zt}offsetName(e,n){throw new zt}formatOffset(e,n){throw new zt}offset(e){throw new zt}equals(e){throw new zt}get isValid(){throw new zt}}let Ua=null;class ia extends gs{static get instance(){return Ua===null&&(Ua=new ia),Ua}get type(){return"system"}get name(){return new Intl.DateTimeFormat().resolvedOptions().timeZone}get isUniversal(){return!1}offsetName(e,{format:n,locale:r}){return Vh(e,n,r)}formatOffset(e,n){return Qr(this.offset(e),n)}offset(e){return-new Date(e).getTimezoneOffset()}equals(e){return e.type==="system"}get isValid(){return!0}}let ui={};function _g(t){return ui[t]||(ui[t]=new Intl.DateTimeFormat("en-US",{hour12:!1,timeZone:t,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",era:"short"})),ui[t]}const Og={year:0,month:1,day:2,era:3,hour:4,minute:5,second:6};function Pg(t,e){const n=t.format(e).replace(/\u200E/g,""),r=/(\d+)\/(\d+)\/(\d+) (AD|BC),? (\d+):(\d+):(\d+)/.exec(n),[,s,i,a,o,u,c,f]=r;return[a,s,i,o,u,c,f]}function Rg(t,e){const n=t.formatToParts(e),r=[];for(let s=0;s=0?w:1e3+w,(p-y)/(60*1e3)}equals(e){return e.type==="iana"&&e.name===this.name}get isValid(){return this.valid}}let wc={};function Dg(t,e={}){const n=JSON.stringify([t,e]);let r=wc[n];return r||(r=new Intl.ListFormat(t,e),wc[n]=r),r}let Yo={};function Ko(t,e={}){const n=JSON.stringify([t,e]);let r=Yo[n];return r||(r=new Intl.DateTimeFormat(t,e),Yo[n]=r),r}let Go={};function Ig(t,e={}){const n=JSON.stringify([t,e]);let r=Go[n];return r||(r=new Intl.NumberFormat(t,e),Go[n]=r),r}let Jo={};function Mg(t,e={}){const{base:n,...r}=e,s=JSON.stringify([t,r]);let i=Jo[s];return i||(i=new Intl.RelativeTimeFormat(t,e),Jo[s]=i),i}let Fr=null;function Lg(){return Fr||(Fr=new Intl.DateTimeFormat().resolvedOptions().locale,Fr)}function Ag(t){const e=t.indexOf("-x-");e!==-1&&(t=t.substring(0,e));const n=t.indexOf("-u-");if(n===-1)return[t];{let r,s;try{r=Ko(t).resolvedOptions(),s=t}catch{const u=t.substring(0,n);r=Ko(u).resolvedOptions(),s=u}const{numberingSystem:i,calendar:a}=r;return[s,i,a]}}function Fg(t,e,n){return(n||e)&&(t.includes("-u-")||(t+="-u"),n&&(t+=`-ca-${n}`),e&&(t+=`-nu-${e}`)),t}function zg(t){const e=[];for(let n=1;n<=12;n++){const r=M.utc(2016,n,1);e.push(t(r))}return e}function $g(t){const e=[];for(let n=1;n<=7;n++){const r=M.utc(2016,11,13+n);e.push(t(r))}return e}function Vs(t,e,n,r,s){const i=t.listingMode(n);return i==="error"?null:i==="en"?r(e):s(e)}function bg(t){return t.numberingSystem&&t.numberingSystem!=="latn"?!1:t.numberingSystem==="latn"||!t.locale||t.locale.startsWith("en")||new Intl.DateTimeFormat(t.intl).resolvedOptions().numberingSystem==="latn"}class Ug{constructor(e,n,r){this.padTo=r.padTo||0,this.floor=r.floor||!1;const{padTo:s,floor:i,...a}=r;if(!n||Object.keys(a).length>0){const o={useGrouping:!1,...r};r.padTo>0&&(o.minimumIntegerDigits=r.padTo),this.inf=Ig(e,o)}}format(e){if(this.inf){const n=this.floor?Math.floor(e):e;return this.inf.format(n)}else{const n=this.floor?Math.floor(e):tu(e,3);return ue(n,this.padTo)}}}class Vg{constructor(e,n,r){this.opts=r,this.originalZone=void 0;let s;if(this.opts.timeZone)this.dt=e;else if(e.zone.type==="fixed"){const a=-1*(e.offset/60),o=a>=0?`Etc/GMT+${a}`:`Etc/GMT${a}`;e.offset!==0&&Mt.create(o).valid?(s=o,this.dt=e):(s="UTC",this.dt=e.offset===0?e:e.setZone("UTC").plus({minutes:e.offset}),this.originalZone=e.zone)}else e.zone.type==="system"?this.dt=e:e.zone.type==="iana"?(this.dt=e,s=e.zone.name):(s="UTC",this.dt=e.setZone("UTC").plus({minutes:e.offset}),this.originalZone=e.zone);const i={...this.opts};i.timeZone=i.timeZone||s,this.dtf=Ko(n,i)}format(){return this.originalZone?this.formatToParts().map(({value:e})=>e).join(""):this.dtf.format(this.dt.toJSDate())}formatToParts(){const e=this.dtf.formatToParts(this.dt.toJSDate());return this.originalZone?e.map(n=>{if(n.type==="timeZoneName"){const r=this.originalZone.offsetName(this.dt.ts,{locale:this.dt.locale,format:this.opts.timeZoneName});return{...n,value:r}}else return n}):e}resolvedOptions(){return this.dtf.resolvedOptions()}}class Hg{constructor(e,n,r){this.opts={style:"long",...r},!n&&Uh()&&(this.rtf=Mg(e,r))}format(e,n){return this.rtf?this.rtf.format(e,n):ay(n,e,this.opts.numeric,this.opts.style!=="long")}formatToParts(e,n){return this.rtf?this.rtf.formatToParts(e,n):[]}}class K{static fromOpts(e){return K.create(e.locale,e.numberingSystem,e.outputCalendar,e.defaultToEN)}static create(e,n,r,s=!1){const i=e||le.defaultLocale,a=i||(s?"en-US":Lg()),o=n||le.defaultNumberingSystem,u=r||le.defaultOutputCalendar;return new K(a,o,u,i)}static resetCache(){Fr=null,Yo={},Go={},Jo={}}static fromObject({locale:e,numberingSystem:n,outputCalendar:r}={}){return K.create(e,n,r)}constructor(e,n,r,s){const[i,a,o]=Ag(e);this.locale=i,this.numberingSystem=n||a||null,this.outputCalendar=r||o||null,this.intl=Fg(this.locale,this.numberingSystem,this.outputCalendar),this.weekdaysCache={format:{},standalone:{}},this.monthsCache={format:{},standalone:{}},this.meridiemCache=null,this.eraCache={},this.specifiedLocale=s,this.fastNumbersCached=null}get fastNumbers(){return this.fastNumbersCached==null&&(this.fastNumbersCached=bg(this)),this.fastNumbersCached}listingMode(){const e=this.isEnglish(),n=(this.numberingSystem===null||this.numberingSystem==="latn")&&(this.outputCalendar===null||this.outputCalendar==="gregory");return e&&n?"en":"intl"}clone(e){return!e||Object.getOwnPropertyNames(e).length===0?this:K.create(e.locale||this.specifiedLocale,e.numberingSystem||this.numberingSystem,e.outputCalendar||this.outputCalendar,e.defaultToEN||!1)}redefaultToEN(e={}){return this.clone({...e,defaultToEN:!0})}redefaultToSystem(e={}){return this.clone({...e,defaultToEN:!1})}months(e,n=!1,r=!0){return Vs(this,e,r,qh,()=>{const s=n?{month:e,day:"numeric"}:{month:e},i=n?"format":"standalone";return this.monthsCache[i][e]||(this.monthsCache[i][e]=zg(a=>this.extract(a,s,"month"))),this.monthsCache[i][e]})}weekdays(e,n=!1,r=!0){return Vs(this,e,r,Qh,()=>{const s=n?{weekday:e,year:"numeric",month:"long",day:"numeric"}:{weekday:e},i=n?"format":"standalone";return this.weekdaysCache[i][e]||(this.weekdaysCache[i][e]=$g(a=>this.extract(a,s,"weekday"))),this.weekdaysCache[i][e]})}meridiems(e=!0){return Vs(this,void 0,e,()=>Yh,()=>{if(!this.meridiemCache){const n={hour:"numeric",hourCycle:"h12"};this.meridiemCache=[M.utc(2016,11,13,9),M.utc(2016,11,13,19)].map(r=>this.extract(r,n,"dayperiod"))}return this.meridiemCache})}eras(e,n=!0){return Vs(this,e,n,Kh,()=>{const r={era:e};return this.eraCache[e]||(this.eraCache[e]=[M.utc(-40,1,1),M.utc(2017,1,1)].map(s=>this.extract(s,r,"era"))),this.eraCache[e]})}extract(e,n,r){const s=this.dtFormatter(e,n),i=s.formatToParts(),a=i.find(o=>o.type.toLowerCase()===r);return a?a.value:null}numberFormatter(e={}){return new Ug(this.intl,e.forceSimple||this.fastNumbers,e)}dtFormatter(e,n={}){return new Vg(e,this.intl,n)}relFormatter(e={}){return new Hg(this.intl,this.isEnglish(),e)}listFormatter(e={}){return Dg(this.intl,e)}isEnglish(){return this.locale==="en"||this.locale.toLowerCase()==="en-us"||new Intl.DateTimeFormat(this.intl).resolvedOptions().locale.startsWith("en-us")}equals(e){return this.locale===e.locale&&this.numberingSystem===e.numberingSystem&&this.outputCalendar===e.outputCalendar}}let Va=null;class Oe extends gs{static get utcInstance(){return Va===null&&(Va=new Oe(0)),Va}static instance(e){return e===0?Oe.utcInstance:new Oe(e)}static parseSpecifier(e){if(e){const n=e.match(/^utc(?:([+-]\d{1,2})(?::(\d{2}))?)?$/i);if(n)return new Oe(oa(n[1],n[2]))}return null}constructor(e){super(),this.fixed=e}get type(){return"fixed"}get name(){return this.fixed===0?"UTC":`UTC${Qr(this.fixed,"narrow")}`}get ianaName(){return this.fixed===0?"Etc/UTC":`Etc/GMT${Qr(-this.fixed,"narrow")}`}offsetName(){return this.name}formatOffset(e,n){return Qr(this.fixed,n)}get isUniversal(){return!0}offset(){return this.fixed}equals(e){return e.type==="fixed"&&e.fixed===this.fixed}get isValid(){return!0}}class Wg extends gs{constructor(e){super(),this.zoneName=e}get type(){return"invalid"}get name(){return this.zoneName}get isUniversal(){return!1}offsetName(){return null}formatOffset(){return""}offset(){return NaN}equals(){return!1}get isValid(){return!1}}function qt(t,e){if($(t)||t===null)return e;if(t instanceof gs)return t;if(qg(t)){const n=t.toLowerCase();return n==="default"?e:n==="local"||n==="system"?ia.instance:n==="utc"||n==="gmt"?Oe.utcInstance:Oe.parseSpecifier(n)||Mt.create(t)}else return Tn(t)?Oe.instance(t):typeof t=="object"&&t.offset&&typeof t.offset=="number"?t:new Wg(t)}let xc=()=>Date.now(),Sc="system",kc=null,Tc=null,Ec=null,Nc=60,Cc;class le{static get now(){return xc}static set now(e){xc=e}static set defaultZone(e){Sc=e}static get defaultZone(){return qt(Sc,ia.instance)}static get defaultLocale(){return kc}static set defaultLocale(e){kc=e}static get defaultNumberingSystem(){return Tc}static set defaultNumberingSystem(e){Tc=e}static get defaultOutputCalendar(){return Ec}static set defaultOutputCalendar(e){Ec=e}static get twoDigitCutoffYear(){return Nc}static set twoDigitCutoffYear(e){Nc=e%100}static get throwOnInvalid(){return Cc}static set throwOnInvalid(e){Cc=e}static resetCaches(){K.resetCache(),Mt.resetCache()}}function $(t){return typeof t>"u"}function Tn(t){return typeof t=="number"}function aa(t){return typeof t=="number"&&t%1===0}function qg(t){return typeof t=="string"}function Bg(t){return Object.prototype.toString.call(t)==="[object Date]"}function Uh(){try{return typeof Intl<"u"&&!!Intl.RelativeTimeFormat}catch{return!1}}function Zg(t){return Array.isArray(t)?t:[t]}function jc(t,e,n){if(t.length!==0)return t.reduce((r,s)=>{const i=[e(s),s];return r&&n(r[0],i[0])===r[0]?r:i},null)[1]}function Qg(t,e){return e.reduce((n,r)=>(n[r]=t[r],n),{})}function dr(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function _t(t,e,n){return aa(t)&&t>=e&&t<=n}function Yg(t,e){return t-e*Math.floor(t/e)}function ue(t,e=2){const n=t<0;let r;return n?r="-"+(""+-t).padStart(e,"0"):r=(""+t).padStart(e,"0"),r}function Vt(t){if(!($(t)||t===null||t===""))return parseInt(t,10)}function mn(t){if(!($(t)||t===null||t===""))return parseFloat(t)}function eu(t){if(!($(t)||t===null||t==="")){const e=parseFloat("0."+t)*1e3;return Math.floor(e)}}function tu(t,e,n=!1){const r=10**e;return(n?Math.trunc:Math.round)(t*r)/r}function ys(t){return t%4===0&&(t%100!==0||t%400===0)}function Zr(t){return ys(t)?366:365}function zi(t,e){const n=Yg(e-1,12)+1,r=t+(e-n)/12;return n===2?ys(r)?29:28:[31,null,31,30,31,30,31,31,30,31,30,31][n-1]}function nu(t){let e=Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,t.second,t.millisecond);return t.year<100&&t.year>=0&&(e=new Date(e),e.setUTCFullYear(t.year,t.month-1,t.day)),+e}function $i(t){const e=(t+Math.floor(t/4)-Math.floor(t/100)+Math.floor(t/400))%7,n=t-1,r=(n+Math.floor(n/4)-Math.floor(n/100)+Math.floor(n/400))%7;return e===4||r===3?53:52}function Xo(t){return t>99?t:t>le.twoDigitCutoffYear?1900+t:2e3+t}function Vh(t,e,n,r=null){const s=new Date(t),i={hourCycle:"h23",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"};r&&(i.timeZone=r);const a={timeZoneName:e,...i},o=new Intl.DateTimeFormat(n,a).formatToParts(s).find(u=>u.type.toLowerCase()==="timezonename");return o?o.value:null}function oa(t,e){let n=parseInt(t,10);Number.isNaN(n)&&(n=0);const r=parseInt(e,10)||0,s=n<0||Object.is(n,-0)?-r:r;return n*60+s}function Hh(t){const e=Number(t);if(typeof t=="boolean"||t===""||Number.isNaN(e))throw new Ge(`Invalid unit value ${t}`);return e}function bi(t,e){const n={};for(const r in t)if(dr(t,r)){const s=t[r];if(s==null)continue;n[e(r)]=Hh(s)}return n}function Qr(t,e){const n=Math.trunc(Math.abs(t/60)),r=Math.trunc(Math.abs(t%60)),s=t>=0?"+":"-";switch(e){case"short":return`${s}${ue(n,2)}:${ue(r,2)}`;case"narrow":return`${s}${n}${r>0?`:${r}`:""}`;case"techie":return`${s}${ue(n,2)}${ue(r,2)}`;default:throw new RangeError(`Value format ${e} is out of range for property format`)}}function la(t){return Qg(t,["hour","minute","second","millisecond"])}const Kg=["January","February","March","April","May","June","July","August","September","October","November","December"],Wh=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],Gg=["J","F","M","A","M","J","J","A","S","O","N","D"];function qh(t){switch(t){case"narrow":return[...Gg];case"short":return[...Wh];case"long":return[...Kg];case"numeric":return["1","2","3","4","5","6","7","8","9","10","11","12"];case"2-digit":return["01","02","03","04","05","06","07","08","09","10","11","12"];default:return null}}const Bh=["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],Zh=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"],Jg=["M","T","W","T","F","S","S"];function Qh(t){switch(t){case"narrow":return[...Jg];case"short":return[...Zh];case"long":return[...Bh];case"numeric":return["1","2","3","4","5","6","7"];default:return null}}const Yh=["AM","PM"],Xg=["Before Christ","Anno Domini"],ey=["BC","AD"],ty=["B","A"];function Kh(t){switch(t){case"narrow":return[...ty];case"short":return[...ey];case"long":return[...Xg];default:return null}}function ny(t){return Yh[t.hour<12?0:1]}function ry(t,e){return Qh(e)[t.weekday-1]}function sy(t,e){return qh(e)[t.month-1]}function iy(t,e){return Kh(e)[t.year<0?0:1]}function ay(t,e,n="always",r=!1){const s={years:["year","yr."],quarters:["quarter","qtr."],months:["month","mo."],weeks:["week","wk."],days:["day","day","days"],hours:["hour","hr."],minutes:["minute","min."],seconds:["second","sec."]},i=["hours","minutes","seconds"].indexOf(t)===-1;if(n==="auto"&&i){const d=t==="days";switch(e){case 1:return d?"tomorrow":`next ${s[t][0]}`;case-1:return d?"yesterday":`last ${s[t][0]}`;case 0:return d?"today":`this ${s[t][0]}`}}const a=Object.is(e,-0)||e<0,o=Math.abs(e),u=o===1,c=s[t],f=r?u?c[1]:c[2]||c[1]:u?s[t][0]:t;return a?`${o} ${f} ago`:`in ${o} ${f}`}function _c(t,e){let n="";for(const r of t)r.literal?n+=r.val:n+=e(r.val);return n}const oy={D:Fi,DD:kh,DDD:Th,DDDD:Eh,t:Nh,tt:Ch,ttt:jh,tttt:_h,T:Oh,TT:Ph,TTT:Rh,TTTT:Dh,f:Ih,ff:Lh,fff:Fh,ffff:$h,F:Mh,FF:Ah,FFF:zh,FFFF:bh};class Ee{static create(e,n={}){return new Ee(e,n)}static parseFormat(e){let n=null,r="",s=!1;const i=[];for(let a=0;a0&&i.push({literal:s||/^\s+$/.test(r),val:r}),n=null,r="",s=!s):s||o===n?r+=o:(r.length>0&&i.push({literal:/^\s+$/.test(r),val:r}),r=o,n=o)}return r.length>0&&i.push({literal:s||/^\s+$/.test(r),val:r}),i}static macroTokenToFormatOpts(e){return oy[e]}constructor(e,n){this.opts=n,this.loc=e,this.systemLoc=null}formatWithSystemDefault(e,n){return this.systemLoc===null&&(this.systemLoc=this.loc.redefaultToSystem()),this.systemLoc.dtFormatter(e,{...this.opts,...n}).format()}formatDateTime(e,n={}){return this.loc.dtFormatter(e,{...this.opts,...n}).format()}formatDateTimeParts(e,n={}){return this.loc.dtFormatter(e,{...this.opts,...n}).formatToParts()}formatInterval(e,n={}){return this.loc.dtFormatter(e.start,{...this.opts,...n}).dtf.formatRange(e.start.toJSDate(),e.end.toJSDate())}resolvedOptions(e,n={}){return this.loc.dtFormatter(e,{...this.opts,...n}).resolvedOptions()}num(e,n=0){if(this.opts.forceSimple)return ue(e,n);const r={...this.opts};return n>0&&(r.padTo=n),this.loc.numberFormatter(r).format(e)}formatDateTimeFromString(e,n){const r=this.loc.listingMode()==="en",s=this.loc.outputCalendar&&this.loc.outputCalendar!=="gregory",i=(y,w)=>this.loc.extract(e,y,w),a=y=>e.isOffsetFixed&&e.offset===0&&y.allowZ?"Z":e.isValid?e.zone.formatOffset(e.ts,y.format):"",o=()=>r?ny(e):i({hour:"numeric",hourCycle:"h12"},"dayperiod"),u=(y,w)=>r?sy(e,y):i(w?{month:y}:{month:y,day:"numeric"},"month"),c=(y,w)=>r?ry(e,y):i(w?{weekday:y}:{weekday:y,month:"long",day:"numeric"},"weekday"),f=y=>{const w=Ee.macroTokenToFormatOpts(y);return w?this.formatWithSystemDefault(e,w):y},d=y=>r?iy(e,y):i({era:y},"era"),p=y=>{switch(y){case"S":return this.num(e.millisecond);case"u":case"SSS":return this.num(e.millisecond,3);case"s":return this.num(e.second);case"ss":return this.num(e.second,2);case"uu":return this.num(Math.floor(e.millisecond/10),2);case"uuu":return this.num(Math.floor(e.millisecond/100));case"m":return this.num(e.minute);case"mm":return this.num(e.minute,2);case"h":return this.num(e.hour%12===0?12:e.hour%12);case"hh":return this.num(e.hour%12===0?12:e.hour%12,2);case"H":return this.num(e.hour);case"HH":return this.num(e.hour,2);case"Z":return a({format:"narrow",allowZ:this.opts.allowZ});case"ZZ":return a({format:"short",allowZ:this.opts.allowZ});case"ZZZ":return a({format:"techie",allowZ:this.opts.allowZ});case"ZZZZ":return e.zone.offsetName(e.ts,{format:"short",locale:this.loc.locale});case"ZZZZZ":return e.zone.offsetName(e.ts,{format:"long",locale:this.loc.locale});case"z":return e.zoneName;case"a":return o();case"d":return s?i({day:"numeric"},"day"):this.num(e.day);case"dd":return s?i({day:"2-digit"},"day"):this.num(e.day,2);case"c":return this.num(e.weekday);case"ccc":return c("short",!0);case"cccc":return c("long",!0);case"ccccc":return c("narrow",!0);case"E":return this.num(e.weekday);case"EEE":return c("short",!1);case"EEEE":return c("long",!1);case"EEEEE":return c("narrow",!1);case"L":return s?i({month:"numeric",day:"numeric"},"month"):this.num(e.month);case"LL":return s?i({month:"2-digit",day:"numeric"},"month"):this.num(e.month,2);case"LLL":return u("short",!0);case"LLLL":return u("long",!0);case"LLLLL":return u("narrow",!0);case"M":return s?i({month:"numeric"},"month"):this.num(e.month);case"MM":return s?i({month:"2-digit"},"month"):this.num(e.month,2);case"MMM":return u("short",!1);case"MMMM":return u("long",!1);case"MMMMM":return u("narrow",!1);case"y":return s?i({year:"numeric"},"year"):this.num(e.year);case"yy":return s?i({year:"2-digit"},"year"):this.num(e.year.toString().slice(-2),2);case"yyyy":return s?i({year:"numeric"},"year"):this.num(e.year,4);case"yyyyyy":return s?i({year:"numeric"},"year"):this.num(e.year,6);case"G":return d("short");case"GG":return d("long");case"GGGGG":return d("narrow");case"kk":return this.num(e.weekYear.toString().slice(-2),2);case"kkkk":return this.num(e.weekYear,4);case"W":return this.num(e.weekNumber);case"WW":return this.num(e.weekNumber,2);case"o":return this.num(e.ordinal);case"ooo":return this.num(e.ordinal,3);case"q":return this.num(e.quarter);case"qq":return this.num(e.quarter,2);case"X":return this.num(Math.floor(e.ts/1e3));case"x":return this.num(e.ts);default:return f(y)}};return _c(Ee.parseFormat(n),p)}formatDurationFromString(e,n){const r=u=>{switch(u[0]){case"S":return"millisecond";case"s":return"second";case"m":return"minute";case"h":return"hour";case"d":return"day";case"w":return"week";case"M":return"month";case"y":return"year";default:return null}},s=u=>c=>{const f=r(c);return f?this.num(u.get(f),c.length):c},i=Ee.parseFormat(n),a=i.reduce((u,{literal:c,val:f})=>c?u:u.concat(f),[]),o=e.shiftTo(...a.map(r).filter(u=>u));return _c(i,s(o))}}class ct{constructor(e,n){this.reason=e,this.explanation=n}toMessage(){return this.explanation?`${this.reason}: ${this.explanation}`:this.reason}}const Gh=/[A-Za-z_+-]{1,256}(?::?\/[A-Za-z0-9_+-]{1,256}(?:\/[A-Za-z0-9_+-]{1,256})?)?/;function vr(...t){const e=t.reduce((n,r)=>n+r.source,"");return RegExp(`^${e}$`)}function gr(...t){return e=>t.reduce(([n,r,s],i)=>{const[a,o,u]=i(e,s);return[{...n,...a},o||r,u]},[{},null,1]).slice(0,2)}function yr(t,...e){if(t==null)return[null,null];for(const[n,r]of e){const s=n.exec(t);if(s)return r(s)}return[null,null]}function Jh(...t){return(e,n)=>{const r={};let s;for(s=0;sy!==void 0&&(w||y&&f)?-y:y;return[{years:p(mn(n)),months:p(mn(r)),weeks:p(mn(s)),days:p(mn(i)),hours:p(mn(a)),minutes:p(mn(o)),seconds:p(mn(u),u==="-0"),milliseconds:p(eu(c),d)}]}const xy={GMT:0,EDT:-4*60,EST:-5*60,CDT:-5*60,CST:-6*60,MDT:-6*60,MST:-7*60,PDT:-7*60,PST:-8*60};function iu(t,e,n,r,s,i,a){const o={year:e.length===2?Xo(Vt(e)):Vt(e),month:Wh.indexOf(n)+1,day:Vt(r),hour:Vt(s),minute:Vt(i)};return a&&(o.second=Vt(a)),t&&(o.weekday=t.length>3?Bh.indexOf(t)+1:Zh.indexOf(t)+1),o}const Sy=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|(?:([+-]\d\d)(\d\d)))$/;function ky(t){const[,e,n,r,s,i,a,o,u,c,f,d]=t,p=iu(e,s,r,n,i,a,o);let y;return u?y=xy[u]:c?y=0:y=oa(f,d),[p,new Oe(y)]}function Ty(t){return t.replace(/\([^()]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").trim()}const Ey=/^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), (\d\d) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{4}) (\d\d):(\d\d):(\d\d) GMT$/,Ny=/^(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (\d\d)-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\d\d) (\d\d):(\d\d):(\d\d) GMT$/,Cy=/^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ( \d|\d\d) (\d\d):(\d\d):(\d\d) (\d{4})$/;function Oc(t){const[,e,n,r,s,i,a,o]=t;return[iu(e,s,r,n,i,a,o),Oe.utcInstance]}function jy(t){const[,e,n,r,s,i,a,o]=t;return[iu(e,o,n,r,s,i,a),Oe.utcInstance]}const _y=vr(uy,su),Oy=vr(cy,su),Py=vr(dy,su),Ry=vr(em),nm=gr(vy,wr,ws,xs),Dy=gr(fy,wr,ws,xs),Iy=gr(hy,wr,ws,xs),My=gr(wr,ws,xs);function Ly(t){return yr(t,[_y,nm],[Oy,Dy],[Py,Iy],[Ry,My])}function Ay(t){return yr(Ty(t),[Sy,ky])}function Fy(t){return yr(t,[Ey,Oc],[Ny,Oc],[Cy,jy])}function zy(t){return yr(t,[yy,wy])}const $y=gr(wr);function by(t){return yr(t,[gy,$y])}const Uy=vr(my,py),Vy=vr(tm),Hy=gr(wr,ws,xs);function Wy(t){return yr(t,[Uy,nm],[Vy,Hy])}const qy="Invalid Duration",rm={weeks:{days:7,hours:7*24,minutes:7*24*60,seconds:7*24*60*60,milliseconds:7*24*60*60*1e3},days:{hours:24,minutes:24*60,seconds:24*60*60,milliseconds:24*60*60*1e3},hours:{minutes:60,seconds:60*60,milliseconds:60*60*1e3},minutes:{seconds:60,milliseconds:60*1e3},seconds:{milliseconds:1e3}},By={years:{quarters:4,months:12,weeks:52,days:365,hours:365*24,minutes:365*24*60,seconds:365*24*60*60,milliseconds:365*24*60*60*1e3},quarters:{months:3,weeks:13,days:91,hours:91*24,minutes:91*24*60,seconds:91*24*60*60,milliseconds:91*24*60*60*1e3},months:{weeks:4,days:30,hours:30*24,minutes:30*24*60,seconds:30*24*60*60,milliseconds:30*24*60*60*1e3},...rm},Ze=146097/400,In=146097/4800,Zy={years:{quarters:4,months:12,weeks:Ze/7,days:Ze,hours:Ze*24,minutes:Ze*24*60,seconds:Ze*24*60*60,milliseconds:Ze*24*60*60*1e3},quarters:{months:3,weeks:Ze/28,days:Ze/4,hours:Ze*24/4,minutes:Ze*24*60/4,seconds:Ze*24*60*60/4,milliseconds:Ze*24*60*60*1e3/4},months:{weeks:In/7,days:In,hours:In*24,minutes:In*24*60,seconds:In*24*60*60,milliseconds:In*24*60*60*1e3},...rm},gn=["years","quarters","months","weeks","days","hours","minutes","seconds","milliseconds"],Qy=gn.slice(0).reverse();function $t(t,e,n=!1){const r={values:n?e.values:{...t.values,...e.values||{}},loc:t.loc.clone(e.loc),conversionAccuracy:e.conversionAccuracy||t.conversionAccuracy,matrix:e.matrix||t.matrix};return new b(r)}function Yy(t){return t<0?Math.floor(t):Math.ceil(t)}function sm(t,e,n,r,s){const i=t[s][n],a=e[n]/i,o=Math.sign(a)===Math.sign(r[s]),u=!o&&r[s]!==0&&Math.abs(a)<=1?Yy(a):Math.trunc(a);r[s]+=u,e[n]-=u*i}function Ky(t,e){Qy.reduce((n,r)=>$(e[r])?n:(n&&sm(t,e,n,e,r),r),null)}function Gy(t){const e={};for(const[n,r]of Object.entries(t))r!==0&&(e[n]=r);return e}class b{constructor(e){const n=e.conversionAccuracy==="longterm"||!1;let r=n?Zy:By;e.matrix&&(r=e.matrix),this.values=e.values,this.loc=e.loc||K.create(),this.conversionAccuracy=n?"longterm":"casual",this.invalid=e.invalid||null,this.matrix=r,this.isLuxonDuration=!0}static fromMillis(e,n){return b.fromObject({milliseconds:e},n)}static fromObject(e,n={}){if(e==null||typeof e!="object")throw new Ge(`Duration.fromObject: argument expected to be an object, got ${e===null?"null":typeof e}`);return new b({values:bi(e,b.normalizeUnit),loc:K.fromObject(n),conversionAccuracy:n.conversionAccuracy,matrix:n.matrix})}static fromDurationLike(e){if(Tn(e))return b.fromMillis(e);if(b.isDuration(e))return e;if(typeof e=="object")return b.fromObject(e);throw new Ge(`Unknown duration argument ${e} of type ${typeof e}`)}static fromISO(e,n){const[r]=zy(e);return r?b.fromObject(r,n):b.invalid("unparsable",`the input "${e}" can't be parsed as ISO 8601`)}static fromISOTime(e,n){const[r]=by(e);return r?b.fromObject(r,n):b.invalid("unparsable",`the input "${e}" can't be parsed as ISO 8601`)}static invalid(e,n=null){if(!e)throw new Ge("need to specify a reason the Duration is invalid");const r=e instanceof ct?e:new ct(e,n);if(le.throwOnInvalid)throw new Ng(r);return new b({invalid:r})}static normalizeUnit(e){const n={year:"years",years:"years",quarter:"quarters",quarters:"quarters",month:"months",months:"months",week:"weeks",weeks:"weeks",day:"days",days:"days",hour:"hours",hours:"hours",minute:"minutes",minutes:"minutes",second:"seconds",seconds:"seconds",millisecond:"milliseconds",milliseconds:"milliseconds"}[e&&e.toLowerCase()];if(!n)throw new Sh(e);return n}static isDuration(e){return e&&e.isLuxonDuration||!1}get locale(){return this.isValid?this.loc.locale:null}get numberingSystem(){return this.isValid?this.loc.numberingSystem:null}toFormat(e,n={}){const r={...n,floor:n.round!==!1&&n.floor!==!1};return this.isValid?Ee.create(this.loc,r).formatDurationFromString(this,e):qy}toHuman(e={}){const n=gn.map(r=>{const s=this.values[r];return $(s)?null:this.loc.numberFormatter({style:"unit",unitDisplay:"long",...e,unit:r.slice(0,-1)}).format(s)}).filter(r=>r);return this.loc.listFormatter({type:"conjunction",style:e.listStyle||"narrow",...e}).format(n)}toObject(){return this.isValid?{...this.values}:{}}toISO(){if(!this.isValid)return null;let e="P";return this.years!==0&&(e+=this.years+"Y"),(this.months!==0||this.quarters!==0)&&(e+=this.months+this.quarters*3+"M"),this.weeks!==0&&(e+=this.weeks+"W"),this.days!==0&&(e+=this.days+"D"),(this.hours!==0||this.minutes!==0||this.seconds!==0||this.milliseconds!==0)&&(e+="T"),this.hours!==0&&(e+=this.hours+"H"),this.minutes!==0&&(e+=this.minutes+"M"),(this.seconds!==0||this.milliseconds!==0)&&(e+=tu(this.seconds+this.milliseconds/1e3,3)+"S"),e==="P"&&(e+="T0S"),e}toISOTime(e={}){if(!this.isValid)return null;const n=this.toMillis();if(n<0||n>=864e5)return null;e={suppressMilliseconds:!1,suppressSeconds:!1,includePrefix:!1,format:"extended",...e};const r=this.shiftTo("hours","minutes","seconds","milliseconds");let s=e.format==="basic"?"hhmm":"hh:mm";(!e.suppressSeconds||r.seconds!==0||r.milliseconds!==0)&&(s+=e.format==="basic"?"ss":":ss",(!e.suppressMilliseconds||r.milliseconds!==0)&&(s+=".SSS"));let i=r.toFormat(s);return e.includePrefix&&(i="T"+i),i}toJSON(){return this.toISO()}toString(){return this.toISO()}toMillis(){return this.as("milliseconds")}valueOf(){return this.toMillis()}plus(e){if(!this.isValid)return this;const n=b.fromDurationLike(e),r={};for(const s of gn)(dr(n.values,s)||dr(this.values,s))&&(r[s]=n.get(s)+this.get(s));return $t(this,{values:r},!0)}minus(e){if(!this.isValid)return this;const n=b.fromDurationLike(e);return this.plus(n.negate())}mapUnits(e){if(!this.isValid)return this;const n={};for(const r of Object.keys(this.values))n[r]=Hh(e(this.values[r],r));return $t(this,{values:n},!0)}get(e){return this[b.normalizeUnit(e)]}set(e){if(!this.isValid)return this;const n={...this.values,...bi(e,b.normalizeUnit)};return $t(this,{values:n})}reconfigure({locale:e,numberingSystem:n,conversionAccuracy:r,matrix:s}={}){const a={loc:this.loc.clone({locale:e,numberingSystem:n}),matrix:s,conversionAccuracy:r};return $t(this,a)}as(e){return this.isValid?this.shiftTo(e).get(e):NaN}normalize(){if(!this.isValid)return this;const e=this.toObject();return Ky(this.matrix,e),$t(this,{values:e},!0)}rescale(){if(!this.isValid)return this;const e=Gy(this.normalize().shiftToAll().toObject());return $t(this,{values:e},!0)}shiftTo(...e){if(!this.isValid)return this;if(e.length===0)return this;e=e.map(a=>b.normalizeUnit(a));const n={},r={},s=this.toObject();let i;for(const a of gn)if(e.indexOf(a)>=0){i=a;let o=0;for(const c in r)o+=this.matrix[c][a]*r[c],r[c]=0;Tn(s[a])&&(o+=s[a]);const u=Math.trunc(o);n[a]=u,r[a]=(o*1e3-u*1e3)/1e3;for(const c in s)gn.indexOf(c)>gn.indexOf(a)&&sm(this.matrix,s,c,n,a)}else Tn(s[a])&&(r[a]=s[a]);for(const a in r)r[a]!==0&&(n[i]+=a===i?r[a]:r[a]/this.matrix[i][a]);return $t(this,{values:n},!0).normalize()}shiftToAll(){return this.isValid?this.shiftTo("years","months","weeks","days","hours","minutes","seconds","milliseconds"):this}negate(){if(!this.isValid)return this;const e={};for(const n of Object.keys(this.values))e[n]=this.values[n]===0?0:-this.values[n];return $t(this,{values:e},!0)}get years(){return this.isValid?this.values.years||0:NaN}get quarters(){return this.isValid?this.values.quarters||0:NaN}get months(){return this.isValid?this.values.months||0:NaN}get weeks(){return this.isValid?this.values.weeks||0:NaN}get days(){return this.isValid?this.values.days||0:NaN}get hours(){return this.isValid?this.values.hours||0:NaN}get minutes(){return this.isValid?this.values.minutes||0:NaN}get seconds(){return this.isValid?this.values.seconds||0:NaN}get milliseconds(){return this.isValid?this.values.milliseconds||0:NaN}get isValid(){return this.invalid===null}get invalidReason(){return this.invalid?this.invalid.reason:null}get invalidExplanation(){return this.invalid?this.invalid.explanation:null}equals(e){if(!this.isValid||!e.isValid||!this.loc.equals(e.loc))return!1;function n(r,s){return r===void 0||r===0?s===void 0||s===0:r===s}for(const r of gn)if(!n(this.values[r],e.values[r]))return!1;return!0}}const Mn="Invalid Interval";function Jy(t,e){return!t||!t.isValid?ne.invalid("missing or invalid start"):!e||!e.isValid?ne.invalid("missing or invalid end"):ee:!1}isBefore(e){return this.isValid?this.e<=e:!1}contains(e){return this.isValid?this.s<=e&&this.e>e:!1}set({start:e,end:n}={}){return this.isValid?ne.fromDateTimes(e||this.s,n||this.e):this}splitAt(...e){if(!this.isValid)return[];const n=e.map(Rr).filter(a=>this.contains(a)).sort(),r=[];let{s}=this,i=0;for(;s+this.e?this.e:a;r.push(ne.fromDateTimes(s,o)),s=o,i+=1}return r}splitBy(e){const n=b.fromDurationLike(e);if(!this.isValid||!n.isValid||n.as("milliseconds")===0)return[];let{s:r}=this,s=1,i;const a=[];for(;ru*s));i=+o>+this.e?this.e:o,a.push(ne.fromDateTimes(r,i)),r=i,s+=1}return a}divideEqually(e){return this.isValid?this.splitBy(this.length()/e).slice(0,e):[]}overlaps(e){return this.e>e.s&&this.s=e.e:!1}equals(e){return!this.isValid||!e.isValid?!1:this.s.equals(e.s)&&this.e.equals(e.e)}intersection(e){if(!this.isValid)return this;const n=this.s>e.s?this.s:e.s,r=this.e=r?null:ne.fromDateTimes(n,r)}union(e){if(!this.isValid)return this;const n=this.se.e?this.e:e.e;return ne.fromDateTimes(n,r)}static merge(e){const[n,r]=e.sort((s,i)=>s.s-i.s).reduce(([s,i],a)=>i?i.overlaps(a)||i.abutsStart(a)?[s,i.union(a)]:[s.concat([i]),a]:[s,a],[[],null]);return r&&n.push(r),n}static xor(e){let n=null,r=0;const s=[],i=e.map(u=>[{time:u.s,type:"s"},{time:u.e,type:"e"}]),a=Array.prototype.concat(...i),o=a.sort((u,c)=>u.time-c.time);for(const u of o)r+=u.type==="s"?1:-1,r===1?n=u.time:(n&&+n!=+u.time&&s.push(ne.fromDateTimes(n,u.time)),n=null);return ne.merge(s)}difference(...e){return ne.xor([this].concat(e)).map(n=>this.intersection(n)).filter(n=>n&&!n.isEmpty())}toString(){return this.isValid?`[${this.s.toISO()} – ${this.e.toISO()})`:Mn}toLocaleString(e=Fi,n={}){return this.isValid?Ee.create(this.s.loc.clone(n),e).formatInterval(this):Mn}toISO(e){return this.isValid?`${this.s.toISO(e)}/${this.e.toISO(e)}`:Mn}toISODate(){return this.isValid?`${this.s.toISODate()}/${this.e.toISODate()}`:Mn}toISOTime(e){return this.isValid?`${this.s.toISOTime(e)}/${this.e.toISOTime(e)}`:Mn}toFormat(e,{separator:n=" – "}={}){return this.isValid?`${this.s.toFormat(e)}${n}${this.e.toFormat(e)}`:Mn}toDuration(e,n){return this.isValid?this.e.diff(this.s,e,n):b.invalid(this.invalidReason)}mapEndpoints(e){return ne.fromDateTimes(e(this.s),e(this.e))}}class Hs{static hasDST(e=le.defaultZone){const n=M.now().setZone(e).set({month:12});return!e.isUniversal&&n.offset!==n.set({month:6}).offset}static isValidIANAZone(e){return Mt.isValidZone(e)}static normalizeZone(e){return qt(e,le.defaultZone)}static months(e="long",{locale:n=null,numberingSystem:r=null,locObj:s=null,outputCalendar:i="gregory"}={}){return(s||K.create(n,r,i)).months(e)}static monthsFormat(e="long",{locale:n=null,numberingSystem:r=null,locObj:s=null,outputCalendar:i="gregory"}={}){return(s||K.create(n,r,i)).months(e,!0)}static weekdays(e="long",{locale:n=null,numberingSystem:r=null,locObj:s=null}={}){return(s||K.create(n,r,null)).weekdays(e)}static weekdaysFormat(e="long",{locale:n=null,numberingSystem:r=null,locObj:s=null}={}){return(s||K.create(n,r,null)).weekdays(e,!0)}static meridiems({locale:e=null}={}){return K.create(e).meridiems()}static eras(e="short",{locale:n=null}={}){return K.create(n,null,"gregory").eras(e)}static features(){return{relative:Uh()}}}function Pc(t,e){const n=s=>s.toUTC(0,{keepLocalTime:!0}).startOf("day").valueOf(),r=n(e)-n(t);return Math.floor(b.fromMillis(r).as("days"))}function Xy(t,e,n){const r=[["years",(u,c)=>c.year-u.year],["quarters",(u,c)=>c.quarter-u.quarter+(c.year-u.year)*4],["months",(u,c)=>c.month-u.month+(c.year-u.year)*12],["weeks",(u,c)=>{const f=Pc(u,c);return(f-f%7)/7}],["days",Pc]],s={},i=t;let a,o;for(const[u,c]of r)n.indexOf(u)>=0&&(a=u,s[u]=c(t,e),o=i.plus(s),o>e?(s[u]--,t=i.plus(s)):t=o);return[t,s,o,a]}function e0(t,e,n,r){let[s,i,a,o]=Xy(t,e,n);const u=e-s,c=n.filter(d=>["hours","minutes","seconds","milliseconds"].indexOf(d)>=0);c.length===0&&(a0?b.fromMillis(u,r).shiftTo(...c).plus(f):f}const au={arab:"[٠-٩]",arabext:"[۰-۹]",bali:"[᭐-᭙]",beng:"[০-৯]",deva:"[०-९]",fullwide:"[0-9]",gujr:"[૦-૯]",hanidec:"[〇|一|二|三|四|五|六|七|八|九]",khmr:"[០-៩]",knda:"[೦-೯]",laoo:"[໐-໙]",limb:"[᥆-᥏]",mlym:"[൦-൯]",mong:"[᠐-᠙]",mymr:"[၀-၉]",orya:"[୦-୯]",tamldec:"[௦-௯]",telu:"[౦-౯]",thai:"[๐-๙]",tibt:"[༠-༩]",latn:"\\d"},Rc={arab:[1632,1641],arabext:[1776,1785],bali:[6992,7001],beng:[2534,2543],deva:[2406,2415],fullwide:[65296,65303],gujr:[2790,2799],khmr:[6112,6121],knda:[3302,3311],laoo:[3792,3801],limb:[6470,6479],mlym:[3430,3439],mong:[6160,6169],mymr:[4160,4169],orya:[2918,2927],tamldec:[3046,3055],telu:[3174,3183],thai:[3664,3673],tibt:[3872,3881]},t0=au.hanidec.replace(/[\[|\]]/g,"").split("");function n0(t){let e=parseInt(t,10);if(isNaN(e)){e="";for(let n=0;n=i&&r<=a&&(e+=r-i)}}return parseInt(e,10)}else return e}function it({numberingSystem:t},e=""){return new RegExp(`${au[t||"latn"]}${e}`)}const r0="missing Intl.DateTimeFormat.formatToParts support";function H(t,e=n=>n){return{regex:t,deser:([n])=>e(n0(n))}}const s0=String.fromCharCode(160),im=`[ ${s0}]`,am=new RegExp(im,"g");function i0(t){return t.replace(/\./g,"\\.?").replace(am,im)}function Dc(t){return t.replace(/\./g,"").replace(am," ").toLowerCase()}function at(t,e){return t===null?null:{regex:RegExp(t.map(i0).join("|")),deser:([n])=>t.findIndex(r=>Dc(n)===Dc(r))+e}}function Ic(t,e){return{regex:t,deser:([,n,r])=>oa(n,r),groups:e}}function Ws(t){return{regex:t,deser:([e])=>e}}function a0(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function o0(t,e){const n=it(e),r=it(e,"{2}"),s=it(e,"{3}"),i=it(e,"{4}"),a=it(e,"{6}"),o=it(e,"{1,2}"),u=it(e,"{1,3}"),c=it(e,"{1,6}"),f=it(e,"{1,9}"),d=it(e,"{2,4}"),p=it(e,"{4,6}"),y=k=>({regex:RegExp(a0(k.val)),deser:([m])=>m,literal:!0}),g=(k=>{if(t.literal)return y(k);switch(k.val){case"G":return at(e.eras("short",!1),0);case"GG":return at(e.eras("long",!1),0);case"y":return H(c);case"yy":return H(d,Xo);case"yyyy":return H(i);case"yyyyy":return H(p);case"yyyyyy":return H(a);case"M":return H(o);case"MM":return H(r);case"MMM":return at(e.months("short",!0,!1),1);case"MMMM":return at(e.months("long",!0,!1),1);case"L":return H(o);case"LL":return H(r);case"LLL":return at(e.months("short",!1,!1),1);case"LLLL":return at(e.months("long",!1,!1),1);case"d":return H(o);case"dd":return H(r);case"o":return H(u);case"ooo":return H(s);case"HH":return H(r);case"H":return H(o);case"hh":return H(r);case"h":return H(o);case"mm":return H(r);case"m":return H(o);case"q":return H(o);case"qq":return H(r);case"s":return H(o);case"ss":return H(r);case"S":return H(u);case"SSS":return H(s);case"u":return Ws(f);case"uu":return Ws(o);case"uuu":return H(n);case"a":return at(e.meridiems(),0);case"kkkk":return H(i);case"kk":return H(d,Xo);case"W":return H(o);case"WW":return H(r);case"E":case"c":return H(n);case"EEE":return at(e.weekdays("short",!1,!1),1);case"EEEE":return at(e.weekdays("long",!1,!1),1);case"ccc":return at(e.weekdays("short",!0,!1),1);case"cccc":return at(e.weekdays("long",!0,!1),1);case"Z":case"ZZ":return Ic(new RegExp(`([+-]${o.source})(?::(${r.source}))?`),2);case"ZZZ":return Ic(new RegExp(`([+-]${o.source})(${r.source})?`),2);case"z":return Ws(/[a-z_+-/]{1,256}?/i);case" ":return Ws(/[^\S\n\r]/);default:return y(k)}})(t)||{invalidReason:r0};return g.token=t,g}const l0={year:{"2-digit":"yy",numeric:"yyyyy"},month:{numeric:"M","2-digit":"MM",short:"MMM",long:"MMMM"},day:{numeric:"d","2-digit":"dd"},weekday:{short:"EEE",long:"EEEE"},dayperiod:"a",dayPeriod:"a",hour:{numeric:"h","2-digit":"hh"},minute:{numeric:"m","2-digit":"mm"},second:{numeric:"s","2-digit":"ss"},timeZoneName:{long:"ZZZZZ",short:"ZZZ"}};function u0(t,e){const{type:n,value:r}=t;if(n==="literal"){const a=/^\s+$/.test(r);return{literal:!a,val:a?" ":r}}const s=e[n];let i=l0[n];if(typeof i=="object"&&(i=i[s]),i)return{literal:!1,val:i}}function c0(t){return[`^${t.map(n=>n.regex).reduce((n,r)=>`${n}(${r.source})`,"")}$`,t]}function d0(t,e,n){const r=t.match(e);if(r){const s={};let i=1;for(const a in n)if(dr(n,a)){const o=n[a],u=o.groups?o.groups+1:1;!o.literal&&o.token&&(s[o.token.val[0]]=o.deser(r.slice(i,i+u))),i+=u}return[r,s]}else return[r,{}]}function f0(t){const e=i=>{switch(i){case"S":return"millisecond";case"s":return"second";case"m":return"minute";case"h":case"H":return"hour";case"d":return"day";case"o":return"ordinal";case"L":case"M":return"month";case"y":return"year";case"E":case"c":return"weekday";case"W":return"weekNumber";case"k":return"weekYear";case"q":return"quarter";default:return null}};let n=null,r;return $(t.z)||(n=Mt.create(t.z)),$(t.Z)||(n||(n=new Oe(t.Z)),r=t.Z),$(t.q)||(t.M=(t.q-1)*3+1),$(t.h)||(t.h<12&&t.a===1?t.h+=12:t.h===12&&t.a===0&&(t.h=0)),t.G===0&&t.y&&(t.y=-t.y),$(t.u)||(t.S=eu(t.u)),[Object.keys(t).reduce((i,a)=>{const o=e(a);return o&&(i[o]=t[a]),i},{}),n,r]}let Ha=null;function h0(){return Ha||(Ha=M.fromMillis(1555555555555)),Ha}function m0(t,e){if(t.literal)return t;const n=Ee.macroTokenToFormatOpts(t.val),r=um(n,e);return r==null||r.includes(void 0)?t:r}function om(t,e){return Array.prototype.concat(...t.map(n=>m0(n,e)))}function lm(t,e,n){const r=om(Ee.parseFormat(n),t),s=r.map(a=>o0(a,t)),i=s.find(a=>a.invalidReason);if(i)return{input:e,tokens:r,invalidReason:i.invalidReason};{const[a,o]=c0(s),u=RegExp(a,"i"),[c,f]=d0(e,u,o),[d,p,y]=f?f0(f):[null,null,void 0];if(dr(f,"a")&&dr(f,"H"))throw new Ar("Can't include meridiem when specifying 24-hour format");return{input:e,tokens:r,regex:u,rawMatches:c,matches:f,result:d,zone:p,specificOffset:y}}}function p0(t,e,n){const{result:r,zone:s,specificOffset:i,invalidReason:a}=lm(t,e,n);return[r,s,i,a]}function um(t,e){return t?Ee.create(e,t).formatDateTimeParts(h0()).map(s=>u0(s,t)):null}const cm=[0,31,59,90,120,151,181,212,243,273,304,334],dm=[0,31,60,91,121,152,182,213,244,274,305,335];function Xe(t,e){return new ct("unit out of range",`you specified ${e} (of type ${typeof e}) as a ${t}, which is invalid`)}function fm(t,e,n){const r=new Date(Date.UTC(t,e-1,n));t<100&&t>=0&&r.setUTCFullYear(r.getUTCFullYear()-1900);const s=r.getUTCDay();return s===0?7:s}function hm(t,e,n){return n+(ys(t)?dm:cm)[e-1]}function mm(t,e){const n=ys(t)?dm:cm,r=n.findIndex(i=>i$i(e)?(o=e+1,a=1):o=e,{weekYear:o,weekNumber:a,weekday:i,...la(t)}}function Mc(t){const{weekYear:e,weekNumber:n,weekday:r}=t,s=fm(e,1,4),i=Zr(e);let a=n*7+r-s-3,o;a<1?(o=e-1,a+=Zr(o)):a>i?(o=e+1,a-=Zr(e)):o=e;const{month:u,day:c}=mm(o,a);return{year:o,month:u,day:c,...la(t)}}function Wa(t){const{year:e,month:n,day:r}=t,s=hm(e,n,r);return{year:e,ordinal:s,...la(t)}}function Lc(t){const{year:e,ordinal:n}=t,{month:r,day:s}=mm(e,n);return{year:e,month:r,day:s,...la(t)}}function v0(t){const e=aa(t.weekYear),n=_t(t.weekNumber,1,$i(t.weekYear)),r=_t(t.weekday,1,7);return e?n?r?!1:Xe("weekday",t.weekday):Xe("week",t.week):Xe("weekYear",t.weekYear)}function g0(t){const e=aa(t.year),n=_t(t.ordinal,1,Zr(t.year));return e?n?!1:Xe("ordinal",t.ordinal):Xe("year",t.year)}function pm(t){const e=aa(t.year),n=_t(t.month,1,12),r=_t(t.day,1,zi(t.year,t.month));return e?n?r?!1:Xe("day",t.day):Xe("month",t.month):Xe("year",t.year)}function vm(t){const{hour:e,minute:n,second:r,millisecond:s}=t,i=_t(e,0,23)||e===24&&n===0&&r===0&&s===0,a=_t(n,0,59),o=_t(r,0,59),u=_t(s,0,999);return i?a?o?u?!1:Xe("millisecond",s):Xe("second",r):Xe("minute",n):Xe("hour",e)}const qa="Invalid DateTime",Ac=864e13;function qs(t){return new ct("unsupported zone",`the zone "${t.name}" is not supported`)}function Ba(t){return t.weekData===null&&(t.weekData=el(t.c)),t.weekData}function Or(t,e){const n={ts:t.ts,zone:t.zone,c:t.c,o:t.o,loc:t.loc,invalid:t.invalid};return new M({...n,...e,old:n})}function gm(t,e,n){let r=t-e*60*1e3;const s=n.offset(r);if(e===s)return[r,e];r-=(s-e)*60*1e3;const i=n.offset(r);return s===i?[r,s]:[t-Math.min(s,i)*60*1e3,Math.max(s,i)]}function Fc(t,e){t+=e*60*1e3;const n=new Date(t);return{year:n.getUTCFullYear(),month:n.getUTCMonth()+1,day:n.getUTCDate(),hour:n.getUTCHours(),minute:n.getUTCMinutes(),second:n.getUTCSeconds(),millisecond:n.getUTCMilliseconds()}}function ci(t,e,n){return gm(nu(t),e,n)}function zc(t,e){const n=t.o,r=t.c.year+Math.trunc(e.years),s=t.c.month+Math.trunc(e.months)+Math.trunc(e.quarters)*3,i={...t.c,year:r,month:s,day:Math.min(t.c.day,zi(r,s))+Math.trunc(e.days)+Math.trunc(e.weeks)*7},a=b.fromObject({years:e.years-Math.trunc(e.years),quarters:e.quarters-Math.trunc(e.quarters),months:e.months-Math.trunc(e.months),weeks:e.weeks-Math.trunc(e.weeks),days:e.days-Math.trunc(e.days),hours:e.hours,minutes:e.minutes,seconds:e.seconds,milliseconds:e.milliseconds}).as("milliseconds"),o=nu(i);let[u,c]=gm(o,n,t.zone);return a!==0&&(u+=a,c=t.zone.offset(u)),{ts:u,o:c}}function Pr(t,e,n,r,s,i){const{setZone:a,zone:o}=n;if(t&&Object.keys(t).length!==0||e){const u=e||o,c=M.fromObject(t,{...n,zone:u,specificOffset:i});return a?c:c.setZone(o)}else return M.invalid(new ct("unparsable",`the input "${s}" can't be parsed as ${r}`))}function Bs(t,e,n=!0){return t.isValid?Ee.create(K.create("en-US"),{allowZ:n,forceSimple:!0}).formatDateTimeFromString(t,e):null}function Za(t,e){const n=t.c.year>9999||t.c.year<0;let r="";return n&&t.c.year>=0&&(r+="+"),r+=ue(t.c.year,n?6:4),e?(r+="-",r+=ue(t.c.month),r+="-",r+=ue(t.c.day)):(r+=ue(t.c.month),r+=ue(t.c.day)),r}function $c(t,e,n,r,s,i){let a=ue(t.c.hour);return e?(a+=":",a+=ue(t.c.minute),(t.c.second!==0||!n)&&(a+=":")):a+=ue(t.c.minute),(t.c.second!==0||!n)&&(a+=ue(t.c.second),(t.c.millisecond!==0||!r)&&(a+=".",a+=ue(t.c.millisecond,3))),s&&(t.isOffsetFixed&&t.offset===0&&!i?a+="Z":t.o<0?(a+="-",a+=ue(Math.trunc(-t.o/60)),a+=":",a+=ue(Math.trunc(-t.o%60))):(a+="+",a+=ue(Math.trunc(t.o/60)),a+=":",a+=ue(Math.trunc(t.o%60)))),i&&(a+="["+t.zone.ianaName+"]"),a}const ym={month:1,day:1,hour:0,minute:0,second:0,millisecond:0},y0={weekNumber:1,weekday:1,hour:0,minute:0,second:0,millisecond:0},w0={ordinal:1,hour:0,minute:0,second:0,millisecond:0},wm=["year","month","day","hour","minute","second","millisecond"],x0=["weekYear","weekNumber","weekday","hour","minute","second","millisecond"],S0=["year","ordinal","hour","minute","second","millisecond"];function bc(t){const e={year:"year",years:"year",month:"month",months:"month",day:"day",days:"day",hour:"hour",hours:"hour",minute:"minute",minutes:"minute",quarter:"quarter",quarters:"quarter",second:"second",seconds:"second",millisecond:"millisecond",milliseconds:"millisecond",weekday:"weekday",weekdays:"weekday",weeknumber:"weekNumber",weeksnumber:"weekNumber",weeknumbers:"weekNumber",weekyear:"weekYear",weekyears:"weekYear",ordinal:"ordinal"}[t.toLowerCase()];if(!e)throw new Sh(t);return e}function Uc(t,e){const n=qt(e.zone,le.defaultZone),r=K.fromObject(e),s=le.now();let i,a;if($(t.year))i=s;else{for(const c of wm)$(t[c])&&(t[c]=ym[c]);const o=pm(t)||vm(t);if(o)return M.invalid(o);const u=n.offset(s);[i,a]=ci(t,u,n)}return new M({ts:i,zone:n,loc:r,o:a})}function Vc(t,e,n){const r=$(n.round)?!0:n.round,s=(a,o)=>(a=tu(a,r||n.calendary?0:2,!0),e.loc.clone(n).relFormatter(n).format(a,o)),i=a=>n.calendary?e.hasSame(t,a)?0:e.startOf(a).diff(t.startOf(a),a).get(a):e.diff(t,a).get(a);if(n.unit)return s(i(n.unit),n.unit);for(const a of n.units){const o=i(a);if(Math.abs(o)>=1)return s(o,a)}return s(t>e?-0:0,n.units[n.units.length-1])}function Hc(t){let e={},n;return t.length>0&&typeof t[t.length-1]=="object"?(e=t[t.length-1],n=Array.from(t).slice(0,t.length-1)):n=Array.from(t),[e,n]}class M{constructor(e){const n=e.zone||le.defaultZone;let r=e.invalid||(Number.isNaN(e.ts)?new ct("invalid input"):null)||(n.isValid?null:qs(n));this.ts=$(e.ts)?le.now():e.ts;let s=null,i=null;if(!r)if(e.old&&e.old.ts===this.ts&&e.old.zone.equals(n))[s,i]=[e.old.c,e.old.o];else{const o=n.offset(this.ts);s=Fc(this.ts,o),r=Number.isNaN(s.year)?new ct("invalid input"):null,s=r?null:s,i=r?null:o}this._zone=n,this.loc=e.loc||K.create(),this.invalid=r,this.weekData=null,this.c=s,this.o=i,this.isLuxonDateTime=!0}static now(){return new M({})}static local(){const[e,n]=Hc(arguments),[r,s,i,a,o,u,c]=n;return Uc({year:r,month:s,day:i,hour:a,minute:o,second:u,millisecond:c},e)}static utc(){const[e,n]=Hc(arguments),[r,s,i,a,o,u,c]=n;return e.zone=Oe.utcInstance,Uc({year:r,month:s,day:i,hour:a,minute:o,second:u,millisecond:c},e)}static fromJSDate(e,n={}){const r=Bg(e)?e.valueOf():NaN;if(Number.isNaN(r))return M.invalid("invalid input");const s=qt(n.zone,le.defaultZone);return s.isValid?new M({ts:r,zone:s,loc:K.fromObject(n)}):M.invalid(qs(s))}static fromMillis(e,n={}){if(Tn(e))return e<-Ac||e>Ac?M.invalid("Timestamp out of range"):new M({ts:e,zone:qt(n.zone,le.defaultZone),loc:K.fromObject(n)});throw new Ge(`fromMillis requires a numerical input, but received a ${typeof e} with value ${e}`)}static fromSeconds(e,n={}){if(Tn(e))return new M({ts:e*1e3,zone:qt(n.zone,le.defaultZone),loc:K.fromObject(n)});throw new Ge("fromSeconds requires a numerical input")}static fromObject(e,n={}){e=e||{};const r=qt(n.zone,le.defaultZone);if(!r.isValid)return M.invalid(qs(r));const s=le.now(),i=$(n.specificOffset)?r.offset(s):n.specificOffset,a=bi(e,bc),o=!$(a.ordinal),u=!$(a.year),c=!$(a.month)||!$(a.day),f=u||c,d=a.weekYear||a.weekNumber,p=K.fromObject(n);if((f||o)&&d)throw new Ar("Can't mix weekYear/weekNumber units with year/month/day or ordinals");if(c&&o)throw new Ar("Can't mix ordinal dates with month/day");const y=d||a.weekday&&!f;let w,g,k=Fc(s,i);y?(w=x0,g=y0,k=el(k)):o?(w=S0,g=w0,k=Wa(k)):(w=wm,g=ym);let m=!1;for(const j of w){const D=a[j];$(D)?m?a[j]=g[j]:a[j]=k[j]:m=!0}const h=y?v0(a):o?g0(a):pm(a),v=h||vm(a);if(v)return M.invalid(v);const x=y?Mc(a):o?Lc(a):a,[S,E]=ci(x,i,r),N=new M({ts:S,zone:r,o:E,loc:p});return a.weekday&&f&&e.weekday!==N.weekday?M.invalid("mismatched weekday",`you can't specify both a weekday of ${a.weekday} and a date of ${N.toISO()}`):N}static fromISO(e,n={}){const[r,s]=Ly(e);return Pr(r,s,n,"ISO 8601",e)}static fromRFC2822(e,n={}){const[r,s]=Ay(e);return Pr(r,s,n,"RFC 2822",e)}static fromHTTP(e,n={}){const[r,s]=Fy(e);return Pr(r,s,n,"HTTP",n)}static fromFormat(e,n,r={}){if($(e)||$(n))throw new Ge("fromFormat requires an input string and a format");const{locale:s=null,numberingSystem:i=null}=r,a=K.fromOpts({locale:s,numberingSystem:i,defaultToEN:!0}),[o,u,c,f]=p0(a,e,n);return f?M.invalid(f):Pr(o,u,r,`format ${n}`,e,c)}static fromString(e,n,r={}){return M.fromFormat(e,n,r)}static fromSQL(e,n={}){const[r,s]=Wy(e);return Pr(r,s,n,"SQL",e)}static invalid(e,n=null){if(!e)throw new Ge("need to specify a reason the DateTime is invalid");const r=e instanceof ct?e:new ct(e,n);if(le.throwOnInvalid)throw new Tg(r);return new M({invalid:r})}static isDateTime(e){return e&&e.isLuxonDateTime||!1}static parseFormatForOpts(e,n={}){const r=um(e,K.fromObject(n));return r?r.map(s=>s?s.val:null).join(""):null}static expandFormat(e,n={}){return om(Ee.parseFormat(e),K.fromObject(n)).map(s=>s.val).join("")}get(e){return this[e]}get isValid(){return this.invalid===null}get invalidReason(){return this.invalid?this.invalid.reason:null}get invalidExplanation(){return this.invalid?this.invalid.explanation:null}get locale(){return this.isValid?this.loc.locale:null}get numberingSystem(){return this.isValid?this.loc.numberingSystem:null}get outputCalendar(){return this.isValid?this.loc.outputCalendar:null}get zone(){return this._zone}get zoneName(){return this.isValid?this.zone.name:null}get year(){return this.isValid?this.c.year:NaN}get quarter(){return this.isValid?Math.ceil(this.c.month/3):NaN}get month(){return this.isValid?this.c.month:NaN}get day(){return this.isValid?this.c.day:NaN}get hour(){return this.isValid?this.c.hour:NaN}get minute(){return this.isValid?this.c.minute:NaN}get second(){return this.isValid?this.c.second:NaN}get millisecond(){return this.isValid?this.c.millisecond:NaN}get weekYear(){return this.isValid?Ba(this).weekYear:NaN}get weekNumber(){return this.isValid?Ba(this).weekNumber:NaN}get weekday(){return this.isValid?Ba(this).weekday:NaN}get ordinal(){return this.isValid?Wa(this.c).ordinal:NaN}get monthShort(){return this.isValid?Hs.months("short",{locObj:this.loc})[this.month-1]:null}get monthLong(){return this.isValid?Hs.months("long",{locObj:this.loc})[this.month-1]:null}get weekdayShort(){return this.isValid?Hs.weekdays("short",{locObj:this.loc})[this.weekday-1]:null}get weekdayLong(){return this.isValid?Hs.weekdays("long",{locObj:this.loc})[this.weekday-1]:null}get offset(){return this.isValid?+this.o:NaN}get offsetNameShort(){return this.isValid?this.zone.offsetName(this.ts,{format:"short",locale:this.locale}):null}get offsetNameLong(){return this.isValid?this.zone.offsetName(this.ts,{format:"long",locale:this.locale}):null}get isOffsetFixed(){return this.isValid?this.zone.isUniversal:null}get isInDST(){return this.isOffsetFixed?!1:this.offset>this.set({month:1,day:1}).offset||this.offset>this.set({month:5}).offset}get isInLeapYear(){return ys(this.year)}get daysInMonth(){return zi(this.year,this.month)}get daysInYear(){return this.isValid?Zr(this.year):NaN}get weeksInWeekYear(){return this.isValid?$i(this.weekYear):NaN}resolvedLocaleOptions(e={}){const{locale:n,numberingSystem:r,calendar:s}=Ee.create(this.loc.clone(e),e).resolvedOptions(this);return{locale:n,numberingSystem:r,outputCalendar:s}}toUTC(e=0,n={}){return this.setZone(Oe.instance(e),n)}toLocal(){return this.setZone(le.defaultZone)}setZone(e,{keepLocalTime:n=!1,keepCalendarTime:r=!1}={}){if(e=qt(e,le.defaultZone),e.equals(this.zone))return this;if(e.isValid){let s=this.ts;if(n||r){const i=e.offset(this.ts),a=this.toObject();[s]=ci(a,i,e)}return Or(this,{ts:s,zone:e})}else return M.invalid(qs(e))}reconfigure({locale:e,numberingSystem:n,outputCalendar:r}={}){const s=this.loc.clone({locale:e,numberingSystem:n,outputCalendar:r});return Or(this,{loc:s})}setLocale(e){return this.reconfigure({locale:e})}set(e){if(!this.isValid)return this;const n=bi(e,bc),r=!$(n.weekYear)||!$(n.weekNumber)||!$(n.weekday),s=!$(n.ordinal),i=!$(n.year),a=!$(n.month)||!$(n.day),o=i||a,u=n.weekYear||n.weekNumber;if((o||s)&&u)throw new Ar("Can't mix weekYear/weekNumber units with year/month/day or ordinals");if(a&&s)throw new Ar("Can't mix ordinal dates with month/day");let c;r?c=Mc({...el(this.c),...n}):$(n.ordinal)?(c={...this.toObject(),...n},$(n.day)&&(c.day=Math.min(zi(c.year,c.month),c.day))):c=Lc({...Wa(this.c),...n});const[f,d]=ci(c,this.o,this.zone);return Or(this,{ts:f,o:d})}plus(e){if(!this.isValid)return this;const n=b.fromDurationLike(e);return Or(this,zc(this,n))}minus(e){if(!this.isValid)return this;const n=b.fromDurationLike(e).negate();return Or(this,zc(this,n))}startOf(e){if(!this.isValid)return this;const n={},r=b.normalizeUnit(e);switch(r){case"years":n.month=1;case"quarters":case"months":n.day=1;case"weeks":case"days":n.hour=0;case"hours":n.minute=0;case"minutes":n.second=0;case"seconds":n.millisecond=0;break}if(r==="weeks"&&(n.weekday=1),r==="quarters"){const s=Math.ceil(this.month/3);n.month=(s-1)*3+1}return this.set(n)}endOf(e){return this.isValid?this.plus({[e]:1}).startOf(e).minus(1):this}toFormat(e,n={}){return this.isValid?Ee.create(this.loc.redefaultToEN(n)).formatDateTimeFromString(this,e):qa}toLocaleString(e=Fi,n={}){return this.isValid?Ee.create(this.loc.clone(n),e).formatDateTime(this):qa}toLocaleParts(e={}){return this.isValid?Ee.create(this.loc.clone(e),e).formatDateTimeParts(this):[]}toISO({format:e="extended",suppressSeconds:n=!1,suppressMilliseconds:r=!1,includeOffset:s=!0,extendedZone:i=!1}={}){if(!this.isValid)return null;const a=e==="extended";let o=Za(this,a);return o+="T",o+=$c(this,a,n,r,s,i),o}toISODate({format:e="extended"}={}){return this.isValid?Za(this,e==="extended"):null}toISOWeekDate(){return Bs(this,"kkkk-'W'WW-c")}toISOTime({suppressMilliseconds:e=!1,suppressSeconds:n=!1,includeOffset:r=!0,includePrefix:s=!1,extendedZone:i=!1,format:a="extended"}={}){return this.isValid?(s?"T":"")+$c(this,a==="extended",n,e,r,i):null}toRFC2822(){return Bs(this,"EEE, dd LLL yyyy HH:mm:ss ZZZ",!1)}toHTTP(){return Bs(this.toUTC(),"EEE, dd LLL yyyy HH:mm:ss 'GMT'")}toSQLDate(){return this.isValid?Za(this,!0):null}toSQLTime({includeOffset:e=!0,includeZone:n=!1,includeOffsetSpace:r=!0}={}){let s="HH:mm:ss.SSS";return(n||e)&&(r&&(s+=" "),n?s+="z":e&&(s+="ZZ")),Bs(this,s,!0)}toSQL(e={}){return this.isValid?`${this.toSQLDate()} ${this.toSQLTime(e)}`:null}toString(){return this.isValid?this.toISO():qa}valueOf(){return this.toMillis()}toMillis(){return this.isValid?this.ts:NaN}toSeconds(){return this.isValid?this.ts/1e3:NaN}toUnixInteger(){return this.isValid?Math.floor(this.ts/1e3):NaN}toJSON(){return this.toISO()}toBSON(){return this.toJSDate()}toObject(e={}){if(!this.isValid)return{};const n={...this.c};return e.includeConfig&&(n.outputCalendar=this.outputCalendar,n.numberingSystem=this.loc.numberingSystem,n.locale=this.loc.locale),n}toJSDate(){return new Date(this.isValid?this.ts:NaN)}diff(e,n="milliseconds",r={}){if(!this.isValid||!e.isValid)return b.invalid("created by diffing an invalid DateTime");const s={locale:this.locale,numberingSystem:this.numberingSystem,...r},i=Zg(n).map(b.normalizeUnit),a=e.valueOf()>this.valueOf(),o=a?this:e,u=a?e:this,c=e0(o,u,i,s);return a?c.negate():c}diffNow(e="milliseconds",n={}){return this.diff(M.now(),e,n)}until(e){return this.isValid?ne.fromDateTimes(this,e):this}hasSame(e,n){if(!this.isValid)return!1;const r=e.valueOf(),s=this.setZone(e.zone,{keepLocalTime:!0});return s.startOf(n)<=r&&r<=s.endOf(n)}equals(e){return this.isValid&&e.isValid&&this.valueOf()===e.valueOf()&&this.zone.equals(e.zone)&&this.loc.equals(e.loc)}toRelative(e={}){if(!this.isValid)return null;const n=e.base||M.fromObject({},{zone:this.zone}),r=e.padding?thisn.valueOf(),Math.min)}static max(...e){if(!e.every(M.isDateTime))throw new Ge("max requires all arguments be DateTimes");return jc(e,n=>n.valueOf(),Math.max)}static fromFormatExplain(e,n,r={}){const{locale:s=null,numberingSystem:i=null}=r,a=K.fromOpts({locale:s,numberingSystem:i,defaultToEN:!0});return lm(a,e,n)}static fromStringExplain(e,n,r={}){return M.fromFormatExplain(e,n,r)}static get DATE_SHORT(){return Fi}static get DATE_MED(){return kh}static get DATE_MED_WITH_WEEKDAY(){return Cg}static get DATE_FULL(){return Th}static get DATE_HUGE(){return Eh}static get TIME_SIMPLE(){return Nh}static get TIME_WITH_SECONDS(){return Ch}static get TIME_WITH_SHORT_OFFSET(){return jh}static get TIME_WITH_LONG_OFFSET(){return _h}static get TIME_24_SIMPLE(){return Oh}static get TIME_24_WITH_SECONDS(){return Ph}static get TIME_24_WITH_SHORT_OFFSET(){return Rh}static get TIME_24_WITH_LONG_OFFSET(){return Dh}static get DATETIME_SHORT(){return Ih}static get DATETIME_SHORT_WITH_SECONDS(){return Mh}static get DATETIME_MED(){return Lh}static get DATETIME_MED_WITH_SECONDS(){return Ah}static get DATETIME_MED_WITH_WEEKDAY(){return jg}static get DATETIME_FULL(){return Fh}static get DATETIME_FULL_WITH_SECONDS(){return zh}static get DATETIME_HUGE(){return $h}static get DATETIME_HUGE_WITH_SECONDS(){return bh}}function Rr(t){if(M.isDateTime(t))return t;if(t&&t.valueOf&&Tn(t.valueOf()))return M.fromJSDate(t);if(t&&typeof t=="object")return M.fromObject(t);throw new Ge(`Unknown datetime argument: ${t}, of type ${typeof t}`)}function k0(t){return t.toString(16).padStart(2,"0")}function Qa(t){const e=new Uint8Array((t||40)/2);return window.crypto.getRandomValues(e),Array.from(e,k0).join("")}function T0(t,e,n,r){if(t[n]===e[n])return 0;const s=(t[n]||"")<(e[n]||"")?-1:1;return r===Ne.asc?s:-s}function E0(t,e,n,r){if(t[n]===e[n])return 0;const s=(t[n]||"")<(e[n]||"")?-1:1;return r===Ne.asc?s:-s}function N0(t,e,n,r){if(t[n]===e[n])return 0;const s=t[n]1?e[e.length-1]:"1"}function xm(t,e){const n=M.fromSeconds(t,{zone:"UTC"}).setLocale(e);return`${n.toFormat("dd-MM-yyyy TTT")} (${n.toRelative()})`}function C0(t){return new RegExp("^(?:[a-z]+:)?//","i").test(t)}function j0(t){return t.includes("withId=true")}function Sm(t){return t.getElementsByTagName("parsererror").length>0?t.getElementsByTagName("parsererror")[0].textContent:""}function _0(t){return` - - ${t.id_cert} - - -`}function O0(t){return` - - ${t.id_cert} - -`}function P0(t){const e=[];if(t.too_permissive)for(const n of t.too_permissive){e.push({action:"remove",reason:vt.tooPermissive,prefix:n.current.prefix,asn:n.current.asn,max_length:n.current.max_length||parseInt(n.current.prefix.split("/")[1])});for(const r of n.new)e.push({action:"remove",reason:vt.specific,prefix:r.prefix,asn:r.asn,max_length:parseInt(r.prefix.split("/")[1])})}if(t.not_found)for(const n of t.not_found)e.push({action:"add",reason:vt.notFound,prefix:n.prefix,asn:n.asn,max_length:parseInt(n.prefix.split("/")[1])});if(t.invalid_length)for(const n of t.invalid_length)e.push({action:"add",reason:vt.invalidLength,prefix:n.prefix,asn:n.asn,max_length:parseInt(n.prefix.split("/")[1])});if(t.redundant)for(const n of t.redundant)e.push({action:"remove",reason:vt.redundant,prefix:n.prefix,asn:n.asn,max_length:parseInt(n.prefix.split("/")[1])});if(t.stale)for(const n of t.stale)e.push({action:"remove",reason:vt.stale,prefix:n.prefix,asn:n.asn,max_length:parseInt(n.prefix.split("/")[1])});if(t.invalid_asn)for(const n of t.invalid_asn)e.push({action:"remove",reason:vt.invalidAsn,prefix:n.prefix,asn:n.asn,max_length:parseInt(n.prefix.split("/")[1])});if(t.as0_redundant)for(const n of t.as0_redundant)e.push({action:"remove",reason:vt.as0Redundant,prefix:n.prefix,asn:n.asn,max_length:parseInt(n.prefix.split("/")[1])});if(t.disallowing)for(const n of t.disallowing)e.push({action:"remove",reason:vt.disallowing,prefix:n.prefix,asn:n.asn,max_length:parseInt(n.prefix.split("/")[1])});return e}class km{constructor(){oe(this,"baseUrl");oe(this,"VERSION_URL","https://api.github.com/repos/nlnetlabs/krill/releases/latest");oe(this,"token");this.baseUrl=window.location.origin,this.token=null}setToken(e){this.token=e}async get(e,n){const r=await fetch(`${this.baseUrl}${e}`,{...n,headers:{Authorization:`Bearer ${this.token}`,...(n==null?void 0:n.headers)||{}}});if((r.status===401||r.status===403)&&this.setToken(null),!(r.headers.get("Content-Type")==="application/json")){const a=await r.text();if(r.status===200)return a;throw{status:r.status,msg:a}}const i=await r.json();if(r.status===200)return i;throw{status:r.status,msg:i.msg||null}}post(e,n){return this.get(e,{method:"POST",...n})}postCas(e){return this.post("/api/v1/cas",{body:JSON.stringify({handle:e}),headers:{"Content-Type":"application/json"}})}getCas(){return this.get("/api/v1/cas").then(({cas:e})=>e.map(({handle:n})=>n).reverse())}getCaDetails(e){return this.get(`/api/v1/cas/${e}`)}getCaRoas(e){return this.get(`/api/v1/cas/${e}/routes/analysis/full`).then(n=>n.map(r=>({id:Qa(10),...r})))}getCaAspas(e){return this.get(`/api/v1/cas/${e}/aspas`).then(n=>n.map(r=>({id:Qa(10),...r})))}getCaSuggestions(e){return this.get(`/api/v1/cas/${e}/routes/analysis/suggest`).then(n=>P0(n)).then(n=>n.map(r=>({id:Qa(10),...r})))}refreshCaParents(){return this.post("/api/v1/bulk/cas/sync/parent")}getCaParents(e){return this.get(`/api/v1/cas/${e}/parents`).then(n=>Object.entries(n).map(([r,s])=>({name:r,...s})))}refreshCaRepo(){return this.post("/api/v1/bulk/cas/sync/repo")}getCaRepoStatus(e){return this.get(`/api/v1/cas/${e}/repo/status`)}getInfo(){return this.get("/stats/info")}getVersion(){return fetch(this.VERSION_URL).then(e=>e.json())}getChildRequest(e){return this.get(`/api/v1/cas/${e}/id/child_request.xml`)}getPublisherRequest(e){return this.get(`/api/v1/cas/${e}/id/publisher_request.xml`)}postParent(e,n,r){return this.post(`/api/v1/cas/${e}/parents/${n}`,{body:r})}postRepository(e,n,r){return this.post(`/api/v1/cas/${e}/repo`,{body:r})}updateRoutes(e,n){return this.get(`/api/v1/cas/${e}/routes`,{method:"POST",body:JSON.stringify(n),headers:{"Content-Type":"application/json"}})}updateAspas(e,n){return this.get(`/api/v1/cas/${e}/aspas`,{method:"POST",body:JSON.stringify(n),headers:{"Content-Type":"application/json"}})}getLoginMethod(){return fetch(`${this.baseUrl}/auth/login`).then(e=>e.status===200?e.text().then(n=>C0(n)?{redirect_url:n}:{with_id:j0(n)}):Promise.reject(e))}postLogin(e,n){const r="/auth/login";if(n){this.setToken(null);const s=btoa(`${n}:${e}`);return this.post(r,{headers:{Authorization:`Basic ${s}`}})}return this.setToken(e),this.post(r)}checkToken(e){return this.setToken(e),this.get("/api/v1/authorized")}getTestBedEnabled(){return fetch("/testbed/enabled").then(e=>e.status===200?!0:e.status===400?!1:Promise.reject(e))}}let qc=null;function R0(){const[t,e]=P.useState(qc);return P.useEffect(()=>{t||new km().getInfo().then(r=>{e(r),qc=r})},[]),t}const D0="/assets/logout-c725fd2c.svg",I0="/assets/user-5d1f1b14.svg";function ou({initial:t}){const e=cn(),[n,r]=P.useState(t);return P.useEffect(()=>e.usePlugin(()=>({onTransitionStart:()=>r(!0),onTransitionSuccess:()=>r(!1)})),[]),n?l.jsx("div",{className:"loader",children:l.jsx("span",{children:"Loading…"})}):null}function Tm({options:t,value:e,onChange:n,className:r}){const[s,i]=P.useState(!1);return l.jsxs("div",{className:`select ${r||""}`,children:[l.jsx("button",{className:s?"open":"",onClick:()=>i(!s),onBlur:()=>{setTimeout(()=>i(!1),300)},onKeyDown:a=>{a.key==="Escape"&&i(!1)},children:t[e]}),l.jsx("ul",{className:s?"show":"hide",children:Object.entries(t).map(([a,o])=>l.jsx("li",{className:e===a?"selected":"",onClick:()=>n(a),children:o},a))})]})}function Ss({notification:t,onClose:e}){return l.jsxs("div",{className:`notification popup ${t.type}`,children:[l.jsx("button",{className:"close",onClick:e,children:"×"}),l.jsx("span",{children:t.message})]})}function M0(){const t=de(),[e,n]=P.useState(!1),r=()=>{n(!0),t.setNotification(null)};return P.useEffect(()=>{if(t.notification){n(!1);const s=setTimeout(r,5e3);return()=>clearTimeout(s)}},[t.notification]),!t.notification||e?null:l.jsx(Ss,{notification:t.notification,onClose:r})}function dn({children:t}){const e=Z(),{route:n}=je(),r=R0(),s=de(),i=new Date().getFullYear(),a=A();return P.useEffect(()=>{document.title=s.ca?`Krill - ${s.ca}`:"Krill"},[s.ca]),l.jsxs(l.Fragment,{children:[l.jsx(ou,{initial:!1}),l.jsxs("header",{children:[l.jsx("h1",{onClick:()=>e({},"cas"),children:l.jsx("span",{children:"Krill"})}),l.jsxs("menu",{children:[l.jsx(Tm,{options:Sg,value:s.locale,onChange:o=>e({locale:o})}),s.userDetails&&l.jsxs(l.Fragment,{children:[l.jsxs("button",{className:"pop",children:[l.jsx("img",{src:I0}),l.jsxs("div",{children:[l.jsx("h5",{children:a.common.userInfo.title}),l.jsx("table",{children:l.jsxs("tbody",{children:[l.jsxs("tr",{children:[l.jsxs("th",{children:[a.common.userInfo.user,":"]}),l.jsx("td",{children:s.userDetails.id})]}),Object.entries(s.userDetails.attributes).map(([o,u])=>l.jsxs("tr",{children:[l.jsxs("th",{className:"user-attribute",children:[o,":"]}),l.jsx("td",{children:u})]},o))]})})]})]}),l.jsx("button",{onClick:()=>e({},"logout"),children:l.jsx("img",{src:D0})})]})]})]}),l.jsx(M0,{}),l.jsx("div",{className:`content route-${n.name}`,children:t}),l.jsxs("footer",{children:[l.jsxs("span",{children:["© ",i," Stichting NLnet Labs"," - ","Krill ",r==null?void 0:r.version]}),l.jsxs("span",{children:[l.jsx("a",{href:"https://nlnetlabs.nl/services/contracts/",target:"_blank",rel:"noreferrer",children:a.common.supportcontracts})," - ",l.jsx("a",{href:"https://krill.docs.nlnetlabs.nl/",target:"_blank",rel:"noreferrer",children:a.common.readthedocs})," - ",l.jsx("a",{href:"https://github.com/NLnetLabs/krill/issues/new",target:"_blank",rel:"noreferrer",children:a.common.report})]})]})]})}function L0({columns:t,filtering:e}){const n=Z(),r=s=>{const i=e.sort===s&&e.order===Ne.asc?Ne.desc:Ne.asc;n({sort:s,order:i})};return l.jsx("thead",{children:l.jsxs("tr",{children:[l.jsx("th",{}),t.map(({label:s,accessor:i})=>l.jsxs("th",{onClick:()=>r(i),children:[s,i===e.sort&&l.jsx("span",{className:e.order})]},i)),l.jsx("th",{})]})})}function Bc({announcements:t}){const e=A();return l.jsxs("table",{children:[l.jsx("thead",{children:l.jsxs("tr",{children:[l.jsx("th",{children:e.announcements.asn}),l.jsx("th",{children:e.announcements.prefix})]})}),l.jsxs("tbody",{children:[t.length===0&&l.jsx("tr",{children:l.jsx("td",{colSpan:2,children:l.jsx("span",{className:"muted",children:e.common.nodata})})}),t.map((n,r)=>l.jsxs("tr",{children:[l.jsx("td",{children:n.asn}),l.jsx("td",{children:n.prefix})]},r))]})]})}function A0({authorizes:t,disallows:e}){const n=A();return l.jsxs("div",{className:"row",children:[l.jsxs("div",{children:[l.jsx("h3",{children:n.announcements.authorizes.replace("{number}",t.length.toString())}),l.jsx(Bc,{announcements:t})]}),l.jsxs("div",{children:[l.jsx("h3",{children:n.announcements.disallows.replace("{number}",e.length.toString())}),l.jsx(Bc,{announcements:e})]})]})}const Em="/assets/trash-d9c6ee55.svg",F0="/assets/edit-776bf3c3.svg",z0="/assets/plus-e8f1d182.svg";function $0({roa:t,allowAdd:e,allowDelete:n,hasAnnouncements:r}){var d;const s=Z(),[i,a]=P.useState(!1),o=A(),u={id:((d=t.id)==null?void 0:d.toString())||"new"},c=`${t.state}_help`,f=o.announcements.state[c];return l.jsxs(l.Fragment,{children:[l.jsxs("tr",{className:r?"announcements":"",children:[l.jsx("td",{children:r&&l.jsx("button",{className:`expand ${i?"open":""}`,onClick:()=>a(!i)})}),l.jsx("td",{children:t.asn}),l.jsxs("td",{children:[t.prefix,t.max_length&&-t.max_length]}),l.jsxs("td",{children:[t.comment,n&&l.jsx("button",{className:"button icon light right",onClick:()=>s(u,"cas.edit"),children:l.jsx("img",{src:F0})})]}),l.jsxs("td",{children:[l.jsx("span",{className:`state ${t.state}`,title:f,children:o.announcements.state[t.state]}),t.authorizes&&l.jsx("span",{className:"badge success",children:t.authorizes.length}),t.disallows&&l.jsx("span",{className:"badge warning",children:t.disallows.length})]}),l.jsxs("td",{className:"actions",children:[e&&l.jsx("button",{className:"button icon",onClick:()=>s(u,"cas.add"),children:l.jsx("img",{src:z0})}),n&&l.jsx("button",{className:"button icon",onClick:()=>s(u,"cas.delete"),children:l.jsx("img",{src:Em})})]})]}),r&&i&&l.jsx("tr",{className:"announcements",children:l.jsx("td",{colSpan:6,children:l.jsx(A0,{authorizes:t.authorizes||[],disallows:t.disallows||[]})})})]})}function b0({tableData:t}){return l.jsx("tbody",{children:t.filter(e=>e.state!=Ie.AnnouncementDisallowedAs0).map(e=>l.jsx($0,{roa:e,hasAnnouncements:!!e.authorizes||!!e.disallows,allowDelete:e.state===Ie.RoaSeen||e.state===Ie.RoaUnseen||e.state===Ie.RoaNotHeld||e.state==Ie.RoaNoAnnouncementInfo||e.state===Ie.RoaTooPermissive||e.state===Ie.RoaDisallowing||e.state===Ie.RoaRedundant||e.state==Ie.RoaAs0||e.state===Ie.RoaAs0Redundant,allowAdd:e.state===Ie.AnnouncementNotFound||e.state===Ie.AnnouncementInvalidLength||e.state===Ie.AnnouncementInvalidAsn},e.id))})}function U0({filtering:t}){const e=A(),r=de().getRoas(t),s=[{label:e.announcements.asn,accessor:Yn.asn},{label:e.announcements.prefix,accessor:Yn.prefix},{label:e.caDetails.comment,accessor:Yn.comment},{label:e.announcements.stateLabel,accessor:Yn.state}];return l.jsxs("table",{className:"roa-table",children:[l.jsx(L0,{columns:s,filtering:t}),l.jsx(b0,{tableData:r})]})}function Nm({details:t}){return l.jsx("div",{className:"ca-details card",children:l.jsx("table",{children:l.jsx("tbody",{children:Object.entries(t.resources).map(([e,n])=>l.jsxs("tr",{children:[l.jsx("th",{children:e}),l.jsx("td",{children:n.split(",").map(r=>l.jsx("p",{children:r},r))})]},e))})})})}function V0({onClose:t,roa:e}){var w;const n=A(),r=Z(),[s,i]=P.useState((e==null?void 0:e.asn.toString())||""),[a,o]=P.useState((e==null?void 0:e.prefix)||""),[u,c]=P.useState((e==null?void 0:e.comment)||""),f=Wc(e==null?void 0:e.prefix),[d,p]=P.useState(((w=e==null?void 0:e.max_length)==null?void 0:w.toString())||f),y=g=>{g.preventDefault();const k=g.target;k.checkValidity()?r({asn:s,prefix:a,comment:u,max_length:d}):k.reportValidity()};return l.jsxs(l.Fragment,{children:[l.jsx("h3",{children:n.caDetails.addRoa}),l.jsxs("form",{onSubmit:y,children:[l.jsxs("div",{children:[l.jsx("label",{htmlFor:"asn required",children:n.announcements.asn}),l.jsx("input",{type:"number",min:"0",name:"asn",onInput:g=>g.target.setCustomValidity(""),onInvalid:g=>g.target.setCustomValidity(n.caDetails.addROAForm.asn_format),value:s,onChange:g=>i(g.target.value),required:!0})]}),l.jsxs("div",{children:[l.jsx("label",{htmlFor:"prefix required",children:n.announcements.prefix}),l.jsx("input",{name:"prefix",pattern:"^((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\\.(?!\\/)|\\/)){4}([0-9]|[1-2][0-9]|3[0-2]))|(([a-fA-F0-9:]+)\\/([1-9]|[1-9][0-9]|1[01][0-9]|12[0-8]))$",onInput:g=>g.target.setCustomValidity(""),onInvalid:g=>g.target.setCustomValidity(n.caDetails.addROAForm.prefix_format),title:n.caDetails.addROAForm.prefix_format,value:a,onChange:g=>o(g.target.value),required:!0})]}),l.jsxs("div",{children:[l.jsx("label",{htmlFor:"maxLength",children:n.caDetails.maxLength}),l.jsx("input",{type:"number",min:Wc(a)||1,max:a.includes(".")||!a.includes(":")?32:128,name:"maxLength",value:d,onChange:g=>p(g.target.value),placeholder:n.caDetails.maxLengthTooltip})]}),l.jsxs("div",{children:[l.jsx("label",{htmlFor:"comment",children:n.caDetails.comment}),l.jsx("input",{name:"comment",value:u,onChange:g=>c(g.target.value)})]}),l.jsxs("div",{className:"actions",children:[l.jsx("button",{type:"button",className:"button outline",onClick:t,children:n.common.cancel}),l.jsx("button",{type:"submit",className:"button",children:n.common.confirm})]})]})]})}const H0="modulepreload",W0=function(t){return"/"+t},Zc={},Tt=function(e,n,r){if(!n||n.length===0)return e();const s=document.getElementsByTagName("link");return Promise.all(n.map(i=>{if(i=W0(i),i in Zc)return;Zc[i]=!0;const a=i.endsWith(".css"),o=a?'[rel="stylesheet"]':"";if(!!r)for(let f=s.length-1;f>=0;f--){const d=s[f];if(d.href===i&&(!a||d.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${i}"]${o}`))return;const c=document.createElement("link");if(c.rel=a?"stylesheet":H0,a||(c.as="script",c.crossOrigin=""),c.href=i,document.head.appendChild(c),a)return new Promise((f,d)=>{c.addEventListener("load",f),c.addEventListener("error",()=>d(new Error(`Unable to preload CSS for ${i}`)))})})).then(()=>e())},q0=(t,e)=>{const n=t[e];return n?typeof n=="function"?n():Promise.resolve(n):new Promise((r,s)=>{(typeof queueMicrotask=="function"?queueMicrotask:setTimeout)(s.bind(null,new Error("Unknown variable dynamic import: "+e)))})};async function B0(t){return(await q0(Object.assign({"../locales/de.ts":()=>Tt(()=>import("./de-e4495468.js"),[]),"../locales/en.ts":()=>Tt(()=>import("./en-893c19c3.js"),[]),"../locales/es.ts":()=>Tt(()=>import("./es-bf4361b1.js"),[]),"../locales/fr.ts":()=>Tt(()=>import("./fr-fd67af37.js"),[]),"../locales/gr.ts":()=>Tt(()=>import("./gr-9c53613e.js"),[]),"../locales/nl.ts":()=>Tt(()=>import("./nl-f91bc25c.js"),[]),"../locales/pt.ts":()=>Tt(()=>import("./pt-ee7cebe0.js"),[]),"../locales/zh-Hans.ts":()=>Tt(()=>import("./zh-Hans-6406b9d3.js"),[]),"../locales/zh-Hant.ts":()=>Tt(()=>import("./zh-Hant-d9271047.js"),[])}),`../locales/${t}.ts`)).translations}function Cm(t,e){return Object.entries(e).reduce((n,[r,s])=>n.replace(`{${r}}`,s),t)}function Z0({onClose:t,roa:e}){var i;const n=A(),r=Z(),s={asn:e.asn.toString(),prefix:e.prefix,max_length:((i=e.max_length)==null?void 0:i.toString())||""};return l.jsxs(l.Fragment,{children:[l.jsx("h3",{children:n.common.warning}),l.jsx("p",{children:Cm(n.caDetails.confirmation.message,s)}),l.jsxs("div",{className:"actions",children:[l.jsx("button",{type:"button",className:"button outline",onClick:t,children:n.common.cancel}),l.jsx("button",{className:"button",onClick:()=>{r(s)},children:n.common.ok})]})]})}function Q0({onClose:t,roa:e}){const n=A(),r=Z(),[s,i]=P.useState((e==null?void 0:e.comment)||"");return l.jsxs(l.Fragment,{children:[l.jsx("h3",{children:n.common.edit}),l.jsxs("form",{autoComplete:"off",onSubmit:a=>{a.preventDefault(),s!==(e==null?void 0:e.comment)?r({comment:s}):t()},children:[l.jsxs("div",{children:[l.jsx("label",{htmlFor:"comment required",children:n.caDetails.comment}),l.jsx("input",{name:"comment",value:s,onChange:a=>i(a.target.value)})]}),l.jsxs("div",{className:"actions",children:[l.jsx("button",{type:"button",className:"button outline",onClick:t,children:n.common.cancel}),l.jsx("button",{type:"submit",className:"button",children:n.common.confirm})]})]})]})}function xr({onClose:t,children:e}){return l.jsx("div",{className:"modal",onMouseDown:t,children:l.jsx("div",{onMouseDown:n=>{n.stopPropagation()},children:e})})}function Y0(){const{route:t}=je(),e=cn(),{route:{params:n}}=je(),i=de().getRoas().find(o=>o.id===n.id),a=()=>{e.navigate("cas",{ca:n.ca})};return!i&&t.name!=="cas.add_new"?null:l.jsxs(xr,{onClose:a,children:[t.name.startsWith("cas.add")&&l.jsx(V0,{onClose:a,roa:i}),t.name.startsWith("cas.edit")&&l.jsx(Q0,{onClose:a,roa:i}),t.name==="cas.delete"&&l.jsx(Z0,{onClose:a,roa:i})]})}function ua(){var i,a,o;const t=de(),e=A(),n=Z(),r=t.ca&&t.parents[t.ca].length>0,s=t.repoStatus&&t.ca&&((i=t.repoStatus[t.ca])==null?void 0:i.last_exchange);return l.jsxs(l.Fragment,{children:[l.jsxs("div",{className:"space-between border-bottom row",children:[l.jsxs("h2",{children:[e.cas.ca," ",l.jsx("strong",{children:t.ca})]}),t.cas&&((a=t.cas)==null?void 0:a.length)>1&&l.jsxs("div",{children:[l.jsx("label",{htmlFor:"ca",children:e.caDetails.current}),l.jsx(Tm,{className:"wide",options:((o=t.cas)==null?void 0:o.sort().reduce((u,c)=>({...u,[c]:[c]}),{}))||{},value:t.ca||"",onChange:u=>n({ca:u},"cas")})]})]}),!r&&l.jsx("div",{className:"notification error",children:e.caDetails.onboardingWarning}),r&&!s&&l.jsx("div",{className:"notification error",children:e.caDetails.initializeRepository}),l.jsx("div",{children:l.jsxs("ul",{className:"tabs",children:[l.jsx("li",{children:l.jsx(Qt,{routeName:"cas",activeStrict:!0,routeParams:{ca:t.ca},children:e.caDetails.roas})}),l.jsx("li",{children:l.jsx(Qt,{routeName:"cas.aspas",routeParams:{ca:t.ca},children:e.caDetails.aspas})}),l.jsx("li",{children:l.jsx(Qt,{routeName:"cas.parents",routeParams:{ca:t.ca},children:e.caDetails.parents})}),l.jsx("li",{children:l.jsx(Qt,{routeName:"cas.repository",routeParams:{ca:t.ca},children:e.caDetails.repo})})]})})]})}function jm({currentPage:t,numPages:e}){const n=Z();let r;if(e<=7)r=[...Array(e).keys()].map(s=>(s+1).toString());else if(r=Array(7),r[0]="1",r[6]=e.toString(),t>=1&&t<=4){for(let s=1;s<5;s++)r[s]=(s+1).toString();r[5]="..."}else if(t>=e-3&&t<=e){r[1]="...";for(let s=2;s<7;s++)r[s]=(e-6+s).toString()}else{r[1]="...";for(let s=2;s<5;s++)r[s]=(t-3+s).toString();r[5]="..."}return l.jsx(l.Fragment,{children:r.map((s,i)=>l.jsx("button",{className:s===t.toString()?"number current":"number",disabled:s===t.toString()||s==="...",onClick:()=>n({page:s}),children:s},i))})}function K0({filtering:t}){const e=A(),r=de().getRoas().length,s=Z(),i=Math.ceil(r/t.limit);return l.jsxs("div",{className:"pagination",children:[l.jsx("select",{value:t.limit,onChange:a=>s({limit:a.target.value,page:"1"}),children:xh.map(a=>l.jsxs("option",{value:a,children:[a," / ",e.common.page]},a))}),l.jsxs("div",{children:[l.jsx("button",{disabled:t.page===1,className:"arrow prev",onClick:()=>s({page:(t.page-1).toString()}),children:l.jsx("span",{children:"<"})}),l.jsx(jm,{currentPage:t.page,numPages:i}),l.jsx("button",{disabled:t.page>i-1,className:"arrow next",onClick:()=>s({page:(t.page+1).toString()}),children:l.jsx("span",{children:">"})})]})]})}function G0({columns:t,filtering:e,setAllCheckboxes:n,checkBoxState:r}){const s=Z(),i=a=>{const o=e.sort===a&&e.order===Ne.asc?Ne.desc:Ne.asc;s({sort:a,order:o})};return l.jsx("thead",{children:l.jsxs("tr",{children:[l.jsx("th",{children:l.jsx("input",{type:"checkbox",checked:r===yt.checked,onChange:n,ref:a=>{a&&(a.indeterminate=r===yt.intermediate)}})}),l.jsx("th",{}),t.map(({label:a,accessor:o})=>l.jsxs("th",{onClick:()=>i(o),children:[a,o===e.sort&&l.jsx("span",{className:e.order})]},o)),l.jsx("th",{})]})})}const J0="/assets/trash-red-65027383.svg",X0="/assets/check-green-4525c79c.svg";function e1({suggestion:t,id:e,checked:n,handleCheckbox:r}){const s=A(),i=s.caDetails.suggestions.reasons[t.reason];return l.jsxs(l.Fragment,{children:[l.jsx("td",{children:l.jsx("input",{type:"checkbox",id:e,onChange:r,checked:n})}),l.jsxs("td",{children:[t.action==="add"&&l.jsx("span",{className:"add",title:s.caDetails.suggestions.adding,children:l.jsx("img",{src:X0,title:`${s.caDetails.suggestions.willAdd} (${i})`})}),t.action==="remove"&&l.jsx("span",{className:"remove",title:s.caDetails.suggestions.willRemove,children:l.jsx("img",{src:J0,title:`${s.caDetails.suggestions.willRemove} (${i})`})})]}),l.jsx("td",{children:t.asn}),l.jsx("td",{children:t.prefix}),l.jsx("td",{children:s.caDetails.suggestions.reasons[t.reason]})]})}function t1({suggestions:t,checkedBoxes:e,handleCheckbox:n}){return l.jsx("tbody",{children:t.map(r=>l.jsx("tr",{children:l.jsx(e1,{checked:e.includes(r.id||""),suggestion:r,id:r.id||"",handleCheckbox:n})},r.id))})}function n1({suggestions:t,filtering:e,checkedBoxes:n,handleCheckbox:r,handleAllCheckboxes:s,topCheckBoxState:i}){const a=A(),o=[{label:a.announcements.asn,accessor:Ai.asn},{label:a.announcements.prefix,accessor:Ai.prefix}];return l.jsxs("table",{className:"roa-table",children:[l.jsx(G0,{columns:o,filtering:e,setAllCheckboxes:s,checkBoxState:i}),l.jsx(t1,{checkedBoxes:n,suggestions:t,handleCheckbox:r})]})}function r1(t){const n=de().getSuggestions(t),r=[];for(const f of n)r.push(f.id||"");const[s,i]=P.useState([]),[a,o]=P.useState(yt.unchecked);return{checked:s,topCheckbox:a,suggestions:n,handleCheckbox:f=>{let d=[...s];f.target.checked?(d=[...s,f.target.id],r.every(p=>d.includes(p))?o(yt.checked):o(yt.intermediate)):(d.splice(s.indexOf(f.target.id),1),d.length>0?o(yt.intermediate):o(yt.unchecked)),i(d)},handleAllCheckboxes:f=>{f.target.checked?(i(r),o(yt.checked)):(i([]),o(yt.unchecked))}}}function s1({onClose:t,filtering:e}){const n=A(),r=Z(),{checked:s,topCheckbox:i,suggestions:a,handleCheckbox:o,handleAllCheckboxes:u}=r1(e);return l.jsxs(l.Fragment,{children:[l.jsx("h3",{children:n.caDetails.analysis}),a.length>0&&l.jsxs(l.Fragment,{children:[l.jsxs("div",{children:[n.caDetails.suggestions.following," ",l.jsx("a",{href:"https://krill.docs.nlnetlabs.nl/en/stable/manage-roas.html",target:"_blank",rel:"noreferrer",children:n.caDetails.suggestions.readMore})]}),l.jsx(n1,{checkedBoxes:s,suggestions:a,filtering:e,handleCheckbox:o,handleAllCheckboxes:u,topCheckBoxState:i})]}),a.length===0&&n.caDetails.suggestions.nochanges,l.jsxs("div",{className:"actions",children:[a.length>0&&l.jsxs(l.Fragment,{children:[l.jsx("button",{type:"button",className:"button outline",onClick:t,children:n.common.cancel}),l.jsx("button",{className:"button",onClick:()=>r({ids:JSON.stringify(s)},"cas.change"),children:n.common.confirm})]}),a.length===0&&l.jsx("button",{className:"button",onClick:t,children:n.common.ok})]})]})}function i1(){const t=cn(),{route:e,route:{params:n}}=je(),r=()=>{t.navigate("cas",{ca:n.ca})};if(e.name!=="cas.analyse")return null;const s={search:null,sort:n.sort||Ai.asn,order:n.order||Ne.asc,limit:parseInt(n.limit,10)||10,page:parseInt(n.page,10)||1};return l.jsx(xr,{onClose:r,children:e.name==="cas.analyse"&&l.jsx(s1,{onClose:r,filtering:s})})}function a1({filtering:t}){const e=A(),n=Z(),[r,s]=P.useState(t.search);return P.useEffect(()=>{const i=setTimeout(()=>{n(r?{search:r}:{search:void 0})},500);return()=>clearTimeout(i)},[r]),P.useEffect(()=>{s(t.search)},[t.search]),l.jsx("input",{type:"search",value:r||"",placeholder:e.announcements.search,onChange:i=>s(i.target.value)})}function o1(){const t=A(),e=de(),{route:n}=je(),r=Z(),s=n.params,i={search:s.search||null,sort:s.sort||Yn.asn,order:s.order||Ne.asc,limit:parseInt(s.limit,10)||25,page:parseInt(s.page,10)||1};return l.jsxs(dn,{children:[l.jsx(Y0,{}),n.name==="cas.analyse"&&l.jsx(i1,{}),l.jsx(ua,{}),l.jsxs("div",{className:"row",children:[l.jsxs("div",{className:"flex-1",children:[l.jsx(a1,{filtering:i}),l.jsx(U0,{filtering:i}),l.jsx(K0,{filtering:i}),l.jsxs("div",{className:"roa-actions",children:[l.jsx("div",{children:l.jsx("button",{className:"button",onClick:()=>r({},"cas.add_new"),children:t.caDetails.addRoa})}),l.jsx("div",{children:l.jsx("button",{className:"button inverted",onClick:()=>r({},"cas.analyse"),children:t.caDetails.analyseThis})})]})]}),e.ca&&l.jsx(Nm,{details:e.caDetails[e.ca]})]})]})}function Qc({onClose:t,aspa:e,aspas:n,edit:r}){const s=A(),i=Z(),[a,o]=P.useState((e==null?void 0:e.customer.toString())||""),[u,c]=P.useState((e==null?void 0:e.providers.join(", "))||""),f=d=>{d.preventDefault();const p=d.target;p.checkValidity()?i({customer:a,providers:u}):p.reportValidity()};return l.jsxs(l.Fragment,{children:[l.jsx("h3",{children:r?s.caDetails.editAspa:s.caDetails.addAspa}),l.jsxs("form",{onSubmit:f,children:[l.jsxs("div",{children:[l.jsx("label",{htmlFor:"customer required",children:s.aspas.customer}),l.jsx("input",{type:"number",min:"0",name:"customer",onInput:d=>d.target.setCustomValidity(""),onInvalid:d=>d.target.setCustomValidity(s.aspas.customer_validation_format),value:a,onChange:d=>{let p=d.target.value;o(p),!r&&n.find(y=>y.customer===Number(p))&&d.target.setCustomValidity(s.aspas.customer_validation_format)},required:!0,disabled:r})]}),l.jsxs("div",{children:[l.jsx("label",{htmlFor:"providers required",children:s.aspas.providers}),l.jsx("input",{type:"text",pattern:"^((\\d+),\\s*)*(\\d+)$",name:"customer",onInput:d=>d.target.setCustomValidity(""),onInvalid:d=>d.target.setCustomValidity(s.aspas.providers_validation_format),value:u,onChange:d=>c(d.target.value),required:!0})]}),l.jsxs("div",{className:"actions",children:[l.jsx("button",{type:"button",className:"button outline",onClick:t,children:s.common.cancel}),l.jsx("button",{type:"submit",className:"button",children:s.common.confirm})]})]})]})}function l1({onClose:t,aspa:e}){const n=A(),r=Z(),s={customer:e.customer.toString(),providers:e.providers.join(", ")};return l.jsxs(l.Fragment,{children:[l.jsx("h3",{children:n.common.warning}),l.jsx("p",{children:Cm(n.aspas.confirmation.message,s)}),l.jsxs("div",{className:"actions",children:[l.jsx("button",{type:"button",className:"button outline",onClick:t,children:n.common.cancel}),l.jsx("button",{className:"button",onClick:()=>{r(s)},children:n.common.ok})]})]})}function u1(){const{route:t}=je(),e=cn(),{route:{params:n}}=je(),s=de().getAspas(),i=s.find(o=>o.id===n.id),a=()=>{e.navigate("cas.aspas",{ca:n.ca})};return!i&&t.name!=="cas.aspas.add_new"?null:l.jsxs(xr,{onClose:a,children:[t.name.startsWith("cas.aspas.add")&&l.jsx(Qc,{onClose:a,aspa:i,aspas:s,edit:!1}),t.name.startsWith("cas.aspas.edit")&&l.jsx(Qc,{onClose:a,aspa:i,aspas:s,edit:!0}),t.name==="cas.aspas.delete"&&l.jsx(l1,{onClose:a,aspa:i})]})}function c1({filtering:t}){const e=A(),n=Z(),[r,s]=P.useState(t.search);return P.useEffect(()=>{const i=setTimeout(()=>{n(r?{search:r}:{search:void 0})},500);return()=>clearTimeout(i)},[r]),P.useEffect(()=>{s(t.search)},[t.search]),l.jsx("input",{type:"search",value:r||"",placeholder:e.aspas.search,onChange:i=>s(i.target.value)})}function d1({columns:t,filtering:e}){const n=Z(),r=s=>{const i=e.sort===s&&e.order===Ne.asc?Ne.desc:Ne.asc;n({sort:s,order:i})};return l.jsx("thead",{children:l.jsxs("tr",{children:[l.jsx("th",{}),t.map(({label:s,accessor:i})=>l.jsxs("th",{onClick:()=>r(i),children:[s,i===e.sort&&l.jsx("span",{className:e.order})]},i)),l.jsx("th",{})]})})}const f1="/assets/edit-white-a808b3e3.svg";function h1({aspa:t}){var r;const e=Z();A();const n={id:((r=t.id)==null?void 0:r.toString())||"new"};return l.jsx(l.Fragment,{children:l.jsxs("tr",{children:[l.jsx("td",{}),l.jsx("td",{children:t.customer}),l.jsx("td",{children:t.providers.join(", ")}),l.jsxs("td",{className:"actions",children:[l.jsx("button",{className:"button icon",onClick:()=>e(n,"cas.aspas.edit"),children:l.jsx("img",{src:f1})}),l.jsx("button",{className:"button icon",onClick:()=>e(n,"cas.aspas.delete"),children:l.jsx("img",{src:Em})})]})]})})}function m1({tableData:t}){return l.jsx("tbody",{children:t.map(e=>l.jsx(h1,{aspa:e},e.id))})}function p1({filtering:t}){const e=A(),r=de().getAspas(t),s=[{label:e.aspas.customer,accessor:Li.customer},{label:e.aspas.providers,accessor:Li.providers}];return l.jsxs("table",{className:"roa-table",children:[l.jsx(d1,{columns:s,filtering:t}),l.jsx(m1,{tableData:r})]})}function v1({filtering:t}){const e=A(),r=de().getRoas().length,s=Z(),i=Math.ceil(r/t.limit);return l.jsxs("div",{className:"pagination",children:[l.jsx("select",{value:t.limit,onChange:a=>s({limit:a.target.value,page:"1"}),children:xh.map(a=>l.jsxs("option",{value:a,children:[a," / ",e.common.page]},a))}),l.jsxs("div",{children:[l.jsx("button",{disabled:t.page===1,className:"arrow prev",onClick:()=>s({page:(t.page-1).toString()}),children:l.jsx("span",{children:"<"})}),l.jsx(jm,{currentPage:t.page,numPages:i}),l.jsx("button",{disabled:t.page>i-1,className:"arrow next",onClick:()=>s({page:(t.page+1).toString()}),children:l.jsx("span",{children:">"})})]})]})}function g1(){const t=A(),e=de(),{route:n}=je(),r=Z(),s=n.params,i={search:s.search||null,sort:s.sort||Li.customer,order:s.order||Ne.asc,limit:parseInt(s.limit,10)||25,page:parseInt(s.page,10)||1};return l.jsxs(dn,{children:[l.jsx(u1,{}),l.jsx(ua,{}),l.jsxs("div",{className:"row",children:[l.jsxs("div",{className:"flex-1",children:[l.jsx(c1,{filtering:i}),l.jsx(p1,{filtering:i}),l.jsx(v1,{filtering:i}),l.jsxs("div",{className:"roa-actions",children:[l.jsx("div",{children:l.jsx("button",{className:"button",onClick:()=>r({},"cas.aspas.add_new"),children:t.caDetails.addAspa})}),l.jsx("div",{})]})]}),e.ca&&l.jsx(Nm,{details:e.caDetails[e.ca]})]})]})}const _m="/assets/upload-87e6fdfd.svg";let Yc="";function y1(){const[t,e]=P.useState(Yc),n=de();return P.useEffect(()=>{n.ca&&n.api.getChildRequest(n.ca).then(r=>{e(r),Yc=r})},[]),t}function Om(t){const[e,n]=P.useState(null),[r,s]=P.useState(t),[i,a]=P.useState("");return P.useEffect(()=>{s(t)},[t]),{notification:e,setNotification:n,request:r,setRequest:s,response:i,setResponse:a,handleUpload:u=>{if(u.currentTarget.files){const c=new FileReader;c.onload=()=>{a(c.result)},c.readAsText(u.currentTarget.files[0])}}}}function w1(){const t=y1(),e=cn(),{route:{params:n}}=je(),r=Z(),[s,i]=P.useState(""),{notification:a,setNotification:o,request:u,setRequest:c,response:f,setResponse:d,handleUpload:p}=Om(t);return{notification:a,setNotification:o,name:s,setName:i,request:u,setRequest:c,response:f,setResponse:d,onSubmit:async g=>{g.preventDefault(),r({name:s,response:f})},onClose:()=>{e.navigate("cas.parents",{ca:n.ca})},handleUpload:p}}const x1="/assets/clipboard-4659ffea.svg",S1="/assets/download-2dfead4c.svg";function ca({xml:t,name:e,setNotification:n}){const r=A(),s=()=>{navigator.clipboard.writeText(t),n({type:U.success,message:r.common.copySuccess})};return l.jsxs(l.Fragment,{children:[l.jsx("button",{className:"button large icon",type:"button",title:r.common.copy,onClick:s,children:l.jsx("img",{src:x1,alt:r.common.copy})}),l.jsx("a",{className:"button large icon",title:r.common.download,href:`data:application/xml;base64,${btoa(t)}`,download:`${e}.xml`,children:l.jsx("img",{src:S1,alt:r.common.download})})]})}function k1(){const t=A(),{notification:e,setNotification:n,name:r,setName:s,request:i,setRequest:a,response:o,setResponse:u,onSubmit:c,onClose:f,handleUpload:d}=w1();return l.jsxs(xr,{onClose:f,children:[e&&l.jsx(Ss,{notification:e,onClose:()=>n(null)}),l.jsx("h3",{children:t.caDetails.parentsTab.addParent}),l.jsxs("form",{onSubmit:c,method:"POST",children:[l.jsxs("div",{children:[l.jsx("label",{children:t.caDetails.parentsTab.request}),l.jsx("textarea",{name:"request",readOnly:!0,value:i,id:"request",onChange:p=>a(p.target.value)}),l.jsx("div",{children:l.jsx(ca,{xml:i,name:"child_request",setNotification:n})})]}),l.jsxs("div",{children:[l.jsx("label",{children:t.caDetails.parentsTab.response}),l.jsx("textarea",{name:"response",value:o,onChange:p=>u(p.target.value)}),l.jsx("input",{type:"file",id:"upload",onChange:d}),l.jsx("label",{className:"button large icon",htmlFor:"upload",title:t.common.dropOrClick,children:l.jsx("img",{src:_m,alt:t.common.dropOrClick})})]}),l.jsxs("div",{children:[l.jsx("label",{children:t.caDetails.parentsTab.name}),l.jsx("input",{name:"name",value:r,onChange:p=>s(p.target.value),required:!0})]}),l.jsxs("div",{className:"actions",children:[l.jsx("button",{type:"button",className:"button outline",onClick:f,children:t.common.cancel}),l.jsx("button",{type:"submit",className:"button",children:t.common.confirm})]})]})]})}function T1({parent:t,loading:e}){const n=A(),{locale:r}=de(),s=e?n.caDetails.loading.replace("{handle}","..."):xm(t.last_exchange.timestamp,r);return l.jsxs("div",{className:"info-table",children:[l.jsx("h4",{children:t.name}),l.jsx("table",{children:l.jsxs("tbody",{children:[l.jsxs("tr",{children:[l.jsx("th",{children:n.caDetails.parents}),l.jsx("td",{children:t.last_exchange.uri})]}),l.jsxs("tr",{children:[l.jsx("th",{children:n.caDetails.lastExchange}),l.jsx("td",{children:t.last_exchange.result!="Success"?l.jsxs("p",{className:"failure",children:[s,l.jsx("br",{}),t.last_exchange.result.Failure.msg]}):l.jsx("p",{className:"success",children:s})})]}),l.jsxs("tr",{children:[l.jsx("th",{children:n.caDetails.allResources}),l.jsxs("td",{children:["ASN: ",t.all_resources.asn,l.jsx("br",{}),"IPv4: ",t.all_resources.ipv4,l.jsx("br",{}),"IPv6: ",t.all_resources.ipv6,l.jsx("br",{})]})]})]})})]})}function E1(){var o;const t=A(),{route:e}=je(),n=de(),r=Z(),[s,i]=P.useState(!1),a=()=>{i(!0),n.refreshParents().then(()=>{i(!1)})};return l.jsxs(dn,{children:[e.name==="cas.parents.add"&&l.jsx(k1,{}),s&&l.jsx(Ss,{notification:{type:U.success,message:t.caDetails.refresh.replace("{handle}",t.caDetails.parents.toLowerCase())},onClose:()=>i(!1)}),l.jsx(ua,{}),n.parents&&n.ca&&((o=n.parents[n.ca])==null?void 0:o.map(u=>l.jsx(T1,{parent:u,loading:s},u.name))),l.jsx("button",{className:"button",onClick:()=>r({},"cas.parents.add"),children:t.caDetails.parentsTab.addParent}),l.jsx("button",{className:"button inverted",onClick:a,children:t.caDetails.syncParents})]})}function N1({repo:t,locale:e,loading:n}){const r=A(),s=n?r.caDetails.loading.replace("{handle}","..."):xm(t.last_exchange.timestamp,e);return l.jsx("div",{className:"info-table",children:l.jsx("table",{children:l.jsxs("tbody",{children:[l.jsxs("tr",{children:[l.jsx("th",{children:r.caDetails.exchangeUri}),l.jsx("td",{children:t.last_exchange.uri})]}),l.jsxs("tr",{children:[l.jsx("th",{children:r.caDetails.lastExchange}),l.jsx("td",{children:t.last_exchange.result!="Success"?l.jsxs("p",{className:"failure",children:[s,l.jsx("br",{}),t.last_exchange.result.Failure.msg]}):l.jsx("p",{className:"success",children:s})})]})]})})})}let Kc="";function C1(){const[t,e]=P.useState(Kc),n=de();return P.useEffect(()=>{n.ca&&n.api.getPublisherRequest(n.ca).then(r=>{e(r),Kc=r})},[]),t}function j1(){const t=C1(),e=cn(),{route:{params:n}}=je(),r=Z(),{notification:s,setNotification:i,request:a,setRequest:o,response:u,setResponse:c,handleUpload:f}=Om(t);return{notification:s,setNotification:i,request:a,setRequest:o,response:u,setResponse:c,onSubmit:async y=>{y.preventDefault(),r({response:u})},onClose:()=>{e.navigate("cas.repository",{ca:n.ca})},handleUpload:f}}function _1(){const t=A(),{notification:e,setNotification:n,request:r,setRequest:s,response:i,setResponse:a,onSubmit:o,onClose:u,handleUpload:c}=j1();return l.jsxs(xr,{onClose:u,children:[e&&l.jsx(Ss,{notification:e,onClose:()=>n(null)}),l.jsx("h3",{children:t.caDetails.repoTab.addRepo}),l.jsxs("form",{onSubmit:o,method:"POST",children:[l.jsxs("div",{children:[l.jsx("label",{children:t.caDetails.repoTab.request}),l.jsx("textarea",{name:"request",readOnly:!0,value:r,id:"request",onChange:f=>s(f.target.value)}),l.jsx("div",{children:l.jsx(ca,{xml:r,name:"publisher_request",setNotification:n})})]}),l.jsxs("div",{children:[l.jsx("label",{children:t.caDetails.repoTab.response}),l.jsx("textarea",{name:"response",value:i,onChange:f=>a(f.target.value)}),l.jsx("input",{type:"file",id:"upload",onChange:c}),l.jsx("label",{className:"button large icon",htmlFor:"upload",title:t.common.dropOrClick,children:l.jsx("img",{src:_m,alt:t.common.dropOrClick})})]}),l.jsxs("div",{className:"actions",children:[l.jsx("button",{type:"button",className:"button outline",onClick:u,children:t.common.cancel}),l.jsx("button",{type:"submit",className:"button",children:t.common.confirm})]})]})]})}function O1(){var u;const t=A(),e=de(),n=Z(),{route:r}=je(),[s,i]=P.useState(!1),a=()=>{i(!0),e.refreshRepo().then(()=>{i(!1)})};if(!e.ca)return null;const o=e.repoStatus&&e.ca&&((u=e.repoStatus[e.ca])==null?void 0:u.last_exchange);return l.jsxs(dn,{children:[r.name==="cas.repository.add"&&l.jsx(_1,{}),s&&l.jsx(Ss,{notification:{type:U.success,message:t.caDetails.refresh.replace("{handle}",t.caDetails.repo.toLowerCase())},onClose:()=>i(!1)}),l.jsx(ua,{}),o?l.jsx(N1,{repo:e.repoStatus[e.ca],locale:e.locale,loading:s}):l.jsx("button",{className:"button",onClick:()=>n({},"cas.repository.add"),children:t.caDetails.repoTab.addRepo}),l.jsx("button",{className:"button inverted",onClick:a,children:t.caDetails.syncRepo})]})}function Pm(){const t=A();return l.jsxs(dn,{children:[l.jsx("h1",{children:t.common.error}),l.jsx("pre",{children:window.location.pathname})]})}function P1(){const[t,e]=P.useState(""),[n,r]=P.useState(""),s=Z(),i=de(),a=A(),o=i.loginMethod;if(!o)return l.jsx(ou,{initial:!0});const u=async c=>{c.preventDefault(),o.with_id?s({password:n,username:t}):s({password:n})};return l.jsx(dn,{children:l.jsxs("form",{onSubmit:u,method:"POST",className:`login card ${o.with_id?"vertical-form":""}`,children:[o.with_id&&l.jsxs("div",{children:[l.jsx("label",{htmlFor:"admin required",children:a.login.id}),l.jsx("input",{name:"token",type:"username",value:t,onChange:c=>e(c.target.value),placeholder:a.login.idPlaceholder,required:!0})]}),l.jsxs("div",{children:[l.jsx("label",{htmlFor:"token required",children:a.login.password}),l.jsx("input",{name:"token",type:"password",value:n,onChange:c=>r(c.target.value),placeholder:a.login.placeholder,required:!0})]}),l.jsx("div",{children:l.jsx("button",{type:"submit",className:"button",children:a.login.signin})})]})})}function fr({notification:t}){const e=Z();return l.jsxs("div",{className:`notification ${t.type}`,children:[l.jsx("button",{className:"close",onClick:()=>e({notification:"clear"}),children:"×"}),l.jsx("span",{children:t.message})]})}function da({onClose:t,onConfirm:e}){const n=A(),{route:r}=je();let s="",i="";return r.name==="testbed"?(s=n.testbed.addChild.confirmation.title,i=n.testbed.addChild.confirmation.message):r.name==="testbed.add_pub"?(s=n.testbed.addPublisher.confirmation.title,i=n.testbed.addPublisher.confirmation.message):r.name==="testbed.del_ca"?(s=n.testbed.removeChild.confirmation.title,i=n.testbed.removeChild.confirmation.message):r.name==="testbed.del_pub"&&(s=n.testbed.removePublisher.confirmation.title,i=n.testbed.removePublisher.confirmation.message),l.jsxs(xr,{onClose:t,children:[l.jsx("h3",{children:s}),l.jsx("p",{children:i}),l.jsxs("div",{className:"actions",children:[l.jsx("button",{className:"button outline",onClick:t,children:n.common.cancel}),l.jsx("button",{className:"button",onClick:e,children:n.common.ok})]})]})}function R1(){const t=A(),[e,n]=P.useState(),[r,s]=P.useState(!1),[i,a]=P.useState(""),[o,u]=P.useState(""),[c,f]=P.useState(""),[d,p]=P.useState(""),[y,w]=P.useState(""),g=async(S,E,N,j,D)=>{const R=await fetch("/testbed/children",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({handle:S,id_cert:E,resources:{asn:N,v4:j,v6:D}})});if(R.status===200){n({type:U.success,message:t.testbed.addChild.success.replace("{child_handle}",S)});const q=_0(await R.json());w(q)}else{const q=await R.json();q.label==="pub-duplicate"?await g(S+Date.now(),E,N,j,D):n({type:U.error,message:q.msg})}},k=async S=>{S.preventDefault(),v(i)&&s(!0)},m=async()=>{const S=v(i);S&&await g(S.handle,S.id_cert,o,c,d)},h=S=>{const E=Sm(S);return E?(n({type:U.error,message:t.testbed.errors.invalid_xml.replace("{err}",E)}),!1):S.getElementsByTagName("child_request").length===0?(n({type:U.error,message:t.testbed.errors.missing_xml_el.replace("{el}","child_request")}),!1):S.getElementsByTagName("child_bpki_ta").length===0?(n({type:U.error,message:t.testbed.errors.missing_xml_el.replace("{el}","child_bpki_ta")}),!1):S.getElementsByTagName("child_request")[0].attributes.child_handle?S.getElementsByTagName("child_bpki_ta")[0].childNodes.length===0?(n({type:U.error,message:t.testbed.errors.empty_xml_el.replace("{el}","child_bpki_ta")}),!1):S.getElementsByTagName("child_bpki_ta")[0].childNodes[0].nodeValue.trim().length===0?(n({type:U.error,message:t.testbed.errors.empty_xml_el.replace("{el}","child_bpki_ta")}),!1):!0:(n({type:U.error,message:t.testbed.errors.missing_xml_attr.replace("{attr}","child_handle").replace("{el}","child_request")}),!1)},v=S=>{const E=new window.DOMParser().parseFromString(S,"text/xml");if(h(E))return{handle:E.getElementsByTagName("child_request")[0].attributes.child_handle.value,id_cert:E.getElementsByTagName("child_bpki_ta")[0].childNodes[0].nodeValue.trim()}},x=()=>{w(""),s(!1),a(t.testbed.addChild.requestXML.placeholder),u(""),f(""),p("")};return y!==""?l.jsxs("div",{className:"testbed-result",children:[e&&l.jsx(fr,{notification:e}),l.jsx("pre",{children:y}),l.jsx("p",{children:l.jsx(ca,{xml:y,name:"parent_response",setNotification:n})}),l.jsx("div",{className:"actions",children:l.jsx("button",{onClick:x,className:"button",children:t.testbed.addChild.registeranother})})]}):l.jsxs(l.Fragment,{children:[r&&l.jsx(da,{onClose:()=>s(!1),onConfirm:m}),l.jsxs("form",{onSubmit:k,method:"POST",children:[e&&l.jsx(fr,{notification:e}),l.jsxs("div",{children:[l.jsxs("label",{children:[t.testbed.addChild.requestXML.label,l.jsx("a",{href:"https://tools.ietf.org/html/rfc8183#section-5.2.1",children:t.testbed.rfcdoclink})]}),l.jsx("textarea",{name:"request",value:i,placeholder:t.testbed.addChild.requestXML.placeholder,onChange:S=>a(S.target.value),required:!0})]}),l.jsxs("div",{children:[l.jsx("label",{children:t.testbed.addChild.asnresources.label}),l.jsx("input",{name:"asn",value:o,onChange:S=>u(S.target.value),placeholder:t.testbed.addChild.asnresources.placeholder})]}),l.jsxs("div",{children:[l.jsx("label",{children:t.testbed.addChild.ipv4resources.label}),l.jsx("input",{name:"v4",value:c,onChange:S=>f(S.target.value),placeholder:t.testbed.addChild.ipv4resources.placeholder})]}),l.jsxs("div",{children:[l.jsx("label",{children:t.testbed.addChild.ipv6resources.label}),l.jsx("input",{name:"v6",value:d,onChange:S=>p(S.target.value),placeholder:t.testbed.addChild.ipv6resources.placeholder})]}),l.jsx("button",{type:"submit",className:"button",children:t.testbed.addChild.confirm})]})]})}function D1(){const t=A(),[e,n]=P.useState(),[r,s]=P.useState(!1),[i,a]=P.useState(""),[o,u]=P.useState(""),c=async(g,k)=>{const m=await fetch("/testbed/publishers",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({publisher_handle:g,id_cert:k,tag:null})});if(m.status===200)n({type:U.success,message:t.testbed.addPublisher.success.replace("{publisher_handle}",g)}),u(O0(await m.json()));else{const h=await m.json();h.label==="pub-duplicate"?await c(g+Date.now(),k):n({type:U.error,message:h.msg})}},f=g=>{const k=Sm(g);return k?(n({type:U.error,message:t.testbed.errors.invalid_xml.replace("{err}",k)}),!1):g.getElementsByTagName("publisher_request").length===0?(n({type:U.error,message:t.testbed.errors.missing_xml_el.replace("{el}","publisher_request")}),!1):g.getElementsByTagName("publisher_bpki_ta").length===0?(n({type:U.error,message:t.testbed.errors.missing_xml_el.replace("{el}","publisher_bpki_ta")}),!1):g.getElementsByTagName("publisher_request")[0].attributes.publisher_handle?g.getElementsByTagName("publisher_bpki_ta")[0].childNodes.length===0?(n({type:U.error,message:t.testbed.errors.empty_xml_el.replace("{el}","publisher_bpki_ta")}),!1):g.getElementsByTagName("publisher_bpki_ta")[0].childNodes[0].nodeValue.trim().length===0?(n({type:U.error,message:t.testbed.errors.empty_xml_el.replace("{el}","publisher_bpki_ta")}),!1):!0:(n({type:U.error,message:t.testbed.errors.missing_xml_attr.replace("{attr}","publisher_handle").replace("{el}","publisher_request")}),!1)},d=g=>{const k=new window.DOMParser().parseFromString(g,"text/xml");if(f(k))return{publisher_handle:k.getElementsByTagName("publisher_request")[0].attributes.publisher_handle.value,id_cert:k.getElementsByTagName("publisher_bpki_ta")[0].childNodes[0].nodeValue.trim()}},p=async g=>{g.preventDefault(),d(i)&&s(!0)},y=async()=>{const g=d(i);g&&await c(g.publisher_handle,g.id_cert)},w=()=>{a(t.testbed.addPublisher.requestXML.placeholder),u(""),s(!1)};return o!==""?l.jsxs("div",{className:"testbed-result",children:[e&&l.jsx(fr,{notification:e}),l.jsx("pre",{children:o}),l.jsx("p",{children:l.jsx(ca,{xml:o,name:"publisher_response",setNotification:n})}),l.jsx("div",{className:"actions",children:l.jsx("button",{onClick:w,className:"button",children:t.testbed.addPublisher.registeranother})})]}):l.jsxs(l.Fragment,{children:[r&&l.jsx(da,{onClose:()=>s(!1),onConfirm:y}),l.jsxs("form",{onSubmit:p,method:"POST",children:[e&&l.jsx(fr,{notification:e}),l.jsxs("div",{children:[l.jsxs("label",{children:[t.testbed.addPublisher.requestXML.label,l.jsx("a",{href:"https://tools.ietf.org/html/rfc8183#section-5.2.3",children:t.testbed.rfcdoclink})]}),l.jsx("textarea",{name:"request",value:i,placeholder:t.testbed.addPublisher.requestXML.placeholder,onChange:g=>a(g.target.value),required:!0})]}),l.jsx("button",{type:"submit",className:"button",children:t.testbed.addPublisher.confirm})]})]})}function I1(){const t=A(),[e,n]=P.useState(),[r,s]=P.useState(!1),[i,a]=P.useState(""),o=async()=>{const f=await fetch(`/testbed/children/${i}`,{method:"DELETE"});if(f.status===200)n({type:U.success,message:t.testbed.removeChild.success.replace("{child_handle}",i)}),a("");else{const d=await f.json();n({type:U.error,message:d.msg})}},u=f=>{f.preventDefault(),s(!0)},c=async()=>{await o(),s(!1)};return l.jsxs(l.Fragment,{children:[r&&l.jsx(da,{onClose:()=>s(!1),onConfirm:c}),l.jsxs("form",{onSubmit:u,method:"POST",children:[e&&l.jsx(fr,{notification:e}),l.jsxs("div",{children:[l.jsx("label",{children:t.testbed.childhandle}),l.jsx("input",{name:"handle",value:i,onChange:f=>a(f.target.value),placeholder:t.testbed.removeChild.placeholder,required:!0})]}),l.jsx("button",{type:"submit",className:"button",children:t.testbed.removeChild.confirm})]})]})}function M1(){const t=A(),[e,n]=P.useState(),[r,s]=P.useState(!1),[i,a]=P.useState(""),o=async()=>{const f=await fetch(`/testbed/publishers/${i}`,{method:"DELETE"});if(f.status===200)n({type:U.success,message:t.testbed.removePublisher.success.replace("{publisher_handle}",i)}),a("");else{const d=await f.json();n({type:U.error,message:d.msg})}},u=async f=>{f.preventDefault(),s(!0)},c=async()=>{await o(),s(!1)};return l.jsxs(l.Fragment,{children:[r&&l.jsx(da,{onClose:()=>s(!1),onConfirm:c}),l.jsxs("form",{onSubmit:u,method:"POST",children:[e&&l.jsx(fr,{notification:e}),l.jsxs("div",{children:[l.jsx("label",{children:t.testbed.publisherhandle}),l.jsx("input",{name:"handle",value:i,onChange:f=>a(f.target.value),placeholder:t.testbed.removePublisher.placeholder,required:!0})]}),l.jsx("button",{type:"submit",className:"button",children:t.testbed.removePublisher.confirm})]})]})}const Rm="/assets/welcome-9fadc7f2.svg";function Zs({children:t}){const e=A();return l.jsx(dn,{children:l.jsxs("div",{className:"testbed",children:[l.jsxs("div",{children:[l.jsx("img",{src:Rm,className:"hero",alt:e.common.copy}),l.jsx("h2",{children:e.testbed.welcome})]}),l.jsxs("div",{children:[l.jsx("h3",{children:e.testbed.disclaimer.heading}),l.jsx("p",{dangerouslySetInnerHTML:{__html:e.testbed.disclaimer.body}}),l.jsx("h3",{children:e.testbed.rpconfighelp.heading}),l.jsx("p",{dangerouslySetInnerHTML:{__html:e.testbed.rpconfighelp.body.replace("{tallink}","/ta/ta.tal")}}),l.jsx("h3",{children:e.testbed.regunreg.heading}),l.jsx("p",{dangerouslySetInnerHTML:{__html:e.testbed.regunreg.body}})]}),l.jsx("div",{children:l.jsxs("ul",{className:"tabs",children:[l.jsx("li",{children:l.jsx(Qt,{routeName:"testbed",activeStrict:!0,children:e.testbed.addChild.heading})}),l.jsx("li",{children:l.jsx(Qt,{routeName:"testbed.del_ca",children:e.testbed.removeChild.heading})}),l.jsx("li",{children:l.jsx(Qt,{routeName:"testbed.add_pub",children:e.testbed.addPublisher.heading})}),l.jsx("li",{children:l.jsx(Qt,{routeName:"testbed.del_pub",children:e.testbed.removePublisher.heading})})]})}),t]})})}function L1(){const{route:t}=je();return de().testBedEnabled?t.name=="testbed.del_ca"?l.jsx(Zs,{children:l.jsx(I1,{})}):t.name=="testbed.add_pub"?l.jsx(Zs,{children:l.jsx(D1,{})}):t.name=="testbed.del_pub"?l.jsx(Zs,{children:l.jsx(M1,{})}):l.jsx(Zs,{children:l.jsx(R1,{})}):l.jsx(Pm,{})}function A1(){const t=Z(),[e,n]=P.useState(""),r=A(),s=i=>{i.preventDefault(),t({name:e})};return l.jsx(dn,{children:l.jsxs("form",{method:"POST",onSubmit:s,className:"center-form",children:[l.jsxs("div",{children:[l.jsx("img",{src:Rm,alt:r.common.copy}),l.jsx("h2",{children:r.onboarding.welcome}),l.jsx("div",{dangerouslySetInnerHTML:{__html:r.onboarding.welcomeHtml}})]}),l.jsxs("div",{children:[l.jsxs("label",{htmlFor:"token required",children:["CA ",r.caDetails.handle]}),l.jsx("input",{name:"name",type:"test",value:e,onChange:i=>n(i.target.value),required:!0})]}),l.jsx("div",{children:l.jsx("button",{type:"submit",className:"button",children:r.onboarding.addCAForm.confirm})})]})})}function F1(){const{route:t}=je();return!t||t.name==="loading"?l.jsx(ou,{initial:!0}):t.name==="login"?l.jsx(P1,{}):t.name==="onboarding"?l.jsx(A1,{}):t.name.startsWith("cas.parents")?l.jsx(E1,{}):t.name.startsWith("cas.repository")?l.jsx(O1,{}):t.name.startsWith("cas.aspas")?l.jsx(g1,{}):t.name.startsWith("cas")?l.jsx(o1,{}):t.name.startsWith("testbed")?l.jsx(L1,{}):l.jsx(Pm,{})}/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. - -Permission to use, copy, modify, and/or distribute this software for any -purpose with or without fee is hereby granted. - -THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH -REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, -INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM -LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -PERFORMANCE OF THIS SOFTWARE. -***************************************************************************** */var Qe=function(){return Qe=Object.assign||function(e){for(var n,r=1,s=arguments.length;r$)/g,""):"[a-zA-Z0-9-_.~%':|=+\\*@$]+")+")"},K1=[{name:"url-parameter",pattern:/^:([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(<(.+?)>)?/,regex:function(e){return new RegExp(tl(e[2]))}},{name:"url-parameter-splat",pattern:/^\*([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})/,regex:/([^?]*)/},{name:"url-parameter-matrix",pattern:/^;([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(<(.+?)>)?/,regex:function(e){return new RegExp(";"+e[1]+"="+tl(e[2]))}},{name:"query-parameter",pattern:/^(?:\?|&)(?::)?([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})/},{name:"delimiter",pattern:/^(\/|\?)/,regex:function(e){return new RegExp("\\"+e[0])}},{name:"sub-delimiter",pattern:/^(!|&|-|_|\.|;)/,regex:function(e){return new RegExp(e[0])}},{name:"fragment",pattern:/^([0-9a-zA-Z]+)/,regex:function(e){return new RegExp(e[0])}}],G1=function t(e,n){n===void 0&&(n=[]);var r=K1.some(function(s){var i=e.match(s.pattern);return i?(n.push({type:s.name,match:i[0],val:i.slice(1,2),otherVal:i.slice(2),regex:s.regex instanceof Function?s.regex(i):s.regex}),i[0].length0,this.hasSpatParam=this.tokens.filter(function(r){return/splat$/.test(r.type)}).length>0,this.hasMatrixParams=this.tokens.filter(function(r){return/matrix$/.test(r.type)}).length>0,this.hasQueryParams=this.tokens.filter(function(r){return/^query-parameter/.test(r.type)}).length>0,this.spatParams=this.getParams("url-parameter-splat"),this.urlParams=this.getParams(/^url-parameter/),this.queryParams=this.getParams("query-parameter"),this.params=this.urlParams.concat(this.queryParams),this.source=this.tokens.filter(function(r){return r.regex!==void 0}).map(function(r){return r.regex.source}).join("")}return t.createPath=function(e,n){return new t(e,n)},t.prototype.isQueryParam=function(e){return this.queryParams.indexOf(e)!==-1},t.prototype.isSpatParam=function(e){return this.spatParams.indexOf(e)!==-1},t.prototype.test=function(e,n){var r=this,s=Qe(Qe({caseSensitive:!1,strictTrailingSlash:!1},this.options),n),i=J1(this.source,s.strictTrailingSlash),a=this.urlTest(e,i+(this.hasQueryParams?"(\\?.*$|$)":"$"),s.caseSensitive,s.urlParamsEncoding);if(!a||!this.hasQueryParams)return a;var o=Ui(e,s.queryParams),u=Object.keys(o).filter(function(c){return!r.isQueryParam(c)});return u.length===0?(Object.keys(o).forEach(function(c){return a[c]=o[c]}),a):null},t.prototype.partialTest=function(e,n){var r=this,s=Qe(Qe({caseSensitive:!1,delimited:!0},this.options),n),i=X1(this.source,s.delimited),a=this.urlTest(e,i,s.caseSensitive,s.urlParamsEncoding);if(!a||!this.hasQueryParams)return a;var o=Ui(e,s.queryParams);return Object.keys(o).filter(function(u){return r.isQueryParam(u)}).forEach(function(u){return ew(a,u,o[u])}),a},t.prototype.build=function(e,n){var r=this;e===void 0&&(e={});var s=Qe(Qe({ignoreConstraints:!1,ignoreSearch:!1,queryParams:{}},this.options),n),i=Object.keys(e).filter(function(d){return!r.isQueryParam(d)}).reduce(function(d,p){if(!Ka(e[p]))return d;var y=e[p],w=r.isSpatParam(p);return typeof y=="boolean"?d[p]=y:Array.isArray(y)?d[p]=y.map(function(g){return Gc(g,s.urlParamsEncoding,w)}):d[p]=Gc(y,s.urlParamsEncoding,w),d},{});if(this.urlParams.some(function(d){return!Ka(e[d])})){var a=this.urlParams.filter(function(d){return!Ka(e[d])});throw new Error("Cannot build path: '"+this.path+"' requires missing parameters { "+a.join(", ")+" }")}if(!s.ignoreConstraints){var o=this.tokens.filter(function(d){return/^url-parameter/.test(d.type)&&!/-splat$/.test(d.type)}).every(function(d){return new RegExp("^"+tl(d.otherVal[0])+"$").test(i[d.val])});if(!o)throw new Error("Some parameters of '"+this.path+"' are of invalid format")}var u=this.tokens.filter(function(d){return/^query-parameter/.test(d.type)===!1}).map(function(d){return d.type==="url-parameter-matrix"?";"+d.val+"="+i[d.val[0]]:/^url-parameter/.test(d.type)?i[d.val[0]]:d.match}).join("");if(s.ignoreSearch)return u;var c=this.queryParams.filter(function(d){return Object.keys(e).indexOf(d)!==-1}).reduce(function(d,p){return d[p]=e[p],d},{}),f=Lm(c,s.queryParams);return f?u+"?"+f:u},t.prototype.getParams=function(e){var n=e instanceof RegExp?function(r){return e.test(r.type)}:function(r){return r.type===e};return this.tokens.filter(n).map(function(r){return r.val[0]})},t.prototype.urlTest=function(e,n,r,s){var i=this,a=new RegExp("^"+n,r?"":"i"),o=e.match(a);if(o){if(!this.urlParams.length)return{}}else return null;return o.slice(1,this.urlParams.length+1).reduce(function(u,c,f){return u[i.urlParams[f]]=Y1(c,s),u},{})},t}(),Fm=function(e){var n="";return e.reduce(function(r,s){var i,a,o,u,c=(a=(i=s.parser)===null||i===void 0?void 0:i.urlParams.reduce(function(d,p){return d[p]="url",d},{}),a??{}),f=(u=(o=s.parser)===null||o===void 0?void 0:o.queryParams.reduce(function(d,p){return d[p]="query",d},c),u??{});return s.name!==void 0&&(n=n?n+"."+s.name:s.name,r[n]=f),r},{})},nw=function(e){if(!e||!e.segments||!e.segments.length)return null;var n=e.segments.map(function(s){return s.name}).filter(function(s){return s}).join("."),r=e.params;return{name:n,params:r,meta:Fm(e.segments)}},rw=function(e,n,r){n===void 0&&(n={}),r===void 0&&(r={});for(var s=r.queryParamsMode,i=s===void 0?"default":s,a=r.trailingSlashMode,o=a===void 0?"default":a,u=[],c=[],f=0,d=e;f/g,"").split("?")[0].replace(/(.+)\/$/,"$1"),d=r.path.replace(/<.*?>/g,"").split("?")[0].replace(/(.+)\/$/,"$1");if(f==="/")return 1;if(d==="/")return-1;if(!((s=n.parser)===null||s===void 0)&&s.hasSpatParam)return 1;if(!((i=r.parser)===null||i===void 0)&&i.hasSpatParam)return-1;var p=(f.match(/\//g)||[]).length,y=(d.match(/\//g)||[]).length;if(py)return-1;var w=(o=(a=n.parser)===null||a===void 0?void 0:a.urlParams.length,o??0),g=(c=(u=r.parser)===null||u===void 0?void 0:u.urlParams.length,c??0);if(wg)return 1;var k=(f.split("/").slice(-1)[0]||"").length,m=(d.split("/").slice(-1)[0]||"").length;return km?-1:e.indexOf(n)-e.indexOf(r)}},Xc=function(){function t(e,n,r,s){return e===void 0&&(e=""),n===void 0&&(n=""),r===void 0&&(r=[]),s===void 0&&(s={}),this.name=e,this.absolute=/^~/.test(n),this.path=this.absolute?n.slice(1):n,this.parser=this.path?new Jc(this.path):null,this.children=[],this.parent=s.parent,this.checkParents(),this.add(r,s.onAdd,s.finalSort?!1:s.sort!==!1),s.finalSort&&this.sortDescendants(),this}return t.prototype.getParentSegments=function(e){return e===void 0&&(e=[]),this.parent&&this.parent.parser?this.parent.getParentSegments(e.concat(this.parent)):e.reverse()},t.prototype.setParent=function(e){this.parent=e,this.checkParents()},t.prototype.setPath=function(e){e===void 0&&(e=""),this.path=e,this.parser=e?new Jc(e):null},t.prototype.add=function(e,n,r){var s=this;if(r===void 0&&(r=!0),e==null)return this;if(e instanceof Array)return e.forEach(function(o){return s.add(o,n,r)}),this;if(!(e instanceof t)&&!(e instanceof Object))throw new Error("RouteNode.add() expects routes to be an Object or an instance of RouteNode.");if(e instanceof t)e.setParent(this),this.addRouteNode(e,r);else{if(!e.name||!e.path)throw new Error("RouteNode.add() expects routes to have a name and a path defined.");var i=new t(e.name,e.path,e.children,{finalSort:!1,onAdd:n,parent:this,sort:r}),a=i.getParentSegments([i]).map(function(o){return o.name}).join(".");n&&n(Qe(Qe({},e),{name:a})),this.addRouteNode(i,r)}return this},t.prototype.addNode=function(e,n){return this.add(new t(e,n)),this},t.prototype.getPath=function(e){var n=this.getSegmentsByName(e);return n?sw(n):null},t.prototype.getNonAbsoluteChildren=function(){return this.children.filter(function(e){return!e.absolute})},t.prototype.sortChildren=function(){this.children.length&&lw(this.children)},t.prototype.sortDescendants=function(){this.sortChildren(),this.children.forEach(function(e){return e.sortDescendants()})},t.prototype.buildPath=function(e,n,r){n===void 0&&(n={}),r===void 0&&(r={});var s=this.getSegmentsByName(e);if(!s)throw new Error("[route-node][buildPath] '{routeName}' is not defined");return rw(s,n,r)},t.prototype.buildState=function(e,n){n===void 0&&(n={});var r=this.getSegmentsByName(e);return!r||!r.length?null:{name:e,params:n,meta:Fm(r)}},t.prototype.matchPath=function(e,n){n===void 0&&(n={}),e===""&&!n.strictTrailingSlash&&(e="/");var r=this.getSegmentsMatchingPath(e,n);if(!r)return null;var s=r.segments;if(s[0].absolute){var i=s[0].getParentSegments();s.reverse(),s.push.apply(s,i),s.reverse()}var a=s[s.length-1],o=a.findSlashChild();return o&&s.push(o),nw(r)},t.prototype.addRouteNode=function(e,n){n===void 0&&(n=!0);var r=e.name.split(".");if(r.length===1){if(this.children.map(function(i){return i.name}).indexOf(e.name)!==-1)throw new Error('Alias "'+e.name+'" is already defined in route node');if(this.children.map(function(i){return i.path}).indexOf(e.path)!==-1)throw new Error('Path "'+e.path+'" is already defined in route node');this.children.push(e),n&&this.sortChildren()}else{var s=this.getSegmentsByName(r.slice(0,-1).join("."));if(s)e.name=r[r.length-1],s[s.length-1].add(e);else throw new Error("Could not add route named '"+e.name+"', parent is missing.")}return this},t.prototype.checkParents=function(){if(this.absolute&&this.hasParentsParams())throw new Error("[RouteNode] A RouteNode with an abolute path cannot have parents with route parameters")},t.prototype.hasParentsParams=function(){if(this.parent&&this.parent.parser){var e=this.parent.parser,n=e.hasUrlParams||e.hasSpatParam||e.hasMatrixParams||e.hasQueryParams;return n||this.parent.hasParentsParams()}return!1},t.prototype.findAbsoluteChildren=function(){return this.children.reduce(function(e,n){return e.concat(n.absolute?n:[]).concat(n.findAbsoluteChildren())},[])},t.prototype.findSlashChild=function(){var e=this.getNonAbsoluteChildren().filter(function(n){return n.parser&&/^\/(\?|$)/.test(n.parser.path)});return e[0]},t.prototype.getSegmentsByName=function(e){var n=function(u,c){var f=c.filter(function(d){return d.name===u});return f.length?f[0]:void 0},r=[],s=this.parser?[this]:this.children,i=(this.parser?[""]:[]).concat(e.split(".")),a=i.every(function(o){var u=n(o,s);return u?(s=u.children,r.push(u),!0):!1});return a?r:null},t.prototype.getSegmentsMatchingPath=function(e,n){var r=this.parser?[this]:this.children,s=r.reduce(function(o,u){return o.concat(u,u.findAbsoluteChildren())},[]),i={segments:[],params:{}},a=ow(s,e,i,n);return a&&a.segments.length===1&&a.segments[0].name===""?null:a},t}();function cw(t){var e,n=t.Symbol;return typeof n=="function"?n.observable?e=n.observable:(e=n("observable"),n.observable=e):e="@@observable",e}var An;typeof self<"u"?An=self:typeof window<"u"?An=window:typeof global<"u"?An=global:typeof rl<"u"?An=rl:An=Function("return this")();var ed=cw(An);/*! ***************************************************************************** -Copyright (c) Microsoft Corporation. All rights reserved. -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 - -THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY -KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED -WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, -MERCHANTABLITY OR NON-INFRINGEMENT. - -See the Apache Version 2.0 License for specific language governing permissions -and limitations under the License. -***************************************************************************** */var z=function(){return z=Object.assign||function(e){for(var n,r=1,s=arguments.length;ri.includes(c.id||"")),o=a.filter(c=>c.action==="add"),u=a.filter(c=>c.action==="remove");return await e.changeRoutes(o,u),Promise.reject({redirect:{name:"cas",params:{ca:e.ca}}})}if((t.name==="cas.aspas.add"||t.name==="cas.aspas.add_new"||t.name==="cas.aspas.edit")&&t.params.customer)return await e.addAspa(t.params)?Promise.reject({redirect:{name:"cas.aspas",params:{ca:e.ca}}}):Promise.reject({redirect:{name:t.name,params:{ca:e.ca,id:t.params.id}}});if(t.name==="cas.aspas.delete"&&t.params.customer&&await e.deleteAspa(t.params))return Promise.reject({redirect:{name:"cas.aspas",params:{ca:e.ca}}});if(t.name==="cas.parents.add"&&t.params.name&&await e.addParent(t.params))return Promise.reject({redirect:{name:"cas.parents",params:{ca:e.ca}}});if(t.name==="cas.repository.add"&&t.params.response&&await e.addRepository(t.params))return Promise.reject({redirect:{name:"cas.repository",params:{ca:e.ca}}});if(await e.loadCas(),((n=e.cas)==null?void 0:n.length)===0&&t.name!=="onboarding")return Promise.reject({redirect:{name:"onboarding"}});if(t.name==="onboarding"&&t.params.name&&await e.addCa(t.params.name))return Promise.reject({redirect:{name:"cas.repository",params:{ca:e.ca}}});if(e.ca&&((r=e.cas)!=null&&r.length)&&!((s=e.cas)!=null&&s.includes(e.ca)))return Promise.reject({redirect:{name:"cas",params:{ca:e.cas[0]}}});if(t.name==="home"&&e.ca)return Promise.reject({redirect:{name:"cas",params:{ca:e.ca}}});t.name.startsWith("cas")&&await Promise.all([e.loadCa(),e.loadParents(),e.loadRepoStatus()])}}async function Hw(t,e){t.params.locale&&(await e.setLocale(t.params.locale),delete t.params.locale)}function Ww(t){return async e=>{const n=t.getDependencies().store;try{await Hw(e,n),n.translations===null&&await n.loadTranslations(),await Uw(e,n),await Vw(e,n)}catch(r){return Promise.reject(r)}return n.storePersistedData(),e}}const Ln="/ui",qw=[{name:"home",path:Ln},{name:"onboarding",path:`${Ln}/onboarding`},{name:"cas",path:`${Ln}/cas/:ca`,children:[{name:"add_new",path:"/add"},{name:"add",path:"/add/:id"},{name:"delete",path:"/delete/:id"},{name:"edit",path:"/edit/:id"},{name:"change",path:"/change"},{name:"aspas",path:"/aspas",children:[{name:"add_new",path:"/add"},{name:"add",path:"/add/:id"},{name:"edit",path:"/edit/:id"},{name:"delete",path:"/delete/:id"}]},{name:"parents",path:"/parents",children:[{name:"add",path:"/add"}]},{name:"repository",path:"/repos",children:[{name:"add",path:"/add"}]},{name:"analyse",path:"/analyse"}]},{name:"testbed",path:`${Ln}/testbed`,children:[{name:"del_ca",path:"/remove"},{name:"add_pub",path:"/register-publisher"},{name:"del_pub",path:"/remove-publisher"}]},{name:"login",path:`${Ln}/login`},{name:"logout",path:`${Ln}/logout`}];function Bw(t){const e=Cw(qw,{allowNotFound:!0,queryParamsMode:"loose"});return e.setDependencies({store:t}),e.usePlugin(bw()),e.useMiddleware(Ww),e}class Zw{constructor(){oe(this,"notification",null);oe(this,"cas",null);oe(this,"ca",null);oe(this,"locale",kg);oe(this,"token",null);oe(this,"translations",null);oe(this,"caDetails",{});oe(this,"roas",{});oe(this,"aspas",{});oe(this,"suggestions",{});oe(this,"repoStatus",{});oe(this,"parents",{});oe(this,"userDetails",null);oe(this,"loginMethod",null);oe(this,"testBedEnabled",!1);oe(this,"api");this.api=new km,this.loadPersistedState()}getAspas(e){let n=this.aspas&&this.ca&&this.aspas[this.ca]||[];if(e){if(e.search){const s=e.search.toLowerCase().split(/\s/);n=n.filter(i=>s.some(a=>i.customer.toString().includes(a))||s.some(a=>i.providers.toString().includes(a)))}n=n.slice().sort((s,i)=>E0(s,i,e.sort,e.order));const r=(e.page-1)*e.limit;n=n.slice(r,r+e.limit)}return n}getRoas(e){let n=this.roas&&this.ca&&this.roas[this.ca]||[];if(n=n.filter(r=>!r.allowed_by),e){if(e.search){const s=e.search.toLowerCase().split(/\s/);n=n.filter(i=>s.some(a=>i.asn.toString().includes(a))||s.some(a=>i.prefix.includes(a))||s.some(a=>{var o;return i.state&&(i.state.includes(a)||((o=this.translations)==null?void 0:o.announcements.state[i.state].toLowerCase().includes(a)))}))}n=n.slice().sort((s,i)=>T0(s,i,e.sort,e.order));const r=(e.page-1)*e.limit;n=n.slice(r,r+e.limit)}return n}getSuggestions(e){let n=this.suggestions&&this.ca&&this.suggestions[this.ca]||[];return e&&(n=n.slice().sort((r,s)=>N0(r,s,e.sort,e.order))),n}async handleError(e){try{return await e()}catch(n){const r=n;return(r.status===401||r.status===403)&&this.setToken(null),this.setNotification({type:U.error,message:r.msg||"Error"}),!1}}loadPersistedState(){const e=window.localStorage.getItem("krill");if(this.setToken(window.sessionStorage.getItem("krillToken")),e!==null)try{const n=JSON.parse(e);this.ca=n.ca,this.locale=n.locale,this.userDetails=n.userDetails}catch(n){console.error(n)}}storePersistedData(){this.token?window.sessionStorage.setItem("krillToken",this.token):window.sessionStorage.removeItem("krillToken"),window.localStorage.setItem("krill",JSON.stringify({ca:this.ca,locale:this.locale,userDetails:this.userDetails}))}setLocale(e){return this.locale=e,this.loadTranslations()}async loadTranslations(){this.translations=await B0(this.locale)}async loadLoginMethod(){return this.loginMethod||await this.handleError(async()=>{this.loginMethod=await this.api.getLoginMethod()}),this.loginMethod}async loadTestBedEnabled(){return this.testBedEnabled||await this.handleError(async()=>{this.testBedEnabled=await this.api.getTestBedEnabled()}),this.testBedEnabled}async tryLogin(e,n){var r;try{const s=await this.api.postLogin(e,n);this.setNotification(null),this.setToken(s.token),this.setUserDetails({id:s.id,attributes:s.attributes})}catch{this.setUserDetails(null),this.setNotification({type:U.error,message:(r=this.translations)==null?void 0:r.login.error})}}async checkToken(){var e;if(this.token)try{this.setNotification(null),await this.api.checkToken(this.token)}catch{this.setToken(null),this.setUserDetails(null),this.storePersistedData(),this.setNotification({type:U.error,message:(e=this.translations)==null?void 0:e.login.error})}}async loadCas(e=!1){(this.cas!==null||!this.token)&&!e||await this.handleError(async()=>{this.cas=await this.api.getCas(),!this.ca&&this.cas.length>0&&(this.ca=this.cas[0])})}async addCa(e){return await this.handleError(async()=>(await this.api.postCas(e),await this.loadCas(!0),await this.loadCa(!0),!0))}async loadCa(e){!this.ca||this.ca&&this.caDetails[this.ca]&&this.roas[this.ca]&&e!==!0||await this.handleError(async()=>{if(this.ca!==null){const[n,r,s]=await Promise.all([this.api.getCaDetails(this.ca),this.api.getCaRoas(this.ca),this.api.getCaAspas(this.ca)]);this.caDetails[this.ca]=n,this.roas[this.ca]=r,this.aspas[this.ca]=s}})}async loadSuggestions(e){!this.ca||this.ca&&this.suggestions[this.ca]&&e!==!0||await this.handleError(async()=>{this.ca!==null&&(this.suggestions[this.ca]=await this.api.getCaSuggestions(this.ca))})}async refreshParents(){if(!this.ca)return;const e=this.ca;return await this.api.refreshCaParents(),new Promise(n=>{const r=setInterval(()=>{this.api.getCaParents(e).then(s=>{JSON.stringify(s)!==JSON.stringify(this.parents[e])&&(this.parents[e]=s,clearInterval(r),n(s))})},5e3)})}async loadParents(e){!this.ca||this.ca&&this.parents[this.ca]&&e!==!0||await this.handleError(async()=>{this.ca!==null&&(this.parents[this.ca]=await this.api.getCaParents(this.ca))})}async loadRepoStatus(e){!this.ca||this.ca&&this.repoStatus[this.ca]&&e!==!0||await this.handleError(async()=>{this.ca!==null&&(this.repoStatus[this.ca]=await this.api.getCaRepoStatus(this.ca))})}async refreshRepo(){if(!this.ca)return;const e=this.ca;return await this.api.refreshCaRepo(),new Promise(n=>{const r=setInterval(()=>{this.api.getCaRepoStatus(e).then(s=>{JSON.stringify(s)!==JSON.stringify(this.repoStatus[e])&&(this.repoStatus[e]=s,clearInterval(r),n(s))})},5e3)})}async changeRoutes(e,n){return this.ca===null?!1:await this.handleError(async()=>{var r;return await this.api.updateRoutes(this.ca,{added:e,removed:n}),await this.loadCa(!0),await this.loadSuggestions(!0),this.setNotification({type:U.success,message:(r=this.translations)==null?void 0:r.common.success}),!0})}async editRoute(e,n){if(this.ca===null||!this.roas[this.ca])return!1;const r=this.roas[this.ca].find(i=>i.id===e);if(!r)return!1;const s={...r,comment:n};return await this.handleError(async()=>{var i;return await this.api.updateRoutes(this.ca,{added:[s],removed:[]}),await this.loadCa(!0),this.setNotification({type:U.success,message:(i=this.translations)==null?void 0:i.caDetails.confirmation.commentUpdatedSuccess}),!0})}async addRoute(e){if(this.ca===null)return!1;const n={asn:parseInt(e.asn,10),prefix:e.prefix,comment:e.comment,max_length:parseInt(e.max_length,10)};return await this.handleError(async()=>{var r;return await this.api.updateRoutes(this.ca,{added:[n],removed:[]}),await this.loadCa(!0),this.setNotification({type:U.success,message:(r=this.translations)==null?void 0:r.caDetails.confirmation.addedSuccess}),!0})}async deleteRoute(e){if(this.ca===null)return!1;const n={asn:parseInt(e.asn,10),prefix:e.prefix,max_length:parseInt(e.max_length,10)};return await this.handleError(async()=>{var r;return await this.api.updateRoutes(this.ca,{added:[],removed:[n]}),await this.loadCa(!0),this.setNotification({type:U.success,message:(r=this.translations)==null?void 0:r.caDetails.confirmation.retiredSuccess}),!0})}async addAspa(e){if(this.ca===null)return!1;const n={customer:Number(e.customer),providers:e.providers.split(",").map(r=>Number(r))};return await this.handleError(async()=>{var r;return await this.api.updateAspas(this.ca,{add_or_replace:[n],remove:[]}),await this.loadCa(!0),this.setNotification({type:U.success,message:(r=this.translations)==null?void 0:r.aspas.confirmation.addedSuccess}),!0})}async deleteAspa(e){return this.ca===null?!1:await this.handleError(async()=>{var n;return await this.api.updateAspas(this.ca,{add_or_replace:[],remove:[Number(e.customer)]}),await this.loadCa(!0),this.setNotification({type:U.success,message:(n=this.translations)==null?void 0:n.aspas.confirmation.retiredSuccess}),!0})}async addParent(e){if(this.ca!==null)return await this.handleError(async()=>(await this.api.postParent(this.ca,e.name,e.response||""),await this.loadParents(!0),!0))}async addRepository(e){if(this.ca!==null)return await this.handleError(async()=>(await this.api.postRepository(this.ca,e.name,e.response||""),await this.loadRepoStatus(!0),!0))}setNotification(e){this.notification=e}setUserDetails(e){this.userDetails=e}setCa(e){this.ca=e}setToken(e){this.token=e,this.api.setToken(e)}}const Qw=new Zw,zm=Bw(Qw),Yw=gh(document.getElementById("root"));Yw.render(l.jsx(yg,{router:zm,children:l.jsx(F1,{})}));zm.start()});export default Kw(); diff --git a/ui/assets/index-35ed2154.css b/ui/assets/index-35ed2154.css new file mode 100644 index 00000000..b50fa546 --- /dev/null +++ b/ui/assets/index-35ed2154.css @@ -0,0 +1 @@ +:root{--red: #f63107;--red-light: #fef0f0;--light: #fafafa;--light-bg: #f5f7fa;--grey-lighter: #ebeef5;--grey-light: #dcdfe6;--grey: #c0c4cc;--grey-dark: #999;--dark: #606266;--shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);--shadow-red: 0 2px 12px 0 rgb(246 49 7 / 10%);--radius: .25rem;--success: #67c23a;--success-border: #e1f3d8;--success-bg: #f0f9eb;--warning: #e6a23c;--warning-border: #faecd8;--warning-bg: #fdf6ec;--error: #f56c6c;--error-border: #fbc4c4;--error-bg: #fbe7e7}@font-face{font-family:Inter;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/assets/Inter-roman.var-17fe38ab.woff2?v=3.19) format("woff2")}@font-face{font-family:Inter;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/assets/Inter-italic.var-d1401419.woff2?v=3.19) format("woff2")}.center-form{max-width:30rem;margin:2rem auto}.center-form img{display:block;margin:2rem auto;width:8rem}.center-form h2{text-align:center;font-weight:500;margin-bottom:2rem}.center-form label{margin-top:1rem;display:block}.center-form input{width:100%;margin-bottom:1rem}.center-form button{float:right}label{line-height:1.1rem;color:var(--dark);font-size:.9rem;margin-right:1rem;margin-top:.7rem;margin-bottom:.7rem}label.required:before{content:"*";color:var(--red);margin-right:.3rem}input,textarea{border:1px solid var(--grey-light);border-radius:var(--radius);line-height:2.5rem;padding:0 .75rem;transition:border .3s;font-size:.9rem;color:var(--dark)}textarea{padding:.75rem;margin-bottom:1rem;line-height:1.4}input:focus,input:active,textarea:focus,textarea:active{border-color:var(--red);outline:none}input::placeholder{color:var(--grey-light)}input[type=search]{margin:1rem 0;line-height:1.5rem;padding-left:1.75rem;background:url(/assets/search-4a30d812.svg) no-repeat center left .5rem;background-size:.8rem;font-size:.8rem;width:25rem;max-width:100%}input::placeholder{color:var(--grey);opacity:1}input[disabled]{background-color:#eee}#upload{display:none}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none}input[type=number]{-moz-appearance:textfield}.aspa-card{width:35rem;max-width:100vw;margin:1rem;display:inline-flex}.aspa-new{background-color:var(--light)}.aspa-form{margin:2rem;width:100%}.aspa-form img{display:block;width:8rem}.aspa-form h2{text-align:center;font-weight:500;margin-bottom:2rem}.aspa-form label{display:block}.aspa-form input{width:100%}.aspa-form .actions{margin-top:1rem}.aspa-list{width:100%}.aspa-table td{padding:.3rem 0}.aspa-table td:first-child{padding-right:.3rem;text-align:right}.aspa-label{color:var(--dark);background:white;border:1px solid var(--grey-dark);border-radius:var(--radius);vertical-align:middle;padding:.2rem;margin:.1rem}.button{display:inline-block;border:none;background:var(--red);border-radius:var(--radius);line-height:2.5rem;font-size:.9rem;padding:0 1rem;color:#fff;white-space:nowrap;cursor:pointer;vertical-align:text-bottom;border:1px solid transparent}a.button{text-decoration:none}.button.outline{color:var(--dark);background:white;border:1px solid var(--grey-dark)}.button.light{color:var(--dark);background:white}.button.right{float:right}.button:hover{opacity:.8}.button.icon{position:relative;line-height:1.5rem;height:1.5rem;width:3rem;border-radius:.75rem}.button.icon img{position:absolute;width:.75rem;height:.75rem;top:50%;left:50%;transform:translate(-50%,-50%)}.button img{width:.75rem;height:.75rem;top:50%;left:50%;display:inline}.button.icon.large{height:2rem}.button.icon.large img{width:1rem;height:1rem}.button+.button{margin-left:.75rem}.button.inverted{padding:0;color:var(--red);background:none}.select{position:relative;display:inline-block;width:10rem}.select.wide{width:20rem}.select button{width:100%;background:white;border:1px solid white;height:2rem;line-height:1rem;text-align:left;color:var(--dark);border:1px solid var(--grey-light);cursor:pointer;border-radius:var(--radius);outline:none;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding-right:2rem}.select button:after,button.expand:after{content:" ";position:absolute;right:.7rem;top:.7rem;display:block;width:.7rem;height:.7rem;border-bottom:1px solid var(--grey-dark);border-right:1px solid var(--grey-dark);transform:translate(-50%,-25%) rotate(45deg);transition:transform .2s}.select button:hover,.select button.open{border:1px solid var(--red)}.select button.open:after{transform:translate(-50%,25%) rotate(-135deg)}.select ul{padding:0;margin:0;position:absolute;display:block;top:2.5rem;background:white;width:100%;border:0 solid var(--light);box-shadow:var(--shadow);border-radius:var(--radius);max-height:0;overflow-x:hidden;overflow-y:auto;z-index:10}.select ul.show{padding:.5rem 0;border-width:1px;max-height:20rem}.select ul li{padding:0 1rem;line-height:2rem;font-size:.9rem;cursor:pointer}.select ul li:hover{background-color:var(--light)}.select ul li.selected{background-color:var(--light);color:var(--red);font-weight:600}html,body{height:100%}#root{height:100%;display:flex;flex-direction:column}#root .content{flex:1}header{background-color:var(--red);display:flex;height:4rem;justify-content:space-between}header h1{display:block;width:10rem;background:url(/assets/krill_logo_white-05224433.svg) no-repeat}header h1 span{display:none}header menu{display:flex;padding:0 1rem}header menu>button{border:none;background:none;margin-left:1rem;width:2rem;height:2rem;cursor:pointer}header menu>button img{width:1rem;height:1rem}header menu>button:hover img{opacity:.8}.content{padding:2rem}footer{background-color:var(--light);color:var(--grey-dark);height:2.5rem;line-height:1.5rem;font-size:.8rem;padding:.5rem 1rem;display:flex;justify-content:space-between}footer a{font-weight:600;text-decoration:none;color:var(--grey-dark)}.user-attribute{text-transform:capitalize}.content.route-login{position:relative;overflow:hidden}.content.route-login:before{content:" ";position:absolute;left:0;bottom:0;width:550px;height:260px;background:url(/assets/route-left-c88b44cb.svg) no-repeat top left -30px;z-index:-1}.content.route-login:after{content:" ";position:absolute;right:0;top:0;width:360px;height:100%;background:url(/assets/route-right-17b0c46a.svg) no-repeat top -30px left;z-index:-1}.login{position:relative;width:35rem;max-width:100%;margin:4rem auto;padding:3rem;display:flex;justify-content:center;background:white}.login>*{margin:0 .5rem}.login.vertical-form{flex-direction:column;padding:2rem}.login.vertical-form label,.login.vertical-form input{display:block;width:100%}.login.vertical-form>div+div{margin-top:1rem}.login.vertical-form .button{display:block;margin:1rem auto}html{box-sizing:border-box;font-size:16px;font-family:Inter,sans-serif}body{font-size:16px}*,*:before,*:after{box-sizing:inherit}body,h1,h2,h3,h4,h5,h6,p,ol,ul{margin:0;padding:0;font-weight:400}ol,ul{list-style:none}img{max-width:100%;height:auto}h2{font-weight:300}input,button,select{font-family:Inter,sans-serif}a{color:var(--red);font-weight:300}.roa-table{width:100%;color:var(--dark);border-collapse:collapse;font-size:.8rem}.roa-table tr td,.roa-table tr th{border-bottom:1px solid var(--grey-lighter);padding:.5rem}.roa-table>thead>tr>th{cursor:pointer}table .asc,table .desc{display:inline-block;width:0;height:0;margin-left:.5rem;margin-bottom:2px}table .asc{border-bottom:5px solid var(--red);border-left:5px solid transparent;border-right:5px solid transparent}table .desc{border-top:5px solid var(--red);border-left:5px solid transparent;border-right:5px solid transparent}.roa-table>tbody>tr>td:first-child{position:relative;width:4rem}.roa-table tr td.actions{text-align:right}.roa-table tr.announcements td{background:var(--light-bg)}.roa-table tr th{font-weight:600;text-align:left;color:var(--grey-dark)}.roa-table .expand{position:absolute;display:block;top:50%;left:50%;transform:translate(-50%,-50%);width:2rem;height:2rem;border:none;cursor:pointer;background:none}.roa-table .expand:after{transform:translate(-50%,-25%) rotate(-45deg)}.roa-table .expand.open:after{transform:translate(-50%,-25%) rotate(45deg)}.roa-table .state{display:inline-block;padding:.25rem .5rem;border:1px solid var(--grey-dark);color:var(--grey-dark);border-radius:var(--radius);background:white}.roa-table .state.roa_seen{color:var(--success);border-color:var(--success-border)}.roa-table .state.roa_disallowing,.roa-table .state.roa_unseen{color:var(--warning);border-color:var(--warning-border)}.roa-table .state.announcement_invalid_length,.roa-table .state.announcement_invalid_asn{color:var(--error);border-color:var(--error-border)}.roa-table .row{background:white}.roa-table .row>div{padding:1.5rem;flex:1}.roa-table .row h3{font-size:.8rem;font-weight:600;margin-bottom:1rem}.roa-table .row table{width:100%;border-collapse:collapse}.roa-table .row table tr td{background:white}.roa-table input[type=checkbox]{border:1px solid var(--grey-dark);box-shadow:none;border-radius:2px;cursor:pointer;padding:.5rem;width:auto}.roa-table .add,.roa-table .remove{display:inline-block;border:1px solid;border-radius:.1rem;padding:.1rem .5rem}.roa-table .add img,.roa-table .remove img{width:.8rem;height:.8rem}.roa-table .add{background-color:#f0f9eb;border-color:#e1f3d8}.roa-table .remove{background-color:#fef0f0;border-color:#fde2e2}.notification{background:white;padding:1.5rem 3.5rem;background-repeat:no-repeat;background-position:center left 1rem;background-size:1.5rem;border-radius:var(--radius);display:flex;align-items:center}.notification.popup{position:fixed;z-index:1000;top:1rem;right:1rem;max-width:30rem;min-width:20rem;box-shadow:0 .5rem 1rem #0006}.notification.error{background-image:url(/assets/error-fd1fc7e1.svg);background-color:snow;color:#600}.notification.success{background-image:url(/assets/check-3e734f78.svg);background-color:#fafffa;color:#060}.notification .close{position:absolute;background:none;border:none;top:.5rem;right:1rem;font-size:1.5rem;opacity:.4;cursor:pointer}.info-table{background:var(--light-bg);color:var(--dark);font-size:.9rem;line-height:1.4;padding:1rem;margin-bottom:1rem}.info-table table{width:100%;background-color:#fff;margin-bottom:1rem}.info-table h4{font-size:1rem;color:#000;font-size:1.2rem;margin-bottom:.75rem}.info-table th,.info-table td{padding:1rem}.info-table th{text-align:left;width:10rem;font-weight:600}.info-table .failure,.info-table .success{display:block;padding-left:2rem;margin-top:.5rem;background:no-repeat top left;background-size:1.2rem;min-height:2rem}.info-table .failure{background-image:url(/assets/error-fd1fc7e1.svg)}.info-table .success{background-image:url(/assets/check-3e734f78.svg)}.ca-details{margin-left:3rem;min-width:20rem;align-self:flex-start;padding:2rem 2rem 4rem}.ca-details table{width:100%;color:var(--dark);border-collapse:collapse;font-size:.8rem;line-height:2;text-align:left}.ca-details table th{font-weight:600;vertical-align:top}.ca-details table th,.ca-details table td{padding:.5rem 1rem .5rem 0;border-bottom:1px solid var(--grey-lighter)}.roa-actions{display:flex;margin-top:1rem;justify-content:space-between}.pop{position:relative}.pop>div{padding:0 1rem;text-align:left;max-height:0;position:absolute;display:block;top:2.5rem;right:-2.5rem;background:white;width:12rem;border:0 solid var(--light);box-shadow:var(--shadow);border-radius:var(--radius);transition:all .3s;overflow:hidden;z-index:10}.pop:hover>div{padding:1rem;max-height:20rem}.pop>div h5{font-weight:600;font-size:1rem;margin-bottom:1rem}.pop>div table{width:100%;border:none;border-collapse:collapse}.pop>div th,.pop>div td{padding:0 0 .5rem}.loader{position:absolute;background:var(--red);top:0;left:0;right:0;width:100%;height:.5rem;overflow:hidden}@keyframes loading{0%{left:-10%;right:100%}to{right:-10%;left:100%}}.loader:after{content:" ";display:block;position:absolute;top:0;left:0;width:10%;height:.5rem;background:var(--red-light);animation:loading 2s infinite ease-in-out}.loader span{display:none}.pagination{display:flex;margin-top:1rem;justify-content:flex-end}.pagination>div{display:flex}.pagination select{border:1px solid var(--grey-light);color:var(--dark);padding:0 .5rem;background:white;border-radius:var(--radius);cursor:pointer;width:8rem}.pagination button{position:relative;margin-left:.5rem;border:none;color:var(--dark);background:var(--light-bg);font-weight:600;width:2rem;height:2rem;line-height:2rem;text-align:center;cursor:pointer}.pagination button:disabled{cursor:default;color:var(--grey)}.pagination button.number.current{opacity:1;color:#fff;background:var(--red)}.pagination .arrow:after{content:" ";position:absolute;left:55%;top:50%;display:block;width:.5rem;height:.5rem;border-bottom:2px solid var(--grey-dark);border-right:2px solid var(--grey-dark);transform:translate(-50%,-50%) rotate(135deg);transition:transform .2s}.pagination .number:hover:not(:disabled){color:var(--red)}.pagination .arrow:hover:not(:disabled):after{border-color:var(--red)}.pagination .arrow span{display:none}.pagination .arrow.next:after{left:45%;transform:translate(-50%,-50%) rotate(-45deg)}.tabs{border-bottom:2px solid var(--grey-light);display:flex;margin-bottom:1rem}.tabs li a{padding:1rem;display:inline-block;background:transparent;border:none;font-size:.8rem;font-family:Inter,sans-serif;cursor:pointer;color:#000;text-decoration:none}.tabs li a.active{color:var(--red);margin-bottom:-2px;border-bottom:2px solid var(--red)}.tabs li a:hover{color:var(--red)}.card{border:1px solid var(--grey-lighter);box-shadow:var(--shadow);border-radius:var(--radius)}.message{width:35rem;border-radius:var(--radius);display:block;margin:4rem auto -2rem;padding:1rem}.message.error{background:var(--red-light);color:var(--red)}.space-between{display:flex;justify-content:space-between}.border-bottom{padding-bottom:1rem;margin-bottom:1rem;border-bottom:1px solid var(--grey-lighter)}.badge{display:inline-block;padding:0 .25rem;border:1px solid var(--grey-dark);color:var(--grey-dark);border-radius:var(--radius);margin-left:.5rem}.badge.success{color:var(--success);border-color:var(--success-border);background:var(--success-bg)}.badge.warning{color:var(--warning);border-color:var(--warning-border);background:var(--warning-bg)}.muted{padding:.5rem;display:block;color:var(--grey-dark);text-align:center}.row{display:flex}@media (max-width: 992px){.row{flex-direction:column}}.flex-1{flex:1}.modal{position:fixed;z-index:100;top:0;left:0;right:0;bottom:0;background-color:#00000080;color:var(--dark);display:flex;align-items:center;justify-content:center}.modal>div{min-width:40rem;min-height:10rem;width:auto;height:auto;max-width:100%;max-height:100%;background:white;border-radius:var(--radius);box-shadow:var(--shadow);padding:1.5rem;overflow-x:hidden;overflow-y:auto;display:flex;flex-direction:column}.modal h3{font-weight:300;font-size:1.5rem;margin-bottom:1.5rem;color:#000}.modal p{flex:1}.modal .actions{margin-top:3rem;text-align:right}.modal label,.modal input,.modal textarea{display:block;width:100%}.modal textarea{width:40rem;max-height:100%;height:10rem;font-family:monospace;line-height:1.4}.modal label{margin-top:1rem}.modal table{margin-top:1rem;width:50rem;max-width:100%}.testbed{max-width:70rem;margin:2rem auto}.testbed img.hero{display:block;margin:3rem auto;width:8rem}.testbed form,.testbed .testbed-result{border:2px solid var(--grey-light);border-top:0;padding:1rem 2rem 2rem;background-color:#fdfdfd}.testbed .testbed-result pre{border:1px solid var(--grey-light);border-radius:var(--radius);font-size:.9rem;white-space:pre-wrap;background:white;padding:1rem}.testbed form a{margin-left:.5rem}.testbed form:after{content:"";clear:both;display:table}.testbed ul{margin-bottom:0}.testbed h2{font-weight:500;text-align:center;margin-bottom:2rem}.testbed h3{font-weight:500;margin-bottom:1rem}.testbed p{margin-bottom:1rem}.testbed label{margin-top:1rem;display:block}.testbed input,.testbed textarea{width:100%}.testbed textarea{height:10rem}.testbed button[type=submit]{margin-top:2rem;float:right}.testbed .actions{text-align:right} diff --git a/ui/assets/index-ce7af331.js b/ui/assets/index-ce7af331.js new file mode 100644 index 00000000..9bd3d737 --- /dev/null +++ b/ui/assets/index-ce7af331.js @@ -0,0 +1,115 @@ +var Am=Object.defineProperty;var Fm=(t,e,n)=>e in t?Am(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var zm=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports);var oe=(t,e,n)=>(Fm(t,typeof e!="symbol"?e+"":e,n),n);var Hw=zm((Ww,nl)=>{(function(){const e=document.createElement("link").relList;if(e&&e.supports&&e.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const i of s)if(i.type==="childList")for(const a of i.addedNodes)a.tagName==="LINK"&&a.rel==="modulepreload"&&r(a)}).observe(document,{childList:!0,subtree:!0});function n(s){const i={};return s.integrity&&(i.integrity=s.integrity),s.referrerPolicy&&(i.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?i.credentials="include":s.crossOrigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function r(s){if(s.ep)return;s.ep=!0;const i=n(s);fetch(s.href,i)}})();function $m(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var td={exports:{}},Ui={},nd={exports:{}},A={};/** + * @license React + * react.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var fs=Symbol.for("react.element"),bm=Symbol.for("react.portal"),Um=Symbol.for("react.fragment"),Vm=Symbol.for("react.strict_mode"),Hm=Symbol.for("react.profiler"),qm=Symbol.for("react.provider"),Wm=Symbol.for("react.context"),Bm=Symbol.for("react.forward_ref"),Zm=Symbol.for("react.suspense"),Qm=Symbol.for("react.memo"),Ym=Symbol.for("react.lazy"),lu=Symbol.iterator;function Km(t){return t===null||typeof t!="object"?null:(t=lu&&t[lu]||t["@@iterator"],typeof t=="function"?t:null)}var rd={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},sd=Object.assign,id={};function hr(t,e,n){this.props=t,this.context=e,this.refs=id,this.updater=n||rd}hr.prototype.isReactComponent={};hr.prototype.setState=function(t,e){if(typeof t!="object"&&typeof t!="function"&&t!=null)throw Error("setState(...): takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,t,e,"setState")};hr.prototype.forceUpdate=function(t){this.updater.enqueueForceUpdate(this,t,"forceUpdate")};function ad(){}ad.prototype=hr.prototype;function rl(t,e,n){this.props=t,this.context=e,this.refs=id,this.updater=n||rd}var sl=rl.prototype=new ad;sl.constructor=rl;sd(sl,hr.prototype);sl.isPureReactComponent=!0;var uu=Array.isArray,od=Object.prototype.hasOwnProperty,il={current:null},ld={key:!0,ref:!0,__self:!0,__source:!0};function ud(t,e,n){var r,s={},i=null,a=null;if(e!=null)for(r in e.ref!==void 0&&(a=e.ref),e.key!==void 0&&(i=""+e.key),e)od.call(e,r)&&!ld.hasOwnProperty(r)&&(s[r]=e[r]);var o=arguments.length-2;if(o===1)s.children=n;else if(1>>1,me=O[se];if(0>>1;ses(ha,L))hns(Es,ha)?(O[se]=Es,O[hn]=L,se=hn):(O[se]=ha,O[fn]=L,se=fn);else if(hns(Es,L))O[se]=Es,O[hn]=L,se=hn;else break e}}return I}function s(O,I){var L=O.sortIndex-I.sortIndex;return L!==0?L:O.id-I.id}if(typeof performance=="object"&&typeof performance.now=="function"){var i=performance;t.unstable_now=function(){return i.now()}}else{var a=Date,o=a.now();t.unstable_now=function(){return a.now()-o}}var l=[],c=[],f=1,d=null,v=3,y=!1,w=!1,g=!1,k=typeof setTimeout=="function"?setTimeout:null,m=typeof clearTimeout=="function"?clearTimeout:null,h=typeof setImmediate<"u"?setImmediate:null;typeof navigator<"u"&&navigator.scheduling!==void 0&&navigator.scheduling.isInputPending!==void 0&&navigator.scheduling.isInputPending.bind(navigator.scheduling);function p(O){for(var I=n(c);I!==null;){if(I.callback===null)r(c);else if(I.startTime<=O)r(c),I.sortIndex=I.expirationTime,e(l,I);else break;I=n(c)}}function S(O){if(g=!1,p(O),!w)if(n(l)!==null)w=!0,da(x);else{var I=n(c);I!==null&&fa(S,I.startTime-O)}}function x(O,I){w=!1,g&&(g=!1,m(C),C=-1),y=!0;var L=v;try{for(p(I),d=n(l);d!==null&&(!(d.expirationTime>I)||O&&!W());){var se=d.callback;if(typeof se=="function"){d.callback=null,v=d.priorityLevel;var me=se(d.expirationTime<=I);I=t.unstable_now(),typeof me=="function"?d.callback=me:d===n(l)&&r(l),p(I)}else r(l);d=n(l)}if(d!==null)var ks=!0;else{var fn=n(c);fn!==null&&fa(S,fn.startTime-I),ks=!1}return ks}finally{d=null,v=L,y=!1}}var T=!1,E=null,C=-1,D=5,R=-1;function W(){return!(t.unstable_now()-RO||125se?(O.sortIndex=L,e(c,O),n(l)===null&&O===n(c)&&(g?(m(C),C=-1):g=!0,fa(S,L-se))):(O.sortIndex=me,e(l,O),w||y||(w=!0,da(x))),O},t.unstable_shouldYield=W,t.unstable_wrapCallback=function(O){var I=v;return function(){var L=v;v=I;try{return O.apply(this,arguments)}finally{v=L}}}})(hd);fd.exports=hd;var op=fd.exports;/** + * @license React + * react-dom.production.min.js + * + * Copyright (c) Facebook, Inc. and its affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var md=P,He=op;function N(t){for(var e="https://reactjs.org/docs/error-decoder.html?invariant="+t,n=1;n"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),Ja=Object.prototype.hasOwnProperty,lp=/^[:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD][:A-Z_a-z\u00C0-\u00D6\u00D8-\u00F6\u00F8-\u02FF\u0370-\u037D\u037F-\u1FFF\u200C-\u200D\u2070-\u218F\u2C00-\u2FEF\u3001-\uD7FF\uF900-\uFDCF\uFDF0-\uFFFD\-.0-9\u00B7\u0300-\u036F\u203F-\u2040]*$/,du={},fu={};function up(t){return Ja.call(fu,t)?!0:Ja.call(du,t)?!1:lp.test(t)?fu[t]=!0:(du[t]=!0,!1)}function cp(t,e,n,r){if(n!==null&&n.type===0)return!1;switch(typeof e){case"function":case"symbol":return!0;case"boolean":return r?!1:n!==null?!n.acceptsBooleans:(t=t.toLowerCase().slice(0,5),t!=="data-"&&t!=="aria-");default:return!1}}function dp(t,e,n,r){if(e===null||typeof e>"u"||cp(t,e,n,r))return!0;if(r)return!1;if(n!==null)switch(n.type){case 3:return!e;case 4:return e===!1;case 5:return isNaN(e);case 6:return isNaN(e)||1>e}return!1}function Re(t,e,n,r,s,i,a){this.acceptsBooleans=e===2||e===3||e===4,this.attributeName=r,this.attributeNamespace=s,this.mustUseProperty=n,this.propertyName=t,this.type=e,this.sanitizeURL=i,this.removeEmptyString=a}var xe={};"children dangerouslySetInnerHTML defaultValue defaultChecked innerHTML suppressContentEditableWarning suppressHydrationWarning style".split(" ").forEach(function(t){xe[t]=new Re(t,0,!1,t,null,!1,!1)});[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(t){var e=t[0];xe[e]=new Re(e,1,!1,t[1],null,!1,!1)});["contentEditable","draggable","spellCheck","value"].forEach(function(t){xe[t]=new Re(t,2,!1,t.toLowerCase(),null,!1,!1)});["autoReverse","externalResourcesRequired","focusable","preserveAlpha"].forEach(function(t){xe[t]=new Re(t,2,!1,t,null,!1,!1)});"allowFullScreen async autoFocus autoPlay controls default defer disabled disablePictureInPicture disableRemotePlayback formNoValidate hidden loop noModule noValidate open playsInline readOnly required reversed scoped seamless itemScope".split(" ").forEach(function(t){xe[t]=new Re(t,3,!1,t.toLowerCase(),null,!1,!1)});["checked","multiple","muted","selected"].forEach(function(t){xe[t]=new Re(t,3,!0,t,null,!1,!1)});["capture","download"].forEach(function(t){xe[t]=new Re(t,4,!1,t,null,!1,!1)});["cols","rows","size","span"].forEach(function(t){xe[t]=new Re(t,6,!1,t,null,!1,!1)});["rowSpan","start"].forEach(function(t){xe[t]=new Re(t,5,!1,t.toLowerCase(),null,!1,!1)});var ol=/[\-:]([a-z])/g;function ll(t){return t[1].toUpperCase()}"accent-height alignment-baseline arabic-form baseline-shift cap-height clip-path clip-rule color-interpolation color-interpolation-filters color-profile color-rendering dominant-baseline enable-background fill-opacity fill-rule flood-color flood-opacity font-family font-size font-size-adjust font-stretch font-style font-variant font-weight glyph-name glyph-orientation-horizontal glyph-orientation-vertical horiz-adv-x horiz-origin-x image-rendering letter-spacing lighting-color marker-end marker-mid marker-start overline-position overline-thickness paint-order panose-1 pointer-events rendering-intent shape-rendering stop-color stop-opacity strikethrough-position strikethrough-thickness stroke-dasharray stroke-dashoffset stroke-linecap stroke-linejoin stroke-miterlimit stroke-opacity stroke-width text-anchor text-decoration text-rendering underline-position underline-thickness unicode-bidi unicode-range units-per-em v-alphabetic v-hanging v-ideographic v-mathematical vector-effect vert-adv-y vert-origin-x vert-origin-y word-spacing writing-mode xmlns:xlink x-height".split(" ").forEach(function(t){var e=t.replace(ol,ll);xe[e]=new Re(e,1,!1,t,null,!1,!1)});"xlink:actuate xlink:arcrole xlink:role xlink:show xlink:title xlink:type".split(" ").forEach(function(t){var e=t.replace(ol,ll);xe[e]=new Re(e,1,!1,t,"http://www.w3.org/1999/xlink",!1,!1)});["xml:base","xml:lang","xml:space"].forEach(function(t){var e=t.replace(ol,ll);xe[e]=new Re(e,1,!1,t,"http://www.w3.org/XML/1998/namespace",!1,!1)});["tabIndex","crossOrigin"].forEach(function(t){xe[t]=new Re(t,1,!1,t.toLowerCase(),null,!1,!1)});xe.xlinkHref=new Re("xlinkHref",1,!1,"xlink:href","http://www.w3.org/1999/xlink",!0,!1);["src","href","action","formAction"].forEach(function(t){xe[t]=new Re(t,1,!1,t.toLowerCase(),null,!0,!0)});function ul(t,e,n,r){var s=xe.hasOwnProperty(e)?xe[e]:null;(s!==null?s.type!==0:r||!(2o||s[a]!==i[o]){var l=` +`+s[a].replace(" at new "," at ");return t.displayName&&l.includes("")&&(l=l.replace("",t.displayName)),l}while(1<=a&&0<=o);break}}}finally{va=!1,Error.prepareStackTrace=n}return(t=t?t.displayName||t.name:"")?Dr(t):""}function fp(t){switch(t.tag){case 5:return Dr(t.type);case 16:return Dr("Lazy");case 13:return Dr("Suspense");case 19:return Dr("SuspenseList");case 0:case 2:case 15:return t=ga(t.type,!1),t;case 11:return t=ga(t.type.render,!1),t;case 1:return t=ga(t.type,!0),t;default:return""}}function no(t){if(t==null)return null;if(typeof t=="function")return t.displayName||t.name||null;if(typeof t=="string")return t;switch(t){case zn:return"Fragment";case Fn:return"Portal";case Xa:return"Profiler";case cl:return"StrictMode";case eo:return"Suspense";case to:return"SuspenseList"}if(typeof t=="object")switch(t.$$typeof){case gd:return(t.displayName||"Context")+".Consumer";case vd:return(t._context.displayName||"Context")+".Provider";case dl:var e=t.render;return t=t.displayName,t||(t=e.displayName||e.name||"",t=t!==""?"ForwardRef("+t+")":"ForwardRef"),t;case fl:return e=t.displayName||null,e!==null?e:no(t.type)||"Memo";case Ut:e=t._payload,t=t._init;try{return no(t(e))}catch{}}return null}function hp(t){var e=t.type;switch(t.tag){case 24:return"Cache";case 9:return(e.displayName||"Context")+".Consumer";case 10:return(e._context.displayName||"Context")+".Provider";case 18:return"DehydratedFragment";case 11:return t=e.render,t=t.displayName||t.name||"",e.displayName||(t!==""?"ForwardRef("+t+")":"ForwardRef");case 7:return"Fragment";case 5:return e;case 4:return"Portal";case 3:return"Root";case 6:return"Text";case 16:return no(e);case 8:return e===cl?"StrictMode":"Mode";case 22:return"Offscreen";case 12:return"Profiler";case 21:return"Scope";case 13:return"Suspense";case 19:return"SuspenseList";case 25:return"TracingMarker";case 1:case 0:case 17:case 2:case 14:case 15:if(typeof e=="function")return e.displayName||e.name||null;if(typeof e=="string")return e}return null}function an(t){switch(typeof t){case"boolean":case"number":case"string":case"undefined":return t;case"object":return t;default:return""}}function wd(t){var e=t.type;return(t=t.nodeName)&&t.toLowerCase()==="input"&&(e==="checkbox"||e==="radio")}function mp(t){var e=wd(t)?"checked":"value",n=Object.getOwnPropertyDescriptor(t.constructor.prototype,e),r=""+t[e];if(!t.hasOwnProperty(e)&&typeof n<"u"&&typeof n.get=="function"&&typeof n.set=="function"){var s=n.get,i=n.set;return Object.defineProperty(t,e,{configurable:!0,get:function(){return s.call(this)},set:function(a){r=""+a,i.call(this,a)}}),Object.defineProperty(t,e,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(a){r=""+a},stopTracking:function(){t._valueTracker=null,delete t[e]}}}}function Cs(t){t._valueTracker||(t._valueTracker=mp(t))}function xd(t){if(!t)return!1;var e=t._valueTracker;if(!e)return!0;var n=e.getValue(),r="";return t&&(r=wd(t)?t.checked?"true":"false":t.value),t=r,t!==n?(e.setValue(t),!0):!1}function di(t){if(t=t||(typeof document<"u"?document:void 0),typeof t>"u")return null;try{return t.activeElement||t.body}catch{return t.body}}function ro(t,e){var n=e.checked;return ee({},e,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:n??t._wrapperState.initialChecked})}function mu(t,e){var n=e.defaultValue==null?"":e.defaultValue,r=e.checked!=null?e.checked:e.defaultChecked;n=an(e.value!=null?e.value:n),t._wrapperState={initialChecked:r,initialValue:n,controlled:e.type==="checkbox"||e.type==="radio"?e.checked!=null:e.value!=null}}function Sd(t,e){e=e.checked,e!=null&&ul(t,"checked",e,!1)}function so(t,e){Sd(t,e);var n=an(e.value),r=e.type;if(n!=null)r==="number"?(n===0&&t.value===""||t.value!=n)&&(t.value=""+n):t.value!==""+n&&(t.value=""+n);else if(r==="submit"||r==="reset"){t.removeAttribute("value");return}e.hasOwnProperty("value")?io(t,e.type,n):e.hasOwnProperty("defaultValue")&&io(t,e.type,an(e.defaultValue)),e.checked==null&&e.defaultChecked!=null&&(t.defaultChecked=!!e.defaultChecked)}function pu(t,e,n){if(e.hasOwnProperty("value")||e.hasOwnProperty("defaultValue")){var r=e.type;if(!(r!=="submit"&&r!=="reset"||e.value!==void 0&&e.value!==null))return;e=""+t._wrapperState.initialValue,n||e===t.value||(t.value=e),t.defaultValue=e}n=t.name,n!==""&&(t.name=""),t.defaultChecked=!!t._wrapperState.initialChecked,n!==""&&(t.name=n)}function io(t,e,n){(e!=="number"||di(t.ownerDocument)!==t)&&(n==null?t.defaultValue=""+t._wrapperState.initialValue:t.defaultValue!==""+n&&(t.defaultValue=""+n))}var Ir=Array.isArray;function Kn(t,e,n,r){if(t=t.options,e){e={};for(var s=0;s"+e.valueOf().toString()+"",e=js.firstChild;t.firstChild;)t.removeChild(t.firstChild);for(;e.firstChild;)t.appendChild(e.firstChild)}});function Kr(t,e){if(e){var n=t.firstChild;if(n&&n===t.lastChild&&n.nodeType===3){n.nodeValue=e;return}}t.textContent=e}var zr={animationIterationCount:!0,aspectRatio:!0,borderImageOutset:!0,borderImageSlice:!0,borderImageWidth:!0,boxFlex:!0,boxFlexGroup:!0,boxOrdinalGroup:!0,columnCount:!0,columns:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,flexOrder:!0,gridArea:!0,gridRow:!0,gridRowEnd:!0,gridRowSpan:!0,gridRowStart:!0,gridColumn:!0,gridColumnEnd:!0,gridColumnSpan:!0,gridColumnStart:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,tabSize:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,floodOpacity:!0,stopOpacity:!0,strokeDasharray:!0,strokeDashoffset:!0,strokeMiterlimit:!0,strokeOpacity:!0,strokeWidth:!0},pp=["Webkit","ms","Moz","O"];Object.keys(zr).forEach(function(t){pp.forEach(function(e){e=e+t.charAt(0).toUpperCase()+t.substring(1),zr[e]=zr[t]})});function Nd(t,e,n){return e==null||typeof e=="boolean"||e===""?"":n||typeof e!="number"||e===0||zr.hasOwnProperty(t)&&zr[t]?(""+e).trim():e+"px"}function Cd(t,e){t=t.style;for(var n in e)if(e.hasOwnProperty(n)){var r=n.indexOf("--")===0,s=Nd(n,e[n],r);n==="float"&&(n="cssFloat"),r?t.setProperty(n,s):t[n]=s}}var vp=ee({menuitem:!0},{area:!0,base:!0,br:!0,col:!0,embed:!0,hr:!0,img:!0,input:!0,keygen:!0,link:!0,meta:!0,param:!0,source:!0,track:!0,wbr:!0});function lo(t,e){if(e){if(vp[t]&&(e.children!=null||e.dangerouslySetInnerHTML!=null))throw Error(N(137,t));if(e.dangerouslySetInnerHTML!=null){if(e.children!=null)throw Error(N(60));if(typeof e.dangerouslySetInnerHTML!="object"||!("__html"in e.dangerouslySetInnerHTML))throw Error(N(61))}if(e.style!=null&&typeof e.style!="object")throw Error(N(62))}}function uo(t,e){if(t.indexOf("-")===-1)return typeof e.is=="string";switch(t){case"annotation-xml":case"color-profile":case"font-face":case"font-face-src":case"font-face-uri":case"font-face-format":case"font-face-name":case"missing-glyph":return!1;default:return!0}}var co=null;function hl(t){return t=t.target||t.srcElement||window,t.correspondingUseElement&&(t=t.correspondingUseElement),t.nodeType===3?t.parentNode:t}var fo=null,Gn=null,Jn=null;function yu(t){if(t=ps(t)){if(typeof fo!="function")throw Error(N(280));var e=t.stateNode;e&&(e=Bi(e),fo(t.stateNode,t.type,e))}}function jd(t){Gn?Jn?Jn.push(t):Jn=[t]:Gn=t}function _d(){if(Gn){var t=Gn,e=Jn;if(Jn=Gn=null,yu(t),e)for(t=0;t>>=0,t===0?32:31-(jp(t)/_p|0)|0}var _s=64,Os=4194304;function Mr(t){switch(t&-t){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return t&4194240;case 4194304:case 8388608:case 16777216:case 33554432:case 67108864:return t&130023424;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 1073741824;default:return t}}function pi(t,e){var n=t.pendingLanes;if(n===0)return 0;var r=0,s=t.suspendedLanes,i=t.pingedLanes,a=n&268435455;if(a!==0){var o=a&~s;o!==0?r=Mr(o):(i&=a,i!==0&&(r=Mr(i)))}else a=n&~s,a!==0?r=Mr(a):i!==0&&(r=Mr(i));if(r===0)return 0;if(e!==0&&e!==r&&!(e&s)&&(s=r&-r,i=e&-e,s>=i||s===16&&(i&4194240)!==0))return e;if(r&4&&(r|=n&16),e=t.entangledLanes,e!==0)for(t=t.entanglements,e&=r;0n;n++)e.push(t);return e}function hs(t,e,n){t.pendingLanes|=e,e!==536870912&&(t.suspendedLanes=0,t.pingedLanes=0),t=t.eventTimes,e=31-dt(e),t[e]=n}function Dp(t,e){var n=t.pendingLanes&~e;t.pendingLanes=e,t.suspendedLanes=0,t.pingedLanes=0,t.expiredLanes&=e,t.mutableReadLanes&=e,t.entangledLanes&=e,e=t.entanglements;var r=t.eventTimes;for(t=t.expirationTimes;0=br),ju=String.fromCharCode(32),_u=!1;function Qd(t,e){switch(t){case"keyup":return av.indexOf(e.keyCode)!==-1;case"keydown":return e.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Yd(t){return t=t.detail,typeof t=="object"&&"data"in t?t.data:null}var $n=!1;function lv(t,e){switch(t){case"compositionend":return Yd(e);case"keypress":return e.which!==32?null:(_u=!0,ju);case"textInput":return t=e.data,t===ju&&_u?null:t;default:return null}}function uv(t,e){if($n)return t==="compositionend"||!Sl&&Qd(t,e)?(t=Bd(),ei=yl=Zt=null,$n=!1,t):null;switch(t){case"paste":return null;case"keypress":if(!(e.ctrlKey||e.altKey||e.metaKey)||e.ctrlKey&&e.altKey){if(e.char&&1=e)return{node:n,offset:e-t};t=r}e:{for(;n;){if(n.nextSibling){n=n.nextSibling;break e}n=n.parentNode}n=void 0}n=Du(n)}}function Xd(t,e){return t&&e?t===e?!0:t&&t.nodeType===3?!1:e&&e.nodeType===3?Xd(t,e.parentNode):"contains"in t?t.contains(e):t.compareDocumentPosition?!!(t.compareDocumentPosition(e)&16):!1:!1}function ef(){for(var t=window,e=di();e instanceof t.HTMLIFrameElement;){try{var n=typeof e.contentWindow.location.href=="string"}catch{n=!1}if(n)t=e.contentWindow;else break;e=di(t.document)}return e}function kl(t){var e=t&&t.nodeName&&t.nodeName.toLowerCase();return e&&(e==="input"&&(t.type==="text"||t.type==="search"||t.type==="tel"||t.type==="url"||t.type==="password")||e==="textarea"||t.contentEditable==="true")}function yv(t){var e=ef(),n=t.focusedElem,r=t.selectionRange;if(e!==n&&n&&n.ownerDocument&&Xd(n.ownerDocument.documentElement,n)){if(r!==null&&kl(n)){if(e=r.start,t=r.end,t===void 0&&(t=e),"selectionStart"in n)n.selectionStart=e,n.selectionEnd=Math.min(t,n.value.length);else if(t=(e=n.ownerDocument||document)&&e.defaultView||window,t.getSelection){t=t.getSelection();var s=n.textContent.length,i=Math.min(r.start,s);r=r.end===void 0?i:Math.min(r.end,s),!t.extend&&i>r&&(s=r,r=i,i=s),s=Iu(n,i);var a=Iu(n,r);s&&a&&(t.rangeCount!==1||t.anchorNode!==s.node||t.anchorOffset!==s.offset||t.focusNode!==a.node||t.focusOffset!==a.offset)&&(e=e.createRange(),e.setStart(s.node,s.offset),t.removeAllRanges(),i>r?(t.addRange(e),t.extend(a.node,a.offset)):(e.setEnd(a.node,a.offset),t.addRange(e)))}}for(e=[],t=n;t=t.parentNode;)t.nodeType===1&&e.push({element:t,left:t.scrollLeft,top:t.scrollTop});for(typeof n.focus=="function"&&n.focus(),n=0;n=document.documentMode,bn=null,yo=null,Vr=null,wo=!1;function Mu(t,e,n){var r=n.window===n?n.document:n.nodeType===9?n:n.ownerDocument;wo||bn==null||bn!==di(r)||(r=bn,"selectionStart"in r&&kl(r)?r={start:r.selectionStart,end:r.selectionEnd}:(r=(r.ownerDocument&&r.ownerDocument.defaultView||window).getSelection(),r={anchorNode:r.anchorNode,anchorOffset:r.anchorOffset,focusNode:r.focusNode,focusOffset:r.focusOffset}),Vr&&ns(Vr,r)||(Vr=r,r=yi(yo,"onSelect"),0Hn||(t.current=No[Hn],No[Hn]=null,Hn--)}function Z(t,e){Hn++,No[Hn]=t.current,t.current=e}var on={},Ne=un(on),Ae=un(!1),Tn=on;function sr(t,e){var n=t.type.contextTypes;if(!n)return on;var r=t.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===e)return r.__reactInternalMemoizedMaskedChildContext;var s={},i;for(i in n)s[i]=e[i];return r&&(t=t.stateNode,t.__reactInternalMemoizedUnmaskedChildContext=e,t.__reactInternalMemoizedMaskedChildContext=s),s}function Fe(t){return t=t.childContextTypes,t!=null}function xi(){K(Ae),K(Ne)}function Uu(t,e,n){if(Ne.current!==on)throw Error(N(168));Z(Ne,e),Z(Ae,n)}function cf(t,e,n){var r=t.stateNode;if(e=e.childContextTypes,typeof r.getChildContext!="function")return n;r=r.getChildContext();for(var s in r)if(!(s in e))throw Error(N(108,hp(t)||"Unknown",s));return ee({},n,r)}function Si(t){return t=(t=t.stateNode)&&t.__reactInternalMemoizedMergedChildContext||on,Tn=Ne.current,Z(Ne,t),Z(Ae,Ae.current),!0}function Vu(t,e,n){var r=t.stateNode;if(!r)throw Error(N(169));n?(t=cf(t,e,Tn),r.__reactInternalMemoizedMergedChildContext=t,K(Ae),K(Ne),Z(Ne,t)):K(Ae),Z(Ae,n)}var Nt=null,Zi=!1,Ra=!1;function df(t){Nt===null?Nt=[t]:Nt.push(t)}function Pv(t){Zi=!0,df(t)}function cn(){if(!Ra&&Nt!==null){Ra=!0;var t=0,e=q;try{var n=Nt;for(q=1;t>=a,s-=a,Ct=1<<32-dt(e)+s|n<C?(D=E,E=null):D=E.sibling;var R=v(m,E,p[C],S);if(R===null){E===null&&(E=D);break}t&&E&&R.alternate===null&&e(m,E),h=i(R,h,C),T===null?x=R:T.sibling=R,T=R,E=D}if(C===p.length)return n(m,E),G&&pn(m,C),x;if(E===null){for(;CC?(D=E,E=null):D=E.sibling;var W=v(m,E,R.value,S);if(W===null){E===null&&(E=D);break}t&&E&&W.alternate===null&&e(m,E),h=i(W,h,C),T===null?x=W:T.sibling=W,T=W,E=D}if(R.done)return n(m,E),G&&pn(m,C),x;if(E===null){for(;!R.done;C++,R=p.next())R=d(m,R.value,S),R!==null&&(h=i(R,h,C),T===null?x=R:T.sibling=R,T=R);return G&&pn(m,C),x}for(E=r(m,E);!R.done;C++,R=p.next())R=y(E,m,C,R.value,S),R!==null&&(t&&R.alternate!==null&&E.delete(R.key===null?C:R.key),h=i(R,h,C),T===null?x=R:T.sibling=R,T=R);return t&&E.forEach(function(he){return e(m,he)}),G&&pn(m,C),x}function k(m,h,p,S){if(typeof p=="object"&&p!==null&&p.type===zn&&p.key===null&&(p=p.props.children),typeof p=="object"&&p!==null){switch(p.$$typeof){case Ns:e:{for(var x=p.key,T=h;T!==null;){if(T.key===x){if(x=p.type,x===zn){if(T.tag===7){n(m,T.sibling),h=s(T,p.props.children),h.return=m,m=h;break e}}else if(T.elementType===x||typeof x=="object"&&x!==null&&x.$$typeof===Ut&&Yu(x)===T.type){n(m,T.sibling),h=s(T,p.props),h.ref=Cr(m,T,p),h.return=m,m=h;break e}n(m,T);break}else e(m,T);T=T.sibling}p.type===zn?(h=kn(p.props.children,m.mode,S,p.key),h.return=m,m=h):(S=li(p.type,p.key,p.props,null,m.mode,S),S.ref=Cr(m,h,p),S.return=m,m=S)}return a(m);case Fn:e:{for(T=p.key;h!==null;){if(h.key===T)if(h.tag===4&&h.stateNode.containerInfo===p.containerInfo&&h.stateNode.implementation===p.implementation){n(m,h.sibling),h=s(h,p.children||[]),h.return=m,m=h;break e}else{n(m,h);break}else e(m,h);h=h.sibling}h=$a(p,m.mode,S),h.return=m,m=h}return a(m);case Ut:return T=p._init,k(m,h,T(p._payload),S)}if(Ir(p))return w(m,h,p,S);if(Sr(p))return g(m,h,p,S);As(m,p)}return typeof p=="string"&&p!==""||typeof p=="number"?(p=""+p,h!==null&&h.tag===6?(n(m,h.sibling),h=s(h,p),h.return=m,m=h):(n(m,h),h=za(p,m.mode,S),h.return=m,m=h),a(m)):n(m,h)}return k}var ar=wf(!0),xf=wf(!1),vs={},St=un(vs),as=un(vs),os=un(vs);function xn(t){if(t===vs)throw Error(N(174));return t}function Rl(t,e){switch(Z(os,e),Z(as,t),Z(St,vs),t=e.nodeType,t){case 9:case 11:e=(e=e.documentElement)?e.namespaceURI:oo(null,"");break;default:t=t===8?e.parentNode:e,e=t.namespaceURI||null,t=t.tagName,e=oo(e,t)}K(St),Z(St,e)}function or(){K(St),K(as),K(os)}function Sf(t){xn(os.current);var e=xn(St.current),n=oo(e,t.type);e!==n&&(Z(as,t),Z(St,n))}function Dl(t){as.current===t&&(K(St),K(as))}var J=un(0);function ji(t){for(var e=t;e!==null;){if(e.tag===13){var n=e.memoizedState;if(n!==null&&(n=n.dehydrated,n===null||n.data==="$?"||n.data==="$!"))return e}else if(e.tag===19&&e.memoizedProps.revealOrder!==void 0){if(e.flags&128)return e}else if(e.child!==null){e.child.return=e,e=e.child;continue}if(e===t)break;for(;e.sibling===null;){if(e.return===null||e.return===t)return null;e=e.return}e.sibling.return=e.return,e=e.sibling}return null}var Da=[];function Il(){for(var t=0;tn?n:4,t(!0);var r=Ia.transition;Ia.transition={};try{t(!1),e()}finally{q=n,Ia.transition=r}}function Ff(){return rt().memoizedState}function Mv(t,e,n){var r=rn(t);if(n={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null},zf(t))$f(e,n);else if(n=pf(t,e,n,r),n!==null){var s=Oe();ft(n,t,r,s),bf(n,e,r)}}function Lv(t,e,n){var r=rn(t),s={lane:r,action:n,hasEagerState:!1,eagerState:null,next:null};if(zf(t))$f(e,s);else{var i=t.alternate;if(t.lanes===0&&(i===null||i.lanes===0)&&(i=e.lastRenderedReducer,i!==null))try{var a=e.lastRenderedState,o=i(a,n);if(s.hasEagerState=!0,s.eagerState=o,ht(o,a)){var l=e.interleaved;l===null?(s.next=s,Ol(e)):(s.next=l.next,l.next=s),e.interleaved=s;return}}catch{}finally{}n=pf(t,e,s,r),n!==null&&(s=Oe(),ft(n,t,r,s),bf(n,e,r))}}function zf(t){var e=t.alternate;return t===X||e!==null&&e===X}function $f(t,e){Hr=_i=!0;var n=t.pending;n===null?e.next=e:(e.next=n.next,n.next=e),t.pending=e}function bf(t,e,n){if(n&4194240){var r=e.lanes;r&=t.pendingLanes,n|=r,e.lanes=n,pl(t,n)}}var Oi={readContext:nt,useCallback:Se,useContext:Se,useEffect:Se,useImperativeHandle:Se,useInsertionEffect:Se,useLayoutEffect:Se,useMemo:Se,useReducer:Se,useRef:Se,useState:Se,useDebugValue:Se,useDeferredValue:Se,useTransition:Se,useMutableSource:Se,useSyncExternalStore:Se,useId:Se,unstable_isNewReconciler:!1},Av={readContext:nt,useCallback:function(t,e){return gt().memoizedState=[t,e===void 0?null:e],t},useContext:nt,useEffect:Gu,useImperativeHandle:function(t,e,n){return n=n!=null?n.concat([t]):null,si(4194308,4,Df.bind(null,e,t),n)},useLayoutEffect:function(t,e){return si(4194308,4,t,e)},useInsertionEffect:function(t,e){return si(4,2,t,e)},useMemo:function(t,e){var n=gt();return e=e===void 0?null:e,t=t(),n.memoizedState=[t,e],t},useReducer:function(t,e,n){var r=gt();return e=n!==void 0?n(e):e,r.memoizedState=r.baseState=e,t={pending:null,interleaved:null,lanes:0,dispatch:null,lastRenderedReducer:t,lastRenderedState:e},r.queue=t,t=t.dispatch=Mv.bind(null,X,t),[r.memoizedState,t]},useRef:function(t){var e=gt();return t={current:t},e.memoizedState=t},useState:Ku,useDebugValue:zl,useDeferredValue:function(t){return gt().memoizedState=t},useTransition:function(){var t=Ku(!1),e=t[0];return t=Iv.bind(null,t[1]),gt().memoizedState=t,[e,t]},useMutableSource:function(){},useSyncExternalStore:function(t,e,n){var r=X,s=gt();if(G){if(n===void 0)throw Error(N(407));n=n()}else{if(n=e(),ve===null)throw Error(N(349));Cn&30||Tf(r,e,n)}s.memoizedState=n;var i={value:n,getSnapshot:e};return s.queue=i,Gu(Cf.bind(null,r,i,t),[t]),r.flags|=2048,cs(9,Nf.bind(null,r,i,n,e),void 0,null),n},useId:function(){var t=gt(),e=ve.identifierPrefix;if(G){var n=jt,r=Ct;n=(r&~(1<<32-dt(r)-1)).toString(32)+n,e=":"+e+"R"+n,n=ls++,0<\/script>",t=t.removeChild(t.firstChild)):typeof r.is=="string"?t=a.createElement(n,{is:r.is}):(t=a.createElement(n),n==="select"&&(a=t,r.multiple?a.multiple=!0:r.size&&(a.size=r.size))):t=a.createElementNS(t,n),t[wt]=e,t[is]=r,Yf(t,e,!1,!1),e.stateNode=t;e:{switch(a=uo(n,r),n){case"dialog":Q("cancel",t),Q("close",t),s=r;break;case"iframe":case"object":case"embed":Q("load",t),s=r;break;case"video":case"audio":for(s=0;sur&&(e.flags|=128,r=!0,jr(i,!1),e.lanes=4194304)}else{if(!r)if(t=ji(a),t!==null){if(e.flags|=128,r=!0,n=t.updateQueue,n!==null&&(e.updateQueue=n,e.flags|=4),jr(i,!0),i.tail===null&&i.tailMode==="hidden"&&!a.alternate&&!G)return ke(e),null}else 2*ie()-i.renderingStartTime>ur&&n!==1073741824&&(e.flags|=128,r=!0,jr(i,!1),e.lanes=4194304);i.isBackwards?(a.sibling=e.child,e.child=a):(n=i.last,n!==null?n.sibling=a:e.child=a,i.last=a)}return i.tail!==null?(e=i.tail,i.rendering=e,i.tail=e.sibling,i.renderingStartTime=ie(),e.sibling=null,n=J.current,Z(J,r?n&1|2:n&1),e):(ke(e),null);case 22:case 23:return ql(),r=e.memoizedState!==null,t!==null&&t.memoizedState!==null!==r&&(e.flags|=8192),r&&e.mode&1?$e&1073741824&&(ke(e),e.subtreeFlags&6&&(e.flags|=8192)):ke(e),null;case 24:return null;case 25:return null}throw Error(N(156,e.tag))}function qv(t,e){switch(Tl(e),e.tag){case 1:return Fe(e.type)&&xi(),t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 3:return or(),K(Ae),K(Ne),Il(),t=e.flags,t&65536&&!(t&128)?(e.flags=t&-65537|128,e):null;case 5:return Dl(e),null;case 13:if(K(J),t=e.memoizedState,t!==null&&t.dehydrated!==null){if(e.alternate===null)throw Error(N(340));ir()}return t=e.flags,t&65536?(e.flags=t&-65537|128,e):null;case 19:return K(J),null;case 4:return or(),null;case 10:return _l(e.type._context),null;case 22:case 23:return ql(),null;case 24:return null;default:return null}}var zs=!1,Ee=!1,Wv=typeof WeakSet=="function"?WeakSet:Set,_=null;function Zn(t,e){var n=t.ref;if(n!==null)if(typeof n=="function")try{n(null)}catch(r){re(t,e,r)}else n.current=null}function Fo(t,e,n){try{n()}catch(r){re(t,e,r)}}var ac=!1;function Bv(t,e){if(xo=vi,t=ef(),kl(t)){if("selectionStart"in t)var n={start:t.selectionStart,end:t.selectionEnd};else e:{n=(n=t.ownerDocument)&&n.defaultView||window;var r=n.getSelection&&n.getSelection();if(r&&r.rangeCount!==0){n=r.anchorNode;var s=r.anchorOffset,i=r.focusNode;r=r.focusOffset;try{n.nodeType,i.nodeType}catch{n=null;break e}var a=0,o=-1,l=-1,c=0,f=0,d=t,v=null;t:for(;;){for(var y;d!==n||s!==0&&d.nodeType!==3||(o=a+s),d!==i||r!==0&&d.nodeType!==3||(l=a+r),d.nodeType===3&&(a+=d.nodeValue.length),(y=d.firstChild)!==null;)v=d,d=y;for(;;){if(d===t)break t;if(v===n&&++c===s&&(o=a),v===i&&++f===r&&(l=a),(y=d.nextSibling)!==null)break;d=v,v=d.parentNode}d=y}n=o===-1||l===-1?null:{start:o,end:l}}else n=null}n=n||{start:0,end:0}}else n=null;for(So={focusedElem:t,selectionRange:n},vi=!1,_=e;_!==null;)if(e=_,t=e.child,(e.subtreeFlags&1028)!==0&&t!==null)t.return=e,_=t;else for(;_!==null;){e=_;try{var w=e.alternate;if(e.flags&1024)switch(e.tag){case 0:case 11:case 15:break;case 1:if(w!==null){var g=w.memoizedProps,k=w.memoizedState,m=e.stateNode,h=m.getSnapshotBeforeUpdate(e.elementType===e.type?g:ot(e.type,g),k);m.__reactInternalSnapshotBeforeUpdate=h}break;case 3:var p=e.stateNode.containerInfo;p.nodeType===1?p.textContent="":p.nodeType===9&&p.documentElement&&p.removeChild(p.documentElement);break;case 5:case 6:case 4:case 17:break;default:throw Error(N(163))}}catch(S){re(e,e.return,S)}if(t=e.sibling,t!==null){t.return=e.return,_=t;break}_=e.return}return w=ac,ac=!1,w}function qr(t,e,n){var r=e.updateQueue;if(r=r!==null?r.lastEffect:null,r!==null){var s=r=r.next;do{if((s.tag&t)===t){var i=s.destroy;s.destroy=void 0,i!==void 0&&Fo(e,n,i)}s=s.next}while(s!==r)}}function Ki(t,e){if(e=e.updateQueue,e=e!==null?e.lastEffect:null,e!==null){var n=e=e.next;do{if((n.tag&t)===t){var r=n.create;n.destroy=r()}n=n.next}while(n!==e)}}function zo(t){var e=t.ref;if(e!==null){var n=t.stateNode;switch(t.tag){case 5:t=n;break;default:t=n}typeof e=="function"?e(t):e.current=t}}function Jf(t){var e=t.alternate;e!==null&&(t.alternate=null,Jf(e)),t.child=null,t.deletions=null,t.sibling=null,t.tag===5&&(e=t.stateNode,e!==null&&(delete e[wt],delete e[is],delete e[To],delete e[_v],delete e[Ov])),t.stateNode=null,t.return=null,t.dependencies=null,t.memoizedProps=null,t.memoizedState=null,t.pendingProps=null,t.stateNode=null,t.updateQueue=null}function Xf(t){return t.tag===5||t.tag===3||t.tag===4}function oc(t){e:for(;;){for(;t.sibling===null;){if(t.return===null||Xf(t.return))return null;t=t.return}for(t.sibling.return=t.return,t=t.sibling;t.tag!==5&&t.tag!==6&&t.tag!==18;){if(t.flags&2||t.child===null||t.tag===4)continue e;t.child.return=t,t=t.child}if(!(t.flags&2))return t.stateNode}}function $o(t,e,n){var r=t.tag;if(r===5||r===6)t=t.stateNode,e?n.nodeType===8?n.parentNode.insertBefore(t,e):n.insertBefore(t,e):(n.nodeType===8?(e=n.parentNode,e.insertBefore(t,n)):(e=n,e.appendChild(t)),n=n._reactRootContainer,n!=null||e.onclick!==null||(e.onclick=wi));else if(r!==4&&(t=t.child,t!==null))for($o(t,e,n),t=t.sibling;t!==null;)$o(t,e,n),t=t.sibling}function bo(t,e,n){var r=t.tag;if(r===5||r===6)t=t.stateNode,e?n.insertBefore(t,e):n.appendChild(t);else if(r!==4&&(t=t.child,t!==null))for(bo(t,e,n),t=t.sibling;t!==null;)bo(t,e,n),t=t.sibling}var ye=null,lt=!1;function zt(t,e,n){for(n=n.child;n!==null;)eh(t,e,n),n=n.sibling}function eh(t,e,n){if(xt&&typeof xt.onCommitFiberUnmount=="function")try{xt.onCommitFiberUnmount(Vi,n)}catch{}switch(n.tag){case 5:Ee||Zn(n,e);case 6:var r=ye,s=lt;ye=null,zt(t,e,n),ye=r,lt=s,ye!==null&&(lt?(t=ye,n=n.stateNode,t.nodeType===8?t.parentNode.removeChild(n):t.removeChild(n)):ye.removeChild(n.stateNode));break;case 18:ye!==null&&(lt?(t=ye,n=n.stateNode,t.nodeType===8?Pa(t.parentNode,n):t.nodeType===1&&Pa(t,n),es(t)):Pa(ye,n.stateNode));break;case 4:r=ye,s=lt,ye=n.stateNode.containerInfo,lt=!0,zt(t,e,n),ye=r,lt=s;break;case 0:case 11:case 14:case 15:if(!Ee&&(r=n.updateQueue,r!==null&&(r=r.lastEffect,r!==null))){s=r=r.next;do{var i=s,a=i.destroy;i=i.tag,a!==void 0&&(i&2||i&4)&&Fo(n,e,a),s=s.next}while(s!==r)}zt(t,e,n);break;case 1:if(!Ee&&(Zn(n,e),r=n.stateNode,typeof r.componentWillUnmount=="function"))try{r.props=n.memoizedProps,r.state=n.memoizedState,r.componentWillUnmount()}catch(o){re(n,e,o)}zt(t,e,n);break;case 21:zt(t,e,n);break;case 22:n.mode&1?(Ee=(r=Ee)||n.memoizedState!==null,zt(t,e,n),Ee=r):zt(t,e,n);break;default:zt(t,e,n)}}function lc(t){var e=t.updateQueue;if(e!==null){t.updateQueue=null;var n=t.stateNode;n===null&&(n=t.stateNode=new Wv),e.forEach(function(r){var s=tg.bind(null,t,r);n.has(r)||(n.add(r),r.then(s,s))})}}function st(t,e){var n=e.deletions;if(n!==null)for(var r=0;rs&&(s=a),r&=~i}if(r=s,r=ie()-r,r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*Qv(r/1960))-r,10t?16:t,Qt===null)var r=!1;else{if(t=Qt,Qt=null,Di=0,V&6)throw Error(N(331));var s=V;for(V|=4,_=t.current;_!==null;){var i=_,a=i.child;if(_.flags&16){var o=i.deletions;if(o!==null){for(var l=0;lie()-Vl?Sn(t,0):Ul|=n),ze(t,e)}function lh(t,e){e===0&&(t.mode&1?(e=Os,Os<<=1,!(Os&130023424)&&(Os=4194304)):e=1);var n=Oe();t=Dt(t,e),t!==null&&(hs(t,e,n),ze(t,n))}function eg(t){var e=t.memoizedState,n=0;e!==null&&(n=e.retryLane),lh(t,n)}function tg(t,e){var n=0;switch(t.tag){case 13:var r=t.stateNode,s=t.memoizedState;s!==null&&(n=s.retryLane);break;case 19:r=t.stateNode;break;default:throw Error(N(314))}r!==null&&r.delete(e),lh(t,n)}var uh;uh=function(t,e,n){if(t!==null)if(t.memoizedProps!==e.pendingProps||Ae.current)Le=!0;else{if(!(t.lanes&n)&&!(e.flags&128))return Le=!1,Vv(t,e,n);Le=!!(t.flags&131072)}else Le=!1,G&&e.flags&1048576&&ff(e,Ei,e.index);switch(e.lanes=0,e.tag){case 2:var r=e.type;ii(t,e),t=e.pendingProps;var s=sr(e,Ne.current);er(e,n),s=Ll(null,e,r,t,s,n);var i=Al();return e.flags|=1,typeof s=="object"&&s!==null&&typeof s.render=="function"&&s.$$typeof===void 0?(e.tag=1,e.memoizedState=null,e.updateQueue=null,Fe(r)?(i=!0,Si(e)):i=!1,e.memoizedState=s.state!==null&&s.state!==void 0?s.state:null,Pl(e),s.updater=Qi,e.stateNode=s,s._reactInternals=e,Po(e,r,t,n),e=Io(null,e,r,!0,i,n)):(e.tag=0,G&&i&&El(e),je(null,e,s,n),e=e.child),e;case 16:r=e.elementType;e:{switch(ii(t,e),t=e.pendingProps,s=r._init,r=s(r._payload),e.type=r,s=e.tag=rg(r),t=ot(r,t),s){case 0:e=Do(null,e,r,t,n);break e;case 1:e=rc(null,e,r,t,n);break e;case 11:e=tc(null,e,r,t,n);break e;case 14:e=nc(null,e,r,ot(r.type,t),n);break e}throw Error(N(306,r,""))}return e;case 0:return r=e.type,s=e.pendingProps,s=e.elementType===r?s:ot(r,s),Do(t,e,r,s,n);case 1:return r=e.type,s=e.pendingProps,s=e.elementType===r?s:ot(r,s),rc(t,e,r,s,n);case 3:e:{if(Bf(e),t===null)throw Error(N(387));r=e.pendingProps,i=e.memoizedState,s=i.element,vf(t,e),Ci(e,r,null,n);var a=e.memoizedState;if(r=a.element,i.isDehydrated)if(i={element:r,isDehydrated:!1,cache:a.cache,pendingSuspenseBoundaries:a.pendingSuspenseBoundaries,transitions:a.transitions},e.updateQueue.baseState=i,e.memoizedState=i,e.flags&256){s=lr(Error(N(423)),e),e=sc(t,e,r,n,s);break e}else if(r!==s){s=lr(Error(N(424)),e),e=sc(t,e,r,n,s);break e}else for(be=en(e.stateNode.containerInfo.firstChild),Ue=e,G=!0,ut=null,n=xf(e,null,r,n),e.child=n;n;)n.flags=n.flags&-3|4096,n=n.sibling;else{if(ir(),r===s){e=It(t,e,n);break e}je(t,e,r,n)}e=e.child}return e;case 5:return Sf(e),t===null&&jo(e),r=e.type,s=e.pendingProps,i=t!==null?t.memoizedProps:null,a=s.children,ko(r,s)?a=null:i!==null&&ko(r,i)&&(e.flags|=32),Wf(t,e),je(t,e,a,n),e.child;case 6:return t===null&&jo(e),null;case 13:return Zf(t,e,n);case 4:return Rl(e,e.stateNode.containerInfo),r=e.pendingProps,t===null?e.child=ar(e,null,r,n):je(t,e,r,n),e.child;case 11:return r=e.type,s=e.pendingProps,s=e.elementType===r?s:ot(r,s),tc(t,e,r,s,n);case 7:return je(t,e,e.pendingProps,n),e.child;case 8:return je(t,e,e.pendingProps.children,n),e.child;case 12:return je(t,e,e.pendingProps.children,n),e.child;case 10:e:{if(r=e.type._context,s=e.pendingProps,i=e.memoizedProps,a=s.value,Z(Ti,r._currentValue),r._currentValue=a,i!==null)if(ht(i.value,a)){if(i.children===s.children&&!Ae.current){e=It(t,e,n);break e}}else for(i=e.child,i!==null&&(i.return=e);i!==null;){var o=i.dependencies;if(o!==null){a=i.child;for(var l=o.firstContext;l!==null;){if(l.context===r){if(i.tag===1){l=Ot(-1,n&-n),l.tag=2;var c=i.updateQueue;if(c!==null){c=c.shared;var f=c.pending;f===null?l.next=l:(l.next=f.next,f.next=l),c.pending=l}}i.lanes|=n,l=i.alternate,l!==null&&(l.lanes|=n),_o(i.return,n,e),o.lanes|=n;break}l=l.next}}else if(i.tag===10)a=i.type===e.type?null:i.child;else if(i.tag===18){if(a=i.return,a===null)throw Error(N(341));a.lanes|=n,o=a.alternate,o!==null&&(o.lanes|=n),_o(a,n,e),a=i.sibling}else a=i.child;if(a!==null)a.return=i;else for(a=i;a!==null;){if(a===e){a=null;break}if(i=a.sibling,i!==null){i.return=a.return,a=i;break}a=a.return}i=a}je(t,e,s.children,n),e=e.child}return e;case 9:return s=e.type,r=e.pendingProps.children,er(e,n),s=nt(s),r=r(s),e.flags|=1,je(t,e,r,n),e.child;case 14:return r=e.type,s=ot(r,e.pendingProps),s=ot(r.type,s),nc(t,e,r,s,n);case 15:return Hf(t,e,e.type,e.pendingProps,n);case 17:return r=e.type,s=e.pendingProps,s=e.elementType===r?s:ot(r,s),ii(t,e),e.tag=1,Fe(r)?(t=!0,Si(e)):t=!1,er(e,n),yf(e,r,s),Po(e,r,s,n),Io(null,e,r,!0,t,n);case 19:return Qf(t,e,n);case 22:return qf(t,e,n)}throw Error(N(156,e.tag))};function ch(t,e){return Ld(t,e)}function ng(t,e,n,r){this.tag=t,this.key=n,this.sibling=this.child=this.return=this.stateNode=this.type=this.elementType=null,this.index=0,this.ref=null,this.pendingProps=e,this.dependencies=this.memoizedState=this.updateQueue=this.memoizedProps=null,this.mode=r,this.subtreeFlags=this.flags=0,this.deletions=null,this.childLanes=this.lanes=0,this.alternate=null}function Ge(t,e,n,r){return new ng(t,e,n,r)}function Bl(t){return t=t.prototype,!(!t||!t.isReactComponent)}function rg(t){if(typeof t=="function")return Bl(t)?1:0;if(t!=null){if(t=t.$$typeof,t===dl)return 11;if(t===fl)return 14}return 2}function sn(t,e){var n=t.alternate;return n===null?(n=Ge(t.tag,e,t.key,t.mode),n.elementType=t.elementType,n.type=t.type,n.stateNode=t.stateNode,n.alternate=t,t.alternate=n):(n.pendingProps=e,n.type=t.type,n.flags=0,n.subtreeFlags=0,n.deletions=null),n.flags=t.flags&14680064,n.childLanes=t.childLanes,n.lanes=t.lanes,n.child=t.child,n.memoizedProps=t.memoizedProps,n.memoizedState=t.memoizedState,n.updateQueue=t.updateQueue,e=t.dependencies,n.dependencies=e===null?null:{lanes:e.lanes,firstContext:e.firstContext},n.sibling=t.sibling,n.index=t.index,n.ref=t.ref,n}function li(t,e,n,r,s,i){var a=2;if(r=t,typeof t=="function")Bl(t)&&(a=1);else if(typeof t=="string")a=5;else e:switch(t){case zn:return kn(n.children,s,i,e);case cl:a=8,s|=8;break;case Xa:return t=Ge(12,n,e,s|2),t.elementType=Xa,t.lanes=i,t;case eo:return t=Ge(13,n,e,s),t.elementType=eo,t.lanes=i,t;case to:return t=Ge(19,n,e,s),t.elementType=to,t.lanes=i,t;case yd:return Ji(n,s,i,e);default:if(typeof t=="object"&&t!==null)switch(t.$$typeof){case vd:a=10;break e;case gd:a=9;break e;case dl:a=11;break e;case fl:a=14;break e;case Ut:a=16,r=null;break e}throw Error(N(130,t==null?t:typeof t,""))}return e=Ge(a,n,e,s),e.elementType=t,e.type=r,e.lanes=i,e}function kn(t,e,n,r){return t=Ge(7,t,r,e),t.lanes=n,t}function Ji(t,e,n,r){return t=Ge(22,t,r,e),t.elementType=yd,t.lanes=n,t.stateNode={isHidden:!1},t}function za(t,e,n){return t=Ge(6,t,null,e),t.lanes=n,t}function $a(t,e,n){return e=Ge(4,t.children!==null?t.children:[],t.key,e),e.lanes=n,e.stateNode={containerInfo:t.containerInfo,pendingChildren:null,implementation:t.implementation},e}function sg(t,e,n,r,s){this.tag=e,this.containerInfo=t,this.finishedWork=this.pingCache=this.current=this.pendingChildren=null,this.timeoutHandle=-1,this.callbackNode=this.pendingContext=this.context=null,this.callbackPriority=0,this.eventTimes=wa(0),this.expirationTimes=wa(-1),this.entangledLanes=this.finishedLanes=this.mutableReadLanes=this.expiredLanes=this.pingedLanes=this.suspendedLanes=this.pendingLanes=0,this.entanglements=wa(0),this.identifierPrefix=r,this.onRecoverableError=s,this.mutableSourceEagerHydrationData=null}function Zl(t,e,n,r,s,i,a,o,l){return t=new sg(t,e,n,o,l),e===1?(e=1,i===!0&&(e|=8)):e=0,i=Ge(3,null,null,e),t.current=i,i.stateNode=t,i.memoizedState={element:r,isDehydrated:n,cache:null,transitions:null,pendingSuspenseBoundaries:null},Pl(i),t}function ig(t,e,n){var r=3"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(mh)}catch(t){console.error(t)}}mh(),dd.exports=qe;var cg=dd.exports,ph,vc=cg;ph=vc.createRoot,vc.hydrateRoot;var Wo=function(t){return t.split(".").reduce(function(e,n){return e.concat(e.length?e[e.length-1]+"."+n:n)},[])},dg=function(t){return t!=null},Bo=function(t){return t&&t.meta&&t.meta.params},gc=function(t,e){return!Bo(e)||!dg(e.meta.params[t])?{}:Object.keys(e.meta.params[t]).reduce(function(n,r){return n[r]=e.params[r],n},{})};function vh(t,e){var n=t.meta&&t.meta&&t.meta.options||{},r=e?Wo(e.name):[],s=Wo(t.name),i=Math.min(r.length,s.length);function a(){var d,v=function(){var w=r[d],g=s[d];if(w!==g)return{value:d};var k=gc(w,t),m=gc(g,e);if(Object.keys(k).length!==Object.keys(m).length)return{value:d};if(Object.keys(k).length===0)return"continue";var h=Object.keys(k).some(function(p){return m[p]!==k[p]});if(h)return{value:d}};for(d=0;d0?r[o-1]:"";return{intersection:f,toDeactivate:l,toActivate:c}}/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. All rights reserved. +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 + +THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +MERCHANTABLITY OR NON-INFRINGEMENT. + +See the Apache Version 2.0 License for specific language governing permissions +and limitations under the License. +***************************************************************************** */function fg(){for(var t=0,e=0,n=arguments.length;e(t.success="success",t.warning="warning",t.error="error",t))(U||{}),De=(t=>(t.RoaSeen="roa_seen",t.RoaUnseen="roa_unseen",t.RoaNotHeld="roa_not_held",t.RoaNoAnnouncementInfo="roa_no_announcement_info",t.RoaTooPermissive="roa_too_permissive",t.RoaDisallowing="roa_disallowing",t.RoaRedundant="roa_redundant",t.RoaAs0="roa_as0",t.RoaAs0Redundant="roa_as0_redundant",t.AnnouncementNotFound="announcement_not_found",t.AnnouncementInvalidLength="announcement_invalid_length",t.AnnouncementInvalidAsn="announcement_invalid_asn",t.AnnouncementDisallowedAs0="announcement_disallowed",t))(De||{}),Yn=(t=>(t.asn="asn",t.comment="comment",t.prefix="prefix",t.state="state",t))(Yn||{}),tt=(t=>(t.asc="asc",t.desc="desc",t))(tt||{}),vt=(t=>(t.notFound="not_found",t.invalidAsn="invalid_asn",t.invalidLength="invalid_length",t.tooPermissive="too_permissive",t.disallowing="disallowing",t.stale="stale",t.redundant="redundant",t.as0Redundant="as0_redundant",t.specific="specific",t))(vt||{}),yt=(t=>(t[t.unchecked=0]="unchecked",t[t.checked=1]="checked",t[t.intermediate=2]="intermediate",t))(yt||{}),Li=(t=>(t.action="action",t.reason="reason",t.asn="asn",t.maxLength="max_length",t.prefix="prefix",t))(Li||{});class Rn extends Error{}class Sg extends Rn{constructor(e){super(`Invalid DateTime: ${e.toMessage()}`)}}class kg extends Rn{constructor(e){super(`Invalid Interval: ${e.toMessage()}`)}}class Eg extends Rn{constructor(e){super(`Invalid Duration: ${e.toMessage()}`)}}class Ar extends Rn{}class yh extends Rn{constructor(e){super(`Invalid unit ${e}`)}}class Ke extends Rn{}class $t extends Rn{constructor(){super("Zone is an abstract class")}}const j="numeric",mt="short",Ve="long",Ai={year:j,month:j,day:j},wh={year:j,month:mt,day:j},Tg={year:j,month:mt,day:j,weekday:mt},xh={year:j,month:Ve,day:j},Sh={year:j,month:Ve,day:j,weekday:Ve},kh={hour:j,minute:j},Eh={hour:j,minute:j,second:j},Th={hour:j,minute:j,second:j,timeZoneName:mt},Nh={hour:j,minute:j,second:j,timeZoneName:Ve},Ch={hour:j,minute:j,hourCycle:"h23"},jh={hour:j,minute:j,second:j,hourCycle:"h23"},_h={hour:j,minute:j,second:j,hourCycle:"h23",timeZoneName:mt},Oh={hour:j,minute:j,second:j,hourCycle:"h23",timeZoneName:Ve},Ph={year:j,month:j,day:j,hour:j,minute:j},Rh={year:j,month:j,day:j,hour:j,minute:j,second:j},Dh={year:j,month:mt,day:j,hour:j,minute:j},Ih={year:j,month:mt,day:j,hour:j,minute:j,second:j},Ng={year:j,month:mt,day:j,weekday:mt,hour:j,minute:j},Mh={year:j,month:Ve,day:j,hour:j,minute:j,timeZoneName:mt},Lh={year:j,month:Ve,day:j,hour:j,minute:j,second:j,timeZoneName:mt},Ah={year:j,month:Ve,day:j,weekday:Ve,hour:j,minute:j,timeZoneName:Ve},Fh={year:j,month:Ve,day:j,weekday:Ve,hour:j,minute:j,second:j,timeZoneName:Ve};class gs{get type(){throw new $t}get name(){throw new $t}get ianaName(){return this.name}get isUniversal(){throw new $t}offsetName(e,n){throw new $t}formatOffset(e,n){throw new $t}offset(e){throw new $t}equals(e){throw new $t}get isValid(){throw new $t}}let ba=null;class sa extends gs{static get instance(){return ba===null&&(ba=new sa),ba}get type(){return"system"}get name(){return new Intl.DateTimeFormat().resolvedOptions().timeZone}get isUniversal(){return!1}offsetName(e,{format:n,locale:r}){return $h(e,n,r)}formatOffset(e,n){return Qr(this.offset(e),n)}offset(e){return-new Date(e).getTimezoneOffset()}equals(e){return e.type==="system"}get isValid(){return!0}}let ui={};function Cg(t){return ui[t]||(ui[t]=new Intl.DateTimeFormat("en-US",{hour12:!1,timeZone:t,year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit",second:"2-digit",era:"short"})),ui[t]}const jg={year:0,month:1,day:2,era:3,hour:4,minute:5,second:6};function _g(t,e){const n=t.format(e).replace(/\u200E/g,""),r=/(\d+)\/(\d+)\/(\d+) (AD|BC),? (\d+):(\d+):(\d+)/.exec(n),[,s,i,a,o,l,c,f]=r;return[a,s,i,o,l,c,f]}function Og(t,e){const n=t.formatToParts(e),r=[];for(let s=0;s=0?w:1e3+w,(v-y)/(60*1e3)}equals(e){return e.type==="iana"&&e.name===this.name}get isValid(){return this.valid}}let yc={};function Pg(t,e={}){const n=JSON.stringify([t,e]);let r=yc[n];return r||(r=new Intl.ListFormat(t,e),yc[n]=r),r}let Qo={};function Yo(t,e={}){const n=JSON.stringify([t,e]);let r=Qo[n];return r||(r=new Intl.DateTimeFormat(t,e),Qo[n]=r),r}let Ko={};function Rg(t,e={}){const n=JSON.stringify([t,e]);let r=Ko[n];return r||(r=new Intl.NumberFormat(t,e),Ko[n]=r),r}let Go={};function Dg(t,e={}){const{base:n,...r}=e,s=JSON.stringify([t,r]);let i=Go[s];return i||(i=new Intl.RelativeTimeFormat(t,e),Go[s]=i),i}let Fr=null;function Ig(){return Fr||(Fr=new Intl.DateTimeFormat().resolvedOptions().locale,Fr)}function Mg(t){const e=t.indexOf("-x-");e!==-1&&(t=t.substring(0,e));const n=t.indexOf("-u-");if(n===-1)return[t];{let r,s;try{r=Yo(t).resolvedOptions(),s=t}catch{const l=t.substring(0,n);r=Yo(l).resolvedOptions(),s=l}const{numberingSystem:i,calendar:a}=r;return[s,i,a]}}function Lg(t,e,n){return(n||e)&&(t.includes("-u-")||(t+="-u"),n&&(t+=`-ca-${n}`),e&&(t+=`-nu-${e}`)),t}function Ag(t){const e=[];for(let n=1;n<=12;n++){const r=M.utc(2016,n,1);e.push(t(r))}return e}function Fg(t){const e=[];for(let n=1;n<=7;n++){const r=M.utc(2016,11,13+n);e.push(t(r))}return e}function Vs(t,e,n,r,s){const i=t.listingMode(n);return i==="error"?null:i==="en"?r(e):s(e)}function zg(t){return t.numberingSystem&&t.numberingSystem!=="latn"?!1:t.numberingSystem==="latn"||!t.locale||t.locale.startsWith("en")||new Intl.DateTimeFormat(t.intl).resolvedOptions().numberingSystem==="latn"}class $g{constructor(e,n,r){this.padTo=r.padTo||0,this.floor=r.floor||!1;const{padTo:s,floor:i,...a}=r;if(!n||Object.keys(a).length>0){const o={useGrouping:!1,...r};r.padTo>0&&(o.minimumIntegerDigits=r.padTo),this.inf=Rg(e,o)}}format(e){if(this.inf){const n=this.floor?Math.floor(e):e;return this.inf.format(n)}else{const n=this.floor?Math.floor(e):eu(e,3);return ue(n,this.padTo)}}}class bg{constructor(e,n,r){this.opts=r,this.originalZone=void 0;let s;if(this.opts.timeZone)this.dt=e;else if(e.zone.type==="fixed"){const a=-1*(e.offset/60),o=a>=0?`Etc/GMT+${a}`:`Etc/GMT${a}`;e.offset!==0&&Mt.create(o).valid?(s=o,this.dt=e):(s="UTC",this.dt=e.offset===0?e:e.setZone("UTC").plus({minutes:e.offset}),this.originalZone=e.zone)}else e.zone.type==="system"?this.dt=e:e.zone.type==="iana"?(this.dt=e,s=e.zone.name):(s="UTC",this.dt=e.setZone("UTC").plus({minutes:e.offset}),this.originalZone=e.zone);const i={...this.opts};i.timeZone=i.timeZone||s,this.dtf=Yo(n,i)}format(){return this.originalZone?this.formatToParts().map(({value:e})=>e).join(""):this.dtf.format(this.dt.toJSDate())}formatToParts(){const e=this.dtf.formatToParts(this.dt.toJSDate());return this.originalZone?e.map(n=>{if(n.type==="timeZoneName"){const r=this.originalZone.offsetName(this.dt.ts,{locale:this.dt.locale,format:this.opts.timeZoneName});return{...n,value:r}}else return n}):e}resolvedOptions(){return this.dtf.resolvedOptions()}}class Ug{constructor(e,n,r){this.opts={style:"long",...r},!n&&zh()&&(this.rtf=Dg(e,r))}format(e,n){return this.rtf?this.rtf.format(e,n):sy(n,e,this.opts.numeric,this.opts.style!=="long")}formatToParts(e,n){return this.rtf?this.rtf.formatToParts(e,n):[]}}class Y{static fromOpts(e){return Y.create(e.locale,e.numberingSystem,e.outputCalendar,e.defaultToEN)}static create(e,n,r,s=!1){const i=e||le.defaultLocale,a=i||(s?"en-US":Ig()),o=n||le.defaultNumberingSystem,l=r||le.defaultOutputCalendar;return new Y(a,o,l,i)}static resetCache(){Fr=null,Qo={},Ko={},Go={}}static fromObject({locale:e,numberingSystem:n,outputCalendar:r}={}){return Y.create(e,n,r)}constructor(e,n,r,s){const[i,a,o]=Mg(e);this.locale=i,this.numberingSystem=n||a||null,this.outputCalendar=r||o||null,this.intl=Lg(this.locale,this.numberingSystem,this.outputCalendar),this.weekdaysCache={format:{},standalone:{}},this.monthsCache={format:{},standalone:{}},this.meridiemCache=null,this.eraCache={},this.specifiedLocale=s,this.fastNumbersCached=null}get fastNumbers(){return this.fastNumbersCached==null&&(this.fastNumbersCached=zg(this)),this.fastNumbersCached}listingMode(){const e=this.isEnglish(),n=(this.numberingSystem===null||this.numberingSystem==="latn")&&(this.outputCalendar===null||this.outputCalendar==="gregory");return e&&n?"en":"intl"}clone(e){return!e||Object.getOwnPropertyNames(e).length===0?this:Y.create(e.locale||this.specifiedLocale,e.numberingSystem||this.numberingSystem,e.outputCalendar||this.outputCalendar,e.defaultToEN||!1)}redefaultToEN(e={}){return this.clone({...e,defaultToEN:!0})}redefaultToSystem(e={}){return this.clone({...e,defaultToEN:!1})}months(e,n=!1,r=!0){return Vs(this,e,r,Vh,()=>{const s=n?{month:e,day:"numeric"}:{month:e},i=n?"format":"standalone";return this.monthsCache[i][e]||(this.monthsCache[i][e]=Ag(a=>this.extract(a,s,"month"))),this.monthsCache[i][e]})}weekdays(e,n=!1,r=!0){return Vs(this,e,r,Wh,()=>{const s=n?{weekday:e,year:"numeric",month:"long",day:"numeric"}:{weekday:e},i=n?"format":"standalone";return this.weekdaysCache[i][e]||(this.weekdaysCache[i][e]=Fg(a=>this.extract(a,s,"weekday"))),this.weekdaysCache[i][e]})}meridiems(e=!0){return Vs(this,void 0,e,()=>Bh,()=>{if(!this.meridiemCache){const n={hour:"numeric",hourCycle:"h12"};this.meridiemCache=[M.utc(2016,11,13,9),M.utc(2016,11,13,19)].map(r=>this.extract(r,n,"dayperiod"))}return this.meridiemCache})}eras(e,n=!0){return Vs(this,e,n,Zh,()=>{const r={era:e};return this.eraCache[e]||(this.eraCache[e]=[M.utc(-40,1,1),M.utc(2017,1,1)].map(s=>this.extract(s,r,"era"))),this.eraCache[e]})}extract(e,n,r){const s=this.dtFormatter(e,n),i=s.formatToParts(),a=i.find(o=>o.type.toLowerCase()===r);return a?a.value:null}numberFormatter(e={}){return new $g(this.intl,e.forceSimple||this.fastNumbers,e)}dtFormatter(e,n={}){return new bg(e,this.intl,n)}relFormatter(e={}){return new Ug(this.intl,this.isEnglish(),e)}listFormatter(e={}){return Pg(this.intl,e)}isEnglish(){return this.locale==="en"||this.locale.toLowerCase()==="en-us"||new Intl.DateTimeFormat(this.intl).resolvedOptions().locale.startsWith("en-us")}equals(e){return this.locale===e.locale&&this.numberingSystem===e.numberingSystem&&this.outputCalendar===e.outputCalendar}}let Ua=null;class _e extends gs{static get utcInstance(){return Ua===null&&(Ua=new _e(0)),Ua}static instance(e){return e===0?_e.utcInstance:new _e(e)}static parseSpecifier(e){if(e){const n=e.match(/^utc(?:([+-]\d{1,2})(?::(\d{2}))?)?$/i);if(n)return new _e(aa(n[1],n[2]))}return null}constructor(e){super(),this.fixed=e}get type(){return"fixed"}get name(){return this.fixed===0?"UTC":`UTC${Qr(this.fixed,"narrow")}`}get ianaName(){return this.fixed===0?"Etc/UTC":`Etc/GMT${Qr(-this.fixed,"narrow")}`}offsetName(){return this.name}formatOffset(e,n){return Qr(this.fixed,n)}get isUniversal(){return!0}offset(){return this.fixed}equals(e){return e.type==="fixed"&&e.fixed===this.fixed}get isValid(){return!0}}class Vg extends gs{constructor(e){super(),this.zoneName=e}get type(){return"invalid"}get name(){return this.zoneName}get isUniversal(){return!1}offsetName(){return null}formatOffset(){return""}offset(){return NaN}equals(){return!1}get isValid(){return!1}}function Bt(t,e){if(z(t)||t===null)return e;if(t instanceof gs)return t;if(Hg(t)){const n=t.toLowerCase();return n==="default"?e:n==="local"||n==="system"?sa.instance:n==="utc"||n==="gmt"?_e.utcInstance:_e.parseSpecifier(n)||Mt.create(t)}else return En(t)?_e.instance(t):typeof t=="object"&&t.offset&&typeof t.offset=="number"?t:new Vg(t)}let wc=()=>Date.now(),xc="system",Sc=null,kc=null,Ec=null,Tc=60,Nc;class le{static get now(){return wc}static set now(e){wc=e}static set defaultZone(e){xc=e}static get defaultZone(){return Bt(xc,sa.instance)}static get defaultLocale(){return Sc}static set defaultLocale(e){Sc=e}static get defaultNumberingSystem(){return kc}static set defaultNumberingSystem(e){kc=e}static get defaultOutputCalendar(){return Ec}static set defaultOutputCalendar(e){Ec=e}static get twoDigitCutoffYear(){return Tc}static set twoDigitCutoffYear(e){Tc=e%100}static get throwOnInvalid(){return Nc}static set throwOnInvalid(e){Nc=e}static resetCaches(){Y.resetCache(),Mt.resetCache()}}function z(t){return typeof t>"u"}function En(t){return typeof t=="number"}function ia(t){return typeof t=="number"&&t%1===0}function Hg(t){return typeof t=="string"}function qg(t){return Object.prototype.toString.call(t)==="[object Date]"}function zh(){try{return typeof Intl<"u"&&!!Intl.RelativeTimeFormat}catch{return!1}}function Wg(t){return Array.isArray(t)?t:[t]}function Cc(t,e,n){if(t.length!==0)return t.reduce((r,s)=>{const i=[e(s),s];return r&&n(r[0],i[0])===r[0]?r:i},null)[1]}function Bg(t,e){return e.reduce((n,r)=>(n[r]=t[r],n),{})}function dr(t,e){return Object.prototype.hasOwnProperty.call(t,e)}function _t(t,e,n){return ia(t)&&t>=e&&t<=n}function Zg(t,e){return t-e*Math.floor(t/e)}function ue(t,e=2){const n=t<0;let r;return n?r="-"+(""+-t).padStart(e,"0"):r=(""+t).padStart(e,"0"),r}function Ht(t){if(!(z(t)||t===null||t===""))return parseInt(t,10)}function mn(t){if(!(z(t)||t===null||t===""))return parseFloat(t)}function Xl(t){if(!(z(t)||t===null||t==="")){const e=parseFloat("0."+t)*1e3;return Math.floor(e)}}function eu(t,e,n=!1){const r=10**e;return(n?Math.trunc:Math.round)(t*r)/r}function ys(t){return t%4===0&&(t%100!==0||t%400===0)}function Zr(t){return ys(t)?366:365}function Fi(t,e){const n=Zg(e-1,12)+1,r=t+(e-n)/12;return n===2?ys(r)?29:28:[31,null,31,30,31,30,31,31,30,31,30,31][n-1]}function tu(t){let e=Date.UTC(t.year,t.month-1,t.day,t.hour,t.minute,t.second,t.millisecond);return t.year<100&&t.year>=0&&(e=new Date(e),e.setUTCFullYear(t.year,t.month-1,t.day)),+e}function zi(t){const e=(t+Math.floor(t/4)-Math.floor(t/100)+Math.floor(t/400))%7,n=t-1,r=(n+Math.floor(n/4)-Math.floor(n/100)+Math.floor(n/400))%7;return e===4||r===3?53:52}function Jo(t){return t>99?t:t>le.twoDigitCutoffYear?1900+t:2e3+t}function $h(t,e,n,r=null){const s=new Date(t),i={hourCycle:"h23",year:"numeric",month:"2-digit",day:"2-digit",hour:"2-digit",minute:"2-digit"};r&&(i.timeZone=r);const a={timeZoneName:e,...i},o=new Intl.DateTimeFormat(n,a).formatToParts(s).find(l=>l.type.toLowerCase()==="timezonename");return o?o.value:null}function aa(t,e){let n=parseInt(t,10);Number.isNaN(n)&&(n=0);const r=parseInt(e,10)||0,s=n<0||Object.is(n,-0)?-r:r;return n*60+s}function bh(t){const e=Number(t);if(typeof t=="boolean"||t===""||Number.isNaN(e))throw new Ke(`Invalid unit value ${t}`);return e}function $i(t,e){const n={};for(const r in t)if(dr(t,r)){const s=t[r];if(s==null)continue;n[e(r)]=bh(s)}return n}function Qr(t,e){const n=Math.trunc(Math.abs(t/60)),r=Math.trunc(Math.abs(t%60)),s=t>=0?"+":"-";switch(e){case"short":return`${s}${ue(n,2)}:${ue(r,2)}`;case"narrow":return`${s}${n}${r>0?`:${r}`:""}`;case"techie":return`${s}${ue(n,2)}${ue(r,2)}`;default:throw new RangeError(`Value format ${e} is out of range for property format`)}}function oa(t){return Bg(t,["hour","minute","second","millisecond"])}const Qg=["January","February","March","April","May","June","July","August","September","October","November","December"],Uh=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],Yg=["J","F","M","A","M","J","J","A","S","O","N","D"];function Vh(t){switch(t){case"narrow":return[...Yg];case"short":return[...Uh];case"long":return[...Qg];case"numeric":return["1","2","3","4","5","6","7","8","9","10","11","12"];case"2-digit":return["01","02","03","04","05","06","07","08","09","10","11","12"];default:return null}}const Hh=["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],qh=["Mon","Tue","Wed","Thu","Fri","Sat","Sun"],Kg=["M","T","W","T","F","S","S"];function Wh(t){switch(t){case"narrow":return[...Kg];case"short":return[...qh];case"long":return[...Hh];case"numeric":return["1","2","3","4","5","6","7"];default:return null}}const Bh=["AM","PM"],Gg=["Before Christ","Anno Domini"],Jg=["BC","AD"],Xg=["B","A"];function Zh(t){switch(t){case"narrow":return[...Xg];case"short":return[...Jg];case"long":return[...Gg];default:return null}}function ey(t){return Bh[t.hour<12?0:1]}function ty(t,e){return Wh(e)[t.weekday-1]}function ny(t,e){return Vh(e)[t.month-1]}function ry(t,e){return Zh(e)[t.year<0?0:1]}function sy(t,e,n="always",r=!1){const s={years:["year","yr."],quarters:["quarter","qtr."],months:["month","mo."],weeks:["week","wk."],days:["day","day","days"],hours:["hour","hr."],minutes:["minute","min."],seconds:["second","sec."]},i=["hours","minutes","seconds"].indexOf(t)===-1;if(n==="auto"&&i){const d=t==="days";switch(e){case 1:return d?"tomorrow":`next ${s[t][0]}`;case-1:return d?"yesterday":`last ${s[t][0]}`;case 0:return d?"today":`this ${s[t][0]}`}}const a=Object.is(e,-0)||e<0,o=Math.abs(e),l=o===1,c=s[t],f=r?l?c[1]:c[2]||c[1]:l?s[t][0]:t;return a?`${o} ${f} ago`:`in ${o} ${f}`}function jc(t,e){let n="";for(const r of t)r.literal?n+=r.val:n+=e(r.val);return n}const iy={D:Ai,DD:wh,DDD:xh,DDDD:Sh,t:kh,tt:Eh,ttt:Th,tttt:Nh,T:Ch,TT:jh,TTT:_h,TTTT:Oh,f:Ph,ff:Dh,fff:Mh,ffff:Ah,F:Rh,FF:Ih,FFF:Lh,FFFF:Fh};class Te{static create(e,n={}){return new Te(e,n)}static parseFormat(e){let n=null,r="",s=!1;const i=[];for(let a=0;a0&&i.push({literal:s||/^\s+$/.test(r),val:r}),n=null,r="",s=!s):s||o===n?r+=o:(r.length>0&&i.push({literal:/^\s+$/.test(r),val:r}),r=o,n=o)}return r.length>0&&i.push({literal:s||/^\s+$/.test(r),val:r}),i}static macroTokenToFormatOpts(e){return iy[e]}constructor(e,n){this.opts=n,this.loc=e,this.systemLoc=null}formatWithSystemDefault(e,n){return this.systemLoc===null&&(this.systemLoc=this.loc.redefaultToSystem()),this.systemLoc.dtFormatter(e,{...this.opts,...n}).format()}formatDateTime(e,n={}){return this.loc.dtFormatter(e,{...this.opts,...n}).format()}formatDateTimeParts(e,n={}){return this.loc.dtFormatter(e,{...this.opts,...n}).formatToParts()}formatInterval(e,n={}){return this.loc.dtFormatter(e.start,{...this.opts,...n}).dtf.formatRange(e.start.toJSDate(),e.end.toJSDate())}resolvedOptions(e,n={}){return this.loc.dtFormatter(e,{...this.opts,...n}).resolvedOptions()}num(e,n=0){if(this.opts.forceSimple)return ue(e,n);const r={...this.opts};return n>0&&(r.padTo=n),this.loc.numberFormatter(r).format(e)}formatDateTimeFromString(e,n){const r=this.loc.listingMode()==="en",s=this.loc.outputCalendar&&this.loc.outputCalendar!=="gregory",i=(y,w)=>this.loc.extract(e,y,w),a=y=>e.isOffsetFixed&&e.offset===0&&y.allowZ?"Z":e.isValid?e.zone.formatOffset(e.ts,y.format):"",o=()=>r?ey(e):i({hour:"numeric",hourCycle:"h12"},"dayperiod"),l=(y,w)=>r?ny(e,y):i(w?{month:y}:{month:y,day:"numeric"},"month"),c=(y,w)=>r?ty(e,y):i(w?{weekday:y}:{weekday:y,month:"long",day:"numeric"},"weekday"),f=y=>{const w=Te.macroTokenToFormatOpts(y);return w?this.formatWithSystemDefault(e,w):y},d=y=>r?ry(e,y):i({era:y},"era"),v=y=>{switch(y){case"S":return this.num(e.millisecond);case"u":case"SSS":return this.num(e.millisecond,3);case"s":return this.num(e.second);case"ss":return this.num(e.second,2);case"uu":return this.num(Math.floor(e.millisecond/10),2);case"uuu":return this.num(Math.floor(e.millisecond/100));case"m":return this.num(e.minute);case"mm":return this.num(e.minute,2);case"h":return this.num(e.hour%12===0?12:e.hour%12);case"hh":return this.num(e.hour%12===0?12:e.hour%12,2);case"H":return this.num(e.hour);case"HH":return this.num(e.hour,2);case"Z":return a({format:"narrow",allowZ:this.opts.allowZ});case"ZZ":return a({format:"short",allowZ:this.opts.allowZ});case"ZZZ":return a({format:"techie",allowZ:this.opts.allowZ});case"ZZZZ":return e.zone.offsetName(e.ts,{format:"short",locale:this.loc.locale});case"ZZZZZ":return e.zone.offsetName(e.ts,{format:"long",locale:this.loc.locale});case"z":return e.zoneName;case"a":return o();case"d":return s?i({day:"numeric"},"day"):this.num(e.day);case"dd":return s?i({day:"2-digit"},"day"):this.num(e.day,2);case"c":return this.num(e.weekday);case"ccc":return c("short",!0);case"cccc":return c("long",!0);case"ccccc":return c("narrow",!0);case"E":return this.num(e.weekday);case"EEE":return c("short",!1);case"EEEE":return c("long",!1);case"EEEEE":return c("narrow",!1);case"L":return s?i({month:"numeric",day:"numeric"},"month"):this.num(e.month);case"LL":return s?i({month:"2-digit",day:"numeric"},"month"):this.num(e.month,2);case"LLL":return l("short",!0);case"LLLL":return l("long",!0);case"LLLLL":return l("narrow",!0);case"M":return s?i({month:"numeric"},"month"):this.num(e.month);case"MM":return s?i({month:"2-digit"},"month"):this.num(e.month,2);case"MMM":return l("short",!1);case"MMMM":return l("long",!1);case"MMMMM":return l("narrow",!1);case"y":return s?i({year:"numeric"},"year"):this.num(e.year);case"yy":return s?i({year:"2-digit"},"year"):this.num(e.year.toString().slice(-2),2);case"yyyy":return s?i({year:"numeric"},"year"):this.num(e.year,4);case"yyyyyy":return s?i({year:"numeric"},"year"):this.num(e.year,6);case"G":return d("short");case"GG":return d("long");case"GGGGG":return d("narrow");case"kk":return this.num(e.weekYear.toString().slice(-2),2);case"kkkk":return this.num(e.weekYear,4);case"W":return this.num(e.weekNumber);case"WW":return this.num(e.weekNumber,2);case"o":return this.num(e.ordinal);case"ooo":return this.num(e.ordinal,3);case"q":return this.num(e.quarter);case"qq":return this.num(e.quarter,2);case"X":return this.num(Math.floor(e.ts/1e3));case"x":return this.num(e.ts);default:return f(y)}};return jc(Te.parseFormat(n),v)}formatDurationFromString(e,n){const r=l=>{switch(l[0]){case"S":return"millisecond";case"s":return"second";case"m":return"minute";case"h":return"hour";case"d":return"day";case"w":return"week";case"M":return"month";case"y":return"year";default:return null}},s=l=>c=>{const f=r(c);return f?this.num(l.get(f),c.length):c},i=Te.parseFormat(n),a=i.reduce((l,{literal:c,val:f})=>c?l:l.concat(f),[]),o=e.shiftTo(...a.map(r).filter(l=>l));return jc(i,s(o))}}class ct{constructor(e,n){this.reason=e,this.explanation=n}toMessage(){return this.explanation?`${this.reason}: ${this.explanation}`:this.reason}}const Qh=/[A-Za-z_+-]{1,256}(?::?\/[A-Za-z0-9_+-]{1,256}(?:\/[A-Za-z0-9_+-]{1,256})?)?/;function vr(...t){const e=t.reduce((n,r)=>n+r.source,"");return RegExp(`^${e}$`)}function gr(...t){return e=>t.reduce(([n,r,s],i)=>{const[a,o,l]=i(e,s);return[{...n,...a},o||r,l]},[{},null,1]).slice(0,2)}function yr(t,...e){if(t==null)return[null,null];for(const[n,r]of e){const s=n.exec(t);if(s)return r(s)}return[null,null]}function Yh(...t){return(e,n)=>{const r={};let s;for(s=0;sy!==void 0&&(w||y&&f)?-y:y;return[{years:v(mn(n)),months:v(mn(r)),weeks:v(mn(s)),days:v(mn(i)),hours:v(mn(a)),minutes:v(mn(o)),seconds:v(mn(l),l==="-0"),milliseconds:v(Xl(c),d)}]}const yy={GMT:0,EDT:-4*60,EST:-5*60,CDT:-5*60,CST:-6*60,MDT:-6*60,MST:-7*60,PDT:-7*60,PST:-8*60};function su(t,e,n,r,s,i,a){const o={year:e.length===2?Jo(Ht(e)):Ht(e),month:Uh.indexOf(n)+1,day:Ht(r),hour:Ht(s),minute:Ht(i)};return a&&(o.second=Ht(a)),t&&(o.weekday=t.length>3?Hh.indexOf(t)+1:qh.indexOf(t)+1),o}const wy=/^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|(?:([+-]\d\d)(\d\d)))$/;function xy(t){const[,e,n,r,s,i,a,o,l,c,f,d]=t,v=su(e,s,r,n,i,a,o);let y;return l?y=yy[l]:c?y=0:y=aa(f,d),[v,new _e(y)]}function Sy(t){return t.replace(/\([^()]*\)|[\n\t]/g," ").replace(/(\s\s+)/g," ").trim()}const ky=/^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), (\d\d) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{4}) (\d\d):(\d\d):(\d\d) GMT$/,Ey=/^(Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (\d\d)-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\d\d) (\d\d):(\d\d):(\d\d) GMT$/,Ty=/^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ( \d|\d\d) (\d\d):(\d\d):(\d\d) (\d{4})$/;function _c(t){const[,e,n,r,s,i,a,o]=t;return[su(e,s,r,n,i,a,o),_e.utcInstance]}function Ny(t){const[,e,n,r,s,i,a,o]=t;return[su(e,o,n,r,s,i,a),_e.utcInstance]}const Cy=vr(oy,ru),jy=vr(ly,ru),_y=vr(uy,ru),Oy=vr(Gh),Xh=gr(my,wr,ws,xs),Py=gr(cy,wr,ws,xs),Ry=gr(dy,wr,ws,xs),Dy=gr(wr,ws,xs);function Iy(t){return yr(t,[Cy,Xh],[jy,Py],[_y,Ry],[Oy,Dy])}function My(t){return yr(Sy(t),[wy,xy])}function Ly(t){return yr(t,[ky,_c],[Ey,_c],[Ty,Ny])}function Ay(t){return yr(t,[vy,gy])}const Fy=gr(wr);function zy(t){return yr(t,[py,Fy])}const $y=vr(fy,hy),by=vr(Jh),Uy=gr(wr,ws,xs);function Vy(t){return yr(t,[$y,Xh],[by,Uy])}const Hy="Invalid Duration",em={weeks:{days:7,hours:7*24,minutes:7*24*60,seconds:7*24*60*60,milliseconds:7*24*60*60*1e3},days:{hours:24,minutes:24*60,seconds:24*60*60,milliseconds:24*60*60*1e3},hours:{minutes:60,seconds:60*60,milliseconds:60*60*1e3},minutes:{seconds:60,milliseconds:60*1e3},seconds:{milliseconds:1e3}},qy={years:{quarters:4,months:12,weeks:52,days:365,hours:365*24,minutes:365*24*60,seconds:365*24*60*60,milliseconds:365*24*60*60*1e3},quarters:{months:3,weeks:13,days:91,hours:91*24,minutes:91*24*60,seconds:91*24*60*60,milliseconds:91*24*60*60*1e3},months:{weeks:4,days:30,hours:30*24,minutes:30*24*60,seconds:30*24*60*60,milliseconds:30*24*60*60*1e3},...em},Be=146097/400,In=146097/4800,Wy={years:{quarters:4,months:12,weeks:Be/7,days:Be,hours:Be*24,minutes:Be*24*60,seconds:Be*24*60*60,milliseconds:Be*24*60*60*1e3},quarters:{months:3,weeks:Be/28,days:Be/4,hours:Be*24/4,minutes:Be*24*60/4,seconds:Be*24*60*60/4,milliseconds:Be*24*60*60*1e3/4},months:{weeks:In/7,days:In,hours:In*24,minutes:In*24*60,seconds:In*24*60*60,milliseconds:In*24*60*60*1e3},...em},gn=["years","quarters","months","weeks","days","hours","minutes","seconds","milliseconds"],By=gn.slice(0).reverse();function bt(t,e,n=!1){const r={values:n?e.values:{...t.values,...e.values||{}},loc:t.loc.clone(e.loc),conversionAccuracy:e.conversionAccuracy||t.conversionAccuracy,matrix:e.matrix||t.matrix};return new b(r)}function Zy(t){return t<0?Math.floor(t):Math.ceil(t)}function tm(t,e,n,r,s){const i=t[s][n],a=e[n]/i,o=Math.sign(a)===Math.sign(r[s]),l=!o&&r[s]!==0&&Math.abs(a)<=1?Zy(a):Math.trunc(a);r[s]+=l,e[n]-=l*i}function Qy(t,e){By.reduce((n,r)=>z(e[r])?n:(n&&tm(t,e,n,e,r),r),null)}function Yy(t){const e={};for(const[n,r]of Object.entries(t))r!==0&&(e[n]=r);return e}class b{constructor(e){const n=e.conversionAccuracy==="longterm"||!1;let r=n?Wy:qy;e.matrix&&(r=e.matrix),this.values=e.values,this.loc=e.loc||Y.create(),this.conversionAccuracy=n?"longterm":"casual",this.invalid=e.invalid||null,this.matrix=r,this.isLuxonDuration=!0}static fromMillis(e,n){return b.fromObject({milliseconds:e},n)}static fromObject(e,n={}){if(e==null||typeof e!="object")throw new Ke(`Duration.fromObject: argument expected to be an object, got ${e===null?"null":typeof e}`);return new b({values:$i(e,b.normalizeUnit),loc:Y.fromObject(n),conversionAccuracy:n.conversionAccuracy,matrix:n.matrix})}static fromDurationLike(e){if(En(e))return b.fromMillis(e);if(b.isDuration(e))return e;if(typeof e=="object")return b.fromObject(e);throw new Ke(`Unknown duration argument ${e} of type ${typeof e}`)}static fromISO(e,n){const[r]=Ay(e);return r?b.fromObject(r,n):b.invalid("unparsable",`the input "${e}" can't be parsed as ISO 8601`)}static fromISOTime(e,n){const[r]=zy(e);return r?b.fromObject(r,n):b.invalid("unparsable",`the input "${e}" can't be parsed as ISO 8601`)}static invalid(e,n=null){if(!e)throw new Ke("need to specify a reason the Duration is invalid");const r=e instanceof ct?e:new ct(e,n);if(le.throwOnInvalid)throw new Eg(r);return new b({invalid:r})}static normalizeUnit(e){const n={year:"years",years:"years",quarter:"quarters",quarters:"quarters",month:"months",months:"months",week:"weeks",weeks:"weeks",day:"days",days:"days",hour:"hours",hours:"hours",minute:"minutes",minutes:"minutes",second:"seconds",seconds:"seconds",millisecond:"milliseconds",milliseconds:"milliseconds"}[e&&e.toLowerCase()];if(!n)throw new yh(e);return n}static isDuration(e){return e&&e.isLuxonDuration||!1}get locale(){return this.isValid?this.loc.locale:null}get numberingSystem(){return this.isValid?this.loc.numberingSystem:null}toFormat(e,n={}){const r={...n,floor:n.round!==!1&&n.floor!==!1};return this.isValid?Te.create(this.loc,r).formatDurationFromString(this,e):Hy}toHuman(e={}){const n=gn.map(r=>{const s=this.values[r];return z(s)?null:this.loc.numberFormatter({style:"unit",unitDisplay:"long",...e,unit:r.slice(0,-1)}).format(s)}).filter(r=>r);return this.loc.listFormatter({type:"conjunction",style:e.listStyle||"narrow",...e}).format(n)}toObject(){return this.isValid?{...this.values}:{}}toISO(){if(!this.isValid)return null;let e="P";return this.years!==0&&(e+=this.years+"Y"),(this.months!==0||this.quarters!==0)&&(e+=this.months+this.quarters*3+"M"),this.weeks!==0&&(e+=this.weeks+"W"),this.days!==0&&(e+=this.days+"D"),(this.hours!==0||this.minutes!==0||this.seconds!==0||this.milliseconds!==0)&&(e+="T"),this.hours!==0&&(e+=this.hours+"H"),this.minutes!==0&&(e+=this.minutes+"M"),(this.seconds!==0||this.milliseconds!==0)&&(e+=eu(this.seconds+this.milliseconds/1e3,3)+"S"),e==="P"&&(e+="T0S"),e}toISOTime(e={}){if(!this.isValid)return null;const n=this.toMillis();if(n<0||n>=864e5)return null;e={suppressMilliseconds:!1,suppressSeconds:!1,includePrefix:!1,format:"extended",...e};const r=this.shiftTo("hours","minutes","seconds","milliseconds");let s=e.format==="basic"?"hhmm":"hh:mm";(!e.suppressSeconds||r.seconds!==0||r.milliseconds!==0)&&(s+=e.format==="basic"?"ss":":ss",(!e.suppressMilliseconds||r.milliseconds!==0)&&(s+=".SSS"));let i=r.toFormat(s);return e.includePrefix&&(i="T"+i),i}toJSON(){return this.toISO()}toString(){return this.toISO()}toMillis(){return this.as("milliseconds")}valueOf(){return this.toMillis()}plus(e){if(!this.isValid)return this;const n=b.fromDurationLike(e),r={};for(const s of gn)(dr(n.values,s)||dr(this.values,s))&&(r[s]=n.get(s)+this.get(s));return bt(this,{values:r},!0)}minus(e){if(!this.isValid)return this;const n=b.fromDurationLike(e);return this.plus(n.negate())}mapUnits(e){if(!this.isValid)return this;const n={};for(const r of Object.keys(this.values))n[r]=bh(e(this.values[r],r));return bt(this,{values:n},!0)}get(e){return this[b.normalizeUnit(e)]}set(e){if(!this.isValid)return this;const n={...this.values,...$i(e,b.normalizeUnit)};return bt(this,{values:n})}reconfigure({locale:e,numberingSystem:n,conversionAccuracy:r,matrix:s}={}){const a={loc:this.loc.clone({locale:e,numberingSystem:n}),matrix:s,conversionAccuracy:r};return bt(this,a)}as(e){return this.isValid?this.shiftTo(e).get(e):NaN}normalize(){if(!this.isValid)return this;const e=this.toObject();return Qy(this.matrix,e),bt(this,{values:e},!0)}rescale(){if(!this.isValid)return this;const e=Yy(this.normalize().shiftToAll().toObject());return bt(this,{values:e},!0)}shiftTo(...e){if(!this.isValid)return this;if(e.length===0)return this;e=e.map(a=>b.normalizeUnit(a));const n={},r={},s=this.toObject();let i;for(const a of gn)if(e.indexOf(a)>=0){i=a;let o=0;for(const c in r)o+=this.matrix[c][a]*r[c],r[c]=0;En(s[a])&&(o+=s[a]);const l=Math.trunc(o);n[a]=l,r[a]=(o*1e3-l*1e3)/1e3;for(const c in s)gn.indexOf(c)>gn.indexOf(a)&&tm(this.matrix,s,c,n,a)}else En(s[a])&&(r[a]=s[a]);for(const a in r)r[a]!==0&&(n[i]+=a===i?r[a]:r[a]/this.matrix[i][a]);return bt(this,{values:n},!0).normalize()}shiftToAll(){return this.isValid?this.shiftTo("years","months","weeks","days","hours","minutes","seconds","milliseconds"):this}negate(){if(!this.isValid)return this;const e={};for(const n of Object.keys(this.values))e[n]=this.values[n]===0?0:-this.values[n];return bt(this,{values:e},!0)}get years(){return this.isValid?this.values.years||0:NaN}get quarters(){return this.isValid?this.values.quarters||0:NaN}get months(){return this.isValid?this.values.months||0:NaN}get weeks(){return this.isValid?this.values.weeks||0:NaN}get days(){return this.isValid?this.values.days||0:NaN}get hours(){return this.isValid?this.values.hours||0:NaN}get minutes(){return this.isValid?this.values.minutes||0:NaN}get seconds(){return this.isValid?this.values.seconds||0:NaN}get milliseconds(){return this.isValid?this.values.milliseconds||0:NaN}get isValid(){return this.invalid===null}get invalidReason(){return this.invalid?this.invalid.reason:null}get invalidExplanation(){return this.invalid?this.invalid.explanation:null}equals(e){if(!this.isValid||!e.isValid||!this.loc.equals(e.loc))return!1;function n(r,s){return r===void 0||r===0?s===void 0||s===0:r===s}for(const r of gn)if(!n(this.values[r],e.values[r]))return!1;return!0}}const Mn="Invalid Interval";function Ky(t,e){return!t||!t.isValid?ne.invalid("missing or invalid start"):!e||!e.isValid?ne.invalid("missing or invalid end"):ee:!1}isBefore(e){return this.isValid?this.e<=e:!1}contains(e){return this.isValid?this.s<=e&&this.e>e:!1}set({start:e,end:n}={}){return this.isValid?ne.fromDateTimes(e||this.s,n||this.e):this}splitAt(...e){if(!this.isValid)return[];const n=e.map(Rr).filter(a=>this.contains(a)).sort(),r=[];let{s}=this,i=0;for(;s+this.e?this.e:a;r.push(ne.fromDateTimes(s,o)),s=o,i+=1}return r}splitBy(e){const n=b.fromDurationLike(e);if(!this.isValid||!n.isValid||n.as("milliseconds")===0)return[];let{s:r}=this,s=1,i;const a=[];for(;rl*s));i=+o>+this.e?this.e:o,a.push(ne.fromDateTimes(r,i)),r=i,s+=1}return a}divideEqually(e){return this.isValid?this.splitBy(this.length()/e).slice(0,e):[]}overlaps(e){return this.e>e.s&&this.s=e.e:!1}equals(e){return!this.isValid||!e.isValid?!1:this.s.equals(e.s)&&this.e.equals(e.e)}intersection(e){if(!this.isValid)return this;const n=this.s>e.s?this.s:e.s,r=this.e=r?null:ne.fromDateTimes(n,r)}union(e){if(!this.isValid)return this;const n=this.se.e?this.e:e.e;return ne.fromDateTimes(n,r)}static merge(e){const[n,r]=e.sort((s,i)=>s.s-i.s).reduce(([s,i],a)=>i?i.overlaps(a)||i.abutsStart(a)?[s,i.union(a)]:[s.concat([i]),a]:[s,a],[[],null]);return r&&n.push(r),n}static xor(e){let n=null,r=0;const s=[],i=e.map(l=>[{time:l.s,type:"s"},{time:l.e,type:"e"}]),a=Array.prototype.concat(...i),o=a.sort((l,c)=>l.time-c.time);for(const l of o)r+=l.type==="s"?1:-1,r===1?n=l.time:(n&&+n!=+l.time&&s.push(ne.fromDateTimes(n,l.time)),n=null);return ne.merge(s)}difference(...e){return ne.xor([this].concat(e)).map(n=>this.intersection(n)).filter(n=>n&&!n.isEmpty())}toString(){return this.isValid?`[${this.s.toISO()} – ${this.e.toISO()})`:Mn}toLocaleString(e=Ai,n={}){return this.isValid?Te.create(this.s.loc.clone(n),e).formatInterval(this):Mn}toISO(e){return this.isValid?`${this.s.toISO(e)}/${this.e.toISO(e)}`:Mn}toISODate(){return this.isValid?`${this.s.toISODate()}/${this.e.toISODate()}`:Mn}toISOTime(e){return this.isValid?`${this.s.toISOTime(e)}/${this.e.toISOTime(e)}`:Mn}toFormat(e,{separator:n=" – "}={}){return this.isValid?`${this.s.toFormat(e)}${n}${this.e.toFormat(e)}`:Mn}toDuration(e,n){return this.isValid?this.e.diff(this.s,e,n):b.invalid(this.invalidReason)}mapEndpoints(e){return ne.fromDateTimes(e(this.s),e(this.e))}}class Hs{static hasDST(e=le.defaultZone){const n=M.now().setZone(e).set({month:12});return!e.isUniversal&&n.offset!==n.set({month:6}).offset}static isValidIANAZone(e){return Mt.isValidZone(e)}static normalizeZone(e){return Bt(e,le.defaultZone)}static months(e="long",{locale:n=null,numberingSystem:r=null,locObj:s=null,outputCalendar:i="gregory"}={}){return(s||Y.create(n,r,i)).months(e)}static monthsFormat(e="long",{locale:n=null,numberingSystem:r=null,locObj:s=null,outputCalendar:i="gregory"}={}){return(s||Y.create(n,r,i)).months(e,!0)}static weekdays(e="long",{locale:n=null,numberingSystem:r=null,locObj:s=null}={}){return(s||Y.create(n,r,null)).weekdays(e)}static weekdaysFormat(e="long",{locale:n=null,numberingSystem:r=null,locObj:s=null}={}){return(s||Y.create(n,r,null)).weekdays(e,!0)}static meridiems({locale:e=null}={}){return Y.create(e).meridiems()}static eras(e="short",{locale:n=null}={}){return Y.create(n,null,"gregory").eras(e)}static features(){return{relative:zh()}}}function Oc(t,e){const n=s=>s.toUTC(0,{keepLocalTime:!0}).startOf("day").valueOf(),r=n(e)-n(t);return Math.floor(b.fromMillis(r).as("days"))}function Gy(t,e,n){const r=[["years",(l,c)=>c.year-l.year],["quarters",(l,c)=>c.quarter-l.quarter+(c.year-l.year)*4],["months",(l,c)=>c.month-l.month+(c.year-l.year)*12],["weeks",(l,c)=>{const f=Oc(l,c);return(f-f%7)/7}],["days",Oc]],s={},i=t;let a,o;for(const[l,c]of r)n.indexOf(l)>=0&&(a=l,s[l]=c(t,e),o=i.plus(s),o>e?(s[l]--,t=i.plus(s)):t=o);return[t,s,o,a]}function Jy(t,e,n,r){let[s,i,a,o]=Gy(t,e,n);const l=e-s,c=n.filter(d=>["hours","minutes","seconds","milliseconds"].indexOf(d)>=0);c.length===0&&(a0?b.fromMillis(l,r).shiftTo(...c).plus(f):f}const iu={arab:"[٠-٩]",arabext:"[۰-۹]",bali:"[᭐-᭙]",beng:"[০-৯]",deva:"[०-९]",fullwide:"[0-9]",gujr:"[૦-૯]",hanidec:"[〇|一|二|三|四|五|六|七|八|九]",khmr:"[០-៩]",knda:"[೦-೯]",laoo:"[໐-໙]",limb:"[᥆-᥏]",mlym:"[൦-൯]",mong:"[᠐-᠙]",mymr:"[၀-၉]",orya:"[୦-୯]",tamldec:"[௦-௯]",telu:"[౦-౯]",thai:"[๐-๙]",tibt:"[༠-༩]",latn:"\\d"},Pc={arab:[1632,1641],arabext:[1776,1785],bali:[6992,7001],beng:[2534,2543],deva:[2406,2415],fullwide:[65296,65303],gujr:[2790,2799],khmr:[6112,6121],knda:[3302,3311],laoo:[3792,3801],limb:[6470,6479],mlym:[3430,3439],mong:[6160,6169],mymr:[4160,4169],orya:[2918,2927],tamldec:[3046,3055],telu:[3174,3183],thai:[3664,3673],tibt:[3872,3881]},Xy=iu.hanidec.replace(/[\[|\]]/g,"").split("");function e0(t){let e=parseInt(t,10);if(isNaN(e)){e="";for(let n=0;n=i&&r<=a&&(e+=r-i)}}return parseInt(e,10)}else return e}function it({numberingSystem:t},e=""){return new RegExp(`${iu[t||"latn"]}${e}`)}const t0="missing Intl.DateTimeFormat.formatToParts support";function H(t,e=n=>n){return{regex:t,deser:([n])=>e(e0(n))}}const n0=String.fromCharCode(160),nm=`[ ${n0}]`,rm=new RegExp(nm,"g");function r0(t){return t.replace(/\./g,"\\.?").replace(rm,nm)}function Rc(t){return t.replace(/\./g,"").replace(rm," ").toLowerCase()}function at(t,e){return t===null?null:{regex:RegExp(t.map(r0).join("|")),deser:([n])=>t.findIndex(r=>Rc(n)===Rc(r))+e}}function Dc(t,e){return{regex:t,deser:([,n,r])=>aa(n,r),groups:e}}function qs(t){return{regex:t,deser:([e])=>e}}function s0(t){return t.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g,"\\$&")}function i0(t,e){const n=it(e),r=it(e,"{2}"),s=it(e,"{3}"),i=it(e,"{4}"),a=it(e,"{6}"),o=it(e,"{1,2}"),l=it(e,"{1,3}"),c=it(e,"{1,6}"),f=it(e,"{1,9}"),d=it(e,"{2,4}"),v=it(e,"{4,6}"),y=k=>({regex:RegExp(s0(k.val)),deser:([m])=>m,literal:!0}),g=(k=>{if(t.literal)return y(k);switch(k.val){case"G":return at(e.eras("short",!1),0);case"GG":return at(e.eras("long",!1),0);case"y":return H(c);case"yy":return H(d,Jo);case"yyyy":return H(i);case"yyyyy":return H(v);case"yyyyyy":return H(a);case"M":return H(o);case"MM":return H(r);case"MMM":return at(e.months("short",!0,!1),1);case"MMMM":return at(e.months("long",!0,!1),1);case"L":return H(o);case"LL":return H(r);case"LLL":return at(e.months("short",!1,!1),1);case"LLLL":return at(e.months("long",!1,!1),1);case"d":return H(o);case"dd":return H(r);case"o":return H(l);case"ooo":return H(s);case"HH":return H(r);case"H":return H(o);case"hh":return H(r);case"h":return H(o);case"mm":return H(r);case"m":return H(o);case"q":return H(o);case"qq":return H(r);case"s":return H(o);case"ss":return H(r);case"S":return H(l);case"SSS":return H(s);case"u":return qs(f);case"uu":return qs(o);case"uuu":return H(n);case"a":return at(e.meridiems(),0);case"kkkk":return H(i);case"kk":return H(d,Jo);case"W":return H(o);case"WW":return H(r);case"E":case"c":return H(n);case"EEE":return at(e.weekdays("short",!1,!1),1);case"EEEE":return at(e.weekdays("long",!1,!1),1);case"ccc":return at(e.weekdays("short",!0,!1),1);case"cccc":return at(e.weekdays("long",!0,!1),1);case"Z":case"ZZ":return Dc(new RegExp(`([+-]${o.source})(?::(${r.source}))?`),2);case"ZZZ":return Dc(new RegExp(`([+-]${o.source})(${r.source})?`),2);case"z":return qs(/[a-z_+-/]{1,256}?/i);case" ":return qs(/[^\S\n\r]/);default:return y(k)}})(t)||{invalidReason:t0};return g.token=t,g}const a0={year:{"2-digit":"yy",numeric:"yyyyy"},month:{numeric:"M","2-digit":"MM",short:"MMM",long:"MMMM"},day:{numeric:"d","2-digit":"dd"},weekday:{short:"EEE",long:"EEEE"},dayperiod:"a",dayPeriod:"a",hour:{numeric:"h","2-digit":"hh"},minute:{numeric:"m","2-digit":"mm"},second:{numeric:"s","2-digit":"ss"},timeZoneName:{long:"ZZZZZ",short:"ZZZ"}};function o0(t,e){const{type:n,value:r}=t;if(n==="literal"){const a=/^\s+$/.test(r);return{literal:!a,val:a?" ":r}}const s=e[n];let i=a0[n];if(typeof i=="object"&&(i=i[s]),i)return{literal:!1,val:i}}function l0(t){return[`^${t.map(n=>n.regex).reduce((n,r)=>`${n}(${r.source})`,"")}$`,t]}function u0(t,e,n){const r=t.match(e);if(r){const s={};let i=1;for(const a in n)if(dr(n,a)){const o=n[a],l=o.groups?o.groups+1:1;!o.literal&&o.token&&(s[o.token.val[0]]=o.deser(r.slice(i,i+l))),i+=l}return[r,s]}else return[r,{}]}function c0(t){const e=i=>{switch(i){case"S":return"millisecond";case"s":return"second";case"m":return"minute";case"h":case"H":return"hour";case"d":return"day";case"o":return"ordinal";case"L":case"M":return"month";case"y":return"year";case"E":case"c":return"weekday";case"W":return"weekNumber";case"k":return"weekYear";case"q":return"quarter";default:return null}};let n=null,r;return z(t.z)||(n=Mt.create(t.z)),z(t.Z)||(n||(n=new _e(t.Z)),r=t.Z),z(t.q)||(t.M=(t.q-1)*3+1),z(t.h)||(t.h<12&&t.a===1?t.h+=12:t.h===12&&t.a===0&&(t.h=0)),t.G===0&&t.y&&(t.y=-t.y),z(t.u)||(t.S=Xl(t.u)),[Object.keys(t).reduce((i,a)=>{const o=e(a);return o&&(i[o]=t[a]),i},{}),n,r]}let Va=null;function d0(){return Va||(Va=M.fromMillis(1555555555555)),Va}function f0(t,e){if(t.literal)return t;const n=Te.macroTokenToFormatOpts(t.val),r=am(n,e);return r==null||r.includes(void 0)?t:r}function sm(t,e){return Array.prototype.concat(...t.map(n=>f0(n,e)))}function im(t,e,n){const r=sm(Te.parseFormat(n),t),s=r.map(a=>i0(a,t)),i=s.find(a=>a.invalidReason);if(i)return{input:e,tokens:r,invalidReason:i.invalidReason};{const[a,o]=l0(s),l=RegExp(a,"i"),[c,f]=u0(e,l,o),[d,v,y]=f?c0(f):[null,null,void 0];if(dr(f,"a")&&dr(f,"H"))throw new Ar("Can't include meridiem when specifying 24-hour format");return{input:e,tokens:r,regex:l,rawMatches:c,matches:f,result:d,zone:v,specificOffset:y}}}function h0(t,e,n){const{result:r,zone:s,specificOffset:i,invalidReason:a}=im(t,e,n);return[r,s,i,a]}function am(t,e){return t?Te.create(e,t).formatDateTimeParts(d0()).map(s=>o0(s,t)):null}const om=[0,31,59,90,120,151,181,212,243,273,304,334],lm=[0,31,60,91,121,152,182,213,244,274,305,335];function Je(t,e){return new ct("unit out of range",`you specified ${e} (of type ${typeof e}) as a ${t}, which is invalid`)}function um(t,e,n){const r=new Date(Date.UTC(t,e-1,n));t<100&&t>=0&&r.setUTCFullYear(r.getUTCFullYear()-1900);const s=r.getUTCDay();return s===0?7:s}function cm(t,e,n){return n+(ys(t)?lm:om)[e-1]}function dm(t,e){const n=ys(t)?lm:om,r=n.findIndex(i=>izi(e)?(o=e+1,a=1):o=e,{weekYear:o,weekNumber:a,weekday:i,...oa(t)}}function Ic(t){const{weekYear:e,weekNumber:n,weekday:r}=t,s=um(e,1,4),i=Zr(e);let a=n*7+r-s-3,o;a<1?(o=e-1,a+=Zr(o)):a>i?(o=e+1,a-=Zr(e)):o=e;const{month:l,day:c}=dm(o,a);return{year:o,month:l,day:c,...oa(t)}}function Ha(t){const{year:e,month:n,day:r}=t,s=cm(e,n,r);return{year:e,ordinal:s,...oa(t)}}function Mc(t){const{year:e,ordinal:n}=t,{month:r,day:s}=dm(e,n);return{year:e,month:r,day:s,...oa(t)}}function m0(t){const e=ia(t.weekYear),n=_t(t.weekNumber,1,zi(t.weekYear)),r=_t(t.weekday,1,7);return e?n?r?!1:Je("weekday",t.weekday):Je("week",t.week):Je("weekYear",t.weekYear)}function p0(t){const e=ia(t.year),n=_t(t.ordinal,1,Zr(t.year));return e?n?!1:Je("ordinal",t.ordinal):Je("year",t.year)}function fm(t){const e=ia(t.year),n=_t(t.month,1,12),r=_t(t.day,1,Fi(t.year,t.month));return e?n?r?!1:Je("day",t.day):Je("month",t.month):Je("year",t.year)}function hm(t){const{hour:e,minute:n,second:r,millisecond:s}=t,i=_t(e,0,23)||e===24&&n===0&&r===0&&s===0,a=_t(n,0,59),o=_t(r,0,59),l=_t(s,0,999);return i?a?o?l?!1:Je("millisecond",s):Je("second",r):Je("minute",n):Je("hour",e)}const qa="Invalid DateTime",Lc=864e13;function Ws(t){return new ct("unsupported zone",`the zone "${t.name}" is not supported`)}function Wa(t){return t.weekData===null&&(t.weekData=Xo(t.c)),t.weekData}function Or(t,e){const n={ts:t.ts,zone:t.zone,c:t.c,o:t.o,loc:t.loc,invalid:t.invalid};return new M({...n,...e,old:n})}function mm(t,e,n){let r=t-e*60*1e3;const s=n.offset(r);if(e===s)return[r,e];r-=(s-e)*60*1e3;const i=n.offset(r);return s===i?[r,s]:[t-Math.min(s,i)*60*1e3,Math.max(s,i)]}function Ac(t,e){t+=e*60*1e3;const n=new Date(t);return{year:n.getUTCFullYear(),month:n.getUTCMonth()+1,day:n.getUTCDate(),hour:n.getUTCHours(),minute:n.getUTCMinutes(),second:n.getUTCSeconds(),millisecond:n.getUTCMilliseconds()}}function ci(t,e,n){return mm(tu(t),e,n)}function Fc(t,e){const n=t.o,r=t.c.year+Math.trunc(e.years),s=t.c.month+Math.trunc(e.months)+Math.trunc(e.quarters)*3,i={...t.c,year:r,month:s,day:Math.min(t.c.day,Fi(r,s))+Math.trunc(e.days)+Math.trunc(e.weeks)*7},a=b.fromObject({years:e.years-Math.trunc(e.years),quarters:e.quarters-Math.trunc(e.quarters),months:e.months-Math.trunc(e.months),weeks:e.weeks-Math.trunc(e.weeks),days:e.days-Math.trunc(e.days),hours:e.hours,minutes:e.minutes,seconds:e.seconds,milliseconds:e.milliseconds}).as("milliseconds"),o=tu(i);let[l,c]=mm(o,n,t.zone);return a!==0&&(l+=a,c=t.zone.offset(l)),{ts:l,o:c}}function Pr(t,e,n,r,s,i){const{setZone:a,zone:o}=n;if(t&&Object.keys(t).length!==0||e){const l=e||o,c=M.fromObject(t,{...n,zone:l,specificOffset:i});return a?c:c.setZone(o)}else return M.invalid(new ct("unparsable",`the input "${s}" can't be parsed as ${r}`))}function Bs(t,e,n=!0){return t.isValid?Te.create(Y.create("en-US"),{allowZ:n,forceSimple:!0}).formatDateTimeFromString(t,e):null}function Ba(t,e){const n=t.c.year>9999||t.c.year<0;let r="";return n&&t.c.year>=0&&(r+="+"),r+=ue(t.c.year,n?6:4),e?(r+="-",r+=ue(t.c.month),r+="-",r+=ue(t.c.day)):(r+=ue(t.c.month),r+=ue(t.c.day)),r}function zc(t,e,n,r,s,i){let a=ue(t.c.hour);return e?(a+=":",a+=ue(t.c.minute),(t.c.second!==0||!n)&&(a+=":")):a+=ue(t.c.minute),(t.c.second!==0||!n)&&(a+=ue(t.c.second),(t.c.millisecond!==0||!r)&&(a+=".",a+=ue(t.c.millisecond,3))),s&&(t.isOffsetFixed&&t.offset===0&&!i?a+="Z":t.o<0?(a+="-",a+=ue(Math.trunc(-t.o/60)),a+=":",a+=ue(Math.trunc(-t.o%60))):(a+="+",a+=ue(Math.trunc(t.o/60)),a+=":",a+=ue(Math.trunc(t.o%60)))),i&&(a+="["+t.zone.ianaName+"]"),a}const pm={month:1,day:1,hour:0,minute:0,second:0,millisecond:0},v0={weekNumber:1,weekday:1,hour:0,minute:0,second:0,millisecond:0},g0={ordinal:1,hour:0,minute:0,second:0,millisecond:0},vm=["year","month","day","hour","minute","second","millisecond"],y0=["weekYear","weekNumber","weekday","hour","minute","second","millisecond"],w0=["year","ordinal","hour","minute","second","millisecond"];function $c(t){const e={year:"year",years:"year",month:"month",months:"month",day:"day",days:"day",hour:"hour",hours:"hour",minute:"minute",minutes:"minute",quarter:"quarter",quarters:"quarter",second:"second",seconds:"second",millisecond:"millisecond",milliseconds:"millisecond",weekday:"weekday",weekdays:"weekday",weeknumber:"weekNumber",weeksnumber:"weekNumber",weeknumbers:"weekNumber",weekyear:"weekYear",weekyears:"weekYear",ordinal:"ordinal"}[t.toLowerCase()];if(!e)throw new yh(t);return e}function bc(t,e){const n=Bt(e.zone,le.defaultZone),r=Y.fromObject(e),s=le.now();let i,a;if(z(t.year))i=s;else{for(const c of vm)z(t[c])&&(t[c]=pm[c]);const o=fm(t)||hm(t);if(o)return M.invalid(o);const l=n.offset(s);[i,a]=ci(t,l,n)}return new M({ts:i,zone:n,loc:r,o:a})}function Uc(t,e,n){const r=z(n.round)?!0:n.round,s=(a,o)=>(a=eu(a,r||n.calendary?0:2,!0),e.loc.clone(n).relFormatter(n).format(a,o)),i=a=>n.calendary?e.hasSame(t,a)?0:e.startOf(a).diff(t.startOf(a),a).get(a):e.diff(t,a).get(a);if(n.unit)return s(i(n.unit),n.unit);for(const a of n.units){const o=i(a);if(Math.abs(o)>=1)return s(o,a)}return s(t>e?-0:0,n.units[n.units.length-1])}function Vc(t){let e={},n;return t.length>0&&typeof t[t.length-1]=="object"?(e=t[t.length-1],n=Array.from(t).slice(0,t.length-1)):n=Array.from(t),[e,n]}class M{constructor(e){const n=e.zone||le.defaultZone;let r=e.invalid||(Number.isNaN(e.ts)?new ct("invalid input"):null)||(n.isValid?null:Ws(n));this.ts=z(e.ts)?le.now():e.ts;let s=null,i=null;if(!r)if(e.old&&e.old.ts===this.ts&&e.old.zone.equals(n))[s,i]=[e.old.c,e.old.o];else{const o=n.offset(this.ts);s=Ac(this.ts,o),r=Number.isNaN(s.year)?new ct("invalid input"):null,s=r?null:s,i=r?null:o}this._zone=n,this.loc=e.loc||Y.create(),this.invalid=r,this.weekData=null,this.c=s,this.o=i,this.isLuxonDateTime=!0}static now(){return new M({})}static local(){const[e,n]=Vc(arguments),[r,s,i,a,o,l,c]=n;return bc({year:r,month:s,day:i,hour:a,minute:o,second:l,millisecond:c},e)}static utc(){const[e,n]=Vc(arguments),[r,s,i,a,o,l,c]=n;return e.zone=_e.utcInstance,bc({year:r,month:s,day:i,hour:a,minute:o,second:l,millisecond:c},e)}static fromJSDate(e,n={}){const r=qg(e)?e.valueOf():NaN;if(Number.isNaN(r))return M.invalid("invalid input");const s=Bt(n.zone,le.defaultZone);return s.isValid?new M({ts:r,zone:s,loc:Y.fromObject(n)}):M.invalid(Ws(s))}static fromMillis(e,n={}){if(En(e))return e<-Lc||e>Lc?M.invalid("Timestamp out of range"):new M({ts:e,zone:Bt(n.zone,le.defaultZone),loc:Y.fromObject(n)});throw new Ke(`fromMillis requires a numerical input, but received a ${typeof e} with value ${e}`)}static fromSeconds(e,n={}){if(En(e))return new M({ts:e*1e3,zone:Bt(n.zone,le.defaultZone),loc:Y.fromObject(n)});throw new Ke("fromSeconds requires a numerical input")}static fromObject(e,n={}){e=e||{};const r=Bt(n.zone,le.defaultZone);if(!r.isValid)return M.invalid(Ws(r));const s=le.now(),i=z(n.specificOffset)?r.offset(s):n.specificOffset,a=$i(e,$c),o=!z(a.ordinal),l=!z(a.year),c=!z(a.month)||!z(a.day),f=l||c,d=a.weekYear||a.weekNumber,v=Y.fromObject(n);if((f||o)&&d)throw new Ar("Can't mix weekYear/weekNumber units with year/month/day or ordinals");if(c&&o)throw new Ar("Can't mix ordinal dates with month/day");const y=d||a.weekday&&!f;let w,g,k=Ac(s,i);y?(w=y0,g=v0,k=Xo(k)):o?(w=w0,g=g0,k=Ha(k)):(w=vm,g=pm);let m=!1;for(const C of w){const D=a[C];z(D)?m?a[C]=g[C]:a[C]=k[C]:m=!0}const h=y?m0(a):o?p0(a):fm(a),p=h||hm(a);if(p)return M.invalid(p);const S=y?Ic(a):o?Mc(a):a,[x,T]=ci(S,i,r),E=new M({ts:x,zone:r,o:T,loc:v});return a.weekday&&f&&e.weekday!==E.weekday?M.invalid("mismatched weekday",`you can't specify both a weekday of ${a.weekday} and a date of ${E.toISO()}`):E}static fromISO(e,n={}){const[r,s]=Iy(e);return Pr(r,s,n,"ISO 8601",e)}static fromRFC2822(e,n={}){const[r,s]=My(e);return Pr(r,s,n,"RFC 2822",e)}static fromHTTP(e,n={}){const[r,s]=Ly(e);return Pr(r,s,n,"HTTP",n)}static fromFormat(e,n,r={}){if(z(e)||z(n))throw new Ke("fromFormat requires an input string and a format");const{locale:s=null,numberingSystem:i=null}=r,a=Y.fromOpts({locale:s,numberingSystem:i,defaultToEN:!0}),[o,l,c,f]=h0(a,e,n);return f?M.invalid(f):Pr(o,l,r,`format ${n}`,e,c)}static fromString(e,n,r={}){return M.fromFormat(e,n,r)}static fromSQL(e,n={}){const[r,s]=Vy(e);return Pr(r,s,n,"SQL",e)}static invalid(e,n=null){if(!e)throw new Ke("need to specify a reason the DateTime is invalid");const r=e instanceof ct?e:new ct(e,n);if(le.throwOnInvalid)throw new Sg(r);return new M({invalid:r})}static isDateTime(e){return e&&e.isLuxonDateTime||!1}static parseFormatForOpts(e,n={}){const r=am(e,Y.fromObject(n));return r?r.map(s=>s?s.val:null).join(""):null}static expandFormat(e,n={}){return sm(Te.parseFormat(e),Y.fromObject(n)).map(s=>s.val).join("")}get(e){return this[e]}get isValid(){return this.invalid===null}get invalidReason(){return this.invalid?this.invalid.reason:null}get invalidExplanation(){return this.invalid?this.invalid.explanation:null}get locale(){return this.isValid?this.loc.locale:null}get numberingSystem(){return this.isValid?this.loc.numberingSystem:null}get outputCalendar(){return this.isValid?this.loc.outputCalendar:null}get zone(){return this._zone}get zoneName(){return this.isValid?this.zone.name:null}get year(){return this.isValid?this.c.year:NaN}get quarter(){return this.isValid?Math.ceil(this.c.month/3):NaN}get month(){return this.isValid?this.c.month:NaN}get day(){return this.isValid?this.c.day:NaN}get hour(){return this.isValid?this.c.hour:NaN}get minute(){return this.isValid?this.c.minute:NaN}get second(){return this.isValid?this.c.second:NaN}get millisecond(){return this.isValid?this.c.millisecond:NaN}get weekYear(){return this.isValid?Wa(this).weekYear:NaN}get weekNumber(){return this.isValid?Wa(this).weekNumber:NaN}get weekday(){return this.isValid?Wa(this).weekday:NaN}get ordinal(){return this.isValid?Ha(this.c).ordinal:NaN}get monthShort(){return this.isValid?Hs.months("short",{locObj:this.loc})[this.month-1]:null}get monthLong(){return this.isValid?Hs.months("long",{locObj:this.loc})[this.month-1]:null}get weekdayShort(){return this.isValid?Hs.weekdays("short",{locObj:this.loc})[this.weekday-1]:null}get weekdayLong(){return this.isValid?Hs.weekdays("long",{locObj:this.loc})[this.weekday-1]:null}get offset(){return this.isValid?+this.o:NaN}get offsetNameShort(){return this.isValid?this.zone.offsetName(this.ts,{format:"short",locale:this.locale}):null}get offsetNameLong(){return this.isValid?this.zone.offsetName(this.ts,{format:"long",locale:this.locale}):null}get isOffsetFixed(){return this.isValid?this.zone.isUniversal:null}get isInDST(){return this.isOffsetFixed?!1:this.offset>this.set({month:1,day:1}).offset||this.offset>this.set({month:5}).offset}get isInLeapYear(){return ys(this.year)}get daysInMonth(){return Fi(this.year,this.month)}get daysInYear(){return this.isValid?Zr(this.year):NaN}get weeksInWeekYear(){return this.isValid?zi(this.weekYear):NaN}resolvedLocaleOptions(e={}){const{locale:n,numberingSystem:r,calendar:s}=Te.create(this.loc.clone(e),e).resolvedOptions(this);return{locale:n,numberingSystem:r,outputCalendar:s}}toUTC(e=0,n={}){return this.setZone(_e.instance(e),n)}toLocal(){return this.setZone(le.defaultZone)}setZone(e,{keepLocalTime:n=!1,keepCalendarTime:r=!1}={}){if(e=Bt(e,le.defaultZone),e.equals(this.zone))return this;if(e.isValid){let s=this.ts;if(n||r){const i=e.offset(this.ts),a=this.toObject();[s]=ci(a,i,e)}return Or(this,{ts:s,zone:e})}else return M.invalid(Ws(e))}reconfigure({locale:e,numberingSystem:n,outputCalendar:r}={}){const s=this.loc.clone({locale:e,numberingSystem:n,outputCalendar:r});return Or(this,{loc:s})}setLocale(e){return this.reconfigure({locale:e})}set(e){if(!this.isValid)return this;const n=$i(e,$c),r=!z(n.weekYear)||!z(n.weekNumber)||!z(n.weekday),s=!z(n.ordinal),i=!z(n.year),a=!z(n.month)||!z(n.day),o=i||a,l=n.weekYear||n.weekNumber;if((o||s)&&l)throw new Ar("Can't mix weekYear/weekNumber units with year/month/day or ordinals");if(a&&s)throw new Ar("Can't mix ordinal dates with month/day");let c;r?c=Ic({...Xo(this.c),...n}):z(n.ordinal)?(c={...this.toObject(),...n},z(n.day)&&(c.day=Math.min(Fi(c.year,c.month),c.day))):c=Mc({...Ha(this.c),...n});const[f,d]=ci(c,this.o,this.zone);return Or(this,{ts:f,o:d})}plus(e){if(!this.isValid)return this;const n=b.fromDurationLike(e);return Or(this,Fc(this,n))}minus(e){if(!this.isValid)return this;const n=b.fromDurationLike(e).negate();return Or(this,Fc(this,n))}startOf(e){if(!this.isValid)return this;const n={},r=b.normalizeUnit(e);switch(r){case"years":n.month=1;case"quarters":case"months":n.day=1;case"weeks":case"days":n.hour=0;case"hours":n.minute=0;case"minutes":n.second=0;case"seconds":n.millisecond=0;break}if(r==="weeks"&&(n.weekday=1),r==="quarters"){const s=Math.ceil(this.month/3);n.month=(s-1)*3+1}return this.set(n)}endOf(e){return this.isValid?this.plus({[e]:1}).startOf(e).minus(1):this}toFormat(e,n={}){return this.isValid?Te.create(this.loc.redefaultToEN(n)).formatDateTimeFromString(this,e):qa}toLocaleString(e=Ai,n={}){return this.isValid?Te.create(this.loc.clone(n),e).formatDateTime(this):qa}toLocaleParts(e={}){return this.isValid?Te.create(this.loc.clone(e),e).formatDateTimeParts(this):[]}toISO({format:e="extended",suppressSeconds:n=!1,suppressMilliseconds:r=!1,includeOffset:s=!0,extendedZone:i=!1}={}){if(!this.isValid)return null;const a=e==="extended";let o=Ba(this,a);return o+="T",o+=zc(this,a,n,r,s,i),o}toISODate({format:e="extended"}={}){return this.isValid?Ba(this,e==="extended"):null}toISOWeekDate(){return Bs(this,"kkkk-'W'WW-c")}toISOTime({suppressMilliseconds:e=!1,suppressSeconds:n=!1,includeOffset:r=!0,includePrefix:s=!1,extendedZone:i=!1,format:a="extended"}={}){return this.isValid?(s?"T":"")+zc(this,a==="extended",n,e,r,i):null}toRFC2822(){return Bs(this,"EEE, dd LLL yyyy HH:mm:ss ZZZ",!1)}toHTTP(){return Bs(this.toUTC(),"EEE, dd LLL yyyy HH:mm:ss 'GMT'")}toSQLDate(){return this.isValid?Ba(this,!0):null}toSQLTime({includeOffset:e=!0,includeZone:n=!1,includeOffsetSpace:r=!0}={}){let s="HH:mm:ss.SSS";return(n||e)&&(r&&(s+=" "),n?s+="z":e&&(s+="ZZ")),Bs(this,s,!0)}toSQL(e={}){return this.isValid?`${this.toSQLDate()} ${this.toSQLTime(e)}`:null}toString(){return this.isValid?this.toISO():qa}valueOf(){return this.toMillis()}toMillis(){return this.isValid?this.ts:NaN}toSeconds(){return this.isValid?this.ts/1e3:NaN}toUnixInteger(){return this.isValid?Math.floor(this.ts/1e3):NaN}toJSON(){return this.toISO()}toBSON(){return this.toJSDate()}toObject(e={}){if(!this.isValid)return{};const n={...this.c};return e.includeConfig&&(n.outputCalendar=this.outputCalendar,n.numberingSystem=this.loc.numberingSystem,n.locale=this.loc.locale),n}toJSDate(){return new Date(this.isValid?this.ts:NaN)}diff(e,n="milliseconds",r={}){if(!this.isValid||!e.isValid)return b.invalid("created by diffing an invalid DateTime");const s={locale:this.locale,numberingSystem:this.numberingSystem,...r},i=Wg(n).map(b.normalizeUnit),a=e.valueOf()>this.valueOf(),o=a?this:e,l=a?e:this,c=Jy(o,l,i,s);return a?c.negate():c}diffNow(e="milliseconds",n={}){return this.diff(M.now(),e,n)}until(e){return this.isValid?ne.fromDateTimes(this,e):this}hasSame(e,n){if(!this.isValid)return!1;const r=e.valueOf(),s=this.setZone(e.zone,{keepLocalTime:!0});return s.startOf(n)<=r&&r<=s.endOf(n)}equals(e){return this.isValid&&e.isValid&&this.valueOf()===e.valueOf()&&this.zone.equals(e.zone)&&this.loc.equals(e.loc)}toRelative(e={}){if(!this.isValid)return null;const n=e.base||M.fromObject({},{zone:this.zone}),r=e.padding?thisn.valueOf(),Math.min)}static max(...e){if(!e.every(M.isDateTime))throw new Ke("max requires all arguments be DateTimes");return Cc(e,n=>n.valueOf(),Math.max)}static fromFormatExplain(e,n,r={}){const{locale:s=null,numberingSystem:i=null}=r,a=Y.fromOpts({locale:s,numberingSystem:i,defaultToEN:!0});return im(a,e,n)}static fromStringExplain(e,n,r={}){return M.fromFormatExplain(e,n,r)}static get DATE_SHORT(){return Ai}static get DATE_MED(){return wh}static get DATE_MED_WITH_WEEKDAY(){return Tg}static get DATE_FULL(){return xh}static get DATE_HUGE(){return Sh}static get TIME_SIMPLE(){return kh}static get TIME_WITH_SECONDS(){return Eh}static get TIME_WITH_SHORT_OFFSET(){return Th}static get TIME_WITH_LONG_OFFSET(){return Nh}static get TIME_24_SIMPLE(){return Ch}static get TIME_24_WITH_SECONDS(){return jh}static get TIME_24_WITH_SHORT_OFFSET(){return _h}static get TIME_24_WITH_LONG_OFFSET(){return Oh}static get DATETIME_SHORT(){return Ph}static get DATETIME_SHORT_WITH_SECONDS(){return Rh}static get DATETIME_MED(){return Dh}static get DATETIME_MED_WITH_SECONDS(){return Ih}static get DATETIME_MED_WITH_WEEKDAY(){return Ng}static get DATETIME_FULL(){return Mh}static get DATETIME_FULL_WITH_SECONDS(){return Lh}static get DATETIME_HUGE(){return Ah}static get DATETIME_HUGE_WITH_SECONDS(){return Fh}}function Rr(t){if(M.isDateTime(t))return t;if(t&&t.valueOf&&En(t.valueOf()))return M.fromJSDate(t);if(t&&typeof t=="object")return M.fromObject(t);throw new Ke(`Unknown datetime argument: ${t}, of type ${typeof t}`)}function x0(t){return t.toString(16).padStart(2,"0")}function Za(t){const e=new Uint8Array((t||40)/2);return window.crypto.getRandomValues(e),Array.from(e,x0).join("")}function S0(t,e,n,r){if(t[n]===e[n])return 0;const s=(t[n]||"")<(e[n]||"")?-1:1;return r===tt.asc?s:-s}function k0(t,e,n,r){if(t[n]===e[n])return 0;const s=(t[n]||"")<(e[n]||"")?-1:1;return r===tt.asc?s:-s}function E0(t,e,n,r){if(t[n]===e[n])return 0;const s=t[n]1?e[e.length-1]:"1"}function T0(t){if(!t)return[];let e=[];return t.split(", ").forEach(n=>{if(!n.includes("-")){e.push(n);return}let r=n.split("-"),s=parseInt(r[0].substring(2)),i=parseInt(r[1].substring(2));for(let a=s;a<=i;a++)e.push("AS"+a)}),e}function gm(t,e){const n=M.fromSeconds(t,{zone:"UTC"}).setLocale(e);return`${n.toFormat("dd-MM-yyyy TTT")} (${n.toRelative()})`}function N0(t){return new RegExp("^(?:[a-z]+:)?//","i").test(t)}function C0(t){return t.includes("withId=true")}function ym(t){return t.getElementsByTagName("parsererror").length>0?t.getElementsByTagName("parsererror")[0].textContent:""}function j0(t){return` + + ${t.id_cert} + + +`}function _0(t){return` + + ${t.id_cert} + +`}function O0(t){const e=[];if(t.too_permissive)for(const n of t.too_permissive){e.push({action:"remove",reason:vt.tooPermissive,prefix:n.current.prefix,asn:n.current.asn,max_length:n.current.max_length||parseInt(n.current.prefix.split("/")[1])});for(const r of n.new)e.push({action:"remove",reason:vt.specific,prefix:r.prefix,asn:r.asn,max_length:parseInt(r.prefix.split("/")[1])})}if(t.not_found)for(const n of t.not_found)e.push({action:"add",reason:vt.notFound,prefix:n.prefix,asn:n.asn,max_length:parseInt(n.prefix.split("/")[1])});if(t.invalid_length)for(const n of t.invalid_length)e.push({action:"add",reason:vt.invalidLength,prefix:n.prefix,asn:n.asn,max_length:parseInt(n.prefix.split("/")[1])});if(t.redundant)for(const n of t.redundant)e.push({action:"remove",reason:vt.redundant,prefix:n.prefix,asn:n.asn,max_length:parseInt(n.prefix.split("/")[1])});if(t.stale)for(const n of t.stale)e.push({action:"remove",reason:vt.stale,prefix:n.prefix,asn:n.asn,max_length:parseInt(n.prefix.split("/")[1])});if(t.invalid_asn)for(const n of t.invalid_asn)e.push({action:"remove",reason:vt.invalidAsn,prefix:n.prefix,asn:n.asn,max_length:parseInt(n.prefix.split("/")[1])});if(t.as0_redundant)for(const n of t.as0_redundant)e.push({action:"remove",reason:vt.as0Redundant,prefix:n.prefix,asn:n.asn,max_length:parseInt(n.prefix.split("/")[1])});if(t.disallowing)for(const n of t.disallowing)e.push({action:"remove",reason:vt.disallowing,prefix:n.prefix,asn:n.asn,max_length:parseInt(n.prefix.split("/")[1])});return e}class wm{constructor(){oe(this,"baseUrl");oe(this,"VERSION_URL","https://api.github.com/repos/nlnetlabs/krill/releases/latest");oe(this,"token");this.baseUrl=window.location.origin,this.token=null}setToken(e){this.token=e}async get(e,n){const r=await fetch(`${this.baseUrl}${e}`,{...n,headers:{Authorization:`Bearer ${this.token}`,...(n==null?void 0:n.headers)||{}}});if((r.status===401||r.status===403)&&this.setToken(null),!(r.headers.get("Content-Type")==="application/json")){const a=await r.text();if(r.status===200)return a;throw{status:r.status,msg:a}}const i=await r.json();if(r.status===200)return i;throw{status:r.status,msg:i.msg||null}}post(e,n){return this.get(e,{method:"POST",...n})}postCas(e){return this.post("/api/v1/cas",{body:JSON.stringify({handle:e}),headers:{"Content-Type":"application/json"}})}getCas(){return this.get("/api/v1/cas").then(({cas:e})=>e.map(({handle:n})=>n).reverse())}getCaDetails(e){return this.get(`/api/v1/cas/${e}`)}getCaRoas(e){return this.get(`/api/v1/cas/${e}/routes/analysis/full`).then(n=>n.map(r=>({id:Za(10),...r})))}getCaAspas(e){return this.get(`/api/v1/cas/${e}/aspas`).then(n=>n.map(r=>({id:Za(10),...r})))}getCaSuggestions(e){return this.get(`/api/v1/cas/${e}/routes/analysis/suggest`).then(n=>O0(n)).then(n=>n.map(r=>({id:Za(10),...r})))}refreshCaParents(){return this.post("/api/v1/bulk/cas/sync/parent")}getCaParents(e){return this.get(`/api/v1/cas/${e}/parents`).then(n=>Object.entries(n).map(([r,s])=>({name:r,...s})))}refreshCaRepo(){return this.post("/api/v1/bulk/cas/sync/repo")}getCaRepoStatus(e){return this.get(`/api/v1/cas/${e}/repo/status`)}getInfo(){return this.get("/stats/info")}getVersion(){return fetch(this.VERSION_URL).then(e=>e.json())}getChildRequest(e){return this.get(`/api/v1/cas/${e}/id/child_request.xml`)}getPublisherRequest(e){return this.get(`/api/v1/cas/${e}/id/publisher_request.xml`)}postParent(e,n,r){return this.post(`/api/v1/cas/${e}/parents/${n}`,{body:r})}postRepository(e,n,r){return this.post(`/api/v1/cas/${e}/repo`,{body:r})}updateRoutes(e,n){return this.get(`/api/v1/cas/${e}/routes`,{method:"POST",body:JSON.stringify(n),headers:{"Content-Type":"application/json"}})}updateAspas(e,n){return this.get(`/api/v1/cas/${e}/aspas`,{method:"POST",body:JSON.stringify(n),headers:{"Content-Type":"application/json"}})}getLoginMethod(){return fetch(`${this.baseUrl}/auth/login`).then(e=>e.status===200?e.text().then(n=>N0(n)?{redirect_url:n}:{with_id:C0(n)}):Promise.reject(e))}postLogin(e,n){const r="/auth/login";if(n){this.setToken(null);const s=btoa(`${n}:${e}`);return this.post(r,{headers:{Authorization:`Basic ${s}`}})}return this.setToken(e),this.post(r)}checkToken(e){return this.setToken(e),this.get("/api/v1/authorized")}getTestBedEnabled(){return fetch("/testbed/enabled").then(e=>e.status===200?!0:e.status===400?!1:Promise.reject(e))}}let qc=null;function xm(){const[t,e]=P.useState(qc);return P.useEffect(()=>{t||new wm().getInfo().then(r=>{e(r),qc=r})},[]),t}const P0="/assets/logout-c725fd2c.svg",R0="/assets/user-5d1f1b14.svg";function au({initial:t}){const e=At(),[n,r]=P.useState(t);return P.useEffect(()=>e.usePlugin(()=>({onTransitionStart:()=>r(!0),onTransitionSuccess:()=>r(!1)})),[]),n?u.jsx("div",{className:"loader",children:u.jsx("span",{children:"Loading…"})}):null}function Sm({options:t,value:e,onChange:n,className:r}){const[s,i]=P.useState(!1);return u.jsxs("div",{className:`select ${r||""}`,children:[u.jsx("button",{className:s?"open":"",onClick:()=>i(!s),onBlur:()=>{setTimeout(()=>i(!1),300)},onKeyDown:a=>{a.key==="Escape"&&i(!1)},children:t[e]}),u.jsx("ul",{className:s?"show":"hide",children:Object.entries(t).map(([a,o])=>u.jsx("li",{className:e===a?"selected":"",onClick:()=>n(a),children:o},a))})]})}function Ss({notification:t,onClose:e}){return u.jsxs("div",{className:`notification popup ${t.type}`,children:[u.jsx("button",{className:"close",onClick:e,children:"×"}),u.jsx("span",{children:t.message})]})}function D0(){const t=ge(),[e,n]=P.useState(!1),r=()=>{n(!0),t.setNotification(null)};return P.useEffect(()=>{if(t.notification){n(!1);const s=setTimeout(r,5e3);return()=>clearTimeout(s)}},[t.notification]),!t.notification||e?null:u.jsx(Ss,{notification:t.notification,onClose:r})}function dn({children:t}){const e=te(),{route:n}=Ce(),r=xm(),s=ge(),i=new Date().getFullYear(),a=$();return P.useEffect(()=>{document.title=s.ca?`Krill - ${s.ca}`:"Krill"},[s.ca]),u.jsxs(u.Fragment,{children:[u.jsx(au,{initial:!1}),u.jsxs("header",{children:[u.jsx("h1",{onClick:()=>e({},"cas"),children:u.jsx("span",{children:"Krill"})}),u.jsxs("menu",{children:[u.jsx(Sm,{options:wg,value:s.locale,onChange:o=>e({locale:o})}),s.userDetails&&u.jsxs(u.Fragment,{children:[u.jsxs("button",{className:"pop",children:[u.jsx("img",{src:R0}),u.jsxs("div",{children:[u.jsx("h5",{children:a.common.userInfo.title}),u.jsx("table",{children:u.jsxs("tbody",{children:[u.jsxs("tr",{children:[u.jsxs("th",{children:[a.common.userInfo.user,":"]}),u.jsx("td",{children:s.userDetails.id})]}),Object.entries(s.userDetails.attributes).map(([o,l])=>u.jsxs("tr",{children:[u.jsxs("th",{className:"user-attribute",children:[o,":"]}),u.jsx("td",{children:l})]},o))]})})]})]}),u.jsx("button",{onClick:()=>e({},"logout"),children:u.jsx("img",{src:P0})})]})]})]}),u.jsx(D0,{}),u.jsx("div",{className:`content route-${n.name}`,children:t}),u.jsxs("footer",{children:[u.jsxs("span",{children:["© ",i," Stichting NLnet Labs"," - ","Krill ",r==null?void 0:r.version]}),u.jsxs("span",{children:[u.jsx("a",{href:"https://nlnetlabs.nl/services/contracts/",target:"_blank",rel:"noreferrer",children:a.common.supportcontracts})," - ",u.jsx("a",{href:"https://krill.docs.nlnetlabs.nl/",target:"_blank",rel:"noreferrer",children:a.common.readthedocs})," - ",u.jsx("a",{href:"https://github.com/NLnetLabs/krill/issues/new",target:"_blank",rel:"noreferrer",children:a.common.report})]})]})]})}function I0({columns:t,filtering:e}){const n=te(),r=s=>{const i=e.sort===s&&e.order===tt.asc?tt.desc:tt.asc;n({sort:s,order:i})};return u.jsx("thead",{children:u.jsxs("tr",{children:[u.jsx("th",{}),t.map(({label:s,accessor:i})=>u.jsxs("th",{onClick:()=>r(i),children:[s,i===e.sort&&u.jsx("span",{className:e.order})]},i)),u.jsx("th",{})]})})}function Wc({announcements:t}){const e=$();return u.jsxs("table",{children:[u.jsx("thead",{children:u.jsxs("tr",{children:[u.jsx("th",{children:e.announcements.asn}),u.jsx("th",{children:e.announcements.prefix})]})}),u.jsxs("tbody",{children:[t.length===0&&u.jsx("tr",{children:u.jsx("td",{colSpan:2,children:u.jsx("span",{className:"muted",children:e.common.nodata})})}),t.map((n,r)=>u.jsxs("tr",{children:[u.jsx("td",{children:n.asn}),u.jsx("td",{children:n.prefix})]},r))]})]})}function M0({authorizes:t,disallows:e}){const n=$();return u.jsxs("div",{className:"row",children:[u.jsxs("div",{children:[u.jsx("h3",{children:n.announcements.authorizes.replace("{number}",t.length.toString())}),u.jsx(Wc,{announcements:t})]}),u.jsxs("div",{children:[u.jsx("h3",{children:n.announcements.disallows.replace("{number}",e.length.toString())}),u.jsx(Wc,{announcements:e})]})]})}const km="/assets/trash-d9c6ee55.svg",L0="/assets/edit-776bf3c3.svg",A0="/assets/plus-e8f1d182.svg";function F0({roa:t,allowAdd:e,allowDelete:n,hasAnnouncements:r}){var d;const s=te(),[i,a]=P.useState(!1),o=$(),l={id:((d=t.id)==null?void 0:d.toString())||"new"},c=`${t.state}_help`,f=o.announcements.state[c];return u.jsxs(u.Fragment,{children:[u.jsxs("tr",{className:r?"announcements":"",children:[u.jsx("td",{children:r&&u.jsx("button",{className:`expand ${i?"open":""}`,onClick:()=>a(!i)})}),u.jsx("td",{children:t.asn}),u.jsxs("td",{children:[t.prefix,t.max_length&&-t.max_length]}),u.jsxs("td",{children:[t.comment,n&&u.jsx("button",{className:"button icon light right",onClick:()=>s(l,"cas.edit"),children:u.jsx("img",{src:L0})})]}),u.jsxs("td",{children:[u.jsx("span",{className:`state ${t.state}`,title:f,children:o.announcements.state[t.state]}),t.authorizes&&u.jsx("span",{className:"badge success",children:t.authorizes.length}),t.disallows&&u.jsx("span",{className:"badge warning",children:t.disallows.length})]}),u.jsxs("td",{className:"actions",children:[e&&u.jsx("button",{className:"button icon",onClick:()=>s(l,"cas.add"),children:u.jsx("img",{src:A0})}),n&&u.jsx("button",{className:"button icon",onClick:()=>s(l,"cas.delete"),children:u.jsx("img",{src:km})})]})]}),r&&i&&u.jsx("tr",{className:"announcements",children:u.jsx("td",{colSpan:6,children:u.jsx(M0,{authorizes:t.authorizes||[],disallows:t.disallows||[]})})})]})}function z0({tableData:t}){return u.jsx("tbody",{children:t.filter(e=>e.state!=De.AnnouncementDisallowedAs0).map(e=>u.jsx(F0,{roa:e,hasAnnouncements:!!e.authorizes||!!e.disallows,allowDelete:e.state===De.RoaSeen||e.state===De.RoaUnseen||e.state===De.RoaNotHeld||e.state==De.RoaNoAnnouncementInfo||e.state===De.RoaTooPermissive||e.state===De.RoaDisallowing||e.state===De.RoaRedundant||e.state==De.RoaAs0||e.state===De.RoaAs0Redundant,allowAdd:e.state===De.AnnouncementNotFound||e.state===De.AnnouncementInvalidLength||e.state===De.AnnouncementInvalidAsn},e.id))})}function $0({filtering:t}){const e=$(),r=ge().getRoas(t),s=[{label:e.announcements.asn,accessor:Yn.asn},{label:e.announcements.prefix,accessor:Yn.prefix},{label:e.caDetails.comment,accessor:Yn.comment},{label:e.announcements.stateLabel,accessor:Yn.state}];return u.jsxs("table",{className:"roa-table",children:[u.jsx(I0,{columns:s,filtering:t}),u.jsx(z0,{tableData:r})]})}function Em({details:t}){return u.jsx("div",{className:"ca-details card",children:u.jsx("table",{children:u.jsx("tbody",{children:Object.entries(t.resources).map(([e,n])=>u.jsxs("tr",{children:[u.jsx("th",{children:e}),u.jsx("td",{children:n.split(",").map(r=>u.jsx("p",{children:r},r))})]},e))})})})}function b0({onClose:t,roa:e}){var w;const n=$(),r=te(),[s,i]=P.useState((e==null?void 0:e.asn.toString())||""),[a,o]=P.useState((e==null?void 0:e.prefix)||""),[l,c]=P.useState((e==null?void 0:e.comment)||""),f=Hc(e==null?void 0:e.prefix),[d,v]=P.useState(((w=e==null?void 0:e.max_length)==null?void 0:w.toString())||f),y=g=>{g.preventDefault();const k=g.target;k.checkValidity()?r({asn:s,prefix:a,comment:l,max_length:d}):k.reportValidity()};return u.jsxs(u.Fragment,{children:[u.jsx("h3",{children:n.caDetails.addRoa}),u.jsxs("form",{onSubmit:y,children:[u.jsxs("div",{children:[u.jsx("label",{htmlFor:"asn required",children:n.announcements.asn}),u.jsx("input",{type:"number",min:"0",name:"asn",onInput:g=>g.target.setCustomValidity(""),onInvalid:g=>g.target.setCustomValidity(n.caDetails.addROAForm.asn_format),value:s,onChange:g=>i(g.target.value),required:!0})]}),u.jsxs("div",{children:[u.jsx("label",{htmlFor:"prefix required",children:n.announcements.prefix}),u.jsx("input",{name:"prefix",pattern:"^((([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(\\.(?!\\/)|\\/)){4}([0-9]|[1-2][0-9]|3[0-2]))|(([a-fA-F0-9:]+)\\/([0-9]|[1-9][0-9]|1[01][0-9]|12[0-8]))$",onInput:g=>g.target.setCustomValidity(""),onInvalid:g=>g.target.setCustomValidity(n.caDetails.addROAForm.prefix_format),title:n.caDetails.addROAForm.prefix_format,value:a,onChange:g=>o(g.target.value),required:!0})]}),u.jsxs("div",{children:[u.jsx("label",{htmlFor:"maxLength",children:n.caDetails.maxLength}),u.jsx("input",{type:"number",min:Hc(a)||1,max:a.includes(".")||!a.includes(":")?32:128,name:"maxLength",value:d,onChange:g=>v(g.target.value),placeholder:n.caDetails.maxLengthTooltip})]}),u.jsxs("div",{children:[u.jsx("label",{htmlFor:"comment",children:n.caDetails.comment}),u.jsx("input",{name:"comment",value:l,onChange:g=>c(g.target.value)})]}),u.jsxs("div",{className:"actions",children:[u.jsx("button",{type:"button",className:"button outline",onClick:t,children:n.common.cancel}),u.jsx("button",{type:"submit",className:"button",children:n.common.confirm})]})]})]})}const U0="modulepreload",V0=function(t){return"/"+t},Bc={},Et=function(e,n,r){if(!n||n.length===0)return e();const s=document.getElementsByTagName("link");return Promise.all(n.map(i=>{if(i=V0(i),i in Bc)return;Bc[i]=!0;const a=i.endsWith(".css"),o=a?'[rel="stylesheet"]':"";if(!!r)for(let f=s.length-1;f>=0;f--){const d=s[f];if(d.href===i&&(!a||d.rel==="stylesheet"))return}else if(document.querySelector(`link[href="${i}"]${o}`))return;const c=document.createElement("link");if(c.rel=a?"stylesheet":U0,a||(c.as="script",c.crossOrigin=""),c.href=i,document.head.appendChild(c),a)return new Promise((f,d)=>{c.addEventListener("load",f),c.addEventListener("error",()=>d(new Error(`Unable to preload CSS for ${i}`)))})})).then(()=>e())},H0=(t,e)=>{const n=t[e];return n?typeof n=="function"?n():Promise.resolve(n):new Promise((r,s)=>{(typeof queueMicrotask=="function"?queueMicrotask:setTimeout)(s.bind(null,new Error("Unknown variable dynamic import: "+e)))})};async function q0(t){return(await H0(Object.assign({"../locales/de.ts":()=>Et(()=>import("./de-960468cc.js"),[]),"../locales/en.ts":()=>Et(()=>import("./en-1f317977.js"),[]),"../locales/es.ts":()=>Et(()=>import("./es-9044ec29.js"),[]),"../locales/fr.ts":()=>Et(()=>import("./fr-87fd8a67.js"),[]),"../locales/gr.ts":()=>Et(()=>import("./gr-85b90120.js"),[]),"../locales/nl.ts":()=>Et(()=>import("./nl-7e5a6fa0.js"),[]),"../locales/pt.ts":()=>Et(()=>import("./pt-b668ac3c.js"),[]),"../locales/zh-Hans.ts":()=>Et(()=>import("./zh-Hans-2645b5fc.js"),[]),"../locales/zh-Hant.ts":()=>Et(()=>import("./zh-Hant-8af42392.js"),[])}),`../locales/${t}.ts`)).translations}function Tm(t,e){return Object.entries(e).reduce((n,[r,s])=>n.replace(`{${r}}`,s),t)}function W0({onClose:t,roa:e}){var i;const n=$(),r=te(),s={asn:e.asn.toString(),prefix:e.prefix,max_length:((i=e.max_length)==null?void 0:i.toString())||""};return u.jsxs(u.Fragment,{children:[u.jsx("h3",{children:n.common.warning}),u.jsx("p",{children:Tm(n.caDetails.confirmation.message,s)}),u.jsxs("div",{className:"actions",children:[u.jsx("button",{type:"button",className:"button outline",onClick:t,children:n.common.cancel}),u.jsx("button",{className:"button",onClick:()=>{r(s)},children:n.common.ok})]})]})}function B0({onClose:t,roa:e}){const n=$(),r=te(),[s,i]=P.useState((e==null?void 0:e.comment)||"");return u.jsxs(u.Fragment,{children:[u.jsx("h3",{children:n.common.edit}),u.jsxs("form",{autoComplete:"off",onSubmit:a=>{a.preventDefault(),s!==(e==null?void 0:e.comment)?r({comment:s}):t()},children:[u.jsxs("div",{children:[u.jsx("label",{htmlFor:"comment required",children:n.caDetails.comment}),u.jsx("input",{name:"comment",value:s,onChange:a=>i(a.target.value)})]}),u.jsxs("div",{className:"actions",children:[u.jsx("button",{type:"button",className:"button outline",onClick:t,children:n.common.cancel}),u.jsx("button",{type:"submit",className:"button",children:n.common.confirm})]})]})]})}function xr({onClose:t,children:e}){return u.jsx("div",{className:"modal",onMouseDown:t,children:u.jsx("div",{onMouseDown:n=>{n.stopPropagation()},children:e})})}function Z0(){const{route:t}=Ce(),e=At(),{route:{params:n}}=Ce(),i=ge().getRoas().find(o=>o.id===n.id),a=()=>{e.navigate("cas",{ca:n.ca})};return!i&&t.name!=="cas.add_new"?null:u.jsxs(xr,{onClose:a,children:[t.name.startsWith("cas.add")&&u.jsx(b0,{onClose:a,roa:i}),t.name.startsWith("cas.edit")&&u.jsx(B0,{onClose:a,roa:i}),t.name==="cas.delete"&&u.jsx(W0,{onClose:a,roa:i})]})}function la(){var i,a,o;const t=ge(),e=$(),n=te(),r=t.ca&&t.parents[t.ca].length>0,s=t.repoStatus&&t.ca&&((i=t.repoStatus[t.ca])==null?void 0:i.last_exchange);return u.jsxs(u.Fragment,{children:[u.jsxs("div",{className:"space-between border-bottom row",children:[u.jsxs("h2",{children:[e.cas.ca," ",u.jsx("strong",{children:t.ca})]}),t.cas&&((a=t.cas)==null?void 0:a.length)>1&&u.jsxs("div",{children:[u.jsx("label",{htmlFor:"ca",children:e.caDetails.current}),u.jsx(Sm,{className:"wide",options:((o=t.cas)==null?void 0:o.sort().reduce((l,c)=>({...l,[c]:[c]}),{}))||{},value:t.ca||"",onChange:l=>n({ca:l},"cas")})]})]}),!r&&u.jsx("div",{className:"notification error",children:e.caDetails.onboardingWarning}),r&&!s&&u.jsx("div",{className:"notification error",children:e.caDetails.initializeRepository}),u.jsx("div",{children:u.jsxs("ul",{className:"tabs",children:[u.jsx("li",{children:u.jsx(Yt,{routeName:"cas",activeStrict:!0,routeParams:{ca:t.ca},children:e.caDetails.roas})}),u.jsx("li",{children:u.jsx(Yt,{routeName:"cas.aspas",routeParams:{ca:t.ca},children:e.caDetails.aspas})}),u.jsx("li",{children:u.jsx(Yt,{routeName:"cas.parents",routeParams:{ca:t.ca},children:e.caDetails.parents})}),u.jsx("li",{children:u.jsx(Yt,{routeName:"cas.repository",routeParams:{ca:t.ca},children:e.caDetails.repo})})]})})]})}function Q0({currentPage:t,numPages:e}){const n=te();let r;if(e<=7)r=[...Array(e).keys()].map(s=>(s+1).toString());else if(r=Array(7),r[0]="1",r[6]=e.toString(),t>=1&&t<=4){for(let s=1;s<5;s++)r[s]=(s+1).toString();r[5]="..."}else if(t>=e-3&&t<=e){r[1]="...";for(let s=2;s<7;s++)r[s]=(e-6+s).toString()}else{r[1]="...";for(let s=2;s<5;s++)r[s]=(t-3+s).toString();r[5]="..."}return u.jsx(u.Fragment,{children:r.map((s,i)=>u.jsx("button",{className:s===t.toString()?"number current":"number",disabled:s===t.toString()||s==="...",onClick:()=>n({page:s}),children:s},i))})}function Y0({filtering:t}){const e=$(),r=ge().getRoas().length,s=te(),i=Math.ceil(r/t.limit);return u.jsxs("div",{className:"pagination",children:[u.jsx("select",{value:t.limit,onChange:a=>s({limit:a.target.value,page:"1"}),children:yg.map(a=>u.jsxs("option",{value:a,children:[a," / ",e.common.page]},a))}),u.jsxs("div",{children:[u.jsx("button",{disabled:t.page===1,className:"arrow prev",onClick:()=>s({page:(t.page-1).toString()}),children:u.jsx("span",{children:"<"})}),u.jsx(Q0,{currentPage:t.page,numPages:i}),u.jsx("button",{disabled:t.page>i-1,className:"arrow next",onClick:()=>s({page:(t.page+1).toString()}),children:u.jsx("span",{children:">"})})]})]})}function K0({columns:t,filtering:e,setAllCheckboxes:n,checkBoxState:r}){const s=te(),i=a=>{const o=e.sort===a&&e.order===tt.asc?tt.desc:tt.asc;s({sort:a,order:o})};return u.jsx("thead",{children:u.jsxs("tr",{children:[u.jsx("th",{children:u.jsx("input",{type:"checkbox",checked:r===yt.checked,onChange:n,ref:a=>{a&&(a.indeterminate=r===yt.intermediate)}})}),u.jsx("th",{}),t.map(({label:a,accessor:o})=>u.jsxs("th",{onClick:()=>i(o),children:[a,o===e.sort&&u.jsx("span",{className:e.order})]},o)),u.jsx("th",{})]})})}const G0="/assets/trash-red-65027383.svg",J0="/assets/check-green-4525c79c.svg";function X0({suggestion:t,id:e,checked:n,handleCheckbox:r}){const s=$(),i=s.caDetails.suggestions.reasons[t.reason];return u.jsxs(u.Fragment,{children:[u.jsx("td",{children:u.jsx("input",{type:"checkbox",id:e,onChange:r,checked:n})}),u.jsxs("td",{children:[t.action==="add"&&u.jsx("span",{className:"add",title:s.caDetails.suggestions.adding,children:u.jsx("img",{src:J0,title:`${s.caDetails.suggestions.willAdd} (${i})`})}),t.action==="remove"&&u.jsx("span",{className:"remove",title:s.caDetails.suggestions.willRemove,children:u.jsx("img",{src:G0,title:`${s.caDetails.suggestions.willRemove} (${i})`})})]}),u.jsx("td",{children:t.asn}),u.jsx("td",{children:t.prefix}),u.jsx("td",{children:s.caDetails.suggestions.reasons[t.reason]})]})}function e1({suggestions:t,checkedBoxes:e,handleCheckbox:n}){return u.jsx("tbody",{children:t.map(r=>u.jsx("tr",{children:u.jsx(X0,{checked:e.includes(r.id||""),suggestion:r,id:r.id||"",handleCheckbox:n})},r.id))})}function t1({suggestions:t,filtering:e,checkedBoxes:n,handleCheckbox:r,handleAllCheckboxes:s,topCheckBoxState:i}){const a=$(),o=[{label:a.announcements.asn,accessor:Li.asn},{label:a.announcements.prefix,accessor:Li.prefix}];return u.jsxs("table",{className:"roa-table",children:[u.jsx(K0,{columns:o,filtering:e,setAllCheckboxes:s,checkBoxState:i}),u.jsx(e1,{checkedBoxes:n,suggestions:t,handleCheckbox:r})]})}function n1(t){const n=ge().getSuggestions(t),r=[];for(const f of n)r.push(f.id||"");const[s,i]=P.useState([]),[a,o]=P.useState(yt.unchecked);return{checked:s,topCheckbox:a,suggestions:n,handleCheckbox:f=>{let d=[...s];f.target.checked?(d=[...s,f.target.id],r.every(v=>d.includes(v))?o(yt.checked):o(yt.intermediate)):(d.splice(s.indexOf(f.target.id),1),d.length>0?o(yt.intermediate):o(yt.unchecked)),i(d)},handleAllCheckboxes:f=>{f.target.checked?(i(r),o(yt.checked)):(i([]),o(yt.unchecked))}}}function r1({onClose:t,filtering:e}){const n=$(),r=te(),{checked:s,topCheckbox:i,suggestions:a,handleCheckbox:o,handleAllCheckboxes:l}=n1(e);return u.jsxs(u.Fragment,{children:[u.jsx("h3",{children:n.caDetails.analysis}),a.length>0&&u.jsxs(u.Fragment,{children:[u.jsxs("div",{children:[n.caDetails.suggestions.following," ",u.jsx("a",{href:"https://krill.docs.nlnetlabs.nl/en/stable/manage-roas.html",target:"_blank",rel:"noreferrer",children:n.caDetails.suggestions.readMore})]}),u.jsx(t1,{checkedBoxes:s,suggestions:a,filtering:e,handleCheckbox:o,handleAllCheckboxes:l,topCheckBoxState:i})]}),a.length===0&&n.caDetails.suggestions.nochanges,u.jsxs("div",{className:"actions",children:[a.length>0&&u.jsxs(u.Fragment,{children:[u.jsx("button",{type:"button",className:"button outline",onClick:t,children:n.common.cancel}),u.jsx("button",{className:"button",onClick:()=>r({ids:JSON.stringify(s)},"cas.change"),children:n.common.confirm})]}),a.length===0&&u.jsx("button",{className:"button",onClick:t,children:n.common.ok})]})]})}function s1(){const t=At(),{route:e,route:{params:n}}=Ce(),r=()=>{t.navigate("cas",{ca:n.ca})};if(e.name!=="cas.analyse")return null;const s={search:null,sort:n.sort||Li.asn,order:n.order||tt.asc,limit:parseInt(n.limit,10)||10,page:parseInt(n.page,10)||1};return u.jsx(xr,{onClose:r,children:e.name==="cas.analyse"&&u.jsx(r1,{onClose:r,filtering:s})})}function i1({filtering:t}){const e=$(),n=te(),[r,s]=P.useState(t.search);return P.useEffect(()=>{const i=setTimeout(()=>{n(r?{search:r}:{search:void 0})},500);return()=>clearTimeout(i)},[r]),P.useEffect(()=>{s(t.search)},[t.search]),u.jsx("input",{type:"search",value:r||"",placeholder:e.announcements.search,onChange:i=>s(i.target.value)})}function a1(){const t=$(),e=ge(),{route:n}=Ce(),r=te(),s=n.params,i={search:s.search||null,sort:s.sort||Yn.asn,order:s.order||tt.asc,limit:parseInt(s.limit,10)||25,page:parseInt(s.page,10)||1};return u.jsxs(dn,{children:[u.jsx(Z0,{}),n.name==="cas.analyse"&&u.jsx(s1,{}),u.jsx(la,{}),u.jsxs("div",{className:"row",children:[u.jsxs("div",{className:"flex-1",children:[u.jsx(i1,{filtering:i}),u.jsx($0,{filtering:i}),u.jsx(Y0,{filtering:i}),u.jsxs("div",{className:"roa-actions",children:[u.jsx("div",{children:u.jsx("button",{className:"button",onClick:()=>r({},"cas.add_new"),children:t.caDetails.addRoa})}),u.jsx("div",{children:u.jsx("button",{className:"button inverted",onClick:()=>r({},"cas.analyse"),children:t.caDetails.analyseThis})})]})]}),e.ca&&u.jsx(Em,{details:e.caDetails[e.ca]})]})]})}function o1({onClose:t,aspa:e}){const n=$(),r=te(),s={customer:e.customer.toString(),providers:e.providers.join(", ")};return u.jsxs(u.Fragment,{children:[u.jsx("h3",{children:n.common.warning}),u.jsx("p",{children:Tm(n.aspas.confirmation.message,s)}),u.jsxs("div",{className:"actions",children:[u.jsx("button",{type:"button",className:"button outline",onClick:t,children:n.common.cancel}),u.jsx("button",{className:"button",onClick:()=>{r(s)},children:n.common.ok})]})]})}function l1(){const{route:t}=Ce(),e=At(),{route:{params:n}}=Ce(),i=ge().getAspas().find(o=>o.id===n.id),a=()=>{e.navigate("cas.aspas",{ca:n.ca})};return!i&&t.name!=="cas.aspas.add_new"?null:u.jsx(xr,{onClose:a,children:t.name==="cas.aspas.delete"&&u.jsx(o1,{onClose:a,aspa:i})})}function u1({asMap:t,asn:e,aspa:n,aspas:r,edit:s}){var S;const i=$(),a=te(),[o,l]=P.useState((n==null?void 0:n.customer.toString())||e.substring(2)),[c,f]=P.useState((n==null?void 0:n.providers.join(", "))||""),[d,v]=P.useState([]),[y,w]=P.useState([]),g=xm(),k=((S=n==null?void 0:n.id)==null?void 0:S.toString())||"new",m={id:k},h=x=>{x.preventDefault();const T=x.target;T.checkValidity()?a({id:k,customer:o,providers:c},s?"cas.aspas.edit":"cas.aspas.add_new"):T.reportValidity()},p=x=>{const T=()=>{v(x.map(E=>[E,t.get(E)||"Unknown"])),fetch(`https://stat.ripe.net/data/asn-neighbours/data.json?sourceapp=krill-${(g==null?void 0:g.version)||"unknown"}&resource=${e}`).then(E=>E.json()).then(E=>{w(E.data.neighbours.filter(C=>C.type=="left"&&!x.includes(""+C.asn)).map(C=>[""+C.asn,t.get(""+C.asn)||"Unknown"]))}).catch(E=>{alert("Could not analyse: "+E)})};t.size===0?fetch("https://ftp.ripe.net/ripe/asnames/asn.txt").then(E=>E.text()).then(E=>{E.split(` +`).forEach(C=>{let D=C.split(/\s(.*)/s);D.length>=2&&t.set(D[0],D[1])}),T()}).catch(E=>{alert("Could not analyse: "+E)}):T()};return u.jsx("div",{className:s?"aspa-card card":"aspa-card card aspa-new",children:u.jsxs("div",{className:"aspa-form",children:[u.jsx("h3",{children:e}),u.jsxs("form",{onSubmit:h,children:[u.jsxs("div",{children:[u.jsx("label",{htmlFor:"customer required",children:i.aspas.customer}),u.jsx("input",{type:"number",min:"0",name:"customer",onInput:x=>x.target.setCustomValidity(""),onInvalid:x=>x.target.setCustomValidity(i.aspas.customer_validation_format),value:e.substring(2),onChange:x=>{let T=x.target.value;l(T),!s&&r.find(E=>E.customer===Number(T))&&x.target.setCustomValidity(i.aspas.customer_validation_format)},required:!0,disabled:!0})]}),u.jsxs("div",{children:[u.jsx("label",{htmlFor:"providers required",children:i.aspas.providers}),u.jsx("input",{type:"text",pattern:"^((\\d+),\\s*)*(\\d+)$",name:"provider",onInput:x=>x.target.setCustomValidity(""),onInvalid:x=>x.target.setCustomValidity(i.aspas.providers_validation_format),value:c,placeholder:"123, 456, 789",onChange:x=>f(x.target.value),required:!0})]}),d.length>0&&u.jsxs("div",{children:[u.jsx("label",{children:i.aspas.detected_providers}),u.jsx("table",{className:"aspa-table",children:u.jsx("tbody",{children:d.map(x=>u.jsxs("tr",{children:[u.jsx("td",{children:u.jsx("span",{className:"aspa-label",children:x[0]})}),u.jsx("td",{children:x[1]})]},x[0]))})})]}),y.length>0&&u.jsxs("div",{children:[u.jsx("label",{children:i.aspas.providers_missing}),u.jsx("table",{className:"aspa-table",children:u.jsx("tbody",{children:y.map(x=>u.jsxs("tr",{children:[u.jsx("td",{children:u.jsx("span",{className:"aspa-label",children:x[0]})}),u.jsx("td",{children:x[1]})]},x[0]))})})]}),u.jsxs("div",{className:"actions",children:[s&&u.jsx("button",{type:"button",className:"button",onClick:()=>a(m,"cas.aspas.delete"),children:u.jsx("img",{src:km,alt:"Remove"})}),u.jsx("button",{type:"submit",className:"button",children:s?i.aspas.edit:i.aspas.add}),c.length>0&&u.jsx("button",{type:"button",className:"button outline",onClick:()=>p(c.split(",").map(x=>x.trim())),children:i.aspas.analyse})]})]})]})})}function c1(){const t=$();At();const e=ge(),{route:n}=Ce();te(),n.params;const r=e.getAspas(),s=e.ca&&T0(e.caDetails[e.ca].resources.asn);let i=new Map;return u.jsxs(dn,{children:[u.jsx(l1,{}),u.jsx(la,{}),u.jsxs("div",{className:"row",children:[u.jsxs("div",{className:"aspa-list",children:[s&&s.map(a=>{const o=r.find(l=>"AS"+l.customer===a);return u.jsx(u1,{asMap:i,asn:a,aspas:r,aspa:o,edit:!!o},a)}),(!s||s.length==0)&&u.jsx("div",{className:"aspa-card card aspa-new",children:u.jsx("div",{className:"aspa-form",children:u.jsx("em",{children:t.aspas.no_aspas})})})]}),e.ca&&u.jsx(Em,{details:e.caDetails[e.ca]})]})]})}const Nm="/assets/upload-87e6fdfd.svg";let Zc="";function d1(){const[t,e]=P.useState(Zc),n=ge();return P.useEffect(()=>{n.ca&&n.api.getChildRequest(n.ca).then(r=>{e(r),Zc=r})},[]),t}function Cm(t){const[e,n]=P.useState(null),[r,s]=P.useState(t),[i,a]=P.useState("");return P.useEffect(()=>{s(t)},[t]),{notification:e,setNotification:n,request:r,setRequest:s,response:i,setResponse:a,handleUpload:l=>{if(l.currentTarget.files){const c=new FileReader;c.onload=()=>{a(c.result)},c.readAsText(l.currentTarget.files[0])}}}}function f1(){const t=d1(),e=At(),{route:{params:n}}=Ce(),r=te(),[s,i]=P.useState(""),{notification:a,setNotification:o,request:l,setRequest:c,response:f,setResponse:d,handleUpload:v}=Cm(t);return{notification:a,setNotification:o,name:s,setName:i,request:l,setRequest:c,response:f,setResponse:d,onSubmit:async g=>{g.preventDefault(),r({name:s,response:f})},onClose:()=>{e.navigate("cas.parents",{ca:n.ca})},handleUpload:v}}const h1="/assets/clipboard-4659ffea.svg",m1="/assets/download-2dfead4c.svg";function ua({xml:t,name:e,setNotification:n}){const r=$(),s=()=>{navigator.clipboard.writeText(t),n({type:U.success,message:r.common.copySuccess})};return u.jsxs(u.Fragment,{children:[u.jsx("button",{className:"button large icon",type:"button",title:r.common.copy,onClick:s,children:u.jsx("img",{src:h1,alt:r.common.copy})}),u.jsx("a",{className:"button large icon",title:r.common.download,href:`data:application/xml;base64,${btoa(t)}`,download:`${e}.xml`,children:u.jsx("img",{src:m1,alt:r.common.download})})]})}function p1(){const t=$(),{notification:e,setNotification:n,name:r,setName:s,request:i,setRequest:a,response:o,setResponse:l,onSubmit:c,onClose:f,handleUpload:d}=f1();return u.jsxs(xr,{onClose:f,children:[e&&u.jsx(Ss,{notification:e,onClose:()=>n(null)}),u.jsx("h3",{children:t.caDetails.parentsTab.addParent}),u.jsxs("form",{onSubmit:c,method:"POST",children:[u.jsxs("div",{children:[u.jsx("label",{children:t.caDetails.parentsTab.request}),u.jsx("textarea",{name:"request",readOnly:!0,value:i,id:"request",onChange:v=>a(v.target.value)}),u.jsx("div",{children:u.jsx(ua,{xml:i,name:"child_request",setNotification:n})})]}),u.jsxs("div",{children:[u.jsx("label",{children:t.caDetails.parentsTab.response}),u.jsx("textarea",{name:"response",value:o,onChange:v=>l(v.target.value)}),u.jsx("input",{type:"file",id:"upload",onChange:d}),u.jsx("label",{className:"button large icon",htmlFor:"upload",title:t.common.dropOrClick,children:u.jsx("img",{src:Nm,alt:t.common.dropOrClick})})]}),u.jsxs("div",{children:[u.jsx("label",{children:t.caDetails.parentsTab.name}),u.jsx("input",{name:"name",value:r,onChange:v=>s(v.target.value),required:!0})]}),u.jsxs("div",{className:"actions",children:[u.jsx("button",{type:"button",className:"button outline",onClick:f,children:t.common.cancel}),u.jsx("button",{type:"submit",className:"button",children:t.common.confirm})]})]})]})}function v1({parent:t,loading:e}){const n=$(),{locale:r}=ge(),s=e?n.caDetails.loading.replace("{handle}","..."):gm(t.last_exchange.timestamp,r);return u.jsxs("div",{className:"info-table",children:[u.jsx("h4",{children:t.name}),u.jsx("table",{children:u.jsxs("tbody",{children:[u.jsxs("tr",{children:[u.jsx("th",{children:n.caDetails.parents}),u.jsx("td",{children:t.last_exchange.uri})]}),u.jsxs("tr",{children:[u.jsx("th",{children:n.caDetails.lastExchange}),u.jsx("td",{children:t.last_exchange.result!="Success"?u.jsxs("p",{className:"failure",children:[s,u.jsx("br",{}),t.last_exchange.result.Failure.msg]}):u.jsx("p",{className:"success",children:s})})]}),u.jsxs("tr",{children:[u.jsx("th",{children:n.caDetails.allResources}),u.jsxs("td",{children:["ASN: ",t.all_resources.asn,u.jsx("br",{}),"IPv4: ",t.all_resources.ipv4,u.jsx("br",{}),"IPv6: ",t.all_resources.ipv6,u.jsx("br",{})]})]})]})})]})}function g1(){var o;const t=$(),{route:e}=Ce(),n=ge(),r=te(),[s,i]=P.useState(!1),a=()=>{i(!0),n.refreshParents().then(()=>{i(!1)})};return u.jsxs(dn,{children:[e.name==="cas.parents.add"&&u.jsx(p1,{}),s&&u.jsx(Ss,{notification:{type:U.success,message:t.caDetails.refresh.replace("{handle}",t.caDetails.parents.toLowerCase())},onClose:()=>i(!1)}),u.jsx(la,{}),n.parents&&n.ca&&((o=n.parents[n.ca])==null?void 0:o.map(l=>u.jsx(v1,{parent:l,loading:s},l.name))),u.jsx("button",{className:"button",onClick:()=>r({},"cas.parents.add"),children:t.caDetails.parentsTab.addParent}),u.jsx("button",{className:"button inverted",onClick:a,children:t.caDetails.syncParents})]})}function y1({repo:t,locale:e,loading:n}){const r=$(),s=n?r.caDetails.loading.replace("{handle}","..."):gm(t.last_exchange.timestamp,e);return u.jsx("div",{className:"info-table",children:u.jsx("table",{children:u.jsxs("tbody",{children:[u.jsxs("tr",{children:[u.jsx("th",{children:r.caDetails.exchangeUri}),u.jsx("td",{children:t.last_exchange.uri})]}),u.jsxs("tr",{children:[u.jsx("th",{children:r.caDetails.lastExchange}),u.jsx("td",{children:t.last_exchange.result!="Success"?u.jsxs("p",{className:"failure",children:[s,u.jsx("br",{}),t.last_exchange.result.Failure.msg]}):u.jsx("p",{className:"success",children:s})})]})]})})})}let Qc="";function w1(){const[t,e]=P.useState(Qc),n=ge();return P.useEffect(()=>{n.ca&&n.api.getPublisherRequest(n.ca).then(r=>{e(r),Qc=r})},[]),t}function x1(){const t=w1(),e=At(),{route:{params:n}}=Ce(),r=te(),{notification:s,setNotification:i,request:a,setRequest:o,response:l,setResponse:c,handleUpload:f}=Cm(t);return{notification:s,setNotification:i,request:a,setRequest:o,response:l,setResponse:c,onSubmit:async y=>{y.preventDefault(),r({response:l})},onClose:()=>{e.navigate("cas.repository",{ca:n.ca})},handleUpload:f}}function S1(){const t=$(),{notification:e,setNotification:n,request:r,setRequest:s,response:i,setResponse:a,onSubmit:o,onClose:l,handleUpload:c}=x1();return u.jsxs(xr,{onClose:l,children:[e&&u.jsx(Ss,{notification:e,onClose:()=>n(null)}),u.jsx("h3",{children:t.caDetails.repoTab.addRepo}),u.jsxs("form",{onSubmit:o,method:"POST",children:[u.jsxs("div",{children:[u.jsx("label",{children:t.caDetails.repoTab.request}),u.jsx("textarea",{name:"request",readOnly:!0,value:r,id:"request",onChange:f=>s(f.target.value)}),u.jsx("div",{children:u.jsx(ua,{xml:r,name:"publisher_request",setNotification:n})})]}),u.jsxs("div",{children:[u.jsx("label",{children:t.caDetails.repoTab.response}),u.jsx("textarea",{name:"response",value:i,onChange:f=>a(f.target.value)}),u.jsx("input",{type:"file",id:"upload",onChange:c}),u.jsx("label",{className:"button large icon",htmlFor:"upload",title:t.common.dropOrClick,children:u.jsx("img",{src:Nm,alt:t.common.dropOrClick})})]}),u.jsxs("div",{className:"actions",children:[u.jsx("button",{type:"button",className:"button outline",onClick:l,children:t.common.cancel}),u.jsx("button",{type:"submit",className:"button",children:t.common.confirm})]})]})]})}function k1(){var l;const t=$(),e=ge(),n=te(),{route:r}=Ce(),[s,i]=P.useState(!1),a=()=>{i(!0),e.refreshRepo().then(()=>{i(!1)})};if(!e.ca)return null;const o=e.repoStatus&&e.ca&&((l=e.repoStatus[e.ca])==null?void 0:l.last_exchange);return u.jsxs(dn,{children:[r.name==="cas.repository.add"&&u.jsx(S1,{}),s&&u.jsx(Ss,{notification:{type:U.success,message:t.caDetails.refresh.replace("{handle}",t.caDetails.repo.toLowerCase())},onClose:()=>i(!1)}),u.jsx(la,{}),o?u.jsx(y1,{repo:e.repoStatus[e.ca],locale:e.locale,loading:s}):u.jsx("button",{className:"button",onClick:()=>n({},"cas.repository.add"),children:t.caDetails.repoTab.addRepo}),u.jsx("button",{className:"button inverted",onClick:a,children:t.caDetails.syncRepo})]})}function jm(){const t=$();return u.jsxs(dn,{children:[u.jsx("h1",{children:t.common.error}),u.jsx("pre",{children:window.location.pathname})]})}function E1(){const[t,e]=P.useState(""),[n,r]=P.useState(""),s=te(),i=ge(),a=$(),o=i.loginMethod;if(!o)return u.jsx(au,{initial:!0});const l=async c=>{c.preventDefault(),o.with_id?s({password:n,username:t}):s({password:n})};return u.jsx(dn,{children:u.jsxs("form",{onSubmit:l,method:"POST",className:`login card ${o.with_id?"vertical-form":""}`,children:[o.with_id&&u.jsxs("div",{children:[u.jsx("label",{htmlFor:"admin required",children:a.login.id}),u.jsx("input",{name:"token",type:"username",value:t,onChange:c=>e(c.target.value),placeholder:a.login.idPlaceholder,required:!0})]}),u.jsxs("div",{children:[u.jsx("label",{htmlFor:"token required",children:a.login.password}),u.jsx("input",{name:"token",type:"password",value:n,onChange:c=>r(c.target.value),placeholder:a.login.placeholder,required:!0})]}),u.jsx("div",{children:u.jsx("button",{type:"submit",className:"button",children:a.login.signin})})]})})}function fr({notification:t}){const e=te();return u.jsxs("div",{className:`notification ${t.type}`,children:[u.jsx("button",{className:"close",onClick:()=>e({notification:"clear"}),children:"×"}),u.jsx("span",{children:t.message})]})}function ca({onClose:t,onConfirm:e}){const n=$(),{route:r}=Ce();let s="",i="";return r.name==="testbed"?(s=n.testbed.addChild.confirmation.title,i=n.testbed.addChild.confirmation.message):r.name==="testbed.add_pub"?(s=n.testbed.addPublisher.confirmation.title,i=n.testbed.addPublisher.confirmation.message):r.name==="testbed.del_ca"?(s=n.testbed.removeChild.confirmation.title,i=n.testbed.removeChild.confirmation.message):r.name==="testbed.del_pub"&&(s=n.testbed.removePublisher.confirmation.title,i=n.testbed.removePublisher.confirmation.message),u.jsxs(xr,{onClose:t,children:[u.jsx("h3",{children:s}),u.jsx("p",{children:i}),u.jsxs("div",{className:"actions",children:[u.jsx("button",{className:"button outline",onClick:t,children:n.common.cancel}),u.jsx("button",{className:"button",onClick:e,children:n.common.ok})]})]})}function T1(){const t=$(),[e,n]=P.useState(),[r,s]=P.useState(!1),[i,a]=P.useState(""),[o,l]=P.useState(""),[c,f]=P.useState(""),[d,v]=P.useState(""),[y,w]=P.useState(""),g=async(x,T,E,C,D)=>{const R=await fetch("/testbed/children",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({handle:x,id_cert:T,resources:{asn:E,v4:C,v6:D}})});if(R.status===200){n({type:U.success,message:t.testbed.addChild.success.replace("{child_handle}",x)});const W=j0(await R.json());w(W)}else{const W=await R.json();W.label==="pub-duplicate"?await g(x+Date.now(),T,E,C,D):n({type:U.error,message:W.msg})}},k=async x=>{x.preventDefault(),p(i)&&s(!0)},m=async()=>{const x=p(i);x&&await g(x.handle,x.id_cert,o,c,d)},h=x=>{const T=ym(x);return T?(n({type:U.error,message:t.testbed.errors.invalid_xml.replace("{err}",T)}),!1):x.getElementsByTagName("child_request").length===0?(n({type:U.error,message:t.testbed.errors.missing_xml_el.replace("{el}","child_request")}),!1):x.getElementsByTagName("child_bpki_ta").length===0?(n({type:U.error,message:t.testbed.errors.missing_xml_el.replace("{el}","child_bpki_ta")}),!1):x.getElementsByTagName("child_request")[0].attributes.child_handle?x.getElementsByTagName("child_bpki_ta")[0].childNodes.length===0?(n({type:U.error,message:t.testbed.errors.empty_xml_el.replace("{el}","child_bpki_ta")}),!1):x.getElementsByTagName("child_bpki_ta")[0].childNodes[0].nodeValue.trim().length===0?(n({type:U.error,message:t.testbed.errors.empty_xml_el.replace("{el}","child_bpki_ta")}),!1):!0:(n({type:U.error,message:t.testbed.errors.missing_xml_attr.replace("{attr}","child_handle").replace("{el}","child_request")}),!1)},p=x=>{const T=new window.DOMParser().parseFromString(x,"text/xml");if(h(T))return{handle:T.getElementsByTagName("child_request")[0].attributes.child_handle.value,id_cert:T.getElementsByTagName("child_bpki_ta")[0].childNodes[0].nodeValue.trim()}},S=()=>{w(""),s(!1),a(t.testbed.addChild.requestXML.placeholder),l(""),f(""),v("")};return y!==""?u.jsxs("div",{className:"testbed-result",children:[e&&u.jsx(fr,{notification:e}),u.jsx("pre",{children:y}),u.jsx("p",{children:u.jsx(ua,{xml:y,name:"parent_response",setNotification:n})}),u.jsx("div",{className:"actions",children:u.jsx("button",{onClick:S,className:"button",children:t.testbed.addChild.registeranother})})]}):u.jsxs(u.Fragment,{children:[r&&u.jsx(ca,{onClose:()=>s(!1),onConfirm:m}),u.jsxs("form",{onSubmit:k,method:"POST",children:[e&&u.jsx(fr,{notification:e}),u.jsxs("div",{children:[u.jsxs("label",{children:[t.testbed.addChild.requestXML.label,u.jsx("a",{href:"https://tools.ietf.org/html/rfc8183#section-5.2.1",children:t.testbed.rfcdoclink})]}),u.jsx("textarea",{name:"request",value:i,placeholder:t.testbed.addChild.requestXML.placeholder,onChange:x=>a(x.target.value),required:!0})]}),u.jsxs("div",{children:[u.jsx("label",{children:t.testbed.addChild.asnresources.label}),u.jsx("input",{name:"asn",value:o,onChange:x=>l(x.target.value),placeholder:t.testbed.addChild.asnresources.placeholder})]}),u.jsxs("div",{children:[u.jsx("label",{children:t.testbed.addChild.ipv4resources.label}),u.jsx("input",{name:"v4",value:c,onChange:x=>f(x.target.value),placeholder:t.testbed.addChild.ipv4resources.placeholder})]}),u.jsxs("div",{children:[u.jsx("label",{children:t.testbed.addChild.ipv6resources.label}),u.jsx("input",{name:"v6",value:d,onChange:x=>v(x.target.value),placeholder:t.testbed.addChild.ipv6resources.placeholder})]}),u.jsx("button",{type:"submit",className:"button",children:t.testbed.addChild.confirm})]})]})}function N1(){const t=$(),[e,n]=P.useState(),[r,s]=P.useState(!1),[i,a]=P.useState(""),[o,l]=P.useState(""),c=async(g,k)=>{const m=await fetch("/testbed/publishers",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({publisher_handle:g,id_cert:k,tag:null})});if(m.status===200)n({type:U.success,message:t.testbed.addPublisher.success.replace("{publisher_handle}",g)}),l(_0(await m.json()));else{const h=await m.json();h.label==="pub-duplicate"?await c(g+Date.now(),k):n({type:U.error,message:h.msg})}},f=g=>{const k=ym(g);return k?(n({type:U.error,message:t.testbed.errors.invalid_xml.replace("{err}",k)}),!1):g.getElementsByTagName("publisher_request").length===0?(n({type:U.error,message:t.testbed.errors.missing_xml_el.replace("{el}","publisher_request")}),!1):g.getElementsByTagName("publisher_bpki_ta").length===0?(n({type:U.error,message:t.testbed.errors.missing_xml_el.replace("{el}","publisher_bpki_ta")}),!1):g.getElementsByTagName("publisher_request")[0].attributes.publisher_handle?g.getElementsByTagName("publisher_bpki_ta")[0].childNodes.length===0?(n({type:U.error,message:t.testbed.errors.empty_xml_el.replace("{el}","publisher_bpki_ta")}),!1):g.getElementsByTagName("publisher_bpki_ta")[0].childNodes[0].nodeValue.trim().length===0?(n({type:U.error,message:t.testbed.errors.empty_xml_el.replace("{el}","publisher_bpki_ta")}),!1):!0:(n({type:U.error,message:t.testbed.errors.missing_xml_attr.replace("{attr}","publisher_handle").replace("{el}","publisher_request")}),!1)},d=g=>{const k=new window.DOMParser().parseFromString(g,"text/xml");if(f(k))return{publisher_handle:k.getElementsByTagName("publisher_request")[0].attributes.publisher_handle.value,id_cert:k.getElementsByTagName("publisher_bpki_ta")[0].childNodes[0].nodeValue.trim()}},v=async g=>{g.preventDefault(),d(i)&&s(!0)},y=async()=>{const g=d(i);g&&await c(g.publisher_handle,g.id_cert)},w=()=>{a(t.testbed.addPublisher.requestXML.placeholder),l(""),s(!1)};return o!==""?u.jsxs("div",{className:"testbed-result",children:[e&&u.jsx(fr,{notification:e}),u.jsx("pre",{children:o}),u.jsx("p",{children:u.jsx(ua,{xml:o,name:"publisher_response",setNotification:n})}),u.jsx("div",{className:"actions",children:u.jsx("button",{onClick:w,className:"button",children:t.testbed.addPublisher.registeranother})})]}):u.jsxs(u.Fragment,{children:[r&&u.jsx(ca,{onClose:()=>s(!1),onConfirm:y}),u.jsxs("form",{onSubmit:v,method:"POST",children:[e&&u.jsx(fr,{notification:e}),u.jsxs("div",{children:[u.jsxs("label",{children:[t.testbed.addPublisher.requestXML.label,u.jsx("a",{href:"https://tools.ietf.org/html/rfc8183#section-5.2.3",children:t.testbed.rfcdoclink})]}),u.jsx("textarea",{name:"request",value:i,placeholder:t.testbed.addPublisher.requestXML.placeholder,onChange:g=>a(g.target.value),required:!0})]}),u.jsx("button",{type:"submit",className:"button",children:t.testbed.addPublisher.confirm})]})]})}function C1(){const t=$(),[e,n]=P.useState(),[r,s]=P.useState(!1),[i,a]=P.useState(""),o=async()=>{const f=await fetch(`/testbed/children/${i}`,{method:"DELETE"});if(f.status===200)n({type:U.success,message:t.testbed.removeChild.success.replace("{child_handle}",i)}),a("");else{const d=await f.json();n({type:U.error,message:d.msg})}},l=f=>{f.preventDefault(),s(!0)},c=async()=>{await o(),s(!1)};return u.jsxs(u.Fragment,{children:[r&&u.jsx(ca,{onClose:()=>s(!1),onConfirm:c}),u.jsxs("form",{onSubmit:l,method:"POST",children:[e&&u.jsx(fr,{notification:e}),u.jsxs("div",{children:[u.jsx("label",{children:t.testbed.childhandle}),u.jsx("input",{name:"handle",value:i,onChange:f=>a(f.target.value),placeholder:t.testbed.removeChild.placeholder,required:!0})]}),u.jsx("button",{type:"submit",className:"button",children:t.testbed.removeChild.confirm})]})]})}function j1(){const t=$(),[e,n]=P.useState(),[r,s]=P.useState(!1),[i,a]=P.useState(""),o=async()=>{const f=await fetch(`/testbed/publishers/${i}`,{method:"DELETE"});if(f.status===200)n({type:U.success,message:t.testbed.removePublisher.success.replace("{publisher_handle}",i)}),a("");else{const d=await f.json();n({type:U.error,message:d.msg})}},l=async f=>{f.preventDefault(),s(!0)},c=async()=>{await o(),s(!1)};return u.jsxs(u.Fragment,{children:[r&&u.jsx(ca,{onClose:()=>s(!1),onConfirm:c}),u.jsxs("form",{onSubmit:l,method:"POST",children:[e&&u.jsx(fr,{notification:e}),u.jsxs("div",{children:[u.jsx("label",{children:t.testbed.publisherhandle}),u.jsx("input",{name:"handle",value:i,onChange:f=>a(f.target.value),placeholder:t.testbed.removePublisher.placeholder,required:!0})]}),u.jsx("button",{type:"submit",className:"button",children:t.testbed.removePublisher.confirm})]})]})}const _m="/assets/welcome-9fadc7f2.svg";function Zs({children:t}){const e=$();return u.jsx(dn,{children:u.jsxs("div",{className:"testbed",children:[u.jsxs("div",{children:[u.jsx("img",{src:_m,className:"hero",alt:e.common.copy}),u.jsx("h2",{children:e.testbed.welcome})]}),u.jsxs("div",{children:[u.jsx("h3",{children:e.testbed.disclaimer.heading}),u.jsx("p",{dangerouslySetInnerHTML:{__html:e.testbed.disclaimer.body}}),u.jsx("h3",{children:e.testbed.rpconfighelp.heading}),u.jsx("p",{dangerouslySetInnerHTML:{__html:e.testbed.rpconfighelp.body.replace("{tallink}","/ta/ta.tal")}}),u.jsx("h3",{children:e.testbed.regunreg.heading}),u.jsx("p",{dangerouslySetInnerHTML:{__html:e.testbed.regunreg.body}})]}),u.jsx("div",{children:u.jsxs("ul",{className:"tabs",children:[u.jsx("li",{children:u.jsx(Yt,{routeName:"testbed",activeStrict:!0,children:e.testbed.addChild.heading})}),u.jsx("li",{children:u.jsx(Yt,{routeName:"testbed.del_ca",children:e.testbed.removeChild.heading})}),u.jsx("li",{children:u.jsx(Yt,{routeName:"testbed.add_pub",children:e.testbed.addPublisher.heading})}),u.jsx("li",{children:u.jsx(Yt,{routeName:"testbed.del_pub",children:e.testbed.removePublisher.heading})})]})}),t]})})}function _1(){const{route:t}=Ce();return ge().testBedEnabled?t.name=="testbed.del_ca"?u.jsx(Zs,{children:u.jsx(C1,{})}):t.name=="testbed.add_pub"?u.jsx(Zs,{children:u.jsx(N1,{})}):t.name=="testbed.del_pub"?u.jsx(Zs,{children:u.jsx(j1,{})}):u.jsx(Zs,{children:u.jsx(T1,{})}):u.jsx(jm,{})}function O1(){const t=te(),[e,n]=P.useState(""),r=$(),s=i=>{i.preventDefault(),t({name:e})};return u.jsx(dn,{children:u.jsxs("form",{method:"POST",onSubmit:s,className:"center-form",children:[u.jsxs("div",{children:[u.jsx("img",{src:_m,alt:r.common.copy}),u.jsx("h2",{children:r.onboarding.welcome}),u.jsx("div",{dangerouslySetInnerHTML:{__html:r.onboarding.welcomeHtml}})]}),u.jsxs("div",{children:[u.jsxs("label",{htmlFor:"token required",children:["CA ",r.caDetails.handle]}),u.jsx("input",{name:"name",type:"test",value:e,onChange:i=>n(i.target.value),required:!0})]}),u.jsx("div",{children:u.jsx("button",{type:"submit",className:"button",children:r.onboarding.addCAForm.confirm})})]})})}function P1(){const{route:t}=Ce();return!t||t.name==="loading"?u.jsx(au,{initial:!0}):t.name==="login"?u.jsx(E1,{}):t.name==="onboarding"?u.jsx(O1,{}):t.name.startsWith("cas.parents")?u.jsx(g1,{}):t.name.startsWith("cas.repository")?u.jsx(k1,{}):t.name.startsWith("cas.aspas")?u.jsx(c1,{}):t.name.startsWith("cas")?u.jsx(a1,{}):t.name.startsWith("testbed")?u.jsx(_1,{}):u.jsx(jm,{})}/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +PERFORMANCE OF THIS SOFTWARE. +***************************************************************************** */var Ze=function(){return Ze=Object.assign||function(e){for(var n,r=1,s=arguments.length;r$)/g,""):"[a-zA-Z0-9-_.~%':|=+\\*@$]+")+")"},H1=[{name:"url-parameter",pattern:/^:([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(<(.+?)>)?/,regex:function(e){return new RegExp(el(e[2]))}},{name:"url-parameter-splat",pattern:/^\*([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})/,regex:/([^?]*)/},{name:"url-parameter-matrix",pattern:/^;([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})(<(.+?)>)?/,regex:function(e){return new RegExp(";"+e[1]+"="+el(e[2]))}},{name:"query-parameter",pattern:/^(?:\?|&)(?::)?([a-zA-Z0-9-_]*[a-zA-Z0-9]{1})/},{name:"delimiter",pattern:/^(\/|\?)/,regex:function(e){return new RegExp("\\"+e[0])}},{name:"sub-delimiter",pattern:/^(!|&|-|_|\.|;)/,regex:function(e){return new RegExp(e[0])}},{name:"fragment",pattern:/^([0-9a-zA-Z]+)/,regex:function(e){return new RegExp(e[0])}}],q1=function t(e,n){n===void 0&&(n=[]);var r=H1.some(function(s){var i=e.match(s.pattern);return i?(n.push({type:s.name,match:i[0],val:i.slice(1,2),otherVal:i.slice(2),regex:s.regex instanceof Function?s.regex(i):s.regex}),i[0].length0,this.hasSpatParam=this.tokens.filter(function(r){return/splat$/.test(r.type)}).length>0,this.hasMatrixParams=this.tokens.filter(function(r){return/matrix$/.test(r.type)}).length>0,this.hasQueryParams=this.tokens.filter(function(r){return/^query-parameter/.test(r.type)}).length>0,this.spatParams=this.getParams("url-parameter-splat"),this.urlParams=this.getParams(/^url-parameter/),this.queryParams=this.getParams("query-parameter"),this.params=this.urlParams.concat(this.queryParams),this.source=this.tokens.filter(function(r){return r.regex!==void 0}).map(function(r){return r.regex.source}).join("")}return t.createPath=function(e,n){return new t(e,n)},t.prototype.isQueryParam=function(e){return this.queryParams.indexOf(e)!==-1},t.prototype.isSpatParam=function(e){return this.spatParams.indexOf(e)!==-1},t.prototype.test=function(e,n){var r=this,s=Ze(Ze({caseSensitive:!1,strictTrailingSlash:!1},this.options),n),i=W1(this.source,s.strictTrailingSlash),a=this.urlTest(e,i+(this.hasQueryParams?"(\\?.*$|$)":"$"),s.caseSensitive,s.urlParamsEncoding);if(!a||!this.hasQueryParams)return a;var o=bi(e,s.queryParams),l=Object.keys(o).filter(function(c){return!r.isQueryParam(c)});return l.length===0?(Object.keys(o).forEach(function(c){return a[c]=o[c]}),a):null},t.prototype.partialTest=function(e,n){var r=this,s=Ze(Ze({caseSensitive:!1,delimited:!0},this.options),n),i=B1(this.source,s.delimited),a=this.urlTest(e,i,s.caseSensitive,s.urlParamsEncoding);if(!a||!this.hasQueryParams)return a;var o=bi(e,s.queryParams);return Object.keys(o).filter(function(l){return r.isQueryParam(l)}).forEach(function(l){return Z1(a,l,o[l])}),a},t.prototype.build=function(e,n){var r=this;e===void 0&&(e={});var s=Ze(Ze({ignoreConstraints:!1,ignoreSearch:!1,queryParams:{}},this.options),n),i=Object.keys(e).filter(function(d){return!r.isQueryParam(d)}).reduce(function(d,v){if(!Ya(e[v]))return d;var y=e[v],w=r.isSpatParam(v);return typeof y=="boolean"?d[v]=y:Array.isArray(y)?d[v]=y.map(function(g){return Yc(g,s.urlParamsEncoding,w)}):d[v]=Yc(y,s.urlParamsEncoding,w),d},{});if(this.urlParams.some(function(d){return!Ya(e[d])})){var a=this.urlParams.filter(function(d){return!Ya(e[d])});throw new Error("Cannot build path: '"+this.path+"' requires missing parameters { "+a.join(", ")+" }")}if(!s.ignoreConstraints){var o=this.tokens.filter(function(d){return/^url-parameter/.test(d.type)&&!/-splat$/.test(d.type)}).every(function(d){return new RegExp("^"+el(d.otherVal[0])+"$").test(i[d.val])});if(!o)throw new Error("Some parameters of '"+this.path+"' are of invalid format")}var l=this.tokens.filter(function(d){return/^query-parameter/.test(d.type)===!1}).map(function(d){return d.type==="url-parameter-matrix"?";"+d.val+"="+i[d.val[0]]:/^url-parameter/.test(d.type)?i[d.val[0]]:d.match}).join("");if(s.ignoreSearch)return l;var c=this.queryParams.filter(function(d){return Object.keys(e).indexOf(d)!==-1}).reduce(function(d,v){return d[v]=e[v],d},{}),f=Dm(c,s.queryParams);return f?l+"?"+f:l},t.prototype.getParams=function(e){var n=e instanceof RegExp?function(r){return e.test(r.type)}:function(r){return r.type===e};return this.tokens.filter(n).map(function(r){return r.val[0]})},t.prototype.urlTest=function(e,n,r,s){var i=this,a=new RegExp("^"+n,r?"":"i"),o=e.match(a);if(o){if(!this.urlParams.length)return{}}else return null;return o.slice(1,this.urlParams.length+1).reduce(function(l,c,f){return l[i.urlParams[f]]=V1(c,s),l},{})},t}(),Mm=function(e){var n="";return e.reduce(function(r,s){var i,a,o,l,c=(a=(i=s.parser)===null||i===void 0?void 0:i.urlParams.reduce(function(d,v){return d[v]="url",d},{}),a??{}),f=(l=(o=s.parser)===null||o===void 0?void 0:o.queryParams.reduce(function(d,v){return d[v]="query",d},c),l??{});return s.name!==void 0&&(n=n?n+"."+s.name:s.name,r[n]=f),r},{})},Y1=function(e){if(!e||!e.segments||!e.segments.length)return null;var n=e.segments.map(function(s){return s.name}).filter(function(s){return s}).join("."),r=e.params;return{name:n,params:r,meta:Mm(e.segments)}},K1=function(e,n,r){n===void 0&&(n={}),r===void 0&&(r={});for(var s=r.queryParamsMode,i=s===void 0?"default":s,a=r.trailingSlashMode,o=a===void 0?"default":a,l=[],c=[],f=0,d=e;f/g,"").split("?")[0].replace(/(.+)\/$/,"$1"),d=r.path.replace(/<.*?>/g,"").split("?")[0].replace(/(.+)\/$/,"$1");if(f==="/")return 1;if(d==="/")return-1;if(!((s=n.parser)===null||s===void 0)&&s.hasSpatParam)return 1;if(!((i=r.parser)===null||i===void 0)&&i.hasSpatParam)return-1;var v=(f.match(/\//g)||[]).length,y=(d.match(/\//g)||[]).length;if(vy)return-1;var w=(o=(a=n.parser)===null||a===void 0?void 0:a.urlParams.length,o??0),g=(c=(l=r.parser)===null||l===void 0?void 0:l.urlParams.length,c??0);if(wg)return 1;var k=(f.split("/").slice(-1)[0]||"").length,m=(d.split("/").slice(-1)[0]||"").length;return km?-1:e.indexOf(n)-e.indexOf(r)}},Gc=function(){function t(e,n,r,s){return e===void 0&&(e=""),n===void 0&&(n=""),r===void 0&&(r=[]),s===void 0&&(s={}),this.name=e,this.absolute=/^~/.test(n),this.path=this.absolute?n.slice(1):n,this.parser=this.path?new Kc(this.path):null,this.children=[],this.parent=s.parent,this.checkParents(),this.add(r,s.onAdd,s.finalSort?!1:s.sort!==!1),s.finalSort&&this.sortDescendants(),this}return t.prototype.getParentSegments=function(e){return e===void 0&&(e=[]),this.parent&&this.parent.parser?this.parent.getParentSegments(e.concat(this.parent)):e.reverse()},t.prototype.setParent=function(e){this.parent=e,this.checkParents()},t.prototype.setPath=function(e){e===void 0&&(e=""),this.path=e,this.parser=e?new Kc(e):null},t.prototype.add=function(e,n,r){var s=this;if(r===void 0&&(r=!0),e==null)return this;if(e instanceof Array)return e.forEach(function(o){return s.add(o,n,r)}),this;if(!(e instanceof t)&&!(e instanceof Object))throw new Error("RouteNode.add() expects routes to be an Object or an instance of RouteNode.");if(e instanceof t)e.setParent(this),this.addRouteNode(e,r);else{if(!e.name||!e.path)throw new Error("RouteNode.add() expects routes to have a name and a path defined.");var i=new t(e.name,e.path,e.children,{finalSort:!1,onAdd:n,parent:this,sort:r}),a=i.getParentSegments([i]).map(function(o){return o.name}).join(".");n&&n(Ze(Ze({},e),{name:a})),this.addRouteNode(i,r)}return this},t.prototype.addNode=function(e,n){return this.add(new t(e,n)),this},t.prototype.getPath=function(e){var n=this.getSegmentsByName(e);return n?G1(n):null},t.prototype.getNonAbsoluteChildren=function(){return this.children.filter(function(e){return!e.absolute})},t.prototype.sortChildren=function(){this.children.length&&tw(this.children)},t.prototype.sortDescendants=function(){this.sortChildren(),this.children.forEach(function(e){return e.sortDescendants()})},t.prototype.buildPath=function(e,n,r){n===void 0&&(n={}),r===void 0&&(r={});var s=this.getSegmentsByName(e);if(!s)throw new Error("[route-node][buildPath] '{routeName}' is not defined");return K1(s,n,r)},t.prototype.buildState=function(e,n){n===void 0&&(n={});var r=this.getSegmentsByName(e);return!r||!r.length?null:{name:e,params:n,meta:Mm(r)}},t.prototype.matchPath=function(e,n){n===void 0&&(n={}),e===""&&!n.strictTrailingSlash&&(e="/");var r=this.getSegmentsMatchingPath(e,n);if(!r)return null;var s=r.segments;if(s[0].absolute){var i=s[0].getParentSegments();s.reverse(),s.push.apply(s,i),s.reverse()}var a=s[s.length-1],o=a.findSlashChild();return o&&s.push(o),Y1(r)},t.prototype.addRouteNode=function(e,n){n===void 0&&(n=!0);var r=e.name.split(".");if(r.length===1){if(this.children.map(function(i){return i.name}).indexOf(e.name)!==-1)throw new Error('Alias "'+e.name+'" is already defined in route node');if(this.children.map(function(i){return i.path}).indexOf(e.path)!==-1)throw new Error('Path "'+e.path+'" is already defined in route node');this.children.push(e),n&&this.sortChildren()}else{var s=this.getSegmentsByName(r.slice(0,-1).join("."));if(s)e.name=r[r.length-1],s[s.length-1].add(e);else throw new Error("Could not add route named '"+e.name+"', parent is missing.")}return this},t.prototype.checkParents=function(){if(this.absolute&&this.hasParentsParams())throw new Error("[RouteNode] A RouteNode with an abolute path cannot have parents with route parameters")},t.prototype.hasParentsParams=function(){if(this.parent&&this.parent.parser){var e=this.parent.parser,n=e.hasUrlParams||e.hasSpatParam||e.hasMatrixParams||e.hasQueryParams;return n||this.parent.hasParentsParams()}return!1},t.prototype.findAbsoluteChildren=function(){return this.children.reduce(function(e,n){return e.concat(n.absolute?n:[]).concat(n.findAbsoluteChildren())},[])},t.prototype.findSlashChild=function(){var e=this.getNonAbsoluteChildren().filter(function(n){return n.parser&&/^\/(\?|$)/.test(n.parser.path)});return e[0]},t.prototype.getSegmentsByName=function(e){var n=function(l,c){var f=c.filter(function(d){return d.name===l});return f.length?f[0]:void 0},r=[],s=this.parser?[this]:this.children,i=(this.parser?[""]:[]).concat(e.split(".")),a=i.every(function(o){var l=n(o,s);return l?(s=l.children,r.push(l),!0):!1});return a?r:null},t.prototype.getSegmentsMatchingPath=function(e,n){var r=this.parser?[this]:this.children,s=r.reduce(function(o,l){return o.concat(l,l.findAbsoluteChildren())},[]),i={segments:[],params:{}},a=ew(s,e,i,n);return a&&a.segments.length===1&&a.segments[0].name===""?null:a},t}();function rw(t){var e,n=t.Symbol;return typeof n=="function"?n.observable?e=n.observable:(e=n("observable"),n.observable=e):e="@@observable",e}var An;typeof self<"u"?An=self:typeof window<"u"?An=window:typeof global<"u"?An=global:typeof nl<"u"?An=nl:An=Function("return this")();var Jc=rw(An);/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. All rights reserved. +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 + +THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +MERCHANTABLITY OR NON-INFRINGEMENT. + +See the Apache Version 2.0 License for specific language governing permissions +and limitations under the License. +***************************************************************************** */var F=function(){return F=Object.assign||function(e){for(var n,r=1,s=arguments.length;ri.includes(c.id||"")),o=a.filter(c=>c.action==="add"),l=a.filter(c=>c.action==="remove");return await e.changeRoutes(o,l),Promise.reject({redirect:{name:"cas",params:{ca:e.ca}}})}if(t.name==="cas.aspas.delete"&&t.params.customer&&await e.deleteAspa(t.params))return Promise.reject({redirect:{name:"cas.aspas",params:{ca:e.ca}}});if((t.name==="cas.aspas.add"||t.name==="cas.aspas.add_new"||t.name==="cas.aspas.edit")&&t.params.customer)return await e.addAspa(t.params)?Promise.reject({redirect:{name:"cas.aspas",params:{ca:e.ca}}}):Promise.reject({redirect:{name:t.name,params:{ca:e.ca,id:t.params.id}}});if(t.name==="cas.parents.add"&&t.params.name&&await e.addParent(t.params))return Promise.reject({redirect:{name:"cas.parents",params:{ca:e.ca}}});if(t.name==="cas.repository.add"&&t.params.response&&await e.addRepository(t.params))return Promise.reject({redirect:{name:"cas.repository",params:{ca:e.ca}}});if(await e.loadCas(),((n=e.cas)==null?void 0:n.length)===0&&t.name!=="onboarding")return Promise.reject({redirect:{name:"onboarding"}});if(t.name==="onboarding"&&t.params.name&&await e.addCa(t.params.name))return Promise.reject({redirect:{name:"cas.repository",params:{ca:e.ca}}});if(e.ca&&((r=e.cas)!=null&&r.length)&&!((s=e.cas)!=null&&s.includes(e.ca)))return Promise.reject({redirect:{name:"cas",params:{ca:e.cas[0]}}});if(t.name==="home"&&e.ca)return Promise.reject({redirect:{name:"cas",params:{ca:e.ca}}});t.name.startsWith("cas")&&await Promise.all([e.loadCa(),e.loadParents(),e.loadRepoStatus()])}}async function Aw(t,e){t.params.locale&&(await e.setLocale(t.params.locale),delete t.params.locale)}function Fw(t){return async e=>{const n=t.getDependencies().store;try{await Aw(e,n),n.translations===null&&await n.loadTranslations(),await Mw(e,n),await Lw(e,n)}catch(r){return Promise.reject(r)}return n.storePersistedData(),e}}const Ln="/ui",zw=[{name:"home",path:Ln},{name:"onboarding",path:`${Ln}/onboarding`},{name:"cas",path:`${Ln}/cas/:ca`,children:[{name:"add_new",path:"/add"},{name:"add",path:"/add/:id"},{name:"delete",path:"/delete/:id"},{name:"edit",path:"/edit/:id"},{name:"change",path:"/change"},{name:"aspas",path:"/aspas",children:[{name:"add_new",path:"/add"},{name:"add",path:"/add/:id"},{name:"edit",path:"/edit/:id"},{name:"delete",path:"/delete/:id"}]},{name:"parents",path:"/parents",children:[{name:"add",path:"/add"}]},{name:"repository",path:"/repos",children:[{name:"add",path:"/add"}]},{name:"analyse",path:"/analyse"}]},{name:"testbed",path:`${Ln}/testbed`,children:[{name:"del_ca",path:"/remove"},{name:"add_pub",path:"/register-publisher"},{name:"del_pub",path:"/remove-publisher"}]},{name:"login",path:`${Ln}/login`},{name:"logout",path:`${Ln}/logout`}];function $w(t){const e=ww(zw,{allowNotFound:!0,queryParamsMode:"loose"});return e.setDependencies({store:t}),e.usePlugin(Iw()),e.useMiddleware(Fw),e}class bw{constructor(){oe(this,"notification",null);oe(this,"cas",null);oe(this,"ca",null);oe(this,"locale",xg);oe(this,"token",null);oe(this,"translations",null);oe(this,"caDetails",{});oe(this,"roas",{});oe(this,"aspas",{});oe(this,"suggestions",{});oe(this,"repoStatus",{});oe(this,"parents",{});oe(this,"userDetails",null);oe(this,"loginMethod",null);oe(this,"testBedEnabled",!1);oe(this,"api");this.api=new wm,this.loadPersistedState()}getAspas(e){let n=this.aspas&&this.ca&&this.aspas[this.ca]||[];if(e){if(e.search){const s=e.search.toLowerCase().split(/\s/);n=n.filter(i=>s.some(a=>i.customer.toString().includes(a))||s.some(a=>i.providers.toString().includes(a)))}n=n.slice().sort((s,i)=>k0(s,i,e.sort,e.order));const r=(e.page-1)*e.limit;n=n.slice(r,r+e.limit)}return n}getRoas(e){let n=this.roas&&this.ca&&this.roas[this.ca]||[];if(n=n.filter(r=>!r.allowed_by),e){if(e.search){const s=e.search.toLowerCase().split(/\s/);n=n.filter(i=>s.some(a=>i.asn.toString().includes(a))||s.some(a=>i.prefix.includes(a))||s.some(a=>{var o;return i.state&&(i.state.includes(a)||((o=this.translations)==null?void 0:o.announcements.state[i.state].toLowerCase().includes(a)))}))}n=n.slice().sort((s,i)=>S0(s,i,e.sort,e.order));const r=(e.page-1)*e.limit;n=n.slice(r,r+e.limit)}return n}getSuggestions(e){let n=this.suggestions&&this.ca&&this.suggestions[this.ca]||[];return e&&(n=n.slice().sort((r,s)=>E0(r,s,e.sort,e.order))),n}async handleError(e){try{return await e()}catch(n){const r=n;return(r.status===401||r.status===403)&&this.setToken(null),this.setNotification({type:U.error,message:r.msg||"Error"}),!1}}loadPersistedState(){const e=window.localStorage.getItem("krill");if(this.setToken(window.sessionStorage.getItem("krillToken")),e!==null)try{const n=JSON.parse(e);this.ca=n.ca,this.locale=n.locale,this.userDetails=n.userDetails}catch(n){console.error(n)}}storePersistedData(){this.token?window.sessionStorage.setItem("krillToken",this.token):window.sessionStorage.removeItem("krillToken"),window.localStorage.setItem("krill",JSON.stringify({ca:this.ca,locale:this.locale,userDetails:this.userDetails}))}setLocale(e){return this.locale=e,this.loadTranslations()}async loadTranslations(){this.translations=await q0(this.locale)}async loadLoginMethod(){return this.loginMethod||await this.handleError(async()=>{this.loginMethod=await this.api.getLoginMethod()}),this.loginMethod}async loadTestBedEnabled(){return this.testBedEnabled||await this.handleError(async()=>{this.testBedEnabled=await this.api.getTestBedEnabled()}),this.testBedEnabled}async tryLogin(e,n){var r;try{const s=await this.api.postLogin(e,n);this.setNotification(null),this.setToken(s.token),this.setUserDetails({id:s.id,attributes:s.attributes})}catch{this.setUserDetails(null),this.setNotification({type:U.error,message:(r=this.translations)==null?void 0:r.login.error})}}async checkToken(){var e;if(this.token)try{this.setNotification(null),await this.api.checkToken(this.token)}catch{this.setToken(null),this.setUserDetails(null),this.storePersistedData(),this.setNotification({type:U.error,message:(e=this.translations)==null?void 0:e.login.error})}}async loadCas(e=!1){(this.cas!==null||!this.token)&&!e||await this.handleError(async()=>{this.cas=await this.api.getCas(),!this.ca&&this.cas.length>0&&(this.ca=this.cas[0])})}async addCa(e){return await this.handleError(async()=>(await this.api.postCas(e),await this.loadCas(!0),await this.loadCa(!0),!0))}async loadCa(e){!this.ca||this.ca&&this.caDetails[this.ca]&&this.roas[this.ca]&&e!==!0||await this.handleError(async()=>{if(this.ca!==null){const[n,r,s]=await Promise.all([this.api.getCaDetails(this.ca),this.api.getCaRoas(this.ca),this.api.getCaAspas(this.ca)]);this.caDetails[this.ca]=n,this.roas[this.ca]=r,this.aspas[this.ca]=s}})}async loadSuggestions(e){!this.ca||this.ca&&this.suggestions[this.ca]&&e!==!0||await this.handleError(async()=>{this.ca!==null&&(this.suggestions[this.ca]=await this.api.getCaSuggestions(this.ca))})}async refreshParents(){if(!this.ca)return;const e=this.ca;return await this.api.refreshCaParents(),new Promise(n=>{const r=setInterval(()=>{this.api.getCaParents(e).then(s=>{JSON.stringify(s)!==JSON.stringify(this.parents[e])&&(this.parents[e]=s,clearInterval(r),n(s))})},5e3)})}async loadParents(e){!this.ca||this.ca&&this.parents[this.ca]&&e!==!0||await this.handleError(async()=>{this.ca!==null&&(this.parents[this.ca]=await this.api.getCaParents(this.ca))})}async loadRepoStatus(e){!this.ca||this.ca&&this.repoStatus[this.ca]&&e!==!0||await this.handleError(async()=>{this.ca!==null&&(this.repoStatus[this.ca]=await this.api.getCaRepoStatus(this.ca))})}async refreshRepo(){if(!this.ca)return;const e=this.ca;return await this.api.refreshCaRepo(),new Promise(n=>{const r=setInterval(()=>{this.api.getCaRepoStatus(e).then(s=>{JSON.stringify(s)!==JSON.stringify(this.repoStatus[e])&&(this.repoStatus[e]=s,clearInterval(r),n(s))})},5e3)})}async changeRoutes(e,n){return this.ca===null?!1:await this.handleError(async()=>{var r;return await this.api.updateRoutes(this.ca,{added:e,removed:n}),await this.loadCa(!0),await this.loadSuggestions(!0),this.setNotification({type:U.success,message:(r=this.translations)==null?void 0:r.common.success}),!0})}async editRoute(e,n){if(this.ca===null||!this.roas[this.ca])return!1;const r=this.roas[this.ca].find(i=>i.id===e);if(!r)return!1;const s={...r,comment:n};return await this.handleError(async()=>{var i;return await this.api.updateRoutes(this.ca,{added:[s],removed:[]}),await this.loadCa(!0),this.setNotification({type:U.success,message:(i=this.translations)==null?void 0:i.caDetails.confirmation.commentUpdatedSuccess}),!0})}async addRoute(e){if(this.ca===null)return!1;const n={asn:parseInt(e.asn,10),prefix:e.prefix,comment:e.comment,max_length:parseInt(e.max_length,10)};return await this.handleError(async()=>{var r;return await this.api.updateRoutes(this.ca,{added:[n],removed:[]}),await this.loadCa(!0),this.setNotification({type:U.success,message:(r=this.translations)==null?void 0:r.caDetails.confirmation.addedSuccess}),!0})}async deleteRoute(e){if(this.ca===null)return!1;const n={asn:parseInt(e.asn,10),prefix:e.prefix,max_length:parseInt(e.max_length,10)};return await this.handleError(async()=>{var r;return await this.api.updateRoutes(this.ca,{added:[],removed:[n]}),await this.loadCa(!0),this.setNotification({type:U.success,message:(r=this.translations)==null?void 0:r.caDetails.confirmation.retiredSuccess}),!0})}async addAspa(e){if(this.ca===null)return!1;const n={customer:Number(e.customer),providers:e.providers.split(",").map(r=>Number(r))};return await this.handleError(async()=>{var r;return await this.api.updateAspas(this.ca,{add_or_replace:[n],remove:[]}),await this.loadCa(!0),this.setNotification({type:U.success,message:(r=this.translations)==null?void 0:r.aspas.confirmation.addedSuccess}),!0})}async deleteAspa(e){return this.ca===null?!1:await this.handleError(async()=>{var n;return await this.api.updateAspas(this.ca,{add_or_replace:[],remove:[Number(e.customer)]}),await this.loadCa(!0),this.setNotification({type:U.success,message:(n=this.translations)==null?void 0:n.aspas.confirmation.retiredSuccess}),!0})}async addParent(e){if(this.ca!==null)return await this.handleError(async()=>(await this.api.postParent(this.ca,e.name,e.response||""),await this.loadParents(!0),!0))}async addRepository(e){if(this.ca!==null)return await this.handleError(async()=>(await this.api.postRepository(this.ca,e.name,e.response||""),await this.loadRepoStatus(!0),!0))}setNotification(e){this.notification=e}setUserDetails(e){this.userDetails=e}setCa(e){this.ca=e}setToken(e){this.token=e,this.api.setToken(e)}}const Uw=new bw,Lm=$w(Uw),Vw=ph(document.getElementById("root"));Vw.render(u.jsx(pg,{router:Lm,children:u.jsx(P1,{})}));Lm.start()});export default Hw(); diff --git a/ui/assets/index-d02216b4.css b/ui/assets/index-d02216b4.css deleted file mode 100644 index ddd8357d..00000000 --- a/ui/assets/index-d02216b4.css +++ /dev/null @@ -1 +0,0 @@ -:root{--red: #f63107;--red-light: #fef0f0;--light: #fafafa;--light-bg: #f5f7fa;--grey-lighter: #ebeef5;--grey-light: #dcdfe6;--grey: #c0c4cc;--grey-dark: #999;--dark: #606266;--shadaw: 0 2px 12px 0 rgb(0 0 0 / 10%);--radius: .25rem;--success: #67c23a;--success-border: #e1f3d8;--success-bg: #f0f9eb;--warning: #e6a23c;--warning-border: #faecd8;--warning-bg: #fdf6ec;--error: #f56c6c;--error-border: #fbc4c4;--error-bg: #fbe7e7}@font-face{font-family:Inter;font-weight:100 900;font-display:swap;font-style:normal;font-named-instance:"Regular";src:url(/assets/Inter-roman.var-17fe38ab.woff2?v=3.19) format("woff2")}@font-face{font-family:Inter;font-weight:100 900;font-display:swap;font-style:italic;font-named-instance:"Italic";src:url(/assets/Inter-italic.var-d1401419.woff2?v=3.19) format("woff2")}.center-form{max-width:30rem;margin:2rem auto}.center-form img{display:block;margin:2rem auto;width:8rem}.center-form h2{text-align:center;font-weight:500;margin-bottom:2rem}.center-form label{margin-top:1rem;display:block}.center-form input{width:100%;margin-bottom:1rem}.center-form button{float:right}label{line-height:2.5rem;color:var(--dark);font-size:.9rem;margin-right:1rem}label.required:before{content:"*";color:var(--red);margin-right:.3rem}input,textarea{border:1px solid var(--grey-light);border-radius:var(--radius);line-height:2.5rem;padding:0 .75rem;transition:border .3s;font-size:.9rem;color:var(--dark)}textarea{padding:.75rem;margin-bottom:1rem;line-height:1.4}input:focus,input:active,textarea:focus,textarea:active{border-color:var(--red);outline:none}input::placeholder{color:var(--grey-light)}input[type=search]{margin:1rem 0;line-height:1.5rem;padding-left:1.75rem;background:url(/assets/search-4a30d812.svg) no-repeat center left .5rem;background-size:.8rem;font-size:.8rem;width:25rem;max-width:100%}input::placeholder{color:var(--grey);opacity:1}input[disabled]{background-color:#eee}#upload{display:none}input::-webkit-outer-spin-button,input::-webkit-inner-spin-button{-webkit-appearance:none}input[type=number]{-moz-appearance:textfield}.button{display:inline-block;border:none;background:var(--red);border-radius:var(--radius);line-height:2.5rem;font-size:.9rem;padding:0 1rem;color:#fff;white-space:nowrap;cursor:pointer;vertical-align:text-bottom}a.button{text-decoration:none}.button.outline{color:var(--dark);background:white;border:1px solid var(--grey-dark)}.button.light{color:var(--dark);background:white}.button.right{float:right}.button:hover{opacity:.8}.button.icon{position:relative;line-height:1.5rem;height:1.5rem;width:3rem;border-radius:.75rem}.button.icon img{position:absolute;width:.75rem;height:.75rem;top:50%;left:50%;transform:translate(-50%,-50%)}.button.icon.large{height:2rem}.button.icon.large img{width:1rem;height:1rem}.button+.button{margin-left:.75rem}.button.inverted{padding:0;color:var(--red);background:none}.select{position:relative;display:inline-block;width:10rem}.select.wide{width:20rem}.select button{width:100%;background:white;border:1px solid white;height:2rem;line-height:1rem;text-align:left;color:var(--dark);border:1px solid var(--grey-light);cursor:pointer;border-radius:var(--radius);outline:none;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;padding-right:2rem}.select button:after,button.expand:after{content:" ";position:absolute;right:.7rem;top:.7rem;display:block;width:.7rem;height:.7rem;border-bottom:1px solid var(--grey-dark);border-right:1px solid var(--grey-dark);transform:translate(-50%,-25%) rotate(45deg);transition:transform .2s}.select button:hover,.select button.open{border:1px solid var(--red)}.select button.open:after{transform:translate(-50%,25%) rotate(-135deg)}.select ul{padding:0;margin:0;position:absolute;display:block;top:2.5rem;background:white;width:100%;border:0 solid var(--light);box-shadow:var(--shadaw);border-radius:var(--radius);max-height:0;overflow-x:hidden;overflow-y:auto;z-index:10}.select ul.show{padding:.5rem 0;border-width:1px;max-height:20rem}.select ul li{padding:0 1rem;line-height:2rem;font-size:.9rem;cursor:pointer}.select ul li:hover{background-color:var(--light)}.select ul li.selected{background-color:var(--light);color:var(--red);font-weight:600}html,body{height:100%}#root{height:100%;display:flex;flex-direction:column}#root .content{flex:1}header{background-color:var(--red);display:flex;height:4rem;justify-content:space-between}header h1{display:block;width:10rem;background:url(/assets/krill_logo_white-05224433.svg) no-repeat}header h1 span{display:none}header menu{display:flex;padding:0 1rem}header menu>button{border:none;background:none;margin-left:1rem;width:2rem;height:2rem;cursor:pointer}header menu>button img{width:1rem;height:1rem}header menu>button:hover img{opacity:.8}.content{padding:2rem}footer{background-color:var(--light);color:var(--grey-dark);height:2.5rem;line-height:1.5rem;font-size:.8rem;padding:.5rem 1rem;display:flex;justify-content:space-between}footer a{font-weight:600;text-decoration:none;color:var(--grey-dark)}.user-attribute{text-transform:capitalize}.content.route-login{position:relative;overflow:hidden}.content.route-login:before{content:" ";position:absolute;left:0;bottom:0;width:550px;height:260px;background:url(/assets/route-left-c88b44cb.svg) no-repeat top left -30px;z-index:-1}.content.route-login:after{content:" ";position:absolute;right:0;top:0;width:360px;height:100%;background:url(/assets/route-right-17b0c46a.svg) no-repeat top -30px left;z-index:-1}.login{position:relative;width:35rem;max-width:100%;margin:4rem auto;padding:3rem;display:flex;justify-content:center;background:white}.login>*{margin:0 .5rem}.login.vertical-form{flex-direction:column;padding:2rem}.login.vertical-form label,.login.vertical-form input{display:block;width:100%}.login.vertical-form>div+div{margin-top:1rem}.login.vertical-form .button{display:block;margin:1rem auto}html{box-sizing:border-box;font-size:16px;font-family:Inter,sans-serif}body{font-size:16px}*,*:before,*:after{box-sizing:inherit}body,h1,h2,h3,h4,h5,h6,p,ol,ul{margin:0;padding:0;font-weight:400}ol,ul{list-style:none}img{max-width:100%;height:auto}h2{font-weight:300}input,button,select{font-family:Inter,sans-serif}a{color:var(--red);font-weight:300}.roa-table{width:100%;color:var(--dark);border-collapse:collapse;font-size:.8rem}.roa-table tr td,.roa-table tr th{border-bottom:1px solid var(--grey-lighter);padding:.5rem}.roa-table>thead>tr>th{cursor:pointer}table .asc,table .desc{display:inline-block;width:0;height:0;margin-left:.5rem;margin-bottom:2px}table .asc{border-bottom:5px solid var(--red);border-left:5px solid transparent;border-right:5px solid transparent}table .desc{border-top:5px solid var(--red);border-left:5px solid transparent;border-right:5px solid transparent}.roa-table>tbody>tr>td:first-child{position:relative;width:4rem}.roa-table tr td.actions{text-align:right}.roa-table tr.announcements td{background:var(--light-bg)}.roa-table tr th{font-weight:600;text-align:left;color:var(--grey-dark)}.roa-table .expand{position:absolute;display:block;top:50%;left:50%;transform:translate(-50%,-50%);width:2rem;height:2rem;border:none;cursor:pointer;background:none}.roa-table .expand:after{transform:translate(-50%,-25%) rotate(-45deg)}.roa-table .expand.open:after{transform:translate(-50%,-25%) rotate(45deg)}.roa-table .state{display:inline-block;padding:.25rem .5rem;border:1px solid var(--grey-dark);color:var(--grey-dark);border-radius:var(--radius);background:white}.roa-table .state.roa_seen{color:var(--success);border-color:var(--success-border)}.roa-table .state.roa_disallowing,.roa-table .state.roa_unseen{color:var(--warning);border-color:var(--warning-border)}.roa-table .state.announcement_invalid_length,.roa-table .state.announcement_invalid_asn{color:var(--error);border-color:var(--error-border)}.roa-table .row{background:white}.roa-table .row>div{padding:1.5rem;flex:1}.roa-table .row h3{font-size:.8rem;font-weight:600;margin-bottom:1rem}.roa-table .row table{width:100%;border-collapse:collapse}.roa-table .row table tr td{background:white}.roa-table input[type=checkbox]{border:1px solid var(--grey-dark);box-shadow:none;border-radius:2px;cursor:pointer;padding:.5rem;width:auto}.roa-table .add,.roa-table .remove{display:inline-block;border:1px solid;border-radius:.1rem;padding:.1rem .5rem}.roa-table .add img,.roa-table .remove img{width:.8rem;height:.8rem}.roa-table .add{background-color:#f0f9eb;border-color:#e1f3d8}.roa-table .remove{background-color:#fef0f0;border-color:#fde2e2}.notification{background:white;padding:1.5rem 3.5rem;background-repeat:no-repeat;background-position:center left 1rem;background-size:1.5rem;border-radius:var(--radius);display:flex;align-items:center}.notification.popup{position:fixed;z-index:1000;top:1rem;right:1rem;max-width:30rem;min-width:20rem;box-shadow:0 .5rem 1rem #0006}.notification.error{background-image:url(/assets/error-fd1fc7e1.svg);background-color:snow;color:#600}.notification.success{background-image:url(/assets/check-3e734f78.svg);background-color:#fafffa;color:#060}.notification .close{position:absolute;background:none;border:none;top:.5rem;right:1rem;font-size:1.5rem;opacity:.4;cursor:pointer}.info-table{background:var(--light-bg);color:var(--dark);font-size:.9rem;line-height:1.4;padding:1rem;margin-bottom:1rem}.info-table table{width:100%;background-color:#fff;margin-bottom:1rem}.info-table h4{font-size:1rem;color:#000;font-size:1.2rem;margin-bottom:.75rem}.info-table th,.info-table td{padding:1rem}.info-table th{text-align:left;width:10rem;font-weight:600}.info-table .failure,.info-table .success{display:block;padding-left:2rem;margin-top:.5rem;background:no-repeat top left;background-size:1.2rem;min-height:2rem}.info-table .failure{background-image:url(/assets/error-fd1fc7e1.svg)}.info-table .success{background-image:url(/assets/check-3e734f78.svg)}.ca-details{margin-left:3rem;min-width:20rem;align-self:flex-start;padding:2rem 2rem 4rem}.ca-details table{width:100%;color:var(--dark);border-collapse:collapse;font-size:.8rem;line-height:2;text-align:left}.ca-details table th{font-weight:600;vertical-align:top}.ca-details table th,.ca-details table td{padding:.5rem 1rem .5rem 0;border-bottom:1px solid var(--grey-lighter)}.roa-actions{display:flex;margin-top:1rem;justify-content:space-between}.pop{position:relative}.pop>div{padding:0 1rem;text-align:left;max-height:0;position:absolute;display:block;top:2.5rem;right:-2.5rem;background:white;width:12rem;border:0 solid var(--light);box-shadow:var(--shadaw);border-radius:var(--radius);transition:all .3s;overflow:hidden;z-index:10}.pop:hover>div{padding:1rem;max-height:20rem}.pop>div h5{font-weight:600;font-size:1rem;margin-bottom:1rem}.pop>div table{width:100%;border:none;border-collapse:collapse}.pop>div th,.pop>div td{padding:0 0 .5rem}.loader{position:absolute;background:var(--red);top:0;left:0;right:0;width:100%;height:.5rem;overflow:hidden}@keyframes loading{0%{left:-10%;right:100%}to{right:-10%;left:100%}}.loader:after{content:" ";display:block;position:absolute;top:0;left:0;width:10%;height:.5rem;background:var(--red-light);animation:loading 2s infinite ease-in-out}.loader span{display:none}.pagination{display:flex;margin-top:1rem;justify-content:flex-end}.pagination>div{display:flex}.pagination select{border:1px solid var(--grey-light);color:var(--dark);padding:0 .5rem;background:white;border-radius:var(--radius);cursor:pointer;width:8rem}.pagination button{position:relative;margin-left:.5rem;border:none;color:var(--dark);background:var(--light-bg);font-weight:600;width:2rem;height:2rem;line-height:2rem;text-align:center;cursor:pointer}.pagination button:disabled{cursor:default;color:var(--grey)}.pagination button.number.current{opacity:1;color:#fff;background:var(--red)}.pagination .arrow:after{content:" ";position:absolute;left:55%;top:50%;display:block;width:.5rem;height:.5rem;border-bottom:2px solid var(--grey-dark);border-right:2px solid var(--grey-dark);transform:translate(-50%,-50%) rotate(135deg);transition:transform .2s}.pagination .number:hover:not(:disabled){color:var(--red)}.pagination .arrow:hover:not(:disabled):after{border-color:var(--red)}.pagination .arrow span{display:none}.pagination .arrow.next:after{left:45%;transform:translate(-50%,-50%) rotate(-45deg)}.tabs{border-bottom:2px solid var(--grey-light);display:flex;margin-bottom:1rem}.tabs li a{padding:1rem;display:inline-block;background:transparent;border:none;font-size:.8rem;font-family:Inter,sans-serif;cursor:pointer;color:#000;text-decoration:none}.tabs li a.active{color:var(--red);margin-bottom:-2px;border-bottom:2px solid var(--red)}.tabs li a:hover{color:var(--red)}.card{border:1px solid var(--grey-lighter);box-shadow:var(--shadaw);border-radius:var(--radius)}.message{width:35rem;border-radius:var(--radius);display:block;margin:4rem auto -2rem;padding:1rem}.message.error{background:var(--red-light);color:var(--red)}.space-between{display:flex;justify-content:space-between}.border-bottom{padding-bottom:1rem;margin-bottom:1rem;border-bottom:1px solid var(--grey-lighter)}.badge{display:inline-block;padding:0 .25rem;border:1px solid var(--grey-dark);color:var(--grey-dark);border-radius:var(--radius);margin-left:.5rem}.badge.success{color:var(--success);border-color:var(--success-border);background:var(--success-bg)}.badge.warning{color:var(--warning);border-color:var(--warning-border);background:var(--warning-bg)}.muted{padding:.5rem;display:block;color:var(--grey-dark);text-align:center}.row{display:flex}@media (max-width: 992px){.row{flex-direction:column}}.flex-1{flex:1}.modal{position:fixed;z-index:100;top:0;left:0;right:0;bottom:0;background-color:#00000080;color:var(--dark);display:flex;align-items:center;justify-content:center}.modal>div{min-width:40rem;min-height:10rem;width:auto;height:auto;max-width:100%;max-height:100%;background:white;border-radius:var(--radius);box-shadow:var(--shadaw);padding:1.5rem;overflow-x:hidden;overflow-y:auto;display:flex;flex-direction:column}.modal h3{font-weight:300;font-size:1.5rem;margin-bottom:1.5rem;color:#000}.modal p{flex:1}.modal .actions{margin-top:3rem;text-align:right}.modal label,.modal input,.modal textarea{display:block;width:100%}.modal textarea{width:40rem;max-height:100%;height:10rem;font-family:monospace;line-height:1.4}.modal label{margin-top:1rem}.modal table{margin-top:1rem;width:50rem;max-width:100%}.testbed{max-width:70rem;margin:2rem auto}.testbed img.hero{display:block;margin:3rem auto;width:8rem}.testbed form,.testbed .testbed-result{border:2px solid var(--grey-light);border-top:0;padding:1rem 2rem 2rem;background-color:#fdfdfd}.testbed .testbed-result pre{border:1px solid var(--grey-light);border-radius:var(--radius);font-size:.9rem;white-space:pre-wrap;background:white;padding:1rem}.testbed form a{margin-left:.5rem}.testbed form:after{content:"";clear:both;display:table}.testbed ul{margin-bottom:0}.testbed h2{font-weight:500;text-align:center;margin-bottom:2rem}.testbed h3{font-weight:500;margin-bottom:1rem}.testbed p{margin-bottom:1rem}.testbed label{margin-top:1rem;display:block}.testbed input,.testbed textarea{width:100%}.testbed textarea{height:10rem}.testbed button[type=submit]{margin-top:2rem;float:right}.testbed .actions{text-align:right} diff --git a/ui/assets/nl-7e5a6fa0.js b/ui/assets/nl-7e5a6fa0.js new file mode 100644 index 00000000..c5ee3017 --- /dev/null +++ b/ui/assets/nl-7e5a6fa0.js @@ -0,0 +1 @@ +const e={common:{readthedocs:"Read the Docs",report:"Meld een probleem",confirm:"Bevestig",cancel:"Annuleer",ok:"OK",error:"Fout",success:"Geslaagd!",copy:"Kopiëer naar klembord",download:"Download",dropOrClick:"Sleep een bestand hierheen of klik om te uploaden",started:"Krill is actief sinds",newversion:"Nieuwe versie beschikbaar!",supportcontracts:"Ondersteuningscontracten",warning:"Waarschuwing",idle:"U bent uitgelogd wegens inactiviteit.",nodata:"Geen data",copySuccess:"De XML is naar uw klembord gekopiëerd",edit:"Edit",page:"pagina",userInfo:{title:"Logingegevens",user:"Gebruiker"}},login:{password:"Wachtwoord",placeholder:"Uw wachtwoord",signin:"Log In",required:"Voer alstublieft uw wachtwoord in",error:"Het wachtwoord is niet correct",copied:"Gebruik geen wachtwoorden van https://xkcd.com/936/",id:"Gebruiker",idPlaceholder:"Uw gebruikersnaam",idRequired:"Voer uw gebruikersnaam in",retry:"Klik {0} om terug te gaan naar de login pagina.",here:"hier"},onboarding:{welcome:"Welkom bij Krill",welcomeHtml:"Laten we beginnen met aanmaken van uw RPKI Certificaatautoriteit (CA). Het zal worden gebruikt om gedelegeerde RPKI te configureren met een of meerdere bovenliggende CA's, over het algemeen uw Regionaal of Nationaal Internet Register.

De naam die u kiest identificeert uw CA tijdens interacties met bovenliggende of ondergeschikte CA's. De gekozen naam wordt niet gepubliceerd in de RPKI. Kies een naam die anderen helpen om uw organisatie te identificeren. Eenmaal ingesteld kan de naam niet worden gewijzigd.",addCAForm:{required:"Dit veld is verplicht",format:"Dit is geen geldige naam voor uw CA",confirm:"Creëer CA",confirmation:{title:"Waarschuwing",message:"De naam kan later niet worden gewijzigd. Doorgaan?"}}},cas:{loading:"Certificaatautoriteiten worden geladen",ca:"Certificaatautoriteit",cas:"Certificaatautoriteiten",search:"Zoek naar CA's...",noCas:"Er zijn op dit moment geen certificaatautoriteiten gedefinieerd."},caDetails:{loading:"{handle} wordt geladen",refresh:"Ververs {handle}, dit kan even duren",current:"Huidige certificaatautoriteit",download:"Download PEM",noRoas:"Geen ROAs gevonden.",noResources:"U heeft nog geen resources ontvangen",noChildren:"Geen ondergeschikte CA's gevonden.",addRoa:"Voeg ROA toe",addAspa:"Voeg ASPA toe",editAspa:"Pas ASPA aan",roas:"ROA's",aspas:"ASPA's",resources:"Resources",parents:"Bovenliggende CA's",repo:"Databank (repository)",type:"Type",properties:"Eigenschappen",property:"Eigenschap",value:"Waarde",kind:"Soort",resource:"Resource",children:"Children",handle:"Naam",comment:"Opmerking",maxLength:"Maximale Lengte",maxLengthTooltip:"Als er geen maximale lengte is gedefinieerd, wordt de lengte van de prefix gebruikt.",confirmation:{title:"Waarschuwing",message:"Hiermee wordt de ROA '{prefix}-{max_length} => {asn}' verwijderd. Doorgaan?",added:"ROA toegevoegd",retired:"ROA verwijderd",retiredSuccess:"De ROA is verwijderd",addedSuccess:"De ROA is toegevoegd",commentUpdatedSuccess:"ROA commentaar is gewijzigd"},addROAForm:{required:"Dit veld is verplicht",asn_format:"Dit is geen geldige ASN",prefix_format:"Vul alstublieft een geldige IPv4 of IPv6 prefix in"},onboardingWarning:"Om uw certificaat en ROAs te publiceren moet uw CA verbonden worden met een publieke RPKI databank (repository). Zodra de configuratie met de bovenliggende CA is voltooid, zal software gebruikt door de vertrouwende partijen (RPKI validators) direct beginnen met het downloaden en verifiëren van uw certificaat en ROAs die gepubliceerd zijn in deze databank.",initializeRepository:"Initialiseer alstublieft eerst uw RPKI databank (repository)",initialize:"Initialiseer alstublieft eerst uw RPKI databank (repository) en/of de bovenliggende CA.",noResourcesYet:"U heeft nog geen resources ontvangen",clickToRefresh:"Klik hier om te verversen",parentsTab:{request:"Child Request",response:"Parent Response",addParent:"Voeg een bovenliggende CA toe",addParentSuccess:"Bovenliggende CA toegevoegd",name:"Naam van de bovenliggende CA",namerequired:"Een naam voor de bovenliggende CA is verplicht",nameformat:"Dit is geen geldige naam"},repoTab:{request:"Publisher Request",response:"Repository Response",addRepo:"Initialiseer databank (repository)",addRepoSuccess:"Databank (repository) toegevoegd"},analyseThis:"Analyseer mijn ROAs",analysis:"ROA-analyse",suggestions:{following:"Controleer a.u.b. de volgende voorgestelde wijzigingen in uw ROAs.",readMore:"Lees meer..",nochanges:"We suggereren op dit moment niets te wijzigen",adding:"Toe te voegen",removing:"Te verwijderen",keep:"Houdt zoals het is",willResult:"Zal resulteren in",yourChoice:"Uw keuze",ourSuggestion:"Onze suggestie",ourSuggestionHelp:"Onze suggestie is gebaseerd op RIPE RIS informatie, gelieve te controleren!",addThis:"Voeg toe",removeThis:"Verwijder",willAdd:"Voeg deze ROA toe vanwege status",willRemove:"Verwijder deze ROA vanwege status",reasons:{not_found:"Niet gevonden",not_held:"ROA kan niet gepubliceerd worden, de prefix staat niet meer op uw certifica(a)t(en)",invalid_asn:"Ongeldig ASN",invalid_length:"Ongeldige lengte",stale:"Niet zichtbaar",disallowing:"Veroorzaakt ongeldige annoucements. Wellicht vervangen door AS0 ROA.",as0_redundant:"Overbodig",redundant:"Overbodig",too_permissive:"Te veroorlovend, kan misbruikt worden voor hijacks",specific:"Sta specifieke announcement toe ipv te veroorlovende ROA",new:"Nieuw"}},syncParents:"Synchroniseer met bovenliggende CA's",syncRepo:"Synchroniseer met databank (repository)",lastExchange:"Laatste uitwisseling",exchangeUri:"URI",nextExchange:"Volgende uitwisseling voor",allResources:"Uw gecertificeerde ASN en IP addressen",entitlements:"Gerechtigde addressen",showEntitlements:"Laat details zien",parentCertificate:"Parent Certificate",published:"Gepubliceerd"},aspas:{customer:"Klant-ASN",providers:"Aanbieder-ASNs",search:"Zoek voor klant-ASN, aanbieder-ASN...",confirmation:{title:"Waarschuwing",message:"Hiermee wordt de ASPA '{customer} => {providers}' verwijderd. Doorgaan?",added:"ASPA toegevoegd",retired:"ASPA verwijderd",retiredSuccess:"De ASPA is verwijderd",addedSuccess:"De ASPA is toegevoegd",commentUpdatedSuccess:"ASPA commentaar is gewijzigd"},customer_validation_format:"Het klant-ASN-formaat is ongeldig of de klant-ASN heeft al een ASPA",providers_validation_format:"Het aanbieders-ASN-formaat is ongeldig",add:"Add ASPA",edit:"Edit ASPA",analyse:"Analyse providers",detected_providers:"Declared providers",providers_missing:"ASNs observed in RIS but not in the provider list. Please verify that none of these ASNs act as your provider.",no_aspas:"Krill did not find any ASNs. You need an ASN to be able to create an ASPA for it."},announcements:{noRoasOrAnnouncements:"Geen ROAs of BGP-aankondigingen gevonden.",search:"Zoek naar ASN, prefix, status...",authorizes:"Autoriseert {number} aankondigingen",disallows:"Weigert {number} aankondigingen",asn:"ASN",prefix:"Prefix",stateLabel:"Status",state:{roa_seen:"ZICHTBAAR",roa_seen_help:"Deze ROA komt overeen met aankondigingen gezien in BGP",roa_unseen:"NIET ZICHTBAAR",roa_unseen_help:"We zien geen BGP aankondigingen overeenkomstig met deze ROA",roa_not_held:"PREFIX VERWIJDERD",roa_not_held_help:"Deze prefix staat niet meer op uw certifica(a)t(en), de ROA wordt niet gepubliceerd",roa_no_announcement_info:"GEEN AANKONDIGINGSINFORMATIE",roa_too_permissive:"TE VEROORLOVEND",roa_too_permissive_help:"Deze ROA komt overeen met aankondigingen gezien in BGP, maar staat ook additionele aankodigingen toe",roa_disallowing:"VEROORZAAKT ONGELDIGE AANKONDIGINGEN",roa_disallowing_help:"Deze ROA veroorzaakt ongeldige aankondigingen. Als dit uw bedoeling is gebruikt u wellicht beter een AS0 ROA.",roa_redundant:"OVERBODIG",roa_redundant_help:"Deze ROA is overbodig omdat u een of meer andere ROAs heeft voor de prefix, lengte en ASN",roa_as0:"AS0",roa_as0_help:"Deze ROA dient ervoor om alle aankondigingen van een prefix te verbieden",roa_as0_redundant:"OVERBODIG",roa_as0_redundant_help:"Deze AS0 ROA is overbodig omdat u een of meerdere andere ROAs heeft voor de prefix",announcement_not_found:"NIET GEVONDEN",announcement_not_found_help:"Deze BGP aankondiging wordt niet gedekt door uw ROAs",announcement_invalid_length:"ONGELDIGE LENGTE",announcement_invalid_length_help:"Deze BGP aankondigin is niet toegestaan, omdat de prefix specifieker is dan toegestaan voor dit ASN",announcement_invalid_asn:"ONGELDIG ASN",announcement_invalid_asn_help:"Deze BGP aankondigin is niet toegestaan, omdat de prefix enkel is toegestaan vanaf andere ASNs",announcement_disallowed:"DISALLOWED BY AS0",announcement_disallowed_help:"This announcement is not allowed because you have an AS0 ROA that disallows it"},download:"Download CSV"},deltaErrors:{duplicates:"ROA bestaat reeds",covered:"Overlappende ROA bestaat",notheld:"Niet uw prefix",unknowns:"ROA bestaat niet",invalid_length:"Invalide Lengte",covering:"Overlapt bestaande ROA",as0_exists:"Overlappende AS0 ROA bestaat",as0_overlaps:"Overlapt bestaande ROA"},errors:{repo_not_set:"U dient eerst een databank (repository) te configureren",pub_unknown:"Publisher '{publisher}' is niet bekend",pub_duplicate:"Publisher '{publisher}' is al geïnitialiseerd",pub_outside_jail:"Publisher uri '{uri}' ligt buiten de repository uri '{sia_base}'",pub_uri_no_slash:"Publisher uri '{uri}' moet eindigen met een slash",pub_no_embedded_repo:"Geen geïntegreerde databank (repository) geconfigureerd",ca_duplicate:"CA '{ca}' is reeds geïnitialiseerd",ca_unknown:"CA '{ca}' is onbekend",ca_repo_same:"Deze databank (repository) is al in gebruik",ca_repo_issue:"Foutmelding ontvangen van de databank (repository): {cause}",ca_repo_response_invalid_xml:"Repository response xml is ongeldig",ca_repo_response_wrong_xml:"Parent response in plaats van repository response ontvangen",ca_parent_duplicate:"U heeft al een bovenliggende CA met de naam '{parent}'",ca_parent_xml_duplicate:"Deze response XML is al in gebruik door een bovenliggende CA met de naam '{parent}'",ca_parent_unknown:"U heeft geen bovenliggende CA me de naam '{parent}'",ca_parent_issue:"Fout ontvangen van bovenliggende CA '{parent}': {cause}",ca_parent_response_invalid_xml:"Ongeldige parent response xml ontvangen",ca_parent_response_wrong_xml:"Repository response ontvangen tijdens het toevoegen van de bovenliggende CA",ca_child_duplicate:"U heeft al een ondergeschikte CA met de naam '{child}'",ca_child_unknown:"U heeft geen ondergeschikte CA met de naam '{child}'",ca_child_resources_required:"U dient resources op te geven voor ondegeschikte CA '{child}'",ca_roa_unknown:"Kan onbekende ROA '{prefix}-{max_length} => {asn}' niet verwijderen",ca_roa_duplicate:"ROA '{prefix}-{max_length} => {asn}' bestaat al",ca_roa_invalid_max_length:"Ongeldige maxLength in ROA '{prefix}-{max_length} => {asn}'",ca_roa_not_entitled:"ROA prefix '{prefix}' staat niet op een van uw huidige certificaten",ta_not_allowed:"Deze functionaliteit wordt niet ondersteund door het test-vertrouwensanker",ta_name_reserved:"Naam gereserveerd",ca_roa_delta_error:"ROA geweigerd om de volgende reden(en):",api_insufficient_rights:"U heeft onvoldoende rechten om deze actie uit te voeren. Neem contact op met uw beheerder.",api_invalid_credentials:"De ingevoerde login gegegens zijn incorrect.",api_login_error:"Er trad een fout op tijdens het inloggen: {cause}",api_auth_transient_error:"Er trad een tijdelijke fout op bij het verifiëren van uw verzoek. Probeert u het later nog eens.",api_auth_permanent_error:"Er trad een fout op bij het verifiëren van uw verzoek. Neem contact op met uw beheerder.",api_auth_session_expired:"Uw sessie is verlopen. Gelieve opnieuw in te loggen.",general_error:"Er trad een fout op. Neem contact op met uw beheerder."},testbed:{welcome:"Welkom bij de RPKI test omgeving",disclaimer:{heading:"Spelregels",body:"Deze test omgeving gebruikt een op zichzelf staande RPKI hierarchie en is bedoeld voor evaluatie doeleinden. U kunt hier uw test CA registreren met eender welke IP en ASN adressen. Er worden geen garanties gegeven over de beschikbaarheid van deze service. Als u problemen ondervindt, laat het ons dan weten."},rpconfighelp:{heading:"Test omgeving TAL",body:"Om de data uit deze test omgevinge te valideren, kunt u deze Trust Anchor Locator (TAL) configureren in uw validatie software. Merk op dat u deze TAL NOOIT in een productie omgeving gebruikt. Deze is enkel bedoeld voor tests."},regunreg:{heading:"(De-)Registreren",body:"

Gebruik het formulies om uw RPKI Certificate Authority (CA) als onderliggende CA onder een test CA te registreren.

Daarnaast kunt u uw CA hier registreren onder een Repository

Als u klaar bent testen, gelieve uw CA dan te de-registreren.

"},rfcdoclink:"Klik om de RFC-8183 documentatie voor deze XML te zien",childhandle:"Child Handle",publisherhandle:"Publisher Handle",responseXML:"Testbed response XML",addChild:{heading:"Registreer CA",requestXML:{label:"Child Request XML",placeholder:"Plak uw XML hier"},asnresources:{label:"ASN Resources",placeholder:"AS resources: bv. AS1, AS3-4"},ipv4resources:{label:"IPv4 Resources",placeholder:"IPv4 resources: bv. 192.168.0.0/16"},ipv6resources:{label:"IPv6 Resources",placeholder:"IPv6 resources: bv. 2001:db8::/32"},confirm:"Registreer CA",format:"Dit is geen valide child request XML",required:"Voegt u aub de child request XML toe",confirmation:{title:"Waarschuwing",message:"Weet u zeker dat u deze CA onder deze test omgeving wil registreren?"},success:"CA '{child_handle}' is toegevoegd aan de test omgeving.",registeranother:"Registreer nog een CA"},removeChild:{heading:"Deregistreer CA",placeholder:"Voer de naam van uw CA in",confirm:"Deregistreer CA",confirmation:{title:"Waarschuwing",message:"Weet u zeker dat u deze CA onder deze test omgeving wil deregistreren?"},success:"CA '{child_handle}' is verwijderd van de test omgeving."},addPublisher:{heading:"Registreer Publisher",requestXML:{label:"Publisher Request XML",placeholder:"Plak uw XML here"},confirm:"Registreer publisher",format:"Dit is geen valide publisher request XML",required:"Voegt u aub de publisher request XML toe",confirmation:{title:"Waarschuwing",message:"Weet u zeker dat u uw CA als publisher wil registreren?"},success:"Publisher '{publisher_handle}' is geregistreerd in de test omgeving.",registeranother:"Registreer nog een Publisher"},removePublisher:{heading:"Deregistreer Publisher",placeholder:"Voer de naam van de publisher in",confirm:"Deregistreer Publisher",confirmation:{title:"Waarschuwing",message:"Weet u zeker dat u uw CA als publisher wil deregistreren?"},success:"Publisher '{publisher_handle}' is gederegistreerd van de test omgeving."},errors:{invalid_xml:"Invalid XML: {err}",missing_xml_el:"Missing element {el}",missing_xml_child_el:"Missing child element {el} of element {parent}",missing_xml_attr:"Missing attribute {attr} on element {el}",empty_xml_el:"Element {el} cannot be empty",empty_xml_attr:"Attribute {attr} on element {el} cannot be empty",non_ascii_xml_el:"Element {el} mag geen non-ASCII karakters bevatten",child_handle_required:"CA naam is vereist",publisher_handle_required:"Publisher naam is vereist",non_base64_certificate_xml_el:"Element {el} must contain a correctly Base64 encoded self-signed X.509 BPKI certificate",invalid_registration_data:"Your registration details could not be parsed correctly"}}};export{e as translations}; diff --git a/ui/assets/nl-f91bc25c.js b/ui/assets/nl-f91bc25c.js deleted file mode 100644 index 767f4c3b..00000000 --- a/ui/assets/nl-f91bc25c.js +++ /dev/null @@ -1 +0,0 @@ -const e={common:{readthedocs:"Read the Docs",report:"Meld een probleem",confirm:"Bevestig",cancel:"Annuleer",ok:"OK",error:"Fout",success:"Geslaagd!",copy:"Kopiëer naar klembord",download:"Download",dropOrClick:"Sleep een bestand hierheen of klik om te uploaden",started:"Krill is actief sinds",newversion:"Nieuwe versie beschikbaar!",supportcontracts:"Ondersteuningscontracten",warning:"Waarschuwing",idle:"U bent uitgelogd wegens inactiviteit.",nodata:"Geen data",copySuccess:"De XML is naar uw klembord gekopiëerd",edit:"Edit",page:"pagina",userInfo:{title:"Logingegevens",user:"Gebruiker"}},login:{password:"Wachtwoord",placeholder:"Uw wachtwoord",signin:"Log In",required:"Voer alstublieft uw wachtwoord in",error:"Het wachtwoord is niet correct",copied:"Gebruik geen wachtwoorden van https://xkcd.com/936/",id:"Gebruiker",idPlaceholder:"Uw gebruikersnaam",idRequired:"Voer uw gebruikersnaam in",retry:"Klik {0} om terug te gaan naar de login pagina.",here:"hier"},onboarding:{welcome:"Welkom bij Krill",welcomeHtml:"Laten we beginnen met aanmaken van uw RPKI Certificaatautoriteit (CA). Het zal worden gebruikt om gedelegeerde RPKI te configureren met een of meerdere bovenliggende CA's, over het algemeen uw Regionaal of Nationaal Internet Register.

De naam die u kiest identificeert uw CA tijdens interacties met bovenliggende of ondergeschikte CA's. De gekozen naam wordt niet gepubliceerd in de RPKI. Kies een naam die anderen helpen om uw organisatie te identificeren. Eenmaal ingesteld kan de naam niet worden gewijzigd.",addCAForm:{required:"Dit veld is verplicht",format:"Dit is geen geldige naam voor uw CA",confirm:"Creëer CA",confirmation:{title:"Waarschuwing",message:"De naam kan later niet worden gewijzigd. Doorgaan?"}}},cas:{loading:"Certificaatautoriteiten worden geladen",ca:"Certificaatautoriteit",cas:"Certificaatautoriteiten",search:"Zoek naar CA's...",noCas:"Er zijn op dit moment geen certificaatautoriteiten gedefinieerd."},caDetails:{loading:"{handle} wordt geladen",refresh:"Ververs {handle}, dit kan even duren",current:"Huidige certificaatautoriteit",download:"Download PEM",noRoas:"Geen ROAs gevonden.",noResources:"U heeft nog geen resources ontvangen",noChildren:"Geen ondergeschikte CA's gevonden.",addRoa:"Voeg ROA toe",addAspa:"Voeg ASPA toe",editAspa:"Pas ASPA aan",roas:"ROA's",aspas:"ASPA's",resources:"Resources",parents:"Bovenliggende CA's",repo:"Databank (repository)",type:"Type",properties:"Eigenschappen",property:"Eigenschap",value:"Waarde",kind:"Soort",resource:"Resource",children:"Children",handle:"Naam",comment:"Opmerking",maxLength:"Maximale Lengte",maxLengthTooltip:"Als er geen maximale lengte is gedefinieerd, wordt de lengte van de prefix gebruikt.",confirmation:{title:"Waarschuwing",message:"Hiermee wordt de ROA '{prefix}-{max_length} => {asn}' verwijderd. Doorgaan?",added:"ROA toegevoegd",retired:"ROA verwijderd",retiredSuccess:"De ROA is verwijderd",addedSuccess:"De ROA is toegevoegd",commentUpdatedSuccess:"ROA commentaar is gewijzigd"},addROAForm:{required:"Dit veld is verplicht",asn_format:"Dit is geen geldige ASN",prefix_format:"Vul alstublieft een geldige IPv4 of IPv6 prefix in"},onboardingWarning:"Om uw certificaat en ROAs te publiceren moet uw CA verbonden worden met een publieke RPKI databank (repository). Zodra de configuratie met de bovenliggende CA is voltooid, zal software gebruikt door de vertrouwende partijen (RPKI validators) direct beginnen met het downloaden en verifiëren van uw certificaat en ROAs die gepubliceerd zijn in deze databank.",initializeRepository:"Initialiseer alstublieft eerst uw RPKI databank (repository)",initialize:"Initialiseer alstublieft eerst uw RPKI databank (repository) en/of de bovenliggende CA.",noResourcesYet:"U heeft nog geen resources ontvangen",clickToRefresh:"Klik hier om te verversen",parentsTab:{request:"Child Request",response:"Parent Response",addParent:"Voeg een bovenliggende CA toe",addParentSuccess:"Bovenliggende CA toegevoegd",name:"Naam van de bovenliggende CA",namerequired:"Een naam voor de bovenliggende CA is verplicht",nameformat:"Dit is geen geldige naam"},repoTab:{request:"Publisher Request",response:"Repository Response",addRepo:"Initialiseer databank (repository)",addRepoSuccess:"Databank (repository) toegevoegd"},analyseThis:"Analyseer mijn ROAs",analysis:"ROA-analyse",suggestions:{following:"Controleer a.u.b. de volgende voorgestelde wijzigingen in uw ROAs.",readMore:"Lees meer..",nochanges:"We suggereren op dit moment niets te wijzigen",adding:"Toe te voegen",removing:"Te verwijderen",keep:"Houdt zoals het is",willResult:"Zal resulteren in",yourChoice:"Uw keuze",ourSuggestion:"Onze suggestie",ourSuggestionHelp:"Onze suggestie is gebaseerd op RIPE RIS informatie, gelieve te controleren!",addThis:"Voeg toe",removeThis:"Verwijder",willAdd:"Voeg deze ROA toe vanwege status",willRemove:"Verwijder deze ROA vanwege status",reasons:{not_found:"Niet gevonden",not_held:"ROA kan niet gepubliceerd worden, de prefix staat niet meer op uw certifica(a)t(en)",invalid_asn:"Ongeldig ASN",invalid_length:"Ongeldige lengte",stale:"Niet zichtbaar",disallowing:"Veroorzaakt ongeldige annoucements. Wellicht vervangen door AS0 ROA.",as0_redundant:"Overbodig",redundant:"Overbodig",too_permissive:"Te veroorlovend, kan misbruikt worden voor hijacks",specific:"Sta specifieke announcement toe ipv te veroorlovende ROA",new:"Nieuw"}},syncParents:"Synchroniseer met bovenliggende CA's",syncRepo:"Synchroniseer met databank (repository)",lastExchange:"Laatste uitwisseling",exchangeUri:"URI",nextExchange:"Volgende uitwisseling voor",allResources:"Uw gecertificeerde ASN en IP addressen",entitlements:"Gerechtigde addressen",showEntitlements:"Laat details zien",parentCertificate:"Parent Certificate",published:"Gepubliceerd"},aspas:{customer:"Klant-ASN",providers:"Aanbieder-ASNs",search:"Zoek voor klant-ASN, aanbieder-ASN...",confirmation:{title:"Waarschuwing",message:"Hiermee wordt de ASPA '{customer} => {providers}' verwijderd. Doorgaan?",added:"ASPA toegevoegd",retired:"ASPA verwijderd",retiredSuccess:"De ASPA is verwijderd",addedSuccess:"De ASPA is toegevoegd",commentUpdatedSuccess:"ASPA commentaar is gewijzigd"},customer_validation_format:"Het klant-ASN-formaat is ongeldig of de klant-ASN heeft al een ASPA",providers_validation_format:"Het aanbieders-ASN-formaat is ongeldig"},announcements:{noRoasOrAnnouncements:"Geen ROAs of BGP-aankondigingen gevonden.",search:"Zoek naar ASN, prefix, status...",authorizes:"Autoriseert {number} aankondigingen",disallows:"Weigert {number} aankondigingen",asn:"ASN",prefix:"Prefix",stateLabel:"Status",state:{roa_seen:"ZICHTBAAR",roa_seen_help:"Deze ROA komt overeen met aankondigingen gezien in BGP",roa_unseen:"NIET ZICHTBAAR",roa_unseen_help:"We zien geen BGP aankondigingen overeenkomstig met deze ROA",roa_not_held:"PREFIX VERWIJDERD",roa_not_held_help:"Deze prefix staat niet meer op uw certifica(a)t(en), de ROA wordt niet gepubliceerd",roa_no_announcement_info:"GEEN AANKONDIGINGSINFORMATIE",roa_too_permissive:"TE VEROORLOVEND",roa_too_permissive_help:"Deze ROA komt overeen met aankondigingen gezien in BGP, maar staat ook additionele aankodigingen toe",roa_disallowing:"VEROORZAAKT ONGELDIGE AANKONDIGINGEN",roa_disallowing_help:"Deze ROA veroorzaakt ongeldige aankondigingen. Als dit uw bedoeling is gebruikt u wellicht beter een AS0 ROA.",roa_redundant:"OVERBODIG",roa_redundant_help:"Deze ROA is overbodig omdat u een of meer andere ROAs heeft voor de prefix, lengte en ASN",roa_as0:"AS0",roa_as0_help:"Deze ROA dient ervoor om alle aankondigingen van een prefix te verbieden",roa_as0_redundant:"OVERBODIG",roa_as0_redundant_help:"Deze AS0 ROA is overbodig omdat u een of meerdere andere ROAs heeft voor de prefix",announcement_not_found:"NIET GEVONDEN",announcement_not_found_help:"Deze BGP aankondiging wordt niet gedekt door uw ROAs",announcement_invalid_length:"ONGELDIGE LENGTE",announcement_invalid_length_help:"Deze BGP aankondigin is niet toegestaan, omdat de prefix specifieker is dan toegestaan voor dit ASN",announcement_invalid_asn:"ONGELDIG ASN",announcement_invalid_asn_help:"Deze BGP aankondigin is niet toegestaan, omdat de prefix enkel is toegestaan vanaf andere ASNs",announcement_disallowed:"DISALLOWED BY AS0",announcement_disallowed_help:"This announcement is not allowed because you have an AS0 ROA that disallows it"},download:"Download CSV"},deltaErrors:{duplicates:"ROA bestaat reeds",covered:"Overlappende ROA bestaat",notheld:"Niet uw prefix",unknowns:"ROA bestaat niet",invalid_length:"Invalide Lengte",covering:"Overlapt bestaande ROA",as0_exists:"Overlappende AS0 ROA bestaat",as0_overlaps:"Overlapt bestaande ROA"},errors:{repo_not_set:"U dient eerst een databank (repository) te configureren",pub_unknown:"Publisher '{publisher}' is niet bekend",pub_duplicate:"Publisher '{publisher}' is al geïnitialiseerd",pub_outside_jail:"Publisher uri '{uri}' ligt buiten de repository uri '{sia_base}'",pub_uri_no_slash:"Publisher uri '{uri}' moet eindigen met een slash",pub_no_embedded_repo:"Geen geïntegreerde databank (repository) geconfigureerd",ca_duplicate:"CA '{ca}' is reeds geïnitialiseerd",ca_unknown:"CA '{ca}' is onbekend",ca_repo_same:"Deze databank (repository) is al in gebruik",ca_repo_issue:"Foutmelding ontvangen van de databank (repository): {cause}",ca_repo_response_invalid_xml:"Repository response xml is ongeldig",ca_repo_response_wrong_xml:"Parent response in plaats van repository response ontvangen",ca_parent_duplicate:"U heeft al een bovenliggende CA met de naam '{parent}'",ca_parent_xml_duplicate:"Deze response XML is al in gebruik door een bovenliggende CA met de naam '{parent}'",ca_parent_unknown:"U heeft geen bovenliggende CA me de naam '{parent}'",ca_parent_issue:"Fout ontvangen van bovenliggende CA '{parent}': {cause}",ca_parent_response_invalid_xml:"Ongeldige parent response xml ontvangen",ca_parent_response_wrong_xml:"Repository response ontvangen tijdens het toevoegen van de bovenliggende CA",ca_child_duplicate:"U heeft al een ondergeschikte CA met de naam '{child}'",ca_child_unknown:"U heeft geen ondergeschikte CA met de naam '{child}'",ca_child_resources_required:"U dient resources op te geven voor ondegeschikte CA '{child}'",ca_roa_unknown:"Kan onbekende ROA '{prefix}-{max_length} => {asn}' niet verwijderen",ca_roa_duplicate:"ROA '{prefix}-{max_length} => {asn}' bestaat al",ca_roa_invalid_max_length:"Ongeldige maxLength in ROA '{prefix}-{max_length} => {asn}'",ca_roa_not_entitled:"ROA prefix '{prefix}' staat niet op een van uw huidige certificaten",ta_not_allowed:"Deze functionaliteit wordt niet ondersteund door het test-vertrouwensanker",ta_name_reserved:"Naam gereserveerd",ca_roa_delta_error:"ROA geweigerd om de volgende reden(en):",api_insufficient_rights:"U heeft onvoldoende rechten om deze actie uit te voeren. Neem contact op met uw beheerder.",api_invalid_credentials:"De ingevoerde login gegegens zijn incorrect.",api_login_error:"Er trad een fout op tijdens het inloggen: {cause}",api_auth_transient_error:"Er trad een tijdelijke fout op bij het verifiëren van uw verzoek. Probeert u het later nog eens.",api_auth_permanent_error:"Er trad een fout op bij het verifiëren van uw verzoek. Neem contact op met uw beheerder.",api_auth_session_expired:"Uw sessie is verlopen. Gelieve opnieuw in te loggen.",general_error:"Er trad een fout op. Neem contact op met uw beheerder."},testbed:{welcome:"Welkom bij de RPKI test omgeving",disclaimer:{heading:"Spelregels",body:"Deze test omgeving gebruikt een op zichzelf staande RPKI hierarchie en is bedoeld voor evaluatie doeleinden. U kunt hier uw test CA registreren met eender welke IP en ASN adressen. Er worden geen garanties gegeven over de beschikbaarheid van deze service. Als u problemen ondervindt, laat het ons dan weten."},rpconfighelp:{heading:"Test omgeving TAL",body:"Om de data uit deze test omgevinge te valideren, kunt u deze Trust Anchor Locator (TAL) configureren in uw validatie software. Merk op dat u deze TAL NOOIT in een productie omgeving gebruikt. Deze is enkel bedoeld voor tests."},regunreg:{heading:"(De-)Registreren",body:"

Gebruik het formulies om uw RPKI Certificate Authority (CA) als onderliggende CA onder een test CA te registreren.

Daarnaast kunt u uw CA hier registreren onder een Repository

Als u klaar bent testen, gelieve uw CA dan te de-registreren.

"},rfcdoclink:"Klik om de RFC-8183 documentatie voor deze XML te zien",childhandle:"Child Handle",publisherhandle:"Publisher Handle",responseXML:"Testbed response XML",addChild:{heading:"Registreer CA",requestXML:{label:"Child Request XML",placeholder:"Plak uw XML hier"},asnresources:{label:"ASN Resources",placeholder:"AS resources: bv. AS1, AS3-4"},ipv4resources:{label:"IPv4 Resources",placeholder:"IPv4 resources: bv. 192.168.0.0/16"},ipv6resources:{label:"IPv6 Resources",placeholder:"IPv6 resources: bv. 2001:db8::/32"},confirm:"Registreer CA",format:"Dit is geen valide child request XML",required:"Voegt u aub de child request XML toe",confirmation:{title:"Waarschuwing",message:"Weet u zeker dat u deze CA onder deze test omgeving wil registreren?"},success:"CA '{child_handle}' is toegevoegd aan de test omgeving.",registeranother:"Registreer nog een CA"},removeChild:{heading:"Deregistreer CA",placeholder:"Voer de naam van uw CA in",confirm:"Deregistreer CA",confirmation:{title:"Waarschuwing",message:"Weet u zeker dat u deze CA onder deze test omgeving wil deregistreren?"},success:"CA '{child_handle}' is verwijderd van de test omgeving."},addPublisher:{heading:"Registreer Publisher",requestXML:{label:"Publisher Request XML",placeholder:"Plak uw XML here"},confirm:"Registreer publisher",format:"Dit is geen valide publisher request XML",required:"Voegt u aub de publisher request XML toe",confirmation:{title:"Waarschuwing",message:"Weet u zeker dat u uw CA als publisher wil registreren?"},success:"Publisher '{publisher_handle}' is geregistreerd in de test omgeving.",registeranother:"Registreer nog een Publisher"},removePublisher:{heading:"Deregistreer Publisher",placeholder:"Voer de naam van de publisher in",confirm:"Deregistreer Publisher",confirmation:{title:"Waarschuwing",message:"Weet u zeker dat u uw CA als publisher wil deregistreren?"},success:"Publisher '{publisher_handle}' is gederegistreerd van de test omgeving."},errors:{invalid_xml:"Invalid XML: {err}",missing_xml_el:"Missing element {el}",missing_xml_child_el:"Missing child element {el} of element {parent}",missing_xml_attr:"Missing attribute {attr} on element {el}",empty_xml_el:"Element {el} cannot be empty",empty_xml_attr:"Attribute {attr} on element {el} cannot be empty",non_ascii_xml_el:"Element {el} mag geen non-ASCII karakters bevatten",child_handle_required:"CA naam is vereist",publisher_handle_required:"Publisher naam is vereist",non_base64_certificate_xml_el:"Element {el} must contain a correctly Base64 encoded self-signed X.509 BPKI certificate",invalid_registration_data:"Your registration details could not be parsed correctly"}}};export{e as translations}; diff --git a/ui/assets/pt-b668ac3c.js b/ui/assets/pt-b668ac3c.js new file mode 100644 index 00000000..cb903b3d --- /dev/null +++ b/ui/assets/pt-b668ac3c.js @@ -0,0 +1 @@ +const e={common:{readthedocs:"Ler documentos (inglês)",report:"Reportar um problema",confirm:"Confirmar",cancel:"Cancelar",ok:"OK",error:"Erro",success:"Successo!",copy:"Copiar para a Área de transferência",download:"Download",dropOrClick:"Arraste o arquivo aqui, ou clique para upload",started:"Krill rodando desde",newversion:"Nova versão disponível!",supportcontracts:"Contratos de Suporte",warning:"Aviso",idle:"Sua sessão expirou por inatividade.",nodata:"No data",copySuccess:"XML copiado para a Área de transferência",edit:"Editar",page:"page",userInfo:{title:"Detalhes de autenticação",user:"Usuário"}},login:{password:"Senha",placeholder:"Sua senha (token de autenticação)",signin:"Entrar",required:"Por favor, digite a sua senha",error:"A senha digitada é inválida/incorreta",copied:"Você não deve utilizar senhas de https://xkcd.com/936/",id:"Nome de usuário",idPlaceholder:"Seu nome de usuário",idRequired:"Por favor, informe seu nome de usuário",retry:"Clique {0} para retornar para a página de autenticação.",here:"aqui"},onboarding:{welcome:"Bem-vindo ao Krill",welcomeHtml:"O primeiro passo é criar uma Autoridade Certificadora (CA) RPKI. Ela será usada para configurar o RPKI delegado com uma ou mais CAs-pai, geralmente uma Autoridade Nacional de Internet (NIR) ou mesmo uma Autoridade Regional de Internet (RIR).

Você deve definir um identificador que vinculará sua CA nas operações com a CA-pai e CAs-filhas. Este identificador não será usado nas publicações RPKI. Por favor, defina um identificador que ajude outras pessoas a identificar sua empresa/organização. Uma vez configurado, este identificador não poderá ser alterado.",addCAForm:{required:"Este campo é obrigatório",format:"Este não é um nome de CA válido",confirm:"Criar CA",confirmation:{title:"Aviso",message:"Uma vez configurado, este identificador não poderá ser alterado. Deseja continuar?"}}},cas:{loading:"Carregando Autoridades Certificadoras (CAs)",ca:"Autoridade Certificadora (CA)",cas:"Autoridades Certificadoras (CAs)",search:"Buscando CAs...",noCas:"Não existe nenhuma Autoridade Certificadora (CA) definida."},caDetails:{loading:"Carregando {handle}",refresh:"Atualizando {handle}, isso pode demorar uns minutos",current:"Autoridade Certificadora atual",download:"Download do arquivo PEM",noRoas:"Nenhuma ROAs encontrada.",noResources:"Você não recebeu nenhum recurso ainda",noChildren:"Nenhum filho encontrado.",addRoa:"Adicionar ROA",addAspa:"Add ASPA",editAspa:"Edit ASPA",roas:"ROAs",aspas:"ASPAs",resources:"Recursos",parents:"CAs-pai",repo:"Repositório",type:"Tipo",properties:"Propriedades",property:"Propriedade",value:"Valor",kind:"Tipo",resource:"Recurso",children:"Filhos",handle:"Identificador",comment:"Commentário",maxLength:"Comprimento máximo",maxLengthTooltip:"Se o comprimento máximo não está especificado, o comprimento do prefixo será utilizado",confirmation:{title:"Aviso",message:"Esta operação irá remover a ROA '{prefix}-{max_length} => {asn}'. Continuar?",added:"ROA adicionada",retired:"ROA removida",retiredSuccess:"A ROA foi removida",addedSuccess:"A ROA foi adicionada",commentUpdatedSuccess:"Commentário foi atualizado"},addROAForm:{required:"Este campo é obrigatório",asn_format:"Este não é um ASN válido",prefix_format:"Por favor, entre um prefixo IPv4 ou IPv6 válido"},onboardingWarning:"Você deve conectar sua Autoridade Certificadora (CA) a um repositório RPKI público, onde será possível publicar seu certificado e ROAs. Assim que a configuração com a CA-pai for finalizada, imediatamente os softwares de validação ('relying parties') terão acesso aos certificado(s) e ROA(s) criados neste repositório.",initializeRepository:"Você ainda deve conectar sua Autoridade Certificadora (CA) a um repositório RPKI público.",initialize:"Por favor, initialize o repositório RPKI e/ou Pai primeiro.",noResourcesYet:"Você ainda não recebeu nenhum recurso",clickToRefresh:"Clique aqui para atualizar",parentsTab:{request:"Requisição da CA-filha",response:"Resposta da CA-pai",addParent:"Incluir uma nova CA-pai",addParentSuccess:"CA-pai adicionada",name:"Nome da CA-pai",namerequired:"O nome da CA-pai é obrigatório",nameformat:"Este não é um nome de CA-pai válido"},repoTab:{request:"Requisição do Publicador",response:"Resposta do Repositório",addRepo:"Incluir um repositório",addRepoSuccess:"Repositório adicionado"},analyseThis:"Analisar minhas ROAs",analysis:"Análise de ROA",suggestions:{following:"Por favor, consulte as seguintes alterações sugeridas para suas ROAs.",readMore:"Saiba mais (texto em inglês)...",nochanges:"Não sugerimos alterações neste momento",adding:"Adicionando",removing:"Removendo ROA",keep:"Mantenha tudo como está.",willResult:"Resultará em",yourChoice:"Sua escolha",ourSuggestion:"Nossa sugestão",ourSuggestionHelp:"Nossa sugestão é baseada em informações de roteamento do RIPE RIS, favor verificar!",addThis:"Adicionar este",removeThis:"Remover este",willAdd:"Adicionará esta ROA",willRemove:"Removerá esta ROA",reasons:{not_found:"Não encontrado",not_held:"O prefixo não existe mais em seu(s) certificado(s), a ROA não será publicada",invalid_asn:"ASN inválido",invalid_length:"Comprimento inválido",stale:"Velho",disallowing:"ROA desautoriza anúncios, e não autoriza nada. Usar AS0 como alternativa?",as0_redundant:"AS0 redundante",redundant:"Redundante",too_permissive:"Muito permissivo",specific:"Permitir anúncio específico em uma ROA que pode ser muito permissiva",new:"Novo"}},syncParents:"Atualizar Parents",syncRepo:"Atualizar Repositório",lastExchange:"Última troca",exchangeUri:"URI",nextExchange:"Próxima troca antes",allResources:"Todos os recursos",entitlements:"Permissões",showEntitlements:"Mostrar Permissões Detalhadas",parentCertificate:"Certificado Pai",published:"Publicado"},aspas:{customer:"Customer",providers:"Providers",search:"Search for customer, provider...",confirmation:{title:"Warning",message:"This will remove the ASPA '{customer} => {providers}'. Continue?",added:"ASPA added",retired:"ASPA removed",retiredSuccess:"The ASPA has been removed",addedSuccess:"The ASPA has been added",commentUpdatedSuccess:"The ASPA comment has been updated"},customer_validation_format:"The customer format is invalid or already exists",providers_validation_format:"The providers format is invalid",add:"Add ASPA",edit:"Edit ASPA",analyse:"Analyse providers",detected_providers:"Declared providers",providers_missing:"ASNs observed in RIS but not in the provider list. Please verify that none of these ASNs act as your provider.",no_aspas:"Krill did not find any ASNs. You need an ASN to be able to create an ASPA for it."},announcements:{noRoasOrAnnouncements:"ROAs ou Anúncios não encontrados.",search:"Pesquisar por ASN, prefixos, estados...",authorizes:"Autoriza {number} anúncio(s)",disallows:"Desabilita {number} anúncio(s)",asn:"ASN",prefix:"Prefixo",stateLabel:"Estado",state:{roa_seen:"VISTO",roa_seen_help:"Esta ROA corresponde a anúncios vistos no BGP",roa_unseen:"NÃO VISTO",roa_unseen_help:"Não identificamos nenhum anúncio BGP que corresponda a esta ROA",roa_not_held:"PREFIXO REMOVIDO",roa_not_held_help:"O prefixo não existe mais em seu(s) certificado(s), a ROA não será publicada",roa_no_announcement_info:"SEM INFORMAÇÕES DE ANÚNCIO",roa_too_permissive:"MUITO PERMISSIVO",roa_too_permissive_help:"Esta ROA corresponde a anúncios visto no BGP, mas também permite anúncios não vistos",roa_disallowing:"DESAUTORIZANDO",roa_disallowing_help:"Esta ROA só desautoriza anúncios. Caso isso seja intencional, talvez você prefira usar um AS0 como alternativa.",roa_redundant:"REDUNDANTE",roa_redundant_help:"Esta ROA é redundante, porque já existe uma ou mais ROAs cobrindo este prefixo, comprimento e ASN",roa_as0:"AS0",roa_as0_help:"Esta ROA tem por objetivo NÃO permitir anúncios para um prefixo",roa_as0_redundant:"REDUNDANTE",roa_as0_redundant_help:"Esta ROA AS0 é redundante porque já existe uma ou mais ROAs cobrindo este prefixo",announcement_not_found:"NÃO ENCONTRADO",announcement_invalid_length:"COMPRIMENTO INVÁLIDO",announcement_invalid_asn:"ASN INVÁLIDO",announcement_not_found_help:"Este anúncio não está coberto por nenhuma de suas ROAs",announcement_invalid_length_help:"Este anúncio não é permitido porque é mais específico do que o prefixo e comprimento máximo autorizado para este ASN",announcement_invalid_asn_help:"Este anúncio não é permitido, porque você já autorizou o prefixo a partir de outro ASN",announcement_disallowed:"DISALLOWED BY AS0",announcement_disallowed_help:"This announcement is not allowed because you have an AS0 ROA that disallows it"},download:"Download CSV"},deltaErrors:{duplicates:"Duplicados",covered:"Coberto",notheld:"Não é seu prefixo",unknowns:"Desconhecidos",invalid_length:"Comprimento inválido",covering:"Cobrindo",as0_exists:"AS0 Existe",as0_overlaps:"Sobreposição com AS0"},errors:{repo_not_set:"Você deve configurar um repositório primeiro",pub_unknown:"Publicador '{publisher}' desconhecido",pub_duplicate:"Publicador '{publisher}' já inicializado",pub_outside_jail:"URI do publicador '{uri}' não pertence à URI do repositório '{sia_base}'",pub_uri_no_slash:"URI do publicador '{uri}' deve ser finalizado com um caracter '/'",pub_no_embedded_repo:"Nenhum repositório embarcado configurado",ca_duplicate:"CA '{ca}' já inicializada",ca_unknown:"CA '{ca}' desconhecida",ca_repo_same:"Este repositório já está em uso",ca_repo_issue:"Erro recebido do repositório: {cause}",ca_repo_response_invalid_xml:"Recebido um XML repository_response inválido",ca_repo_response_wrong_xml:"Recebido um XML parent_response ao invés de repository_response",ca_parent_duplicate:"Você já possui uma CA-pai chamada '{parent}'",ca_parent_xml_duplicate:"Esta resposta já é usado por uma CA-pai chamada '{parent}'",ca_parent_unknown:"Você não tem uma CA-pai chamada '{parent}'",ca_parent_issue:"Erro recebido da CA-pai '{parent}': {cause}",ca_parent_response_invalid_xml:"Xml parent_response inválido",ca_parent_response_wrong_xml:"Resposta do repositório após adicionar a CA-pai",ca_child_duplicate:"Você já possui uma CA-filha chamada '{child}'",ca_child_unknown:"Você não tem uma CA-filha chamada '{child}'",ca_child_resources_required:"Você deve especificar recursos para sua CA-filha '{child}'",ca_roa_unknown:"Impossível remover ROA desconhecida '{prefix}-{max_length} => {asn}'",ca_roa_duplicate:"ROA duplicada '{prefix}-{max_length} => {asn}'",ca_roa_invalid_max_length:"Comprimento máximo inválido na ROA '{prefix}-{max_length} => {asn}'",ca_roa_not_entitled:"Prefixo da ROA '{prefix}' não pertence a nenhum de seus certificados atuais",ta_not_allowed:"Esta funcionalidade não é suportada pelo Trust Anchor de testes",ta_name_reserved:"Nome reservado",ca_roa_delta_error:"ROA rejeitada pelos seguintes motivos:",api_insufficient_rights:"Seu usuário não possui privilégios suficientes para esta operação. Por favor, entre em contato com seu administrador.",api_invalid_credentials:"As credenciais fornecidas estão incorretas.",api_login_error:"Um erro ocorreu durante a autenticação: {cause}",api_auth_transient_error:"Um erro (temporário) ocorreu na tentativa de autenticação. Por favor, tente mais tarde.",api_auth_permanent_error:"Um erro ocorreu na tentativa de autenticação. Por favor, entre em contato com seu administrador.",api_auth_session_expired:"Sua sessão expirou. Por favor, autentique-se novamente.",general_error:"Ocorreu um erro. Por favor, entre em contato com seu administrador."},testbed:{welcome:"Bem-vindo ao ambiente de testes RPKI",disclaimer:{heading:"Aviso legal",body:"Este ambiente de testes utiliza um hierarquia RPKI completamente independente, que pode ser utilizada para fins de avaliação. Ele permite que você registre qualquer recurso para sua CA-filha. Nenhuma garantia é dada em relação a disponibilidade deste serviço. Se você encontrar algum problema, favor nos informar."},rpconfighelp:{heading:"TAL do ambiente de testes",body:"Para obter dados publicados por este ambiente de testes, favor baixar este Trust Anchor Locator (TAL) e configurá-lo em seu software de validação ('relying party'). Note que você NUNCA deve usar este TAL num ambiente de produção. Ele é fornecido apenas para testes."},regunreg:{heading:"Registrar/Remover",body:"

Use o formulário para registrar sua CA-filha de RPKI neste ambiente de testes para poder criar Route Origin Authorisations (ROAs) para seus recursos.

Se você não pretende hospedar seu próprio repositório Rsync e RRDP você pode usar o formulário 'Registrar Publicador' para configurar a publicação de seus ROAs no repositório hospedado neste ambiente de testes. Use o formulário 'Remover' para cancelar relações estabelecidas anteriormente (inclusive aquela de outros usuários deste ambiente de testes!).

"},rfcdoclink:"Clique para ver a documentação da RFC-8183 para este XML",childhandle:"Identificador da CA-filha",publisherhandle:"Identificador do Publicador",responseXML:"Resposta XML do ambiente de testes",addChild:{heading:"Registrar CA",requestXML:{label:"XML Child Request",placeholder:"Cole aqui seu XML "},asnresources:{label:"ASNs",placeholder:"ASNs: p. ex. AS1, AS3-4"},ipv4resources:{label:"Recursos IPv4",placeholder:"Recursos IPv4: p. ex. 192.168.0.0/16"},ipv6resources:{label:"Recursos IPv6",placeholder:"Recursos IPv6: p. ex. 2001:db8::/32"},confirm:"Registrar CA-filha",format:"Este não é um XML válido",required:"Favor informar um XML ",confirmation:{title:"Atenção",message:"Você tem certeza que quer registrar esta CA-filha neste ambiente de testes?"},success:"CA-filha '{child_handle}' adicionado ao ambiente de testes.",registeranother:"Registrar outra CA"},removeChild:{heading:"Remover CA",placeholder:"Informe o nome da CA a ser removida",confirm:"Remover CA-filha",confirmation:{title:"Atenção",message:"Você tem certeza que quer remover esta CA-filha deste ambiente de testes?"},success:"CA-filha '{child_handle}' foi removido deste ambiente de testes."},addPublisher:{heading:"Registrar Publicador",requestXML:{label:"XML Publisher Request",placeholder:"Cole aqui seu XML "},confirm:"Registrar publicador",format:"Este não é um XML válido",required:"Favor informar um XML ",confirmation:{title:"Atenção",message:"Você tem certeza que quer registrar este publicador neste ambiente de testes?"},success:"Publicador '{publisher_handle}' adicionado ao ambiente de testes.",registeranother:"Registrar outro Publicador"},removePublisher:{heading:"Remover Publicador",placeholder:"Informe o nome do Publicador a ser removido",confirm:"Remover publicador",confirmation:{title:"Atenção",message:"Você tem certeza que quer remover este publicador deste ambiente de testes?"},success:"Publicador '{publisher_handle}' foi removido deste ambiente de testes."},errors:{invalid_xml:"XML inválido: {err}",missing_xml_el:"Elemento {el} ausente",missing_xml_child_el:"Elemento filho {el} ausente do elemento {parent}",missing_xml_attr:"Atributo {attr} ausente no elemento {el}",empty_xml_el:"Elemento {el} não pode ser vazio",empty_xml_attr:"Atributo {attr} do elemento {el} não pode ser vazio",non_ascii_xml_el:"Elemento {el} não pode incluir caracteres não-ASCII",child_handle_required:"Identificador da CA-filha é obrigatório",publisher_handle_required:"Identificador do Publicador é obrigatório",non_base64_certificate_xml_el:"Elemento {el} deve conter um certificado X.509 BPKI auto-assinado, no formato Base64",invalid_registration_data:"As informações em sua solicitação de registro não puderam ser interpretadas corretamente"}}};export{e as translations}; diff --git a/ui/assets/pt-ee7cebe0.js b/ui/assets/pt-ee7cebe0.js deleted file mode 100644 index fa77b628..00000000 --- a/ui/assets/pt-ee7cebe0.js +++ /dev/null @@ -1 +0,0 @@ -const e={common:{readthedocs:"Ler documentos (inglês)",report:"Reportar um problema",confirm:"Confirmar",cancel:"Cancelar",ok:"OK",error:"Erro",success:"Successo!",copy:"Copiar para a Área de transferência",download:"Download",dropOrClick:"Arraste o arquivo aqui, ou clique para upload",started:"Krill rodando desde",newversion:"Nova versão disponível!",supportcontracts:"Contratos de Suporte",warning:"Aviso",idle:"Sua sessão expirou por inatividade.",nodata:"No data",copySuccess:"XML copiado para a Área de transferência",edit:"Editar",page:"page",userInfo:{title:"Detalhes de autenticação",user:"Usuário"}},login:{password:"Senha",placeholder:"Sua senha (token de autenticação)",signin:"Entrar",required:"Por favor, digite a sua senha",error:"A senha digitada é inválida/incorreta",copied:"Você não deve utilizar senhas de https://xkcd.com/936/",id:"Nome de usuário",idPlaceholder:"Seu nome de usuário",idRequired:"Por favor, informe seu nome de usuário",retry:"Clique {0} para retornar para a página de autenticação.",here:"aqui"},onboarding:{welcome:"Bem-vindo ao Krill",welcomeHtml:"O primeiro passo é criar uma Autoridade Certificadora (CA) RPKI. Ela será usada para configurar o RPKI delegado com uma ou mais CAs-pai, geralmente uma Autoridade Nacional de Internet (NIR) ou mesmo uma Autoridade Regional de Internet (RIR).

Você deve definir um identificador que vinculará sua CA nas operações com a CA-pai e CAs-filhas. Este identificador não será usado nas publicações RPKI. Por favor, defina um identificador que ajude outras pessoas a identificar sua empresa/organização. Uma vez configurado, este identificador não poderá ser alterado.",addCAForm:{required:"Este campo é obrigatório",format:"Este não é um nome de CA válido",confirm:"Criar CA",confirmation:{title:"Aviso",message:"Uma vez configurado, este identificador não poderá ser alterado. Deseja continuar?"}}},cas:{loading:"Carregando Autoridades Certificadoras (CAs)",ca:"Autoridade Certificadora (CA)",cas:"Autoridades Certificadoras (CAs)",search:"Buscando CAs...",noCas:"Não existe nenhuma Autoridade Certificadora (CA) definida."},caDetails:{loading:"Carregando {handle}",refresh:"Atualizando {handle}, isso pode demorar uns minutos",current:"Autoridade Certificadora atual",download:"Download do arquivo PEM",noRoas:"Nenhuma ROAs encontrada.",noResources:"Você não recebeu nenhum recurso ainda",noChildren:"Nenhum filho encontrado.",addRoa:"Adicionar ROA",addAspa:"Add ASPA",editAspa:"Edit ASPA",roas:"ROAs",aspas:"ASPAs",resources:"Recursos",parents:"CAs-pai",repo:"Repositório",type:"Tipo",properties:"Propriedades",property:"Propriedade",value:"Valor",kind:"Tipo",resource:"Recurso",children:"Filhos",handle:"Identificador",comment:"Commentário",maxLength:"Comprimento máximo",maxLengthTooltip:"Se o comprimento máximo não está especificado, o comprimento do prefixo será utilizado",confirmation:{title:"Aviso",message:"Esta operação irá remover a ROA '{prefix}-{max_length} => {asn}'. Continuar?",added:"ROA adicionada",retired:"ROA removida",retiredSuccess:"A ROA foi removida",addedSuccess:"A ROA foi adicionada",commentUpdatedSuccess:"Commentário foi atualizado"},addROAForm:{required:"Este campo é obrigatório",asn_format:"Este não é um ASN válido",prefix_format:"Por favor, entre um prefixo IPv4 ou IPv6 válido"},onboardingWarning:"Você deve conectar sua Autoridade Certificadora (CA) a um repositório RPKI público, onde será possível publicar seu certificado e ROAs. Assim que a configuração com a CA-pai for finalizada, imediatamente os softwares de validação ('relying parties') terão acesso aos certificado(s) e ROA(s) criados neste repositório.",initializeRepository:"Você ainda deve conectar sua Autoridade Certificadora (CA) a um repositório RPKI público.",initialize:"Por favor, initialize o repositório RPKI e/ou Pai primeiro.",noResourcesYet:"Você ainda não recebeu nenhum recurso",clickToRefresh:"Clique aqui para atualizar",parentsTab:{request:"Requisição da CA-filha",response:"Resposta da CA-pai",addParent:"Incluir uma nova CA-pai",addParentSuccess:"CA-pai adicionada",name:"Nome da CA-pai",namerequired:"O nome da CA-pai é obrigatório",nameformat:"Este não é um nome de CA-pai válido"},repoTab:{request:"Requisição do Publicador",response:"Resposta do Repositório",addRepo:"Incluir um repositório",addRepoSuccess:"Repositório adicionado"},analyseThis:"Analisar minhas ROAs",analysis:"Análise de ROA",suggestions:{following:"Por favor, consulte as seguintes alterações sugeridas para suas ROAs.",readMore:"Saiba mais (texto em inglês)...",nochanges:"Não sugerimos alterações neste momento",adding:"Adicionando",removing:"Removendo ROA",keep:"Mantenha tudo como está.",willResult:"Resultará em",yourChoice:"Sua escolha",ourSuggestion:"Nossa sugestão",ourSuggestionHelp:"Nossa sugestão é baseada em informações de roteamento do RIPE RIS, favor verificar!",addThis:"Adicionar este",removeThis:"Remover este",willAdd:"Adicionará esta ROA",willRemove:"Removerá esta ROA",reasons:{not_found:"Não encontrado",not_held:"O prefixo não existe mais em seu(s) certificado(s), a ROA não será publicada",invalid_asn:"ASN inválido",invalid_length:"Comprimento inválido",stale:"Velho",disallowing:"ROA desautoriza anúncios, e não autoriza nada. Usar AS0 como alternativa?",as0_redundant:"AS0 redundante",redundant:"Redundante",too_permissive:"Muito permissivo",specific:"Permitir anúncio específico em uma ROA que pode ser muito permissiva",new:"Novo"}},syncParents:"Atualizar Parents",syncRepo:"Atualizar Repositório",lastExchange:"Última troca",exchangeUri:"URI",nextExchange:"Próxima troca antes",allResources:"Todos os recursos",entitlements:"Permissões",showEntitlements:"Mostrar Permissões Detalhadas",parentCertificate:"Certificado Pai",published:"Publicado"},aspas:{customer:"Customer",providers:"Providers",search:"Search for customer, provider...",confirmation:{title:"Warning",message:"This will remove the ASPA '{customer} => {providers}'. Continue?",added:"ASPA added",retired:"ASPA removed",retiredSuccess:"The ASPA has been removed",addedSuccess:"The ASPA has been added",commentUpdatedSuccess:"The ASPA comment has been updated"},customer_validation_format:"The customer format is invalid or already exists",providers_validation_format:"The providers format is invalid"},announcements:{noRoasOrAnnouncements:"ROAs ou Anúncios não encontrados.",search:"Pesquisar por ASN, prefixos, estados...",authorizes:"Autoriza {number} anúncio(s)",disallows:"Desabilita {number} anúncio(s)",asn:"ASN",prefix:"Prefixo",stateLabel:"Estado",state:{roa_seen:"VISTO",roa_seen_help:"Esta ROA corresponde a anúncios vistos no BGP",roa_unseen:"NÃO VISTO",roa_unseen_help:"Não identificamos nenhum anúncio BGP que corresponda a esta ROA",roa_not_held:"PREFIXO REMOVIDO",roa_not_held_help:"O prefixo não existe mais em seu(s) certificado(s), a ROA não será publicada",roa_no_announcement_info:"SEM INFORMAÇÕES DE ANÚNCIO",roa_too_permissive:"MUITO PERMISSIVO",roa_too_permissive_help:"Esta ROA corresponde a anúncios visto no BGP, mas também permite anúncios não vistos",roa_disallowing:"DESAUTORIZANDO",roa_disallowing_help:"Esta ROA só desautoriza anúncios. Caso isso seja intencional, talvez você prefira usar um AS0 como alternativa.",roa_redundant:"REDUNDANTE",roa_redundant_help:"Esta ROA é redundante, porque já existe uma ou mais ROAs cobrindo este prefixo, comprimento e ASN",roa_as0:"AS0",roa_as0_help:"Esta ROA tem por objetivo NÃO permitir anúncios para um prefixo",roa_as0_redundant:"REDUNDANTE",roa_as0_redundant_help:"Esta ROA AS0 é redundante porque já existe uma ou mais ROAs cobrindo este prefixo",announcement_not_found:"NÃO ENCONTRADO",announcement_invalid_length:"COMPRIMENTO INVÁLIDO",announcement_invalid_asn:"ASN INVÁLIDO",announcement_not_found_help:"Este anúncio não está coberto por nenhuma de suas ROAs",announcement_invalid_length_help:"Este anúncio não é permitido porque é mais específico do que o prefixo e comprimento máximo autorizado para este ASN",announcement_invalid_asn_help:"Este anúncio não é permitido, porque você já autorizou o prefixo a partir de outro ASN",announcement_disallowed:"DISALLOWED BY AS0",announcement_disallowed_help:"This announcement is not allowed because you have an AS0 ROA that disallows it"},download:"Download CSV"},deltaErrors:{duplicates:"Duplicados",covered:"Coberto",notheld:"Não é seu prefixo",unknowns:"Desconhecidos",invalid_length:"Comprimento inválido",covering:"Cobrindo",as0_exists:"AS0 Existe",as0_overlaps:"Sobreposição com AS0"},errors:{repo_not_set:"Você deve configurar um repositório primeiro",pub_unknown:"Publicador '{publisher}' desconhecido",pub_duplicate:"Publicador '{publisher}' já inicializado",pub_outside_jail:"URI do publicador '{uri}' não pertence à URI do repositório '{sia_base}'",pub_uri_no_slash:"URI do publicador '{uri}' deve ser finalizado com um caracter '/'",pub_no_embedded_repo:"Nenhum repositório embarcado configurado",ca_duplicate:"CA '{ca}' já inicializada",ca_unknown:"CA '{ca}' desconhecida",ca_repo_same:"Este repositório já está em uso",ca_repo_issue:"Erro recebido do repositório: {cause}",ca_repo_response_invalid_xml:"Recebido um XML repository_response inválido",ca_repo_response_wrong_xml:"Recebido um XML parent_response ao invés de repository_response",ca_parent_duplicate:"Você já possui uma CA-pai chamada '{parent}'",ca_parent_xml_duplicate:"Esta resposta já é usado por uma CA-pai chamada '{parent}'",ca_parent_unknown:"Você não tem uma CA-pai chamada '{parent}'",ca_parent_issue:"Erro recebido da CA-pai '{parent}': {cause}",ca_parent_response_invalid_xml:"Xml parent_response inválido",ca_parent_response_wrong_xml:"Resposta do repositório após adicionar a CA-pai",ca_child_duplicate:"Você já possui uma CA-filha chamada '{child}'",ca_child_unknown:"Você não tem uma CA-filha chamada '{child}'",ca_child_resources_required:"Você deve especificar recursos para sua CA-filha '{child}'",ca_roa_unknown:"Impossível remover ROA desconhecida '{prefix}-{max_length} => {asn}'",ca_roa_duplicate:"ROA duplicada '{prefix}-{max_length} => {asn}'",ca_roa_invalid_max_length:"Comprimento máximo inválido na ROA '{prefix}-{max_length} => {asn}'",ca_roa_not_entitled:"Prefixo da ROA '{prefix}' não pertence a nenhum de seus certificados atuais",ta_not_allowed:"Esta funcionalidade não é suportada pelo Trust Anchor de testes",ta_name_reserved:"Nome reservado",ca_roa_delta_error:"ROA rejeitada pelos seguintes motivos:",api_insufficient_rights:"Seu usuário não possui privilégios suficientes para esta operação. Por favor, entre em contato com seu administrador.",api_invalid_credentials:"As credenciais fornecidas estão incorretas.",api_login_error:"Um erro ocorreu durante a autenticação: {cause}",api_auth_transient_error:"Um erro (temporário) ocorreu na tentativa de autenticação. Por favor, tente mais tarde.",api_auth_permanent_error:"Um erro ocorreu na tentativa de autenticação. Por favor, entre em contato com seu administrador.",api_auth_session_expired:"Sua sessão expirou. Por favor, autentique-se novamente.",general_error:"Ocorreu um erro. Por favor, entre em contato com seu administrador."},testbed:{welcome:"Bem-vindo ao ambiente de testes RPKI",disclaimer:{heading:"Aviso legal",body:"Este ambiente de testes utiliza um hierarquia RPKI completamente independente, que pode ser utilizada para fins de avaliação. Ele permite que você registre qualquer recurso para sua CA-filha. Nenhuma garantia é dada em relação a disponibilidade deste serviço. Se você encontrar algum problema, favor nos informar."},rpconfighelp:{heading:"TAL do ambiente de testes",body:"Para obter dados publicados por este ambiente de testes, favor baixar este Trust Anchor Locator (TAL) e configurá-lo em seu software de validação ('relying party'). Note que você NUNCA deve usar este TAL num ambiente de produção. Ele é fornecido apenas para testes."},regunreg:{heading:"Registrar/Remover",body:"

Use o formulário para registrar sua CA-filha de RPKI neste ambiente de testes para poder criar Route Origin Authorisations (ROAs) para seus recursos.

Se você não pretende hospedar seu próprio repositório Rsync e RRDP você pode usar o formulário 'Registrar Publicador' para configurar a publicação de seus ROAs no repositório hospedado neste ambiente de testes. Use o formulário 'Remover' para cancelar relações estabelecidas anteriormente (inclusive aquela de outros usuários deste ambiente de testes!).

"},rfcdoclink:"Clique para ver a documentação da RFC-8183 para este XML",childhandle:"Identificador da CA-filha",publisherhandle:"Identificador do Publicador",responseXML:"Resposta XML do ambiente de testes",addChild:{heading:"Registrar CA",requestXML:{label:"XML Child Request",placeholder:"Cole aqui seu XML "},asnresources:{label:"ASNs",placeholder:"ASNs: p. ex. AS1, AS3-4"},ipv4resources:{label:"Recursos IPv4",placeholder:"Recursos IPv4: p. ex. 192.168.0.0/16"},ipv6resources:{label:"Recursos IPv6",placeholder:"Recursos IPv6: p. ex. 2001:db8::/32"},confirm:"Registrar CA-filha",format:"Este não é um XML válido",required:"Favor informar um XML ",confirmation:{title:"Atenção",message:"Você tem certeza que quer registrar esta CA-filha neste ambiente de testes?"},success:"CA-filha '{child_handle}' adicionado ao ambiente de testes.",registeranother:"Registrar outra CA"},removeChild:{heading:"Remover CA",placeholder:"Informe o nome da CA a ser removida",confirm:"Remover CA-filha",confirmation:{title:"Atenção",message:"Você tem certeza que quer remover esta CA-filha deste ambiente de testes?"},success:"CA-filha '{child_handle}' foi removido deste ambiente de testes."},addPublisher:{heading:"Registrar Publicador",requestXML:{label:"XML Publisher Request",placeholder:"Cole aqui seu XML "},confirm:"Registrar publicador",format:"Este não é um XML válido",required:"Favor informar um XML ",confirmation:{title:"Atenção",message:"Você tem certeza que quer registrar este publicador neste ambiente de testes?"},success:"Publicador '{publisher_handle}' adicionado ao ambiente de testes.",registeranother:"Registrar outro Publicador"},removePublisher:{heading:"Remover Publicador",placeholder:"Informe o nome do Publicador a ser removido",confirm:"Remover publicador",confirmation:{title:"Atenção",message:"Você tem certeza que quer remover este publicador deste ambiente de testes?"},success:"Publicador '{publisher_handle}' foi removido deste ambiente de testes."},errors:{invalid_xml:"XML inválido: {err}",missing_xml_el:"Elemento {el} ausente",missing_xml_child_el:"Elemento filho {el} ausente do elemento {parent}",missing_xml_attr:"Atributo {attr} ausente no elemento {el}",empty_xml_el:"Elemento {el} não pode ser vazio",empty_xml_attr:"Atributo {attr} do elemento {el} não pode ser vazio",non_ascii_xml_el:"Elemento {el} não pode incluir caracteres não-ASCII",child_handle_required:"Identificador da CA-filha é obrigatório",publisher_handle_required:"Identificador do Publicador é obrigatório",non_base64_certificate_xml_el:"Elemento {el} deve conter um certificado X.509 BPKI auto-assinado, no formato Base64",invalid_registration_data:"As informações em sua solicitação de registro não puderam ser interpretadas corretamente"}}};export{e as translations}; diff --git a/ui/assets/zh-Hans-2645b5fc.js b/ui/assets/zh-Hans-2645b5fc.js new file mode 100644 index 00000000..fcbceff4 --- /dev/null +++ b/ui/assets/zh-Hans-2645b5fc.js @@ -0,0 +1 @@ +const e={common:{readthedocs:"阅读使用手册",report:"反馈问题",confirm:"确认",cancel:"取消",ok:"OK",error:"错误",success:"成功!",copy:"复制到剪贴板",download:"下载",dropOrClick:"拖动文件至此处或点此上传",started:"Krill起始运行时间为",newversion:"有版本更新!",supportcontracts:"服务合同",warning:"警告",idle:"您因无活动而被登出。",nodata:"无数据",copySuccess:"XML已复制到您的剪贴板",edit:"编辑",page:"页面",userInfo:{title:"登录数据",user:"用户"}},login:{password:"密码",placeholder:"您的密码",signin:"登录",required:"请输入您的密码",error:"您输入的密钥有误",copied:"请勿使用从https://xkcd.com/936/获得的密码",id:"用户名",idPlaceholder:"您的用户名",idRequired:"请输入您的用户名",retry:"点击{0}返回登陆页面。",here:"这里"},onboarding:{welcome:"欢迎来到Krill",welcomeHtml:"让我们从创建您的RPKI证书颁发机构(CA)开始。它将被用来配置通常为一或多个区域或国家互联网注册管理机构父级CA下发的RPKI。

您选择的handle会被用来在与父级或子级CA交互过程中识别您的CA。它将不会在RPKI中发布。请选择能让他人识别出您机构的handle。设置后handle将无法更改。",addCAForm:{required:"此为必填项",format:"这不是有效的CA名称",confirm:"创建CA",confirmation:{title:"警告",message:"设置后handle将无法更改。是否继续?"}}},cas:{loading:"加载证书颁发机构中",ca:"证书颁发机构",cas:"证书颁发机构",search:"搜索CAs⋯⋯",noCas:"当前没有已被界定的证书颁发机构。"},caDetails:{loading:"加载{handle}中",refresh:"刷新{handle}中,可能需要稍作等待",current:"当前证书颁发机构",download:"下载PEM",noRoas:"未找到ROA。",noResources:"您暂未获得任何资源",noChildren:"未发现子CA",addRoa:"添加ROA",addAspa:"Add ASPA",editAspa:"Edit ASPA",roas:"ROA",aspas:"ASPA",resources:"资源",parents:"父级CA",repo:"数据库",type:"类型",properties:"特性",property:"特性",value:"数值",kind:"类别",resource:"资源",children:"子项",handle:"Handle",comment:"备注",maxLength:"最大长度",maxLengthTooltip:"若不指定最大长度,该长度默认为地址前缀的掩码长度。",confirmation:{title:"警告",message:"此举将会移除ROA '{prefix}-{max_length} => {asn}'。是否继续?",added:"已添加ROA",retired:"已移除ROA",retiredSuccess:"该ROA已被移除",addedSuccess:"该ROA已被添加",commentUpdatedSuccess:"该ROA的备注已更新"},addROAForm:{required:"该项为必填项",asn_format:"这不是有效的ASN",prefix_format:"请输入有效的IPv4或IPv6前缀"},onboardingWarning:"您需要将您的CA与可发布您的证书及ROA的公共RPKI数据库相连接。当父级CA配置完成时,关联的受信任软件将立即开始下载您于此数据库创建的证书及ROA。",initializeRepository:"在您的CA向父级CA申请资源证书前您仍需为它设置一个数据库",initialize:"请先初始化RPKI数据库及/或父级CA。",noResourcesYet:"您暂未获得任何资源",clickToRefresh:"点此刷新",parentsTab:{request:"子CA请求",response:"父级CA应答",addParent:"添加额外的父级CA",addParentSuccess:"父级CA已添加",name:"父级CA名称",namerequired:"父级CA名称为必填项",nameformat:"该父级CA名称无效"},repoTab:{request:"发布者申请",addRepo:"添加数据库",response:"数据库应答",addRepoSuccess:"数据库已添加"},analyseThis:"分析我的ROA",analysis:"ROA分析",suggestions:{following:"请确认以下关于您ROA的建议更新。",readMore:"阅读更多⋯⋯",nochanges:"当前无变更建议",adding:"添加中",removing:"ROA移除中",keep:"请依原样保留。",willResult:"将会导致",yourChoice:"您的选择",ourSuggestion:"我们的建议",ourSuggestionHelp:"我们的建议是建立在RIPE RIS路由信息上的,请确认!",addThis:"添加该",removeThis:"移除该",willAdd:"将会添加该ROA",willRemove:"将会移除移除该ROA",reasons:{not_found:"允许未被您ROA涵盖的路由宣告",not_held:"ROA无法发布,您的证书不再包含相关的地址前缀",invalid_asn:"允许来自新的ASN的路由宣告",invalid_length:"允许该ASN相关更详细前缀的路由宣告",stale:"未发现与ROA相关的宣告",disallowing:"该ROA仅能禁止路由宣告。若这是您的诉求,我们推荐创建AS0的ROA。",as0_redundant:"ROA冗余",redundant:"ROA冗余",too_permissive:"ROA允许额外的路由宣告,这可能被路径欺骗攻击滥用",specific:"在ROA中允许可能过于宽容的详细路由宣告",new:"新"}},syncParents:"更新父级CA",syncRepo:"更新数据库",lastExchange:"最近交换",exchangeUri:"URI",nextExchange:"下次交换前",allResources:"所有资源",entitlements:"授权机制",showEntitlements:"显示授权机制详情",parentCertificate:"父级证书",published:"已发布"},aspas:{customer:"Customer",providers:"Providers",search:"Search for customer, provider...",confirmation:{title:"Warning",message:"This will remove the ASPA '{customer} => {providers}'. Continue?",added:"ASPA added",retired:"ASPA removed",retiredSuccess:"The ASPA has been removed",addedSuccess:"The ASPA has been added",commentUpdatedSuccess:"The ASPA comment has been updated"},customer_validation_format:"The customer format is invalid or already exists",providers_validation_format:"The providers format is invalid",add:"Add ASPA",edit:"Edit ASPA",analyse:"Analyse providers",detected_providers:"Declared providers",providers_missing:"ASNs observed in RIS but not in the provider list. Please verify that none of these ASNs act as your provider.",no_aspas:"Krill did not find any ASNs. You need an ASN to be able to create an ASPA for it."},announcements:{noRoasOrAnnouncements:"未发现ROA或路由宣告。",search:"搜索ASN,地址前缀,状态中⋯⋯",authorizes:"授权了{number}个路由宣告",disallows:"禁止了{number}个路由宣告",asn:"ASN",prefix:"前缀",stateLabel:"状态",state:{roa_seen:"可见",roa_seen_help:"该ROA符合BGP中可见的路由宣告",roa_unseen:"不可见",roa_unseen_help:"未找到符合该ROA的BGP路由宣告",roa_not_held:"前缀已移除",roa_not_held_help:"该前缀已不在您的证书上,这条ROA将不会被发布",roa_no_announcement_info:"无路由宣告信息",roa_too_permissive:"过于宽容",roa_too_permissive_help:"该ROA符合BGP中的路由宣告,但同时也允许不可见的路由宣告",roa_disallowing:"禁止中",roa_disallowing_help:"该ROA仅能禁止路由宣告。若这是您的诉求,推荐创建AS0的ROA。",roa_redundant:"冗余",roa_redundant_help:"由于存在一或多个该前缀,掩码及ASN相关的ROA,该ROA是多余的",roa_as0:"AS0",roa_as0_help:"通过该ROA可禁止某一前缀的所有路由宣告",roa_as0_redundant:"冗余",roa_as0_redundant_help:"由于存在一或多个该前缀相关的ROA,因此该AS0 ROA是多余的",announcement_not_found:"未找到",announcement_not_found_help:"该路由宣告未被您的ROA保护",announcement_invalid_length:"无效掩码",announcement_invalid_length_help:"该路由宣告因前缀及其最大长度比您给予该ASN的授权更大而不被允许",announcement_invalid_asn:"无效ASN",announcement_invalid_asn_help:"该路由宣告因您仅将该前缀授权给另一ASN而不被允许",announcement_disallowed:"DISALLOWED BY AS0",announcement_disallowed_help:"This announcement is not allowed because you have an AS0 ROA that disallows it"},download:"下载CSV"},deltaErrors:{duplicates:"已存在该ROA",covered:"存在被覆盖的ROA",notheld:"不是您的前缀",unknowns:"未知",invalid_length:"无效掩码长度",covering:"正在覆盖现有的ROA",as0_exists:"存在AS0",as0_overlaps:"存在被覆盖的ROA"},errors:{repo_not_set:"您必须先设置数据库",pub_unknown:"未知发布者:'{publisher}'",pub_duplicate:"发布者:'{publisher}'已被初始化",pub_outside_jail:"发布者uri:'{uri}'不在数据库uri:'{sia_base}'中",pub_uri_no_slash:"发布者uri '{uri}'必须以右斜杠结尾",pub_no_embedded_repo:"无已配置的内置数据库",ca_duplicate:"名为'{ca}'的CA已被初始化",ca_unknown:"未知CA:'{ca}'",ca_repo_same:"该数据库正在使用中",ca_repo_issue:"从数据库收到错误: {cause}",ca_repo_response_invalid_xml:"返回无效数据库应答xml",ca_repo_response_wrong_xml:"收到父级CA应答而非数据库应答",ca_parent_duplicate:"名为'{parent}'的父级CA已存在",ca_parent_xml_duplicate:"该响应已被名为'{parent}'的父级CA使用",ca_parent_unknown:"您没有名为'{parent}'的父级CA",ca_parent_issue:"从父级CA '{parent}'收到错误: {cause}",ca_parent_response_invalid_xml:"收到无效的父级CA应答xml",ca_parent_response_wrong_xml:"添加父级CA时收到数据库应答",ca_child_duplicate:"您已有名为'{child}'的子CA",ca_child_unknown:"您没有名为'{child}'的子CA",ca_child_resources_required:"您必须为名为'{child}'的子CA指定资源",ca_roa_unknown:"无法移除未知ROA '{prefix}-{max_length} => {asn}'",ca_roa_duplicate:"重复的ROA '{prefix}-{max_length} => {asn}'",ca_roa_invalid_max_length:"于ROA '{prefix}-{max_length} => {asn}'中的最大掩码长度无效",ca_roa_not_entitled:"ROA前缀:'{prefix}'未列于您的任一证书当中",ta_not_allowed:"该功能不提供给测试用信任锚",ta_name_reserved:"该名字被保留",ca_roa_delta_error:"ROA因下列原因被拒绝",api_insufficient_rights:"当前用户无权限进行该操作。请联系您的超管。",api_invalid_credentials:"您提供的密钥错误。",api_login_error:"登录时出现错误:{cause}",api_auth_transient_error:"试图验证你的请求时出现(临时)错误。请重新尝试。",api_auth_permanent_error:"试图验证你的请求时出现错误。请联系您的超管。",api_auth_session_expired:"您的登录已过期。请重新登录⋯⋯",general_error:"出现错误。请联系您的超管。"},testbed:{welcome:"欢迎来到RPKI实验环境",disclaimer:{heading:"免责声明",body:"本实验环境提供完全独立的RPKI等级结构,以作为评估用途。它允许您为您的子CA注册任何IP或ASN资源。本服务的可用性不被担保。如果您遇到任何问题,请告知我们。"},rpconfighelp:{heading:"实验环境TAL",body:"如需验证发布至本实验环境的数据,请下载该信任锚定位器 (TAL)并将其配置在您的依赖方软件中。请注意您绝不应在生产环境使用该TAL。这仅为测试提供。"},regunreg:{heading:"注册/注销",body:"

使用此表格将您的RPKI证书注册机构作为实验环境的子CA注册,以便您创建您声明已获取的资源的路由起源授权(ROA)。

若您无意托管Rsync及RRDP数据库,您可用注册发布者表格设置将您的ROA发布于由实验环境托管的数据库中。使用注销表格以中断此前建立的关系(亦针对其他实验环境的用户生效)。

"},rfcdoclink:"点此以阅读该XML相关的RFC-8183文档",childhandle:"子Handle",publisherhandle:"发布者Handle",responseXML:"实验环境应答XML",addChild:{heading:"注册CA",requestXML:{label:"子CA申请XML",placeholder:"复制您的 XML到此处"},asnresources:{label:"ASN资源",placeholder:"AS资源:如AS1, AS3-4"},ipv4resources:{label:"IPv4资源",placeholder:"IPv4资源:如192.168.0.0/16"},ipv6resources:{label:"IPv6资源",placeholder:"IPv6资源:如2001:db8::/32"},confirm:"注册子CA",format:"此为无效的子CA申请XML",required:"请提供子CA申请的XML",confirmation:{title:"警告",message:"您确认在实验环境注册该CA吗?"},success:"子CA:'{child_handle}'已被添加至实验环境。",registeranother:"注册另一CA"},removeChild:{heading:"注销CA",placeholder:"输入CA名字以移除",confirm:"移除子CA",confirmation:{title:"警告",message:"您确定从实验环境移除此子CA吗?"},success:"子CA:'{child_handle}'已被添加到实验环境。"},addPublisher:{heading:"发布者注册",requestXML:{label:"发布者申请XML",placeholder:"复制您的 XML到这里"},confirm:"发布者注册",format:"这不是有效的发布者申请XML",required:"请提供发布者申请XML",confirmation:{title:"警告",message:"确定在实验环境中注册该发布者吗?"},success:"发布者:'{publisher_handle}'已被添加到实验环境。",registeranother:"注册另一发布者"},removePublisher:{heading:"注销发布者",placeholder:"输入发布者名称以移除",confirm:"移除发布者",confirmation:{title:"警告",message:"您确认取消该发布者在实验环境的注册吗?"},success:"发布者:'{publisher_handle}'已从实验环境移除。"},errors:{invalid_xml:"无效的XML: {err}",missing_xml_el:"缺少{el}元素",missing_xml_child_el:"{parent}元素的缺少{el}子元素",missing_xml_attr:"{el}元素上缺少属性{attr}",empty_xml_el:"{el}元素不得为空",empty_xml_attr:"{el}元素上的{attr}属性不得为空",non_ascii_xml_el:"{el}元素不得包含非ASCII符号",child_handle_required:"子Handle为必填项",publisher_handle_required:"发布者Handle为必填项",non_base64_certificate_xml_el:"{el}元素必须正确包含由Base64编码的自签名X.509 BPKI证书",invalid_registration_data:"您的注册信息无法被正确解析"}}};export{e as translations}; diff --git a/ui/assets/zh-Hans-6406b9d3.js b/ui/assets/zh-Hans-6406b9d3.js deleted file mode 100644 index bae5d154..00000000 --- a/ui/assets/zh-Hans-6406b9d3.js +++ /dev/null @@ -1 +0,0 @@ -const e={common:{readthedocs:"阅读使用手册",report:"反馈问题",confirm:"确认",cancel:"取消",ok:"OK",error:"错误",success:"成功!",copy:"复制到剪贴板",download:"下载",dropOrClick:"拖动文件至此处或点此上传",started:"Krill起始运行时间为",newversion:"有版本更新!",supportcontracts:"服务合同",warning:"警告",idle:"您因无活动而被登出。",nodata:"无数据",copySuccess:"XML已复制到您的剪贴板",edit:"编辑",page:"页面",userInfo:{title:"登录数据",user:"用户"}},login:{password:"密码",placeholder:"您的密码",signin:"登录",required:"请输入您的密码",error:"您输入的密钥有误",copied:"请勿使用从https://xkcd.com/936/获得的密码",id:"用户名",idPlaceholder:"您的用户名",idRequired:"请输入您的用户名",retry:"点击{0}返回登陆页面。",here:"这里"},onboarding:{welcome:"欢迎来到Krill",welcomeHtml:"让我们从创建您的RPKI证书颁发机构(CA)开始。它将被用来配置通常为一或多个区域或国家互联网注册管理机构父级CA下发的RPKI。

您选择的handle会被用来在与父级或子级CA交互过程中识别您的CA。它将不会在RPKI中发布。请选择能让他人识别出您机构的handle。设置后handle将无法更改。",addCAForm:{required:"此为必填项",format:"这不是有效的CA名称",confirm:"创建CA",confirmation:{title:"警告",message:"设置后handle将无法更改。是否继续?"}}},cas:{loading:"加载证书颁发机构中",ca:"证书颁发机构",cas:"证书颁发机构",search:"搜索CAs⋯⋯",noCas:"当前没有已被界定的证书颁发机构。"},caDetails:{loading:"加载{handle}中",refresh:"刷新{handle}中,可能需要稍作等待",current:"当前证书颁发机构",download:"下载PEM",noRoas:"未找到ROA。",noResources:"您暂未获得任何资源",noChildren:"未发现子CA",addRoa:"添加ROA",addAspa:"Add ASPA",editAspa:"Edit ASPA",roas:"ROA",aspas:"ASPA",resources:"资源",parents:"父级CA",repo:"数据库",type:"类型",properties:"特性",property:"特性",value:"数值",kind:"类别",resource:"资源",children:"子项",handle:"Handle",comment:"备注",maxLength:"最大长度",maxLengthTooltip:"若不指定最大长度,该长度默认为地址前缀的掩码长度。",confirmation:{title:"警告",message:"此举将会移除ROA '{prefix}-{max_length} => {asn}'。是否继续?",added:"已添加ROA",retired:"已移除ROA",retiredSuccess:"该ROA已被移除",addedSuccess:"该ROA已被添加",commentUpdatedSuccess:"该ROA的备注已更新"},addROAForm:{required:"该项为必填项",asn_format:"这不是有效的ASN",prefix_format:"请输入有效的IPv4或IPv6前缀"},onboardingWarning:"您需要将您的CA与可发布您的证书及ROA的公共RPKI数据库相连接。当父级CA配置完成时,关联的受信任软件将立即开始下载您于此数据库创建的证书及ROA。",initializeRepository:"在您的CA向父级CA申请资源证书前您仍需为它设置一个数据库",initialize:"请先初始化RPKI数据库及/或父级CA。",noResourcesYet:"您暂未获得任何资源",clickToRefresh:"点此刷新",parentsTab:{request:"子CA请求",response:"父级CA应答",addParent:"添加额外的父级CA",addParentSuccess:"父级CA已添加",name:"父级CA名称",namerequired:"父级CA名称为必填项",nameformat:"该父级CA名称无效"},repoTab:{request:"发布者申请",addRepo:"添加数据库",response:"数据库应答",addRepoSuccess:"数据库已添加"},analyseThis:"分析我的ROA",analysis:"ROA分析",suggestions:{following:"请确认以下关于您ROA的建议更新。",readMore:"阅读更多⋯⋯",nochanges:"当前无变更建议",adding:"添加中",removing:"ROA移除中",keep:"请依原样保留。",willResult:"将会导致",yourChoice:"您的选择",ourSuggestion:"我们的建议",ourSuggestionHelp:"我们的建议是建立在RIPE RIS路由信息上的,请确认!",addThis:"添加该",removeThis:"移除该",willAdd:"将会添加该ROA",willRemove:"将会移除移除该ROA",reasons:{not_found:"允许未被您ROA涵盖的路由宣告",not_held:"ROA无法发布,您的证书不再包含相关的地址前缀",invalid_asn:"允许来自新的ASN的路由宣告",invalid_length:"允许该ASN相关更详细前缀的路由宣告",stale:"未发现与ROA相关的宣告",disallowing:"该ROA仅能禁止路由宣告。若这是您的诉求,我们推荐创建AS0的ROA。",as0_redundant:"ROA冗余",redundant:"ROA冗余",too_permissive:"ROA允许额外的路由宣告,这可能被路径欺骗攻击滥用",specific:"在ROA中允许可能过于宽容的详细路由宣告",new:"新"}},syncParents:"更新父级CA",syncRepo:"更新数据库",lastExchange:"最近交换",exchangeUri:"URI",nextExchange:"下次交换前",allResources:"所有资源",entitlements:"授权机制",showEntitlements:"显示授权机制详情",parentCertificate:"父级证书",published:"已发布"},aspas:{customer:"Customer",providers:"Providers",search:"Search for customer, provider...",confirmation:{title:"Warning",message:"This will remove the ASPA '{customer} => {providers}'. Continue?",added:"ASPA added",retired:"ASPA removed",retiredSuccess:"The ASPA has been removed",addedSuccess:"The ASPA has been added",commentUpdatedSuccess:"The ASPA comment has been updated"},customer_validation_format:"The customer format is invalid or already exists",providers_validation_format:"The providers format is invalid"},announcements:{noRoasOrAnnouncements:"未发现ROA或路由宣告。",search:"搜索ASN,地址前缀,状态中⋯⋯",authorizes:"授权了{number}个路由宣告",disallows:"禁止了{number}个路由宣告",asn:"ASN",prefix:"前缀",stateLabel:"状态",state:{roa_seen:"可见",roa_seen_help:"该ROA符合BGP中可见的路由宣告",roa_unseen:"不可见",roa_unseen_help:"未找到符合该ROA的BGP路由宣告",roa_not_held:"前缀已移除",roa_not_held_help:"该前缀已不在您的证书上,这条ROA将不会被发布",roa_no_announcement_info:"无路由宣告信息",roa_too_permissive:"过于宽容",roa_too_permissive_help:"该ROA符合BGP中的路由宣告,但同时也允许不可见的路由宣告",roa_disallowing:"禁止中",roa_disallowing_help:"该ROA仅能禁止路由宣告。若这是您的诉求,推荐创建AS0的ROA。",roa_redundant:"冗余",roa_redundant_help:"由于存在一或多个该前缀,掩码及ASN相关的ROA,该ROA是多余的",roa_as0:"AS0",roa_as0_help:"通过该ROA可禁止某一前缀的所有路由宣告",roa_as0_redundant:"冗余",roa_as0_redundant_help:"由于存在一或多个该前缀相关的ROA,因此该AS0 ROA是多余的",announcement_not_found:"未找到",announcement_not_found_help:"该路由宣告未被您的ROA保护",announcement_invalid_length:"无效掩码",announcement_invalid_length_help:"该路由宣告因前缀及其最大长度比您给予该ASN的授权更大而不被允许",announcement_invalid_asn:"无效ASN",announcement_invalid_asn_help:"该路由宣告因您仅将该前缀授权给另一ASN而不被允许",announcement_disallowed:"DISALLOWED BY AS0",announcement_disallowed_help:"This announcement is not allowed because you have an AS0 ROA that disallows it"},download:"下载CSV"},deltaErrors:{duplicates:"已存在该ROA",covered:"存在被覆盖的ROA",notheld:"不是您的前缀",unknowns:"未知",invalid_length:"无效掩码长度",covering:"正在覆盖现有的ROA",as0_exists:"存在AS0",as0_overlaps:"存在被覆盖的ROA"},errors:{repo_not_set:"您必须先设置数据库",pub_unknown:"未知发布者:'{publisher}'",pub_duplicate:"发布者:'{publisher}'已被初始化",pub_outside_jail:"发布者uri:'{uri}'不在数据库uri:'{sia_base}'中",pub_uri_no_slash:"发布者uri '{uri}'必须以右斜杠结尾",pub_no_embedded_repo:"无已配置的内置数据库",ca_duplicate:"名为'{ca}'的CA已被初始化",ca_unknown:"未知CA:'{ca}'",ca_repo_same:"该数据库正在使用中",ca_repo_issue:"从数据库收到错误: {cause}",ca_repo_response_invalid_xml:"返回无效数据库应答xml",ca_repo_response_wrong_xml:"收到父级CA应答而非数据库应答",ca_parent_duplicate:"名为'{parent}'的父级CA已存在",ca_parent_xml_duplicate:"该响应已被名为'{parent}'的父级CA使用",ca_parent_unknown:"您没有名为'{parent}'的父级CA",ca_parent_issue:"从父级CA '{parent}'收到错误: {cause}",ca_parent_response_invalid_xml:"收到无效的父级CA应答xml",ca_parent_response_wrong_xml:"添加父级CA时收到数据库应答",ca_child_duplicate:"您已有名为'{child}'的子CA",ca_child_unknown:"您没有名为'{child}'的子CA",ca_child_resources_required:"您必须为名为'{child}'的子CA指定资源",ca_roa_unknown:"无法移除未知ROA '{prefix}-{max_length} => {asn}'",ca_roa_duplicate:"重复的ROA '{prefix}-{max_length} => {asn}'",ca_roa_invalid_max_length:"于ROA '{prefix}-{max_length} => {asn}'中的最大掩码长度无效",ca_roa_not_entitled:"ROA前缀:'{prefix}'未列于您的任一证书当中",ta_not_allowed:"该功能不提供给测试用信任锚",ta_name_reserved:"该名字被保留",ca_roa_delta_error:"ROA因下列原因被拒绝",api_insufficient_rights:"当前用户无权限进行该操作。请联系您的超管。",api_invalid_credentials:"您提供的密钥错误。",api_login_error:"登录时出现错误:{cause}",api_auth_transient_error:"试图验证你的请求时出现(临时)错误。请重新尝试。",api_auth_permanent_error:"试图验证你的请求时出现错误。请联系您的超管。",api_auth_session_expired:"您的登录已过期。请重新登录⋯⋯",general_error:"出现错误。请联系您的超管。"},testbed:{welcome:"欢迎来到RPKI实验环境",disclaimer:{heading:"免责声明",body:"本实验环境提供完全独立的RPKI等级结构,以作为评估用途。它允许您为您的子CA注册任何IP或ASN资源。本服务的可用性不被担保。如果您遇到任何问题,请告知我们。"},rpconfighelp:{heading:"实验环境TAL",body:"如需验证发布至本实验环境的数据,请下载该信任锚定位器 (TAL)并将其配置在您的依赖方软件中。请注意您绝不应在生产环境使用该TAL。这仅为测试提供。"},regunreg:{heading:"注册/注销",body:"

使用此表格将您的RPKI证书注册机构作为实验环境的子CA注册,以便您创建您声明已获取的资源的路由起源授权(ROA)。

若您无意托管Rsync及RRDP数据库,您可用注册发布者表格设置将您的ROA发布于由实验环境托管的数据库中。使用注销表格以中断此前建立的关系(亦针对其他实验环境的用户生效)。

"},rfcdoclink:"点此以阅读该XML相关的RFC-8183文档",childhandle:"子Handle",publisherhandle:"发布者Handle",responseXML:"实验环境应答XML",addChild:{heading:"注册CA",requestXML:{label:"子CA申请XML",placeholder:"复制您的 XML到此处"},asnresources:{label:"ASN资源",placeholder:"AS资源:如AS1, AS3-4"},ipv4resources:{label:"IPv4资源",placeholder:"IPv4资源:如192.168.0.0/16"},ipv6resources:{label:"IPv6资源",placeholder:"IPv6资源:如2001:db8::/32"},confirm:"注册子CA",format:"此为无效的子CA申请XML",required:"请提供子CA申请的XML",confirmation:{title:"警告",message:"您确认在实验环境注册该CA吗?"},success:"子CA:'{child_handle}'已被添加至实验环境。",registeranother:"注册另一CA"},removeChild:{heading:"注销CA",placeholder:"输入CA名字以移除",confirm:"移除子CA",confirmation:{title:"警告",message:"您确定从实验环境移除此子CA吗?"},success:"子CA:'{child_handle}'已被添加到实验环境。"},addPublisher:{heading:"发布者注册",requestXML:{label:"发布者申请XML",placeholder:"复制您的 XML到这里"},confirm:"发布者注册",format:"这不是有效的发布者申请XML",required:"请提供发布者申请XML",confirmation:{title:"警告",message:"确定在实验环境中注册该发布者吗?"},success:"发布者:'{publisher_handle}'已被添加到实验环境。",registeranother:"注册另一发布者"},removePublisher:{heading:"注销发布者",placeholder:"输入发布者名称以移除",confirm:"移除发布者",confirmation:{title:"警告",message:"您确认取消该发布者在实验环境的注册吗?"},success:"发布者:'{publisher_handle}'已从实验环境移除。"},errors:{invalid_xml:"无效的XML: {err}",missing_xml_el:"缺少{el}元素",missing_xml_child_el:"{parent}元素的缺少{el}子元素",missing_xml_attr:"{el}元素上缺少属性{attr}",empty_xml_el:"{el}元素不得为空",empty_xml_attr:"{el}元素上的{attr}属性不得为空",non_ascii_xml_el:"{el}元素不得包含非ASCII符号",child_handle_required:"子Handle为必填项",publisher_handle_required:"发布者Handle为必填项",non_base64_certificate_xml_el:"{el}元素必须正确包含由Base64编码的自签名X.509 BPKI证书",invalid_registration_data:"您的注册信息无法被正确解析"}}};export{e as translations}; diff --git a/ui/assets/zh-Hant-8af42392.js b/ui/assets/zh-Hant-8af42392.js new file mode 100644 index 00000000..326bcc6e --- /dev/null +++ b/ui/assets/zh-Hant-8af42392.js @@ -0,0 +1 @@ +const e={common:{readthedocs:"閱讀文檔",report:"反饋問題",confirm:"確認",cancel:"取消",ok:"OK",error:"錯誤",success:"成功!",copy:"複製到剪貼板",download:"下載",dropOrClick:"拖拽文件至此處或點此上載",started:"Krill初始運行時間為",newversion:"有版本更新!",supportcontracts:"服務合約",warning:"警告",idle:"您因無活動而被登出。",nodata:"無數據",copySuccess:"XML已複製到剪貼板",edit:"編輯",page:"頁面",userInfo:{title:"登錄數據",user:"用戶"}},login:{password:"密碼",placeholder:"您的密碼",signin:"登錄",required:"請輸入您的密碼",error:"您鍵入的密碼有誤",copied:"請勿使用自https://xkcd.com/936/取得的密碼",id:"用戶名",idPlaceholder:"您的用戶名",idRequired:"請輸入您的用戶名",retry:"點擊{0}返回登錄界面。",here:"這裡"},onboarding:{welcome:"歡迎來到Krill",welcomeHtml:"讓我們從創建您的RPKI證書頒發機構(CA)開始。它將被用來配置通常為一或多個區域或國家互聯網註冊管理機構父級CA下發的RPKI。

您選擇的handle會被用來在與父級或子級CA交互過程中識別您的CA。它將不會在RPKI中發布。請選擇能讓他人識別出您機構的handle。設置後handle將無法更改。",addCAForm:{required:"此為必填項",format:"這不是有效的CA名稱",confirm:"創建CA",confirmation:{title:"警告",message:"設置後handle將無法更改。是否繼續?"}}},cas:{loading:"加載證書頒發機構中",ca:"證書頒發機構",cas:"證書頒發機構",search:"搜索CAs⋯⋯",noCas:"當前沒有已被界定的證書頒發機構。"},caDetails:{loading:"加載{handle}中",refresh:"刷新{handle}中,可能需要略作等待",current:"當前證書頒發機構",download:"下載PEM",noRoas:"未找到ROA。",noResources:"您暫為獲得任何資源",noChildren:"未發現子CA",addRoa:"添加ROA",addAspa:"Add ASPA",editAspa:"Edit ASPA",roas:"ROA",aspas:"ASPA",resources:"資源",parents:"父級CA",repo:"數據庫",type:"類型",properties:"特性",property:"特性",value:"數值",kind:"類別",resource:"資源",children:"子項",handle:"Handle",comment:"備註",maxLength:"最大長度",maxLengthTooltip:"若不指定最大長度,該長度默認為地址前綴的掩碼長度。",confirmation:{title:"警告",message:"此舉將會移除ROA '{prefix}-{max_length} => {asn}'。是否繼續?",added:"已添加ROA",retired:"已移除ROA",retiredSuccess:"該ROA已被移除",addedSuccess:"該ROA已被添加",commentUpdatedSuccess:"該ROA的備註已更新"},addROAForm:{required:"該項為必填項",asn_format:"這不是有效的ASN",prefix_format:"請輸入有效的IPv4或IPv6前綴"},onboardingWarning:"您需要將您的CA與可發布您的證書及ROA的公共RPKI數據庫相連結。當父級CA配置完成時,關聯的受信任軟件將立即開始下載您於此數據庫創建的證書及ROA。",initializeRepository:"在您的CA向父級CA申請資源證書前您仍須為它設置一个數據庫",initialize:"請先初始化RPKI數據庫及/或父級CA。",noResourcesYet:"您暫未獲得任何資源",clickToRefresh:"點此刷新",parentsTab:{request:"子CA請求",response:"父級CA應答",addParent:"添加額外的父級CA",addParentSuccess:"父級CA已添加",name:"父級CA名稱",namerequired:"父級CA名稱為必填項",nameformat:"該父級CA名稱無效"},repoTab:{request:"發布者申請",addRepo:"添加數據庫",response:"數據庫應答",addRepoSuccess:"數據庫已添加"},analyseThis:"分析我的ROA",analysis:"ROA分析",suggestions:{following:"請確認以下關於您ROA的建議更新。",readMore:"閱讀更多⋯⋯",nochanges:"當前無變更建議",adding:"添加中",removing:"ROA移除中",keep:"請依原樣保留。",willResult:"將會導致",yourChoice:"您的選擇",ourSuggestion:"我們的建議",ourSuggestionHelp:"我們的建議是建立在RIPE RIS路由信息上的,請確認!",addThis:"添加該",removeThis:"移除該",willAdd:"將會添加該ROA",willRemove:"將會移除移除該ROA",reasons:{not_found:"允許未被您ROA涵蓋的路由宣告",not_held:"ROA無法發布,您的證書不再包含相關的地址前綴",invalid_asn:"允許來自新的ASN的路由宣告",invalid_length:"允許該ASN相關更詳細前綴的路由宣告",stale:"未發現與ROA相關的宣告",disallowing:"該ROA僅能禁止路由宣告。若這是您的訴求,我們推荐創建AS0的ROA。",as0_redundant:"ROA冗余",redundant:"ROA冗余",too_permissive:"ROA允許額外的路由宣告,這可能被路径欺詐攻擊濫用",specific:"在ROA中允許可能過於寬容的詳細路由宣告",new:"新"}},syncParents:"更新父級CA",syncRepo:"更新數據庫",lastExchange:"最近交換",exchangeUri:"URI",nextExchange:"下次交換前",allResources:"所有資源",entitlements:"授權機制",showEntitlements:"顯示授權機制詳情",parentCertificate:"父級證書",published:"已發布"},aspas:{customer:"Customer",providers:"Providers",search:"Search for customer, provider...",confirmation:{title:"Warning",message:"This will remove the ASPA '{customer} => {providers}'. Continue?",added:"ASPA added",retired:"ASPA removed",retiredSuccess:"The ASPA has been removed",addedSuccess:"The ASPA has been added",commentUpdatedSuccess:"The ASPA comment has been updated"},customer_validation_format:"The customer format is invalid or already exists",providers_validation_format:"The providers format is invalid",add:"Add ASPA",edit:"Edit ASPA",analyse:"Analyse providers",detected_providers:"Declared providers",providers_missing:"ASNs observed in RIS but not in the provider list. Please verify that none of these ASNs act as your provider.",no_aspas:"Krill did not find any ASNs. You need an ASN to be able to create an ASPA for it."},announcements:{noRoasOrAnnouncements:"未發現ROA或路由宣告。",search:"搜索ASN,地址前綴,狀態中⋯⋯",authorizes:"授權了{number}個路由宣告",disallows:"禁止了{number}個路由宣告",asn:"ASN",prefix:"前綴",stateLabel:"狀態",state:{roa_seen:"可見",roa_seen_help:"該ROA符合BGP中可見的路由宣告",roa_unseen:"不可見",roa_unseen_help:"未找到符合該ROA的BGP路由宣告",roa_not_held:"前綴已移除",roa_not_held_help:"該前綴已不在您的證書上,這条ROA將不會被發布",roa_no_announcement_info:"無路由宣告信息",roa_too_permissive:"過於寬容",roa_too_permissive_help:"該ROA符合BGP中的路由宣告,但同時也允許不可見的路由宣告",roa_disallowing:"禁止中",roa_disallowing_help:"該ROA僅能禁止路由宣告。若這是您的訴求,推荐創建AS0的ROA。",roa_redundant:"冗余",roa_redundant_help:"由於存在一或多个該前綴,掩碼及ASN相關的ROA,該ROA是多餘的",roa_as0:"AS0",roa_as0_help:"通过該ROA可禁止某一前綴的所有路由宣告",roa_as0_redundant:"冗余",roa_as0_redundant_help:"由於存在一或多个該前綴相關的ROA,因此該AS0 ROA是多餘的",announcement_not_found:"未找到",announcement_not_found_help:"該路由宣告未被您的ROA保護",announcement_invalid_length:"無效掩碼",announcement_invalid_length_help:"該路由宣告因前綴及其最大長度比您给予該ASN的授權更大而不被允許",announcement_invalid_asn:"無效ASN",announcement_invalid_asn_help:"該路由宣告因您僅將該前綴授權给另一ASN而不被允許",announcement_disallowed:"DISALLOWED BY AS0",announcement_disallowed_help:"This announcement is not allowed because you have an AS0 ROA that disallows it"},download:"下載CSV"},deltaErrors:{duplicates:"已存在該ROA",covered:"存在被覆蓋的ROA",notheld:"不是您的前綴",unknowns:"未知",invalid_length:"無效掩碼長度",covering:"正在覆蓋現有的ROA",as0_exists:"存在AS0",as0_overlaps:"存在被覆蓋的ROA"},errors:{repo_not_set:"您必須先設置數據庫",pub_unknown:"未知發布者:'{publisher}'",pub_duplicate:"發布者:'{publisher}'已被初始化",pub_outside_jail:"發布者uri:'{uri}'不在數據庫uri:'{sia_base}'中",pub_uri_no_slash:"發布者uri '{uri}'必須以右斜槓結尾",pub_no_embedded_repo:"無已配置的內置數據庫",ca_duplicate:"名為'{ca}'的CA已被初始化",ca_unknown:"未知CA:'{ca}'",ca_repo_same:"該數據庫正在使用中",ca_repo_issue:"从數據庫收到錯誤: {cause}",ca_repo_response_invalid_xml:"返回無效數據庫應答xml",ca_repo_response_wrong_xml:"收到父級CA應答而非數據庫應答",ca_parent_duplicate:"名為'{parent}'的父級CA已存在",ca_parent_xml_duplicate:"該响应已被名為'{parent}'的父級CA使用",ca_parent_unknown:"您没有名為'{parent}'的父級CA",ca_parent_issue:"从父級CA '{parent}'收到錯誤: {cause}",ca_parent_response_invalid_xml:"收到無效的父級CA應答xml",ca_parent_response_wrong_xml:"添加父級CA時收到數據庫應答",ca_child_duplicate:"您已有名為'{child}'的子CA",ca_child_unknown:"您没有名為'{child}'的子CA",ca_child_resources_required:"您必須為名為'{child}'的子CA指定資源",ca_roa_unknown:"無法移除未知ROA '{prefix}-{max_length} => {asn}'",ca_roa_duplicate:"重複的ROA '{prefix}-{max_length} => {asn}'",ca_roa_invalid_max_length:"于ROA '{prefix}-{max_length} => {asn}'中的最大掩碼長度無效",ca_roa_not_entitled:"ROA前綴:'{prefix}'未列于您的任一證書當中",ta_not_allowed:"該功能不提供给測試用信任錨",ta_name_reserved:"該名字被預留",ca_roa_delta_error:"ROA因下列原因被拒絕",api_insufficient_rights:"當前用戶無权限进行該操作。請聯繫您的超管。",api_invalid_credentials:"您提供的密鑰錯誤。",api_login_error:"登錄時出現錯誤:{cause}",api_auth_transient_error:"試圖驗證你的請求時出現(临時)錯誤。請重新尝试。",api_auth_permanent_error:"試圖驗證你的請求時出現錯誤。請聯繫您的超管。",api_auth_session_expired:"您的登錄已過期。請重新登錄⋯⋯",general_error:"出現錯誤。請聯繫您的超管。"},testbed:{welcome:"歡迎來到RPKI實驗環境",disclaimer:{heading:"免責聲明",body:"本實驗環境提供完全獨立的RPKI等級結構,以作為評估用途。它允許您為您的子CA註冊任何IP或ASN資源。本服務的可用性不被擔保。如果您遇到任何問題,請告知我們。"},rpconfighelp:{heading:"實驗環境TAL",body:"如需驗證發布至本實驗環境的數據,請下載該信任錨定位器 (TAL)并將其配置在您的依赖方軟件中。請注意您絕不應在生產環境使用該TAL。因這僅為測試提供。"},regunreg:{heading:"註冊/註銷",body:"

使用此表格將您的RPKI證書註冊机构作為實驗環境的子CA註冊,以便您創建您聲明已獲取的資源的路由來源授權(ROA)。

若您無意託管Rsync及RRDP數據庫,您可用註冊發布者表格設置將您的ROA發布于由實驗環境託管的數據庫中。使用註銷表格以中斷此前建立的關係(亦針對其他實驗環境的用戶生效)。

"},rfcdoclink:"點此以閱讀該XML相關的RFC-8183文檔",childhandle:"子Handle",publisherhandle:"發布者Handle",responseXML:"實驗環境應答XML",addChild:{heading:"註冊CA",requestXML:{label:"子CA申請XML",placeholder:"複製您的 XML到此處"},asnresources:{label:"ASN資源",placeholder:"AS資源:如AS1, AS3-4"},ipv4resources:{label:"IPv4資源",placeholder:"IPv4資源:如192.168.0.0/16"},ipv6resources:{label:"IPv6資源",placeholder:"IPv6資源:如2001:db8::/32"},confirm:"註冊子CA",format:"此為無效的子CA申請XML",required:"請提供子CA申請的XML",confirmation:{title:"警告",message:"您確認在實驗環境註冊該CA嗎?"},success:"子CA:'{child_handle}'已被添加至實驗環境。",registeranother:"註冊另一CA"},removeChild:{heading:"註銷CA",placeholder:"輸入CA名字以移除",confirm:"移除子CA",confirmation:{title:"警告",message:"您確定从實驗環境移除此子CA嗎?"},success:"子CA:'{child_handle}'已被添加到實驗環境。"},addPublisher:{heading:"發布者註冊",requestXML:{label:"發布者申請XML",placeholder:"複製您的 XML到這里"},confirm:"發布者註冊",format:"這不是有效的發布者申請XML",required:"請提供發布者申請XML",confirmation:{title:"警告",message:"確定在實驗環境中註冊該發布者嗎?"},success:"發布者:'{publisher_handle}'已被添加到實驗環境。",registeranother:"註冊另一發布者"},removePublisher:{heading:"註銷發布者",placeholder:"輸入發布者名稱以移除",confirm:"移除發布者",confirmation:{title:"警告",message:"您確認取消該發布者在實驗環境的註冊嗎?"},success:"發布者:'{publisher_handle}'已从實驗環境移除。"},errors:{invalid_xml:"無效的XML: {err}",missing_xml_el:"缺少{el}元素",missing_xml_child_el:"{parent}元素的缺少{el}子元素",missing_xml_attr:"{el}元素上缺少屬性{attr}",empty_xml_el:"{el}元素不得為空",empty_xml_attr:"{el}元素上的{attr}屬性不得為空",non_ascii_xml_el:"{el}元素不得包含非ASCII符號",child_handle_required:"子Handle為必填項",publisher_handle_required:"發布者Handle為必填項",non_base64_certificate_xml_el:"{el}元素必須正確包含由Base64編碼的自簽名X.509 BPKI證書",invalid_registration_data:"您的註冊信息無法被正確解析"}}};export{e as translations}; diff --git a/ui/assets/zh-Hant-d9271047.js b/ui/assets/zh-Hant-d9271047.js deleted file mode 100644 index 881c433b..00000000 --- a/ui/assets/zh-Hant-d9271047.js +++ /dev/null @@ -1 +0,0 @@ -const e={common:{readthedocs:"閱讀文檔",report:"反饋問題",confirm:"確認",cancel:"取消",ok:"OK",error:"錯誤",success:"成功!",copy:"複製到剪貼板",download:"下載",dropOrClick:"拖拽文件至此處或點此上載",started:"Krill初始運行時間為",newversion:"有版本更新!",supportcontracts:"服務合約",warning:"警告",idle:"您因無活動而被登出。",nodata:"無數據",copySuccess:"XML已複製到剪貼板",edit:"編輯",page:"頁面",userInfo:{title:"登錄數據",user:"用戶"}},login:{password:"密碼",placeholder:"您的密碼",signin:"登錄",required:"請輸入您的密碼",error:"您鍵入的密碼有誤",copied:"請勿使用自https://xkcd.com/936/取得的密碼",id:"用戶名",idPlaceholder:"您的用戶名",idRequired:"請輸入您的用戶名",retry:"點擊{0}返回登錄界面。",here:"這裡"},onboarding:{welcome:"歡迎來到Krill",welcomeHtml:"讓我們從創建您的RPKI證書頒發機構(CA)開始。它將被用來配置通常為一或多個區域或國家互聯網註冊管理機構父級CA下發的RPKI。

您選擇的handle會被用來在與父級或子級CA交互過程中識別您的CA。它將不會在RPKI中發布。請選擇能讓他人識別出您機構的handle。設置後handle將無法更改。",addCAForm:{required:"此為必填項",format:"這不是有效的CA名稱",confirm:"創建CA",confirmation:{title:"警告",message:"設置後handle將無法更改。是否繼續?"}}},cas:{loading:"加載證書頒發機構中",ca:"證書頒發機構",cas:"證書頒發機構",search:"搜索CAs⋯⋯",noCas:"當前沒有已被界定的證書頒發機構。"},caDetails:{loading:"加載{handle}中",refresh:"刷新{handle}中,可能需要略作等待",current:"當前證書頒發機構",download:"下載PEM",noRoas:"未找到ROA。",noResources:"您暫為獲得任何資源",noChildren:"未發現子CA",addRoa:"添加ROA",addAspa:"Add ASPA",editAspa:"Edit ASPA",roas:"ROA",aspas:"ASPA",resources:"資源",parents:"父級CA",repo:"數據庫",type:"類型",properties:"特性",property:"特性",value:"數值",kind:"類別",resource:"資源",children:"子項",handle:"Handle",comment:"備註",maxLength:"最大長度",maxLengthTooltip:"若不指定最大長度,該長度默認為地址前綴的掩碼長度。",confirmation:{title:"警告",message:"此舉將會移除ROA '{prefix}-{max_length} => {asn}'。是否繼續?",added:"已添加ROA",retired:"已移除ROA",retiredSuccess:"該ROA已被移除",addedSuccess:"該ROA已被添加",commentUpdatedSuccess:"該ROA的備註已更新"},addROAForm:{required:"該項為必填項",asn_format:"這不是有效的ASN",prefix_format:"請輸入有效的IPv4或IPv6前綴"},onboardingWarning:"您需要將您的CA與可發布您的證書及ROA的公共RPKI數據庫相連結。當父級CA配置完成時,關聯的受信任軟件將立即開始下載您於此數據庫創建的證書及ROA。",initializeRepository:"在您的CA向父級CA申請資源證書前您仍須為它設置一个數據庫",initialize:"請先初始化RPKI數據庫及/或父級CA。",noResourcesYet:"您暫未獲得任何資源",clickToRefresh:"點此刷新",parentsTab:{request:"子CA請求",response:"父級CA應答",addParent:"添加額外的父級CA",addParentSuccess:"父級CA已添加",name:"父級CA名稱",namerequired:"父級CA名稱為必填項",nameformat:"該父級CA名稱無效"},repoTab:{request:"發布者申請",addRepo:"添加數據庫",response:"數據庫應答",addRepoSuccess:"數據庫已添加"},analyseThis:"分析我的ROA",analysis:"ROA分析",suggestions:{following:"請確認以下關於您ROA的建議更新。",readMore:"閱讀更多⋯⋯",nochanges:"當前無變更建議",adding:"添加中",removing:"ROA移除中",keep:"請依原樣保留。",willResult:"將會導致",yourChoice:"您的選擇",ourSuggestion:"我們的建議",ourSuggestionHelp:"我們的建議是建立在RIPE RIS路由信息上的,請確認!",addThis:"添加該",removeThis:"移除該",willAdd:"將會添加該ROA",willRemove:"將會移除移除該ROA",reasons:{not_found:"允許未被您ROA涵蓋的路由宣告",not_held:"ROA無法發布,您的證書不再包含相關的地址前綴",invalid_asn:"允許來自新的ASN的路由宣告",invalid_length:"允許該ASN相關更詳細前綴的路由宣告",stale:"未發現與ROA相關的宣告",disallowing:"該ROA僅能禁止路由宣告。若這是您的訴求,我們推荐創建AS0的ROA。",as0_redundant:"ROA冗余",redundant:"ROA冗余",too_permissive:"ROA允許額外的路由宣告,這可能被路径欺詐攻擊濫用",specific:"在ROA中允許可能過於寬容的詳細路由宣告",new:"新"}},syncParents:"更新父級CA",syncRepo:"更新數據庫",lastExchange:"最近交換",exchangeUri:"URI",nextExchange:"下次交換前",allResources:"所有資源",entitlements:"授權機制",showEntitlements:"顯示授權機制詳情",parentCertificate:"父級證書",published:"已發布"},aspas:{customer:"Customer",providers:"Providers",search:"Search for customer, provider...",confirmation:{title:"Warning",message:"This will remove the ASPA '{customer} => {providers}'. Continue?",added:"ASPA added",retired:"ASPA removed",retiredSuccess:"The ASPA has been removed",addedSuccess:"The ASPA has been added",commentUpdatedSuccess:"The ASPA comment has been updated"},customer_validation_format:"The customer format is invalid or already exists",providers_validation_format:"The providers format is invalid"},announcements:{noRoasOrAnnouncements:"未發現ROA或路由宣告。",search:"搜索ASN,地址前綴,狀態中⋯⋯",authorizes:"授權了{number}個路由宣告",disallows:"禁止了{number}個路由宣告",asn:"ASN",prefix:"前綴",stateLabel:"狀態",state:{roa_seen:"可見",roa_seen_help:"該ROA符合BGP中可見的路由宣告",roa_unseen:"不可見",roa_unseen_help:"未找到符合該ROA的BGP路由宣告",roa_not_held:"前綴已移除",roa_not_held_help:"該前綴已不在您的證書上,這条ROA將不會被發布",roa_no_announcement_info:"無路由宣告信息",roa_too_permissive:"過於寬容",roa_too_permissive_help:"該ROA符合BGP中的路由宣告,但同時也允許不可見的路由宣告",roa_disallowing:"禁止中",roa_disallowing_help:"該ROA僅能禁止路由宣告。若這是您的訴求,推荐創建AS0的ROA。",roa_redundant:"冗余",roa_redundant_help:"由於存在一或多个該前綴,掩碼及ASN相關的ROA,該ROA是多餘的",roa_as0:"AS0",roa_as0_help:"通过該ROA可禁止某一前綴的所有路由宣告",roa_as0_redundant:"冗余",roa_as0_redundant_help:"由於存在一或多个該前綴相關的ROA,因此該AS0 ROA是多餘的",announcement_not_found:"未找到",announcement_not_found_help:"該路由宣告未被您的ROA保護",announcement_invalid_length:"無效掩碼",announcement_invalid_length_help:"該路由宣告因前綴及其最大長度比您给予該ASN的授權更大而不被允許",announcement_invalid_asn:"無效ASN",announcement_invalid_asn_help:"該路由宣告因您僅將該前綴授權给另一ASN而不被允許",announcement_disallowed:"DISALLOWED BY AS0",announcement_disallowed_help:"This announcement is not allowed because you have an AS0 ROA that disallows it"},download:"下載CSV"},deltaErrors:{duplicates:"已存在該ROA",covered:"存在被覆蓋的ROA",notheld:"不是您的前綴",unknowns:"未知",invalid_length:"無效掩碼長度",covering:"正在覆蓋現有的ROA",as0_exists:"存在AS0",as0_overlaps:"存在被覆蓋的ROA"},errors:{repo_not_set:"您必須先設置數據庫",pub_unknown:"未知發布者:'{publisher}'",pub_duplicate:"發布者:'{publisher}'已被初始化",pub_outside_jail:"發布者uri:'{uri}'不在數據庫uri:'{sia_base}'中",pub_uri_no_slash:"發布者uri '{uri}'必須以右斜槓結尾",pub_no_embedded_repo:"無已配置的內置數據庫",ca_duplicate:"名為'{ca}'的CA已被初始化",ca_unknown:"未知CA:'{ca}'",ca_repo_same:"該數據庫正在使用中",ca_repo_issue:"从數據庫收到錯誤: {cause}",ca_repo_response_invalid_xml:"返回無效數據庫應答xml",ca_repo_response_wrong_xml:"收到父級CA應答而非數據庫應答",ca_parent_duplicate:"名為'{parent}'的父級CA已存在",ca_parent_xml_duplicate:"該响应已被名為'{parent}'的父級CA使用",ca_parent_unknown:"您没有名為'{parent}'的父級CA",ca_parent_issue:"从父級CA '{parent}'收到錯誤: {cause}",ca_parent_response_invalid_xml:"收到無效的父級CA應答xml",ca_parent_response_wrong_xml:"添加父級CA時收到數據庫應答",ca_child_duplicate:"您已有名為'{child}'的子CA",ca_child_unknown:"您没有名為'{child}'的子CA",ca_child_resources_required:"您必須為名為'{child}'的子CA指定資源",ca_roa_unknown:"無法移除未知ROA '{prefix}-{max_length} => {asn}'",ca_roa_duplicate:"重複的ROA '{prefix}-{max_length} => {asn}'",ca_roa_invalid_max_length:"于ROA '{prefix}-{max_length} => {asn}'中的最大掩碼長度無效",ca_roa_not_entitled:"ROA前綴:'{prefix}'未列于您的任一證書當中",ta_not_allowed:"該功能不提供给測試用信任錨",ta_name_reserved:"該名字被預留",ca_roa_delta_error:"ROA因下列原因被拒絕",api_insufficient_rights:"當前用戶無权限进行該操作。請聯繫您的超管。",api_invalid_credentials:"您提供的密鑰錯誤。",api_login_error:"登錄時出現錯誤:{cause}",api_auth_transient_error:"試圖驗證你的請求時出現(临時)錯誤。請重新尝试。",api_auth_permanent_error:"試圖驗證你的請求時出現錯誤。請聯繫您的超管。",api_auth_session_expired:"您的登錄已過期。請重新登錄⋯⋯",general_error:"出現錯誤。請聯繫您的超管。"},testbed:{welcome:"歡迎來到RPKI實驗環境",disclaimer:{heading:"免責聲明",body:"本實驗環境提供完全獨立的RPKI等級結構,以作為評估用途。它允許您為您的子CA註冊任何IP或ASN資源。本服務的可用性不被擔保。如果您遇到任何問題,請告知我們。"},rpconfighelp:{heading:"實驗環境TAL",body:"如需驗證發布至本實驗環境的數據,請下載該信任錨定位器 (TAL)并將其配置在您的依赖方軟件中。請注意您絕不應在生產環境使用該TAL。因這僅為測試提供。"},regunreg:{heading:"註冊/註銷",body:"

使用此表格將您的RPKI證書註冊机构作為實驗環境的子CA註冊,以便您創建您聲明已獲取的資源的路由來源授權(ROA)。

若您無意託管Rsync及RRDP數據庫,您可用註冊發布者表格設置將您的ROA發布于由實驗環境託管的數據庫中。使用註銷表格以中斷此前建立的關係(亦針對其他實驗環境的用戶生效)。

"},rfcdoclink:"點此以閱讀該XML相關的RFC-8183文檔",childhandle:"子Handle",publisherhandle:"發布者Handle",responseXML:"實驗環境應答XML",addChild:{heading:"註冊CA",requestXML:{label:"子CA申請XML",placeholder:"複製您的 XML到此處"},asnresources:{label:"ASN資源",placeholder:"AS資源:如AS1, AS3-4"},ipv4resources:{label:"IPv4資源",placeholder:"IPv4資源:如192.168.0.0/16"},ipv6resources:{label:"IPv6資源",placeholder:"IPv6資源:如2001:db8::/32"},confirm:"註冊子CA",format:"此為無效的子CA申請XML",required:"請提供子CA申請的XML",confirmation:{title:"警告",message:"您確認在實驗環境註冊該CA嗎?"},success:"子CA:'{child_handle}'已被添加至實驗環境。",registeranother:"註冊另一CA"},removeChild:{heading:"註銷CA",placeholder:"輸入CA名字以移除",confirm:"移除子CA",confirmation:{title:"警告",message:"您確定从實驗環境移除此子CA嗎?"},success:"子CA:'{child_handle}'已被添加到實驗環境。"},addPublisher:{heading:"發布者註冊",requestXML:{label:"發布者申請XML",placeholder:"複製您的 XML到這里"},confirm:"發布者註冊",format:"這不是有效的發布者申請XML",required:"請提供發布者申請XML",confirmation:{title:"警告",message:"確定在實驗環境中註冊該發布者嗎?"},success:"發布者:'{publisher_handle}'已被添加到實驗環境。",registeranother:"註冊另一發布者"},removePublisher:{heading:"註銷發布者",placeholder:"輸入發布者名稱以移除",confirm:"移除發布者",confirmation:{title:"警告",message:"您確認取消該發布者在實驗環境的註冊嗎?"},success:"發布者:'{publisher_handle}'已从實驗環境移除。"},errors:{invalid_xml:"無效的XML: {err}",missing_xml_el:"缺少{el}元素",missing_xml_child_el:"{parent}元素的缺少{el}子元素",missing_xml_attr:"{el}元素上缺少屬性{attr}",empty_xml_el:"{el}元素不得為空",empty_xml_attr:"{el}元素上的{attr}屬性不得為空",non_ascii_xml_el:"{el}元素不得包含非ASCII符號",child_handle_required:"子Handle為必填項",publisher_handle_required:"發布者Handle為必填項",non_base64_certificate_xml_el:"{el}元素必須正確包含由Base64編碼的自簽名X.509 BPKI證書",invalid_registration_data:"您的註冊信息無法被正確解析"}}};export{e as translations}; diff --git a/ui/index.html b/ui/index.html index 301ab715..b7be0bfa 100644 --- a/ui/index.html +++ b/ui/index.html @@ -5,8 +5,8 @@ Krill-RPKI - - + +