diff --git a/composer.lock b/composer.lock index ed1f0a6..83da89c 100644 --- a/composer.lock +++ b/composer.lock @@ -8,21 +8,21 @@ "packages": [ { "name": "amteich/kirby-twig", - "version": "4.1.6", + "version": "4.2.0", "source": { "type": "git", "url": "https://github.com/amteich/kirby-twig.git", - "reference": "d7f5535a24211702a76bde5c7f59aaf23904efab" + "reference": "7cdc1e5d78a19e8e395c1d3516fe90bf512c20fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amteich/kirby-twig/zipball/d7f5535a24211702a76bde5c7f59aaf23904efab", - "reference": "d7f5535a24211702a76bde5c7f59aaf23904efab", + "url": "https://api.github.com/repos/amteich/kirby-twig/zipball/7cdc1e5d78a19e8e395c1d3516fe90bf512c20fb", + "reference": "7cdc1e5d78a19e8e395c1d3516fe90bf512c20fb", "shasum": "" }, "require": { "getkirby/composer-installer": "^1.1", - "twig/twig": "^3.0" + "twig/twig": "^3.4" }, "type": "kirby-plugin", "autoload": { @@ -47,9 +47,9 @@ "description": "Twig templating support for Kirby CMS", "support": { "issues": "https://github.com/amteich/kirby-twig/issues", - "source": "https://github.com/amteich/kirby-twig/tree/4.1.6" + "source": "https://github.com/amteich/kirby-twig/tree/4.2.0" }, - "time": "2022-01-03T09:07:58+00:00" + "time": "2022-12-09T21:39:13+00:00" }, { "name": "claviska/simpleimage", @@ -101,17 +101,98 @@ "time": "2022-07-05T13:18:44+00:00" }, { - "name": "filp/whoops", - "version": "2.14.5", + "name": "composer/semver", + "version": "3.3.2", "source": { "type": "git", - "url": "https://github.com/filp/whoops.git", - "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc" + "url": "https://github.com/composer/semver.git", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", - "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", + "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-04-01T19:23:25+00:00" + }, + { + "name": "filp/whoops", + "version": "2.14.6", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "f7948baaa0330277c729714910336383286305da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/f7948baaa0330277c729714910336383286305da", + "reference": "f7948baaa0330277c729714910336383286305da", "shasum": "" }, "require": { @@ -161,7 +242,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.14.5" + "source": "https://github.com/filp/whoops/tree/2.14.6" }, "funding": [ { @@ -169,24 +250,25 @@ "type": "github" } ], - "time": "2022-01-07T12:00:00+00:00" + "time": "2022-11-02T16:23:29+00:00" }, { "name": "getkirby/cms", - "version": "3.7.5", + "version": "3.8.3", "source": { "type": "git", "url": "https://github.com/getkirby/kirby.git", - "reference": "021561f7444896fc9917eccb52768a6e715e9a74" + "reference": "41719bd54310dfc2e321a75a8549da98ccf5cd1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/getkirby/kirby/zipball/021561f7444896fc9917eccb52768a6e715e9a74", - "reference": "021561f7444896fc9917eccb52768a6e715e9a74", + "url": "https://api.github.com/repos/getkirby/kirby/zipball/41719bd54310dfc2e321a75a8549da98ccf5cd1d", + "reference": "41719bd54310dfc2e321a75a8549da98ccf5cd1d", "shasum": "" }, "require": { "claviska/simpleimage": "3.7.0", + "composer/semver": "3.3.2", "ext-ctype": "*", "ext-curl": "*", "ext-dom": "*", @@ -198,12 +280,12 @@ "ext-mbstring": "*", "ext-openssl": "*", "ext-simplexml": "*", - "filp/whoops": "2.14.5", + "filp/whoops": "2.14.6", "getkirby/composer-installer": "^1.2.1", - "laminas/laminas-escaper": "2.10.0", + "laminas/laminas-escaper": "2.12.0", "michelf/php-smartypants": "1.8.1", - "php": ">=7.4.0 <8.2.0", - "phpmailer/phpmailer": "6.6.4", + "php": ">=8.0.0 <8.2.0", + "phpmailer/phpmailer": "6.6.5", "symfony/polyfill-intl-idn": "1.26.0", "symfony/polyfill-mbstring": "1.26.0" }, @@ -268,7 +350,7 @@ "type": "custom" } ], - "time": "2022-08-30T18:27:48+00:00" + "time": "2022-12-06T14:31:06+00:00" }, { "name": "getkirby/composer-installer", @@ -356,32 +438,32 @@ }, { "name": "laminas/laminas-escaper", - "version": "2.10.0", + "version": "2.12.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-escaper.git", - "reference": "58af67282db37d24e584a837a94ee55b9c7552be" + "reference": "ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/58af67282db37d24e584a837a94ee55b9c7552be", - "reference": "58af67282db37d24e584a837a94ee55b9c7552be", + "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490", + "reference": "ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490", "shasum": "" }, "require": { "ext-ctype": "*", "ext-mbstring": "*", - "php": "^7.4 || ~8.0.0 || ~8.1.0" + "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0" }, "conflict": { "zendframework/zend-escaper": "*" }, "require-dev": { "infection/infection": "^0.26.6", - "laminas/laminas-coding-standard": "~2.3.0", + "laminas/laminas-coding-standard": "~2.4.0", "maglnet/composer-require-checker": "^3.8.0", "phpunit/phpunit": "^9.5.18", - "psalm/plugin-phpunit": "^0.16.1", + "psalm/plugin-phpunit": "^0.17.0", "vimeo/psalm": "^4.22.0" }, "type": "library", @@ -414,7 +496,7 @@ "type": "community_bridge" } ], - "time": "2022-03-08T20:15:36+00:00" + "time": "2022-10-10T10:11:09+00:00" }, { "name": "league/color-extractor", @@ -530,16 +612,16 @@ }, { "name": "mullema/k3-image-clip", - "version": "3.1.0", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/mullema/k3-image-clip.git", - "reference": "c2e01f2ceb9eb5bc56895177359d398a3a2dbcf4" + "reference": "66e5c2147fd6736f48878aaed6eef9ffe08cdd21" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mullema/k3-image-clip/zipball/c2e01f2ceb9eb5bc56895177359d398a3a2dbcf4", - "reference": "c2e01f2ceb9eb5bc56895177359d398a3a2dbcf4", + "url": "https://api.github.com/repos/mullema/k3-image-clip/zipball/66e5c2147fd6736f48878aaed6eef9ffe08cdd21", + "reference": "66e5c2147fd6736f48878aaed6eef9ffe08cdd21", "shasum": "" }, "require": { @@ -566,22 +648,22 @@ "description": "Visual image clip for Kirby 3", "support": { "issues": "https://github.com/mullema/k3-image-clip/issues", - "source": "https://github.com/mullema/k3-image-clip/tree/3.1.0" + "source": "https://github.com/mullema/k3-image-clip/tree/3.2.0" }, - "time": "2022-06-26T08:59:46+00:00" + "time": "2022-11-05T10:49:35+00:00" }, { "name": "phpmailer/phpmailer", - "version": "v6.6.4", + "version": "v6.6.5", "source": { "type": "git", "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b" + "reference": "8b6386d7417526d1ea4da9edb70b8352f7543627" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a94fdebaea6bd17f51be0c2373ab80d3d681269b", - "reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/8b6386d7417526d1ea4da9edb70b8352f7543627", + "reference": "8b6386d7417526d1ea4da9edb70b8352f7543627", "shasum": "" }, "require": { @@ -605,8 +687,8 @@ "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", "league/oauth2-google": "Needed for Google XOAUTH2 authentication", "psr/log": "For optional PSR-3 debug logging", - "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", - "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)", + "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication" }, "type": "library", "autoload": { @@ -638,7 +720,7 @@ "description": "PHPMailer is a full-featured email creation and transfer class for PHP", "support": { "issues": "https://github.com/PHPMailer/PHPMailer/issues", - "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.4" + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.5" }, "funding": [ { @@ -646,7 +728,7 @@ "type": "github" } ], - "time": "2022-08-22T09:22:00+00:00" + "time": "2022-10-07T12:23:10+00:00" }, { "name": "psr/log", @@ -738,16 +820,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", "shasum": "" }, "require": { @@ -762,7 +844,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -800,7 +882,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" }, "funding": [ { @@ -816,7 +898,7 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-intl-idn", @@ -907,16 +989,16 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd" + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", "shasum": "" }, "require": { @@ -928,7 +1010,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -971,7 +1053,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" }, "funding": [ { @@ -987,7 +1069,7 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -1074,16 +1156,16 @@ }, { "name": "twig/twig", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077" + "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077", - "reference": "e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58", + "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58", "shasum": "" }, "require": { @@ -1134,7 +1216,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.4.2" + "source": "https://github.com/twigphp/Twig/tree/v3.4.3" }, "funding": [ { @@ -1146,7 +1228,7 @@ "type": "tidelift" } ], - "time": "2022-08-12T06:47:24+00:00" + "time": "2022-09-28T08:42:51+00:00" } ], "packages-dev": [], diff --git a/kirby/bootstrap.php b/kirby/bootstrap.php index b4c1fa3..472c0ad 100644 --- a/kirby/bootstrap.php +++ b/kirby/bootstrap.php @@ -5,7 +5,7 @@ * stop at older or too recent versions */ if ( - version_compare(PHP_VERSION, '7.4.0', '>=') === false || + version_compare(PHP_VERSION, '8.0.0', '>=') === false || version_compare(PHP_VERSION, '8.2.0', '<') === false ) { die(include __DIR__ . '/views/php.php'); @@ -16,11 +16,15 @@ if (is_file($autoloader = dirname(__DIR__) . '/vendor/autoload.php')) { * Always prefer a site-wide Composer autoloader * if it exists, it means that the user has probably * installed additional packages + * + * @psalm-suppress MissingFile */ include $autoloader; } elseif (is_file($autoloader = __DIR__ . '/vendor/autoload.php')) { /** * Fall back to the local autoloader if that exists + * + * @psalm-suppress MissingFile */ include $autoloader; } else { diff --git a/kirby/cacert.pem b/kirby/cacert.pem index 6b70ee0..0c69f9f 100644 --- a/kirby/cacert.pem +++ b/kirby/cacert.pem @@ -1,7 +1,7 @@ ## ## Bundle of CA Root Certificates ## -## Certificate data from Mozilla as of: Tue Jul 19 03:12:06 2022 GMT +## Certificate data from Mozilla as of: Tue Oct 11 03:12:05 2022 GMT ## ## This is a bundle of X.509 certificates of public Certificate Authorities ## (CA). These were automatically extracted from Mozilla's root certificates @@ -14,7 +14,7 @@ ## Just configure this file as the SSLCACertificateFile. ## ## Conversion done with mk-ca-bundle.pl version 1.29. -## SHA256: 9bf3799611fb58197f61d45e71ce3dc19f30e7dd73731915872ce5108a7bb066 +## SHA256: 3ff8bd209b5f2e739b9f2b96eacb694a774114685b02978257824f37ff528f71 ## @@ -3458,3 +3458,49 @@ zPUwHQYDVR0OBBYEFP+CMXI++cRmbK04ntGwUYilkMz1MA4GA1UdDwEB/wQEAwIBBjAKBggqhkjO PQQDAwNpADBmAjEA5gVYaWHlLcoNy/EZCL3W/VGSGn5jVASQkZo1kTmZ+gepZpO6yGjUij/67W4W Aie3AjEA3VoXK3YdZUKWpqxdinlW2Iob35reX8dQj7FbcQwm32pAAOwzkSFxvmjkI6TZraE3 -----END CERTIFICATE----- + +Security Communication RootCA3 +============================== +-----BEGIN CERTIFICATE----- +MIIFfzCCA2egAwIBAgIJAOF8N0D9G/5nMA0GCSqGSIb3DQEBDAUAMF0xCzAJBgNVBAYTAkpQMSUw +IwYDVQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMScwJQYDVQQDEx5TZWN1cml0eSBD +b21tdW5pY2F0aW9uIFJvb3RDQTMwHhcNMTYwNjE2MDYxNzE2WhcNMzgwMTE4MDYxNzE2WjBdMQsw +CQYDVQQGEwJKUDElMCMGA1UEChMcU0VDT00gVHJ1c3QgU3lzdGVtcyBDTy4sTFRELjEnMCUGA1UE +AxMeU2VjdXJpdHkgQ29tbXVuaWNhdGlvbiBSb290Q0EzMIICIjANBgkqhkiG9w0BAQEFAAOCAg8A +MIICCgKCAgEA48lySfcw3gl8qUCBWNO0Ot26YQ+TUG5pPDXC7ltzkBtnTCHsXzW7OT4rCmDvu20r +hvtxosis5FaU+cmvsXLUIKx00rgVrVH+hXShuRD+BYD5UpOzQD11EKzAlrenfna84xtSGc4RHwsE +NPXY9Wk8d/Nk9A2qhd7gCVAEF5aEt8iKvE1y/By7z/MGTfmfZPd+pmaGNXHIEYBMwXFAWB6+oHP2 +/D5Q4eAvJj1+XCO1eXDe+uDRpdYMQXF79+qMHIjH7Iv10S9VlkZ8WjtYO/u62C21Jdp6Ts9EriGm +npjKIG58u4iFW/vAEGK78vknR+/RiTlDxN/e4UG/VHMgly1s2vPUB6PmudhvrvyMGS7TZ2crldtY +XLVqAvO4g160a75BflcJdURQVc1aEWEhCmHCqYj9E7wtiS/NYeCVvsq1e+F7NGcLH7YMx3weGVPK +p7FKFSBWFHA9K4IsD50VHUeAR/94mQ4xr28+j+2GaR57GIgUssL8gjMunEst+3A7caoreyYn8xrC +3PsXuKHqy6C0rtOUfnrQq8PsOC0RLoi/1D+tEjtCrI8Cbn3M0V9hvqG8OmpI6iZVIhZdXw3/JzOf +GAN0iltSIEdrRU0id4xVJ/CvHozJgyJUt5rQT9nO/NkuHJYosQLTA70lUhw0Zk8jq/R3gpYd0Vcw +CBEF/VfR2ccCAwEAAaNCMEAwHQYDVR0OBBYEFGQUfPxYchamCik0FW8qy7z8r6irMA4GA1UdDwEB +/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBDAUAA4ICAQDcAiMI4u8hOscNtybS +YpOnpSNyByCCYN8Y11StaSWSntkUz5m5UoHPrmyKO1o5yGwBQ8IibQLwYs1OY0PAFNr0Y/Dq9HHu +Tofjcan0yVflLl8cebsjqodEV+m9NU1Bu0soo5iyG9kLFwfl9+qd9XbXv8S2gVj/yP9kaWJ5rW4O +H3/uHWnlt3Jxs/6lATWUVCvAUm2PVcTJ0rjLyjQIUYWg9by0F1jqClx6vWPGOi//lkkZhOpn2ASx +YfQAW0q3nHE3GYV5v4GwxxMOdnE+OoAGrgYWp421wsTL/0ClXI2lyTrtcoHKXJg80jQDdwj98ClZ +XSEIx2C/pHF7uNkegr4Jr2VvKKu/S7XuPghHJ6APbw+LP6yVGPO5DtxnVW5inkYO0QR4ynKudtml ++LLfiAlhi+8kTtFZP1rUPcmTPCtk9YENFpb3ksP+MW/oKjJ0DvRMmEoYDjBU1cXrvMUVnuiZIesn +KwkK2/HmcBhWuwzkvvnoEKQTkrgc4NtnHVMDpCKn3F2SEDzq//wbEBrD2NCcnWXL0CsnMQMeNuE9 +dnUM/0Umud1RvCPHX9jYhxBAEg09ODfnRDwYwFMJZI//1ZqmfHAuc1Uh6N//g7kdPjIe1qZ9LPFm +6Vwdp6POXiUyK+OVrCoHzrQoeIY8LaadTdJ0MN1kURXbg4NR16/9M51NZg== +-----END CERTIFICATE----- + +Security Communication ECC RootCA1 +================================== +-----BEGIN CERTIFICATE----- +MIICODCCAb6gAwIBAgIJANZdm7N4gS7rMAoGCCqGSM49BAMDMGExCzAJBgNVBAYTAkpQMSUwIwYD +VQQKExxTRUNPTSBUcnVzdCBTeXN0ZW1zIENPLixMVEQuMSswKQYDVQQDEyJTZWN1cml0eSBDb21t +dW5pY2F0aW9uIEVDQyBSb290Q0ExMB4XDTE2MDYxNjA1MTUyOFoXDTM4MDExODA1MTUyOFowYTEL +MAkGA1UEBhMCSlAxJTAjBgNVBAoTHFNFQ09NIFRydXN0IFN5c3RlbXMgQ08uLExURC4xKzApBgNV +BAMTIlNlY3VyaXR5IENvbW11bmljYXRpb24gRUNDIFJvb3RDQTEwdjAQBgcqhkjOPQIBBgUrgQQA +IgNiAASkpW9gAwPDvTH00xecK4R1rOX9PVdu12O/5gSJko6BnOPpR27KkBLIE+CnnfdldB9sELLo +5OnvbYUymUSxXv3MdhDYW72ixvnWQuRXdtyQwjWpS4g8EkdtXP9JTxpKULGjQjBAMB0GA1UdDgQW +BBSGHOf+LaVKiwj+KBH6vqNm+GBZLzAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAK +BggqhkjOPQQDAwNoADBlAjAVXUI9/Lbu9zuxNuie9sRGKEkz0FhDKmMpzE2xtHqiuQ04pV1IKv3L +snNdo4gIxwwCMQDAqy0Obe0YottT6SXbVQjgUMzfRGEWgqtJsLKB7HOHeLRMsmIbEvoWTSVLY70e +N9k= +-----END CERTIFICATE----- diff --git a/kirby/composer.json b/kirby/composer.json index 94059bb..c010c7b 100644 --- a/kirby/composer.json +++ b/kirby/composer.json @@ -3,7 +3,7 @@ "description": "The Kirby 3 core", "license": "proprietary", "type": "kirby-cms", - "version": "3.7.5", + "version": "3.8.3", "keywords": [ "kirby", "cms", @@ -24,7 +24,7 @@ "source": "https://github.com/getkirby/kirby" }, "require": { - "php": ">=7.4.0 <8.2.0", + "php": ">=8.0.0 <8.2.0", "ext-SimpleXML": "*", "ext-ctype": "*", "ext-curl": "*", @@ -37,11 +37,12 @@ "ext-mbstring": "*", "ext-openssl": "*", "claviska/simpleimage": "3.7.0", - "filp/whoops": "2.14.5", + "composer/semver": "3.3.2", + "filp/whoops": "2.14.6", "getkirby/composer-installer": "^1.2.1", - "laminas/laminas-escaper": "2.10.0", + "laminas/laminas-escaper": "2.12.0", "michelf/php-smartypants": "1.8.1", - "phpmailer/phpmailer": "6.6.4", + "phpmailer/phpmailer": "6.6.5", "symfony/polyfill-intl-idn": "1.26.0", "symfony/polyfill-mbstring": "1.26.0" }, @@ -76,7 +77,7 @@ }, "optimize-autoloader": true, "platform": { - "php": "7.4.0" + "php": "8.0.0" }, "platform-check": false }, diff --git a/kirby/composer.lock b/kirby/composer.lock index eb7aeaf..0489fb9 100644 --- a/kirby/composer.lock +++ b/kirby/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "fb087946fb5ac5910e25a4d263905d99", + "content-hash": "a2b48616382734757b5cf4a9bd73ccdb", "packages": [ { "name": "claviska/simpleimage", @@ -56,17 +56,98 @@ "time": "2022-07-05T13:18:44+00:00" }, { - "name": "filp/whoops", - "version": "2.14.5", + "name": "composer/semver", + "version": "3.3.2", "source": { "type": "git", - "url": "https://github.com/filp/whoops.git", - "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc" + "url": "https://github.com/composer/semver.git", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", - "reference": "a63e5e8f26ebbebf8ed3c5c691637325512eb0dc", + "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.4", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-04-01T19:23:25+00:00" + }, + { + "name": "filp/whoops", + "version": "2.14.6", + "source": { + "type": "git", + "url": "https://github.com/filp/whoops.git", + "reference": "f7948baaa0330277c729714910336383286305da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/filp/whoops/zipball/f7948baaa0330277c729714910336383286305da", + "reference": "f7948baaa0330277c729714910336383286305da", "shasum": "" }, "require": { @@ -116,7 +197,7 @@ ], "support": { "issues": "https://github.com/filp/whoops/issues", - "source": "https://github.com/filp/whoops/tree/2.14.5" + "source": "https://github.com/filp/whoops/tree/2.14.6" }, "funding": [ { @@ -124,7 +205,7 @@ "type": "github" } ], - "time": "2022-01-07T12:00:00+00:00" + "time": "2022-11-02T16:23:29+00:00" }, { "name": "getkirby/composer-installer", @@ -175,32 +256,32 @@ }, { "name": "laminas/laminas-escaper", - "version": "2.10.0", + "version": "2.12.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-escaper.git", - "reference": "58af67282db37d24e584a837a94ee55b9c7552be" + "reference": "ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/58af67282db37d24e584a837a94ee55b9c7552be", - "reference": "58af67282db37d24e584a837a94ee55b9c7552be", + "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490", + "reference": "ee7a4c37bf3d0e8c03635d5bddb5bb3184ead490", "shasum": "" }, "require": { "ext-ctype": "*", "ext-mbstring": "*", - "php": "^7.4 || ~8.0.0 || ~8.1.0" + "php": "^7.4 || ~8.0.0 || ~8.1.0 || ~8.2.0" }, "conflict": { "zendframework/zend-escaper": "*" }, "require-dev": { "infection/infection": "^0.26.6", - "laminas/laminas-coding-standard": "~2.3.0", + "laminas/laminas-coding-standard": "~2.4.0", "maglnet/composer-require-checker": "^3.8.0", "phpunit/phpunit": "^9.5.18", - "psalm/plugin-phpunit": "^0.16.1", + "psalm/plugin-phpunit": "^0.17.0", "vimeo/psalm": "^4.22.0" }, "type": "library", @@ -233,7 +314,7 @@ "type": "community_bridge" } ], - "time": "2022-03-08T20:15:36+00:00" + "time": "2022-10-10T10:11:09+00:00" }, { "name": "league/color-extractor", @@ -349,16 +430,16 @@ }, { "name": "phpmailer/phpmailer", - "version": "v6.6.4", + "version": "v6.6.5", "source": { "type": "git", "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b" + "reference": "8b6386d7417526d1ea4da9edb70b8352f7543627" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/a94fdebaea6bd17f51be0c2373ab80d3d681269b", - "reference": "a94fdebaea6bd17f51be0c2373ab80d3d681269b", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/8b6386d7417526d1ea4da9edb70b8352f7543627", + "reference": "8b6386d7417526d1ea4da9edb70b8352f7543627", "shasum": "" }, "require": { @@ -382,8 +463,8 @@ "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", "league/oauth2-google": "Needed for Google XOAUTH2 authentication", "psr/log": "For optional PSR-3 debug logging", - "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", - "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)", + "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication" }, "type": "library", "autoload": { @@ -415,7 +496,7 @@ "description": "PHPMailer is a full-featured email creation and transfer class for PHP", "support": { "issues": "https://github.com/PHPMailer/PHPMailer/issues", - "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.4" + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.6.5" }, "funding": [ { @@ -423,34 +504,34 @@ "type": "github" } ], - "time": "2022-08-22T09:22:00+00:00" + "time": "2022-10-07T12:23:10+00:00" }, { "name": "psr/log", - "version": "1.1.4", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "3.x-dev" } }, "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "Psr\\Log\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -471,9 +552,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" + "source": "https://github.com/php-fig/log/tree/3.0.0" }, - "time": "2021-05-03T11:20:27+00:00" + "time": "2021-07-14T16:46:02+00:00" }, { "name": "symfony/polyfill-intl-idn", @@ -564,16 +645,16 @@ }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd" + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", "shasum": "" }, "require": { @@ -585,7 +666,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -628,7 +709,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" }, "funding": [ { @@ -644,7 +725,7 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-mbstring", @@ -737,7 +818,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=7.4.0 <8.2.0", + "php": ">=8.0.0 <8.2.0", "ext-simplexml": "*", "ext-ctype": "*", "ext-curl": "*", @@ -752,7 +833,7 @@ }, "platform-dev": [], "platform-overrides": { - "php": "7.4.0" + "php": "8.0.0" }, "plugin-api-version": "2.3.0" } diff --git a/kirby/config/aliases.php b/kirby/config/aliases.php index ee795a3..527ede1 100644 --- a/kirby/config/aliases.php +++ b/kirby/config/aliases.php @@ -46,7 +46,6 @@ return [ 'cookie' => 'Kirby\Http\Cookie', 'header' => 'Kirby\Http\Header', 'remote' => 'Kirby\Http\Remote', - 'server' => 'Kirby\Http\Server', // image classes 'dimensions' => 'Kirby\Image\Dimensions', diff --git a/kirby/config/api/models/File.php b/kirby/config/api/models/File.php index dac185d..4e9a3a0 100644 --- a/kirby/config/api/models/File.php +++ b/kirby/config/api/models/File.php @@ -57,6 +57,7 @@ return [ }, 'type' => fn (File $file) => $file->type(), 'url' => fn (File $file) => $file->url(), + 'uuid' => fn (File $file) => $file->uuid()?->toString() ], 'type' => 'Kirby\Cms\File', 'views' => [ @@ -79,7 +80,8 @@ return [ 'size', 'template', 'type', - 'url' + 'url', + 'uuid' ], 'compact' => [ 'filename', @@ -87,6 +89,7 @@ return [ 'link', 'type', 'url', + 'uuid' ], 'panel' => [ 'blueprint', @@ -109,7 +112,8 @@ return [ 'prevWithTemplate' => 'compact', 'template', 'type', - 'url' + 'url', + 'uuid' ] ], ]; diff --git a/kirby/config/api/models/Page.php b/kirby/config/api/models/Page.php index 03b6c7d..8941c00 100644 --- a/kirby/config/api/models/Page.php +++ b/kirby/config/api/models/Page.php @@ -1,6 +1,5 @@ fn (Page $page) => $page->hasFiles(), 'id' => fn (Page $page) => $page->id(), 'isSortable' => fn (Page $page) => $page->isSortable(), - /** - * @deprecated 3.6.0 - * @todo Remove in 3.8.0 - * @codeCoverageIgnore - */ - 'next' => function (Page $page) { - Helpers::deprecated('The API field page.next has been deprecated and will be removed in 3.8.0.'); - - return $page - ->nextAll() - ->filter('intendedTemplate', $page->intendedTemplate()) - ->filter('status', $page->status()) - ->filter('isReadable', true) - ->first(); - }, - 'num' => fn (Page $page) => $page->num(), - 'options' => fn (Page $page) => $page->panel()->options(['preview']), - 'panelImage' => fn (Page $page) => $page->panel()->image(), - 'parent' => fn (Page $page) => $page->parent(), - 'parents' => fn (Page $page) => $page->parents()->flip(), - /** - * @deprecated 3.6.0 - * @todo Remove in 3.8.0 - * @codeCoverageIgnore - */ - 'prev' => function (Page $page) { - Helpers::deprecated('The API field page.prev has been deprecated and will be removed in 3.8.0.'); - - return $page - ->prevAll() - ->filter('intendedTemplate', $page->intendedTemplate()) - ->filter('status', $page->status()) - ->filter('isReadable', true) - ->last(); - }, - 'previewUrl' => fn (Page $page) => $page->previewUrl(), - 'siblings' => function (Page $page) { + 'num' => fn (Page $page) => $page->num(), + 'options' => fn (Page $page) => $page->panel()->options(['preview']), + 'panelImage' => fn (Page $page) => $page->panel()->image(), + 'parent' => fn (Page $page) => $page->parent(), + 'parents' => fn (Page $page) => $page->parents()->flip(), + 'previewUrl' => fn (Page $page) => $page->previewUrl(), + 'siblings' => function (Page $page) { if ($page->isDraft() === true) { return $page->parentModel()->children()->not($page); - } else { - return $page->siblings(); } + + return $page->siblings(); }, 'slug' => fn (Page $page) => $page->slug(), 'status' => fn (Page $page) => $page->status(), 'template' => fn (Page $page) => $page->intendedTemplate()->name(), 'title' => fn (Page $page) => $page->title()->value(), 'url' => fn (Page $page) => $page->url(), + 'uuid' => fn (Page $page) => $page->uuid()?->toString() ], 'type' => 'Kirby\Cms\Page', 'views' => [ @@ -76,7 +46,8 @@ return [ 'id', 'title', 'url', - 'num' + 'num', + 'uuid' ], 'default' => [ 'content', @@ -88,7 +59,8 @@ return [ 'slug', 'template', 'title', - 'url' + 'url', + 'uuid' ], 'panel' => [ 'id', @@ -102,7 +74,8 @@ return [ 'previewUrl', 'slug', 'title', - 'url' + 'url', + 'uuid' ], 'selector' => [ 'id', diff --git a/kirby/config/api/models/System.php b/kirby/config/api/models/System.php index 260aa45..c69a23d 100644 --- a/kirby/config/api/models/System.php +++ b/kirby/config/api/models/System.php @@ -32,28 +32,20 @@ return [ 'slugs' => fn () => Str::$language, 'title' => fn () => $this->site()->title()->value(), 'translation' => function () { - if ($user = $this->user()) { - $translationCode = $user->language(); - } else { - $translationCode = $this->kirby()->panelLanguage(); - } + $code = $this->user()?->language() ?? + $this->kirby()->panelLanguage(); - if ($translation = $this->kirby()->translation($translationCode)) { - return $translation; - } else { - return $this->kirby()->translation('en'); - } + return $this->kirby()->translation($code) ?? + $this->kirby()->translation('en'); }, 'kirbytext' => fn () => $this->kirby()->option('panel.kirbytext') ?? true, 'user' => fn () => $this->user(), 'version' => function () { - $user = $this->user(); - - if ($user && $user->role()->permissions()->for('access', 'system') === true) { + if ($this->user()?->role()->permissions()->for('access', 'system') === true) { return $this->kirby()->version(); - } else { - return null; } + + return null; } ], 'type' => 'Kirby\Cms\System', diff --git a/kirby/config/api/models/User.php b/kirby/config/api/models/User.php index 5354e3a..20c03f4 100644 --- a/kirby/config/api/models/User.php +++ b/kirby/config/api/models/User.php @@ -24,7 +24,8 @@ return [ 'prev' => fn (User $user) => $user->prev(), 'role' => fn (User $user) => $user->role(), 'roles' => fn (User $user) => $user->roles(), - 'username' => fn (User $user) => $user->username() + 'username' => fn (User $user) => $user->username(), + 'uuid' => fn (User $user) => $user->uuid()?->toString() ], 'type' => 'Kirby\Cms\User', 'views' => [ @@ -39,7 +40,8 @@ return [ 'options', 'prev' => 'compact', 'role', - 'username' + 'username', + 'uuid' ], 'compact' => [ 'avatar' => 'compact', @@ -48,7 +50,8 @@ return [ 'language', 'name', 'role' => 'compact', - 'username' + 'username', + 'uuid' ], 'auth' => [ 'avatar' => 'compact', @@ -72,6 +75,7 @@ return [ 'prev' => ['id', 'name'], 'role', 'username', + 'uuid' ], ] ]; diff --git a/kirby/config/api/routes/auth.php b/kirby/config/api/routes/auth.php index a4fcbb4..97b81a1 100644 --- a/kirby/config/api/routes/auth.php +++ b/kirby/config/api/routes/auth.php @@ -70,13 +70,11 @@ return [ $user = $auth->login($email, $password, $long); } } else { - if (isset($methods['code']) === true) { - $mode = 'login'; - } elseif (isset($methods['password-reset']) === true) { - $mode = 'password-reset'; - } else { - throw new InvalidArgumentException('Login without password is not enabled'); - } + $mode = match (true) { + isset($methods['code']) => 'login', + isset($methods['password-reset']) => 'password-reset', + default => throw new InvalidArgumentException('Login without password is not enabled') + }; $status = $auth->createChallenge($email, $long, $mode); } @@ -87,13 +85,13 @@ return [ 'status' => 'ok', 'user' => $this->resolve($user)->view('auth')->toArray() ]; - } else { - return [ - 'code' => 200, - 'status' => 'ok', - 'challenge' => $status->challenge() - ]; } + + return [ + 'code' => 200, + 'status' => 'ok', + 'challenge' => $status->challenge() + ]; } ], [ @@ -105,4 +103,14 @@ return [ return true; } ], + [ + 'pattern' => 'auth/ping', + 'method' => 'POST', + 'auth' => false, + 'action' => function () { + // refresh the session timeout + $this->kirby()->session(); + return true; + } + ], ]; diff --git a/kirby/config/api/routes/files.php b/kirby/config/api/routes/files.php index c1b755b..3194b88 100644 --- a/kirby/config/api/routes/files.php +++ b/kirby/config/api/routes/files.php @@ -12,9 +12,7 @@ return [ 'pattern' => $pattern . '/files/(:any)/sections/(:any)', 'method' => 'GET', 'action' => function (string $path, string $filename, string $sectionName) { - if ($section = $this->file($path, $filename)->blueprint()->section($sectionName)) { - return $section->toResponse(); - } + return $this->file($path, $filename)->blueprint()->section($sectionName)?->toResponse(); } ], [ @@ -60,9 +58,9 @@ return [ if ($this->requestMethod() === 'GET') { return $files->search($this->requestQuery('q')); - } else { - return $files->query($this->requestBody()); } + + return $files->query($this->requestBody()); } ], [ @@ -86,16 +84,20 @@ return [ 'pattern' => $pattern . '/files/(:any)', 'method' => 'PATCH', 'action' => function (string $path, string $filename) { - return $this->file($path, $filename)->update($this->requestBody(), $this->language(), true); + return $this->file($path, $filename)->update( + $this->requestBody(), + $this->language(), + true + ); } ], [ 'pattern' => $pattern . '/files/(:any)', 'method' => 'POST', 'action' => function (string $path, string $filename) { - return $this->upload(function ($source) use ($path, $filename) { - return $this->file($path, $filename)->replace($source); - }); + return $this->upload( + fn ($source) => $this->file($path, $filename)->replace($source) + ); } ], [ @@ -124,9 +126,9 @@ return [ if ($this->requestMethod() === 'GET') { return $files->search($this->requestQuery('q')); - } else { - return $files->query($this->requestBody()); } + + return $files->query($this->requestBody()); } ], ]; diff --git a/kirby/config/api/routes/languages.php b/kirby/config/api/routes/languages.php index 4105ef2..e2d4f6b 100644 --- a/kirby/config/api/routes/languages.php +++ b/kirby/config/api/routes/languages.php @@ -29,18 +29,14 @@ return [ 'pattern' => 'languages/(:any)', 'method' => 'PATCH', 'action' => function (string $code) { - if ($language = $this->kirby()->languages()->find($code)) { - return $language->update($this->requestBody()); - } + return $this->kirby()->languages()->find($code)?->update($this->requestBody()); } ], [ 'pattern' => 'languages/(:any)', 'method' => 'DELETE', 'action' => function (string $code) { - if ($language = $this->kirby()->languages()->find($code)) { - return $language->delete(); - } + return $this->kirby()->languages()->find($code)?->delete(); } ] ]; diff --git a/kirby/config/api/routes/lock.php b/kirby/config/api/routes/lock.php index c5b2da4..71ff785 100644 --- a/kirby/config/api/routes/lock.php +++ b/kirby/config/api/routes/lock.php @@ -5,40 +5,41 @@ * Content Lock Routes */ return [ + [ + 'pattern' => '(:all)/lock', + 'method' => 'GET', + 'action' => function (string $path) { + return [ + 'lock' => $this->parent($path)->lock()?->toArray() ?? false + ]; + } + ], [ 'pattern' => '(:all)/lock', 'method' => 'PATCH', 'action' => function (string $path) { - if ($lock = $this->parent($path)->lock()) { - return $lock->create(); - } + return $this->parent($path)->lock()?->create(); } ], [ 'pattern' => '(:all)/lock', 'method' => 'DELETE', 'action' => function (string $path) { - if ($lock = $this->parent($path)->lock()) { - return $lock->remove(); - } + return $this->parent($path)->lock()?->remove(); } ], [ 'pattern' => '(:all)/unlock', 'method' => 'PATCH', 'action' => function (string $path) { - if ($lock = $this->parent($path)->lock()) { - return $lock->unlock(); - } + return $this->parent($path)->lock()?->unlock(); } ], [ 'pattern' => '(:all)/unlock', 'method' => 'DELETE', 'action' => function (string $path) { - if ($lock = $this->parent($path)->lock()) { - return $lock->resolve(); - } + return $this->parent($path)->lock()?->resolve(); } ], ]; diff --git a/kirby/config/api/routes/pages.php b/kirby/config/api/routes/pages.php index 3ff255c..476b1ef 100644 --- a/kirby/config/api/routes/pages.php +++ b/kirby/config/api/routes/pages.php @@ -104,9 +104,7 @@ return [ 'pattern' => 'pages/(:any)/sections/(:any)', 'method' => 'GET', 'action' => function (string $id, string $sectionName) { - if ($section = $this->page($id)->blueprint()->section($sectionName)) { - return $section->toResponse(); - } + return $this->page($id)->blueprint()->section($sectionName)?->toResponse(); } ], [ diff --git a/kirby/config/api/routes/roles.php b/kirby/config/api/routes/roles.php index 7dbe45f..56ecfea 100644 --- a/kirby/config/api/routes/roles.php +++ b/kirby/config/api/routes/roles.php @@ -10,14 +10,11 @@ return [ 'action' => function () { $kirby = $this->kirby(); - switch ($kirby->request()->get('canBe')) { - case 'changed': - return $kirby->roles()->canBeChanged(); - case 'created': - return $kirby->roles()->canBeCreated(); - default: - return $kirby->roles(); - } + return match ($kirby->request()->get('canBe')) { + 'changed' => $kirby->roles()->canBeChanged(), + 'created' => $kirby->roles()->canBeCreated(), + default => $kirby->roles() + }; } ], [ diff --git a/kirby/config/api/routes/site.php b/kirby/config/api/routes/site.php index 3f2601c..afad5bd 100644 --- a/kirby/config/api/routes/site.php +++ b/kirby/config/api/routes/site.php @@ -79,18 +79,16 @@ return [ if ($this->requestMethod() === 'GET') { return $pages->search($this->requestQuery('q')); - } else { - return $pages->query($this->requestBody()); } + + return $pages->query($this->requestBody()); } ], [ 'pattern' => 'site/sections/(:any)', 'method' => 'GET', 'action' => function (string $sectionName) { - if ($section = $this->site()->blueprint()->section($sectionName)) { - return $section->toResponse(); - } + return $this->site()->blueprint()->section($sectionName)?->toResponse(); } ], [ diff --git a/kirby/config/api/routes/system.php b/kirby/config/api/routes/system.php index 0f6ba46..103e826 100644 --- a/kirby/config/api/routes/system.php +++ b/kirby/config/api/routes/system.php @@ -17,19 +17,18 @@ return [ if ($this->kirby()->user()) { return $system; - } else { - if ($system->isOk() === true) { - $info = $this->resolve($system)->view('login')->toArray(); - } else { - $info = $this->resolve($system)->view('troubleshooting')->toArray(); - } - - return [ - 'status' => 'ok', - 'data' => $info, - 'type' => 'model' - ]; } + + $info = match ($system->isOk()) { + true => $this->resolve($system)->view('login')->toArray(), + false => $this->resolve($system)->view('troubleshooting')->toArray() + }; + + return [ + 'status' => 'ok', + 'data' => $info, + 'type' => 'model' + ]; } ], [ diff --git a/kirby/config/api/routes/users.php b/kirby/config/api/routes/users.php index daa245d..c36ad31 100644 --- a/kirby/config/api/routes/users.php +++ b/kirby/config/api/routes/users.php @@ -26,9 +26,9 @@ return [ 'action' => function () { if ($this->requestMethod() === 'GET') { return $this->users()->search($this->requestQuery('q')); - } else { - return $this->users()->query($this->requestBody()); } + + return $this->users()->query($this->requestBody()); } ], [ @@ -79,17 +79,16 @@ return [ ], 'method' => 'POST', 'action' => function (string $id) { - if ($avatar = $this->user($id)->avatar()) { - $avatar->delete(); - } + $this->user($id)->avatar()?->delete(); - return $this->upload(function ($source, $filename) use ($id) { - return $this->user($id)->createFile([ + return $this->upload( + fn ($source, $filename) => $this->user($id)->createFile([ 'filename' => 'profile.' . F::extension($filename), 'template' => 'avatar', 'source' => $source - ]); - }, $single = true); + ]), + single: true + ); } ], // @codeCoverageIgnoreEnd diff --git a/kirby/config/areas/system/views.php b/kirby/config/areas/system/views.php index 8bab2a2..dab7de6 100644 --- a/kirby/config/areas/system/views.php +++ b/kirby/config/areas/system/views.php @@ -1,48 +1,92 @@ [ 'pattern' => 'system', 'action' => function () { - $kirby = App::instance(); - $system = $kirby->system(); - $license = $system->license(); + $kirby = App::instance(); + $system = $kirby->system(); + $updateStatus = $system->updateStatus(); + $license = $system->license(); - // @codeCoverageIgnoreStart - if ($license === true) { - // valid license, but user is not admin - $license = 'Kirby 3'; - } elseif ($license === false) { - // no valid license - $license = null; - } - // @codeCoverageIgnoreEnd + $environment = [ + [ + 'label' => $license ? I18n::translate('license') : I18n::translate('license.register.label'), + 'value' => $license ? 'Kirby 3' : I18n::translate('license.unregistered.label'), + 'theme' => $license ? null : 'negative', + 'dialog' => $license ? 'license' : 'registration' + ], + [ + 'label' => $updateStatus?->label() ?? I18n::translate('version'), + 'value' => $kirby->version(), + 'link' => ( + $updateStatus ? + $updateStatus->url() : + 'https://github.com/getkirby/kirby/releases/tag/' . $kirby->version() + ), + 'theme' => $updateStatus?->theme() + ], + [ + 'label' => 'PHP', + 'value' => phpversion() + ], + [ + 'label' => I18n::translate('server'), + 'value' => $system->serverSoftware() ?? '?' + ] + ]; + + $exceptions = $updateStatus?->exceptionMessages() ?? []; + + $plugins = $system->plugins()->values(function ($plugin) use (&$exceptions) { + $authors = $plugin->authorsNames(); + $updateStatus = $plugin->updateStatus(); + $version = $updateStatus?->toArray() ?? $plugin->version() ?? '–'; + + if ($updateStatus !== null) { + $exceptions = array_merge($exceptions, $updateStatus->exceptionMessages()); + } - $plugins = $system->plugins()->values(function ($plugin) { return [ - 'author' => $plugin->authorsNames(), - 'license' => $plugin->license(), + 'author' => empty($authors) ? '–' : $authors, + 'license' => $plugin->license() ?? '–', 'name' => [ - 'text' => $plugin->name(), + 'text' => $plugin->name() ?? '–', 'href' => $plugin->link(), ], - 'version' => $plugin->version(), + 'version' => $version, ]; }); + $security = $updateStatus?->messages() ?? []; + + if ($kirby->option('debug', false) === true) { + $security[] = [ + 'id' => 'debug', + 'text' => I18n::translate('system.issues.debug'), + 'link' => 'https://getkirby.com/security/debug' + ]; + } + + if ($kirby->environment()->https() !== true) { + $security[] = [ + 'id' => 'https', + 'text' => I18n::translate('system.issues.https'), + 'link' => 'https://getkirby.com/security/https' + ]; + } + return [ 'component' => 'k-system-view', 'props' => [ - 'debug' => $kirby->option('debug', false), - 'license' => $license, - 'plugins' => $plugins, - 'php' => phpversion(), - 'server' => $system->serverSoftware(), - 'https' => $kirby->environment()->https(), - 'version' => $kirby->version(), - 'urls' => [ + 'environment' => $environment, + 'exceptions' => $kirby->option('debug') === true ? $exceptions : [], + 'plugins' => $plugins, + 'security' => $security, + 'urls' => [ 'content' => $system->exposedFileUrl('content'), 'git' => $system->exposedFileUrl('git'), 'kirby' => $system->exposedFileUrl('kirby'), diff --git a/kirby/config/blocks/gallery/gallery.php b/kirby/config/blocks/gallery/gallery.php index 77ab465..033575b 100644 --- a/kirby/config/blocks/gallery/gallery.php +++ b/kirby/config/blocks/gallery/gallery.php @@ -1,5 +1,10 @@ - -
+caption(); +$crop = $block->crop()->isTrue(); +$ratio = $block->ratio()->or('auto'); +?> + $ratio, 'data-crop' => $crop], null, ' ') ?>> + isNotEmpty()): ?> +
+ +
+
diff --git a/kirby/config/blocks/gallery/gallery.yml b/kirby/config/blocks/gallery/gallery.yml index 168dbe9..e57379b 100644 --- a/kirby/config/blocks/gallery/gallery.yml +++ b/kirby/config/blocks/gallery/gallery.yml @@ -14,3 +14,27 @@ fields: template: blocks/image image: ratio: 1/1 + caption: + label: field.blocks.image.caption + type: writer + icon: text + inline: true + ratio: + label: field.blocks.image.ratio + type: select + placeholder: Auto + width: 1/2 + options: + 1/1: "1:1" + 16/9: "16:9" + 10/8: "10:8" + 21/9: "21:9" + 7/5: "7:5" + 4/3: "4:3" + 5/3: "5:3" + 3/2: "3:2" + 3/1: "3:1" + crop: + label: field.blocks.image.crop + type: toggle + width: 1/2 diff --git a/kirby/config/components.php b/kirby/config/components.php index 914cc36..042a426 100644 --- a/kirby/config/components.php +++ b/kirby/config/components.php @@ -4,8 +4,9 @@ use Kirby\Cms\App; use Kirby\Cms\Collection; use Kirby\Cms\File; use Kirby\Cms\FileVersion; -use Kirby\Cms\Helpers; +use Kirby\Cms\Page; use Kirby\Cms\Template; +use Kirby\Cms\User; use Kirby\Data\Data; use Kirby\Email\PHPMailer as Emailer; use Kirby\Filesystem\F; @@ -30,33 +31,6 @@ return [ */ 'css' => fn (App $kirby, string $url, $options = null): string => $url, - - /** - * Object and variable dumper - * to help with debugging. - * - * @param \Kirby\Cms\App $kirby Kirby instance - * @param mixed $variable - * @param bool $echo - * @return string - * - * @deprecated 3.7.0 Disable `dump()` via `KIRBY_HELPER_DUMP` instead and create your own function - * @todo move to `Helpers::dump()`, remove component in 3.8.0 - */ - 'dump' => function (App $kirby, $variable, bool $echo = true) { - if ($kirby->environment()->cli() === true) { - $output = print_r($variable, true) . PHP_EOL; - } else { - $output = '
' . print_r($variable, true) . '
'; - } - - if ($echo === true) { - echo $output; - } - - return $output; - }, - /** * Add your own email provider * @@ -108,7 +82,7 @@ return [ Data::write($job, array_merge($options, [ 'filename' => $file->filename() ])); - } catch (Throwable $e) { + } catch (Throwable) { // if thumb doesn't exist yet and job file cannot // be created, return return $file; @@ -138,24 +112,16 @@ return [ * @param \Kirby\Cms\App $kirby Kirby instance * @param string $text Text to parse * @param array $options Markdown options - * @param bool $inline Whether to wrap the text in `

` tags (deprecated: set via $options['inline'] instead) * @return string - * @todo remove $inline parameter in in 3.8.0 */ - 'markdown' => function (App $kirby, string $text = null, array $options = [], bool $inline = false): string { + 'markdown' => function ( + App $kirby, + string $text = null, + array $options = [] + ): string { static $markdown; static $config; - // warning for deprecated fourth parameter - if (func_num_args() === 4 && isset($options['inline']) === false) { - // @codeCoverageIgnoreStart - Helpers::deprecated('markdown component: the $inline parameter is deprecated and will be removed in Kirby 3.8.0. Use $options[\'inline\'] instead.'); - // @codeCoverageIgnoreEnd - } - - // support for the deprecated fourth argument - $options['inline'] ??= $inline; - // if the config options have changed or the component is called for the first time, // (re-)initialize the parser object if ($config !== $options) { @@ -206,17 +172,22 @@ return [ return $options['words'] ? '\b' . preg_quote($value) . '\b' : preg_quote($value); }, $searchWords); + // returns an empty collection if there is no search word + if (empty($searchWords) === true) { + return $collection->limit(0); + } + $preg = '!(' . implode('|', $searchWords) . ')!i'; $results = $collection->filter(function ($item) use ($query, $preg, $options, $lowerQuery, $exactQuery) { $data = $item->content()->toArray(); $keys = array_keys($data); $keys[] = 'id'; - if (is_a($item, 'Kirby\Cms\User') === true) { + if ($item instanceof User) { $keys[] = 'name'; $keys[] = 'email'; $keys[] = 'role'; - } elseif (is_a($item, 'Kirby\Cms\Page') === true) { + } elseif ($item instanceof Page) { // apply the default score for pages $options['score'] = array_merge([ 'id' => 64, @@ -295,9 +266,8 @@ return [ * @param \Kirby\Cms\App $kirby Kirby instance * @param string|array $name Snippet name * @param array $data Data array for the snippet - * @return string|null */ - 'snippet' => function (App $kirby, $name, array $data = []): ?string { + 'snippet' => function (App $kirby, $name, array $data = []): string { $snippets = A::wrap($name); foreach ($snippets as $name) { diff --git a/kirby/config/fields/date.php b/kirby/config/fields/date.php index ffb6dc4..b05a8b9 100644 --- a/kirby/config/fields/date.php +++ b/kirby/config/fields/date.php @@ -46,13 +46,13 @@ return [ /** * Latest date, which can be selected/saved (Y-m-d) */ - 'max' => function (string $max = null): ?string { + 'max' => function (string $max = null): string|null { return Date::optional($max); }, /** * Earliest date, which can be selected/saved (Y-m-d) */ - 'min' => function (string $min = null): ?string { + 'min' => function (string $min = null): string|null { return Date::optional($min); }, diff --git a/kirby/config/fields/files.php b/kirby/config/fields/files.php index 5fef3e2..5e8fb6f 100644 --- a/kirby/config/fields/files.php +++ b/kirby/config/fields/files.php @@ -34,7 +34,10 @@ return [ ], 'computed' => [ 'parentModel' => function () { - if (is_string($this->parent) === true && $model = $this->model()->query($this->parent, 'Kirby\Cms\Model')) { + if ( + is_string($this->parent) === true && + $model = $this->model()->query($this->parent, 'Kirby\Cms\Model') + ) { return $model; } @@ -68,10 +71,13 @@ return [ foreach (Data::decode($value, 'yaml') as $id) { if (is_array($id) === true) { - $id = $id['id'] ?? null; + $id = $id['uuid'] ?? $id['id'] ?? null; } - if ($id !== null && ($file = $this->kirby()->file($id, $this->model()))) { + if ( + $id !== null && + ($file = $this->kirby()->file($id, $this->model())) + ) { $files[] = $this->fileResponse($file); } } @@ -122,7 +128,7 @@ return [ ]; }, 'save' => function ($value = null) { - return A::pluck($value, 'uuid'); + return A::pluck($value, $this->store); }, 'validations' => [ 'max', diff --git a/kirby/config/fields/mixins/options.php b/kirby/config/fields/mixins/options.php index 465ac50..ce8fa92 100644 --- a/kirby/config/fields/mixins/options.php +++ b/kirby/config/fields/mixins/options.php @@ -1,6 +1,6 @@ [ @@ -30,19 +30,18 @@ return [ ], 'methods' => [ 'getOptions' => function () { - return Options::factory( - $this->options(), - $this->props, - $this->model() - ); + $props = FieldOptions::polyfill($this->props); + $options = FieldOptions::factory($props['options']); + return $options->render($this->model()); }, - 'sanitizeOption' => function ($option) { - $allowed = array_column($this->options(), 'value'); - return in_array($option, $allowed, true) === true ? $option : null; + 'sanitizeOption' => function ($value) { + $options = array_column($this->options(), 'value'); + return in_array($value, $options, true) === true ? $value : null; }, - 'sanitizeOptions' => function ($options) { - $allowed = array_column($this->options(), 'value'); - return array_intersect($options, $allowed); + 'sanitizeOptions' => function ($values) { + $options = array_column($this->options(), 'value'); + $options = array_intersect($values, $options); + return array_values($options); }, ] ]; diff --git a/kirby/config/fields/mixins/picker.php b/kirby/config/fields/mixins/picker.php index 97b4f8a..5d95e45 100644 --- a/kirby/config/fields/mixins/picker.php +++ b/kirby/config/fields/mixins/picker.php @@ -1,6 +1,7 @@ [ @@ -67,12 +68,21 @@ return [ return $search; }, + /** + * Whether to store UUID or ID in the + * content file of the model + * + * @param string $store 'uuid'|'id' + */ + 'store' => function (string $store = 'uuid') { + return Str::lower($store); + }, + /** * Main text for each item */ 'text' => function (string $text = null) { return $text; }, - ], ]; diff --git a/kirby/config/fields/mixins/upload.php b/kirby/config/fields/mixins/upload.php index 166aeb1..10cfc7b 100644 --- a/kirby/config/fields/mixins/upload.php +++ b/kirby/config/fields/mixins/upload.php @@ -51,7 +51,7 @@ return [ $parent = $this->model(); } - if (is_a($parent, 'Kirby\Cms\File') === true) { + if ($parent instanceof File) { $parent = $parent->parent(); } @@ -62,7 +62,7 @@ return [ 'filename' => $filename, ]); - if (is_a($file, 'Kirby\Cms\File') === false) { + if ($file instanceof File === false) { throw new Exception('The file could not be uploaded'); } diff --git a/kirby/config/fields/multiselect.php b/kirby/config/fields/multiselect.php index 37ab356..2c77c00 100644 --- a/kirby/config/fields/multiselect.php +++ b/kirby/config/fields/multiselect.php @@ -1,5 +1,7 @@ 'tags', 'props' => [ @@ -28,5 +30,18 @@ return [ 'sort' => function (bool $sort = false) { return $sort; }, - ] + ], + 'methods' => [ + 'toValues' => function ($value) { + if (is_null($value) === true) { + return []; + } + + if (is_array($value) === false) { + $value = Str::split($value, $this->separator()); + } + + return $this->sanitizeOptions($value); + } + ], ]; diff --git a/kirby/config/fields/object.php b/kirby/config/fields/object.php new file mode 100644 index 0000000..cae125a --- /dev/null +++ b/kirby/config/fields/object.php @@ -0,0 +1,104 @@ + [ + /** + * Unset inherited props + */ + 'after' => null, + 'before' => null, + 'autofocus' => null, + 'icon' => null, + 'placeholder' => null, + + /** + * Set the default values for the object + */ + 'default' => function ($default = null) { + return $default; + }, + + /** + * The placeholder text if no information has been added yet + */ + 'empty' => function ($empty = null) { + return I18n::translate($empty, $empty); + }, + + /** + * Fields setup for the object form. Works just like fields in regular forms. + */ + 'fields' => function (array $fields = []) { + return $fields; + } + ], + 'computed' => [ + 'default' => function () { + if (empty($this->default) === true) { + return ''; + } + + return $this->form($this->default)->values(); + }, + 'fields' => function () { + if (empty($this->fields) === true) { + throw new Exception('Please provide some fields for the object'); + } + + return $this->form()->fields()->toArray(); + }, + 'value' => function () { + $data = Data::decode($this->value, 'yaml'); + + if (empty($data) === true) { + return ''; + } + + return $this->form($data)->values(); + } + ], + 'methods' => [ + 'form' => function (array $values = []) { + return new Form([ + 'fields' => $this->attrs['fields'], + 'values' => $values, + 'model' => $this->model + ]); + }, + ], + 'save' => function ($value) { + if (empty($value) === true) { + return ''; + } + + return $this->form($value)->content(); + }, + 'validations' => [ + 'object' => function ($value) { + if (empty($value) === true) { + return true; + } + + $errors = $this->form($value)->errors(); + + if (empty($errors) === false) { + // use the first error for details + $name = array_key_first($errors); + $error = $errors[$name]; + + throw new InvalidArgumentException([ + 'key' => 'object.validation', + 'data' => [ + 'label' => $error['label'] ?? $name, + 'message' => implode("\n", $error['message']) + ] + ]); + } + } + ] +]; diff --git a/kirby/config/fields/pages.php b/kirby/config/fields/pages.php index 8eaa70d..54d9aa8 100644 --- a/kirby/config/fields/pages.php +++ b/kirby/config/fields/pages.php @@ -67,7 +67,7 @@ return [ foreach (Data::decode($value, 'yaml') as $id) { if (is_array($id) === true) { - $id = $id['id'] ?? null; + $id = $id['uuid'] ?? $id['id'] ?? null; } if ($id !== null && ($page = $kirby->page($id))) { @@ -102,7 +102,7 @@ return [ ]; }, 'save' => function ($value = null) { - return A::pluck($value, 'id'); + return A::pluck($value, $this->store); }, 'validations' => [ 'max', diff --git a/kirby/config/fields/structure.php b/kirby/config/fields/structure.php index ee74703..5f7f77f 100644 --- a/kirby/config/fields/structure.php +++ b/kirby/config/fields/structure.php @@ -108,7 +108,7 @@ return [ $columns = []; $mobile = 0; - if (empty($this->columns)) { + if (empty($this->columns) === true) { foreach ($this->fields as $field) { // Skip hidden and unsaveable fields // They should never be included as column @@ -129,7 +129,10 @@ return [ $field = $this->fields[$columnName] ?? null; - if (empty($field) === true || $field['saveable'] === false) { + if ( + empty($field) === true || + $field['saveable'] === false + ) { continue; } @@ -137,10 +140,10 @@ return [ $mobile++; } - $columns[$columnName] = array_merge($columnProps, [ + $columns[$columnName] = array_merge([ 'type' => $field['type'], 'label' => $field['label'] ?? $field['name'] - ]); + ], $columnProps); } } diff --git a/kirby/config/fields/tags.php b/kirby/config/fields/tags.php index ab8121a..afbe1f0 100644 --- a/kirby/config/fields/tags.php +++ b/kirby/config/fields/tags.php @@ -31,7 +31,7 @@ return [ * Set to `list` to display each tag with 100% width, * otherwise the tags are displayed inline */ - 'layout' => function (?string $layout = null) { + 'layout' => function (string|null $layout = null) { return $layout; }, /** @@ -55,43 +55,32 @@ return [ ], 'computed' => [ 'default' => function (): array { - return $this->toTags($this->default); + return $this->toValues($this->default); }, 'value' => function (): array { - return $this->toTags($this->value); + return $this->toValues($this->value); } ], 'methods' => [ - 'toTags' => function ($value) { + 'toValues' => function ($value) { if (is_null($value) === true) { return []; } - $options = $this->options(); + if (is_array($value) === false) { + $value = Str::split($value, $this->separator()); + } - // transform into value-text objects - return array_map(function ($option) use ($options) { - // already a valid object - if (is_array($option) === true && isset($option['value'], $option['text']) === true) { - return $option; - } + if ($this->accept === 'options') { + $value = $this->sanitizeOptions($value); + } - $index = array_search($option, array_column($options, 'value')); - - if ($index !== false) { - return $options[$index]; - } - - return [ - 'value' => $option, - 'text' => $option, - ]; - }, Str::split($value, $this->separator())); + return $value; } ], 'save' => function (array $value = null): string { return A::join( - A::pluck($value, 'value'), + $value, $this->separator() . ' ' ); }, diff --git a/kirby/config/fields/time.php b/kirby/config/fields/time.php index 69a2da9..4a0b6fc 100644 --- a/kirby/config/fields/time.php +++ b/kirby/config/fields/time.php @@ -15,7 +15,7 @@ return [ /** * Sets the default time when a new page/file/user is created */ - 'default' => function ($default = null): ?string { + 'default' => function ($default = null): string|null { return $default; }, @@ -36,13 +36,13 @@ return [ /** * Latest time, which can be selected/saved (H:i or H:i:s) */ - 'max' => function (string $max = null): ?string { + 'max' => function (string $max = null): string|null { return Date::optional($max); }, /** * Earliest time, which can be selected/saved (H:i or H:i:s) */ - 'min' => function (string $min = null): ?string { + 'min' => function (string $min = null): string|null { return Date::optional($min); }, @@ -62,7 +62,7 @@ return [ 'unit' => 'minute', ]); }, - 'value' => function ($value = null): ?string { + 'value' => function ($value = null): string|null { return $value; } ], @@ -80,7 +80,7 @@ return [ 'format' => function () { return $this->props['format'] ?? 'H:i:s'; }, - 'value' => function (): ?string { + 'value' => function (): string|null { return $this->toDatetime($this->value, 'H:i:s') ?? ''; } ], diff --git a/kirby/config/fields/toggle.php b/kirby/config/fields/toggle.php index 4cb8a6e..a9b7897 100644 --- a/kirby/config/fields/toggle.php +++ b/kirby/config/fields/toggle.php @@ -49,9 +49,9 @@ return [ 'value' => function () { if ($this->props['value'] === null) { return $this->default(); - } else { - return $this->toBool($this->props['value']); } + + return $this->toBool($this->props['value']); } ], 'methods' => [ diff --git a/kirby/config/fields/users.php b/kirby/config/fields/users.php index 8641eee..b962a36 100644 --- a/kirby/config/fields/users.php +++ b/kirby/config/fields/users.php @@ -96,7 +96,7 @@ return [ ]; }, 'save' => function ($value = null) { - return A::pluck($value, 'id'); + return A::pluck($value, $this->store); }, 'validations' => [ 'max', diff --git a/kirby/config/helpers.php b/kirby/config/helpers.php index f8d0476..3bb94af 100644 --- a/kirby/config/helpers.php +++ b/kirby/config/helpers.php @@ -3,10 +3,10 @@ use Kirby\Cms\App; use Kirby\Cms\Helpers; use Kirby\Cms\Html; +use Kirby\Cms\Response; use Kirby\Cms\Url; use Kirby\Filesystem\Asset; use Kirby\Filesystem\F; -use Kirby\Http\Response; use Kirby\Http\Router; use Kirby\Toolkit\Date; use Kirby\Toolkit\I18n; @@ -35,7 +35,7 @@ if (Helpers::hasOverride('attr') === false) { // @codeCoverageIgnore * @param string|null $after An optional string that will be appended if the result is not empty * @return string|null */ - function attr(?array $attr = null, ?string $before = null, ?string $after = null): ?string + function attr(array|null $attr = null, string|null $before = null, string|null $after = null): string|null { return Html::attr($attr, null, $before, $after); } @@ -61,7 +61,7 @@ if (Helpers::hasOverride('csrf') === false) { // @codeCoverageIgnore * @param string|null $check Pass a token here to compare it to the one in the session * @return string|bool Either the token or a boolean check result */ - function csrf(?string $check = null) + function csrf(string|null $check = null) { // check explicitly if there have been no arguments at all; // checking for null introduces a security issue because null could come @@ -82,7 +82,7 @@ if (Helpers::hasOverride('css') === false) { // @codeCoverageIgnore * @param string|array $options Pass an array of attributes for the link tag or a media attribute string * @return string|null */ - function css($url, $options = null): ?string + function css($url, $options = null): string|null { return Html::css($url, $options); } @@ -167,7 +167,7 @@ if (Helpers::hasOverride('gist') === false) { // @codeCoverageIgnore * @param string|null $file * @return string */ - function gist(string $url, ?string $file = null): string + function gist(string $url, string|null $file = null): string { return App::instance()->kirbytag([ 'gist' => $url, @@ -199,7 +199,7 @@ if (Helpers::hasOverride('h') === false) { // @codeCoverageIgnore * @param bool $keepTags * @return string */ - function h(?string $string, bool $keepTags = false): string + function h(string|null $string, bool $keepTags = false): string { return Html::encode($string, $keepTags); } @@ -213,7 +213,7 @@ if (Helpers::hasOverride('html') === false) { // @codeCoverageIgnore * @param bool $keepTags * @return string */ - function html(?string $string, bool $keepTags = false): string + function html(string|null $string, bool $keepTags = false): string { return Html::encode($string, $keepTags); } @@ -230,7 +230,7 @@ if (Helpers::hasOverride('image') === false) { // @codeCoverageIgnore * @param string|null $path * @return \Kirby\Cms\File|null */ - function image(?string $path = null) + function image(string|null $path = null) { return App::instance()->image($path); } @@ -259,7 +259,7 @@ if (Helpers::hasOverride('js') === false) { // @codeCoverageIgnore * @param string|array $options * @return string|null */ - function js($url, $options = null): ?string + function js($url, $options = null): string|null { return Html::js($url, $options); } @@ -287,7 +287,7 @@ if (Helpers::hasOverride('kirbytag') === false) { // @codeCoverageIgnore * @param array $data * @return string */ - function kirbytag($type, ?string $value = null, array $attr = [], array $data = []): string + function kirbytag($type, string|null $value = null, array $attr = [], array $data = []): string { return App::instance()->kirbytag($type, $value, $attr, $data); } @@ -302,7 +302,7 @@ if (Helpers::hasOverride('kirbytags') === false) { // @codeCoverageIgnore * @param array $data * @return string */ - function kirbytags(?string $text = null, array $data = []): string + function kirbytags(string|null $text = null, array $data = []): string { return App::instance()->kirbytags($text, $data); } @@ -317,7 +317,7 @@ if (Helpers::hasOverride('kirbytext') === false) { // @codeCoverageIgnore * @param array $data * @return string */ - function kirbytext(?string $text = null, array $data = []): string + function kirbytext(string|null $text = null, array $data = []): string { return App::instance()->kirbytext($text, $data); } @@ -333,7 +333,7 @@ if (Helpers::hasOverride('kirbytextinline') === false) { // @codeCoverageIgnore * @param array $options * @return string */ - function kirbytextinline(?string $text = null, array $options = []): string + function kirbytextinline(string|null $text = null, array $options = []): string { $options['markdown']['inline'] = true; return App::instance()->kirbytext($text, $options); @@ -348,7 +348,7 @@ if (Helpers::hasOverride('kt') === false) { // @codeCoverageIgnore * @param array $data * @return string */ - function kt(?string $text = null, array $data = []): string + function kt(string|null $text = null, array $data = []): string { return App::instance()->kirbytext($text, $data); } @@ -363,7 +363,7 @@ if (Helpers::hasOverride('kti') === false) { // @codeCoverageIgnore * @param array $options * @return string */ - function kti(?string $text = null, array $options = []): string + function kti(string|null $text = null, array $options = []): string { $options['markdown']['inline'] = true; return App::instance()->kirbytext($text, $options); @@ -378,7 +378,7 @@ if (Helpers::hasOverride('load') === false) { // @codeCoverageIgnore * @param string|null $base * @return void */ - function load(array $classmap, ?string $base = null): void + function load(array $classmap, string|null $base = null): void { F::loadClasses($classmap, $base); } @@ -393,7 +393,7 @@ if (Helpers::hasOverride('markdown') === false) { // @codeCoverageIgnore * @param array $options * @return string */ - function markdown(?string $text = null, array $options = []): string + function markdown(string|null $text = null, array $options = []): string { return App::instance()->markdown($text, $options); } @@ -421,7 +421,7 @@ if (Helpers::hasOverride('page') === false) { // @codeCoverageIgnore * @param string|null $id * @return \Kirby\Cms\Page|null */ - function page(?string $id = null) + function page(string|null $id = null) { if (empty($id) === true) { return App::instance()->site()->page(); @@ -459,8 +459,9 @@ if (Helpers::hasOverride('param') === false) { // @codeCoverageIgnore * @param string $key * @param string|null $fallback * @return string|null + * @psalm-return ($fallback is string ? string : string|null) */ - function param(string $key, ?string $fallback = null): ?string + function param(string $key, string|null $fallback = null): string|null { return App::instance()->request()->url()->params()->$key ?? $fallback; } @@ -505,7 +506,7 @@ if (Helpers::hasOverride('router') === false) { // @codeCoverageIgnore * @param \Closure|null $callback * @return mixed */ - function router(?string $path = null, string $method = 'GET', array $routes = [], ?Closure $callback = null) + function router(string|null $path = null, string $method = 'GET', array $routes = [], Closure|null $callback = null) { return Router::execute($path, $method, $routes, $callback); } @@ -545,7 +546,7 @@ if (Helpers::hasOverride('smartypants') === false) { // @codeCoverageIgnore * @param string|null $text * @return string */ - function smartypants(?string $text = null): string + function smartypants(string|null $text = null): string { return App::instance()->smartypants($text); } @@ -560,7 +561,7 @@ if (Helpers::hasOverride('snippet') === false) { // @codeCoverageIgnore * @param bool $return * @return string|null */ - function snippet($name, $data = [], bool $return = false): ?string + function snippet($name, $data = [], bool $return = false): string|null { return App::instance()->snippet($name, $data, $return); } @@ -624,7 +625,7 @@ if (Helpers::hasOverride('timestamp') === false) { // @codeCoverageIgnore * @param int|array|null $step array of `unit` and `size` to round to nearest * @return int|null */ - function timestamp(?string $date = null, $step = null): ?int + function timestamp(string|null $date = null, $step = null): int|null { return Date::roundedTimestamp($date, $step); } @@ -641,7 +642,7 @@ if (Helpers::hasOverride('tt') === false) { // @codeCoverageIgnore * @param string|null $locale * @return string */ - function tt(string $key, $fallback = null, ?array $replace = null, ?string $locale = null): string + function tt(string $key, $fallback = null, array|null $replace = null, string|null $locale = null): string { return I18n::template($key, $fallback, $replace, $locale); } @@ -657,7 +658,7 @@ if (Helpers::hasOverride('twitter') === false) { // @codeCoverageIgnore * @param string|null $class * @return string */ - function twitter(string $username, ?string $text = null, ?string $title = null, ?string $class = null): string + function twitter(string $username, string|null $text = null, string|null $title = null, string|null $class = null): string { return App::instance()->kirbytag([ 'twitter' => $username, @@ -676,7 +677,7 @@ if (Helpers::hasOverride('u') === false) { // @codeCoverageIgnore * @param array|string|null $options * @return string */ - function u(?string $path = null, $options = null): string + function u(string|null $path = null, $options = null): string { return Url::to($path, $options); } @@ -690,7 +691,7 @@ if (Helpers::hasOverride('url') === false) { // @codeCoverageIgnore * @param array|string|null $options * @return string */ - function url(?string $path = null, $options = null): string + function url(string|null $path = null, $options = null): string { return Url::to($path, $options); } @@ -719,7 +720,7 @@ if (Helpers::hasOverride('video') === false) { // @codeCoverageIgnore * @param array $attr * @return string|null */ - function video(string $url, array $options = [], array $attr = []): ?string + function video(string $url, array $options = [], array $attr = []): string|null { return Html::video($url, $options, $attr); } @@ -734,7 +735,7 @@ if (Helpers::hasOverride('vimeo') === false) { // @codeCoverageIgnore * @param array $attr * @return string|null */ - function vimeo(string $url, array $options = [], array $attr = []): ?string + function vimeo(string $url, array $options = [], array $attr = []): string|null { return Html::vimeo($url, $options, $attr); } @@ -764,7 +765,7 @@ if (Helpers::hasOverride('youtube') === false) { // @codeCoverageIgnore * @param array $attr * @return string|null */ - function youtube(string $url, array $options = [], array $attr = []): ?string + function youtube(string $url, array $options = [], array $attr = []): string|null { return Html::youtube($url, $options, $attr); } diff --git a/kirby/config/methods.php b/kirby/config/methods.php index 00209c0..ab63592 100644 --- a/kirby/config/methods.php +++ b/kirby/config/methods.php @@ -2,6 +2,7 @@ use Kirby\Cms\App; use Kirby\Cms\Blocks; +use Kirby\Cms\Content; use Kirby\Cms\Field; use Kirby\Cms\Files; use Kirby\Cms\Html; @@ -63,16 +64,16 @@ return function (App $app) { */ 'toBlocks' => function (Field $field) { try { - $blocks = Blocks::factory(Blocks::parse($field->value()), [ - 'parent' => $field->parent(), + $blocks = Blocks::parse($field->value()); + $blocks = Blocks::factory($blocks, [ + 'parent' => $field->parent() ]); - return $blocks->filter('isHidden', false); - } catch (Throwable $e) { - if ($field->parent() === null) { - $message = 'Invalid blocks data for "' . $field->key() . '" field'; - } else { - $message = 'Invalid blocks data for "' . $field->key() . '" field on parent "' . $field->parent()->title() . '"'; + } catch (Throwable) { + $message = 'Invalid blocks data for "' . $field->key() . '" field'; + + if ($parent = $field->parent()) { + $message .= ' on parent "' . $parent->title() . '"'; } throw new InvalidArgumentException($message); @@ -99,13 +100,10 @@ return function (App $app) { * @return array */ 'toData' => function (Field $field, string $method = ',') { - switch ($method) { - case 'yaml': - case 'json': - return Data::decode($field->value, $method); - default: - return $field->split($method); - } + return match ($method) { + 'yaml', 'json' => Data::decode($field->value, $method), + default => $field->split($method) + }; }, /** @@ -222,6 +220,17 @@ return function (App $app) { return Html::a($href, $field->value, $attr ?? []); }, + /** + * Parse yaml data and convert it to a + * content object + * + * @param \Kirby\Cms\Field $field + * @return \Kirby\Cms\Content + */ + 'toObject' => function (Field $field) { + return new Content($field->yaml(), $field->parent(), true); + }, + /** * Returns a page object from a page id in the field * @@ -252,11 +261,11 @@ return function (App $app) { 'toStructure' => function (Field $field) { try { return new Structure(Data::decode($field->value, 'yaml'), $field->parent()); - } catch (Exception $e) { - if ($field->parent() === null) { - $message = 'Invalid structure data for "' . $field->key() . '" field'; - } else { - $message = 'Invalid structure data for "' . $field->key() . '" field on parent "' . $field->parent()->title() . '"'; + } catch (Exception) { + $message = 'Invalid structure data for "' . $field->key() . '" field'; + + if ($parent = $field->parent()) { + $message .= ' on parent "' . $parent->title() . '"'; } throw new InvalidArgumentException($message); @@ -341,7 +350,7 @@ return function (App $app) { * @param string $context Location of output (`html`, `attr`, `js`, `css`, `url` or `xml`) */ 'escape' => function (Field $field, string $context = 'html') { - $field->value = Str::esc($field->value, $context); + $field->value = Str::esc($field->value ?? '', $context); return $field; }, @@ -500,10 +509,11 @@ return function (App $app) { * * @param \Kirby\Cms\Field $field * @param array $data - * @param string $fallback Fallback for tokens in the template that cannot be replaced + * @param string|null $fallback Fallback for tokens in the template that cannot be replaced + * (`null` to keep the original token) * @return \Kirby\Cms\Field */ - 'replace' => function (Field $field, array $data = [], string $fallback = '') use ($app) { + 'replace' => function (Field $field, array $data = [], string|null $fallback = '') use ($app) { if ($parent = $field->parent()) { // never pass `null` as the $template to avoid the fallback to the model ID $field->value = $parent->toString($field->value ?? '', $data, $fallback); diff --git a/kirby/config/presets/files.php b/kirby/config/presets/files.php index c5cea1d..aefc535 100644 --- a/kirby/config/presets/files.php +++ b/kirby/config/presets/files.php @@ -5,7 +5,7 @@ use Kirby\Toolkit\I18n; return function (array $props) { $props['sections'] = [ 'files' => [ - 'headline' => $props['headline'] ?? I18n::translate('files'), + 'label' => $props['label'] ?? $props['headline'] ?? I18n::translate('files'), 'type' => 'files', 'layout' => $props['layout'] ?? 'cards', 'template' => $props['template'] ?? null, @@ -17,6 +17,7 @@ return function (array $props) { // remove global options unset( $props['headline'], + $props['label'], $props['layout'], $props['template'], $props['image'] diff --git a/kirby/config/presets/page.php b/kirby/config/presets/page.php index fa0e6e6..e01bcf1 100644 --- a/kirby/config/presets/page.php +++ b/kirby/config/presets/page.php @@ -10,7 +10,7 @@ return function ($props) { if (is_string($props) === true) { $props = [ - 'headline' => $props + 'label' => $props ]; } @@ -27,18 +27,18 @@ return function ($props) { if ($pages !== false) { $sidebar['pages'] = $section([ - 'headline' => I18n::translate('pages'), - 'type' => 'pages', - 'status' => 'all', - 'layout' => 'list', + 'label' => I18n::translate('pages'), + 'type' => 'pages', + 'status' => 'all', + 'layout' => 'list', ], $pages); } if ($files !== false) { $sidebar['files'] = $section([ - 'headline' => I18n::translate('files'), - 'type' => 'files', - 'layout' => 'list' + 'label' => I18n::translate('files'), + 'type' => 'files', + 'layout' => 'list' ], $files); } } diff --git a/kirby/config/presets/pages.php b/kirby/config/presets/pages.php index 8a3e51f..32a4589 100644 --- a/kirby/config/presets/pages.php +++ b/kirby/config/presets/pages.php @@ -6,12 +6,12 @@ return function (array $props) { // load the general templates setting for all sections $templates = $props['templates'] ?? null; - $section = function ($headline, $status, $props) use ($templates) { + $section = function ($label, $status, $props) use ($templates) { $defaults = [ - 'headline' => $headline, - 'type' => 'pages', - 'layout' => 'list', - 'status' => $status + 'label' => $label, + 'type' => 'pages', + 'layout' => 'list', + 'status' => $status ]; if ($props === true) { @@ -20,7 +20,7 @@ return function (array $props) { if (is_string($props) === true) { $props = [ - 'headline' => $props + 'label' => $props ]; } diff --git a/kirby/config/routes.php b/kirby/config/routes.php index 3168dd3..0a53526 100644 --- a/kirby/config/routes.php +++ b/kirby/config/routes.php @@ -6,6 +6,7 @@ use Kirby\Cms\PluginAssets; use Kirby\Panel\Panel; use Kirby\Panel\Plugins; use Kirby\Toolkit\Str; +use Kirby\Uuid\Uuid; return function ($kirby) { $api = $kirby->option('api.slug', 'api'); @@ -101,6 +102,26 @@ return function ($kirby) { return Panel::router($path); } ], + // permalinks for page/file UUIDs + [ + 'pattern' => '@/(page|file)/(:all)', + 'method' => 'ALL', + 'env' => 'site', + 'action' => function (string $type, string $id) use ($kirby) { + // try to resolve to model, but only from UUID cache; + // this ensures that only existing UUIDs can be queried + // and attackers can't force Kirby to go through the whole + // site index with a non-existing UUID + if ($model = Uuid::for($type . '://' . $id)?->model(true)) { + return $kirby + ->response() + ->redirect($model->url()); + } + + // render the error page + return false; + } + ], ]; // Multi-language setup diff --git a/kirby/config/sections/fields.php b/kirby/config/sections/fields.php index 38565e5..7eb79ba 100644 --- a/kirby/config/sections/fields.php +++ b/kirby/config/sections/fields.php @@ -1,5 +1,7 @@ function () { $fields = $this->form->fields()->toArray(); - if (is_a($this->model, 'Kirby\Cms\Page') === true || is_a($this->model, 'Kirby\Cms\Site') === true) { + if ( + $this->model instanceof Page || + $this->model instanceof Site + ) { // the title should never be updated directly via // fields section to avoid conflicts with the rename dialog unset($fields['title']); diff --git a/kirby/config/sections/info.php b/kirby/config/sections/info.php index e348bd4..bc390c7 100644 --- a/kirby/config/sections/info.php +++ b/kirby/config/sections/info.php @@ -25,9 +25,9 @@ return [ ], 'toArray' => function () { return [ - 'headline' => $this->headline, - 'text' => $this->text, - 'theme' => $this->theme + 'label' => $this->headline, + 'text' => $this->text, + 'theme' => $this->theme ]; } ]; diff --git a/kirby/config/sections/mixins/headline.php b/kirby/config/sections/mixins/headline.php index df323c6..ebc2bb7 100644 --- a/kirby/config/sections/mixins/headline.php +++ b/kirby/config/sections/mixins/headline.php @@ -1,20 +1,14 @@ [ /** * The headline for the section. This can be a simple string or a template with additional info from the parent page. - * @todo remove in 3.9.0 + * @deprecated 3.8.0 Use `label` instead */ 'headline' => function ($headline = null) { - // TODO: add deprecation notive in 3.8.0 - // if ($headline !== null) { - // Helpers::deprecated('`headline` prop for sections has been deprecated and will be removed in Kirby 3.9.0. Use `label` instead.'); - // } - return I18n::translate($headline, $headline); }, /** @@ -28,14 +22,14 @@ return [ ], 'computed' => [ 'headline' => function () { - if ($this->headline) { - return $this->model()->toString($this->headline); - } - if ($this->label) { return $this->model()->toString($this->label); } + if ($this->headline) { + return $this->model()->toString($this->headline); + } + return ucfirst($this->name); } ] diff --git a/kirby/config/sections/mixins/parent.php b/kirby/config/sections/mixins/parent.php index 2df8425..1096930 100644 --- a/kirby/config/sections/mixins/parent.php +++ b/kirby/config/sections/mixins/parent.php @@ -1,5 +1,9 @@ name() . '" has to be a page, site or user object'); } diff --git a/kirby/config/sections/mixins/search.php b/kirby/config/sections/mixins/search.php index a50a375..0791152 100644 --- a/kirby/config/sections/mixins/search.php +++ b/kirby/config/sections/mixins/search.php @@ -12,7 +12,7 @@ return [ } ], 'methods' => [ - 'searchterm' => function (): ?string { + 'searchterm' => function (): string|null { return App::instance()->request()->get('searchterm'); } ] diff --git a/kirby/config/sections/pages.php b/kirby/config/sections/pages.php index 35f666e..5f5a367 100644 --- a/kirby/config/sections/pages.php +++ b/kirby/config/sections/pages.php @@ -1,6 +1,8 @@ parentModel(); if ( - is_a($parent, 'Kirby\Cms\Site') === false && - is_a($parent, 'Kirby\Cms\Page') === false + $parent instanceof Site === false && + $parent instanceof Page === false ) { throw new InvalidArgumentException('The parent is invalid. You must choose the site or a page as parent.'); } @@ -62,22 +64,13 @@ return [ return $parent; }, 'pages' => function () { - switch ($this->status) { - case 'draft': - $pages = $this->parent->drafts(); - break; - case 'listed': - $pages = $this->parent->children()->listed(); - break; - case 'published': - $pages = $this->parent->children(); - break; - case 'unlisted': - $pages = $this->parent->children()->unlisted(); - break; - default: - $pages = $this->parent->childrenAndDrafts(); - } + $pages = match ($this->status) { + 'draft' => $this->parent->drafts(), + 'listed' => $this->parent->children()->listed(), + 'published' => $this->parent->children(), + 'unlisted' => $this->parent->children()->unlisted(), + default => $this->parent->childrenAndDrafts() + }; // filters pages that are protected and not in the templates list // internal `filter()` method used instead of foreach loop that previously included `unset()` @@ -228,7 +221,7 @@ return [ 'name' => basename($props['name']), 'title' => $props['title'], ]; - } catch (Throwable $e) { + } catch (Throwable) { $blueprints[] = [ 'name' => basename($template), 'title' => ucfirst($template), diff --git a/kirby/config/sections/stats.php b/kirby/config/sections/stats.php index e04755b..e73e7dc 100644 --- a/kirby/config/sections/stats.php +++ b/kirby/config/sections/stats.php @@ -47,10 +47,12 @@ return [ continue; } + $info = $report['info'] ?? null; + $reports[] = [ 'label' => I18n::translate($report['label'], $report['label']), 'value' => $value($report['value'] ?? null), - 'info' => $value($report['info'] ?? null), + 'info' => $value(I18n::translate($info, $info)), 'link' => $value($report['link'] ?? null), 'theme' => $value($report['theme'] ?? null) ]; diff --git a/kirby/config/setup.php b/kirby/config/setup.php index 853b54b..bbe61c1 100644 --- a/kirby/config/setup.php +++ b/kirby/config/setup.php @@ -2,6 +2,7 @@ /** * Constants + * @deprecated 3.8.0 Use `/` instead */ define('DS', '/'); diff --git a/kirby/config/tags.php b/kirby/config/tags.php index 52232f8..8191e1b 100644 --- a/kirby/config/tags.php +++ b/kirby/config/tags.php @@ -3,6 +3,7 @@ use Kirby\Cms\Html; use Kirby\Cms\Url; use Kirby\Toolkit\Str; +use Kirby\Uuid\Uuid; /** * Default KirbyTags definition @@ -117,11 +118,8 @@ return [ return $img; } - if ($link = $tag->file($tag->link)) { - $link = $link->url(); - } else { - $link = $tag->link === 'self' ? $tag->src : $tag->link; - } + $link = $tag->file($tag->link)?->url(); + $link ??= $tag->link === 'self' ? $tag->src : $tag->link; return Html::a($link, [$img], [ 'rel' => $tag->rel, @@ -173,6 +171,15 @@ return [ $tag->value = Url::to($tag->value, $tag->lang); } + // if value is a UUID, resolve to page/file model + // and use the URL as value + if ( + Uuid::is($tag->value, 'page') === true || + Uuid::is($tag->value, 'file') === true + ) { + $tag->value = Uuid::for($tag->value)->model()->url(); + } + return Html::a($tag->value, $tag->text, [ 'rel' => $tag->rel, 'class' => $tag->class, diff --git a/kirby/dependencies/parsedown-extra/ParsedownExtra.php b/kirby/dependencies/parsedown-extra/ParsedownExtra.php index 7c47422..6328eac 100644 --- a/kirby/dependencies/parsedown-extra/ParsedownExtra.php +++ b/kirby/dependencies/parsedown-extra/ParsedownExtra.php @@ -465,7 +465,7 @@ class ParsedownExtra extends Parsedown ), ); - uasort($this->DefinitionData['Footnote'], 'self::sortFootnotes'); + uasort($this->DefinitionData['Footnote'], [$this,'sortFootnotes']); foreach ($this->DefinitionData['Footnote'] as $definitionId => $DefinitionData) { if (! isset($DefinitionData['number'])) { diff --git a/kirby/i18n/translations/bg.json b/kirby/i18n/translations/bg.json index 64e1823..5fcd118 100644 --- a/kirby/i18n/translations/bg.json +++ b/kirby/i18n/translations/bg.json @@ -1,573 +1,596 @@ { - "account.changeName": "Change your name", - "account.delete": "Delete your account", - "account.delete.confirm": "Do you really want to delete your account? You will be logged out immediately. Your account cannot be recovered.", - - "add": "\u0414\u043e\u0431\u0430\u0432\u0438", - "author": "Author", - "avatar": "Профилна снимка", - "back": "Назад", - "cancel": "\u041e\u0442\u043a\u0430\u0436\u0438", - "change": "\u041f\u0440\u043e\u043c\u0435\u043d\u0438", - "close": "\u0417\u0430\u0442\u0432\u043e\u0440\u0438", - "confirm": "Ок", - "collapse": "Collapse", - "collapse.all": "Collapse All", - "copy": "Копирай", - "copy.all": "Copy all", - "create": "Създай", - - "date": "Дата", - "date.select": "Select a date", - - "day": "Day", - "days.fri": "\u041f\u0442", - "days.mon": "\u041f\u043d", - "days.sat": "\u0421\u0431", - "days.sun": "\u041d\u0434", - "days.thu": "\u0427\u0442", - "days.tue": "\u0412\u0442", - "days.wed": "\u0421\u0440", - - "debugging": "Debugging", - - "delete": "\u0418\u0437\u0442\u0440\u0438\u0439", - "delete.all": "Delete all", - - "dialog.files.empty": "No files to select", - "dialog.pages.empty": "No pages to select", - "dialog.users.empty": "No users to select", - - "dimensions": "Размери", - "disabled": "Disabled", - "discard": "\u041e\u0442\u043c\u0435\u043d\u0438", - "download": "Download", - "duplicate": "Duplicate", - - "edit": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0430\u0439", - - "email": "Email", - "email.placeholder": "mail@example.com", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Environment", - - "error.access.code": "Invalid code", - "error.access.login": "Invalid login", - "error.access.panel": "Нямате права за достъп до панела", - "error.access.view": "You are not allowed to access this part of the panel", - - "error.avatar.create.fail": "Профилната снимка не може да се качи", - "error.avatar.delete.fail": "Профилната снимка не може да бъде изтрита", - "error.avatar.dimensions.invalid": "Моля запазете ширината и височината на профилната снимка под 3000 пиксела", - "error.avatar.mime.forbidden": "Профилната снимка трябва да бъде в JPEG или PNG формат", - - "error.blueprint.notFound": "Образецът \"{name}\" не може да бъде зареден", - - "error.blocks.max.plural": "You must not add more than {max} blocks", - "error.blocks.max.singular": "You must not add more than one block", - "error.blocks.min.plural": "You must add at least {min} blocks", - "error.blocks.min.singular": "You must add at least one block", - "error.blocks.validation": "There's an error in block {index}", - - "error.email.preset.notFound": "Email шаблонът \"{name}\" не може да бъде открит", - - "error.field.converter.invalid": "Невалиден конвертор \"{converter}\"", - - "error.file.changeName.empty": "The name must not be empty", - "error.file.changeName.permission": "Не можете да смените името на \"{filename}\"", - "error.file.duplicate": "Файл с име \"{filename}\" вече съществува", - "error.file.extension.forbidden": "Файловото разширение \"{extension}\" не е позволено", - "error.file.extension.invalid": "Invalid extension: {extension}", - "error.file.extension.missing": "Липсва файлово разширение за файла \"{filename}\"", - "error.file.maxheight": "The height of the image must not exceed {height} pixels", - "error.file.maxsize": "The file is too large", - "error.file.maxwidth": "The width of the image must not exceed {width} pixels", - "error.file.mime.differs": "Каченият файл трябва да бъде от същия mime тип \"{mime}\"", - "error.file.mime.forbidden": "The media type \"{mime}\" is not allowed", - "error.file.mime.invalid": "Invalid mime type: {mime}", - "error.file.mime.missing": "The media type for \"{filename}\" cannot be detected", - "error.file.minheight": "The height of the image must be at least {height} pixels", - "error.file.minsize": "The file is too small", - "error.file.minwidth": "The width of the image must be at least {width} pixels", - "error.file.name.missing": "Името на файла е задължително", - "error.file.notFound": "Файлът \"{filename}\" не може да бъде намерен", - "error.file.orientation": "The orientation of the image must be \"{orientation}\"", - "error.file.type.forbidden": "Не е позволен ъплоуда на файлове от тип {type}", - "error.file.type.invalid": "Invalid file type: {type}", - "error.file.undefined": "\u0424\u0430\u0439\u043b\u044a\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u043d\u0430\u043c\u0435\u0440\u0435\u043d", - - "error.form.incomplete": "Моля коригирайте всички грешки във формата...", - "error.form.notSaved": "Формата не може да бъде запазена", - - "error.language.code": "Please enter a valid code for the language", - "error.language.duplicate": "The language already exists", - "error.language.name": "Please enter a valid name for the language", - "error.language.notFound": "The language could not be found", - - "error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}", - "error.layout.validation.settings": "There's an error in layout {index} settings", - - "error.license.format": "Please enter a valid license key", - "error.license.email": "Моля въведете валиден email адрес", - "error.license.verification": "The license could not be verified", - - "error.offline": "The Panel is currently offline", - - "error.page.changeSlug.permission": "Не можете да смените URL на \"{slug}\"", - "error.page.changeStatus.incomplete": "Страницата съдържа грешки и не може да бъде публикувана", - "error.page.changeStatus.permission": "Статусът на страницата не може да бъде променен", - "error.page.changeStatus.toDraft.invalid": "Страницата \"{slug}\" не може да бъде променена в чернова", - "error.page.changeTemplate.invalid": "Темплейтът за страница \"{slug}\" не може да бъде променен", - "error.page.changeTemplate.permission": "Нямате права за да промените шаблона за \"{slug}\"", - "error.page.changeTitle.empty": "Заглавието е задължително", - "error.page.changeTitle.permission": "Не можете да промените заглавието на \"{slug}\"", - "error.page.create.permission": "Не можете да създадете \"{slug}\"", - "error.page.delete": "Страницата \"{slug}\" не може да бъде изтрита", - "error.page.delete.confirm": "Моля въведете името на страницата, за да потвърдите", - "error.page.delete.hasChildren": "Страницата има подстраници и не може да бъде изтрита", - "error.page.delete.permission": "Не можете да изтриете \"{slug}\"", - "error.page.draft.duplicate": "Вече съществува чернова с URL-добавка \"{slug}\"", - "error.page.duplicate": "Страница с URL-добавка \"{slug}\" вече съществува", - "error.page.duplicate.permission": "You are not allowed to duplicate \"{slug}\"", - "error.page.notFound": "Страницата \"{slug}\" не може да бъде намерена", - "error.page.num.invalid": "Моля въведете валидно число за сортиране. Числата не трябва да са негативни.", - "error.page.slug.invalid": "Please enter a valid URL appendix", - "error.page.slug.maxlength": "Slug length must be less than \"{length}\" characters", - "error.page.sort.permission": "Страницата \"{slug}\" не може да бъде сортирана", - "error.page.status.invalid": "Моля изберете валиден статус на страницата", - "error.page.undefined": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0442\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u0430", - "error.page.update.permission": "Не можете да обновите \"{slug}\"", - - "error.section.files.max.plural": "Не можете да добавяте повече от {max} файлa в секция \"{section}\"", - "error.section.files.max.singular": "Не можете да добавяте повече от един файл в секция \"{section}\"", - "error.section.files.min.plural": "The \"{section}\" section requires at least {min} files", - "error.section.files.min.singular": "The \"{section}\" section requires at least one file", - - "error.section.pages.max.plural": "Не можете да добавяте повече от {max} страници в секция \"{section}\"", - "error.section.pages.max.singular": "Не можете да добавяте повече от една страница в секция \"{section}\"", - "error.section.pages.min.plural": "The \"{section}\" section requires at least {min} pages", - "error.section.pages.min.singular": "The \"{section}\" section requires at least one page", - - "error.section.notLoaded": "Секция \"{name}\" не може да бъде заредена", - "error.section.type.invalid": "Типът \"{type}\" на секция не е валиден", - - "error.site.changeTitle.empty": "Заглавието е задължително", - "error.site.changeTitle.permission": "Не може да променяте заглавието на сайта", - "error.site.update.permission": "Нямате права за да обновите сайта", - - "error.template.default.notFound": "Стандартният шаблон не съществува", - - "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Нямате права да промените имейла на този потребител \"{name}\"", - "error.user.changeLanguage.permission": "Нямате права да промените езика за този потребител \"{name}\"", - "error.user.changeName.permission": "Нямате права да промените името на този потребител \"{name}\"", - "error.user.changePassword.permission": "Нямате права да промените паролата за този потребител \"{name}\"", - "error.user.changeRole.lastAdmin": "Ролята на последния администратор не може да бъде променена", - "error.user.changeRole.permission": "Нямате права да промените ролята на този потребител \"{name}\"", - "error.user.changeRole.toAdmin": "You are not allowed to promote someone to the admin role", - "error.user.create.permission": "Нямате права да създадете този потребител", - "error.user.delete": "\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u0438\u0437\u0442\u0440\u0438\u0442", - "error.user.delete.lastAdmin": "\u041d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u0430 \u0438\u0437\u0442\u0440\u0438\u0435\u0442\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u044f \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440", - "error.user.delete.lastUser": "Последният потребител не може да бъде изтрит", - "error.user.delete.permission": "\u041d\u0435 \u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0435\u043d\u043e \u0434\u0430 \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u0442\u0435 \u0442\u043e\u0437\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b", - "error.user.duplicate": "Потребител с имейл \"{email}\" вече съществува", - "error.user.email.invalid": "Моля въведете валиден email адрес", - "error.user.language.invalid": "Моля въведете валиден език", - "error.user.notFound": "\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u043d\u0430\u043c\u0435\u0440\u0435\u043d.", - "error.user.password.invalid": "Моля въведете валидна парола. Тя трабва да съдържа поне 8 символа.", - "error.user.password.notSame": "\u041c\u043e\u043b\u044f, \u043f\u043e\u0442\u0432\u044a\u0440\u0434\u0435\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u0430\u0442\u0430", - "error.user.password.undefined": "Потребителят няма парола", - "error.user.password.wrong": "Wrong password", - "error.user.role.invalid": "Моля въведете валидна роля", - "error.user.undefined": "Потребителят не може да бъде намерен.", - "error.user.update.permission": "Нямате права да обновите този потребител \"{name}\"", - - "error.validation.accepted": "Моля потвърдете", - "error.validation.alpha": "Моля въвдете символи измежду a-z", - "error.validation.alphanum": "Моля въвдете символи измежду a-z или цифри 0-9", - "error.validation.between": "Моля въведете стойност между \"{min}\" и \"{max}\"", - "error.validation.boolean": "Моля потвърдете или откажете", - "error.validation.contains": "Моля въведете стойност, която съдържа \"{needle}\"", - "error.validation.date": "Моля въведете валидна дата", - "error.validation.date.after": "Please enter a date after {date}", - "error.validation.date.before": "Please enter a date before {date}", - "error.validation.date.between": "Please enter a date between {min} and {max}", - "error.validation.denied": "Моля откажете", - "error.validation.different": "Стойността не трябва да е \"{other}\"", - "error.validation.email": "Моля въведете валиден email адрес", - "error.validation.endswith": "Стойността трябва да завършва с \"{end\"}", - "error.validation.filename": "Моля въведете валидно име на файла", - "error.validation.in": "Моля въведете едно от следните: ({in})", - "error.validation.integer": "Моля въведете валидно цяло число", - "error.validation.ip": "Моля въведете валиден IP адрес", - "error.validation.less": "Моля въведете стойност по-ниска от {max}", - "error.validation.match": "Стойността не съвпада с очаквания модел", - "error.validation.max": "Please enter a value equal to or lower than {max}", - "error.validation.maxlength": "Моля въведете по-къса стойност. (макс. {max} символа)", - "error.validation.maxwords": "Моля въведете не повече от {max} дума(и)", - "error.validation.min": "Please enter a value equal to or greater than {min}", - "error.validation.minlength": "Моля въведете по-дълга стойност. (мин. {min} символа)", - "error.validation.minwords": "Моля въведете поне {min} дума(и).", - "error.validation.more": "Моля въведете стойност по-висока от {min}", - "error.validation.notcontains": "Моля въведете стойност, която не съдържа \"{needle}\"", - "error.validation.notin": "Моля не въвеждайте нито едно от следните: ({notIn})", - "error.validation.option": "Моля изберете валидна опция", - "error.validation.num": "Моля въведете валидно число", - "error.validation.required": "Моля въведете нещо", - "error.validation.same": "Моля въведете \"{other}\"", - "error.validation.size": "Размерът на стойността трябва да бъде \"{size}\"", - "error.validation.startswith": "Стойността трябва да започва с \"{start}\"", - "error.validation.time": "Моля въведете валидно време", - "error.validation.time.after": "Please enter a time after {time}", - "error.validation.time.before": "Please enter a time before {time}", - "error.validation.time.between": "Please enter a time between {min} and {max}", - "error.validation.url": "Моля въведете валиден URL", - - "expand": "Expand", - "expand.all": "Expand All", - - "field.required": "The field is required", - "field.blocks.changeType": "Change type", - "field.blocks.code.name": "Код", - "field.blocks.code.language": "Език", - "field.blocks.code.placeholder": "Your code …", - "field.blocks.delete.confirm": "Do you really want to delete this block?", - "field.blocks.delete.confirm.all": "Do you really want to delete all blocks?", - "field.blocks.delete.confirm.selected": "Do you really want to delete the selected blocks?", - "field.blocks.empty": "No blocks yet", - "field.blocks.fieldsets.label": "Please select a block type …", - "field.blocks.fieldsets.paste": "Press {{ shortcut }} to paste/import blocks from your clipboard", - "field.blocks.gallery.name": "Gallery", - "field.blocks.gallery.images.empty": "No images yet", - "field.blocks.gallery.images.label": "Images", - "field.blocks.heading.level": "Level", - "field.blocks.heading.name": "Heading", - "field.blocks.heading.text": "Text", - "field.blocks.heading.placeholder": "Heading …", - "field.blocks.image.alt": "Alternative text", - "field.blocks.image.caption": "Caption", - "field.blocks.image.crop": "Crop", - "field.blocks.image.link": "Връзка", - "field.blocks.image.location": "Location", - "field.blocks.image.name": "Изображение", - "field.blocks.image.placeholder": "Select an image", - "field.blocks.image.ratio": "Ratio", - "field.blocks.image.url": "Image URL", - "field.blocks.line.name": "Line", - "field.blocks.list.name": "List", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Text", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Quote", - "field.blocks.quote.text.label": "Text", - "field.blocks.quote.text.placeholder": "Quote …", - "field.blocks.quote.citation.label": "Citation", - "field.blocks.quote.citation.placeholder": "by …", - "field.blocks.text.name": "Text", - "field.blocks.text.placeholder": "Text …", - "field.blocks.video.caption": "Caption", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Enter a video URL", - "field.blocks.video.url.label": "Video-URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Все още не са избрани файлове", - - "field.layout.delete": "Delete layout", - "field.layout.delete.confirm": "Do you really want to delete this layout?", - "field.layout.empty": "No rows yet", - "field.layout.select": "Select a layout", - - "field.pages.empty": "Все още не са избрани страници", - "field.structure.delete.confirm": "Сигурни ли сте, че искате да изтриете това вписване?", - "field.structure.empty": "Все още няма статии", - "field.users.empty": "Все още не са избрани потребители", - - "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Сигурни ли сте, че искате да изтриете
{filename}?", - "file.sort": "Change position", - - "files": "Файлове", - "files.empty": "Няма файлове", - - "hide": "Hide", - "hour": "Hour", - "import": "Import", - "info": "Info", - "insert": "\u0412\u043c\u044a\u043a\u043d\u0438", - "insert.after": "Insert after", - "insert.before": "Insert before", - "install": "Инсталирай", - - "installation": "Инсталация", - "installation.completed": "The panel has been installed", - "installation.disabled": "The panel installer is disabled on public servers by default. Please run the installer on a local machine or enable it with the panel.install option.", - "installation.issues.accounts": "Папката /site/accounts не съществува или не позволява запис", - "installation.issues.content": "Папката /content и всички файлове в нея трябва да позволяват запис", - "installation.issues.curl": "Изисква се CURL разширението", - "installation.issues.headline": "Панелът не може да бъде инсталиран", - "installation.issues.mbstring": "Изисква се разширението MB String", - "installation.issues.media": "Папката /media не съществува или няма права за запис", - "installation.issues.php": "Бъдете сигурни, че използвате PHP 7+", - "installation.issues.server": "Kirby изисква Apache, Nginx или Caddy", - "installation.issues.sessions": "The /site/sessions folder does not exist or is not writable", - - "language": "\u0415\u0437\u0438\u043a", - "language.code": "Код", - "language.convert": "Направи по подразбиране", - "language.convert.confirm": "

Сигурни ли сте, че искате да зададете {name} за език по подразбиране? Действието не може да бъде отменено.

В случай, че в {name} има непреведено съдържание, то части от сайта ви могат да останат празни.

", - "language.create": "Добавете нов език", - "language.delete.confirm": "Сигурни ли сте, че искате да изтриете език {name}, включително всички негови преводи? Действието не може да бъде отменено!", - "language.deleted": "Езикът беше изтрит", - "language.direction": "Посока на четене", - "language.direction.ltr": "Отляво надясно", - "language.direction.rtl": "Отдясно наляво", - "language.locale": "PHP locale string", - "language.locale.warning": "You are using a custom locale set up. Please modify it in the language file in /site/languages", - "language.name": "Име", - "language.updated": "Езикът беше обновен", - - "languages": "Езици", - "languages.default": "Език по подразбиране", - "languages.empty": "Все още няма добавени езици", - "languages.secondary": "Второстепенни езици", - "languages.secondary.empty": "Все още няма второстепенни езици", - - "license": "\u041b\u0438\u0446\u0435\u043d\u0437 \u0437\u0430 Kirby", - "license.buy": "Купи лиценз", - "license.register": "Регистрирай", - "license.manage": "Manage your licenses", - "license.register.help": "You received your license code after the purchase via email. Please copy and paste it to register.", - "license.register.label": "Please enter your license code", - "license.register.success": "Thank you for supporting Kirby", - "license.unregistered": "Това е нерегистрирана демо версия на Kirby", - "license.unregistered.label": "Unregistered", - - "link": "\u0412\u0440\u044a\u0437\u043a\u0430", - "link.text": "Текстова връзка", - - "loading": "Зареждане", - - "lock.unsaved": "Unsaved changes", - "lock.unsaved.empty": "There are no more unsaved changes", - "lock.isLocked": "Unsaved changes by {email}", - "lock.file.isLocked": "The file is currently being edited by {email} and cannot be changed.", - "lock.page.isLocked": "The page is currently being edited by {email} and cannot be changed.", - "lock.unlock": "Unlock", - "lock.isUnlocked": "Your unsaved changes have been overwritten by another user. You can download your changes to merge them manually.", - - "login": "Подписване", - "login.code.label.login": "Login code", - "login.code.label.password-reset": "Password reset code", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "If your email address is registered, the requested code was sent via email.", - "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.login.subject": "Your login code", - "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.password-reset.subject": "Your password reset code", - "login.remember": "Keep me logged in", - "login.reset": "Reset password", - "login.toggleText.code.email": "Login via email", - "login.toggleText.code.email-password": "Login with password", - "login.toggleText.password-reset.email": "Forgot your password?", - "login.toggleText.password-reset.email-password": "← Back to login", - - "logout": "Изход", - - "menu": "Меню", - "meridiem": "AM/PM", - "mime": "Media Type", - "minutes": "Minutes", - - "month": "Month", - "months.april": "\u0410\u043f\u0440\u0438\u043b", - "months.august": "\u0410\u0432\u0433\u0443\u0441\u0442", - "months.december": "\u0414\u0435\u043a\u0435\u043c\u0432\u0440\u0438", - "months.february": "Февруари", - "months.january": "\u042f\u043d\u0443\u0430\u0440\u0438", - "months.july": "\u042e\u043b\u0438", - "months.june": "\u042e\u043d\u0438", - "months.march": "\u041c\u0430\u0440\u0442", - "months.may": "\u041c\u0430\u0439", - "months.november": "\u041d\u043e\u0435\u043c\u0432\u0440\u0438", - "months.october": "\u041e\u043a\u0442\u043e\u043c\u0432\u0440\u0438", - "months.september": "\u0421\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438", - - "more": "Още", - "name": "Име", - "next": "Next", - "no": "no", - "off": "off", - "on": "on", - "open": "Отвори", - "open.newWindow": "Open in new window", - "options": "Options", - "options.none": "No options", - - "orientation": "Ориентация", - "orientation.landscape": "Пейзаж", - "orientation.portrait": "Портрет", - "orientation.square": "Квадрат", - - "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "\u041f\u0440\u043e\u043c\u0435\u043d\u0438 URL", - "page.changeSlug.fromTitle": "\u0421\u044a\u0437\u0434\u0430\u0439\u0442\u0435 \u043e\u0442 \u0437\u0430\u0433\u043b\u0430\u0432\u0438\u0435\u0442\u043e", - "page.changeStatus": "Промени статус", - "page.changeStatus.position": "Моля изберете позиция", - "page.changeStatus.select": "Изберете нов статус", - "page.changeTemplate": "Промени шаблон", - "page.delete.confirm": "Сигурни ли сте, че искате да изтриете {title}?", - "page.delete.confirm.subpages": "Тази страница има подстраници.
Всички подстраници също ще бъдат изтрити.", - "page.delete.confirm.title": "Въведи заглавие на страница за да потвърдиш", - "page.draft.create": "Създай чернова", - "page.duplicate.appendix": "Копирай", - "page.duplicate.files": "Copy files", - "page.duplicate.pages": "Copy pages", - "page.sort": "Change position", - "page.status": "Status", - "page.status.draft": "Чернова", - "page.status.draft.description": "The page is in draft mode and only visible for logged in editors or via secret link", - "page.status.listed": "Публично", - "page.status.listed.description": "Страницата е публична за всички", - "page.status.unlisted": "Скрит", - "page.status.unlisted.description": "Страницата е достъпна само чрез URL", - - "pages": "Страници", - "pages.empty": "Все още няма страници", - "pages.status.draft": "Drafts", - "pages.status.listed": "Published", - "pages.status.unlisted": "Скрит", - - "pagination.page": "Страница", - - "password": "\u041f\u0430\u0440\u043e\u043b\u0430", - "paste": "Paste", - "paste.after": "Paste after", - "pixel": "Пиксел", - "plugins": "Plugins", - "prev": "Previous", - "preview": "Preview", - "remove": "Премахни", - "rename": "Преименувай", - "replace": "\u0417\u0430\u043c\u0435\u0441\u0442\u0438", - "retry": "\u041e\u043f\u0438\u0442\u0430\u0439 \u043f\u0430\u043a", - "revert": "\u041e\u0442\u043c\u0435\u043d\u0438", - "revert.confirm": "Do you really want to delete all unsaved changes?", - - "role": "\u0420\u043e\u043b\u044f", - "role.admin.description": "The admin has all rights", - "role.admin.title": "Admin", - "role.all": "Всички", - "role.empty": "Не съществуват потребители с тази роля", - "role.description.placeholder": "Липсва описание", - "role.nobody.description": "This is a fallback role without any permissions", - "role.nobody.title": "Nobody", - - "save": "\u0417\u0430\u043f\u0438\u0448\u0438", - "search": "Търси", - "search.min": "Enter {min} characters to search", - "search.all": "Show all", - "search.results.none": "No results", - - "section.required": "The section is required", - - "security": "Security", - "select": "Избери", - "server": "Server", - "settings": "Настройки", - "show": "Show", - "site.blueprint": "The site has no blueprint yet. You can define the setup in /site/blueprints/site.yml", - "size": "Размер", - "slug": "URL-\u0434\u043e\u0431\u0430\u0432\u043a\u0430", - "sort": "Сортирай", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Заглавие", - "template": "Образец", - "today": "Днес", - - "toolbar.button.code": "Код", - "toolbar.button.bold": "\u041f\u043e\u043b\u0443\u0447\u0435\u0440 \u0448\u0440\u0438\u0444\u0442", - "toolbar.button.email": "Email", - "toolbar.button.headings": "Заглавия", - "toolbar.button.heading.1": "Заглавие 1", - "toolbar.button.heading.2": "Заглавие 2", - "toolbar.button.heading.3": "Заглавие 3", - "toolbar.button.heading.4": "Heading 4", - "toolbar.button.heading.5": "Heading 5", - "toolbar.button.heading.6": "Heading 6", - "toolbar.button.italic": "\u041d\u0430\u043a\u043b\u043e\u043d\u0435\u043d \u0448\u0440\u0438\u0444\u0442", - "toolbar.button.file": "Файл", - "toolbar.button.file.select": "Select a file", - "toolbar.button.file.upload": "Upload a file", - "toolbar.button.link": "\u0412\u0440\u044a\u0437\u043a\u0430", - "toolbar.button.paragraph": "Paragraph", - "toolbar.button.strike": "Strike-through", - "toolbar.button.ol": "Подреден списък", - "toolbar.button.underline": "Underline", - "toolbar.button.ul": "Списък", - - "translation.author": "Kirby екип", - "translation.direction": "ltr", - "translation.name": "Български", - "translation.locale": "bg_BG", - - "upload": "Прикачи", - "upload.error.cantMove": "The uploaded file could not be moved", - "upload.error.cantWrite": "Failed to write file to disk", - "upload.error.default": "The file could not be uploaded", - "upload.error.extension": "File upload stopped by extension", - "upload.error.formSize": "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the form", - "upload.error.iniPostSize": "The uploaded file exceeds the post_max_size directive in php.ini", - "upload.error.iniSize": "The uploaded file exceeds the upload_max_filesize directive in php.ini", - "upload.error.noFile": "No file was uploaded", - "upload.error.noFiles": "No files were uploaded", - "upload.error.partial": "The uploaded file was only partially uploaded", - "upload.error.tmpDir": "Missing a temporary folder", - "upload.errors": "Грешка", - "upload.progress": "Uploading…", - - "url": "Url", - "url.placeholder": "https://example.com", - - "user": "Потребител", - "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Промени email", - "user.changeLanguage": "Промени език", - "user.changeName": "Преименувай този потребител", - "user.changePassword": "Промени парола", - "user.changePassword.new": "Нова парола", - "user.changePassword.new.confirm": "Потвърдете новата парола...", - "user.changeRole": "Променете роля", - "user.changeRole.select": "Изберете нова роля", - "user.create": "Добавете нов потребител", - "user.delete": "Изтрийте потребителя", - "user.delete.confirm": "Сигурни ли сте, че искате да изтриете
{email}?", - - "users": "Потребители", - - "version": "\u0412\u0435\u0440\u0441\u0438\u044f \u043d\u0430 Kirby", - - "view.account": "\u0412\u0430\u0448\u0438\u044f \u0430\u043a\u0430\u0443\u043d\u0442", - "view.installation": "\u0418\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f", - "view.languages": "Езици", - "view.resetPassword": "Reset password", - "view.site": "Сайт", - "view.system": "System", - "view.users": "\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438", - - "welcome": "Добре дошли", - "year": "Year", - "yes": "yes" + "account.changeName": "Change your name", + "account.delete": "Delete your account", + "account.delete.confirm": "Do you really want to delete your account? You will be logged out immediately. Your account cannot be recovered.", + + "add": "\u0414\u043e\u0431\u0430\u0432\u0438", + "author": "Author", + "avatar": "Профилна снимка", + "back": "Назад", + "cancel": "\u041e\u0442\u043a\u0430\u0436\u0438", + "change": "\u041f\u0440\u043e\u043c\u0435\u043d\u0438", + "close": "\u0417\u0430\u0442\u0432\u043e\u0440\u0438", + "confirm": "Ок", + "collapse": "Collapse", + "collapse.all": "Collapse All", + "copy": "Копирай", + "copy.all": "Copy all", + "create": "Създай", + + "date": "Дата", + "date.select": "Select a date", + + "day": "Day", + "days.fri": "\u041f\u0442", + "days.mon": "\u041f\u043d", + "days.sat": "\u0421\u0431", + "days.sun": "\u041d\u0434", + "days.thu": "\u0427\u0442", + "days.tue": "\u0412\u0442", + "days.wed": "\u0421\u0440", + + "debugging": "Debugging", + + "delete": "\u0418\u0437\u0442\u0440\u0438\u0439", + "delete.all": "Delete all", + + "dialog.files.empty": "No files to select", + "dialog.pages.empty": "No pages to select", + "dialog.users.empty": "No users to select", + + "dimensions": "Размери", + "disabled": "Disabled", + "discard": "\u041e\u0442\u043c\u0435\u043d\u0438", + "download": "Download", + "duplicate": "Duplicate", + + "edit": "\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u0430\u0439", + + "email": "Email", + "email.placeholder": "mail@example.com", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Environment", + + "error.access.code": "Invalid code", + "error.access.login": "Invalid login", + "error.access.panel": "Нямате права за достъп до панела", + "error.access.view": "You are not allowed to access this part of the panel", + + "error.avatar.create.fail": "Профилната снимка не може да се качи", + "error.avatar.delete.fail": "Профилната снимка не може да бъде изтрита", + "error.avatar.dimensions.invalid": "Моля запазете ширината и височината на профилната снимка под 3000 пиксела", + "error.avatar.mime.forbidden": "Профилната снимка трябва да бъде в JPEG или PNG формат", + + "error.blueprint.notFound": "Образецът \"{name}\" не може да бъде зареден", + + "error.blocks.max.plural": "You must not add more than {max} blocks", + "error.blocks.max.singular": "You must not add more than one block", + "error.blocks.min.plural": "You must add at least {min} blocks", + "error.blocks.min.singular": "You must add at least one block", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "Email шаблонът \"{name}\" не може да бъде открит", + + "error.field.converter.invalid": "Невалиден конвертор \"{converter}\"", + + "error.file.changeName.empty": "The name must not be empty", + "error.file.changeName.permission": "Не можете да смените името на \"{filename}\"", + "error.file.duplicate": "Файл с име \"{filename}\" вече съществува", + "error.file.extension.forbidden": "Файловото разширение \"{extension}\" не е позволено", + "error.file.extension.invalid": "Invalid extension: {extension}", + "error.file.extension.missing": "Липсва файлово разширение за файла \"{filename}\"", + "error.file.maxheight": "The height of the image must not exceed {height} pixels", + "error.file.maxsize": "The file is too large", + "error.file.maxwidth": "The width of the image must not exceed {width} pixels", + "error.file.mime.differs": "Каченият файл трябва да бъде от същия mime тип \"{mime}\"", + "error.file.mime.forbidden": "The media type \"{mime}\" is not allowed", + "error.file.mime.invalid": "Invalid mime type: {mime}", + "error.file.mime.missing": "The media type for \"{filename}\" cannot be detected", + "error.file.minheight": "The height of the image must be at least {height} pixels", + "error.file.minsize": "The file is too small", + "error.file.minwidth": "The width of the image must be at least {width} pixels", + "error.file.name.missing": "Името на файла е задължително", + "error.file.notFound": "Файлът \"{filename}\" не може да бъде намерен", + "error.file.orientation": "The orientation of the image must be \"{orientation}\"", + "error.file.type.forbidden": "Не е позволен ъплоуда на файлове от тип {type}", + "error.file.type.invalid": "Invalid file type: {type}", + "error.file.undefined": "\u0424\u0430\u0439\u043b\u044a\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u043d\u0430\u043c\u0435\u0440\u0435\u043d", + + "error.form.incomplete": "Моля коригирайте всички грешки във формата...", + "error.form.notSaved": "Формата не може да бъде запазена", + + "error.language.code": "Please enter a valid code for the language", + "error.language.duplicate": "The language already exists", + "error.language.name": "Please enter a valid name for the language", + "error.language.notFound": "The language could not be found", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "There's an error in layout {index} settings", + + "error.license.format": "Please enter a valid license key", + "error.license.email": "Моля въведете валиден email адрес", + "error.license.verification": "The license could not be verified", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "The Panel is currently offline", + + "error.page.changeSlug.permission": "Не можете да смените URL на \"{slug}\"", + "error.page.changeStatus.incomplete": "Страницата съдържа грешки и не може да бъде публикувана", + "error.page.changeStatus.permission": "Статусът на страницата не може да бъде променен", + "error.page.changeStatus.toDraft.invalid": "Страницата \"{slug}\" не може да бъде променена в чернова", + "error.page.changeTemplate.invalid": "Темплейтът за страница \"{slug}\" не може да бъде променен", + "error.page.changeTemplate.permission": "Нямате права за да промените шаблона за \"{slug}\"", + "error.page.changeTitle.empty": "Заглавието е задължително", + "error.page.changeTitle.permission": "Не можете да промените заглавието на \"{slug}\"", + "error.page.create.permission": "Не можете да създадете \"{slug}\"", + "error.page.delete": "Страницата \"{slug}\" не може да бъде изтрита", + "error.page.delete.confirm": "Моля въведете името на страницата, за да потвърдите", + "error.page.delete.hasChildren": "Страницата има подстраници и не може да бъде изтрита", + "error.page.delete.permission": "Не можете да изтриете \"{slug}\"", + "error.page.draft.duplicate": "Вече съществува чернова с URL-добавка \"{slug}\"", + "error.page.duplicate": "Страница с URL-добавка \"{slug}\" вече съществува", + "error.page.duplicate.permission": "You are not allowed to duplicate \"{slug}\"", + "error.page.notFound": "Страницата \"{slug}\" не може да бъде намерена", + "error.page.num.invalid": "Моля въведете валидно число за сортиране. Числата не трябва да са негативни.", + "error.page.slug.invalid": "Please enter a valid URL appendix", + "error.page.slug.maxlength": "Slug length must be less than \"{length}\" characters", + "error.page.sort.permission": "Страницата \"{slug}\" не може да бъде сортирана", + "error.page.status.invalid": "Моля изберете валиден статус на страницата", + "error.page.undefined": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0442\u0430 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u043d\u0430\u043c\u0435\u0440\u0435\u043d\u0430", + "error.page.update.permission": "Не можете да обновите \"{slug}\"", + + "error.section.files.max.plural": "Не можете да добавяте повече от {max} файлa в секция \"{section}\"", + "error.section.files.max.singular": "Не можете да добавяте повече от един файл в секция \"{section}\"", + "error.section.files.min.plural": "The \"{section}\" section requires at least {min} files", + "error.section.files.min.singular": "The \"{section}\" section requires at least one file", + + "error.section.pages.max.plural": "Не можете да добавяте повече от {max} страници в секция \"{section}\"", + "error.section.pages.max.singular": "Не можете да добавяте повече от една страница в секция \"{section}\"", + "error.section.pages.min.plural": "The \"{section}\" section requires at least {min} pages", + "error.section.pages.min.singular": "The \"{section}\" section requires at least one page", + + "error.section.notLoaded": "Секция \"{name}\" не може да бъде заредена", + "error.section.type.invalid": "Типът \"{type}\" на секция не е валиден", + + "error.site.changeTitle.empty": "Заглавието е задължително", + "error.site.changeTitle.permission": "Не може да променяте заглавието на сайта", + "error.site.update.permission": "Нямате права за да обновите сайта", + + "error.template.default.notFound": "Стандартният шаблон не съществува", + + "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Нямате права да промените имейла на този потребител \"{name}\"", + "error.user.changeLanguage.permission": "Нямате права да промените езика за този потребител \"{name}\"", + "error.user.changeName.permission": "Нямате права да промените името на този потребител \"{name}\"", + "error.user.changePassword.permission": "Нямате права да промените паролата за този потребител \"{name}\"", + "error.user.changeRole.lastAdmin": "Ролята на последния администратор не може да бъде променена", + "error.user.changeRole.permission": "Нямате права да промените ролята на този потребител \"{name}\"", + "error.user.changeRole.toAdmin": "You are not allowed to promote someone to the admin role", + "error.user.create.permission": "Нямате права да създадете този потребител", + "error.user.delete": "\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u0438\u0437\u0442\u0440\u0438\u0442", + "error.user.delete.lastAdmin": "\u041d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u0430 \u0438\u0437\u0442\u0440\u0438\u0435\u0442\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u044f \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440", + "error.user.delete.lastUser": "Последният потребител не може да бъде изтрит", + "error.user.delete.permission": "\u041d\u0435 \u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0435\u043d\u043e \u0434\u0430 \u0438\u0437\u0442\u0440\u0438\u0432\u0430\u0442\u0435 \u0442\u043e\u0437\u0438 \u043f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b", + "error.user.duplicate": "Потребител с имейл \"{email}\" вече съществува", + "error.user.email.invalid": "Моля въведете валиден email адрес", + "error.user.language.invalid": "Моля въведете валиден език", + "error.user.notFound": "\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u044f\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435 \u0434\u0430 \u0431\u044a\u0434\u0435 \u043d\u0430\u043c\u0435\u0440\u0435\u043d.", + "error.user.password.invalid": "Моля въведете валидна парола. Тя трабва да съдържа поне 8 символа.", + "error.user.password.notSame": "\u041c\u043e\u043b\u044f, \u043f\u043e\u0442\u0432\u044a\u0440\u0434\u0435\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u0430\u0442\u0430", + "error.user.password.undefined": "Потребителят няма парола", + "error.user.password.wrong": "Wrong password", + "error.user.role.invalid": "Моля въведете валидна роля", + "error.user.undefined": "Потребителят не може да бъде намерен.", + "error.user.update.permission": "Нямате права да обновите този потребител \"{name}\"", + + "error.validation.accepted": "Моля потвърдете", + "error.validation.alpha": "Моля въвдете символи измежду a-z", + "error.validation.alphanum": "Моля въвдете символи измежду a-z или цифри 0-9", + "error.validation.between": "Моля въведете стойност между \"{min}\" и \"{max}\"", + "error.validation.boolean": "Моля потвърдете или откажете", + "error.validation.contains": "Моля въведете стойност, която съдържа \"{needle}\"", + "error.validation.date": "Моля въведете валидна дата", + "error.validation.date.after": "Please enter a date after {date}", + "error.validation.date.before": "Please enter a date before {date}", + "error.validation.date.between": "Please enter a date between {min} and {max}", + "error.validation.denied": "Моля откажете", + "error.validation.different": "Стойността не трябва да е \"{other}\"", + "error.validation.email": "Моля въведете валиден email адрес", + "error.validation.endswith": "Стойността трябва да завършва с \"{end\"}", + "error.validation.filename": "Моля въведете валидно име на файла", + "error.validation.in": "Моля въведете едно от следните: ({in})", + "error.validation.integer": "Моля въведете валидно цяло число", + "error.validation.ip": "Моля въведете валиден IP адрес", + "error.validation.less": "Моля въведете стойност по-ниска от {max}", + "error.validation.match": "Стойността не съвпада с очаквания модел", + "error.validation.max": "Please enter a value equal to or lower than {max}", + "error.validation.maxlength": "Моля въведете по-къса стойност. (макс. {max} символа)", + "error.validation.maxwords": "Моля въведете не повече от {max} дума(и)", + "error.validation.min": "Please enter a value equal to or greater than {min}", + "error.validation.minlength": "Моля въведете по-дълга стойност. (мин. {min} символа)", + "error.validation.minwords": "Моля въведете поне {min} дума(и).", + "error.validation.more": "Моля въведете стойност по-висока от {min}", + "error.validation.notcontains": "Моля въведете стойност, която не съдържа \"{needle}\"", + "error.validation.notin": "Моля не въвеждайте нито едно от следните: ({notIn})", + "error.validation.option": "Моля изберете валидна опция", + "error.validation.num": "Моля въведете валидно число", + "error.validation.required": "Моля въведете нещо", + "error.validation.same": "Моля въведете \"{other}\"", + "error.validation.size": "Размерът на стойността трябва да бъде \"{size}\"", + "error.validation.startswith": "Стойността трябва да започва с \"{start}\"", + "error.validation.time": "Моля въведете валидно време", + "error.validation.time.after": "Please enter a time after {time}", + "error.validation.time.before": "Please enter a time before {time}", + "error.validation.time.between": "Please enter a time between {min} and {max}", + "error.validation.url": "Моля въведете валиден URL", + + "expand": "Expand", + "expand.all": "Expand All", + + "field.required": "The field is required", + "field.blocks.changeType": "Change type", + "field.blocks.code.name": "Код", + "field.blocks.code.language": "Език", + "field.blocks.code.placeholder": "Your code …", + "field.blocks.delete.confirm": "Do you really want to delete this block?", + "field.blocks.delete.confirm.all": "Do you really want to delete all blocks?", + "field.blocks.delete.confirm.selected": "Do you really want to delete the selected blocks?", + "field.blocks.empty": "No blocks yet", + "field.blocks.fieldsets.label": "Please select a block type …", + "field.blocks.fieldsets.paste": "Press {{ shortcut }} to paste/import blocks from your clipboard", + "field.blocks.gallery.name": "Gallery", + "field.blocks.gallery.images.empty": "No images yet", + "field.blocks.gallery.images.label": "Images", + "field.blocks.heading.level": "Level", + "field.blocks.heading.name": "Heading", + "field.blocks.heading.text": "Text", + "field.blocks.heading.placeholder": "Heading …", + "field.blocks.image.alt": "Alternative text", + "field.blocks.image.caption": "Caption", + "field.blocks.image.crop": "Crop", + "field.blocks.image.link": "Връзка", + "field.blocks.image.location": "Location", + "field.blocks.image.name": "Изображение", + "field.blocks.image.placeholder": "Select an image", + "field.blocks.image.ratio": "Ratio", + "field.blocks.image.url": "Image URL", + "field.blocks.line.name": "Line", + "field.blocks.list.name": "List", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Text", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Quote", + "field.blocks.quote.text.label": "Text", + "field.blocks.quote.text.placeholder": "Quote …", + "field.blocks.quote.citation.label": "Citation", + "field.blocks.quote.citation.placeholder": "by …", + "field.blocks.text.name": "Text", + "field.blocks.text.placeholder": "Text …", + "field.blocks.video.caption": "Caption", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Enter a video URL", + "field.blocks.video.url.label": "Video-URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Все още не са избрани файлове", + + "field.layout.delete": "Delete layout", + "field.layout.delete.confirm": "Do you really want to delete this layout?", + "field.layout.empty": "No rows yet", + "field.layout.select": "Select a layout", + + "field.object.empty": "No information yet", + + "field.pages.empty": "Все още не са избрани страници", + + "field.structure.delete.confirm": "Сигурни ли сте, че искате да изтриете това вписване?", + "field.structure.empty": "Все още няма статии", + + "field.users.empty": "Все още не са избрани потребители", + + "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Сигурни ли сте, че искате да изтриете
{filename}?", + "file.sort": "Change position", + + "files": "Файлове", + "files.empty": "Няма файлове", + + "hide": "Hide", + "hour": "Hour", + "import": "Import", + "info": "Info", + "insert": "\u0412\u043c\u044a\u043a\u043d\u0438", + "insert.after": "Insert after", + "insert.before": "Insert before", + "install": "Инсталирай", + + "installation": "Инсталация", + "installation.completed": "The panel has been installed", + "installation.disabled": "The panel installer is disabled on public servers by default. Please run the installer on a local machine or enable it with the panel.install option.", + "installation.issues.accounts": "Папката /site/accounts не съществува или не позволява запис", + "installation.issues.content": "Папката /content и всички файлове в нея трябва да позволяват запис", + "installation.issues.curl": "Изисква се CURL разширението", + "installation.issues.headline": "Панелът не може да бъде инсталиран", + "installation.issues.mbstring": "Изисква се разширението MB String", + "installation.issues.media": "Папката /media не съществува или няма права за запис", + "installation.issues.php": "Бъдете сигурни, че използвате PHP 7+", + "installation.issues.server": "Kirby изисква Apache, Nginx или Caddy", + "installation.issues.sessions": "The /site/sessions folder does not exist or is not writable", + + "language": "\u0415\u0437\u0438\u043a", + "language.code": "Код", + "language.convert": "Направи по подразбиране", + "language.convert.confirm": "

Сигурни ли сте, че искате да зададете {name} за език по подразбиране? Действието не може да бъде отменено.

В случай, че в {name} има непреведено съдържание, то части от сайта ви могат да останат празни.

", + "language.create": "Добавете нов език", + "language.delete.confirm": "Сигурни ли сте, че искате да изтриете език {name}, включително всички негови преводи? Действието не може да бъде отменено!", + "language.deleted": "Езикът беше изтрит", + "language.direction": "Посока на четене", + "language.direction.ltr": "Отляво надясно", + "language.direction.rtl": "Отдясно наляво", + "language.locale": "PHP locale string", + "language.locale.warning": "You are using a custom locale set up. Please modify it in the language file in /site/languages", + "language.name": "Име", + "language.updated": "Езикът беше обновен", + + "languages": "Езици", + "languages.default": "Език по подразбиране", + "languages.empty": "Все още няма добавени езици", + "languages.secondary": "Второстепенни езици", + "languages.secondary.empty": "Все още няма второстепенни езици", + + "license": "\u041b\u0438\u0446\u0435\u043d\u0437 \u0437\u0430 Kirby", + "license.buy": "Купи лиценз", + "license.register": "Регистрирай", + "license.manage": "Manage your licenses", + "license.register.help": "You received your license code after the purchase via email. Please copy and paste it to register.", + "license.register.label": "Please enter your license code", + "license.register.success": "Thank you for supporting Kirby", + "license.unregistered": "Това е нерегистрирана демо версия на Kirby", + "license.unregistered.label": "Unregistered", + + "link": "\u0412\u0440\u044a\u0437\u043a\u0430", + "link.text": "Текстова връзка", + + "loading": "Зареждане", + + "lock.unsaved": "Unsaved changes", + "lock.unsaved.empty": "There are no more unsaved changes", + "lock.isLocked": "Unsaved changes by {email}", + "lock.file.isLocked": "The file is currently being edited by {email} and cannot be changed.", + "lock.page.isLocked": "The page is currently being edited by {email} and cannot be changed.", + "lock.unlock": "Unlock", + "lock.isUnlocked": "Your unsaved changes have been overwritten by another user. You can download your changes to merge them manually.", + + "login": "Подписване", + "login.code.label.login": "Login code", + "login.code.label.password-reset": "Password reset code", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "If your email address is registered, the requested code was sent via email.", + "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.login.subject": "Your login code", + "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.password-reset.subject": "Your password reset code", + "login.remember": "Keep me logged in", + "login.reset": "Reset password", + "login.toggleText.code.email": "Login via email", + "login.toggleText.code.email-password": "Login with password", + "login.toggleText.password-reset.email": "Forgot your password?", + "login.toggleText.password-reset.email-password": "← Back to login", + + "logout": "Изход", + + "menu": "Меню", + "meridiem": "AM/PM", + "mime": "Media Type", + "minutes": "Minutes", + + "month": "Month", + "months.april": "\u0410\u043f\u0440\u0438\u043b", + "months.august": "\u0410\u0432\u0433\u0443\u0441\u0442", + "months.december": "\u0414\u0435\u043a\u0435\u043c\u0432\u0440\u0438", + "months.february": "Февруари", + "months.january": "\u042f\u043d\u0443\u0430\u0440\u0438", + "months.july": "\u042e\u043b\u0438", + "months.june": "\u042e\u043d\u0438", + "months.march": "\u041c\u0430\u0440\u0442", + "months.may": "\u041c\u0430\u0439", + "months.november": "\u041d\u043e\u0435\u043c\u0432\u0440\u0438", + "months.october": "\u041e\u043a\u0442\u043e\u043c\u0432\u0440\u0438", + "months.september": "\u0421\u0435\u043f\u0442\u0435\u043c\u0432\u0440\u0438", + + "more": "Още", + "name": "Име", + "next": "Next", + "no": "no", + "off": "off", + "on": "on", + "open": "Отвори", + "open.newWindow": "Open in new window", + "options": "Options", + "options.none": "No options", + + "orientation": "Ориентация", + "orientation.landscape": "Пейзаж", + "orientation.portrait": "Портрет", + "orientation.square": "Квадрат", + + "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "\u041f\u0440\u043e\u043c\u0435\u043d\u0438 URL", + "page.changeSlug.fromTitle": "\u0421\u044a\u0437\u0434\u0430\u0439\u0442\u0435 \u043e\u0442 \u0437\u0430\u0433\u043b\u0430\u0432\u0438\u0435\u0442\u043e", + "page.changeStatus": "Промени статус", + "page.changeStatus.position": "Моля изберете позиция", + "page.changeStatus.select": "Изберете нов статус", + "page.changeTemplate": "Промени шаблон", + "page.delete.confirm": "Сигурни ли сте, че искате да изтриете {title}?", + "page.delete.confirm.subpages": "Тази страница има подстраници.
Всички подстраници също ще бъдат изтрити.", + "page.delete.confirm.title": "Въведи заглавие на страница за да потвърдиш", + "page.draft.create": "Създай чернова", + "page.duplicate.appendix": "Копирай", + "page.duplicate.files": "Copy files", + "page.duplicate.pages": "Copy pages", + "page.sort": "Change position", + "page.status": "Status", + "page.status.draft": "Чернова", + "page.status.draft.description": "The page is in draft mode and only visible for logged in editors or via secret link", + "page.status.listed": "Публично", + "page.status.listed.description": "Страницата е публична за всички", + "page.status.unlisted": "Скрит", + "page.status.unlisted.description": "Страницата е достъпна само чрез URL", + + "pages": "Страници", + "pages.empty": "Все още няма страници", + "pages.status.draft": "Drafts", + "pages.status.listed": "Published", + "pages.status.unlisted": "Скрит", + + "pagination.page": "Страница", + + "password": "\u041f\u0430\u0440\u043e\u043b\u0430", + "paste": "Paste", + "paste.after": "Paste after", + "pixel": "Пиксел", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "Previous", + "preview": "Preview", + "remove": "Премахни", + "rename": "Преименувай", + "replace": "\u0417\u0430\u043c\u0435\u0441\u0442\u0438", + "retry": "\u041e\u043f\u0438\u0442\u0430\u0439 \u043f\u0430\u043a", + "revert": "\u041e\u0442\u043c\u0435\u043d\u0438", + "revert.confirm": "Do you really want to delete all unsaved changes?", + + "role": "\u0420\u043e\u043b\u044f", + "role.admin.description": "The admin has all rights", + "role.admin.title": "Admin", + "role.all": "Всички", + "role.empty": "Не съществуват потребители с тази роля", + "role.description.placeholder": "Липсва описание", + "role.nobody.description": "This is a fallback role without any permissions", + "role.nobody.title": "Nobody", + + "save": "\u0417\u0430\u043f\u0438\u0448\u0438", + "search": "Търси", + "search.min": "Enter {min} characters to search", + "search.all": "Show all", + "search.results.none": "No results", + + "section.required": "The section is required", + + "security": "Security", + "select": "Избери", + "server": "Server", + "settings": "Настройки", + "show": "Show", + "site.blueprint": "The site has no blueprint yet. You can define the setup in /site/blueprints/site.yml", + "size": "Размер", + "slug": "URL-\u0434\u043e\u0431\u0430\u0432\u043a\u0430", + "sort": "Сортирай", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Заглавие", + "template": "Образец", + "today": "Днес", + + "toolbar.button.code": "Код", + "toolbar.button.bold": "\u041f\u043e\u043b\u0443\u0447\u0435\u0440 \u0448\u0440\u0438\u0444\u0442", + "toolbar.button.email": "Email", + "toolbar.button.headings": "Заглавия", + "toolbar.button.heading.1": "Заглавие 1", + "toolbar.button.heading.2": "Заглавие 2", + "toolbar.button.heading.3": "Заглавие 3", + "toolbar.button.heading.4": "Heading 4", + "toolbar.button.heading.5": "Heading 5", + "toolbar.button.heading.6": "Heading 6", + "toolbar.button.italic": "\u041d\u0430\u043a\u043b\u043e\u043d\u0435\u043d \u0448\u0440\u0438\u0444\u0442", + "toolbar.button.file": "Файл", + "toolbar.button.file.select": "Select a file", + "toolbar.button.file.upload": "Upload a file", + "toolbar.button.link": "\u0412\u0440\u044a\u0437\u043a\u0430", + "toolbar.button.paragraph": "Paragraph", + "toolbar.button.strike": "Strike-through", + "toolbar.button.ol": "Подреден списък", + "toolbar.button.underline": "Underline", + "toolbar.button.ul": "Списък", + + "translation.author": "Kirby екип", + "translation.direction": "ltr", + "translation.name": "Български", + "translation.locale": "bg_BG", + + "upload": "Прикачи", + "upload.error.cantMove": "The uploaded file could not be moved", + "upload.error.cantWrite": "Failed to write file to disk", + "upload.error.default": "The file could not be uploaded", + "upload.error.extension": "File upload stopped by extension", + "upload.error.formSize": "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the form", + "upload.error.iniPostSize": "The uploaded file exceeds the post_max_size directive in php.ini", + "upload.error.iniSize": "The uploaded file exceeds the upload_max_filesize directive in php.ini", + "upload.error.noFile": "No file was uploaded", + "upload.error.noFiles": "No files were uploaded", + "upload.error.partial": "The uploaded file was only partially uploaded", + "upload.error.tmpDir": "Missing a temporary folder", + "upload.errors": "Грешка", + "upload.progress": "Uploading…", + + "url": "Url", + "url.placeholder": "https://example.com", + + "user": "Потребител", + "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Промени email", + "user.changeLanguage": "Промени език", + "user.changeName": "Преименувай този потребител", + "user.changePassword": "Промени парола", + "user.changePassword.new": "Нова парола", + "user.changePassword.new.confirm": "Потвърдете новата парола...", + "user.changeRole": "Променете роля", + "user.changeRole.select": "Изберете нова роля", + "user.create": "Добавете нов потребител", + "user.delete": "Изтрийте потребителя", + "user.delete.confirm": "Сигурни ли сте, че искате да изтриете
{email}?", + + "users": "Потребители", + + "version": "\u0412\u0435\u0440\u0441\u0438\u044f \u043d\u0430 Kirby", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "\u0412\u0430\u0448\u0438\u044f \u0430\u043a\u0430\u0443\u043d\u0442", + "view.installation": "\u0418\u043d\u0441\u0442\u0430\u043b\u0430\u0446\u0438\u044f", + "view.languages": "Езици", + "view.resetPassword": "Reset password", + "view.site": "Сайт", + "view.system": "System", + "view.users": "\u041f\u043e\u0442\u0440\u0435\u0431\u0438\u0442\u0435\u043b\u0438", + + "welcome": "Добре дошли", + "year": "Year", + "yes": "yes" } diff --git a/kirby/i18n/translations/ca.json b/kirby/i18n/translations/ca.json index 026491e..ce9a2cc 100644 --- a/kirby/i18n/translations/ca.json +++ b/kirby/i18n/translations/ca.json @@ -1,573 +1,596 @@ { - "account.changeName": "Change your name", - "account.delete": "Delete your account", - "account.delete.confirm": "Do you really want to delete your account? You will be logged out immediately. Your account cannot be recovered.", - - "add": "Afegir", - "author": "Author", - "avatar": "Imatge del perfil", - "back": "Tornar", - "cancel": "Cancel\u00b7lar", - "change": "Canviar", - "close": "Tancar", - "confirm": "Ok", - "collapse": "Col·lapsar", - "collapse.all": "Col·lapsar tot", - "copy": "Copiar", - "copy.all": "Copy all", - "create": "Crear", - - "date": "Data", - "date.select": "Selecciona una data", - - "day": "Dia", - "days.fri": "dv.", - "days.mon": "dl.", - "days.sat": "ds.", - "days.sun": "dg.", - "days.thu": "dj.", - "days.tue": "dt.", - "days.wed": "dc.", - - "debugging": "Debugging", - - "delete": "Eliminar", - "delete.all": "Eliminar tot", - - "dialog.files.empty": "No hi ha cap fitxer per seleccionar", - "dialog.pages.empty": "No hi ha cap pàgina per seleccionar", - "dialog.users.empty": "No hi ha cap usuari per seleccionar", - - "dimensions": "Dimensions", - "disabled": "Desactivat", - "discard": "Descartar", - "download": "Descarregar", - "duplicate": "Duplicar", - - "edit": "Editar", - - "email": "Email", - "email.placeholder": "mail@exemple.com", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Environment", - - "error.access.code": "Codi invàlid", - "error.access.login": "Inici de sessió no vàlid", - "error.access.panel": "No tens permís per accedir al panell", - "error.access.view": "No tens accés a aquesta part del tauler", - - "error.avatar.create.fail": "No s'ha pogut carregar la imatge del perfil", - "error.avatar.delete.fail": "La imatge del perfil no s'ha pogut eliminar", - "error.avatar.dimensions.invalid": "Mantingueu l'amplada i l'alçada de la imatge de perfil de menys de 3000 píxels", - "error.avatar.mime.forbidden": "La imatge del perfil ha de ser fitxers JPEG o PNG", - - "error.blueprint.notFound": "No s'ha potgut carregar el blueprint \"{name}\"", - - "error.blocks.max.plural": "You must not add more than {max} blocks", - "error.blocks.max.singular": "You must not add more than one block", - "error.blocks.min.plural": "You must add at least {min} blocks", - "error.blocks.min.singular": "You must add at least one block", - "error.blocks.validation": "There's an error in block {index}", - - "error.email.preset.notFound": "No es pot trobar la configuració de correu electrònic \"{name}\"", - - "error.field.converter.invalid": "Convertidor no vàlid \"{converter}\"", - - "error.file.changeName.empty": "El nom no pot estar buit", - "error.file.changeName.permission": "No tens permís per canviar el nom de \"{filename}\"", - "error.file.duplicate": "Ja existeix un fitxer amb el nom \"{filename}\"", - "error.file.extension.forbidden": "L'extensió de l'arxiu \"{extension}\" no està permesa", - "error.file.extension.invalid": "Invalid extension: {extension}", - "error.file.extension.missing": "Falta l'extensió de l'arxiu \"{filename}\"", - "error.file.maxheight": "L'alçada de la imatge no ha de ser superior a {height} píxels", - "error.file.maxsize": "El fitxer és massa gran", - "error.file.maxwidth": "L'amplada de la imatge no ha de ser superior a {width} píxels", - "error.file.mime.differs": "L'arxiu carregat ha ha de ser del mateix tipus de mime \"{mime}\"", - "error.file.mime.forbidden": "El tipus de mitjà \"{mime}\" no està permès", - "error.file.mime.invalid": "Mime type no vàlid: {mime}", - "error.file.mime.missing": "El tipus de suport per a \"{filename}\" no es pot detectar", - "error.file.minheight": "L'alçada de la imatge ha de ser com a mínim de {height} píxels", - "error.file.minsize": "El fitxer és massa petit", - "error.file.minwidth": "L'amplada de la imatge ha de ser com a mínim de {width} píxels", - "error.file.name.missing": "El nom del fitxer no pot estar buit", - "error.file.notFound": "L'arxiu \"{filename}\" no s'ha trobat", - "error.file.orientation": "L’orientació de la imatge ha de ser \"{orientation}\"", - "error.file.type.forbidden": "No tens permís per penjar fitxers {type}", - "error.file.type.invalid": "Invalid file type: {type}", - "error.file.undefined": "L'arxiu no s'ha trobat", - - "error.form.incomplete": "Si us plau, corregeix els errors del formulari ...", - "error.form.notSaved": "No s'ha pogut desar el formulari", - - "error.language.code": "Introdueix un codi vàlid per a l’idioma", - "error.language.duplicate": "L'idioma ja existeix", - "error.language.name": "Introdueix un nom vàlid per a l'idioma", - "error.language.notFound": "The language could not be found", - - "error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}", - "error.layout.validation.settings": "There's an error in layout {index} settings", - - "error.license.format": "Introduïu una clau de llicència vàlida", - "error.license.email": "Si us plau, introdueix una adreça de correu electrònic vàlida", - "error.license.verification": "No s’ha pogut verificar la llicència", - - "error.offline": "The Panel is currently offline", - - "error.page.changeSlug.permission": "No teniu permís per canviar l'apèndix d'URL per a \"{slug}\"", - "error.page.changeStatus.incomplete": "La pàgina té errors i no es pot publicar", - "error.page.changeStatus.permission": "No es pot canviar l'estat d'aquesta pàgina", - "error.page.changeStatus.toDraft.invalid": "La pàgina \"{slug}\" no es pot convertir en un esborrany", - "error.page.changeTemplate.invalid": "La plantilla per a la pàgina \"{slug}\" no es pot canviar", - "error.page.changeTemplate.permission": "No tens permís per canviar la plantilla per \"{slug}\"", - "error.page.changeTitle.empty": "El títol no pot estar buit", - "error.page.changeTitle.permission": "No tens permís per canviar el títol de \"{slug}\"", - "error.page.create.permission": "No tens permís per crear \"{slug}\"", - "error.page.delete": "La pàgina \"{slug}\" no es pot esborrar", - "error.page.delete.confirm": "Si us plau, introdueix el títol de la pàgina per confirmar", - "error.page.delete.hasChildren": "La pàgina té subpàgines i no es pot esborrar", - "error.page.delete.permission": "No tens permís per esborrar \"{slug}\"", - "error.page.draft.duplicate": "Ja existeix un esborrany de pàgina amb l'apèndix d'URL \"{slug}\"", - "error.page.duplicate": "Ja existeix una pàgina amb l'apèndix d'URL \"{slug}\"", - "error.page.duplicate.permission": "No tens permís per duplicar \"{slug}\"", - "error.page.notFound": "La pàgina \"{slug}\" no s'ha trobat", - "error.page.num.invalid": "Si us plau, introdueix un número d 'ordenació vàlid. Els números no poden ser negatius.", - "error.page.slug.invalid": "Please enter a valid URL appendix", - "error.page.slug.maxlength": "La longitud del nom ha de tenir menys de caràcters \"{length}\"", - "error.page.sort.permission": "La pàgina \"{slug}\" no es pot ordenar", - "error.page.status.invalid": "Si us plau, estableix un estat de pàgina vàlid", - "error.page.undefined": "La p\u00e0gina no s'ha trobat", - "error.page.update.permission": "No tens permís per actualitzar \"{slug}\"", - - "error.section.files.max.plural": "No has d'afegir més de {max} fitxers a la secció \"{section}\"", - "error.section.files.max.singular": "No podeu afegir més d'un fitxer a la secció \"{section}\"", - "error.section.files.min.plural": "La secció \"{section}\" requereix almenys {min} fitxer", - "error.section.files.min.singular": "La secció \"{section}\" requereix almenys un fitxer", - - "error.section.pages.max.plural": "No heu d'afegir més de {max} pàgines a la secció \"{section}\"", - "error.section.pages.max.singular": "No podeu afegir més d'una pàgina a la secció \"{section}\"", - "error.section.pages.min.plural": "La secció \"{section}\" requereix almenys {min} pàgines", - "error.section.pages.min.singular": "La secció \"{section}\" requereix almenys una pàgina", - - "error.section.notLoaded": "No s'ha pogut carregar la secció \"{name}\"", - "error.section.type.invalid": "La secció tipus \"{type}\" no és vàlida", - - "error.site.changeTitle.empty": "El títol no pot estar buit", - "error.site.changeTitle.permission": "No tens permís per canviar el títol del lloc web", - "error.site.update.permission": "No tens permís per actualitzar el lloc web", - - "error.template.default.notFound": "La plantilla predeterminada no existeix", - - "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "No tens permís per canviar el correu electrònic per a l'usuari \"{name}\"", - "error.user.changeLanguage.permission": "No tens permís per canviar l'idioma de l'usuari \"{name}\"", - "error.user.changeName.permission": "No tens permís per canviar el nom de l'usuari \"{name}\"", - "error.user.changePassword.permission": "No tens permís per canviar la contrasenya de l'usuari \"{name}\"", - "error.user.changeRole.lastAdmin": "El rol del darrer administrador no es pot canviar", - "error.user.changeRole.permission": "No tens permís per canviar el rol de l'usuari \"{name}\"", - "error.user.changeRole.toAdmin": "No tens permís per promocionar algú al rol d’administrador", - "error.user.create.permission": "No tens permís per crear aquest usuari", - "error.user.delete": "L'usuari \"{name}\" no es pot eliminar", - "error.user.delete.lastAdmin": "No es pot eliminar l'\u00faltim administrador", - "error.user.delete.lastUser": "El darrer usuari no es pot eliminar", - "error.user.delete.permission": "No pots eliminar l'usuari \"{name}\"", - "error.user.duplicate": "Ja existeix un usuari amb l'adreça electrònica \"{email}\"", - "error.user.email.invalid": "Si us plau, introdueix una adreça de correu electrònic vàlida", - "error.user.language.invalid": "Introduïu un idioma vàlid", - "error.user.notFound": "L'usuari \"{name}\" no s'ha trobat", - "error.user.password.invalid": "Introduïu una contrasenya vàlida. Les contrasenyes han de tenir com a mínim 8 caràcters.", - "error.user.password.notSame": "Les contrasenyes no coincideixen", - "error.user.password.undefined": "L'usuari no té una contrasenya", - "error.user.password.wrong": "Wrong password", - "error.user.role.invalid": "Si us plau, introdueix un rol vàlid", - "error.user.undefined": "L'usuari no s'ha trobat", - "error.user.update.permission": "No tens permís per actualitzar l'usuari \"{name}\"", - - "error.validation.accepted": "Si us plau confirma", - "error.validation.alpha": "Si us plau, introdueix únicament caràcters entre a-z", - "error.validation.alphanum": "Si us plau, introdueix únicament caràcters entre a-z o números de 0-9", - "error.validation.between": "Introdueix un valor entre \"{min}\" i \"{max}\"", - "error.validation.boolean": "Si us plau confirma o denega", - "error.validation.contains": "Si us plau, introduïu un valor que contingui \"{needle}\"", - "error.validation.date": "Si us plau, introdueix una data vàlida", - "error.validation.date.after": "Introdueix una data posterior {date}", - "error.validation.date.before": "Introdueix una data anterior {date}", - "error.validation.date.between": "Introdueix una data entre {min} i {max}", - "error.validation.denied": "Si us plau, denegui", - "error.validation.different": "El valor no ha de ser \"{other}\"", - "error.validation.email": "Si us plau, introdueix una adreça de correu electrònic vàlida", - "error.validation.endswith": "El valor ha de finalitzar amb \"{end}\"", - "error.validation.filename": "Si us plau, introdueix un nom de fitxer vàlid", - "error.validation.in": "Si us plau, introduïu una de les opcions següents: ({in})", - "error.validation.integer": "Si us plau, introduïu un nombre enter vàlid", - "error.validation.ip": "Si us plau, introduïu una adreça IP vàlida", - "error.validation.less": "Si us plau, introduïu un valor inferior a {max}", - "error.validation.match": "El valor no coincideix amb el patró esperat", - "error.validation.max": "Si us plau, introduïu un valor igual o inferior a {max}", - "error.validation.maxlength": "Si us plau, introduïu un valor més curt. (màxim {max} caràcters)", - "error.validation.maxwords": "Si us plau, introduïu no més de {max} paraula(es)", - "error.validation.min": "Si us plau, introduïu un valor igual o superior a {min}", - "error.validation.minlength": "Si us plau, introduïu un valor més llarg. (min. {min} caràcters)", - "error.validation.minwords": "Si us plau, introduïu almenys {min} paraula(es)", - "error.validation.more": "Si us plau, introduïu un valor més gran que {min}", - "error.validation.notcontains": "Introduïu un valor que no contingui \"{needle}\"", - "error.validation.notin": "Si us plau, no introduïu cap d'aquests elements: ({notIn})", - "error.validation.option": "Si us plau, seleccioneu una opció vàlida", - "error.validation.num": "Si us plau, introduïu un número vàlid", - "error.validation.required": "Si us plau, introduïu alguna cosa", - "error.validation.same": "Si us plau, introduïu \"{other}\"", - "error.validation.size": "La mida del valor ha de ser \"{size}\"", - "error.validation.startswith": "El valor ha de començar amb \"{start}\"", - "error.validation.time": "Si us plau, introduïu una hora vàlida", - "error.validation.time.after": "Please enter a time after {time}", - "error.validation.time.before": "Please enter a time before {time}", - "error.validation.time.between": "Please enter a time between {min} and {max}", - "error.validation.url": "Si us plau, introduïu una URL vàlida", - - "expand": "Expandir", - "expand.all": "Expandir tot", - - "field.required": "El camp és obligatori", - "field.blocks.changeType": "Change type", - "field.blocks.code.name": "Codi", - "field.blocks.code.language": "Idioma", - "field.blocks.code.placeholder": "Your code …", - "field.blocks.delete.confirm": "Do you really want to delete this block?", - "field.blocks.delete.confirm.all": "Do you really want to delete all blocks?", - "field.blocks.delete.confirm.selected": "Do you really want to delete the selected blocks?", - "field.blocks.empty": "No blocks yet", - "field.blocks.fieldsets.label": "Please select a block type …", - "field.blocks.fieldsets.paste": "Press {{ shortcut }} to paste/import blocks from your clipboard", - "field.blocks.gallery.name": "Gallery", - "field.blocks.gallery.images.empty": "No images yet", - "field.blocks.gallery.images.label": "Images", - "field.blocks.heading.level": "Level", - "field.blocks.heading.name": "Heading", - "field.blocks.heading.text": "Text", - "field.blocks.heading.placeholder": "Heading …", - "field.blocks.image.alt": "Alternative text", - "field.blocks.image.caption": "Caption", - "field.blocks.image.crop": "Crop", - "field.blocks.image.link": "Enllaç", - "field.blocks.image.location": "Location", - "field.blocks.image.name": "Imatge", - "field.blocks.image.placeholder": "Select an image", - "field.blocks.image.ratio": "Ratio", - "field.blocks.image.url": "Image URL", - "field.blocks.line.name": "Line", - "field.blocks.list.name": "List", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Text", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Quote", - "field.blocks.quote.text.label": "Text", - "field.blocks.quote.text.placeholder": "Quote …", - "field.blocks.quote.citation.label": "Citation", - "field.blocks.quote.citation.placeholder": "by …", - "field.blocks.text.name": "Text", - "field.blocks.text.placeholder": "Text …", - "field.blocks.video.caption": "Caption", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Enter a video URL", - "field.blocks.video.url.label": "Video-URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Encara no hi ha cap fitxer seleccionat", - - "field.layout.delete": "Delete layout", - "field.layout.delete.confirm": "Do you really want to delete this layout?", - "field.layout.empty": "No rows yet", - "field.layout.select": "Select a layout", - - "field.pages.empty": "Encara no s'ha seleccionat cap pàgina", - "field.structure.delete.confirm": "Segur que voleu eliminar aquesta fila?", - "field.structure.empty": "Encara no hi ha entrades.", - "field.users.empty": "Encara no s'ha seleccionat cap usuari", - - "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Esteu segurs d'eliminar
{filename}?", - "file.sort": "Change position", - - "files": "Arxius", - "files.empty": "Encara no hi ha fitxers", - - "hide": "Hide", - "hour": "Hora", - "import": "Import", - "info": "Info", - "insert": "Insertar", - "insert.after": "Insert after", - "insert.before": "Insert before", - "install": "Instal·lar", - - "installation": "Instal·lació", - "installation.completed": "S'ha instal·lat el panell", - "installation.disabled": "L'instal·lador del panell està desactivat per defecte als servidors públics. Si us plau, executeu l'instal·lador en una màquina local o habiliteu-lo amb l'opció panel.install", - "installation.issues.accounts": "La carpeta /site/accounts no existeix o no es pot escriure", - "installation.issues.content": "La carpeta /content no existeix o no es pot escriure", - "installation.issues.curl": "Es requereix l'extensió CURL", - "installation.issues.headline": "El panell no es pot instal·lar", - "installation.issues.mbstring": "Es requereix l'extensió de MB String", - "installation.issues.media": "La carpeta /media no existeix o no es pot escriure", - "installation.issues.php": "Assegureu-vos d'utilitzar PHP 7+", - "installation.issues.server": "Kirby requereix Apache, Nginx o Caddy", - "installation.issues.sessions": "La carpeta /site/sessions no existeix o no es pot escriure", - - "language": "Idioma", - "language.code": "Codi", - "language.convert": "Fer per defecte", - "language.convert.confirm": "

Segur que voleu convertir {name} a l'idioma predeterminat? Això no es pot desfer.

Si {name} té contingut no traduït, ja no podreu tornar enrere i algunes parts del vostre lloc poden quedar buides.

", - "language.create": "Afegir un nou idioma", - "language.delete.confirm": "Segur que voleu eliminar l'idioma {name} incloent totes les traduccions? Això no es pot desfer!", - "language.deleted": "S'ha suprimit l'idioma", - "language.direction": "Direcció de lectura", - "language.direction.ltr": "Esquerra a dreta", - "language.direction.rtl": "De dreta a esquerra", - "language.locale": "Cadena local de PHP", - "language.locale.warning": "S'està fent servir una configuració regional personalitzada. Modifica el fitxer d'idioma a /site/languages", - "language.name": "Nom", - "language.updated": "S'ha actualitzat l'idioma", - - "languages": "Idiomes", - "languages.default": "Idioma per defecte", - "languages.empty": "Encara no hi ha cap idioma", - "languages.secondary": "Idiomes secundaris", - "languages.secondary.empty": "Encara no hi ha idiomes secundaris", - - "license": "Llic\u00e8ncia Kirby", - "license.buy": "Comprar una llicència", - "license.register": "Registrar", - "license.manage": "Manage your licenses", - "license.register.help": "Heu rebut el codi de la vostra llicència després de la compra, per correu electrònic. Copieu-lo i enganxeu-lo per registrar-vos.", - "license.register.label": "Si us plau, introdueixi el seu codi de llicència", - "license.register.success": "Gràcies per donar suport a Kirby", - "license.unregistered": "Aquesta és una demo no registrada de Kirby", - "license.unregistered.label": "Unregistered", - - "link": "Enlla\u00e7", - "link.text": "Enllaç de text", - - "loading": "Carregant", - - "lock.unsaved": "Canvis no guardats", - "lock.unsaved.empty": "Ja no hi ha canvis no guardats", - "lock.isLocked": "Canvis no guardats per {email}", - "lock.file.isLocked": "El fitxer està sent editat actualment per {email} i no pot ser modificat.", - "lock.page.isLocked": "La pàgina està sent editat actualment per {email} i no pot ser modificat.", - "lock.unlock": "Desbloquejar", - "lock.isUnlocked": "Els teus canvis sense guardar han estat sobreescrits per a un altra usuario. Pots descarregar els teus canvis per combinar-los manualment.", - - "login": "Entrar", - "login.code.label.login": "Login code", - "login.code.label.password-reset": "Password reset code", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "If your email address is registered, the requested code was sent via email.", - "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.login.subject": "Your login code", - "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.password-reset.subject": "Your password reset code", - "login.remember": "Manten-me connectat", - "login.reset": "Reset password", - "login.toggleText.code.email": "Login via email", - "login.toggleText.code.email-password": "Login with password", - "login.toggleText.password-reset.email": "Forgot your password?", - "login.toggleText.password-reset.email-password": "← Back to login", - - "logout": "Tancar sessi\u00f3", - - "menu": "Menú", - "meridiem": "AM/PM", - "mime": "Tipus de mitjà", - "minutes": "Minuts", - - "month": "Mes", - "months.april": "Abril", - "months.august": "Agost", - "months.december": "Desembre", - "months.february": "Febrer", - "months.january": "Gener", - "months.july": "Juliol", - "months.june": "Juny", - "months.march": "Mar\u00e7", - "months.may": "Maig", - "months.november": "Novembre", - "months.october": "Octubre", - "months.september": "Setembre", - - "more": "Més", - "name": "Nom", - "next": "Següent", - "no": "no", - "off": "apagat", - "on": "encès", - "open": "Obrir", - "open.newWindow": "Open in new window", - "options": "Opcions", - "options.none": "Sense opcions", - - "orientation": "Orientació", - "orientation.landscape": "Horitzontal", - "orientation.portrait": "Vertical", - "orientation.square": "Quadrat", - - "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Canviar URL", - "page.changeSlug.fromTitle": "Crear a partir del t\u00edtol", - "page.changeStatus": "Canviar l'estat", - "page.changeStatus.position": "Si us plau, seleccioneu una posició", - "page.changeStatus.select": "Seleccioneu un nou estat", - "page.changeTemplate": "Canviar la plantilla", - "page.delete.confirm": "Segur que voleu eliminar {title}?", - "page.delete.confirm.subpages": "Aquesta pàgina té subpàgines.
Totes les subpàgines també s'eliminaran.", - "page.delete.confirm.title": "Introduïu el títol de la pàgina per confirmar", - "page.draft.create": "Crear un esborrany", - "page.duplicate.appendix": "Copiar", - "page.duplicate.files": "Copiar fitxers", - "page.duplicate.pages": "Copiar pàgines", - "page.sort": "Change position", - "page.status": "Estat", - "page.status.draft": "Esborrany", - "page.status.draft.description": "La pàgina està en mode d'esborrany i només és visible per als editors registrats o a través d'un enllaç secret", - "page.status.listed": "Públic", - "page.status.listed.description": "La pàgina és pública per a tothom", - "page.status.unlisted": "Sense classificar", - "page.status.unlisted.description": "La pàgina només es pot accedir a través de l'URL", - - "pages": "Pàgines", - "pages.empty": "Encara no hi ha pàgines", - "pages.status.draft": "Esborranys", - "pages.status.listed": "Publicat", - "pages.status.unlisted": "Sense classificar", - - "pagination.page": "Pàgina", - - "password": "Contrasenya", - "paste": "Paste", - "paste.after": "Paste after", - "pixel": "Pixel", - "plugins": "Plugins", - "prev": "Anterior", - "preview": "Preview", - "remove": "Eliminar", - "rename": "Canviar el nom", - "replace": "Reempla\u00e7ar", - "retry": "Reintentar", - "revert": "Revertir", - "revert.confirm": "Segur que voleu eliminar tots els canvis pendents desar?", - - "role": "Rol", - "role.admin.description": "L’administrador té tots els permisos", - "role.admin.title": "Administrador", - "role.all": "Tots", - "role.empty": "No hi ha usuaris amb aquest rol", - "role.description.placeholder": "Sense descripció", - "role.nobody.description": "Aquest és un rol per defecte sense permisos", - "role.nobody.title": "Ningú", - - "save": "Desar", - "search": "Cercar", - "search.min": "Introduïu {min} caràcters per cercar", - "search.all": "Mostrar tots", - "search.results.none": "Sense resultats", - - "section.required": "La secció és obligatòria", - - "security": "Security", - "select": "Seleccionar", - "server": "Server", - "settings": "Configuració", - "show": "Show", - "site.blueprint": "The site has no blueprint yet. You can define the setup in /site/blueprints/site.yml", - "size": "Tamany", - "slug": "URL-ap\u00e8ndix", - "sort": "Ordenar", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Títol", - "template": "Plantilla", - "today": "Avui", - - "toolbar.button.code": "Codi", - "toolbar.button.bold": "Negreta", - "toolbar.button.email": "Email", - "toolbar.button.headings": "Encapçalaments", - "toolbar.button.heading.1": "Encapçalament 1", - "toolbar.button.heading.2": "Encapçalament 2", - "toolbar.button.heading.3": "Encapçalament 3", - "toolbar.button.heading.4": "Heading 4", - "toolbar.button.heading.5": "Heading 5", - "toolbar.button.heading.6": "Heading 6", - "toolbar.button.italic": "Cursiva", - "toolbar.button.file": "Arxiu", - "toolbar.button.file.select": "Selecciona un fitxer", - "toolbar.button.file.upload": "Carrega un fitxer", - "toolbar.button.link": "Enlla\u00e7", - "toolbar.button.paragraph": "Paragraph", - "toolbar.button.strike": "Strike-through", - "toolbar.button.ol": "Llista ordenada", - "toolbar.button.underline": "Underline", - "toolbar.button.ul": "Llista de vinyetes", - - "translation.author": "Equip Kirby", - "translation.direction": "ltr", - "translation.name": "Catalan", - "translation.locale": "ca_ES", - - "upload": "Carregar", - "upload.error.cantMove": "El fitxer carregat no s'ha pogut moure", - "upload.error.cantWrite": "No s'ha pogut escriure el fitxer al disc", - "upload.error.default": "No s'ha pogut carregar el fitxer", - "upload.error.extension": "La càrrega del fitxer s'ha aturat per l'extensió", - "upload.error.formSize": "El fitxer carregat supera la directiva MAX_FILE_SIZE especificada en el formulari", - "upload.error.iniPostSize": "El fitxer carregat supera la directiva post_max_size especifiada al php.ini", - "upload.error.iniSize": "El fitxer carregat supera la directiva upload_max_filesize especifiada al php.ini", - "upload.error.noFile": "No s'ha carregat cap fitxer", - "upload.error.noFiles": "No s'ha penjat cap fitxer", - "upload.error.partial": "El fitxer carregat només s'ha carregat parcialment", - "upload.error.tmpDir": "Falta una carpeta temporal", - "upload.errors": "Error", - "upload.progress": "Carregant...", - - "url": "Url", - "url.placeholder": "https://example.com", - - "user": "Usuari", - "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Canviar e-mail", - "user.changeLanguage": "Canviar idioma", - "user.changeName": "Canviar el nom d'aquest usuari", - "user.changePassword": "Canviar contrasenya", - "user.changePassword.new": "Nova contrasenya", - "user.changePassword.new.confirm": "Confirma la nova contrasenya ...", - "user.changeRole": "Canviar el rol", - "user.changeRole.select": "Seleccionar un nou rol", - "user.create": "Afegir un nou usuari", - "user.delete": "Eliminar aquest usuari", - "user.delete.confirm": "Segur que voleu eliminar
{email}?", - - "users": "Usuaris", - - "version": "Versi\u00f3 de Kirby", - - "view.account": "La teva compta", - "view.installation": "Instal·lació", - "view.languages": "Idiomes", - "view.resetPassword": "Reset password", - "view.site": "Lloc web", - "view.system": "System", - "view.users": "Usuaris", - - "welcome": "Benvinguda", - "year": "Any", - "yes": "yes" + "account.changeName": "Change your name", + "account.delete": "Delete your account", + "account.delete.confirm": "Do you really want to delete your account? You will be logged out immediately. Your account cannot be recovered.", + + "add": "Afegir", + "author": "Author", + "avatar": "Imatge del perfil", + "back": "Tornar", + "cancel": "Cancel\u00b7lar", + "change": "Canviar", + "close": "Tancar", + "confirm": "Ok", + "collapse": "Col·lapsar", + "collapse.all": "Col·lapsar tot", + "copy": "Copiar", + "copy.all": "Copy all", + "create": "Crear", + + "date": "Data", + "date.select": "Selecciona una data", + + "day": "Dia", + "days.fri": "dv.", + "days.mon": "dl.", + "days.sat": "ds.", + "days.sun": "dg.", + "days.thu": "dj.", + "days.tue": "dt.", + "days.wed": "dc.", + + "debugging": "Debugging", + + "delete": "Eliminar", + "delete.all": "Eliminar tot", + + "dialog.files.empty": "No hi ha cap fitxer per seleccionar", + "dialog.pages.empty": "No hi ha cap pàgina per seleccionar", + "dialog.users.empty": "No hi ha cap usuari per seleccionar", + + "dimensions": "Dimensions", + "disabled": "Desactivat", + "discard": "Descartar", + "download": "Descarregar", + "duplicate": "Duplicar", + + "edit": "Editar", + + "email": "Email", + "email.placeholder": "mail@exemple.com", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Environment", + + "error.access.code": "Codi invàlid", + "error.access.login": "Inici de sessió no vàlid", + "error.access.panel": "No tens permís per accedir al panell", + "error.access.view": "No tens accés a aquesta part del tauler", + + "error.avatar.create.fail": "No s'ha pogut carregar la imatge del perfil", + "error.avatar.delete.fail": "La imatge del perfil no s'ha pogut eliminar", + "error.avatar.dimensions.invalid": "Mantingueu l'amplada i l'alçada de la imatge de perfil de menys de 3000 píxels", + "error.avatar.mime.forbidden": "La imatge del perfil ha de ser fitxers JPEG o PNG", + + "error.blueprint.notFound": "No s'ha potgut carregar el blueprint \"{name}\"", + + "error.blocks.max.plural": "You must not add more than {max} blocks", + "error.blocks.max.singular": "You must not add more than one block", + "error.blocks.min.plural": "You must add at least {min} blocks", + "error.blocks.min.singular": "You must add at least one block", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "No es pot trobar la configuració de correu electrònic \"{name}\"", + + "error.field.converter.invalid": "Convertidor no vàlid \"{converter}\"", + + "error.file.changeName.empty": "El nom no pot estar buit", + "error.file.changeName.permission": "No tens permís per canviar el nom de \"{filename}\"", + "error.file.duplicate": "Ja existeix un fitxer amb el nom \"{filename}\"", + "error.file.extension.forbidden": "L'extensió de l'arxiu \"{extension}\" no està permesa", + "error.file.extension.invalid": "Invalid extension: {extension}", + "error.file.extension.missing": "Falta l'extensió de l'arxiu \"{filename}\"", + "error.file.maxheight": "L'alçada de la imatge no ha de ser superior a {height} píxels", + "error.file.maxsize": "El fitxer és massa gran", + "error.file.maxwidth": "L'amplada de la imatge no ha de ser superior a {width} píxels", + "error.file.mime.differs": "L'arxiu carregat ha ha de ser del mateix tipus de mime \"{mime}\"", + "error.file.mime.forbidden": "El tipus de mitjà \"{mime}\" no està permès", + "error.file.mime.invalid": "Mime type no vàlid: {mime}", + "error.file.mime.missing": "El tipus de suport per a \"{filename}\" no es pot detectar", + "error.file.minheight": "L'alçada de la imatge ha de ser com a mínim de {height} píxels", + "error.file.minsize": "El fitxer és massa petit", + "error.file.minwidth": "L'amplada de la imatge ha de ser com a mínim de {width} píxels", + "error.file.name.missing": "El nom del fitxer no pot estar buit", + "error.file.notFound": "L'arxiu \"{filename}\" no s'ha trobat", + "error.file.orientation": "L’orientació de la imatge ha de ser \"{orientation}\"", + "error.file.type.forbidden": "No tens permís per penjar fitxers {type}", + "error.file.type.invalid": "Invalid file type: {type}", + "error.file.undefined": "L'arxiu no s'ha trobat", + + "error.form.incomplete": "Si us plau, corregeix els errors del formulari ...", + "error.form.notSaved": "No s'ha pogut desar el formulari", + + "error.language.code": "Introdueix un codi vàlid per a l’idioma", + "error.language.duplicate": "L'idioma ja existeix", + "error.language.name": "Introdueix un nom vàlid per a l'idioma", + "error.language.notFound": "The language could not be found", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "There's an error in layout {index} settings", + + "error.license.format": "Introduïu una clau de llicència vàlida", + "error.license.email": "Si us plau, introdueix una adreça de correu electrònic vàlida", + "error.license.verification": "No s’ha pogut verificar la llicència", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "The Panel is currently offline", + + "error.page.changeSlug.permission": "No teniu permís per canviar l'apèndix d'URL per a \"{slug}\"", + "error.page.changeStatus.incomplete": "La pàgina té errors i no es pot publicar", + "error.page.changeStatus.permission": "No es pot canviar l'estat d'aquesta pàgina", + "error.page.changeStatus.toDraft.invalid": "La pàgina \"{slug}\" no es pot convertir en un esborrany", + "error.page.changeTemplate.invalid": "La plantilla per a la pàgina \"{slug}\" no es pot canviar", + "error.page.changeTemplate.permission": "No tens permís per canviar la plantilla per \"{slug}\"", + "error.page.changeTitle.empty": "El títol no pot estar buit", + "error.page.changeTitle.permission": "No tens permís per canviar el títol de \"{slug}\"", + "error.page.create.permission": "No tens permís per crear \"{slug}\"", + "error.page.delete": "La pàgina \"{slug}\" no es pot esborrar", + "error.page.delete.confirm": "Si us plau, introdueix el títol de la pàgina per confirmar", + "error.page.delete.hasChildren": "La pàgina té subpàgines i no es pot esborrar", + "error.page.delete.permission": "No tens permís per esborrar \"{slug}\"", + "error.page.draft.duplicate": "Ja existeix un esborrany de pàgina amb l'apèndix d'URL \"{slug}\"", + "error.page.duplicate": "Ja existeix una pàgina amb l'apèndix d'URL \"{slug}\"", + "error.page.duplicate.permission": "No tens permís per duplicar \"{slug}\"", + "error.page.notFound": "La pàgina \"{slug}\" no s'ha trobat", + "error.page.num.invalid": "Si us plau, introdueix un número d 'ordenació vàlid. Els números no poden ser negatius.", + "error.page.slug.invalid": "Please enter a valid URL appendix", + "error.page.slug.maxlength": "La longitud del nom ha de tenir menys de caràcters \"{length}\"", + "error.page.sort.permission": "La pàgina \"{slug}\" no es pot ordenar", + "error.page.status.invalid": "Si us plau, estableix un estat de pàgina vàlid", + "error.page.undefined": "La p\u00e0gina no s'ha trobat", + "error.page.update.permission": "No tens permís per actualitzar \"{slug}\"", + + "error.section.files.max.plural": "No has d'afegir més de {max} fitxers a la secció \"{section}\"", + "error.section.files.max.singular": "No podeu afegir més d'un fitxer a la secció \"{section}\"", + "error.section.files.min.plural": "La secció \"{section}\" requereix almenys {min} fitxer", + "error.section.files.min.singular": "La secció \"{section}\" requereix almenys un fitxer", + + "error.section.pages.max.plural": "No heu d'afegir més de {max} pàgines a la secció \"{section}\"", + "error.section.pages.max.singular": "No podeu afegir més d'una pàgina a la secció \"{section}\"", + "error.section.pages.min.plural": "La secció \"{section}\" requereix almenys {min} pàgines", + "error.section.pages.min.singular": "La secció \"{section}\" requereix almenys una pàgina", + + "error.section.notLoaded": "No s'ha pogut carregar la secció \"{name}\"", + "error.section.type.invalid": "La secció tipus \"{type}\" no és vàlida", + + "error.site.changeTitle.empty": "El títol no pot estar buit", + "error.site.changeTitle.permission": "No tens permís per canviar el títol del lloc web", + "error.site.update.permission": "No tens permís per actualitzar el lloc web", + + "error.template.default.notFound": "La plantilla predeterminada no existeix", + + "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "No tens permís per canviar el correu electrònic per a l'usuari \"{name}\"", + "error.user.changeLanguage.permission": "No tens permís per canviar l'idioma de l'usuari \"{name}\"", + "error.user.changeName.permission": "No tens permís per canviar el nom de l'usuari \"{name}\"", + "error.user.changePassword.permission": "No tens permís per canviar la contrasenya de l'usuari \"{name}\"", + "error.user.changeRole.lastAdmin": "El rol del darrer administrador no es pot canviar", + "error.user.changeRole.permission": "No tens permís per canviar el rol de l'usuari \"{name}\"", + "error.user.changeRole.toAdmin": "No tens permís per promocionar algú al rol d’administrador", + "error.user.create.permission": "No tens permís per crear aquest usuari", + "error.user.delete": "L'usuari \"{name}\" no es pot eliminar", + "error.user.delete.lastAdmin": "No es pot eliminar l'\u00faltim administrador", + "error.user.delete.lastUser": "El darrer usuari no es pot eliminar", + "error.user.delete.permission": "No pots eliminar l'usuari \"{name}\"", + "error.user.duplicate": "Ja existeix un usuari amb l'adreça electrònica \"{email}\"", + "error.user.email.invalid": "Si us plau, introdueix una adreça de correu electrònic vàlida", + "error.user.language.invalid": "Introduïu un idioma vàlid", + "error.user.notFound": "L'usuari \"{name}\" no s'ha trobat", + "error.user.password.invalid": "Introduïu una contrasenya vàlida. Les contrasenyes han de tenir com a mínim 8 caràcters.", + "error.user.password.notSame": "Les contrasenyes no coincideixen", + "error.user.password.undefined": "L'usuari no té una contrasenya", + "error.user.password.wrong": "Wrong password", + "error.user.role.invalid": "Si us plau, introdueix un rol vàlid", + "error.user.undefined": "L'usuari no s'ha trobat", + "error.user.update.permission": "No tens permís per actualitzar l'usuari \"{name}\"", + + "error.validation.accepted": "Si us plau confirma", + "error.validation.alpha": "Si us plau, introdueix únicament caràcters entre a-z", + "error.validation.alphanum": "Si us plau, introdueix únicament caràcters entre a-z o números de 0-9", + "error.validation.between": "Introdueix un valor entre \"{min}\" i \"{max}\"", + "error.validation.boolean": "Si us plau confirma o denega", + "error.validation.contains": "Si us plau, introduïu un valor que contingui \"{needle}\"", + "error.validation.date": "Si us plau, introdueix una data vàlida", + "error.validation.date.after": "Introdueix una data posterior {date}", + "error.validation.date.before": "Introdueix una data anterior {date}", + "error.validation.date.between": "Introdueix una data entre {min} i {max}", + "error.validation.denied": "Si us plau, denegui", + "error.validation.different": "El valor no ha de ser \"{other}\"", + "error.validation.email": "Si us plau, introdueix una adreça de correu electrònic vàlida", + "error.validation.endswith": "El valor ha de finalitzar amb \"{end}\"", + "error.validation.filename": "Si us plau, introdueix un nom de fitxer vàlid", + "error.validation.in": "Si us plau, introduïu una de les opcions següents: ({in})", + "error.validation.integer": "Si us plau, introduïu un nombre enter vàlid", + "error.validation.ip": "Si us plau, introduïu una adreça IP vàlida", + "error.validation.less": "Si us plau, introduïu un valor inferior a {max}", + "error.validation.match": "El valor no coincideix amb el patró esperat", + "error.validation.max": "Si us plau, introduïu un valor igual o inferior a {max}", + "error.validation.maxlength": "Si us plau, introduïu un valor més curt. (màxim {max} caràcters)", + "error.validation.maxwords": "Si us plau, introduïu no més de {max} paraula(es)", + "error.validation.min": "Si us plau, introduïu un valor igual o superior a {min}", + "error.validation.minlength": "Si us plau, introduïu un valor més llarg. (min. {min} caràcters)", + "error.validation.minwords": "Si us plau, introduïu almenys {min} paraula(es)", + "error.validation.more": "Si us plau, introduïu un valor més gran que {min}", + "error.validation.notcontains": "Introduïu un valor que no contingui \"{needle}\"", + "error.validation.notin": "Si us plau, no introduïu cap d'aquests elements: ({notIn})", + "error.validation.option": "Si us plau, seleccioneu una opció vàlida", + "error.validation.num": "Si us plau, introduïu un número vàlid", + "error.validation.required": "Si us plau, introduïu alguna cosa", + "error.validation.same": "Si us plau, introduïu \"{other}\"", + "error.validation.size": "La mida del valor ha de ser \"{size}\"", + "error.validation.startswith": "El valor ha de començar amb \"{start}\"", + "error.validation.time": "Si us plau, introduïu una hora vàlida", + "error.validation.time.after": "Please enter a time after {time}", + "error.validation.time.before": "Please enter a time before {time}", + "error.validation.time.between": "Please enter a time between {min} and {max}", + "error.validation.url": "Si us plau, introduïu una URL vàlida", + + "expand": "Expandir", + "expand.all": "Expandir tot", + + "field.required": "El camp és obligatori", + "field.blocks.changeType": "Change type", + "field.blocks.code.name": "Codi", + "field.blocks.code.language": "Idioma", + "field.blocks.code.placeholder": "Your code …", + "field.blocks.delete.confirm": "Do you really want to delete this block?", + "field.blocks.delete.confirm.all": "Do you really want to delete all blocks?", + "field.blocks.delete.confirm.selected": "Do you really want to delete the selected blocks?", + "field.blocks.empty": "No blocks yet", + "field.blocks.fieldsets.label": "Please select a block type …", + "field.blocks.fieldsets.paste": "Press {{ shortcut }} to paste/import blocks from your clipboard", + "field.blocks.gallery.name": "Gallery", + "field.blocks.gallery.images.empty": "No images yet", + "field.blocks.gallery.images.label": "Images", + "field.blocks.heading.level": "Level", + "field.blocks.heading.name": "Heading", + "field.blocks.heading.text": "Text", + "field.blocks.heading.placeholder": "Heading …", + "field.blocks.image.alt": "Alternative text", + "field.blocks.image.caption": "Caption", + "field.blocks.image.crop": "Crop", + "field.blocks.image.link": "Enllaç", + "field.blocks.image.location": "Location", + "field.blocks.image.name": "Imatge", + "field.blocks.image.placeholder": "Select an image", + "field.blocks.image.ratio": "Ratio", + "field.blocks.image.url": "Image URL", + "field.blocks.line.name": "Line", + "field.blocks.list.name": "List", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Text", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Quote", + "field.blocks.quote.text.label": "Text", + "field.blocks.quote.text.placeholder": "Quote …", + "field.blocks.quote.citation.label": "Citation", + "field.blocks.quote.citation.placeholder": "by …", + "field.blocks.text.name": "Text", + "field.blocks.text.placeholder": "Text …", + "field.blocks.video.caption": "Caption", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Enter a video URL", + "field.blocks.video.url.label": "Video-URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Encara no hi ha cap fitxer seleccionat", + + "field.layout.delete": "Delete layout", + "field.layout.delete.confirm": "Do you really want to delete this layout?", + "field.layout.empty": "No rows yet", + "field.layout.select": "Select a layout", + + "field.object.empty": "No information yet", + + "field.pages.empty": "Encara no s'ha seleccionat cap pàgina", + + "field.structure.delete.confirm": "Segur que voleu eliminar aquesta fila?", + "field.structure.empty": "Encara no hi ha entrades.", + + "field.users.empty": "Encara no s'ha seleccionat cap usuari", + + "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Esteu segurs d'eliminar
{filename}?", + "file.sort": "Change position", + + "files": "Arxius", + "files.empty": "Encara no hi ha fitxers", + + "hide": "Hide", + "hour": "Hora", + "import": "Import", + "info": "Info", + "insert": "Insertar", + "insert.after": "Insert after", + "insert.before": "Insert before", + "install": "Instal·lar", + + "installation": "Instal·lació", + "installation.completed": "S'ha instal·lat el panell", + "installation.disabled": "L'instal·lador del panell està desactivat per defecte als servidors públics. Si us plau, executeu l'instal·lador en una màquina local o habiliteu-lo amb l'opció panel.install", + "installation.issues.accounts": "La carpeta /site/accounts no existeix o no es pot escriure", + "installation.issues.content": "La carpeta /content no existeix o no es pot escriure", + "installation.issues.curl": "Es requereix l'extensió CURL", + "installation.issues.headline": "El panell no es pot instal·lar", + "installation.issues.mbstring": "Es requereix l'extensió de MB String", + "installation.issues.media": "La carpeta /media no existeix o no es pot escriure", + "installation.issues.php": "Assegureu-vos d'utilitzar PHP 7+", + "installation.issues.server": "Kirby requereix Apache, Nginx o Caddy", + "installation.issues.sessions": "La carpeta /site/sessions no existeix o no es pot escriure", + + "language": "Idioma", + "language.code": "Codi", + "language.convert": "Fer per defecte", + "language.convert.confirm": "

Segur que voleu convertir {name} a l'idioma predeterminat? Això no es pot desfer.

Si {name} té contingut no traduït, ja no podreu tornar enrere i algunes parts del vostre lloc poden quedar buides.

", + "language.create": "Afegir un nou idioma", + "language.delete.confirm": "Segur que voleu eliminar l'idioma {name} incloent totes les traduccions? Això no es pot desfer!", + "language.deleted": "S'ha suprimit l'idioma", + "language.direction": "Direcció de lectura", + "language.direction.ltr": "Esquerra a dreta", + "language.direction.rtl": "De dreta a esquerra", + "language.locale": "Cadena local de PHP", + "language.locale.warning": "S'està fent servir una configuració regional personalitzada. Modifica el fitxer d'idioma a /site/languages", + "language.name": "Nom", + "language.updated": "S'ha actualitzat l'idioma", + + "languages": "Idiomes", + "languages.default": "Idioma per defecte", + "languages.empty": "Encara no hi ha cap idioma", + "languages.secondary": "Idiomes secundaris", + "languages.secondary.empty": "Encara no hi ha idiomes secundaris", + + "license": "Llic\u00e8ncia Kirby", + "license.buy": "Comprar una llicència", + "license.register": "Registrar", + "license.manage": "Manage your licenses", + "license.register.help": "Heu rebut el codi de la vostra llicència després de la compra, per correu electrònic. Copieu-lo i enganxeu-lo per registrar-vos.", + "license.register.label": "Si us plau, introdueixi el seu codi de llicència", + "license.register.success": "Gràcies per donar suport a Kirby", + "license.unregistered": "Aquesta és una demo no registrada de Kirby", + "license.unregistered.label": "Unregistered", + + "link": "Enlla\u00e7", + "link.text": "Enllaç de text", + + "loading": "Carregant", + + "lock.unsaved": "Canvis no guardats", + "lock.unsaved.empty": "Ja no hi ha canvis no guardats", + "lock.isLocked": "Canvis no guardats per {email}", + "lock.file.isLocked": "El fitxer està sent editat actualment per {email} i no pot ser modificat.", + "lock.page.isLocked": "La pàgina està sent editat actualment per {email} i no pot ser modificat.", + "lock.unlock": "Desbloquejar", + "lock.isUnlocked": "Els teus canvis sense guardar han estat sobreescrits per a un altra usuario. Pots descarregar els teus canvis per combinar-los manualment.", + + "login": "Entrar", + "login.code.label.login": "Login code", + "login.code.label.password-reset": "Password reset code", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "If your email address is registered, the requested code was sent via email.", + "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.login.subject": "Your login code", + "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.password-reset.subject": "Your password reset code", + "login.remember": "Manten-me connectat", + "login.reset": "Reset password", + "login.toggleText.code.email": "Login via email", + "login.toggleText.code.email-password": "Login with password", + "login.toggleText.password-reset.email": "Forgot your password?", + "login.toggleText.password-reset.email-password": "← Back to login", + + "logout": "Tancar sessi\u00f3", + + "menu": "Menú", + "meridiem": "AM/PM", + "mime": "Tipus de mitjà", + "minutes": "Minuts", + + "month": "Mes", + "months.april": "Abril", + "months.august": "Agost", + "months.december": "Desembre", + "months.february": "Febrer", + "months.january": "Gener", + "months.july": "Juliol", + "months.june": "Juny", + "months.march": "Mar\u00e7", + "months.may": "Maig", + "months.november": "Novembre", + "months.october": "Octubre", + "months.september": "Setembre", + + "more": "Més", + "name": "Nom", + "next": "Següent", + "no": "no", + "off": "apagat", + "on": "encès", + "open": "Obrir", + "open.newWindow": "Open in new window", + "options": "Opcions", + "options.none": "Sense opcions", + + "orientation": "Orientació", + "orientation.landscape": "Horitzontal", + "orientation.portrait": "Vertical", + "orientation.square": "Quadrat", + + "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Canviar URL", + "page.changeSlug.fromTitle": "Crear a partir del t\u00edtol", + "page.changeStatus": "Canviar l'estat", + "page.changeStatus.position": "Si us plau, seleccioneu una posició", + "page.changeStatus.select": "Seleccioneu un nou estat", + "page.changeTemplate": "Canviar la plantilla", + "page.delete.confirm": "Segur que voleu eliminar {title}?", + "page.delete.confirm.subpages": "Aquesta pàgina té subpàgines.
Totes les subpàgines també s'eliminaran.", + "page.delete.confirm.title": "Introduïu el títol de la pàgina per confirmar", + "page.draft.create": "Crear un esborrany", + "page.duplicate.appendix": "Copiar", + "page.duplicate.files": "Copiar fitxers", + "page.duplicate.pages": "Copiar pàgines", + "page.sort": "Change position", + "page.status": "Estat", + "page.status.draft": "Esborrany", + "page.status.draft.description": "La pàgina està en mode d'esborrany i només és visible per als editors registrats o a través d'un enllaç secret", + "page.status.listed": "Públic", + "page.status.listed.description": "La pàgina és pública per a tothom", + "page.status.unlisted": "Sense classificar", + "page.status.unlisted.description": "La pàgina només es pot accedir a través de l'URL", + + "pages": "Pàgines", + "pages.empty": "Encara no hi ha pàgines", + "pages.status.draft": "Esborranys", + "pages.status.listed": "Publicat", + "pages.status.unlisted": "Sense classificar", + + "pagination.page": "Pàgina", + + "password": "Contrasenya", + "paste": "Paste", + "paste.after": "Paste after", + "pixel": "Pixel", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "Anterior", + "preview": "Preview", + "remove": "Eliminar", + "rename": "Canviar el nom", + "replace": "Reempla\u00e7ar", + "retry": "Reintentar", + "revert": "Revertir", + "revert.confirm": "Segur que voleu eliminar tots els canvis pendents desar?", + + "role": "Rol", + "role.admin.description": "L’administrador té tots els permisos", + "role.admin.title": "Administrador", + "role.all": "Tots", + "role.empty": "No hi ha usuaris amb aquest rol", + "role.description.placeholder": "Sense descripció", + "role.nobody.description": "Aquest és un rol per defecte sense permisos", + "role.nobody.title": "Ningú", + + "save": "Desar", + "search": "Cercar", + "search.min": "Introduïu {min} caràcters per cercar", + "search.all": "Mostrar tots", + "search.results.none": "Sense resultats", + + "section.required": "La secció és obligatòria", + + "security": "Security", + "select": "Seleccionar", + "server": "Server", + "settings": "Configuració", + "show": "Show", + "site.blueprint": "The site has no blueprint yet. You can define the setup in /site/blueprints/site.yml", + "size": "Tamany", + "slug": "URL-ap\u00e8ndix", + "sort": "Ordenar", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Títol", + "template": "Plantilla", + "today": "Avui", + + "toolbar.button.code": "Codi", + "toolbar.button.bold": "Negreta", + "toolbar.button.email": "Email", + "toolbar.button.headings": "Encapçalaments", + "toolbar.button.heading.1": "Encapçalament 1", + "toolbar.button.heading.2": "Encapçalament 2", + "toolbar.button.heading.3": "Encapçalament 3", + "toolbar.button.heading.4": "Heading 4", + "toolbar.button.heading.5": "Heading 5", + "toolbar.button.heading.6": "Heading 6", + "toolbar.button.italic": "Cursiva", + "toolbar.button.file": "Arxiu", + "toolbar.button.file.select": "Selecciona un fitxer", + "toolbar.button.file.upload": "Carrega un fitxer", + "toolbar.button.link": "Enlla\u00e7", + "toolbar.button.paragraph": "Paragraph", + "toolbar.button.strike": "Strike-through", + "toolbar.button.ol": "Llista ordenada", + "toolbar.button.underline": "Underline", + "toolbar.button.ul": "Llista de vinyetes", + + "translation.author": "Equip Kirby", + "translation.direction": "ltr", + "translation.name": "Catalan", + "translation.locale": "ca_ES", + + "upload": "Carregar", + "upload.error.cantMove": "El fitxer carregat no s'ha pogut moure", + "upload.error.cantWrite": "No s'ha pogut escriure el fitxer al disc", + "upload.error.default": "No s'ha pogut carregar el fitxer", + "upload.error.extension": "La càrrega del fitxer s'ha aturat per l'extensió", + "upload.error.formSize": "El fitxer carregat supera la directiva MAX_FILE_SIZE especificada en el formulari", + "upload.error.iniPostSize": "El fitxer carregat supera la directiva post_max_size especifiada al php.ini", + "upload.error.iniSize": "El fitxer carregat supera la directiva upload_max_filesize especifiada al php.ini", + "upload.error.noFile": "No s'ha carregat cap fitxer", + "upload.error.noFiles": "No s'ha penjat cap fitxer", + "upload.error.partial": "El fitxer carregat només s'ha carregat parcialment", + "upload.error.tmpDir": "Falta una carpeta temporal", + "upload.errors": "Error", + "upload.progress": "Carregant...", + + "url": "Url", + "url.placeholder": "https://example.com", + + "user": "Usuari", + "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Canviar e-mail", + "user.changeLanguage": "Canviar idioma", + "user.changeName": "Canviar el nom d'aquest usuari", + "user.changePassword": "Canviar contrasenya", + "user.changePassword.new": "Nova contrasenya", + "user.changePassword.new.confirm": "Confirma la nova contrasenya ...", + "user.changeRole": "Canviar el rol", + "user.changeRole.select": "Seleccionar un nou rol", + "user.create": "Afegir un nou usuari", + "user.delete": "Eliminar aquest usuari", + "user.delete.confirm": "Segur que voleu eliminar
{email}?", + + "users": "Usuaris", + + "version": "Versi\u00f3 de Kirby", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "La teva compta", + "view.installation": "Instal·lació", + "view.languages": "Idiomes", + "view.resetPassword": "Reset password", + "view.site": "Lloc web", + "view.system": "System", + "view.users": "Usuaris", + + "welcome": "Benvinguda", + "year": "Any", + "yes": "yes" } diff --git a/kirby/i18n/translations/cs.json b/kirby/i18n/translations/cs.json index ba19b77..8487826 100644 --- a/kirby/i18n/translations/cs.json +++ b/kirby/i18n/translations/cs.json @@ -1,573 +1,596 @@ { - "account.changeName": "Přejmenovat", - "account.delete": "Smazat účet", - "account.delete.confirm": "Opravdu chcete smazat svůj účet? Budete okamžitě odhlášeni. Účet nemůže být zpětně obnoven.", - - "add": "P\u0159idat", - "author": "Autor", - "avatar": "Profilov\u00fd obr\u00e1zek", - "back": "Zpět", - "cancel": "Zru\u0161it", - "change": "Zm\u011bnit", - "close": "Zavřít", - "confirm": "Ok", - "collapse": "Sbalit", - "collapse.all": "Sbalit vše", - "copy": "Kopírovat", - "copy.all": "Kopírovat vše", - "create": "Vytvořit", - - "date": "Datum", - "date.select": "Vyberte datum", - - "day": "Den", - "days.fri": "p\u00e1", - "days.mon": "po", - "days.sat": "so", - "days.sun": "ne", - "days.thu": "\u010dt", - "days.tue": "\u00fat", - "days.wed": "st", - - "debugging": "Ladění", - - "delete": "Smazat", - "delete.all": "Smazat vše", - - "dialog.files.empty": "Žádné soubory k výběru", - "dialog.pages.empty": "Žádné stránky k výběru", - "dialog.users.empty": "Žádní uživatelé k výběru", - - "dimensions": "Rozměry", - "disabled": "Zakázáno", - "discard": "Zahodit", - "download": "Stáhnout", - "duplicate": "Duplikovat", - - "edit": "Upravit", - - "email": "Email", - "email.placeholder": "mail@example.com", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Prostředí", - - "error.access.code": "Neplatný kód", - "error.access.login": "Neplatné přihlášení", - "error.access.panel": "Nemáte oprávnění k přihlášení do panelu", - "error.access.view": "Nemáte oprávnění ke vstupu do této části panelu.", - - "error.avatar.create.fail": "Nebylo možné nahrát profilový obrázek", - "error.avatar.delete.fail": "Nebylo mo\u017en\u00e9 smazat profilov\u00fd obr\u00e1zek", - "error.avatar.dimensions.invalid": "Šířka a výška obrázku musí být pod 3000 pixelů", - "error.avatar.mime.forbidden": "Profilový obrázek musí být ve formátu JPEG nebo PNG", - - "error.blueprint.notFound": "Nelze načíst blueprint \"{name}\" ", - - "error.blocks.max.plural": "Nelze přidat více něž {max} bloků", - "error.blocks.max.singular": "Nelze přidat více než jeden blok", - "error.blocks.min.plural": "Musíte přidat alespoň {min} bloků", - "error.blocks.min.singular": "Musíte přidat alespoň jeden blok", - "error.blocks.validation": "Chyba v bloku {index}", - - "error.email.preset.notFound": "Nelze nalézt emailové přednastavení \"{name}\"", - - "error.field.converter.invalid": "Neplatný konvertor \"{converter}\"", - - "error.file.changeName.empty": "Toto jméno nesmí být prázdné", - "error.file.changeName.permission": "Nemáte povoleno změnit jméno souboru \"{filename}\"", - "error.file.duplicate": "Soubor s názvem \"{filename}\" již existuje", - "error.file.extension.forbidden": "Přípona souboru \"{extension}\" není povolena", - "error.file.extension.invalid": "Neplatná přípona souboru: {extension}", - "error.file.extension.missing": "Nem\u016f\u017eete nahr\u00e1t soubor bez p\u0159\u00edpony", - "error.file.maxheight": "Výška obrázku nesmí přesáhnout {height} pixelů", - "error.file.maxsize": "Soubor je příliš velký", - "error.file.maxwidth": "Šířka obrázku nesmí přesáhnout {width} pixelů", - "error.file.mime.differs": "Nahraný soubor musí být stejného typu \"{mime}\"", - "error.file.mime.forbidden": "Soubor typu \"{mime}\" není povolený", - "error.file.mime.invalid": "Neplatný MIME typ: {mime}", - "error.file.mime.missing": "Nelze rozeznat mime typ souboru \"{filename}\"", - "error.file.minheight": "Výška obrázku musí být alespoň {height} pixelů", - "error.file.minsize": "Soubor je příliš malý", - "error.file.minwidth": "Šířka obrázku musí být alespoň {width} pixelů", - "error.file.name.missing": "Název souboru nesmí být prázdný", - "error.file.notFound": "Soubor se nepoda\u0159ilo nal\u00e9zt", - "error.file.orientation": "Orientace obrázku másí být \"{orientation}\"", - "error.file.type.forbidden": "Nemáte povoleno nahrávat soubory typu {type} ", - "error.file.type.invalid": "Neplatný typ souboru: {type}", - "error.file.undefined": "Soubor se nepoda\u0159ilo nal\u00e9zt", - - "error.form.incomplete": "Prosím opravte všechny chyby ve formuláři", - "error.form.notSaved": "Formulář nemohl být uložen", - - "error.language.code": "Zadejte prosím platný kód jazyka", - "error.language.duplicate": "Jazyk již existuje", - "error.language.name": "Zadejte prosím platné jméno jazyka", - "error.language.notFound": "Jazyk nebyl nalezen", - - "error.layout.validation.block": "Chyba v bloku {blockIndex} v rozvržení {layoutIndex}", - "error.layout.validation.settings": "Chyba v nastavení rozvržení {index}", - - "error.license.format": "Zadejte prosím platné licenční číslo", - "error.license.email": "Zadejte prosím platnou emailovou adresu", - "error.license.verification": "Licenci nelze ověřit", - - "error.offline": "Panel je v současnosti off-line", - - "error.page.changeSlug.permission": "Nem\u016f\u017eete zm\u011bnit URL t\u00e9to str\u00e1nky", - "error.page.changeStatus.incomplete": "Stránka obsahuje chyby a nemohla být zveřejněna", - "error.page.changeStatus.permission": "Status této stránky nelze změnit", - "error.page.changeStatus.toDraft.invalid": "Stránka \"{slug}\" nemůže být převedena na koncept", - "error.page.changeTemplate.invalid": "Šablonu stránky \"{slug}\" nelze změnit", - "error.page.changeTemplate.permission": "Nemáte dovoleno změnit šablonu stránky \"{slug}\"", - "error.page.changeTitle.empty": "Titulek nesmí být prázdný", - "error.page.changeTitle.permission": "Nemáte dovoleno změnit titulek stránky \"{slug}\"", - "error.page.create.permission": "Nemáte dovoleno vytvořit \"{slug}\"", - "error.page.delete": "Stránku \"{slug}\" nelze vymazat", - "error.page.delete.confirm": "Pro potvrzení prosím zadejte titulek stránky", - "error.page.delete.hasChildren": "Stránka má podstránky, nemůže být vymazána", - "error.page.delete.permission": "Nemáte dovoleno odstranit \"{slug}\"", - "error.page.draft.duplicate": "Koncept stránky, který obsahuje v adrese URL \"{slug}\" již existuje ", - "error.page.duplicate": "Stránka, která v adrese URL obsahuje \"{slug}\" již existuje", - "error.page.duplicate.permission": "Nemáte dovoleno duplikovat \"{slug}\"", - "error.page.notFound": "Str\u00e1nku se nepoda\u0159ilo nal\u00e9zt.", - "error.page.num.invalid": "Zadejte prosím platné pořadové číslo. Čísla nesmí být záporná.", - "error.page.slug.invalid": "Podtržení", - "error.page.slug.maxlength": "URL musí mít méně než \"{length}\" znaků", - "error.page.sort.permission": "Stránce \"{slug}\" nelze změnit pořadí", - "error.page.status.invalid": "Nastavte prosím platný status stránky", - "error.page.undefined": "Str\u00e1nku se nepoda\u0159ilo nal\u00e9zt.", - "error.page.update.permission": "Nemáte dovoleno upravit \"{slug}\"", - - "error.section.files.max.plural": "Sekce \"{section}\" nesmí obsahovat více jak {max} souborů", - "error.section.files.max.singular": "Sekce \"{section}\" může obsahovat nejvýše jeden soubor", - "error.section.files.min.plural": "Sekce \"{section}\" vyžaduje nejméně {min} souborů", - "error.section.files.min.singular": "Sekce \"{section}\" vyžaduje alespoň jeden soubor", - - "error.section.pages.max.plural": "Sekce \"{section}\" nesmí obsahovat více jak {max} stránek", - "error.section.pages.max.singular": "Sekce \"{section}\" může obsahovat nejvýše jednu stránku", - "error.section.pages.min.plural": "Sekce \"{section}\" vyžaduje alespoň {min} stránek", - "error.section.pages.min.singular": "Sekce \"{section}\" vyžaduje alespoň jednu stránku", - - "error.section.notLoaded": "Nelze načíst sekci \"{name}\"", - "error.section.type.invalid": "Typ sekce \"{type}\" není platný", - - "error.site.changeTitle.empty": "Titulek nesmí být prázdný", - "error.site.changeTitle.permission": "Nemáte dovoleno změnit titulek stránky", - "error.site.update.permission": "Nemáte dovoleno upravit stránku", - - "error.template.default.notFound": "Výchozí šablona neexistuje", - - "error.unexpected": "Vyskytla se neočekávaná chyba! Pro více informací povolte debug mód, viz: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Nemáte dovoleno měnit email uživatele \"{name}\"", - "error.user.changeLanguage.permission": "Nemáte dovoleno změnit jazyk uživatele \"{name}\"", - "error.user.changeName.permission": "Nemáte dovoleno změnit jméno uživatele \"{name}\"", - "error.user.changePassword.permission": "Nemáte dovoleno změnit heslo uživatele \"{name}\"", - "error.user.changeRole.lastAdmin": "Role posledního administrátora nemůže být změněna", - "error.user.changeRole.permission": "Nemáte dovoleno změnit roli uživatele \"{name}\"", - "error.user.changeRole.toAdmin": "Nemáte dovoleno povýšit uživatele do role administrátora.", - "error.user.create.permission": "Nemáte dovoleno vytvořit tohoto uživatele", - "error.user.delete": "U\u017eivatel nemohl b\u00fdt smaz\u00e1n", - "error.user.delete.lastAdmin": "Nem\u016f\u017eete smazat posledn\u00edho administr\u00e1tora", - "error.user.delete.lastUser": "Poslední uživatel nemůže být smazán", - "error.user.delete.permission": "Nem\u00e1te dovoleno smazat tohoto u\u017eivatele", - "error.user.duplicate": "Uživatel s emailovou adresou \"{email}\" již existuje", - "error.user.email.invalid": "Zadejte prosím platnou emailovou adresu", - "error.user.language.invalid": "Zadejte prosím platný jazyk", - "error.user.notFound": "U\u017eivatele se nepoda\u0159ilo nal\u00e9zt", - "error.user.password.invalid": "Zadejte prosím platné heslo. Heslo musí být dlouhé alespoň 8 znaků.", - "error.user.password.notSame": "Pros\u00edm potvr\u010fte heslo", - "error.user.password.undefined": "Uživatel nemá nastavené heslo.", - "error.user.password.wrong": "Špatné heslo", - "error.user.role.invalid": "Zadejte prosím platnou roli", - "error.user.undefined": "Uživatele se nepodařilo nalézt", - "error.user.update.permission": "Nemáte dovoleno upravit uživatele \"{name}\"", - - "error.validation.accepted": "Potvrďte prosím", - "error.validation.alpha": "Zadávejte prosím pouze znaky v rozmezí a-z", - "error.validation.alphanum": "Zadávejte prosím pouze znaky v rozmezí a-z nebo čísla v rozmezí 0-9", - "error.validation.between": "Zadejte prosím hodnotu mez \"{min}\" a \"{max}\"", - "error.validation.boolean": "Potvrďte prosím, nebo odmítněte", - "error.validation.contains": "Zadejte prosím hodnotu, která obsahuje \"{needle}\"", - "error.validation.date": "Zadejte prosím platné datum", - "error.validation.date.after": "Zadejte prosím datum po {date}", - "error.validation.date.before": "Zadejte prosím datum před {date}", - "error.validation.date.between": "Zadejte prosím datum mezi {min} a {max}", - "error.validation.denied": "Prosím, odmítněte", - "error.validation.different": "Hodnota nesmí být \"{other}\"", - "error.validation.email": "Zadejte prosím platnou emailovou adresu", - "error.validation.endswith": "Hodnota nesmí končit \"{end}\"", - "error.validation.filename": "Zadejte prosím platný název souboru", - "error.validation.in": "Zadejte prosím některou z následujíích hodnot: ({in})", - "error.validation.integer": "Zadejte prosím platné celé číslo", - "error.validation.ip": "Zadejte prosím platnou IP adresu", - "error.validation.less": "Zadejte prosím hodnotu menší než {max}", - "error.validation.match": "Hodnota neodpovídá očekávanému vzoru", - "error.validation.max": "Zadejte prosím hodnotu rovnou, nebo menší než {max}", - "error.validation.maxlength": "Zadaná hodnota je příliš dlouhá. (Povoleno nejvýše {max} znaků)", - "error.validation.maxwords": "Nezadávejte prosím více jak {max} slov", - "error.validation.min": "Zadejte prosím hodnotu rovnou, nebo větší než {min}", - "error.validation.minlength": "Zadaná hodnota je příliš krátká. (Požadováno nejméně {min} znaků)", - "error.validation.minwords": "Zadejte prosím alespoň {min} slov", - "error.validation.more": "Zadejte prosím hodnotu větší než {min}", - "error.validation.notcontains": "Zadejte prosím hodnotu, která neobsahuje \"{needle}\"", - "error.validation.notin": "Nezadávejte prosím žádnou z následujíích hodnot: ({notIn})", - "error.validation.option": "Vyberte prosím platnou možnost", - "error.validation.num": "Zadejte prosím platné číslo", - "error.validation.required": "Zadejte prosím jakoukoli hodnotu", - "error.validation.same": "Zadejte prosím \"{other}\"", - "error.validation.size": "Velikost hodnoty musí být \"{size}\"", - "error.validation.startswith": "Hodnota musí začínat \"{start}\"", - "error.validation.time": "Zadejte prosím platný čas", - "error.validation.time.after": "Zadejte prosím čas po {time}", - "error.validation.time.before": "Zadejte prosím čas před {time}", - "error.validation.time.between": "Zadejte prosím čas v rozmezí od {min} do {max}", - "error.validation.url": "Zadejte prosím platnou adresu URL", - - "expand": "Rozbalit", - "expand.all": "Rozbalit vše", - - "field.required": "Pole musí být vyplněno.", - "field.blocks.changeType": "Změnit typ", - "field.blocks.code.name": "Kód", - "field.blocks.code.language": "Jazyk", - "field.blocks.code.placeholder": "Váš kód …", - "field.blocks.delete.confirm": "Opravdu chcete smazat tento blok?", - "field.blocks.delete.confirm.all": "Opravdu chcete smazat všechny bloky?", - "field.blocks.delete.confirm.selected": "Opravdu chcete smazat vybrané bloky?", - "field.blocks.empty": "Zatím žádné bloky", - "field.blocks.fieldsets.label": "Vyberte prosím typ bloku …", - "field.blocks.fieldsets.paste": "Stiskněte{{ shortcut }} pro vložení/import bloků z Vaší schránky", - "field.blocks.gallery.name": "Galerie", - "field.blocks.gallery.images.empty": "Zatím žádné obrázky", - "field.blocks.gallery.images.label": "Obrázky", - "field.blocks.heading.level": "Úroveň", - "field.blocks.heading.name": "Nadpis", - "field.blocks.heading.text": "Text", - "field.blocks.heading.placeholder": "Nadpis …", - "field.blocks.image.alt": "Alternativní text", - "field.blocks.image.caption": "Titulek", - "field.blocks.image.crop": "Oříznout", - "field.blocks.image.link": "Odkaz", - "field.blocks.image.location": "Umístění", - "field.blocks.image.name": "Obrázek", - "field.blocks.image.placeholder": "Vyberte obrázek", - "field.blocks.image.ratio": "Poměr stran", - "field.blocks.image.url": "URL obrázku", - "field.blocks.line.name": "Čára", - "field.blocks.list.name": "Seznam", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Text", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Citát", - "field.blocks.quote.text.label": "Text", - "field.blocks.quote.text.placeholder": "Citát …", - "field.blocks.quote.citation.label": "Citace", - "field.blocks.quote.citation.placeholder": "od …", - "field.blocks.text.name": "Text", - "field.blocks.text.placeholder": "Text …", - "field.blocks.video.caption": "Titulek", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Zadejte URL adresu videa", - "field.blocks.video.url.label": "URL adresa videa", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Nebyly zatím vybrány žádné soubory", - - "field.layout.delete": "Smazat rozložení", - "field.layout.delete.confirm": "Opravdu chcete smazat toto rozložení?", - "field.layout.empty": "Zatím žádné řádky", - "field.layout.select": "Vyberte rozložení", - - "field.pages.empty": "Nebyly zatím vybrány žádné stránky", - "field.structure.delete.confirm": "Opravdu chcete smazat tento z\u00e1znam?", - "field.structure.empty": "Zat\u00edm nejsou \u017e\u00e1dn\u00e9 z\u00e1znamy.", - "field.users.empty": "Nebyli zatím vybráni žádní uživatelé", - - "file.blueprint": "Tento typ souboru nemá blueprint. Blueprint můžete definovat v /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Opravdu chcete smazat tento soubor?", - "file.sort": "Změnit pozici", - - "files": "Soubory", - "files.empty": "Zatím žádné soubory", - - "hide": "Skrýt", - "hour": "Hodina", - "import": "Import", - "info": "Info", - "insert": "Vlo\u017eit", - "insert.after": "Vložit za", - "insert.before": "Vložit před", - "install": "Instalovat", - - "installation": "Instalace", - "installation.completed": "Panel byl nainstalován", - "installation.disabled": "Instalátor panelu je ve výchozím nastavení na veřejných serverech zakázán. Spusťte prosím instalátor na lokálním počítači nebo jej povolte prostřednictvím panel.install.", - "installation.issues.accounts": "\/site\/accounts nen\u00ed zapisovateln\u00e9", - "installation.issues.content": "Slo\u017eka content a v\u0161echny soubory a slo\u017eky v n\u00ed mus\u00ed b\u00fdt zapisovateln\u00e9.", - "installation.issues.curl": "Je vyžadováno rozšířeníCURL", - "installation.issues.headline": "Panel nelze nainstalovat", - "installation.issues.mbstring": "Je vyžadováno rozšířeníMB String", - "installation.issues.media": "Složka/media neexistuje, nebo nemá povolený zápis", - "installation.issues.php": "Ujistěte se, že používátePHP 7+", - "installation.issues.server": "Kirby vyžadujeApache, Nginx neboCaddy", - "installation.issues.sessions": "Složka/site/sessions neexistuje, nebo nemá povolený zápis", - - "language": "Jazyk", - "language.code": "Kód", - "language.convert": "Nastavte výchozí možnost", - "language.convert.confirm": "

Opravdu chcete převést{name} na výchozí jazyk? Tuto volbu nelze vzít zpátky.

Pokud {name} obsahuje nepřeložený text, nebude již k dispozici záložní varianta a části stránky mohou zůstat prázdné.

", - "language.create": "Přidat nový jazyk", - "language.delete.confirm": "Opravdu chcete smazat jazyk {name} včetně všech překladů? Tuto volbu nelze vzít zpátky!", - "language.deleted": "Jazyk byl smazán", - "language.direction": "Směr čtení", - "language.direction.ltr": "Zleva doprava", - "language.direction.rtl": "Zprava doleva", - "language.locale": "Řetězec lokalizace PHP", - "language.locale.warning": "Používáte vlastní jazykové nastavení. Upravte prosím soubor s nastavením v /site/languages", - "language.name": "Jméno", - "language.updated": "Jazyk byl aktualizován", - - "languages": "Jazyky", - "languages.default": "Výchozí jazyk", - "languages.empty": "Zatím neexistují žádné jazyky", - "languages.secondary": "Další jazyky", - "languages.secondary.empty": "Neexistují zatím žádné další jazyky", - - "license": "Kirby licence", - "license.buy": "Zakoupit licenci", - "license.register": "Registrovat", - "license.manage": "Manage your licenses", - "license.register.help": "Licenční kód jste po zakoupení obdrželi na email. Vložte prosím kód a zaregistrujte Vaší kopii.", - "license.register.label": "Zadejte prosím licenční kód", - "license.register.success": "Děkujeme Vám za podporu Kirby", - "license.unregistered": "Toto je neregistrovaná kopie Kirby", - "license.unregistered.label": "Unregistered", - - "link": "Odkaz", - "link.text": "Text odkazu", - - "loading": "Načítám", - - "lock.unsaved": "Neuložené změny", - "lock.unsaved.empty": "Nezbývají již žádné neuložené změny.", - "lock.isLocked": "Neuložené změny provedené {email}", - "lock.file.isLocked": "Soubor nelze změnit, právě jej upravuje {email}.", - "lock.page.isLocked": "Stránku nelze změnit, právě jí upravuje {email} .", - "lock.unlock": "Odemknout", - "lock.isUnlocked": "Vaše neuložené změny byly přepsány jiným uživatelem. Můžeze si své úpravy stáhnout a zapracovat je ručně.", - - "login": "P\u0159ihl\u00e1sit se", - "login.code.label.login": "Kód pro přihlášení", - "login.code.label.password-reset": "Kód pro resetování hesla", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "Vaše e-mailová adresa byla zaregistrována, kód byl odeslán do Vaší e-mailové schránky.", - "login.email.login.body": "Ahoj {user.nameOrEmail},\n\nV nedávné době jsi zažádal(a) o kód pro přihlášení do Kirby Panelu na stránce {site}.\nNásledující kód pro přihlášení je platný {timeout} minut:\n\n{code}\n\nPokud jsi o kód pro přihlášení nežádal(a), tuto zprávu prosím ignoruj a v případě dotazů prosím kontaktuj svého administrátora.\nZ bezpečnostních důvodů prosím tuto zprávu nepřeposílej nikomu dalšímu.", - "login.email.login.subject": "Váš kód pro přihlášení", - "login.email.password-reset.body": "Ahoj {user.nameOrEmail},\n\nV nedávné době jsi zažádal(a) o kód pro resetování hesla do Kirby Panelu na stránce {site}.\nNásledující kód pro resetování hesla je platný {timeout} minut:\n\n{code}\n\nPokud jsi o kód pro resetování hesla nežádal(a), tuto zprávu prosím ignoruj a v případě dotazů prosím kontaktuj svého administrátora.\nZ bezpečnostních důvodů prosím tuto zprávu nepřeposílej nikomu dalšímu.", - "login.email.password-reset.subject": "Váš kód pro resetování hesla", - "login.remember": "Zůstat přihlášen", - "login.reset": "Resetovat heslo", - "login.toggleText.code.email": "Přihlásit se pomocí e-mailu", - "login.toggleText.code.email-password": "Přihlásit se pomocí hesla", - "login.toggleText.password-reset.email": "Zapomenuté heslo?", - "login.toggleText.password-reset.email-password": "← Zpět na přihlášení", - - "logout": "Odhl\u00e1sit se", - - "menu": "Menu", - "meridiem": "AM/PM", - "mime": "Typ média", - "minutes": "Minuty", - - "month": "Měsíc", - "months.april": "Duben", - "months.august": "Srpen", - "months.december": "Prosinec", - "months.february": "Únor", - "months.january": "Leden", - "months.july": "\u010cervenec", - "months.june": "\u010cerven", - "months.march": "B\u0159ezen", - "months.may": "Kv\u011bten", - "months.november": "Listopad", - "months.october": "\u0158\u00edjen", - "months.september": "Z\u00e1\u0159\u00ed", - - "more": "Více", - "name": "Jméno", - "next": "Další", - "no": "ne", - "off": "vypnuto", - "on": "zapnuto", - "open": "Otevřít", - "open.newWindow": "Otevřít v novém okně", - "options": "Možnosti", - "options.none": "Žádné možnosti", - - "orientation": "Orientace", - "orientation.landscape": "Na šířku", - "orientation.portrait": "Na výšku", - "orientation.square": "Čtverec", - - "page.blueprint": "Tento typ stránky nemá blueprint. Blueprint můžete definovat v /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Zm\u011bnit URL", - "page.changeSlug.fromTitle": "Vytvo\u0159it z n\u00e1zvu", - "page.changeStatus": "Změnit status", - "page.changeStatus.position": "Vyberte prosím pozici", - "page.changeStatus.select": "Vybrat nový status", - "page.changeTemplate": "Změnit šablonu", - "page.delete.confirm": "Opravdu chcete smazat tuto str\u00e1nku?", - "page.delete.confirm.subpages": "Tato stránka má podstránky.
Všechny podstránky budou vymazány.", - "page.delete.confirm.title": "Pro potvrzení zadejte titulek stránky", - "page.draft.create": "Vytvořit koncept", - "page.duplicate.appendix": "Kopírovat", - "page.duplicate.files": "Kopírovat soubory", - "page.duplicate.pages": "Kopírovat stránky", - "page.sort": "Změnit pozici", - "page.status": "Stav", - "page.status.draft": "Koncept", - "page.status.draft.description": "Stránka je ve stavu konceptu a je viditelná pouze pro přihlášené editory, nebo přes tajný odkaz", - "page.status.listed": "Veřejná", - "page.status.listed.description": "Stránka je zveřejněná pro všechny", - "page.status.unlisted": "Neveřejná", - "page.status.unlisted.description": "Tato stránka je dostupná pouze přes URL.", - - "pages": "Stránky", - "pages.empty": "Zatím žádné stránky", - "pages.status.draft": "Koncepty", - "pages.status.listed": "Zveřejněno", - "pages.status.unlisted": "Neveřejná", - - "pagination.page": "Stránka", - - "password": "Heslo", - "paste": "Vložit", - "paste.after": "Vložit za", - "pixel": "Pixel", - "plugins": "Doplňky", - "prev": "Předchozí", - "preview": "Náhled", - "remove": "Odstranit", - "rename": "Přejmenovat", - "replace": "Nahradit", - "retry": "Zkusit znovu", - "revert": "Zahodit", - "revert.confirm": "Opravdu chcete smazat všechny provedené změny?", - - "role": "Role", - "role.admin.description": "Administrátor má všechna práva", - "role.admin.title": "Administrátor", - "role.all": "Vše", - "role.empty": "Neexistují uživatelé s touto rolí", - "role.description.placeholder": "Žádný popis", - "role.nobody.description": "Toto je výchozí role bez jakýchkoli oprávnění", - "role.nobody.title": "Nikdo", - - "save": "Ulo\u017eit", - "search": "Hledat", - "search.min": "Pro vyhledání zadejte alespoň {min} znaky", - "search.all": "Zobrazit vše", - "search.results.none": "Žádné výsledky", - - "section.required": "Sekce musí být vyplněna", - - "security": "Security", - "select": "Vybrat", - "server": "Server", - "settings": "Nastavení", - "show": "Zobrazit", - "site.blueprint": "Hlavní panel nemá blueprint. Blueprint můžete definovat v /site/blueprints/site.yml", - "size": "Velikost", - "slug": "P\u0159\u00edpona URL", - "sort": "Řadit", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Název", - "template": "\u0160ablona", - "today": "Dnes", - - "toolbar.button.code": "Kód", - "toolbar.button.bold": "Tu\u010dn\u00fd text", - "toolbar.button.email": "Email", - "toolbar.button.headings": "Nadpisy", - "toolbar.button.heading.1": "Nadpis 1", - "toolbar.button.heading.2": "Nadpis 2", - "toolbar.button.heading.3": "Nadpis 3", - "toolbar.button.heading.4": "Nadpis 4", - "toolbar.button.heading.5": "Nadpis 5", - "toolbar.button.heading.6": "Nadpis 6", - "toolbar.button.italic": "Kurz\u00edva", - "toolbar.button.file": "Soubor", - "toolbar.button.file.select": "Vyberte soubor", - "toolbar.button.file.upload": "Nahrajte soubor", - "toolbar.button.link": "Odkaz", - "toolbar.button.paragraph": "Odstavec", - "toolbar.button.strike": "Přeškrtnutí", - "toolbar.button.ol": "Číslovaný seznam", - "toolbar.button.underline": "Podtržení", - "toolbar.button.ul": "Odrážkový seznam", - - "translation.author": "Kirby tým", - "translation.direction": "ltr", - "translation.name": "\u010cesky", - "translation.locale": "cs_CZ", - - "upload": "Nahrát", - "upload.error.cantMove": "Nahraný soubor nemohl být přesunut", - "upload.error.cantWrite": "Zápis souboru na disk se nezdařil", - "upload.error.default": "Soubor se nepodařilo nahrát", - "upload.error.extension": "Nahrávání souboru přerušeno rozšířením.", - "upload.error.formSize": "Velikost nahrávaného souboru převyšuje omezení stanovené direktivou MAX_FILE_SIZE", - "upload.error.iniPostSize": "Velikost nahrávaného souboru převyšuje omezení stanovené direktivou post_max_size, která je nastavena v php.ini", - "upload.error.iniSize": "Velikost nahrávaného souboru převyšuje omezení stanovené direktivou upload_max_filesize, která je nastavena v php.ini ", - "upload.error.noFile": "Nebyl nahrán žádný soubor", - "upload.error.noFiles": "Nebyly nahrány žádné soubory", - "upload.error.partial": "Soubor byl nahrán pouze z části", - "upload.error.tmpDir": "Chybí dočasná složka", - "upload.errors": "Chyba", - "upload.progress": "Nahrávání...", - - "url": "Url", - "url.placeholder": "https://example.com", - - "user": "Uživatel", - "user.blueprint": "Pro tuto uživatelskou roli můžete definovat další sekce a pole v /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Změnit email", - "user.changeLanguage": "Změnit jazyk", - "user.changeName": "Přejmenovat tohoto uživatele", - "user.changePassword": "Změnit heslo", - "user.changePassword.new": "Nové heslo", - "user.changePassword.new.confirm": "Potvrdit nové heslo...", - "user.changeRole": "Změnit roli", - "user.changeRole.select": "Vybrat novou roli", - "user.create": "Přidat nového uživatele", - "user.delete": "Smazat tohoto uživatele", - "user.delete.confirm": "Opravdu chcete smazat tohoto u\u017eivatele?", - - "users": "Uživatelé", - - "version": "Verze Kirby", - - "view.account": "V\u00e1\u0161 \u00fa\u010det", - "view.installation": "Instalace", - "view.languages": "Jazyky", - "view.resetPassword": "Resetovat heslo", - "view.site": "Stránka", - "view.system": "Systém", - "view.users": "U\u017eivatel\u00e9", - - "welcome": "Vítejte", - "year": "Rok", - "yes": "ano" + "account.changeName": "Přejmenovat", + "account.delete": "Smazat účet", + "account.delete.confirm": "Opravdu chcete smazat svůj účet? Budete okamžitě odhlášeni. Účet nemůže být zpětně obnoven.", + + "add": "P\u0159idat", + "author": "Autor", + "avatar": "Profilov\u00fd obr\u00e1zek", + "back": "Zpět", + "cancel": "Zru\u0161it", + "change": "Zm\u011bnit", + "close": "Zavřít", + "confirm": "Ok", + "collapse": "Sbalit", + "collapse.all": "Sbalit vše", + "copy": "Kopírovat", + "copy.all": "Kopírovat vše", + "create": "Vytvořit", + + "date": "Datum", + "date.select": "Vyberte datum", + + "day": "Den", + "days.fri": "p\u00e1", + "days.mon": "po", + "days.sat": "so", + "days.sun": "ne", + "days.thu": "\u010dt", + "days.tue": "\u00fat", + "days.wed": "st", + + "debugging": "Ladění", + + "delete": "Smazat", + "delete.all": "Smazat vše", + + "dialog.files.empty": "Žádné soubory k výběru", + "dialog.pages.empty": "Žádné stránky k výběru", + "dialog.users.empty": "Žádní uživatelé k výběru", + + "dimensions": "Rozměry", + "disabled": "Zakázáno", + "discard": "Zahodit", + "download": "Stáhnout", + "duplicate": "Duplikovat", + + "edit": "Upravit", + + "email": "Email", + "email.placeholder": "mail@example.com", + + "entries": "Záznamy", + "entry": "Záznam", + + "environment": "Prostředí", + + "error.access.code": "Neplatný kód", + "error.access.login": "Neplatné přihlášení", + "error.access.panel": "Nemáte oprávnění k přihlášení do panelu", + "error.access.view": "Nemáte oprávnění ke vstupu do této části panelu.", + + "error.avatar.create.fail": "Nebylo možné nahrát profilový obrázek", + "error.avatar.delete.fail": "Nebylo mo\u017en\u00e9 smazat profilov\u00fd obr\u00e1zek", + "error.avatar.dimensions.invalid": "Šířka a výška obrázku musí být pod 3000 pixelů", + "error.avatar.mime.forbidden": "Profilový obrázek musí být ve formátu JPEG nebo PNG", + + "error.blueprint.notFound": "Nelze načíst blueprint \"{name}\" ", + + "error.blocks.max.plural": "Nelze přidat více něž {max} bloků", + "error.blocks.max.singular": "Nelze přidat více než jeden blok", + "error.blocks.min.plural": "Musíte přidat alespoň {min} bloků", + "error.blocks.min.singular": "Musíte přidat alespoň jeden blok", + "error.blocks.validation": "V poli \"{field}\" v bloku {index} je při použití \"{fieldset}\" typu chyba", + + "error.email.preset.notFound": "Nelze nalézt emailové přednastavení \"{name}\"", + + "error.field.converter.invalid": "Neplatný konvertor \"{converter}\"", + + "error.file.changeName.empty": "Toto jméno nesmí být prázdné", + "error.file.changeName.permission": "Nemáte povoleno změnit jméno souboru \"{filename}\"", + "error.file.duplicate": "Soubor s názvem \"{filename}\" již existuje", + "error.file.extension.forbidden": "Přípona souboru \"{extension}\" není povolena", + "error.file.extension.invalid": "Neplatná přípona souboru: {extension}", + "error.file.extension.missing": "Nem\u016f\u017eete nahr\u00e1t soubor bez p\u0159\u00edpony", + "error.file.maxheight": "Výška obrázku nesmí přesáhnout {height} pixelů", + "error.file.maxsize": "Soubor je příliš velký", + "error.file.maxwidth": "Šířka obrázku nesmí přesáhnout {width} pixelů", + "error.file.mime.differs": "Nahraný soubor musí být stejného typu \"{mime}\"", + "error.file.mime.forbidden": "Soubor typu \"{mime}\" není povolený", + "error.file.mime.invalid": "Neplatný MIME typ: {mime}", + "error.file.mime.missing": "Nelze rozeznat mime typ souboru \"{filename}\"", + "error.file.minheight": "Výška obrázku musí být alespoň {height} pixelů", + "error.file.minsize": "Soubor je příliš malý", + "error.file.minwidth": "Šířka obrázku musí být alespoň {width} pixelů", + "error.file.name.missing": "Název souboru nesmí být prázdný", + "error.file.notFound": "Soubor se nepoda\u0159ilo nal\u00e9zt", + "error.file.orientation": "Orientace obrázku másí být \"{orientation}\"", + "error.file.type.forbidden": "Nemáte povoleno nahrávat soubory typu {type} ", + "error.file.type.invalid": "Neplatný typ souboru: {type}", + "error.file.undefined": "Soubor se nepoda\u0159ilo nal\u00e9zt", + + "error.form.incomplete": "Prosím opravte všechny chyby ve formuláři", + "error.form.notSaved": "Formulář nemohl být uložen", + + "error.language.code": "Zadejte prosím platný kód jazyka", + "error.language.duplicate": "Jazyk již existuje", + "error.language.name": "Zadejte prosím platné jméno jazyka", + "error.language.notFound": "Jazyk nebyl nalezen", + + "error.layout.validation.block": "V rozvržení {layoutIndex} je v poli \"{field}\" v bloku {blockIndex} při použití \"{fieldset}\" typu chyba", + "error.layout.validation.settings": "Chyba v nastavení rozvržení {index}", + + "error.license.format": "Zadejte prosím platné licenční číslo", + "error.license.email": "Zadejte prosím platnou emailovou adresu", + "error.license.verification": "Licenci nelze ověřit", + + "error.object.validation": "V poli \"{label}\" je chyba:\n{message}", + + "error.offline": "Panel je v současnosti off-line", + + "error.page.changeSlug.permission": "Nem\u016f\u017eete zm\u011bnit URL t\u00e9to str\u00e1nky", + "error.page.changeStatus.incomplete": "Stránka obsahuje chyby a nemohla být zveřejněna", + "error.page.changeStatus.permission": "Status této stránky nelze změnit", + "error.page.changeStatus.toDraft.invalid": "Stránka \"{slug}\" nemůže být převedena na koncept", + "error.page.changeTemplate.invalid": "Šablonu stránky \"{slug}\" nelze změnit", + "error.page.changeTemplate.permission": "Nemáte dovoleno změnit šablonu stránky \"{slug}\"", + "error.page.changeTitle.empty": "Titulek nesmí být prázdný", + "error.page.changeTitle.permission": "Nemáte dovoleno změnit titulek stránky \"{slug}\"", + "error.page.create.permission": "Nemáte dovoleno vytvořit \"{slug}\"", + "error.page.delete": "Stránku \"{slug}\" nelze vymazat", + "error.page.delete.confirm": "Pro potvrzení prosím zadejte titulek stránky", + "error.page.delete.hasChildren": "Stránka má podstránky, nemůže být vymazána", + "error.page.delete.permission": "Nemáte dovoleno odstranit \"{slug}\"", + "error.page.draft.duplicate": "Koncept stránky, který obsahuje v adrese URL \"{slug}\" již existuje ", + "error.page.duplicate": "Stránka, která v adrese URL obsahuje \"{slug}\" již existuje", + "error.page.duplicate.permission": "Nemáte dovoleno duplikovat \"{slug}\"", + "error.page.notFound": "Str\u00e1nku se nepoda\u0159ilo nal\u00e9zt.", + "error.page.num.invalid": "Zadejte prosím platné pořadové číslo. Čísla nesmí být záporná.", + "error.page.slug.invalid": "Podtržení", + "error.page.slug.maxlength": "URL musí mít méně než \"{length}\" znaků", + "error.page.sort.permission": "Stránce \"{slug}\" nelze změnit pořadí", + "error.page.status.invalid": "Nastavte prosím platný status stránky", + "error.page.undefined": "Str\u00e1nku se nepoda\u0159ilo nal\u00e9zt.", + "error.page.update.permission": "Nemáte dovoleno upravit \"{slug}\"", + + "error.section.files.max.plural": "Sekce \"{section}\" nesmí obsahovat více jak {max} souborů", + "error.section.files.max.singular": "Sekce \"{section}\" může obsahovat nejvýše jeden soubor", + "error.section.files.min.plural": "Sekce \"{section}\" vyžaduje nejméně {min} souborů", + "error.section.files.min.singular": "Sekce \"{section}\" vyžaduje alespoň jeden soubor", + + "error.section.pages.max.plural": "Sekce \"{section}\" nesmí obsahovat více jak {max} stránek", + "error.section.pages.max.singular": "Sekce \"{section}\" může obsahovat nejvýše jednu stránku", + "error.section.pages.min.plural": "Sekce \"{section}\" vyžaduje alespoň {min} stránek", + "error.section.pages.min.singular": "Sekce \"{section}\" vyžaduje alespoň jednu stránku", + + "error.section.notLoaded": "Nelze načíst sekci \"{name}\"", + "error.section.type.invalid": "Typ sekce \"{type}\" není platný", + + "error.site.changeTitle.empty": "Titulek nesmí být prázdný", + "error.site.changeTitle.permission": "Nemáte dovoleno změnit titulek stránky", + "error.site.update.permission": "Nemáte dovoleno upravit stránku", + + "error.template.default.notFound": "Výchozí šablona neexistuje", + + "error.unexpected": "Vyskytla se neočekávaná chyba! Pro více informací povolte debug mód, viz: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Nemáte dovoleno měnit email uživatele \"{name}\"", + "error.user.changeLanguage.permission": "Nemáte dovoleno změnit jazyk uživatele \"{name}\"", + "error.user.changeName.permission": "Nemáte dovoleno změnit jméno uživatele \"{name}\"", + "error.user.changePassword.permission": "Nemáte dovoleno změnit heslo uživatele \"{name}\"", + "error.user.changeRole.lastAdmin": "Role posledního administrátora nemůže být změněna", + "error.user.changeRole.permission": "Nemáte dovoleno změnit roli uživatele \"{name}\"", + "error.user.changeRole.toAdmin": "Nemáte dovoleno povýšit uživatele do role administrátora.", + "error.user.create.permission": "Nemáte dovoleno vytvořit tohoto uživatele", + "error.user.delete": "U\u017eivatel nemohl b\u00fdt smaz\u00e1n", + "error.user.delete.lastAdmin": "Nem\u016f\u017eete smazat posledn\u00edho administr\u00e1tora", + "error.user.delete.lastUser": "Poslední uživatel nemůže být smazán", + "error.user.delete.permission": "Nem\u00e1te dovoleno smazat tohoto u\u017eivatele", + "error.user.duplicate": "Uživatel s emailovou adresou \"{email}\" již existuje", + "error.user.email.invalid": "Zadejte prosím platnou emailovou adresu", + "error.user.language.invalid": "Zadejte prosím platný jazyk", + "error.user.notFound": "U\u017eivatele se nepoda\u0159ilo nal\u00e9zt", + "error.user.password.invalid": "Zadejte prosím platné heslo. Heslo musí být dlouhé alespoň 8 znaků.", + "error.user.password.notSame": "Pros\u00edm potvr\u010fte heslo", + "error.user.password.undefined": "Uživatel nemá nastavené heslo.", + "error.user.password.wrong": "Špatné heslo", + "error.user.role.invalid": "Zadejte prosím platnou roli", + "error.user.undefined": "Uživatele se nepodařilo nalézt", + "error.user.update.permission": "Nemáte dovoleno upravit uživatele \"{name}\"", + + "error.validation.accepted": "Potvrďte prosím", + "error.validation.alpha": "Zadávejte prosím pouze znaky v rozmezí a-z", + "error.validation.alphanum": "Zadávejte prosím pouze znaky v rozmezí a-z nebo čísla v rozmezí 0-9", + "error.validation.between": "Zadejte prosím hodnotu mez \"{min}\" a \"{max}\"", + "error.validation.boolean": "Potvrďte prosím, nebo odmítněte", + "error.validation.contains": "Zadejte prosím hodnotu, která obsahuje \"{needle}\"", + "error.validation.date": "Zadejte prosím platné datum", + "error.validation.date.after": "Zadejte prosím datum po {date}", + "error.validation.date.before": "Zadejte prosím datum před {date}", + "error.validation.date.between": "Zadejte prosím datum mezi {min} a {max}", + "error.validation.denied": "Prosím, odmítněte", + "error.validation.different": "Hodnota nesmí být \"{other}\"", + "error.validation.email": "Zadejte prosím platnou emailovou adresu", + "error.validation.endswith": "Hodnota nesmí končit \"{end}\"", + "error.validation.filename": "Zadejte prosím platný název souboru", + "error.validation.in": "Zadejte prosím některou z následujíích hodnot: ({in})", + "error.validation.integer": "Zadejte prosím platné celé číslo", + "error.validation.ip": "Zadejte prosím platnou IP adresu", + "error.validation.less": "Zadejte prosím hodnotu menší než {max}", + "error.validation.match": "Hodnota neodpovídá očekávanému vzoru", + "error.validation.max": "Zadejte prosím hodnotu rovnou, nebo menší než {max}", + "error.validation.maxlength": "Zadaná hodnota je příliš dlouhá. (Povoleno nejvýše {max} znaků)", + "error.validation.maxwords": "Nezadávejte prosím více jak {max} slov", + "error.validation.min": "Zadejte prosím hodnotu rovnou, nebo větší než {min}", + "error.validation.minlength": "Zadaná hodnota je příliš krátká. (Požadováno nejméně {min} znaků)", + "error.validation.minwords": "Zadejte prosím alespoň {min} slov", + "error.validation.more": "Zadejte prosím hodnotu větší než {min}", + "error.validation.notcontains": "Zadejte prosím hodnotu, která neobsahuje \"{needle}\"", + "error.validation.notin": "Nezadávejte prosím žádnou z následujíích hodnot: ({notIn})", + "error.validation.option": "Vyberte prosím platnou možnost", + "error.validation.num": "Zadejte prosím platné číslo", + "error.validation.required": "Zadejte prosím jakoukoli hodnotu", + "error.validation.same": "Zadejte prosím \"{other}\"", + "error.validation.size": "Velikost hodnoty musí být \"{size}\"", + "error.validation.startswith": "Hodnota musí začínat \"{start}\"", + "error.validation.time": "Zadejte prosím platný čas", + "error.validation.time.after": "Zadejte prosím čas po {time}", + "error.validation.time.before": "Zadejte prosím čas před {time}", + "error.validation.time.between": "Zadejte prosím čas v rozmezí od {min} do {max}", + "error.validation.url": "Zadejte prosím platnou adresu URL", + + "expand": "Rozbalit", + "expand.all": "Rozbalit vše", + + "field.required": "Pole musí být vyplněno.", + "field.blocks.changeType": "Změnit typ", + "field.blocks.code.name": "Kód", + "field.blocks.code.language": "Jazyk", + "field.blocks.code.placeholder": "Váš kód …", + "field.blocks.delete.confirm": "Opravdu chcete smazat tento blok?", + "field.blocks.delete.confirm.all": "Opravdu chcete smazat všechny bloky?", + "field.blocks.delete.confirm.selected": "Opravdu chcete smazat vybrané bloky?", + "field.blocks.empty": "Zatím žádné bloky", + "field.blocks.fieldsets.label": "Vyberte prosím typ bloku …", + "field.blocks.fieldsets.paste": "Stiskněte{{ shortcut }} pro vložení/import bloků z Vaší schránky", + "field.blocks.gallery.name": "Galerie", + "field.blocks.gallery.images.empty": "Zatím žádné obrázky", + "field.blocks.gallery.images.label": "Obrázky", + "field.blocks.heading.level": "Úroveň", + "field.blocks.heading.name": "Nadpis", + "field.blocks.heading.text": "Text", + "field.blocks.heading.placeholder": "Nadpis …", + "field.blocks.image.alt": "Alternativní text", + "field.blocks.image.caption": "Titulek", + "field.blocks.image.crop": "Oříznout", + "field.blocks.image.link": "Odkaz", + "field.blocks.image.location": "Umístění", + "field.blocks.image.name": "Obrázek", + "field.blocks.image.placeholder": "Vyberte obrázek", + "field.blocks.image.ratio": "Poměr stran", + "field.blocks.image.url": "URL obrázku", + "field.blocks.line.name": "Čára", + "field.blocks.list.name": "Seznam", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Text", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Citát", + "field.blocks.quote.text.label": "Text", + "field.blocks.quote.text.placeholder": "Citát …", + "field.blocks.quote.citation.label": "Citace", + "field.blocks.quote.citation.placeholder": "od …", + "field.blocks.text.name": "Text", + "field.blocks.text.placeholder": "Text …", + "field.blocks.video.caption": "Titulek", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Zadejte URL adresu videa", + "field.blocks.video.url.label": "URL adresa videa", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Nebyly zatím vybrány žádné soubory", + + "field.layout.delete": "Smazat rozložení", + "field.layout.delete.confirm": "Opravdu chcete smazat toto rozložení?", + "field.layout.empty": "Zatím žádné řádky", + "field.layout.select": "Vyberte rozložení", + + "field.object.empty": "Zatím žádná informace", + + "field.pages.empty": "Nebyly zatím vybrány žádné stránky", + + "field.structure.delete.confirm": "Opravdu chcete smazat tento z\u00e1znam?", + "field.structure.empty": "Zat\u00edm nejsou \u017e\u00e1dn\u00e9 z\u00e1znamy.", + + "field.users.empty": "Nebyli zatím vybráni žádní uživatelé", + + "file.blueprint": "Tento typ souboru nemá blueprint. Blueprint můžete definovat v /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Opravdu chcete smazat tento soubor?", + "file.sort": "Změnit pozici", + + "files": "Soubory", + "files.empty": "Zatím žádné soubory", + + "hide": "Skrýt", + "hour": "Hodina", + "import": "Import", + "info": "Informace", + "insert": "Vlo\u017eit", + "insert.after": "Vložit za", + "insert.before": "Vložit před", + "install": "Instalovat", + + "installation": "Instalace", + "installation.completed": "Panel byl nainstalován", + "installation.disabled": "Instalátor panelu je ve výchozím nastavení na veřejných serverech zakázán. Spusťte prosím instalátor na lokálním počítači nebo jej povolte prostřednictvím panel.install.", + "installation.issues.accounts": "\/site\/accounts nen\u00ed zapisovateln\u00e9", + "installation.issues.content": "Slo\u017eka content a v\u0161echny soubory a slo\u017eky v n\u00ed mus\u00ed b\u00fdt zapisovateln\u00e9.", + "installation.issues.curl": "Je vyžadováno rozšířeníCURL", + "installation.issues.headline": "Panel nelze nainstalovat", + "installation.issues.mbstring": "Je vyžadováno rozšířeníMB String", + "installation.issues.media": "Složka/media neexistuje, nebo nemá povolený zápis", + "installation.issues.php": "Ujistěte se, že používátePHP 7+", + "installation.issues.server": "Kirby vyžadujeApache, Nginx neboCaddy", + "installation.issues.sessions": "Složka/site/sessions neexistuje, nebo nemá povolený zápis", + + "language": "Jazyk", + "language.code": "Kód", + "language.convert": "Nastavte výchozí možnost", + "language.convert.confirm": "

Opravdu chcete převést{name} na výchozí jazyk? Tuto volbu nelze vzít zpátky.

Pokud {name} obsahuje nepřeložený text, nebude již k dispozici záložní varianta a části stránky mohou zůstat prázdné.

", + "language.create": "Přidat nový jazyk", + "language.delete.confirm": "Opravdu chcete smazat jazyk {name} včetně všech překladů? Tuto volbu nelze vzít zpátky!", + "language.deleted": "Jazyk byl smazán", + "language.direction": "Směr čtení", + "language.direction.ltr": "Zleva doprava", + "language.direction.rtl": "Zprava doleva", + "language.locale": "Řetězec lokalizace PHP", + "language.locale.warning": "Používáte vlastní jazykové nastavení. Upravte prosím soubor s nastavením v /site/languages", + "language.name": "Jméno", + "language.updated": "Jazyk byl aktualizován", + + "languages": "Jazyky", + "languages.default": "Výchozí jazyk", + "languages.empty": "Zatím neexistují žádné jazyky", + "languages.secondary": "Další jazyky", + "languages.secondary.empty": "Neexistují zatím žádné další jazyky", + + "license": "Kirby licence", + "license.buy": "Zakoupit licenci", + "license.register": "Registrovat", + "license.manage": "Spravovat licence", + "license.register.help": "Licenční kód jste po zakoupení obdrželi na email. Vložte prosím kód a zaregistrujte Vaší kopii.", + "license.register.label": "Zadejte prosím licenční kód", + "license.register.success": "Děkujeme Vám za podporu Kirby", + "license.unregistered": "Toto je neregistrovaná kopie Kirby", + "license.unregistered.label": "Neregistrovaný", + + "link": "Odkaz", + "link.text": "Text odkazu", + + "loading": "Načítám", + + "lock.unsaved": "Neuložené změny", + "lock.unsaved.empty": "Nezbývají již žádné neuložené změny.", + "lock.isLocked": "Neuložené změny provedené {email}", + "lock.file.isLocked": "Soubor nelze změnit, právě jej upravuje {email}.", + "lock.page.isLocked": "Stránku nelze změnit, právě jí upravuje {email} .", + "lock.unlock": "Odemknout", + "lock.isUnlocked": "Vaše neuložené změny byly přepsány jiným uživatelem. Můžeze si své úpravy stáhnout a zapracovat je ručně.", + + "login": "Přihlásit se", + "login.code.label.login": "Kód pro přihlášení", + "login.code.label.password-reset": "Kód pro resetování hesla", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "Vaše e-mailová adresa byla zaregistrována, kód byl odeslán do Vaší e-mailové schránky.", + "login.email.login.body": "Ahoj {user.nameOrEmail},\n\nV nedávné době jsi zažádal(a) o kód pro přihlášení do Kirby Panelu na stránce {site}.\nNásledující kód pro přihlášení je platný {timeout} minut:\n\n{code}\n\nPokud jsi o kód pro přihlášení nežádal(a), tuto zprávu prosím ignoruj a v případě dotazů prosím kontaktuj svého administrátora.\nZ bezpečnostních důvodů prosím tuto zprávu nepřeposílej nikomu dalšímu.", + "login.email.login.subject": "Váš kód pro přihlášení", + "login.email.password-reset.body": "Ahoj {user.nameOrEmail},\n\nV nedávné době jsi zažádal(a) o kód pro resetování hesla do Kirby Panelu na stránce {site}.\nNásledující kód pro resetování hesla je platný {timeout} minut:\n\n{code}\n\nPokud jsi o kód pro resetování hesla nežádal(a), tuto zprávu prosím ignoruj a v případě dotazů prosím kontaktuj svého administrátora.\nZ bezpečnostních důvodů prosím tuto zprávu nepřeposílej nikomu dalšímu.", + "login.email.password-reset.subject": "Váš kód pro resetování hesla", + "login.remember": "Zůstat přihlášen", + "login.reset": "Resetovat heslo", + "login.toggleText.code.email": "Přihlásit se pomocí e-mailu", + "login.toggleText.code.email-password": "Přihlásit se pomocí hesla", + "login.toggleText.password-reset.email": "Zapomenuté heslo?", + "login.toggleText.password-reset.email-password": "← Zpět na přihlášení", + + "logout": "Odhl\u00e1sit se", + + "menu": "Menu", + "meridiem": "AM/PM", + "mime": "Typ média", + "minutes": "Minuty", + + "month": "Měsíc", + "months.april": "Duben", + "months.august": "Srpen", + "months.december": "Prosinec", + "months.february": "Únor", + "months.january": "Leden", + "months.july": "\u010cervenec", + "months.june": "\u010cerven", + "months.march": "B\u0159ezen", + "months.may": "Kv\u011bten", + "months.november": "Listopad", + "months.october": "\u0158\u00edjen", + "months.september": "Z\u00e1\u0159\u00ed", + + "more": "Více", + "name": "Jméno", + "next": "Další", + "no": "ne", + "off": "vypnuto", + "on": "zapnuto", + "open": "Otevřít", + "open.newWindow": "Otevřít v novém okně", + "options": "Možnosti", + "options.none": "Žádné možnosti", + + "orientation": "Orientace", + "orientation.landscape": "Na šířku", + "orientation.portrait": "Na výšku", + "orientation.square": "Čtverec", + + "page.blueprint": "Tento typ stránky nemá blueprint. Blueprint můžete definovat v /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Zm\u011bnit URL", + "page.changeSlug.fromTitle": "Vytvo\u0159it z n\u00e1zvu", + "page.changeStatus": "Změnit status", + "page.changeStatus.position": "Vyberte prosím pozici", + "page.changeStatus.select": "Vybrat nový status", + "page.changeTemplate": "Změnit šablonu", + "page.delete.confirm": "Opravdu chcete smazat tuto str\u00e1nku?", + "page.delete.confirm.subpages": "Tato stránka má podstránky.
Všechny podstránky budou vymazány.", + "page.delete.confirm.title": "Pro potvrzení zadejte titulek stránky", + "page.draft.create": "Vytvořit koncept", + "page.duplicate.appendix": "Kopírovat", + "page.duplicate.files": "Kopírovat soubory", + "page.duplicate.pages": "Kopírovat stránky", + "page.sort": "Změnit pozici", + "page.status": "Stav", + "page.status.draft": "Koncept", + "page.status.draft.description": "Stránka je ve stavu konceptu a je viditelná pouze pro přihlášené editory, nebo přes tajný odkaz", + "page.status.listed": "Veřejná", + "page.status.listed.description": "Stránka je zveřejněná pro všechny", + "page.status.unlisted": "Neveřejná", + "page.status.unlisted.description": "Tato stránka je dostupná pouze přes URL.", + + "pages": "Stránky", + "pages.empty": "Zatím žádné stránky", + "pages.status.draft": "Koncepty", + "pages.status.listed": "Zveřejněno", + "pages.status.unlisted": "Neveřejná", + + "pagination.page": "Stránka", + + "password": "Heslo", + "paste": "Vložit", + "paste.after": "Vložit za", + "pixel": "Pixel", + "plugin": "Plugin", + "plugins": "Doplňky", + "prev": "Předchozí", + "preview": "Náhled", + "remove": "Odstranit", + "rename": "Přejmenovat", + "replace": "Nahradit", + "retry": "Zkusit znovu", + "revert": "Zahodit", + "revert.confirm": "Opravdu chcete smazat všechny provedené změny?", + + "role": "Role", + "role.admin.description": "Administrátor má všechna práva", + "role.admin.title": "Administrátor", + "role.all": "Vše", + "role.empty": "Neexistují uživatelé s touto rolí", + "role.description.placeholder": "Žádný popis", + "role.nobody.description": "Toto je výchozí role bez jakýchkoli oprávnění", + "role.nobody.title": "Nikdo", + + "save": "Ulo\u017eit", + "search": "Hledat", + "search.min": "Pro vyhledání zadejte alespoň {min} znaky", + "search.all": "Zobrazit vše", + "search.results.none": "Žádné výsledky", + + "section.required": "Sekce musí být vyplněna", + + "security": "Zabezpečení", + "select": "Vybrat", + "server": "Server", + "settings": "Nastavení", + "show": "Zobrazit", + "site.blueprint": "Hlavní panel nemá blueprint. Blueprint můžete definovat v /site/blueprints/site.yml", + "size": "Velikost", + "slug": "P\u0159\u00edpona URL", + "sort": "Řadit", + + "stats.empty": "Žádná hlášení", + "system.issues.content": "Složka content je zřejmě přístupná zvenčí", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debug mode musí být v produkci vypnutý", + "system.issues.git": "Složka .git je zřejmě přístupná zvenčí", + "system.issues.https": "Při všechny stránky doporučujeme používat protokol HTTPS", + "system.issues.kirby": "Složka kirby je zřejmě přístupná zvenčí", + "system.issues.site": "Složka site je zřejmě přístupná zvenčí", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Název", + "template": "\u0160ablona", + "today": "Dnes", + + "toolbar.button.code": "Kód", + "toolbar.button.bold": "Tu\u010dn\u00fd text", + "toolbar.button.email": "Email", + "toolbar.button.headings": "Nadpisy", + "toolbar.button.heading.1": "Nadpis 1", + "toolbar.button.heading.2": "Nadpis 2", + "toolbar.button.heading.3": "Nadpis 3", + "toolbar.button.heading.4": "Nadpis 4", + "toolbar.button.heading.5": "Nadpis 5", + "toolbar.button.heading.6": "Nadpis 6", + "toolbar.button.italic": "Kurz\u00edva", + "toolbar.button.file": "Soubor", + "toolbar.button.file.select": "Vyberte soubor", + "toolbar.button.file.upload": "Nahrajte soubor", + "toolbar.button.link": "Odkaz", + "toolbar.button.paragraph": "Odstavec", + "toolbar.button.strike": "Přeškrtnutí", + "toolbar.button.ol": "Číslovaný seznam", + "toolbar.button.underline": "Podtržení", + "toolbar.button.ul": "Odrážkový seznam", + + "translation.author": "Kirby tým", + "translation.direction": "ltr", + "translation.name": "\u010cesky", + "translation.locale": "cs_CZ", + + "upload": "Nahrát", + "upload.error.cantMove": "Nahraný soubor nemohl být přesunut", + "upload.error.cantWrite": "Zápis souboru na disk se nezdařil", + "upload.error.default": "Soubor se nepodařilo nahrát", + "upload.error.extension": "Nahrávání souboru přerušeno rozšířením.", + "upload.error.formSize": "Velikost nahrávaného souboru převyšuje omezení stanovené direktivou MAX_FILE_SIZE", + "upload.error.iniPostSize": "Velikost nahrávaného souboru převyšuje omezení stanovené direktivou post_max_size, která je nastavena v php.ini", + "upload.error.iniSize": "Velikost nahrávaného souboru převyšuje omezení stanovené direktivou upload_max_filesize, která je nastavena v php.ini ", + "upload.error.noFile": "Nebyl nahrán žádný soubor", + "upload.error.noFiles": "Nebyly nahrány žádné soubory", + "upload.error.partial": "Soubor byl nahrán pouze z části", + "upload.error.tmpDir": "Chybí dočasná složka", + "upload.errors": "Chyba", + "upload.progress": "Nahrávání...", + + "url": "Url", + "url.placeholder": "https://example.com", + + "user": "Uživatel", + "user.blueprint": "Pro tuto uživatelskou roli můžete definovat další sekce a pole v /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Změnit email", + "user.changeLanguage": "Změnit jazyk", + "user.changeName": "Přejmenovat tohoto uživatele", + "user.changePassword": "Změnit heslo", + "user.changePassword.new": "Nové heslo", + "user.changePassword.new.confirm": "Potvrdit nové heslo...", + "user.changeRole": "Změnit roli", + "user.changeRole.select": "Vybrat novou roli", + "user.create": "Přidat nového uživatele", + "user.delete": "Smazat tohoto uživatele", + "user.delete.confirm": "Opravdu chcete smazat tohoto u\u017eivatele?", + + "users": "Uživatelé", + + "version": "Verze Kirby", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "V\u00e1\u0161 \u00fa\u010det", + "view.installation": "Instalace", + "view.languages": "Jazyky", + "view.resetPassword": "Resetovat heslo", + "view.site": "Stránka", + "view.system": "Systém", + "view.users": "U\u017eivatel\u00e9", + + "welcome": "Vítejte", + "year": "Rok", + "yes": "ano" } diff --git a/kirby/i18n/translations/da.json b/kirby/i18n/translations/da.json index e71e9c5..8493067 100644 --- a/kirby/i18n/translations/da.json +++ b/kirby/i18n/translations/da.json @@ -1,573 +1,596 @@ { - "account.changeName": "Ændre dit navn", - "account.delete": "Slet din konto", - "account.delete.confirm": "Ønsker du virkelig at slette din konto? Du vil blive logget ud med det samme. Din konto kan ikke gendannes.", - - "add": "Ny", - "author": "Forfatter", - "avatar": "Profilbillede", - "back": "Tilbage", - "cancel": "Annuller", - "change": "\u00c6ndre", - "close": "Luk", - "confirm": "Gem", - "collapse": "Fold sammen", - "collapse.all": "Fold alle sammen", - "copy": "Kopier", - "copy.all": "Kopier alle", - "create": "Opret", - - "date": "Dato", - "date.select": "Vælg en dato", - - "day": "Dag", - "days.fri": "Fre", - "days.mon": "Man", - "days.sat": "L\u00f8r", - "days.sun": "S\u00f8n", - "days.thu": "Tor", - "days.tue": "Tir", - "days.wed": "Ons", - - "debugging": "Fejlfinding", - - "delete": "Slet", - "delete.all": "Slet alle", - - "dialog.files.empty": "Ingen filer kan vælges", - "dialog.pages.empty": "Ingen sider kan vælges", - "dialog.users.empty": "Ingen brugere kan vælges", - - "dimensions": "Dimensioner", - "disabled": "Deaktiveret", - "discard": "Kass\u00e9r", - "download": "Download", - "duplicate": "Dupliker", - - "edit": "Rediger", - - "email": "Email", - "email.placeholder": "mail@eksempel.dk", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Miljø", - - "error.access.code": "Ugyldig kode", - "error.access.login": "Ugyldigt log ind", - "error.access.panel": "Du har ikke adgang til panelet", - "error.access.view": "Du har ikke adgang til denne del af panelet", - - "error.avatar.create.fail": "Profilbilledet kunne blev ikke uploadet ", - "error.avatar.delete.fail": "Profilbilledet kunne ikke slettes", - "error.avatar.dimensions.invalid": "Hold venligst bredte og højde på billedet under 3000 pixels", - "error.avatar.mime.forbidden": "Uacceptabel fil-type", - - "error.blueprint.notFound": "Blueprint \"{name}\" kunne ikke indlæses", - - "error.blocks.max.plural": "Du må ikke tilføje flere end {max} blokke", - "error.blocks.max.singular": "Du må ikke tilføje mere end een blok", - "error.blocks.min.plural": "Du skal tilføje minimum {min} blokke", - "error.blocks.min.singular": "Du skal tilføje minimum een blok", - "error.blocks.validation": "Der er fejl i blok {index}", - - "error.email.preset.notFound": "Email preset \"{name}\" findes ikke", - - "error.field.converter.invalid": "Ugyldig converter \"{converter}\"", - - "error.file.changeName.empty": "Navn kan ikke efterlades tomt", - "error.file.changeName.permission": "Du har ikke tilladelse til at ændre navnet på filen \"{filename}\"", - "error.file.duplicate": "En fil med navnet \"{filename}\" eksisterer allerede", - "error.file.extension.forbidden": "Uacceptabel fil-endelse", - "error.file.extension.invalid": "Ugyldig endelse: {extension}", - "error.file.extension.missing": "Du kan ikke uploade filer uden fil-endelse", - "error.file.maxheight": "Højden på billedet af billedet må ikke være større end {height} pixels", - "error.file.maxsize": "Filen er for stor", - "error.file.maxwidth": "Bredden af billedet må ikke være større end {width} pixels", - "error.file.mime.differs": "Den uploadede fil skal være af samme mime type \"{mime}\"", - "error.file.mime.forbidden": "Media typen \"{mime}\" er ikke tilladt", - "error.file.mime.invalid": "Ugyldig mime type: {mime}", - "error.file.mime.missing": "Media typen for \"{filename}\" kan ikke bestemmes", - "error.file.minheight": "Højden af billedet skal mindst være {height} pixels", - "error.file.minsize": "Filen er for lille", - "error.file.minwidth": "Bredden af billedet skal mindst være {width} pixels", - "error.file.name.missing": "Filnavn må ikke være tomt", - "error.file.notFound": "Filen kunne ikke findes", - "error.file.orientation": "Formatet på billedet skal være \"{orientation}\"", - "error.file.type.forbidden": "Du har ikke tilladelse til at uploade {type} filer", - "error.file.type.invalid": "Ugyldig filtype: {type}", - "error.file.undefined": "Filen kunne ikke findes", - - "error.form.incomplete": "Ret venligst alle fejl i formularen...", - "error.form.notSaved": "Formularen kunne ikke gemmes", - - "error.language.code": "Indtast venligst en gyldig kode for sproget", - "error.language.duplicate": "Sproget eksisterer allerede", - "error.language.name": "Indtast venligst et gyldigt navn for sproget", - "error.language.notFound": "Sproget fandtes ikke", - - "error.layout.validation.block": "Der er fejl i blok {blockIndex} i layout {layoutIndex}", - "error.layout.validation.settings": "Der er fejl i layout {index} indstillinger", - - "error.license.format": "Indtast venligst en gyldig licensnøgle", - "error.license.email": "Indtast venligst en gyldig email adresse", - "error.license.verification": "Licensen kunne ikke verificeres", - - "error.offline": "Panelet er i øjeblikket offline", - - "error.page.changeSlug.permission": "Du kan ikke ændre URL-endelse for \"{slug}\"", - "error.page.changeStatus.incomplete": "Siden indeholder fejl og kan derfor ikke udgives", - "error.page.changeStatus.permission": "Status for denne side kan ikke ændres", - "error.page.changeStatus.toDraft.invalid": "Siden \"{slug}\" kan ikke konverteres om til en kladde", - "error.page.changeTemplate.invalid": "Skabelonen for siden \"{slug}\" kan ikke ændres", - "error.page.changeTemplate.permission": "Du har ikke tilladelse til at ændre skabelonen for \"{slug}\"", - "error.page.changeTitle.empty": "Titlen kan ikke være tom", - "error.page.changeTitle.permission": "Du har ikke tilladelse til at ændre titlen for \"{slug}\"", - "error.page.create.permission": "Du har ikke tilladelse til at oprette \"{slug}\"", - "error.page.delete": "Siden \"{slug}\" kan ikke slettes", - "error.page.delete.confirm": "Indtast venligst sidens titel for at bekræfte", - "error.page.delete.hasChildren": "Siden har unsersider og kan derfor ikke slettes", - "error.page.delete.permission": "Du har ikke tilladelse til at slette \"{slug}\"", - "error.page.draft.duplicate": "En sidekladde med URL-endelsen \"{slug}\" eksisterer allerede", - "error.page.duplicate": "En side med URL-endelsen \"{slug}\" eksisterer allerede", - "error.page.duplicate.permission": "Du har ikke mulighed for at duplikere \"{slug}\"", - "error.page.notFound": "Siden kunne ikke findes", - "error.page.num.invalid": "Indtast venligst et gyldigt sorteringsnummer. Nummeret kan ikke være negativt.", - "error.page.slug.invalid": "Indtast venligst et gyldigt URL appendix", - "error.page.slug.maxlength": "Navnet skal være kortere end \"{length}\" tegn", - "error.page.sort.permission": "Siden \"{slug}\" kan ikke sorteres", - "error.page.status.invalid": "Sæt venligst en gyldig status for siden", - "error.page.undefined": "Siden kunne ikke findes", - "error.page.update.permission": "Du har ikke tilladelse til at opdatere \"{slug}\"", - - "error.section.files.max.plural": "Du kan ikk tilføje mere end {max} filer til \"{section}\" sektionen", - "error.section.files.max.singular": "Du kan ikke tilføje mere end een fil til \"{section}\" sektionen", - "error.section.files.min.plural": "Sektionen \"{section}\" kræver mindst {min} filer", - "error.section.files.min.singular": "Sektionen \"{section}\" kræver mindst een fil", - - "error.section.pages.max.plural": "Du kan ikke tilføje flere end {max} sider til \"{section}\" sektionen", - "error.section.pages.max.singular": "Du kan ikke tilføje mere end een side til \"{section}\" sektionen", - "error.section.pages.min.plural": "Sektionen \"{section}\" kræver mindst {min} sider", - "error.section.pages.min.singular": "Sektionen \"{section}\" kræver mindst een side", - - "error.section.notLoaded": "Sektionen \"{section}\" kunne ikke indlæses", - "error.section.type.invalid": "Sektionstypen \"{type}\" er ikke gyldig", - - "error.site.changeTitle.empty": "Titlen kan ikke være tom", - "error.site.changeTitle.permission": "Du har ikke tilladelse til at ændre titlen på sitet", - "error.site.update.permission": "Du har ikke tilladelse til at opdatere sitet", - - "error.template.default.notFound": "Standardskabelonen eksisterer ikke", - - "error.unexpected": "En uventet fejl opstod! Aktiver debug mode for mere info: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Du har ikke tilladelse til at ændre emailen for brugeren \"{name}\"", - "error.user.changeLanguage.permission": "Du har ikke tilladelse til at ændre sproget for brugeren \"{name}\"", - "error.user.changeName.permission": "Du har ikke tilladelse til at ændre navn på brugeren \"{name}\"", - "error.user.changePassword.permission": "Du har ikke tilladelse til at ændre adgangskoden for brugeren \"{name}\"", - "error.user.changeRole.lastAdmin": "Rollen for den sidste admin kan ikke ændres", - "error.user.changeRole.permission": "Du har ikke tilladelse til at ændre rollen for brugeren \"{name}\"", - "error.user.changeRole.toAdmin": "Du har ikke tilladelse til at tildele nogen admin rollen", - "error.user.create.permission": "Du har ikke tilladelse til at oprette denne bruger", - "error.user.delete": "Brugeren kunne ikke slettes", - "error.user.delete.lastAdmin": "Du kan ikke slette den sidste admin", - "error.user.delete.lastUser": "Den sidste bruger kan ikke slettes", - "error.user.delete.permission": "Du har ikke tilladelse til at slette denne bruger", - "error.user.duplicate": "En bruger med email adresse \"{email}\" eksisterer allerede", - "error.user.email.invalid": "Indtast venligst en gyldig email adresse", - "error.user.language.invalid": "Indtast venligst et gyldigt sprog", - "error.user.notFound": "Brugeren kunne ikke findes", - "error.user.password.invalid": "Indtast venligst en gyldig adgangskode. Adgangskoder skal minimum være 8 tegn lange.", - "error.user.password.notSame": "Bekr\u00e6ft venligst adgangskoden", - "error.user.password.undefined": "Brugeren har ikke en adgangskode", - "error.user.password.wrong": "Forkert adgangskode", - "error.user.role.invalid": "Indtast venligst en gyldig rolle", - "error.user.undefined": "Brugeren kunne ikke findes", - "error.user.update.permission": "Du har ikke tilladelse til at opdatere brugeren \"{name}\"", - - "error.validation.accepted": "Bekræft venligst", - "error.validation.alpha": "Indtast venligst kun bogstaver imellem a-z", - "error.validation.alphanum": "Indtast venligst kun bogstaver og tal imellem a-z eller 0-9", - "error.validation.between": "Indtast venligst en værdi imellem \"{min}\" og \"{max}\"", - "error.validation.boolean": "Venligst bekræft eller afvis", - "error.validation.contains": "Indtast venligst en værdi der indeholder \"{needle}\"", - "error.validation.date": "Indtast venligst en gyldig dato", - "error.validation.date.after": "Indtast venligst en dato efter {date}", - "error.validation.date.before": "Indtast venligst en dato før {date}", - "error.validation.date.between": "Indtast venligst en dato imellem {min} og {max}", - "error.validation.denied": "Venligst afvis", - "error.validation.different": "Værdien må ikke være \"{other}\"", - "error.validation.email": "Indtast venligst en gyldig email adresse", - "error.validation.endswith": "Værdi skal ende med \"{end}\"", - "error.validation.filename": "Indtast venligst et gyldigt filnavn", - "error.validation.in": "Indtast venligst en af følgende: ({in})", - "error.validation.integer": "Indtast et gyldigt tal", - "error.validation.ip": "Indtast en gyldig IP adresse", - "error.validation.less": "Indtast venligst en værdi mindre end {max}", - "error.validation.match": "Værdien matcher ikke det forventede mønster", - "error.validation.max": "Indtast venligst en værdi lig med eller lavere end {max}", - "error.validation.maxlength": "Indtast venligst en kortere værdi. (maks. {max} karakterer)", - "error.validation.maxwords": "Indtast ikke flere end {max} ord", - "error.validation.min": "Indtast en værdi lig med eller højere end {min}", - "error.validation.minlength": "Indtast venligst en længere værdi. (min. {min} karakterer)", - "error.validation.minwords": "Indtast venligst mindst {min} ord", - "error.validation.more": "Indtast venligst en værdi større end {min}", - "error.validation.notcontains": "Indtast venligst en værdi der ikke indeholder \"{needle}\"", - "error.validation.notin": "Indtast venligst ikke nogen af følgende: ({notIn})", - "error.validation.option": "Vælg venligst en gyldig mulighed", - "error.validation.num": "Indtast venligst et gyldigt nummer", - "error.validation.required": "Indtast venligst noget", - "error.validation.same": "Indtast venligst \"{other}\"", - "error.validation.size": "Størrelsen på værdien skal være \"{size}\"", - "error.validation.startswith": "Værdien skal starte med \"{start}\"", - "error.validation.time": "Indtast venligst et gyldigt tidspunkt", - "error.validation.time.after": "Indtast venligst et tidspunkt efter {time}", - "error.validation.time.before": "Indtast venligst et tidspunkt inden {time}", - "error.validation.time.between": "Indtast venligst et tidspunkt imellem {min} og {max}", - "error.validation.url": "Indtast venligst en gyldig URL", - - "expand": "Fold ud", - "expand.all": "Fold alle ud", - - "field.required": "Feltet er påkrævet", - "field.blocks.changeType": "Skift type", - "field.blocks.code.name": "Kode", - "field.blocks.code.language": "Sprog", - "field.blocks.code.placeholder": "Din kode …", - "field.blocks.delete.confirm": "Ønsker du virkelig at slette denne blok?", - "field.blocks.delete.confirm.all": "Ønsker du virkelig at slette alle blokke?", - "field.blocks.delete.confirm.selected": "Ønsker du virkelig at slette de valgte blokke?", - "field.blocks.empty": "Ingen blokke endnu", - "field.blocks.fieldsets.label": "Vælg venligst en blok type", - "field.blocks.fieldsets.paste": "Tryk {{ shortcut }} for at indsætte/importere blokke fra dit udklipsholder", - "field.blocks.gallery.name": "Galleri", - "field.blocks.gallery.images.empty": "Ingen billeder endnu", - "field.blocks.gallery.images.label": "Billeder", - "field.blocks.heading.level": "Niveau", - "field.blocks.heading.name": "Overskrift", - "field.blocks.heading.text": "Tekst", - "field.blocks.heading.placeholder": "Overskrift …", - "field.blocks.image.alt": "Alternativ tekst", - "field.blocks.image.caption": "Billedtekst", - "field.blocks.image.crop": "Beskær", - "field.blocks.image.link": "Link", - "field.blocks.image.location": "Placering", - "field.blocks.image.name": "Billede", - "field.blocks.image.placeholder": "Vælg et billede", - "field.blocks.image.ratio": "Størrelsesforhold", - "field.blocks.image.url": "Billede URL", - "field.blocks.line.name": "Linje", - "field.blocks.list.name": "Liste", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Tekst", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Citat", - "field.blocks.quote.text.label": "Tekst", - "field.blocks.quote.text.placeholder": "Citat …", - "field.blocks.quote.citation.label": "Citeret af", - "field.blocks.quote.citation.placeholder": "af …", - "field.blocks.text.name": "Tekst", - "field.blocks.text.placeholder": "Tekst …", - "field.blocks.video.caption": "Billedtekst", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Indtast URL til en video", - "field.blocks.video.url.label": "Video-URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Ingen filer valgt endnu", - - "field.layout.delete": "Slet layout", - "field.layout.delete.confirm": "Ønsker du virkelig at slette dette layout", - "field.layout.empty": "Ingen rækker endnu", - "field.layout.select": "Vælg et layout", - - "field.pages.empty": "Ingen sider valgt endnu", - "field.structure.delete.confirm": "\u00d8nsker du virkelig at slette denne indtastning?", - "field.structure.empty": "Ingen indtastninger endnu.", - "field.users.empty": "Ingen brugere er valgt", - - "file.blueprint": "Denne fil har intet blueprint endnu. Du kan definere opsætningen i /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "\u00d8nsker du virkelig at slette denne fil?", - "file.sort": "Skift position", - - "files": "Filer", - "files.empty": "Ingen filer endnu", - - "hide": "Skjul", - "hour": "Time", - "import": "Importer", - "info": "Info", - "insert": "Inds\u00e6t", - "insert.after": "Indsæt efter", - "insert.before": "Indsæt før", - "install": "Installer", - - "installation": "Installation", - "installation.completed": "Panelet er blevet installeret", - "installation.disabled": "Panel installationen er deaktiveret på offentlige servere som standard. Kør venligst installationen på en lokal maskine eller aktiver det med panel.install panel.install muligheden.", - "installation.issues.accounts": "\/site\/accounts er ikke skrivbar", - "installation.issues.content": "Content mappen samt alle underliggende filer og mapper skal v\u00e6re skrivbare.", - "installation.issues.curl": "CURL extension er påkrævet", - "installation.issues.headline": "Panelet kan ikke installeres", - "installation.issues.mbstring": "MB String extension er påkrævet", - "installation.issues.media": "/media mappen eksisterer ikke eller er ikke skrivbar", - "installation.issues.php": "Sikre dig at der benyttes PHP 7+", - "installation.issues.server": "Kirby kræver Apache, Nginx eller Caddy", - "installation.issues.sessions": "/site/sessions mappen eksisterer ikke eller er ikke skrivbar", - - "language": "Sprog", - "language.code": "Kode", - "language.convert": "Gør standard", - "language.convert.confirm": "

Ønsker du virkelig at konvertere {name} til standardsproget? Dette kan ikke fortrydes.

Hvis {name} har uoversat indhold, vil der ikke længere være et gyldigt tilbagefald og dele af dit website vil måske fremstå tomt.

", - "language.create": "Tilføj nyt sprog", - "language.delete.confirm": "Ønsker du virkelig at slette sproget {name} inklusiv alle oversættelser? Kan ikke fortrydes!", - "language.deleted": "Sproget er blevet slettet", - "language.direction": "Læseretning", - "language.direction.ltr": "Venstre mod højre", - "language.direction.rtl": "Højre mod venstre", - "language.locale": "PHP locale string", - "language.locale.warning": "Du benytter en brugerdefineret sprogopsætning. Rediger venligst dette i sprogfilen i /site/languages", - "language.name": "Navn", - "language.updated": "Sproget er blevet opdateret", - - "languages": "Sprog", - "languages.default": "Standardsprog", - "languages.empty": "Der er ingen sprog endnu", - "languages.secondary": "Sekundære sprog", - "languages.secondary.empty": "Der er ingen sekundære sprog endnu", - - "license": "Kirby licens", - "license.buy": "Køb en licens", - "license.register": "Registrer", - "license.manage": "Manage your licenses", - "license.register.help": "Du modtog din licenskode efter købet via email. Venligst kopier og indsæt den for at registrere.", - "license.register.label": "Indtast venligst din licenskode", - "license.register.success": "Tak for din støtte af Kirby", - "license.unregistered": "Dette er en uregistreret demo af Kirby", - "license.unregistered.label": "Unregistered", - - "link": "Link", - "link.text": "Link tekst", - - "loading": "Indlæser", - - "lock.unsaved": "Ugemte ændringer", - "lock.unsaved.empty": "Der er ikke flere ændringer der ikke er gamt", - "lock.isLocked": "Ugemte ændringer af {email}", - "lock.file.isLocked": "Filen redigeres på nuværende af {email} og kan derfor ikke ændres.", - "lock.page.isLocked": "Siden redigeres på nuværende af {email} og kan derfor ikke ændres.", - "lock.unlock": "Lås op", - "lock.isUnlocked": "Dine ugemte ændringer er blevet overskrevet af en anden bruger. Du kan downloade dine ændringer for at flette dem ind manuelt.", - - "login": "Log ind", - "login.code.label.login": "Log ind kode", - "login.code.label.password-reset": "Sikkerhedskode", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "Hvis din email adresse er registreret er en sikkerhedskode blevet sendt via email.", - "login.email.login.body": "Hej {user.nameOrEmail},\n\nDu har for nyligt anmodet om en log ind kode til panelet af {site}.\nFølgende log ind kode vil være gyldig i {timeout} minutter:\n\n{code}\n\nHvis du ikke har anmodet om en log ind kode, kan du blot ignorere denne email eller kontakte din administrator hvis du har spørgsmål.\nAf sikkerhedsmæssige årsager, bør du IKKE videresende denne email.", - "login.email.login.subject": "Din log ind kode", - "login.email.password-reset.body": "Hej {user.nameOrEmail},\n\nDu har for nyligt anmodet om kode til nulstilling af adgangskode til panelet af {site}.\nFølgende kode til nulstilling af adgangskode vil være gyldig i {timeout} minutter:\n\n{code}\n\nHvis du ikke har anmodet om kode til nulstilling af adgangskode, kan du blot ignorere denne email eller kontakte din administrator hvis du har spørgsmål.\nAf sikkerhedsmæssige årsager, bør du IKKE videresende denne email.", - "login.email.password-reset.subject": "Din kode til nulstilling af adgangskode", - "login.remember": "Forbliv logget ind", - "login.reset": "Nulstil adgangskode", - "login.toggleText.code.email": "Log ind via email", - "login.toggleText.code.email-password": "Log ind med adgangskode", - "login.toggleText.password-reset.email": "Glemt din adgangskode?", - "login.toggleText.password-reset.email-password": "← Tilbage til log ind", - - "logout": "Log ud", - - "menu": "Menu", - "meridiem": "AM/PM", - "mime": "Medie Type", - "minutes": "Minutter", - - "month": "Måned", - "months.april": "April", - "months.august": "August", - "months.december": "December", - "months.february": "Februar", - "months.january": "Januar", - "months.july": "Juli", - "months.june": "Juni", - "months.march": "Marts", - "months.may": "Maj", - "months.november": "November", - "months.october": "Oktober", - "months.september": "September", - - "more": "Mere", - "name": "Navn", - "next": "Næste", - "no": "nej", - "off": "Sluk", - "on": "Aktiveret", - "open": "Åben", - "open.newWindow": "Åben i et nyt vindue", - "options": "Indstillinger", - "options.none": "Ingen muligheder", - - "orientation": "Orientering", - "orientation.landscape": "Landskab", - "orientation.portrait": "Portræt", - "orientation.square": "Kvadrat", - - "page.blueprint": "Denne side har intet blueprint endnu. Du kan definere opsætningen i /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "\u00c6ndre URL", - "page.changeSlug.fromTitle": "Generer udfra titel", - "page.changeStatus": "Skift status", - "page.changeStatus.position": "Vælg venligst position", - "page.changeStatus.select": "Vælg en ny status", - "page.changeTemplate": "Skift skabelon", - "page.delete.confirm": "\u00d8nsker du virkelig at slette denne side?", - "page.delete.confirm.subpages": "Denne side har undersider.
Alle undersider vil også blive slettet.", - "page.delete.confirm.title": "Indtast sidens titel for at bekræfte", - "page.draft.create": "Opret kladde", - "page.duplicate.appendix": "Kopier", - "page.duplicate.files": "Kopier filer", - "page.duplicate.pages": "Kopier sider", - "page.sort": "Skift position", - "page.status": "Status", - "page.status.draft": "Kladde", - "page.status.draft.description": "Siden er i kladde udgave og er kun synlig for redaktører der er logget ind eller via hemmeligt link", - "page.status.listed": "Offentlig", - "page.status.listed.description": "Siden er offentlig for enhver", - "page.status.unlisted": "Ulistede", - "page.status.unlisted.description": "Siden er kun tilgængelig via URL", - - "pages": "Sider", - "pages.empty": "Ingen sider endnu", - "pages.status.draft": "Kladder", - "pages.status.listed": "Udgivede", - "pages.status.unlisted": "Ulistede", - - "pagination.page": "Side", - - "password": "Adgangskode", - "paste": "Indsæt", - "paste.after": "Indsæt efter", - "pixel": "Pixel", - "plugins": "Plugins", - "prev": "Forrige", - "preview": "Forhåndsvisning", - "remove": "Fjern", - "rename": "Omdøb", - "replace": "Erstat", - "retry": "Pr\u00f8v igen", - "revert": "Kass\u00e9r", - "revert.confirm": "Ønsker du virkelig at slette all ændringer der ikke er gemt?", - - "role": "Rolle", - "role.admin.description": "Admin har alle rettigheder", - "role.admin.title": "Admin", - "role.all": "All", - "role.empty": "Der er ingen bruger med denne rolle", - "role.description.placeholder": "Ingen beskrivelse", - "role.nobody.description": "Dette er en tilbagefaldsrolle uden rettigheder", - "role.nobody.title": "Ingen", - - "save": "Gem", - "search": "Søg", - "search.min": "Indtast {min} tegn for at søge", - "search.all": "Vis alle", - "search.results.none": "Ingen resultater", - - "section.required": "Sektionen er påkrævet", - - "security": "Security", - "select": "Vælg", - "server": "Server", - "settings": "Indstillinger", - "show": "Vis", - "site.blueprint": "Sitet har intet blueprint endnu. Du kan definere opsætningen i /site/blueprints/site.yml", - "size": "Størrelse", - "slug": "URL-appendiks", - "sort": "Sorter", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Titel", - "template": "Skabelon", - "today": "Idag", - - "toolbar.button.code": "Kode", - "toolbar.button.bold": "Fed tekst", - "toolbar.button.email": "Email", - "toolbar.button.headings": "Overskrifter", - "toolbar.button.heading.1": "Overskrift 1", - "toolbar.button.heading.2": "Overskrift 2", - "toolbar.button.heading.3": "Overskrift 3", - "toolbar.button.heading.4": "Overskrift 4", - "toolbar.button.heading.5": "Overskrift 5", - "toolbar.button.heading.6": "Overskrift 6", - "toolbar.button.italic": "Kursiv tekst", - "toolbar.button.file": "Fil", - "toolbar.button.file.select": "Vælg en fil", - "toolbar.button.file.upload": "Upload en fil", - "toolbar.button.link": "Link", - "toolbar.button.paragraph": "Afsnit", - "toolbar.button.strike": "Gennemstreg", - "toolbar.button.ol": "Ordnet liste", - "toolbar.button.underline": "Understreg", - "toolbar.button.ul": "Punktliste", - - "translation.author": "Kirby Team", - "translation.direction": "ltr", - "translation.name": "Dansk", - "translation.locale": "da_DK", - - "upload": "Upload", - "upload.error.cantMove": "Den uploadede fil kunne ikke flyttes", - "upload.error.cantWrite": "Kunne ikke skrive fil til disk", - "upload.error.default": "Filen kunne ikke uploades", - "upload.error.extension": "Upload af filen blev stoppet af dens type", - "upload.error.formSize": "Filen overskrider MAX_FILE_SIZE direktivet der er specificeret for formularen", - "upload.error.iniPostSize": "FIlen overskrider post_max_size direktivet i php.ini", - "upload.error.iniSize": "FIlen overskrider upload_max_filesize direktivet i php.ini", - "upload.error.noFile": "Ingen fil blev uploadet", - "upload.error.noFiles": "Ingen filer blev uploadet", - "upload.error.partial": "Den uploadede fil blev kun delvist uploadet", - "upload.error.tmpDir": "Der mangler en midlertidig mappe", - "upload.errors": "Fejl", - "upload.progress": "Uploader...", - - "url": "Url", - "url.placeholder": "https://example.com", - - "user": "Bruger", - "user.blueprint": "Du kan definere yderligere sektioner og formular felter for denne brugerrolle i /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Skift email", - "user.changeLanguage": "Skift sprog", - "user.changeName": "Omdøb denne bruger", - "user.changePassword": "Skift adgangskode", - "user.changePassword.new": "Ny adgangskode", - "user.changePassword.new.confirm": "Bekræft den nye adgangskode...", - "user.changeRole": "Skift rolle", - "user.changeRole.select": "Vælg en ny rolle", - "user.create": "Tilføj en ny bruger", - "user.delete": "Slet denne bruger", - "user.delete.confirm": "\u00d8nsker du virkelig at slette denne bruger?", - - "users": "Brugere", - - "version": "Kirby version", - - "view.account": "Din konto", - "view.installation": "Installation", - "view.languages": "Sprog", - "view.resetPassword": "Nulstil adgangskode", - "view.site": "Website", - "view.system": "System", - "view.users": "Brugere", - - "welcome": "Velkommen", - "year": "År", - "yes": "ja" + "account.changeName": "Ændre dit navn", + "account.delete": "Slet din konto", + "account.delete.confirm": "Ønsker du virkelig at slette din konto? Du vil blive logget ud med det samme. Din konto kan ikke gendannes.", + + "add": "Ny", + "author": "Forfatter", + "avatar": "Profilbillede", + "back": "Tilbage", + "cancel": "Annuller", + "change": "\u00c6ndre", + "close": "Luk", + "confirm": "Gem", + "collapse": "Fold sammen", + "collapse.all": "Fold alle sammen", + "copy": "Kopier", + "copy.all": "Kopier alle", + "create": "Opret", + + "date": "Dato", + "date.select": "Vælg en dato", + + "day": "Dag", + "days.fri": "Fre", + "days.mon": "Man", + "days.sat": "L\u00f8r", + "days.sun": "S\u00f8n", + "days.thu": "Tor", + "days.tue": "Tir", + "days.wed": "Ons", + + "debugging": "Fejlfinding", + + "delete": "Slet", + "delete.all": "Slet alle", + + "dialog.files.empty": "Ingen filer kan vælges", + "dialog.pages.empty": "Ingen sider kan vælges", + "dialog.users.empty": "Ingen brugere kan vælges", + + "dimensions": "Dimensioner", + "disabled": "Deaktiveret", + "discard": "Kass\u00e9r", + "download": "Download", + "duplicate": "Dupliker", + + "edit": "Rediger", + + "email": "Email", + "email.placeholder": "mail@eksempel.dk", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Miljø", + + "error.access.code": "Ugyldig kode", + "error.access.login": "Ugyldigt log ind", + "error.access.panel": "Du har ikke adgang til panelet", + "error.access.view": "Du har ikke adgang til denne del af panelet", + + "error.avatar.create.fail": "Profilbilledet kunne blev ikke uploadet ", + "error.avatar.delete.fail": "Profilbilledet kunne ikke slettes", + "error.avatar.dimensions.invalid": "Hold venligst bredte og højde på billedet under 3000 pixels", + "error.avatar.mime.forbidden": "Uacceptabel fil-type", + + "error.blueprint.notFound": "Blueprint \"{name}\" kunne ikke indlæses", + + "error.blocks.max.plural": "Du må ikke tilføje flere end {max} blokke", + "error.blocks.max.singular": "Du må ikke tilføje mere end een blok", + "error.blocks.min.plural": "Du skal tilføje minimum {min} blokke", + "error.blocks.min.singular": "Du skal tilføje minimum een blok", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "Email preset \"{name}\" findes ikke", + + "error.field.converter.invalid": "Ugyldig converter \"{converter}\"", + + "error.file.changeName.empty": "Navn kan ikke efterlades tomt", + "error.file.changeName.permission": "Du har ikke tilladelse til at ændre navnet på filen \"{filename}\"", + "error.file.duplicate": "En fil med navnet \"{filename}\" eksisterer allerede", + "error.file.extension.forbidden": "Uacceptabel fil-endelse", + "error.file.extension.invalid": "Ugyldig endelse: {extension}", + "error.file.extension.missing": "Du kan ikke uploade filer uden fil-endelse", + "error.file.maxheight": "Højden på billedet af billedet må ikke være større end {height} pixels", + "error.file.maxsize": "Filen er for stor", + "error.file.maxwidth": "Bredden af billedet må ikke være større end {width} pixels", + "error.file.mime.differs": "Den uploadede fil skal være af samme mime type \"{mime}\"", + "error.file.mime.forbidden": "Media typen \"{mime}\" er ikke tilladt", + "error.file.mime.invalid": "Ugyldig mime type: {mime}", + "error.file.mime.missing": "Media typen for \"{filename}\" kan ikke bestemmes", + "error.file.minheight": "Højden af billedet skal mindst være {height} pixels", + "error.file.minsize": "Filen er for lille", + "error.file.minwidth": "Bredden af billedet skal mindst være {width} pixels", + "error.file.name.missing": "Filnavn må ikke være tomt", + "error.file.notFound": "Filen kunne ikke findes", + "error.file.orientation": "Formatet på billedet skal være \"{orientation}\"", + "error.file.type.forbidden": "Du har ikke tilladelse til at uploade {type} filer", + "error.file.type.invalid": "Ugyldig filtype: {type}", + "error.file.undefined": "Filen kunne ikke findes", + + "error.form.incomplete": "Ret venligst alle fejl i formularen...", + "error.form.notSaved": "Formularen kunne ikke gemmes", + + "error.language.code": "Indtast venligst en gyldig kode for sproget", + "error.language.duplicate": "Sproget eksisterer allerede", + "error.language.name": "Indtast venligst et gyldigt navn for sproget", + "error.language.notFound": "Sproget fandtes ikke", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "Der er fejl i layout {index} indstillinger", + + "error.license.format": "Indtast venligst en gyldig licensnøgle", + "error.license.email": "Indtast venligst en gyldig email adresse", + "error.license.verification": "Licensen kunne ikke verificeres", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "Panelet er i øjeblikket offline", + + "error.page.changeSlug.permission": "Du kan ikke ændre URL-endelse for \"{slug}\"", + "error.page.changeStatus.incomplete": "Siden indeholder fejl og kan derfor ikke udgives", + "error.page.changeStatus.permission": "Status for denne side kan ikke ændres", + "error.page.changeStatus.toDraft.invalid": "Siden \"{slug}\" kan ikke konverteres om til en kladde", + "error.page.changeTemplate.invalid": "Skabelonen for siden \"{slug}\" kan ikke ændres", + "error.page.changeTemplate.permission": "Du har ikke tilladelse til at ændre skabelonen for \"{slug}\"", + "error.page.changeTitle.empty": "Titlen kan ikke være tom", + "error.page.changeTitle.permission": "Du har ikke tilladelse til at ændre titlen for \"{slug}\"", + "error.page.create.permission": "Du har ikke tilladelse til at oprette \"{slug}\"", + "error.page.delete": "Siden \"{slug}\" kan ikke slettes", + "error.page.delete.confirm": "Indtast venligst sidens titel for at bekræfte", + "error.page.delete.hasChildren": "Siden har unsersider og kan derfor ikke slettes", + "error.page.delete.permission": "Du har ikke tilladelse til at slette \"{slug}\"", + "error.page.draft.duplicate": "En sidekladde med URL-endelsen \"{slug}\" eksisterer allerede", + "error.page.duplicate": "En side med URL-endelsen \"{slug}\" eksisterer allerede", + "error.page.duplicate.permission": "Du har ikke mulighed for at duplikere \"{slug}\"", + "error.page.notFound": "Siden kunne ikke findes", + "error.page.num.invalid": "Indtast venligst et gyldigt sorteringsnummer. Nummeret kan ikke være negativt.", + "error.page.slug.invalid": "Indtast venligst et gyldigt URL appendix", + "error.page.slug.maxlength": "Navnet skal være kortere end \"{length}\" tegn", + "error.page.sort.permission": "Siden \"{slug}\" kan ikke sorteres", + "error.page.status.invalid": "Sæt venligst en gyldig status for siden", + "error.page.undefined": "Siden kunne ikke findes", + "error.page.update.permission": "Du har ikke tilladelse til at opdatere \"{slug}\"", + + "error.section.files.max.plural": "Du kan ikk tilføje mere end {max} filer til \"{section}\" sektionen", + "error.section.files.max.singular": "Du kan ikke tilføje mere end een fil til \"{section}\" sektionen", + "error.section.files.min.plural": "Sektionen \"{section}\" kræver mindst {min} filer", + "error.section.files.min.singular": "Sektionen \"{section}\" kræver mindst een fil", + + "error.section.pages.max.plural": "Du kan ikke tilføje flere end {max} sider til \"{section}\" sektionen", + "error.section.pages.max.singular": "Du kan ikke tilføje mere end een side til \"{section}\" sektionen", + "error.section.pages.min.plural": "Sektionen \"{section}\" kræver mindst {min} sider", + "error.section.pages.min.singular": "Sektionen \"{section}\" kræver mindst een side", + + "error.section.notLoaded": "Sektionen \"{section}\" kunne ikke indlæses", + "error.section.type.invalid": "Sektionstypen \"{type}\" er ikke gyldig", + + "error.site.changeTitle.empty": "Titlen kan ikke være tom", + "error.site.changeTitle.permission": "Du har ikke tilladelse til at ændre titlen på sitet", + "error.site.update.permission": "Du har ikke tilladelse til at opdatere sitet", + + "error.template.default.notFound": "Standardskabelonen eksisterer ikke", + + "error.unexpected": "En uventet fejl opstod! Aktiver debug mode for mere info: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Du har ikke tilladelse til at ændre emailen for brugeren \"{name}\"", + "error.user.changeLanguage.permission": "Du har ikke tilladelse til at ændre sproget for brugeren \"{name}\"", + "error.user.changeName.permission": "Du har ikke tilladelse til at ændre navn på brugeren \"{name}\"", + "error.user.changePassword.permission": "Du har ikke tilladelse til at ændre adgangskoden for brugeren \"{name}\"", + "error.user.changeRole.lastAdmin": "Rollen for den sidste admin kan ikke ændres", + "error.user.changeRole.permission": "Du har ikke tilladelse til at ændre rollen for brugeren \"{name}\"", + "error.user.changeRole.toAdmin": "Du har ikke tilladelse til at tildele nogen admin rollen", + "error.user.create.permission": "Du har ikke tilladelse til at oprette denne bruger", + "error.user.delete": "Brugeren kunne ikke slettes", + "error.user.delete.lastAdmin": "Du kan ikke slette den sidste admin", + "error.user.delete.lastUser": "Den sidste bruger kan ikke slettes", + "error.user.delete.permission": "Du har ikke tilladelse til at slette denne bruger", + "error.user.duplicate": "En bruger med email adresse \"{email}\" eksisterer allerede", + "error.user.email.invalid": "Indtast venligst en gyldig email adresse", + "error.user.language.invalid": "Indtast venligst et gyldigt sprog", + "error.user.notFound": "Brugeren kunne ikke findes", + "error.user.password.invalid": "Indtast venligst en gyldig adgangskode. Adgangskoder skal minimum være 8 tegn lange.", + "error.user.password.notSame": "Bekr\u00e6ft venligst adgangskoden", + "error.user.password.undefined": "Brugeren har ikke en adgangskode", + "error.user.password.wrong": "Forkert adgangskode", + "error.user.role.invalid": "Indtast venligst en gyldig rolle", + "error.user.undefined": "Brugeren kunne ikke findes", + "error.user.update.permission": "Du har ikke tilladelse til at opdatere brugeren \"{name}\"", + + "error.validation.accepted": "Bekræft venligst", + "error.validation.alpha": "Indtast venligst kun bogstaver imellem a-z", + "error.validation.alphanum": "Indtast venligst kun bogstaver og tal imellem a-z eller 0-9", + "error.validation.between": "Indtast venligst en værdi imellem \"{min}\" og \"{max}\"", + "error.validation.boolean": "Venligst bekræft eller afvis", + "error.validation.contains": "Indtast venligst en værdi der indeholder \"{needle}\"", + "error.validation.date": "Indtast venligst en gyldig dato", + "error.validation.date.after": "Indtast venligst en dato efter {date}", + "error.validation.date.before": "Indtast venligst en dato før {date}", + "error.validation.date.between": "Indtast venligst en dato imellem {min} og {max}", + "error.validation.denied": "Venligst afvis", + "error.validation.different": "Værdien må ikke være \"{other}\"", + "error.validation.email": "Indtast venligst en gyldig email adresse", + "error.validation.endswith": "Værdi skal ende med \"{end}\"", + "error.validation.filename": "Indtast venligst et gyldigt filnavn", + "error.validation.in": "Indtast venligst en af følgende: ({in})", + "error.validation.integer": "Indtast et gyldigt tal", + "error.validation.ip": "Indtast en gyldig IP adresse", + "error.validation.less": "Indtast venligst en værdi mindre end {max}", + "error.validation.match": "Værdien matcher ikke det forventede mønster", + "error.validation.max": "Indtast venligst en værdi lig med eller lavere end {max}", + "error.validation.maxlength": "Indtast venligst en kortere værdi. (maks. {max} karakterer)", + "error.validation.maxwords": "Indtast ikke flere end {max} ord", + "error.validation.min": "Indtast en værdi lig med eller højere end {min}", + "error.validation.minlength": "Indtast venligst en længere værdi. (min. {min} karakterer)", + "error.validation.minwords": "Indtast venligst mindst {min} ord", + "error.validation.more": "Indtast venligst en værdi større end {min}", + "error.validation.notcontains": "Indtast venligst en værdi der ikke indeholder \"{needle}\"", + "error.validation.notin": "Indtast venligst ikke nogen af følgende: ({notIn})", + "error.validation.option": "Vælg venligst en gyldig mulighed", + "error.validation.num": "Indtast venligst et gyldigt nummer", + "error.validation.required": "Indtast venligst noget", + "error.validation.same": "Indtast venligst \"{other}\"", + "error.validation.size": "Størrelsen på værdien skal være \"{size}\"", + "error.validation.startswith": "Værdien skal starte med \"{start}\"", + "error.validation.time": "Indtast venligst et gyldigt tidspunkt", + "error.validation.time.after": "Indtast venligst et tidspunkt efter {time}", + "error.validation.time.before": "Indtast venligst et tidspunkt inden {time}", + "error.validation.time.between": "Indtast venligst et tidspunkt imellem {min} og {max}", + "error.validation.url": "Indtast venligst en gyldig URL", + + "expand": "Fold ud", + "expand.all": "Fold alle ud", + + "field.required": "Feltet er påkrævet", + "field.blocks.changeType": "Skift type", + "field.blocks.code.name": "Kode", + "field.blocks.code.language": "Sprog", + "field.blocks.code.placeholder": "Din kode …", + "field.blocks.delete.confirm": "Ønsker du virkelig at slette denne blok?", + "field.blocks.delete.confirm.all": "Ønsker du virkelig at slette alle blokke?", + "field.blocks.delete.confirm.selected": "Ønsker du virkelig at slette de valgte blokke?", + "field.blocks.empty": "Ingen blokke endnu", + "field.blocks.fieldsets.label": "Vælg venligst en blok type", + "field.blocks.fieldsets.paste": "Tryk {{ shortcut }} for at indsætte/importere blokke fra dit udklipsholder", + "field.blocks.gallery.name": "Galleri", + "field.blocks.gallery.images.empty": "Ingen billeder endnu", + "field.blocks.gallery.images.label": "Billeder", + "field.blocks.heading.level": "Niveau", + "field.blocks.heading.name": "Overskrift", + "field.blocks.heading.text": "Tekst", + "field.blocks.heading.placeholder": "Overskrift …", + "field.blocks.image.alt": "Alternativ tekst", + "field.blocks.image.caption": "Billedtekst", + "field.blocks.image.crop": "Beskær", + "field.blocks.image.link": "Link", + "field.blocks.image.location": "Placering", + "field.blocks.image.name": "Billede", + "field.blocks.image.placeholder": "Vælg et billede", + "field.blocks.image.ratio": "Størrelsesforhold", + "field.blocks.image.url": "Billede URL", + "field.blocks.line.name": "Linje", + "field.blocks.list.name": "Liste", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Tekst", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Citat", + "field.blocks.quote.text.label": "Tekst", + "field.blocks.quote.text.placeholder": "Citat …", + "field.blocks.quote.citation.label": "Citeret af", + "field.blocks.quote.citation.placeholder": "af …", + "field.blocks.text.name": "Tekst", + "field.blocks.text.placeholder": "Tekst …", + "field.blocks.video.caption": "Billedtekst", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Indtast URL til en video", + "field.blocks.video.url.label": "Video-URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Ingen filer valgt endnu", + + "field.layout.delete": "Slet layout", + "field.layout.delete.confirm": "Ønsker du virkelig at slette dette layout", + "field.layout.empty": "Ingen rækker endnu", + "field.layout.select": "Vælg et layout", + + "field.object.empty": "No information yet", + + "field.pages.empty": "Ingen sider valgt endnu", + + "field.structure.delete.confirm": "\u00d8nsker du virkelig at slette denne indtastning?", + "field.structure.empty": "Ingen indtastninger endnu.", + + "field.users.empty": "Ingen brugere er valgt", + + "file.blueprint": "Denne fil har intet blueprint endnu. Du kan definere opsætningen i /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "\u00d8nsker du virkelig at slette denne fil?", + "file.sort": "Skift position", + + "files": "Filer", + "files.empty": "Ingen filer endnu", + + "hide": "Skjul", + "hour": "Time", + "import": "Importer", + "info": "Info", + "insert": "Inds\u00e6t", + "insert.after": "Indsæt efter", + "insert.before": "Indsæt før", + "install": "Installer", + + "installation": "Installation", + "installation.completed": "Panelet er blevet installeret", + "installation.disabled": "Panel installationen er deaktiveret på offentlige servere som standard. Kør venligst installationen på en lokal maskine eller aktiver det med panel.install panel.install muligheden.", + "installation.issues.accounts": "\/site\/accounts er ikke skrivbar", + "installation.issues.content": "Content mappen samt alle underliggende filer og mapper skal v\u00e6re skrivbare.", + "installation.issues.curl": "CURL extension er påkrævet", + "installation.issues.headline": "Panelet kan ikke installeres", + "installation.issues.mbstring": "MB String extension er påkrævet", + "installation.issues.media": "/media mappen eksisterer ikke eller er ikke skrivbar", + "installation.issues.php": "Sikre dig at der benyttes PHP 7+", + "installation.issues.server": "Kirby kræver Apache, Nginx eller Caddy", + "installation.issues.sessions": "/site/sessions mappen eksisterer ikke eller er ikke skrivbar", + + "language": "Sprog", + "language.code": "Kode", + "language.convert": "Gør standard", + "language.convert.confirm": "

Ønsker du virkelig at konvertere {name} til standardsproget? Dette kan ikke fortrydes.

Hvis {name} har uoversat indhold, vil der ikke længere være et gyldigt tilbagefald og dele af dit website vil måske fremstå tomt.

", + "language.create": "Tilføj nyt sprog", + "language.delete.confirm": "Ønsker du virkelig at slette sproget {name} inklusiv alle oversættelser? Kan ikke fortrydes!", + "language.deleted": "Sproget er blevet slettet", + "language.direction": "Læseretning", + "language.direction.ltr": "Venstre mod højre", + "language.direction.rtl": "Højre mod venstre", + "language.locale": "PHP locale string", + "language.locale.warning": "Du benytter en brugerdefineret sprogopsætning. Rediger venligst dette i sprogfilen i /site/languages", + "language.name": "Navn", + "language.updated": "Sproget er blevet opdateret", + + "languages": "Sprog", + "languages.default": "Standardsprog", + "languages.empty": "Der er ingen sprog endnu", + "languages.secondary": "Sekundære sprog", + "languages.secondary.empty": "Der er ingen sekundære sprog endnu", + + "license": "Kirby licens", + "license.buy": "Køb en licens", + "license.register": "Registrer", + "license.manage": "Manage your licenses", + "license.register.help": "Du modtog din licenskode efter købet via email. Venligst kopier og indsæt den for at registrere.", + "license.register.label": "Indtast venligst din licenskode", + "license.register.success": "Tak for din støtte af Kirby", + "license.unregistered": "Dette er en uregistreret demo af Kirby", + "license.unregistered.label": "Unregistered", + + "link": "Link", + "link.text": "Link tekst", + + "loading": "Indlæser", + + "lock.unsaved": "Ugemte ændringer", + "lock.unsaved.empty": "Der er ikke flere ændringer der ikke er gamt", + "lock.isLocked": "Ugemte ændringer af {email}", + "lock.file.isLocked": "Filen redigeres på nuværende af {email} og kan derfor ikke ændres.", + "lock.page.isLocked": "Siden redigeres på nuværende af {email} og kan derfor ikke ændres.", + "lock.unlock": "Lås op", + "lock.isUnlocked": "Dine ugemte ændringer er blevet overskrevet af en anden bruger. Du kan downloade dine ændringer for at flette dem ind manuelt.", + + "login": "Log ind", + "login.code.label.login": "Log ind kode", + "login.code.label.password-reset": "Sikkerhedskode", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "Hvis din email adresse er registreret er en sikkerhedskode blevet sendt via email.", + "login.email.login.body": "Hej {user.nameOrEmail},\n\nDu har for nyligt anmodet om en log ind kode til panelet af {site}.\nFølgende log ind kode vil være gyldig i {timeout} minutter:\n\n{code}\n\nHvis du ikke har anmodet om en log ind kode, kan du blot ignorere denne email eller kontakte din administrator hvis du har spørgsmål.\nAf sikkerhedsmæssige årsager, bør du IKKE videresende denne email.", + "login.email.login.subject": "Din log ind kode", + "login.email.password-reset.body": "Hej {user.nameOrEmail},\n\nDu har for nyligt anmodet om kode til nulstilling af adgangskode til panelet af {site}.\nFølgende kode til nulstilling af adgangskode vil være gyldig i {timeout} minutter:\n\n{code}\n\nHvis du ikke har anmodet om kode til nulstilling af adgangskode, kan du blot ignorere denne email eller kontakte din administrator hvis du har spørgsmål.\nAf sikkerhedsmæssige årsager, bør du IKKE videresende denne email.", + "login.email.password-reset.subject": "Din kode til nulstilling af adgangskode", + "login.remember": "Forbliv logget ind", + "login.reset": "Nulstil adgangskode", + "login.toggleText.code.email": "Log ind via email", + "login.toggleText.code.email-password": "Log ind med adgangskode", + "login.toggleText.password-reset.email": "Glemt din adgangskode?", + "login.toggleText.password-reset.email-password": "← Tilbage til log ind", + + "logout": "Log ud", + + "menu": "Menu", + "meridiem": "AM/PM", + "mime": "Medie Type", + "minutes": "Minutter", + + "month": "Måned", + "months.april": "April", + "months.august": "August", + "months.december": "December", + "months.february": "Februar", + "months.january": "Januar", + "months.july": "Juli", + "months.june": "Juni", + "months.march": "Marts", + "months.may": "Maj", + "months.november": "November", + "months.october": "Oktober", + "months.september": "September", + + "more": "Mere", + "name": "Navn", + "next": "Næste", + "no": "nej", + "off": "Sluk", + "on": "Aktiveret", + "open": "Åben", + "open.newWindow": "Åben i et nyt vindue", + "options": "Indstillinger", + "options.none": "Ingen muligheder", + + "orientation": "Orientering", + "orientation.landscape": "Landskab", + "orientation.portrait": "Portræt", + "orientation.square": "Kvadrat", + + "page.blueprint": "Denne side har intet blueprint endnu. Du kan definere opsætningen i /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "\u00c6ndre URL", + "page.changeSlug.fromTitle": "Generer udfra titel", + "page.changeStatus": "Skift status", + "page.changeStatus.position": "Vælg venligst position", + "page.changeStatus.select": "Vælg en ny status", + "page.changeTemplate": "Skift skabelon", + "page.delete.confirm": "\u00d8nsker du virkelig at slette denne side?", + "page.delete.confirm.subpages": "Denne side har undersider.
Alle undersider vil også blive slettet.", + "page.delete.confirm.title": "Indtast sidens titel for at bekræfte", + "page.draft.create": "Opret kladde", + "page.duplicate.appendix": "Kopier", + "page.duplicate.files": "Kopier filer", + "page.duplicate.pages": "Kopier sider", + "page.sort": "Skift position", + "page.status": "Status", + "page.status.draft": "Kladde", + "page.status.draft.description": "Siden er i kladde udgave og er kun synlig for redaktører der er logget ind eller via hemmeligt link", + "page.status.listed": "Offentlig", + "page.status.listed.description": "Siden er offentlig for enhver", + "page.status.unlisted": "Ulistede", + "page.status.unlisted.description": "Siden er kun tilgængelig via URL", + + "pages": "Sider", + "pages.empty": "Ingen sider endnu", + "pages.status.draft": "Kladder", + "pages.status.listed": "Udgivede", + "pages.status.unlisted": "Ulistede", + + "pagination.page": "Side", + + "password": "Adgangskode", + "paste": "Indsæt", + "paste.after": "Indsæt efter", + "pixel": "Pixel", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "Forrige", + "preview": "Forhåndsvisning", + "remove": "Fjern", + "rename": "Omdøb", + "replace": "Erstat", + "retry": "Pr\u00f8v igen", + "revert": "Kass\u00e9r", + "revert.confirm": "Ønsker du virkelig at slette all ændringer der ikke er gemt?", + + "role": "Rolle", + "role.admin.description": "Admin har alle rettigheder", + "role.admin.title": "Admin", + "role.all": "All", + "role.empty": "Der er ingen bruger med denne rolle", + "role.description.placeholder": "Ingen beskrivelse", + "role.nobody.description": "Dette er en tilbagefaldsrolle uden rettigheder", + "role.nobody.title": "Ingen", + + "save": "Gem", + "search": "Søg", + "search.min": "Indtast {min} tegn for at søge", + "search.all": "Vis alle", + "search.results.none": "Ingen resultater", + + "section.required": "Sektionen er påkrævet", + + "security": "Security", + "select": "Vælg", + "server": "Server", + "settings": "Indstillinger", + "show": "Vis", + "site.blueprint": "Sitet har intet blueprint endnu. Du kan definere opsætningen i /site/blueprints/site.yml", + "size": "Størrelse", + "slug": "URL-appendiks", + "sort": "Sorter", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Titel", + "template": "Skabelon", + "today": "Idag", + + "toolbar.button.code": "Kode", + "toolbar.button.bold": "Fed tekst", + "toolbar.button.email": "Email", + "toolbar.button.headings": "Overskrifter", + "toolbar.button.heading.1": "Overskrift 1", + "toolbar.button.heading.2": "Overskrift 2", + "toolbar.button.heading.3": "Overskrift 3", + "toolbar.button.heading.4": "Overskrift 4", + "toolbar.button.heading.5": "Overskrift 5", + "toolbar.button.heading.6": "Overskrift 6", + "toolbar.button.italic": "Kursiv tekst", + "toolbar.button.file": "Fil", + "toolbar.button.file.select": "Vælg en fil", + "toolbar.button.file.upload": "Upload en fil", + "toolbar.button.link": "Link", + "toolbar.button.paragraph": "Afsnit", + "toolbar.button.strike": "Gennemstreg", + "toolbar.button.ol": "Ordnet liste", + "toolbar.button.underline": "Understreg", + "toolbar.button.ul": "Punktliste", + + "translation.author": "Kirby Team", + "translation.direction": "ltr", + "translation.name": "Dansk", + "translation.locale": "da_DK", + + "upload": "Upload", + "upload.error.cantMove": "Den uploadede fil kunne ikke flyttes", + "upload.error.cantWrite": "Kunne ikke skrive fil til disk", + "upload.error.default": "Filen kunne ikke uploades", + "upload.error.extension": "Upload af filen blev stoppet af dens type", + "upload.error.formSize": "Filen overskrider MAX_FILE_SIZE direktivet der er specificeret for formularen", + "upload.error.iniPostSize": "FIlen overskrider post_max_size direktivet i php.ini", + "upload.error.iniSize": "FIlen overskrider upload_max_filesize direktivet i php.ini", + "upload.error.noFile": "Ingen fil blev uploadet", + "upload.error.noFiles": "Ingen filer blev uploadet", + "upload.error.partial": "Den uploadede fil blev kun delvist uploadet", + "upload.error.tmpDir": "Der mangler en midlertidig mappe", + "upload.errors": "Fejl", + "upload.progress": "Uploader...", + + "url": "Url", + "url.placeholder": "https://example.com", + + "user": "Bruger", + "user.blueprint": "Du kan definere yderligere sektioner og formular felter for denne brugerrolle i /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Skift email", + "user.changeLanguage": "Skift sprog", + "user.changeName": "Omdøb denne bruger", + "user.changePassword": "Skift adgangskode", + "user.changePassword.new": "Ny adgangskode", + "user.changePassword.new.confirm": "Bekræft den nye adgangskode...", + "user.changeRole": "Skift rolle", + "user.changeRole.select": "Vælg en ny rolle", + "user.create": "Tilføj en ny bruger", + "user.delete": "Slet denne bruger", + "user.delete.confirm": "\u00d8nsker du virkelig at slette denne bruger?", + + "users": "Brugere", + + "version": "Kirby version", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "Din konto", + "view.installation": "Installation", + "view.languages": "Sprog", + "view.resetPassword": "Nulstil adgangskode", + "view.site": "Website", + "view.system": "System", + "view.users": "Brugere", + + "welcome": "Velkommen", + "year": "År", + "yes": "ja" } diff --git a/kirby/i18n/translations/de.json b/kirby/i18n/translations/de.json index ae1052e..80c969d 100644 --- a/kirby/i18n/translations/de.json +++ b/kirby/i18n/translations/de.json @@ -1,573 +1,596 @@ { - "account.changeName": "Deinen Namen ändern", - "account.delete": "Deinen Account löschen", - "account.delete.confirm": "Willst du deinen Account wirklich löschen? Du wirst sofort danach abgemeldet. Dein Account kann nicht wieder hergestellt werden. ", - - "add": "Hinzuf\u00fcgen", - "author": "Autor", - "avatar": "Profilbild", - "back": "Zurück", - "cancel": "Abbrechen", - "change": "\u00c4ndern", - "close": "Schlie\u00dfen", - "confirm": "OK", - "collapse": "Zusammenklappen", - "collapse.all": "Alle zusammenklappen", - "copy": "Kopieren", - "copy.all": "Alle kopieren", - "create": "Erstellen", - - "date": "Datum", - "date.select": "Datum auswählen", - - "day": "Tag", - "days.fri": "Fr", - "days.mon": "Mo", - "days.sat": "Sa", - "days.sun": "So", - "days.thu": "Do", - "days.tue": "Di", - "days.wed": "Mi", - - "debugging": "Debugging", - - "delete": "L\u00f6schen", - "delete.all": "Alle löschen", - - "dialog.files.empty": "Keine verfügbaren Dateien", - "dialog.pages.empty": "Keine verfügbaren Seiten", - "dialog.users.empty": "Keine verfügbaren Accounts", - - "dimensions": "Maße", - "disabled": "Gesperrt", - "discard": "Verwerfen", - "download": "Download", - "duplicate": "Duplizieren", - - "edit": "Bearbeiten", - - "email": "E-Mail", - "email.placeholder": "mail@beispiel.de", - - "entries": "Einträge", - "entry": "Eintrag", - - "environment": "Umgebung", - - "error.access.code": "Ungültiger Code", - "error.access.login": "Ungültige Zugangsdaten", - "error.access.panel": "Du hast keinen Zugang zum Panel", - "error.access.view": "Du hast keinen Zugriff auf diesen Teil des Panels", - - "error.avatar.create.fail": "Das Profilbild konnte nicht hochgeladen werden", - "error.avatar.delete.fail": "Das Profilbild konnte nicht gel\u00f6scht werden", - "error.avatar.dimensions.invalid": "Bitte lade ein Profilbild hoch, das nicht breiter oder höher als 3000 Pixel ist.", - "error.avatar.mime.forbidden": "Das Profilbild muss vom Format JPEG oder PNG sein", - - "error.blueprint.notFound": "Das Blueprint \"{name}\" konnte nicht geladen werden.", - - "error.blocks.max.plural": "Bitte füge nicht mehr als {max} Blöcke hinzu", - "error.blocks.max.singular": "Bitte füge nicht mehr als einen Block hinzu", - "error.blocks.min.plural": "Bitte füge mindestens {min} Blöcke hinzu", - "error.blocks.min.singular": "Bitte füge mindestens einen Block hinzu", - "error.blocks.validation": "Fehler in Block {index}", - - "error.email.preset.notFound": "Die E-Mailvorlage \"{name}\" wurde nicht gefunden", - - "error.field.converter.invalid": "Ungültiger Konverter: \"{converter}\"", - - "error.file.changeName.empty": "Bitte gib einen Namen an", - "error.file.changeName.permission": "Du darfst den Dateinamen von \"{filename}\" nicht ändern", - "error.file.duplicate": "Eine Datei mit dem Dateinamen \"{filename}\" besteht bereits", - "error.file.extension.forbidden": "Verbotene Dateiendung \"{extension}\"", - "error.file.extension.invalid": "Verbotene Dateiendung \"{extension}\"", - "error.file.extension.missing": "Du kannst keine Dateien ohne Dateiendung hochladen", - "error.file.maxheight": "Die Bildhöhe darf {height} Pixel nicht überschreiten", - "error.file.maxsize": "Die Datei ist zu groß", - "error.file.maxwidth": "Die Bildbreite darf {width} Pixel nicht überschreiten", - "error.file.mime.differs": "Die Datei muss den Medientyp \"{mime}\" haben.", - "error.file.mime.forbidden": "Der Medientyp \"{mime}\" ist nicht erlaubt", - "error.file.mime.invalid": "Ungültiger Dateityp: {mime}", - "error.file.mime.missing": "Der Medientyp für \"{filename}\" konnte nicht erkannt werden", - "error.file.minheight": "Die Bildhöhe muss mindestens {height} Pixel betragen", - "error.file.minsize": "Die Datei ist zu klein", - "error.file.minwidth": "Die Bildbreite muss mindestens {width} Pixel betragen", - "error.file.name.missing": "Bitte gib einen Dateinamen an", - "error.file.notFound": "Die Datei \"{filename}\" konnte nicht gefunden werden", - "error.file.orientation": "Das Bildformat ist ungültig. Erwartetes Format: \"{orientation}\"", - "error.file.type.forbidden": "Du kannst keinen {type}-Dateien hochladen", - "error.file.type.invalid": "Ungültiger Dateityp: {mime}", - "error.file.undefined": "Die Datei konnte nicht gefunden werden", - - "error.form.incomplete": "Bitte behebe alle Fehler …", - "error.form.notSaved": "Das Formular konnte nicht gespeichert werden", - - "error.language.code": "Bitte gib einen gültigen Code für die Sprache an", - "error.language.duplicate": "Die Sprache besteht bereits", - "error.language.name": "Bitte gib einen gültigen Namen für die Sprache an", - "error.language.notFound": "Die Sprache konnte nicht gefunden werden", - - "error.layout.validation.block": "Fehler in Block {blockIndex} in Layout {layoutIndex}", - "error.layout.validation.settings": "Fehler in den Einstellungen von Layout {index}", - - "error.license.format": "Bitte gib einen gültigen Lizenzschlüssel ein", - "error.license.email": "Bitte gib eine gültige E-Mailadresse an", - "error.license.verification": "Die Lizenz konnte nicht verifiziert werden", - - "error.offline": "Das Panel ist zur Zeit offline", - - "error.page.changeSlug.permission": "Du darfst die URL der Seite \"{slug}\" nicht ändern", - "error.page.changeStatus.incomplete": "Die Seite ist nicht vollständig und kann daher nicht veröffentlicht werden", - "error.page.changeStatus.permission": "Der Status der Seite kann nicht geändert werden", - "error.page.changeStatus.toDraft.invalid": "Die Seite \"{slug}\" kann nicht in einen Entwurf umgewandelt werden", - "error.page.changeTemplate.invalid": "Die Vorlage für die Seite \"{slug}\" kann nicht geändert werden", - "error.page.changeTemplate.permission": "Du kannst die Vorlage für die Seite \"{slug}\" nicht ändern", - "error.page.changeTitle.empty": "Bitte gib einen Titel an", - "error.page.changeTitle.permission": "Du kannst den Titel für die Seite \"{slug}\" nicht ändern", - "error.page.create.permission": "Du kannst die Seite \"{slug}\" nicht anlegen", - "error.page.delete": "Die Seite \"{slug}\" kann nicht gelöscht werden", - "error.page.delete.confirm": "Bitte gib zur Bestätigung den Seitentitel ein", - "error.page.delete.hasChildren": "Die Seite hat Unterseiten und kann nicht gelöscht werden", - "error.page.delete.permission": "Du kannst die Seite \"{slug}\" nicht löschen", - "error.page.draft.duplicate": "Ein Entwurf mit dem URL-Kürzel \"{slug}\" besteht bereits", - "error.page.duplicate": "Eine Seite mit dem URL-Kürzel \"{slug}\" besteht bereits", - "error.page.duplicate.permission": "Du kannst die Seite \"{slug}\" nicht duplizieren", - "error.page.notFound": "Die Seite \"{slug}\" konnte nicht gefunden werden", - "error.page.num.invalid": "Bitte gib eine gültige Sortierungszahl an. Negative Zahlen sind nicht erlaubt.", - "error.page.slug.invalid": "Bitte gib ein gültiges URL-Kürzel an", - "error.page.slug.maxlength": "Die Pfadlänge darf {length} Zeichen nicht überschreiten", - "error.page.sort.permission": "Die Seite \"{slug}\" kann nicht umsortiert werden", - "error.page.status.invalid": "Bitte gib einen gültigen Seitenstatus an", - "error.page.undefined": "Die Seite konnte nicht gefunden werden", - "error.page.update.permission": "Du kannst die Seite \"{slug}\" nicht editieren", - - "error.section.files.max.plural": "Bitte füge nicht mehr als {max} Dateien zum Bereich \"{section}\" hinzu", - "error.section.files.max.singular": "Bitte füge nicht mehr als eine Datei zum Bereich \"{section}\" hinzu", - "error.section.files.min.plural": "Der Bereich \"{section}\" benötigt mindestens {min} Dateien", - "error.section.files.min.singular": "Der Bereich \"{section}\" benötigt mindestens eine Datei", - - "error.section.pages.max.plural": "Bitte füge nicht mehr als {max} Seiten zum Bereich \"{section}\" hinzu", - "error.section.pages.max.singular": "Bitte füge nicht mehr als eine Seite zum Bereich \"{section}\" hinzu", - "error.section.pages.min.plural": "Der Bereich \"{section}\" benötigt mindestens {min} Seiten", - "error.section.pages.min.singular": "Der Bereich \"{section}\" benötigt mindestens eine Seite", - - "error.section.notLoaded": "Der Bereich \"{name}\" konnte nicht geladen werden", - "error.section.type.invalid": "Der Bereichstyp \"{type}\" ist nicht gültig", - - "error.site.changeTitle.empty": "Bitte gib einen Titel an", - "error.site.changeTitle.permission": "Du kannst den Titel der Seite nicht ändern", - "error.site.update.permission": "Du darfst die Seite nicht bearbeiten", - - "error.template.default.notFound": "Die \"Default\"-Vorlage existiert nicht", - - "error.unexpected": "Ein unerwarteter Fehler ist aufgetreten. Aktiviere den Debug Modus für weitere Informationen: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Du kannst die E-Mailadresse für den Account \"{name}\" nicht ändern", - "error.user.changeLanguage.permission": "Du kannst die Sprache für den Account \"{name}\" nicht ändern", - "error.user.changeName.permission": "Du kannst den Namen für den Account \"{name}\" nicht ändern", - "error.user.changePassword.permission": "Du kannst das Passwort für den Account \"{name}\" nicht ändern", - "error.user.changeRole.lastAdmin": "Die Rolle des letzten Accounts mit Administrationsrechten kann nicht geändert werden", - "error.user.changeRole.permission": "Du kannst die Rolle für den Benutzer \"{name}\" nicht ändern", - "error.user.changeRole.toAdmin": "Du darfst die Admin-Rolle nicht an andere Accounts vergeben", - "error.user.create.permission": "Du darfst diesen Account nicht anlegen", - "error.user.delete": "Der Account \"{name}\" konnte nicht gelöscht werden", - "error.user.delete.lastAdmin": "Du kannst den letzten Account mit Administrationsrechten nicht löschen", - "error.user.delete.lastUser": "Der letzte Account kann nicht gelöscht werden", - "error.user.delete.permission": "Du darfst den Account \"{name}\" nicht löschen", - "error.user.duplicate": "Ein Account mit der E-Mailadresse \"{email}\" besteht bereits", - "error.user.email.invalid": "Bitte gib eine gültige E-Mailadresse an", - "error.user.language.invalid": "Bitte gib eine gültige Sprache an", - "error.user.notFound": "Der Account \"{name}\" wurde nicht gefunden", - "error.user.password.invalid": "Bitte gib ein gültiges Passwort ein. Passwörter müssen mindestens 8 Zeichen lang sein.", - "error.user.password.notSame": "Die Passwörter stimmen nicht überein", - "error.user.password.undefined": "Der Account hat kein Passwort", - "error.user.password.wrong": "Falsches Passwort", - "error.user.role.invalid": "Bitte gib eine gültige Rolle an", - "error.user.undefined": "Der Benutzer wurde nicht gefunden", - "error.user.update.permission": "Du darfst den den Account \"{name}\" nicht bearbeiten", - - "error.validation.accepted": "Bitte bestätige", - "error.validation.alpha": "Bitte gib nur Zeichen zwischen A und Z ein", - "error.validation.alphanum": "Bitte gib nur Zeichen zwischen A und Z und Zahlen zwischen 0 und 9 ein", - "error.validation.between": "Bitte gib einen Wert zwischen \"{min}\" und \"{max}\" ein", - "error.validation.boolean": "Bitte bestätige oder lehne ab", - "error.validation.contains": "Bitte gib einen Wert ein, der \"{needle}\" enthält", - "error.validation.date": "Bitte gib ein gültiges Datum ein", - "error.validation.date.after": "Bitte gib ein Datum nach dem {date} ein", - "error.validation.date.before": "Bitte gib ein Datum vor dem {date} ein", - "error.validation.date.between": "Bitte gib ein Datum zwischen dem {min} und dem {max} ein", - "error.validation.denied": "Bitte lehne die Eingabe ab", - "error.validation.different": "Der Wert darf nicht \"{other}\" sein", - "error.validation.email": "Bitte gib eine gültige E-Mailadresse an", - "error.validation.endswith": "Der Wert muss auf \"{end}\" enden", - "error.validation.filename": "Bitte gib einen gültigen Dateinamen ein", - "error.validation.in": "Bitte gib einen der folgenden Werte ein: ({in})", - "error.validation.integer": "Bitte gib eine ganze Zahl ein", - "error.validation.ip": "Bitte gib eine gültige IP Adresse ein", - "error.validation.less": "Bitte gib einen Wert kleiner als {max} ein", - "error.validation.match": "Der Wert entspricht nicht dem erwarteten Muster", - "error.validation.max": "Bitte gib einen Wert ein, der nicht größer als {max} ist", - "error.validation.maxlength": "Bitte gib einen kürzeren Text ein (max. {max} Zeichen)", - "error.validation.maxwords": "Bitte nutze nicht mehr als {max} Wort(e)", - "error.validation.min": "Bitte gib einen Wert ein, der nicht kleiner als {min} ist", - "error.validation.minlength": "Bitte gib einen längeren Text ein. (min. {min} Zeichen)", - "error.validation.minwords": "Bitte nutze mindestens {min} Wort(e)", - "error.validation.more": "Bitte gib einen größeren Wert als {min} ein", - "error.validation.notcontains": "Bitte gib einen Wert ein, der nicht \"{needle}\" enthält", - "error.validation.notin": "Bitte gib keinen der folgenden Werte ein: ({notIn})", - "error.validation.option": "Bitte wähle eine gültige Option aus", - "error.validation.num": "Bitte gib eine gültige Zahl an", - "error.validation.required": "Bitte gib etwas ein", - "error.validation.same": "Bitte gib \"{other}\" ein", - "error.validation.size": "Die Größe des Wertes muss \"{size}\" sein", - "error.validation.startswith": "Der Wert muss mit \"{start}\" beginnen", - "error.validation.time": "Bitte gib eine gültige Uhrzeit ein", - "error.validation.time.after": "Bitte gib eine Zeit nach {time} ein", - "error.validation.time.before": "Bitte gib eine Zeit vor {time} ein", - "error.validation.time.between": "Bitte gib eine Zeit zwischen {min} und {max} ein", - "error.validation.url": "Bitte gib eine gültige URL ein", - - "expand": "Aufklappen", - "expand.all": "Alle aufklappen", - - "field.required": "Das Feld ist Pflicht", - "field.blocks.changeType": "Blocktyp ändern", - "field.blocks.code.name": "Code", - "field.blocks.code.language": "Sprache", - "field.blocks.code.placeholder": "Code …", - "field.blocks.delete.confirm": "Willst du diesen Block wirklich löschen?", - "field.blocks.delete.confirm.all": "Willst du wirklich alle Blöcke löschen?", - "field.blocks.delete.confirm.selected": "Willst du wirklich die ausgewählten Blöcke löschen?", - "field.blocks.empty": "Keine Blöcke", - "field.blocks.fieldsets.label": "Bitte wähle einen Blocktyp aus …", - "field.blocks.fieldsets.paste": "Drücke {{ shortcut }} um Blöcke aus der Zwischenablage zu importieren", - "field.blocks.gallery.name": "Galerie", - "field.blocks.gallery.images.empty": "Keine Bilder", - "field.blocks.gallery.images.label": "Bilder", - "field.blocks.heading.level": "Ebene", - "field.blocks.heading.name": "Überschrift", - "field.blocks.heading.text": "Text", - "field.blocks.heading.placeholder": "Überschrift …", - "field.blocks.image.alt": "Alternativer Text", - "field.blocks.image.caption": "Bildunterschrift", - "field.blocks.image.crop": "Beschneiden", - "field.blocks.image.link": "Link", - "field.blocks.image.location": "Ort", - "field.blocks.image.name": "Bild", - "field.blocks.image.placeholder": "Bild auswählen", - "field.blocks.image.ratio": "Seitenverhältnis", - "field.blocks.image.url": "Bild URL", - "field.blocks.line.name": "Linie", - "field.blocks.list.name": "Liste", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Text", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Zitat", - "field.blocks.quote.text.label": "Text", - "field.blocks.quote.text.placeholder": "Zitat …", - "field.blocks.quote.citation.label": "Quelle", - "field.blocks.quote.citation.placeholder": "Quelle …", - "field.blocks.text.name": "Text", - "field.blocks.text.placeholder": "Text …", - "field.blocks.video.caption": "Bildunterschrift", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Video-URL eingeben", - "field.blocks.video.url.label": "Video-URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Keine Dateien ausgewählt", - - "field.layout.delete": "Layout löschen", - "field.layout.delete.confirm": "Willst du dieses Layout wirklich löschen?", - "field.layout.empty": "Keine Layouts", - "field.layout.select": "Layout auswählen", - - "field.pages.empty": "Keine Seiten ausgewählt", - "field.structure.delete.confirm": "Willst du diesen Eintrag wirklich l\u00f6schen?", - "field.structure.empty": "Es bestehen keine Eintr\u00e4ge.", - "field.users.empty": "Keine Accounts ausgewählt", - - "file.blueprint": "Du kannst zusätzliche Felder und Bereiche für diese Datei in /site/blueprints/files/{blueprint}.yml anlegen", - "file.delete.confirm": "Willst du die Datei {filename}
wirklich löschen?", - "file.sort": "Position ändern", - - "files": "Dateien", - "files.empty": "Keine Dateien", - - "hide": "Verbergen", - "hour": "Stunde", - "import": "Importieren", - "info": "Info", - "insert": "Einf\u00fcgen", - "insert.after": "Danach einfügen", - "insert.before": "Davor einfügen", - "install": "Installieren", - - "installation": "Installation", - "installation.completed": "Das Panel wurde installiert", - "installation.disabled": "Die Panel-Installation ist auf öffentlichen Servern automatisch deaktiviert. Bitte installiere das Panel auf einem lokalen Server oder aktiviere die Installation gezielt mit der panel.install Option. ", - "installation.issues.accounts": "/site/accounts ist nicht beschreibbar", - "installation.issues.content": "/content existiert nicht oder ist nicht beschreibbar", - "installation.issues.curl": "Die CURL Erweiterung wird benötigt", - "installation.issues.headline": "Das Panel kann nicht installiert werden", - "installation.issues.mbstring": "Die MB String Erweiterung wird benötigt", - "installation.issues.media": "Der /media Ordner ist nicht beschreibbar", - "installation.issues.php": "Bitte verwende PHP 7+", - "installation.issues.server": "Kirby benötigt Apache, Nginx or Caddy", - "installation.issues.sessions": "/site/sessions ist nicht beschreibbar", - - "language": "Sprache", - "language.code": "Code", - "language.convert": "Als Standard auswählen", - "language.convert.confirm": "

Willst du {name} wirklich in die Standardsprache umwandeln? Dieser Schritt kann nicht rückgängig gemacht werden.

Wenn {name} unübersetzte Felder hat, gibt es keine gültigen Standardwerte für diese Felder und Inhalte könnten verloren gehen.

", - "language.create": "Neue Sprache anlegen", - "language.delete.confirm": "Willst du {name} inklusive aller Übersetzungen wirklich löschen? Dieser Schritt kann nicht rückgängig gemacht werden!", - "language.deleted": "Die Sprache wurde gelöscht", - "language.direction": "Leserichtung", - "language.direction.ltr": "Von links nach rechts", - "language.direction.rtl": "Von rechts nach links", - "language.locale": "PHP locale string", - "language.locale.warning": "Du nutzt ein angepasstes Setup for PHP Locales. Bitte bearbeite dieses direkt in der entsprechenden Sprachdatei in /site/languages", - "language.name": "Name", - "language.updated": "Die Sprache wurde gespeichert", - - "languages": "Sprachen", - "languages.default": "Standardsprache", - "languages.empty": "Noch keine Sprachen", - "languages.secondary": "Sekundäre Sprachen", - "languages.secondary.empty": "Noch keine sekundären Sprachen", - - "license": "Lizenz", - "license.buy": "Kaufe eine Lizenz", - "license.register": "Registrieren", - "license.manage": "Verwalte deine Lizenzen", - "license.register.help": "Den Lizenzcode findest du in der Bestätigungsmail zu deinem Kauf. Bitte kopiere und füge ihn ein, um Kirby zu registrieren.", - "license.register.label": "Bitte gib deinen Lizenzcode ein", - "license.register.success": "Vielen Dank für deine Unterstützung", - "license.unregistered": "Dies ist eine unregistrierte Kirby-Demo", - "license.unregistered.label": "Unregistriert", - - "link": "Link", - "link.text": "Linktext", - - "loading": "Laden", - - "lock.unsaved": "Ungespeicherte Änderungen", - "lock.unsaved.empty": "Keine ungespeicherten Änderungen", - "lock.isLocked": "Ungespeicherte Änderungen von {email}", - "lock.file.isLocked": "Die Datei wird von {email} bearbeitet und kann nicht geändert werden.", - "lock.page.isLocked": "Die Seite wird von {email} bearbeitet und kann nicht geändert werden.", - "lock.unlock": "Entsperren", - "lock.isUnlocked": "Deine ungespeicherten Änderungen wurden von einem anderen Account überschrieben. Du kannst sie herunterladen, um sie manuell einzufügen. ", - - "login": "Anmelden", - "login.code.label.login": "Anmeldecode", - "login.code.label.password-reset": "Anmeldecode", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "Wenn deine E-Mail-Adresse registriert ist, wurde der angeforderte Code per E-Mail versendet.", - "login.email.login.body": "Hallo {user.nameOrEmail},\n\ndu hast gerade einen Anmeldecode für das Kirby Panel von {site} angefordert.\n\nDer folgende Anmeldecode ist für die nächsten {timeout} Minuten gültig:\n\n{code}\n\nWenn du keinen Anmeldecode angefordert hast, ignoriere bitte diese E-Mail oder kontaktiere bei Fragen deinen Administrator.\nBitte leite diese E-Mail aus Sicherheitsgründen NICHT weiter.", - "login.email.login.subject": "Dein Anmeldecode", - "login.email.password-reset.body": "Hallo {user.nameOrEmail},\n\ndu hast gerade einen Anmeldecode für das Kirby Panel von {site} angefordert.\n\nDer folgende Anmeldecode ist für die nächsten {timeout} Minuten gültig:\n\n{code}\n\nWenn du keinen Anmeldecode angefordert hast, ignoriere bitte diese E-Mail oder kontaktiere bei Fragen deinen Administrator.\nBitte leite diese E-Mail aus Sicherheitsgründen NICHT weiter.", - "login.email.password-reset.subject": "Dein Anmeldecode", - "login.remember": "Angemeldet bleiben", - "login.reset": "Passwort zurücksetzen", - "login.toggleText.code.email": "Anmelden über E-Mail", - "login.toggleText.code.email-password": "Anmelden mit Passwort", - "login.toggleText.password-reset.email": "Passwort vergessen?", - "login.toggleText.password-reset.email-password": "← Zurück zur Anmeldung", - - "logout": "Abmelden", - - "menu": "Menü", - "meridiem": "AM/PM", - "mime": "Medientyp", - "minutes": "Minuten", - - "month": "Monat", - "months.april": "April", - "months.august": "August", - "months.december": "Dezember", - "months.february": "Februar", - "months.january": "Januar", - "months.july": "Juli", - "months.june": "Juni", - "months.march": "M\u00e4rz", - "months.may": "Mai", - "months.november": "November", - "months.october": "Oktober", - "months.september": "September", - - "more": "Mehr", - "name": "Name", - "next": "Nächster Eintrag", - "no": "nein", - "off": "aus", - "on": "an", - "open": "Öffnen", - "open.newWindow": "In neuem Fenster öffnen", - "options": "Optionen", - "options.none": "Keine Optionen", - - "orientation": "Ausrichtung", - "orientation.landscape": "Querformat", - "orientation.portrait": "Hochformat", - "orientation.square": "Quadratisch", - - "page.blueprint": "Du kannst zusätzliche Felder und Bereiche für diese Seite in /site/blueprints/pages/{blueprint}.yml anlegen", - "page.changeSlug": "URL \u00e4ndern", - "page.changeSlug.fromTitle": "Aus Titel erzeugen", - "page.changeStatus": "Status ändern", - "page.changeStatus.position": "Bitte wähle eine Position aus", - "page.changeStatus.select": "Wähle einen neuen Status aus", - "page.changeTemplate": "Vorlage ändern", - "page.delete.confirm": "Willst du die Seite {title} wirklich löschen?", - "page.delete.confirm.subpages": "Diese Seite hat Unterseiten.
Alle Unterseiten werden ebenfalls gelöscht.", - "page.delete.confirm.title": "Gib zur Bestätigung den Seitentitel ein", - "page.draft.create": "Entwurf anlegen", - "page.duplicate.appendix": "Kopie", - "page.duplicate.files": "Dateien kopieren", - "page.duplicate.pages": "Seiten kopieren", - "page.sort": "Position ändern", - "page.status": "Status", - "page.status.draft": "Entwurf", - "page.status.draft.description": "Die Seite ist im Entwurfsmodus und ist nur nach Anmeldung oder über den geheimen Link sichtbar", - "page.status.listed": "Öffentlich", - "page.status.listed.description": "Die Seite ist öffentlich für alle", - "page.status.unlisted": "Ungelistet", - "page.status.unlisted.description": "Die Seite kann nur über die URL aufgerufen werden", - - "pages": "Seiten", - "pages.empty": "Keine Seiten", - "pages.status.draft": "Entwürfe", - "pages.status.listed": "Veröffentlicht", - "pages.status.unlisted": "Ungelistet", - - "pagination.page": "Seite", - - "password": "Passwort", - "paste": "Einfügen", - "paste.after": "Danach einfügen", - "pixel": "Pixel", - "plugins": "Plugins", - "prev": "Vorheriger Eintrag", - "preview": "Vorschau", - "remove": "Entfernen", - "rename": "Umbenennen", - "replace": "Ersetzen", - "retry": "Wiederholen", - "revert": "Verwerfen", - "revert.confirm": "Willst du wirklich alle ungespeicherten Änderungen verwerfen? ", - - "role": "Rolle", - "role.admin.description": "Admins haben alle Rechte", - "role.admin.title": "Admin", - "role.all": "Alle", - "role.empty": "Keine Accounts mit dieser Rolle", - "role.description.placeholder": "Keine Beschreibung", - "role.nobody.description": "Dies ist die Platzhalterrolle ohne Rechte", - "role.nobody.title": "Niemand", - - "save": "Speichern", - "search": "Suchen", - "search.min": "Gib mindestens {min}  Zeichen ein, um zu suchen", - "search.all": "Alles zeigen", - "search.results.none": "Keine Ergebnisse", - - "section.required": "Der Bereich ist Pflicht", - - "security": "Sicherheit", - "select": "Auswählen", - "server": "Server", - "settings": "Einstellungen", - "show": "Anzeigen", - "site.blueprint": "Du kannst zusätzliche Felder und Bereiche für die Seite in /site/blueprints/site.yml anlegen", - "size": "Größe", - "slug": "URL-Anhang", - "sort": "Sortieren", - - "stats.empty": "Keine Daten", - "system.issues.content": "Der content Ordner scheint öffentlich zugänglich zu sein", - "system.issues.debug": "Debugging muss im öffentlichen Betrieb ausgeschaltet sein", - "system.issues.git": "Der .git Ordner scheint öffentlich zugänglich zu sein", - "system.issues.https": "Wir empfehlen HTTPS für alle deine Seiten", - "system.issues.kirby": "Der kirby Ordner scheint öffentlich zugänglich zu sein", - "system.issues.site": "Der site Ordner scheint öffentlich zugänglich zu sein", - - "title": "Titel", - "template": "Vorlage", - "today": "Heute", - - "toolbar.button.code": "Code", - "toolbar.button.bold": "Fetter Text", - "toolbar.button.email": "E-Mail", - "toolbar.button.headings": "Überschriften", - "toolbar.button.heading.1": "Überschrift 1", - "toolbar.button.heading.2": "Überschrift 2", - "toolbar.button.heading.3": "Überschrift 3", - "toolbar.button.heading.4": "Überschrift 4", - "toolbar.button.heading.5": "Überschrift 5", - "toolbar.button.heading.6": "Überschrift 6", - "toolbar.button.italic": "Kursiver Text", - "toolbar.button.file": "Datei", - "toolbar.button.file.select": "Datei auswählen", - "toolbar.button.file.upload": "Datei hochladen", - "toolbar.button.link": "Link", - "toolbar.button.paragraph": "Absatz", - "toolbar.button.strike": "Durchgestrichen", - "toolbar.button.ol": "Geordnete Liste", - "toolbar.button.underline": "Unterstrichen", - "toolbar.button.ul": "Ungeordnete Liste", - - "translation.author": "Kirby Team", - "translation.direction": "ltr", - "translation.name": "Deutsch", - "translation.locale": "de_DE", - - "upload": "Hochladen", - "upload.error.cantMove": "Die Datei konnte nicht an ihren Zielort bewegt werden", - "upload.error.cantWrite": "Die Datei konnte nicht auf der Festplatte gespeichert werden", - "upload.error.default": "Die Datei konnte nicht hochgeladen werden", - "upload.error.extension": "Der Dateiupload wurde durch eine Erweiterung verhindert", - "upload.error.formSize": "Die Datei ist größer als die MAX_FILE_SIZE Einstellung im Formular", - "upload.error.iniPostSize": "Die Datei ist größer als die post_max_size Einstellung in der php.ini", - "upload.error.iniSize": "Die Datei ist größer als die upload_max_filesize Einstellung in der php.ini", - "upload.error.noFile": "Es wurde keine Datei hochgeladen", - "upload.error.noFiles": "Es wurden keine Dateien hochgeladen", - "upload.error.partial": "Die Datei wurde nur teilweise hochgeladen", - "upload.error.tmpDir": "Der temporäre Ordner für den Dateiupload existiert leider nicht", - "upload.errors": "Fehler", - "upload.progress": "Hochladen …", - - "url": "Url", - "url.placeholder": "https://beispiel.de", - - "user": "Account", - "user.blueprint": "Du kannst zusätzliche Felder und Bereiche für diese Rolle in /site/blueprints/users/{blueprint}.yml anlegen", - "user.changeEmail": "E-Mail ändern", - "user.changeLanguage": "Sprache ändern", - "user.changeName": "Account umbenennen", - "user.changePassword": "Passwort ändern", - "user.changePassword.new": "Neues Passwort", - "user.changePassword.new.confirm": "Wiederhole das Passwort …", - "user.changeRole": "Rolle ändern", - "user.changeRole.select": "Neue Rolle auswählen", - "user.create": "Neuen Account anlegen", - "user.delete": "Account löschen", - "user.delete.confirm": "Willst du den Account
{email} wirklich löschen?", - - "users": "Accounts", - - "version": "Version", - - "view.account": "Dein Account", - "view.installation": "Installation", - "view.languages": "Sprachen", - "view.resetPassword": "Passwort zurücksetzen", - "view.site": "Seite", - "view.system": "System", - "view.users": "Accounts", - - "welcome": "Willkommen", - "year": "Jahr", - "yes": "ja" + "account.changeName": "Deinen Namen ändern", + "account.delete": "Deinen Account löschen", + "account.delete.confirm": "Willst du deinen Account wirklich löschen? Du wirst sofort danach abgemeldet. Dein Account kann nicht wieder hergestellt werden. ", + + "add": "Hinzuf\u00fcgen", + "author": "Autor", + "avatar": "Profilbild", + "back": "Zurück", + "cancel": "Abbrechen", + "change": "\u00c4ndern", + "close": "Schlie\u00dfen", + "confirm": "OK", + "collapse": "Zusammenklappen", + "collapse.all": "Alle zusammenklappen", + "copy": "Kopieren", + "copy.all": "Alle kopieren", + "create": "Erstellen", + + "date": "Datum", + "date.select": "Datum auswählen", + + "day": "Tag", + "days.fri": "Fr", + "days.mon": "Mo", + "days.sat": "Sa", + "days.sun": "So", + "days.thu": "Do", + "days.tue": "Di", + "days.wed": "Mi", + + "debugging": "Debugging", + + "delete": "L\u00f6schen", + "delete.all": "Alle löschen", + + "dialog.files.empty": "Keine verfügbaren Dateien", + "dialog.pages.empty": "Keine verfügbaren Seiten", + "dialog.users.empty": "Keine verfügbaren Accounts", + + "dimensions": "Maße", + "disabled": "Gesperrt", + "discard": "Verwerfen", + "download": "Download", + "duplicate": "Duplizieren", + + "edit": "Bearbeiten", + + "email": "E-Mail", + "email.placeholder": "mail@beispiel.de", + + "entries": "Einträge", + "entry": "Eintrag", + + "environment": "Umgebung", + + "error.access.code": "Ungültiger Code", + "error.access.login": "Ungültige Zugangsdaten", + "error.access.panel": "Du hast keinen Zugang zum Panel", + "error.access.view": "Du hast keinen Zugriff auf diesen Teil des Panels", + + "error.avatar.create.fail": "Das Profilbild konnte nicht hochgeladen werden", + "error.avatar.delete.fail": "Das Profilbild konnte nicht gel\u00f6scht werden", + "error.avatar.dimensions.invalid": "Bitte lade ein Profilbild hoch, das nicht breiter oder höher als 3000 Pixel ist.", + "error.avatar.mime.forbidden": "Das Profilbild muss vom Format JPEG oder PNG sein", + + "error.blueprint.notFound": "Das Blueprint \"{name}\" konnte nicht geladen werden.", + + "error.blocks.max.plural": "Bitte füge nicht mehr als {max} Blöcke hinzu", + "error.blocks.max.singular": "Bitte füge nicht mehr als einen Block hinzu", + "error.blocks.min.plural": "Bitte füge mindestens {min} Blöcke hinzu", + "error.blocks.min.singular": "Bitte füge mindestens einen Block hinzu", + "error.blocks.validation": "Fehler im \"{field}\" Feld in Block {index} mit dem Block Typ \"{fieldset}\"", + + "error.email.preset.notFound": "Die E-Mailvorlage \"{name}\" wurde nicht gefunden", + + "error.field.converter.invalid": "Ungültiger Konverter: \"{converter}\"", + + "error.file.changeName.empty": "Bitte gib einen Namen an", + "error.file.changeName.permission": "Du darfst den Dateinamen von \"{filename}\" nicht ändern", + "error.file.duplicate": "Eine Datei mit dem Dateinamen \"{filename}\" besteht bereits", + "error.file.extension.forbidden": "Verbotene Dateiendung \"{extension}\"", + "error.file.extension.invalid": "Verbotene Dateiendung \"{extension}\"", + "error.file.extension.missing": "Du kannst keine Dateien ohne Dateiendung hochladen", + "error.file.maxheight": "Die Bildhöhe darf {height} Pixel nicht überschreiten", + "error.file.maxsize": "Die Datei ist zu groß", + "error.file.maxwidth": "Die Bildbreite darf {width} Pixel nicht überschreiten", + "error.file.mime.differs": "Die Datei muss den Medientyp \"{mime}\" haben.", + "error.file.mime.forbidden": "Der Medientyp \"{mime}\" ist nicht erlaubt", + "error.file.mime.invalid": "Ungültiger Dateityp: {mime}", + "error.file.mime.missing": "Der Medientyp für \"{filename}\" konnte nicht erkannt werden", + "error.file.minheight": "Die Bildhöhe muss mindestens {height} Pixel betragen", + "error.file.minsize": "Die Datei ist zu klein", + "error.file.minwidth": "Die Bildbreite muss mindestens {width} Pixel betragen", + "error.file.name.missing": "Bitte gib einen Dateinamen an", + "error.file.notFound": "Die Datei \"{filename}\" konnte nicht gefunden werden", + "error.file.orientation": "Das Bildformat ist ungültig. Erwartetes Format: \"{orientation}\"", + "error.file.type.forbidden": "Du kannst keinen {type}-Dateien hochladen", + "error.file.type.invalid": "Ungültiger Dateityp: {mime}", + "error.file.undefined": "Die Datei konnte nicht gefunden werden", + + "error.form.incomplete": "Bitte behebe alle Fehler …", + "error.form.notSaved": "Das Formular konnte nicht gespeichert werden", + + "error.language.code": "Bitte gib einen gültigen Code für die Sprache an", + "error.language.duplicate": "Die Sprache besteht bereits", + "error.language.name": "Bitte gib einen gültigen Namen für die Sprache an", + "error.language.notFound": "Die Sprache konnte nicht gefunden werden", + + "error.layout.validation.block": "Fehler im \"{field}\" Feld in Block {blockIndex} mit dem Block Typ \"{fieldset}\" in Layout {layoutIndex}", + "error.layout.validation.settings": "Fehler in den Einstellungen von Layout {index}", + + "error.license.format": "Bitte gib einen gültigen Lizenzschlüssel ein", + "error.license.email": "Bitte gib eine gültige E-Mailadresse an", + "error.license.verification": "Die Lizenz konnte nicht verifiziert werden", + + "error.object.validation": "Fehler im \"{label}\" Feld:\n{message}", + + "error.offline": "Das Panel ist zur Zeit offline", + + "error.page.changeSlug.permission": "Du darfst die URL der Seite \"{slug}\" nicht ändern", + "error.page.changeStatus.incomplete": "Die Seite ist nicht vollständig und kann daher nicht veröffentlicht werden", + "error.page.changeStatus.permission": "Der Status der Seite kann nicht geändert werden", + "error.page.changeStatus.toDraft.invalid": "Die Seite \"{slug}\" kann nicht in einen Entwurf umgewandelt werden", + "error.page.changeTemplate.invalid": "Die Vorlage für die Seite \"{slug}\" kann nicht geändert werden", + "error.page.changeTemplate.permission": "Du kannst die Vorlage für die Seite \"{slug}\" nicht ändern", + "error.page.changeTitle.empty": "Bitte gib einen Titel an", + "error.page.changeTitle.permission": "Du kannst den Titel für die Seite \"{slug}\" nicht ändern", + "error.page.create.permission": "Du kannst die Seite \"{slug}\" nicht anlegen", + "error.page.delete": "Die Seite \"{slug}\" kann nicht gelöscht werden", + "error.page.delete.confirm": "Bitte gib zur Bestätigung den Seitentitel ein", + "error.page.delete.hasChildren": "Die Seite hat Unterseiten und kann nicht gelöscht werden", + "error.page.delete.permission": "Du kannst die Seite \"{slug}\" nicht löschen", + "error.page.draft.duplicate": "Ein Entwurf mit dem URL-Kürzel \"{slug}\" besteht bereits", + "error.page.duplicate": "Eine Seite mit dem URL-Kürzel \"{slug}\" besteht bereits", + "error.page.duplicate.permission": "Du kannst die Seite \"{slug}\" nicht duplizieren", + "error.page.notFound": "Die Seite \"{slug}\" konnte nicht gefunden werden", + "error.page.num.invalid": "Bitte gib eine gültige Sortierungszahl an. Negative Zahlen sind nicht erlaubt.", + "error.page.slug.invalid": "Bitte gib ein gültiges URL-Kürzel an", + "error.page.slug.maxlength": "Die Pfadlänge darf {length} Zeichen nicht überschreiten", + "error.page.sort.permission": "Die Seite \"{slug}\" kann nicht umsortiert werden", + "error.page.status.invalid": "Bitte gib einen gültigen Seitenstatus an", + "error.page.undefined": "Die Seite konnte nicht gefunden werden", + "error.page.update.permission": "Du kannst die Seite \"{slug}\" nicht editieren", + + "error.section.files.max.plural": "Bitte füge nicht mehr als {max} Dateien zum Bereich \"{section}\" hinzu", + "error.section.files.max.singular": "Bitte füge nicht mehr als eine Datei zum Bereich \"{section}\" hinzu", + "error.section.files.min.plural": "Der Bereich \"{section}\" benötigt mindestens {min} Dateien", + "error.section.files.min.singular": "Der Bereich \"{section}\" benötigt mindestens eine Datei", + + "error.section.pages.max.plural": "Bitte füge nicht mehr als {max} Seiten zum Bereich \"{section}\" hinzu", + "error.section.pages.max.singular": "Bitte füge nicht mehr als eine Seite zum Bereich \"{section}\" hinzu", + "error.section.pages.min.plural": "Der Bereich \"{section}\" benötigt mindestens {min} Seiten", + "error.section.pages.min.singular": "Der Bereich \"{section}\" benötigt mindestens eine Seite", + + "error.section.notLoaded": "Der Bereich \"{name}\" konnte nicht geladen werden", + "error.section.type.invalid": "Der Bereichstyp \"{type}\" ist nicht gültig", + + "error.site.changeTitle.empty": "Bitte gib einen Titel an", + "error.site.changeTitle.permission": "Du kannst den Titel der Seite nicht ändern", + "error.site.update.permission": "Du darfst die Seite nicht bearbeiten", + + "error.template.default.notFound": "Die \"Default\"-Vorlage existiert nicht", + + "error.unexpected": "Ein unerwarteter Fehler ist aufgetreten. Aktiviere den Debug Modus für weitere Informationen: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Du kannst die E-Mailadresse für den Account \"{name}\" nicht ändern", + "error.user.changeLanguage.permission": "Du kannst die Sprache für den Account \"{name}\" nicht ändern", + "error.user.changeName.permission": "Du kannst den Namen für den Account \"{name}\" nicht ändern", + "error.user.changePassword.permission": "Du kannst das Passwort für den Account \"{name}\" nicht ändern", + "error.user.changeRole.lastAdmin": "Die Rolle des letzten Accounts mit Administrationsrechten kann nicht geändert werden", + "error.user.changeRole.permission": "Du kannst die Rolle für den Benutzer \"{name}\" nicht ändern", + "error.user.changeRole.toAdmin": "Du darfst die Admin-Rolle nicht an andere Accounts vergeben", + "error.user.create.permission": "Du darfst diesen Account nicht anlegen", + "error.user.delete": "Der Account \"{name}\" konnte nicht gelöscht werden", + "error.user.delete.lastAdmin": "Du kannst den letzten Account mit Administrationsrechten nicht löschen", + "error.user.delete.lastUser": "Der letzte Account kann nicht gelöscht werden", + "error.user.delete.permission": "Du darfst den Account \"{name}\" nicht löschen", + "error.user.duplicate": "Ein Account mit der E-Mailadresse \"{email}\" besteht bereits", + "error.user.email.invalid": "Bitte gib eine gültige E-Mailadresse an", + "error.user.language.invalid": "Bitte gib eine gültige Sprache an", + "error.user.notFound": "Der Account \"{name}\" wurde nicht gefunden", + "error.user.password.invalid": "Bitte gib ein gültiges Passwort ein. Passwörter müssen mindestens 8 Zeichen lang sein.", + "error.user.password.notSame": "Die Passwörter stimmen nicht überein", + "error.user.password.undefined": "Der Account hat kein Passwort", + "error.user.password.wrong": "Falsches Passwort", + "error.user.role.invalid": "Bitte gib eine gültige Rolle an", + "error.user.undefined": "Der Benutzer wurde nicht gefunden", + "error.user.update.permission": "Du darfst den den Account \"{name}\" nicht bearbeiten", + + "error.validation.accepted": "Bitte bestätige", + "error.validation.alpha": "Bitte gib nur Zeichen zwischen A und Z ein", + "error.validation.alphanum": "Bitte gib nur Zeichen zwischen A und Z und Zahlen zwischen 0 und 9 ein", + "error.validation.between": "Bitte gib einen Wert zwischen \"{min}\" und \"{max}\" ein", + "error.validation.boolean": "Bitte bestätige oder lehne ab", + "error.validation.contains": "Bitte gib einen Wert ein, der \"{needle}\" enthält", + "error.validation.date": "Bitte gib ein gültiges Datum ein", + "error.validation.date.after": "Bitte gib ein Datum nach dem {date} ein", + "error.validation.date.before": "Bitte gib ein Datum vor dem {date} ein", + "error.validation.date.between": "Bitte gib ein Datum zwischen dem {min} und dem {max} ein", + "error.validation.denied": "Bitte lehne die Eingabe ab", + "error.validation.different": "Der Wert darf nicht \"{other}\" sein", + "error.validation.email": "Bitte gib eine gültige E-Mailadresse an", + "error.validation.endswith": "Der Wert muss auf \"{end}\" enden", + "error.validation.filename": "Bitte gib einen gültigen Dateinamen ein", + "error.validation.in": "Bitte gib einen der folgenden Werte ein: ({in})", + "error.validation.integer": "Bitte gib eine ganze Zahl ein", + "error.validation.ip": "Bitte gib eine gültige IP Adresse ein", + "error.validation.less": "Bitte gib einen Wert kleiner als {max} ein", + "error.validation.match": "Der Wert entspricht nicht dem erwarteten Muster", + "error.validation.max": "Bitte gib einen Wert ein, der nicht größer als {max} ist", + "error.validation.maxlength": "Bitte gib einen kürzeren Text ein (max. {max} Zeichen)", + "error.validation.maxwords": "Bitte nutze nicht mehr als {max} Wort(e)", + "error.validation.min": "Bitte gib einen Wert ein, der nicht kleiner als {min} ist", + "error.validation.minlength": "Bitte gib einen längeren Text ein. (min. {min} Zeichen)", + "error.validation.minwords": "Bitte nutze mindestens {min} Wort(e)", + "error.validation.more": "Bitte gib einen größeren Wert als {min} ein", + "error.validation.notcontains": "Bitte gib einen Wert ein, der nicht \"{needle}\" enthält", + "error.validation.notin": "Bitte gib keinen der folgenden Werte ein: ({notIn})", + "error.validation.option": "Bitte wähle eine gültige Option aus", + "error.validation.num": "Bitte gib eine gültige Zahl an", + "error.validation.required": "Bitte gib etwas ein", + "error.validation.same": "Bitte gib \"{other}\" ein", + "error.validation.size": "Die Größe des Wertes muss \"{size}\" sein", + "error.validation.startswith": "Der Wert muss mit \"{start}\" beginnen", + "error.validation.time": "Bitte gib eine gültige Uhrzeit ein", + "error.validation.time.after": "Bitte gib eine Zeit nach {time} ein", + "error.validation.time.before": "Bitte gib eine Zeit vor {time} ein", + "error.validation.time.between": "Bitte gib eine Zeit zwischen {min} und {max} ein", + "error.validation.url": "Bitte gib eine gültige URL ein", + + "expand": "Aufklappen", + "expand.all": "Alle aufklappen", + + "field.required": "Das Feld ist Pflicht", + "field.blocks.changeType": "Blocktyp ändern", + "field.blocks.code.name": "Code", + "field.blocks.code.language": "Sprache", + "field.blocks.code.placeholder": "Code …", + "field.blocks.delete.confirm": "Willst du diesen Block wirklich löschen?", + "field.blocks.delete.confirm.all": "Willst du wirklich alle Blöcke löschen?", + "field.blocks.delete.confirm.selected": "Willst du wirklich die ausgewählten Blöcke löschen?", + "field.blocks.empty": "Keine Blöcke", + "field.blocks.fieldsets.label": "Bitte wähle einen Blocktyp aus …", + "field.blocks.fieldsets.paste": "Drücke {{ shortcut }} um Blöcke aus der Zwischenablage zu importieren", + "field.blocks.gallery.name": "Galerie", + "field.blocks.gallery.images.empty": "Keine Bilder", + "field.blocks.gallery.images.label": "Bilder", + "field.blocks.heading.level": "Ebene", + "field.blocks.heading.name": "Überschrift", + "field.blocks.heading.text": "Text", + "field.blocks.heading.placeholder": "Überschrift …", + "field.blocks.image.alt": "Alternativer Text", + "field.blocks.image.caption": "Bildunterschrift", + "field.blocks.image.crop": "Beschneiden", + "field.blocks.image.link": "Link", + "field.blocks.image.location": "Ort", + "field.blocks.image.name": "Bild", + "field.blocks.image.placeholder": "Bild auswählen", + "field.blocks.image.ratio": "Seitenverhältnis", + "field.blocks.image.url": "Bild URL", + "field.blocks.line.name": "Linie", + "field.blocks.list.name": "Liste", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Text", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Zitat", + "field.blocks.quote.text.label": "Text", + "field.blocks.quote.text.placeholder": "Zitat …", + "field.blocks.quote.citation.label": "Quelle", + "field.blocks.quote.citation.placeholder": "Quelle …", + "field.blocks.text.name": "Text", + "field.blocks.text.placeholder": "Text …", + "field.blocks.video.caption": "Bildunterschrift", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Video-URL eingeben", + "field.blocks.video.url.label": "Video-URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Keine Dateien ausgewählt", + + "field.layout.delete": "Layout löschen", + "field.layout.delete.confirm": "Willst du dieses Layout wirklich löschen?", + "field.layout.empty": "Keine Layouts", + "field.layout.select": "Layout auswählen", + + "field.object.empty": "Noch keine Information", + + "field.pages.empty": "Keine Seiten ausgewählt", + + "field.structure.delete.confirm": "Willst du diesen Eintrag wirklich l\u00f6schen?", + "field.structure.empty": "Es bestehen keine Eintr\u00e4ge.", + + "field.users.empty": "Keine Accounts ausgewählt", + + "file.blueprint": "Du kannst zusätzliche Felder und Bereiche für diese Datei in /site/blueprints/files/{blueprint}.yml anlegen", + "file.delete.confirm": "Willst du die Datei {filename}
wirklich löschen?", + "file.sort": "Position ändern", + + "files": "Dateien", + "files.empty": "Keine Dateien", + + "hide": "Verbergen", + "hour": "Stunde", + "import": "Importieren", + "info": "Info", + "insert": "Einf\u00fcgen", + "insert.after": "Danach einfügen", + "insert.before": "Davor einfügen", + "install": "Installieren", + + "installation": "Installation", + "installation.completed": "Das Panel wurde installiert", + "installation.disabled": "Die Panel-Installation ist auf öffentlichen Servern automatisch deaktiviert. Bitte installiere das Panel auf einem lokalen Server oder aktiviere die Installation gezielt mit der panel.install Option. ", + "installation.issues.accounts": "/site/accounts ist nicht beschreibbar", + "installation.issues.content": "/content existiert nicht oder ist nicht beschreibbar", + "installation.issues.curl": "Die CURL Erweiterung wird benötigt", + "installation.issues.headline": "Das Panel kann nicht installiert werden", + "installation.issues.mbstring": "Die MB String Erweiterung wird benötigt", + "installation.issues.media": "Der /media Ordner ist nicht beschreibbar", + "installation.issues.php": "Bitte verwende PHP 7+", + "installation.issues.server": "Kirby benötigt Apache, Nginx or Caddy", + "installation.issues.sessions": "/site/sessions ist nicht beschreibbar", + + "language": "Sprache", + "language.code": "Code", + "language.convert": "Als Standard auswählen", + "language.convert.confirm": "

Willst du {name} wirklich in die Standardsprache umwandeln? Dieser Schritt kann nicht rückgängig gemacht werden.

Wenn {name} unübersetzte Felder hat, gibt es keine gültigen Standardwerte für diese Felder und Inhalte könnten verloren gehen.

", + "language.create": "Neue Sprache anlegen", + "language.delete.confirm": "Willst du {name} inklusive aller Übersetzungen wirklich löschen? Dieser Schritt kann nicht rückgängig gemacht werden!", + "language.deleted": "Die Sprache wurde gelöscht", + "language.direction": "Leserichtung", + "language.direction.ltr": "Von links nach rechts", + "language.direction.rtl": "Von rechts nach links", + "language.locale": "PHP locale string", + "language.locale.warning": "Du nutzt ein angepasstes Setup for PHP Locales. Bitte bearbeite dieses direkt in der entsprechenden Sprachdatei in /site/languages", + "language.name": "Name", + "language.updated": "Die Sprache wurde gespeichert", + + "languages": "Sprachen", + "languages.default": "Standardsprache", + "languages.empty": "Noch keine Sprachen", + "languages.secondary": "Sekundäre Sprachen", + "languages.secondary.empty": "Noch keine sekundären Sprachen", + + "license": "Lizenz", + "license.buy": "Kaufe eine Lizenz", + "license.register": "Registrieren", + "license.manage": "Verwalte deine Lizenzen", + "license.register.help": "Den Lizenzcode findest du in der Bestätigungsmail zu deinem Kauf. Bitte kopiere und füge ihn ein, um Kirby zu registrieren.", + "license.register.label": "Bitte gib deinen Lizenzcode ein", + "license.register.success": "Vielen Dank für deine Unterstützung", + "license.unregistered": "Dies ist eine unregistrierte Kirby-Demo", + "license.unregistered.label": "Unregistriert", + + "link": "Link", + "link.text": "Linktext", + + "loading": "Laden", + + "lock.unsaved": "Ungespeicherte Änderungen", + "lock.unsaved.empty": "Keine ungespeicherten Änderungen", + "lock.isLocked": "Ungespeicherte Änderungen von {email}", + "lock.file.isLocked": "Die Datei wird von {email} bearbeitet und kann nicht geändert werden.", + "lock.page.isLocked": "Die Seite wird von {email} bearbeitet und kann nicht geändert werden.", + "lock.unlock": "Entsperren", + "lock.isUnlocked": "Deine ungespeicherten Änderungen wurden von einem anderen Account überschrieben. Du kannst sie herunterladen, um sie manuell einzufügen. ", + + "login": "Anmelden", + "login.code.label.login": "Anmeldecode", + "login.code.label.password-reset": "Anmeldecode", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "Wenn deine E-Mail-Adresse registriert ist, wurde der angeforderte Code per E-Mail versendet.", + "login.email.login.body": "Hallo {user.nameOrEmail},\n\ndu hast gerade einen Anmeldecode für das Kirby Panel von {site} angefordert.\n\nDer folgende Anmeldecode ist für die nächsten {timeout} Minuten gültig:\n\n{code}\n\nWenn du keinen Anmeldecode angefordert hast, ignoriere bitte diese E-Mail oder kontaktiere bei Fragen deinen Administrator.\nBitte leite diese E-Mail aus Sicherheitsgründen NICHT weiter.", + "login.email.login.subject": "Dein Anmeldecode", + "login.email.password-reset.body": "Hallo {user.nameOrEmail},\n\ndu hast gerade einen Anmeldecode für das Kirby Panel von {site} angefordert.\n\nDer folgende Anmeldecode ist für die nächsten {timeout} Minuten gültig:\n\n{code}\n\nWenn du keinen Anmeldecode angefordert hast, ignoriere bitte diese E-Mail oder kontaktiere bei Fragen deinen Administrator.\nBitte leite diese E-Mail aus Sicherheitsgründen NICHT weiter.", + "login.email.password-reset.subject": "Dein Anmeldecode", + "login.remember": "Angemeldet bleiben", + "login.reset": "Passwort zurücksetzen", + "login.toggleText.code.email": "Anmelden über E-Mail", + "login.toggleText.code.email-password": "Anmelden mit Passwort", + "login.toggleText.password-reset.email": "Passwort vergessen?", + "login.toggleText.password-reset.email-password": "← Zurück zur Anmeldung", + + "logout": "Abmelden", + + "menu": "Menü", + "meridiem": "AM/PM", + "mime": "Medientyp", + "minutes": "Minuten", + + "month": "Monat", + "months.april": "April", + "months.august": "August", + "months.december": "Dezember", + "months.february": "Februar", + "months.january": "Januar", + "months.july": "Juli", + "months.june": "Juni", + "months.march": "M\u00e4rz", + "months.may": "Mai", + "months.november": "November", + "months.october": "Oktober", + "months.september": "September", + + "more": "Mehr", + "name": "Name", + "next": "Nächster Eintrag", + "no": "nein", + "off": "aus", + "on": "an", + "open": "Öffnen", + "open.newWindow": "In neuem Fenster öffnen", + "options": "Optionen", + "options.none": "Keine Optionen", + + "orientation": "Ausrichtung", + "orientation.landscape": "Querformat", + "orientation.portrait": "Hochformat", + "orientation.square": "Quadratisch", + + "page.blueprint": "Du kannst zusätzliche Felder und Bereiche für diese Seite in /site/blueprints/pages/{blueprint}.yml anlegen", + "page.changeSlug": "URL \u00e4ndern", + "page.changeSlug.fromTitle": "Aus Titel erzeugen", + "page.changeStatus": "Status ändern", + "page.changeStatus.position": "Bitte wähle eine Position aus", + "page.changeStatus.select": "Wähle einen neuen Status aus", + "page.changeTemplate": "Vorlage ändern", + "page.delete.confirm": "Willst du die Seite {title} wirklich löschen?", + "page.delete.confirm.subpages": "Diese Seite hat Unterseiten.
Alle Unterseiten werden ebenfalls gelöscht.", + "page.delete.confirm.title": "Gib zur Bestätigung den Seitentitel ein", + "page.draft.create": "Entwurf anlegen", + "page.duplicate.appendix": "Kopie", + "page.duplicate.files": "Dateien kopieren", + "page.duplicate.pages": "Seiten kopieren", + "page.sort": "Position ändern", + "page.status": "Status", + "page.status.draft": "Entwurf", + "page.status.draft.description": "Die Seite ist im Entwurfsmodus und ist nur nach Anmeldung oder über den geheimen Link sichtbar", + "page.status.listed": "Öffentlich", + "page.status.listed.description": "Die Seite ist öffentlich für alle", + "page.status.unlisted": "Ungelistet", + "page.status.unlisted.description": "Die Seite kann nur über die URL aufgerufen werden", + + "pages": "Seiten", + "pages.empty": "Keine Seiten", + "pages.status.draft": "Entwürfe", + "pages.status.listed": "Veröffentlicht", + "pages.status.unlisted": "Ungelistet", + + "pagination.page": "Seite", + + "password": "Passwort", + "paste": "Einfügen", + "paste.after": "Danach einfügen", + "pixel": "Pixel", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "Vorheriger Eintrag", + "preview": "Vorschau", + "remove": "Entfernen", + "rename": "Umbenennen", + "replace": "Ersetzen", + "retry": "Wiederholen", + "revert": "Verwerfen", + "revert.confirm": "Willst du wirklich alle ungespeicherten Änderungen verwerfen? ", + + "role": "Rolle", + "role.admin.description": "Admins haben alle Rechte", + "role.admin.title": "Admin", + "role.all": "Alle", + "role.empty": "Keine Accounts mit dieser Rolle", + "role.description.placeholder": "Keine Beschreibung", + "role.nobody.description": "Dies ist die Platzhalterrolle ohne Rechte", + "role.nobody.title": "Niemand", + + "save": "Speichern", + "search": "Suchen", + "search.min": "Gib mindestens {min}  Zeichen ein, um zu suchen", + "search.all": "Alles zeigen", + "search.results.none": "Keine Ergebnisse", + + "section.required": "Der Bereich ist Pflicht", + + "security": "Sicherheit", + "select": "Auswählen", + "server": "Server", + "settings": "Einstellungen", + "show": "Anzeigen", + "site.blueprint": "Du kannst zusätzliche Felder und Bereiche für die Seite in /site/blueprints/site.yml anlegen", + "size": "Größe", + "slug": "URL-Anhang", + "sort": "Sortieren", + + "stats.empty": "Keine Daten", + "system.issues.content": "Der content Ordner scheint öffentlich zugänglich zu sein", + "system.issues.eol.kirby": "Deine Kirby Installation ist veraltet und erhält keine weiteren Sicherheitsupdates", + "system.issues.eol.plugin": "Deine Version des { plugin } Plugins ist veraltet und erhält keine weiteren Sicherheitsupdates", + "system.issues.debug": "Debugging muss im öffentlichen Betrieb ausgeschaltet sein", + "system.issues.git": "Der .git Ordner scheint öffentlich zugänglich zu sein", + "system.issues.https": "Wir empfehlen HTTPS für alle deine Seiten", + "system.issues.kirby": "Der kirby Ordner scheint öffentlich zugänglich zu sein", + "system.issues.site": "Der site Ordner scheint öffentlich zugänglich zu sein", + "system.issues.vulnerability.kirby": "Deine Installation könnte von folgender Sicherheitslücke betroffen sein ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Deine Installation könnte von folgender Sicherheitslücke im { plugin } Plugin betroffen sein ({ severity } severity): { description }", + "system.updateStatus": "Update Status", + "system.updateStatus.error": "Update Check nicht möglich", + "system.updateStatus.not-vulnerable": "Keine bekannten Sicherheitslücken", + "system.updateStatus.security-update": "Kostenloses Sicherheitsupdate { version } verfügbar", + "system.updateStatus.security-upgrade": "Upgrade { version } mit Sicherheitsverbesserungen verfügbar ", + "system.updateStatus.unreleased": "Unveröffentlichte Version", + "system.updateStatus.up-to-date": "Aktuell", + "system.updateStatus.update": "Kostenloses Update { version } verfügbar", + "system.updateStatus.upgrade": "Upgrade { version } verfügbar", + + "title": "Titel", + "template": "Vorlage", + "today": "Heute", + + "toolbar.button.code": "Code", + "toolbar.button.bold": "Fetter Text", + "toolbar.button.email": "E-Mail", + "toolbar.button.headings": "Überschriften", + "toolbar.button.heading.1": "Überschrift 1", + "toolbar.button.heading.2": "Überschrift 2", + "toolbar.button.heading.3": "Überschrift 3", + "toolbar.button.heading.4": "Überschrift 4", + "toolbar.button.heading.5": "Überschrift 5", + "toolbar.button.heading.6": "Überschrift 6", + "toolbar.button.italic": "Kursiver Text", + "toolbar.button.file": "Datei", + "toolbar.button.file.select": "Datei auswählen", + "toolbar.button.file.upload": "Datei hochladen", + "toolbar.button.link": "Link", + "toolbar.button.paragraph": "Absatz", + "toolbar.button.strike": "Durchgestrichen", + "toolbar.button.ol": "Geordnete Liste", + "toolbar.button.underline": "Unterstrichen", + "toolbar.button.ul": "Ungeordnete Liste", + + "translation.author": "Kirby Team", + "translation.direction": "ltr", + "translation.name": "Deutsch", + "translation.locale": "de_DE", + + "upload": "Hochladen", + "upload.error.cantMove": "Die Datei konnte nicht an ihren Zielort bewegt werden", + "upload.error.cantWrite": "Die Datei konnte nicht auf der Festplatte gespeichert werden", + "upload.error.default": "Die Datei konnte nicht hochgeladen werden", + "upload.error.extension": "Der Dateiupload wurde durch eine Erweiterung verhindert", + "upload.error.formSize": "Die Datei ist größer als die MAX_FILE_SIZE Einstellung im Formular", + "upload.error.iniPostSize": "Die Datei ist größer als die post_max_size Einstellung in der php.ini", + "upload.error.iniSize": "Die Datei ist größer als die upload_max_filesize Einstellung in der php.ini", + "upload.error.noFile": "Es wurde keine Datei hochgeladen", + "upload.error.noFiles": "Es wurden keine Dateien hochgeladen", + "upload.error.partial": "Die Datei wurde nur teilweise hochgeladen", + "upload.error.tmpDir": "Der temporäre Ordner für den Dateiupload existiert leider nicht", + "upload.errors": "Fehler", + "upload.progress": "Hochladen …", + + "url": "Url", + "url.placeholder": "https://beispiel.de", + + "user": "Account", + "user.blueprint": "Du kannst zusätzliche Felder und Bereiche für diese Rolle in /site/blueprints/users/{blueprint}.yml anlegen", + "user.changeEmail": "E-Mail ändern", + "user.changeLanguage": "Sprache ändern", + "user.changeName": "Account umbenennen", + "user.changePassword": "Passwort ändern", + "user.changePassword.new": "Neues Passwort", + "user.changePassword.new.confirm": "Wiederhole das Passwort …", + "user.changeRole": "Rolle ändern", + "user.changeRole.select": "Neue Rolle auswählen", + "user.create": "Neuen Account anlegen", + "user.delete": "Account löschen", + "user.delete.confirm": "Willst du den Account
{email} wirklich löschen?", + + "users": "Accounts", + + "version": "Version", + "version.current": "Aktuelle Version", + "version.latest": "Neueste Version", + "versionInformation": "Informationen zur Version", + + "view.account": "Dein Account", + "view.installation": "Installation", + "view.languages": "Sprachen", + "view.resetPassword": "Passwort zurücksetzen", + "view.site": "Seite", + "view.system": "System", + "view.users": "Accounts", + + "welcome": "Willkommen", + "year": "Jahr", + "yes": "ja" } diff --git a/kirby/i18n/translations/el.json b/kirby/i18n/translations/el.json index e61f2c5..dd1bb36 100644 --- a/kirby/i18n/translations/el.json +++ b/kirby/i18n/translations/el.json @@ -1,573 +1,596 @@ { - "account.changeName": "Change your name", - "account.delete": "Delete your account", - "account.delete.confirm": "Do you really want to delete your account? You will be logged out immediately. Your account cannot be recovered.", - - "add": "\u03a0\u03c1\u03bf\u03c3\u03b8\u03ae\u03ba\u03b7", - "author": "Author", - "avatar": "\u0395\u03b9\u03ba\u03cc\u03bd\u03b1 \u03c0\u03c1\u03bf\u03c6\u03af\u03bb", - "back": "Πίσω", - "cancel": "\u0391\u03ba\u03cd\u03c1\u03c9\u03c3\u03b7", - "change": "\u0391\u03bb\u03bb\u03b1\u03b3\u03ae", - "close": "\u039a\u03bb\u03b5\u03af\u03c3\u03b9\u03bc\u03bf", - "confirm": "Εντάξει", - "collapse": "Collapse", - "collapse.all": "Collapse All", - "copy": "Αντιγραφή", - "copy.all": "Copy all", - "create": "Δημιουργία", - - "date": "Ημερομηνία", - "date.select": "Επιλογή ημερομηνίας", - - "day": "Ημέρα", - "days.fri": "\u03a0\u03b1\u03c1", - "days.mon": "\u0394\u03b5\u03c5", - "days.sat": "\u03a3\u03ac\u03b2", - "days.sun": "\u039a\u03c5\u03c1", - "days.thu": "\u03a0\u03ad\u03bc", - "days.tue": "\u03a4\u03c1\u03af", - "days.wed": "\u03a4\u03b5\u03c4", - - "debugging": "Debugging", - - "delete": "\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae", - "delete.all": "Delete all", - - "dialog.files.empty": "No files to select", - "dialog.pages.empty": "No pages to select", - "dialog.users.empty": "No users to select", - - "dimensions": "Διαστάσεις", - "disabled": "Disabled", - "discard": "Απόρριψη", - "download": "Λήψη", - "duplicate": "Αντίγραφο", - - "edit": "\u0395\u03c0\u03b5\u03be\u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1", - - "email": "Διεύθυνση ηλεκτρονικού ταχυδρομείου", - "email.placeholder": "mail@example.com", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Environment", - - "error.access.code": "Mη έγκυρος κωδικός", - "error.access.login": "Mη έγκυρη σύνδεση", - "error.access.panel": "Δεν επιτρέπεται η πρόσβαση στον πίνακα ελέγχου", - "error.access.view": "Δεν επιτρέπεται η πρόσβαση σε αυτό το τμήμα του πίνακα ελέγχου", - - "error.avatar.create.fail": "Δεν ήταν δυνατή η μεταφόρτωση της εικόνας προφίλ", - "error.avatar.delete.fail": "Δεν ήταν δυνατή η διαγραφή της εικόνας προφίλ", - "error.avatar.dimensions.invalid": "Διατηρήστε το πλάτος και το ύψος της εικόνας προφίλ κάτω από 3000 εικονοστοιχεία", - "error.avatar.mime.forbidden": "\u039c\u03b7 \u03b1\u03c0\u03bf\u03b4\u03b5\u03ba\u03c4\u03cc\u03c2 \u03c4\u03cd\u03c0\u03bf\u03c2 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5", - - "error.blueprint.notFound": "Δεν ήταν δυνατή η φόρτωση του προσχεδίου \"{name}\"", - - "error.blocks.max.plural": "You must not add more than {max} blocks", - "error.blocks.max.singular": "You must not add more than one block", - "error.blocks.min.plural": "You must add at least {min} blocks", - "error.blocks.min.singular": "You must add at least one block", - "error.blocks.validation": "There's an error in block {index}", - - "error.email.preset.notFound": "Δεν είναι δυνατή η εύρεση της προεπιλογής διεύθινσης ηλεκτρονικού ταχυδρομείου \"{name}\"", - - "error.field.converter.invalid": "Μη έγκυρος μετατροπέας \"{converter}\"", - - "error.file.changeName.empty": "The name must not be empty", - "error.file.changeName.permission": "Δεν επιτρέπεται να αλλάξετε το όνομα του \"{filename}\"", - "error.file.duplicate": "Ένα αρχείο με το όνομα \"{filename}\" υπάρχει ήδη", - "error.file.extension.forbidden": "\u039c\u03b7 \u03b1\u03c0\u03bf\u03b4\u03b5\u03ba\u03c4\u03ae \u03b5\u03c0\u03ad\u03ba\u03c4\u03b1\u03c3\u03b7 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5", - "error.file.extension.invalid": "Invalid extension: {extension}", - "error.file.extension.missing": "Λείπει η επέκταση για το \"{filename}\"", - "error.file.maxheight": "The height of the image must not exceed {height} pixels", - "error.file.maxsize": "The file is too large", - "error.file.maxwidth": "The width of the image must not exceed {width} pixels", - "error.file.mime.differs": "Το αρχείο πρέπει να είναι του ίδιου τύπου mime \"{mime}\"", - "error.file.mime.forbidden": "Ο τύπος μέσου \"{mime}\" δεν επιτρέπεται", - "error.file.mime.invalid": "Invalid mime type: {mime}", - "error.file.mime.missing": "Δεν είναι δυνατό να εντοπιστεί ο τύπος μέσου για το \"{filename}\"", - "error.file.minheight": "The height of the image must be at least {height} pixels", - "error.file.minsize": "The file is too small", - "error.file.minwidth": "The width of the image must be at least {width} pixels", - "error.file.name.missing": "Το όνομα αρχείου δεν μπορεί να είναι άδειο", - "error.file.notFound": "Δεν είναι δυνατό να βρεθεί το αρχείο \"{filename}\"", - "error.file.orientation": "The orientation of the image must be \"{orientation}\"", - "error.file.type.forbidden": "Δεν επιτρέπεται η μεταφόρτωση αρχείων {type}", - "error.file.type.invalid": "Invalid file type: {type}", - "error.file.undefined": "Δεν ήταν δυνατή η εύρεση του αρχείου", - - "error.form.incomplete": "Παρακαλώ διορθώστε τα σφάλματα στη φόρμα...", - "error.form.notSaved": "Δεν ήταν δυνατή η αποθήκευση της φόρμας", - - "error.language.code": "Please enter a valid code for the language", - "error.language.duplicate": "The language already exists", - "error.language.name": "Please enter a valid name for the language", - "error.language.notFound": "The language could not be found", - - "error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}", - "error.layout.validation.settings": "There's an error in layout {index} settings", - - "error.license.format": "Please enter a valid license key", - "error.license.email": "Παρακαλώ εισάγετε μια έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου", - "error.license.verification": "The license could not be verified", - - "error.offline": "The Panel is currently offline", - - "error.page.changeSlug.permission": "Δεν επιτρέπεται να αλλάξετε το URL της σελίδας \"{slug}\"", - "error.page.changeStatus.incomplete": "Δεν ήταν δυνατή η δημοσίευση της σελίδας καθώς περιέχει σφάλματα", - "error.page.changeStatus.permission": "Δεν είναι δυνατή η αλλαγή κατάστασης για αυτή τη σελίδα", - "error.page.changeStatus.toDraft.invalid": "Δεν είναι δυνατή η μετατροπή της σελίδας \"{slug}\" σε προσχέδιο", - "error.page.changeTemplate.invalid": "Δεν είναι δυνατή η αλλαγή προτύπου για τη σελίδα \"{slug}\"", - "error.page.changeTemplate.permission": "Δεν επιτρέπεται να αλλάξετε το πρότυπο για τη σελίδα \"{slug}\"", - "error.page.changeTitle.empty": "Ο τίτλος δεν μπορεί να είναι κενός", - "error.page.changeTitle.permission": "Δεν επιτρέπεται να αλλάξετε τον τίτλο για τη σελίδα \"{slug}\"", - "error.page.create.permission": "Δεν επιτρέπεται να δημιουργήσετε τη σελίδα \"{slug}\"", - "error.page.delete": "Δεν είναι δυνατή η διαγραφή της σελίδας \"{slug}\"", - "error.page.delete.confirm": "Παρακαλώ εισάγετε τον τίτλο της σελίδας για επιβεβαίωση", - "error.page.delete.hasChildren": "Δεν είναι δυνατή η διαγραφή της σελίδας καθώς περιέχει υποσελίδες", - "error.page.delete.permission": "Δεν επιτρέπεται η διαγραφή της σελίδας \"{slug}\"", - "error.page.draft.duplicate": "Υπάρχει ήδη ένα προσχέδιο σελίδας με την διεύθυνση URL \"{slug}\"", - "error.page.duplicate": "Υπάρχει ήδη μια σελίδα με την διεύθυνση URL \"{slug}\"", - "error.page.duplicate.permission": "You are not allowed to duplicate \"{slug}\"", - "error.page.notFound": "Δεν ήταν δυνατή η εύρεση της σελίδας \"{slug}\"", - "error.page.num.invalid": "Παρακαλώ εισάγετε έναν έγκυρο αριθμό ταξινόμησης. Οι αριθμοί δεν μπορεί να είναι αρνητικοί.", - "error.page.slug.invalid": "Please enter a valid URL appendix", - "error.page.slug.maxlength": "Slug length must be less than \"{length}\" characters", - "error.page.sort.permission": "Δεν είναι δυνατή η ταξινόμηση της σελίδας \"{slug}\"", - "error.page.status.invalid": "Ορίστε μια έγκυρη κατάσταση σελίδας", - "error.page.undefined": "Δεν ήταν δυνατή η εύρεση της σελίδας", - "error.page.update.permission": "Δεν επιτρέπεται η ενημέρωση της σελίδας \"{slug}\"", - - "error.section.files.max.plural": "Δεν πρέπει να προσθέσετε περισσότερα από {max} αρχεία στην ενότητα \"{section}\"", - "error.section.files.max.singular": "Δεν πρέπει να προσθέσετε περισσότερα από ένα αρχεία στην ενότητα \"{section}\"", - "error.section.files.min.plural": "The \"{section}\" section requires at least {min} files", - "error.section.files.min.singular": "The \"{section}\" section requires at least one file", - - "error.section.pages.max.plural": "Δεν μπορείτε να προσθέσετε περισσότερες από {max} σελίδες στην ενότητα \"{section}\"", - "error.section.pages.max.singular": "Δεν μπορείτε να προσθέσετε περισσότερες από μία σελίδες στην ενότητα \"{section}\"", - "error.section.pages.min.plural": "The \"{section}\" section requires at least {min} pages", - "error.section.pages.min.singular": "The \"{section}\" section requires at least one page", - - "error.section.notLoaded": "Δεν ήταν δυνατή η φόρτωση της ενότητας \"{name}\"", - "error.section.type.invalid": "Ο τύπος ενότητας \"{type}\" δεν είναι έγκυρος", - - "error.site.changeTitle.empty": "Ο τίτλος δεν μπορεί να είναι κενός", - "error.site.changeTitle.permission": "Δεν επιτρέπεται να αλλάξετε τον τίτλο του ιστότοπου", - "error.site.update.permission": "Δεν επιτρέπεται η ενημέρωση του ιστότοπου", - - "error.template.default.notFound": "Το προεπιλεγμένο πρότυπο δεν υπάρχει", - - "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Δεν επιτρέπεται να αλλάξετε τη διεύθινση ηλεκτρονικού ταχυδρομείου για τον χρήστη \"{name}\"", - "error.user.changeLanguage.permission": "Δεν επιτρέπεται να αλλάξετε τη γλώσσα για τον χρήστη \"{name}\"", - "error.user.changeName.permission": "Δεν επιτρέπεται να αλλάξετε το όνομα του χρήστη \"{name}", - "error.user.changePassword.permission": "Δεν επιτρέπεται να αλλάξετε τον κωδικό πρόσβασης για τον χρήστη \"{name}\"", - "error.user.changeRole.lastAdmin": "Ο ρόλος του τελευταίου διαχειριστή δεν μπορεί να αλλάξει", - "error.user.changeRole.permission": "Δεν επιτρέπεται να αλλάξετε το ρόλο του χρήστη \"{name}\"", - "error.user.changeRole.toAdmin": "You are not allowed to promote someone to the admin role", - "error.user.create.permission": "Δεν επιτρέπεται η δημιουργία αυτού του χρήστη", - "error.user.delete": "\u039f \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2 \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03bf\u03cd\u03c3\u03b5 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03b5\u03af", - "error.user.delete.lastAdmin": "Δεν είναι δυνατή η διαγραφή του τελευταίου διαχειριστή", - "error.user.delete.lastUser": "Δεν είναι δυνατή η διαγραφή του τελευταίου χρήστη", - "error.user.delete.permission": "Δεν επιτρέπεται να διαγράψετ τον χρήστη \"{name}\"", - "error.user.duplicate": "Ένας χρήστης με τη διεύθυνση ηλεκτρονικού ταχυδρομείου \"{email}\" υπάρχει ήδη", - "error.user.email.invalid": "Παρακαλώ εισάγετε μια έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου", - "error.user.language.invalid": "Παρακαλώ εισαγάγετε μια έγκυρη γλώσσα", - "error.user.notFound": "Δεν είναι δυνατή η εύρεση του χρήστη \"{name}\"", - "error.user.password.invalid": "Παρακαλώ εισάγετε έναν έγκυρο κωδικό πρόσβασης. Οι κωδικοί πρόσβασης πρέπει να έχουν μήκος τουλάχιστον 8 χαρακτήρων.", - "error.user.password.notSame": "\u03a0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03bf\u03cd\u03bc\u03b5 \u03b5\u03c0\u03b9\u03b2\u03b5\u03b2\u03b1\u03b9\u03ce\u03c3\u03c4\u03b5 \u03c4\u03bf\u03bd \u039a\u03c9\u03b4\u03b9\u03ba\u03cc \u03a0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2", - "error.user.password.undefined": "Ο χρήστης δεν έχει κωδικό πρόσβασης", - "error.user.password.wrong": "Wrong password", - "error.user.role.invalid": "Παρακαλώ εισαγάγετε έναν έγκυρο ρόλο", - "error.user.undefined": "Δεν είναι δυνατή η εύρεση του χρήστη", - "error.user.update.permission": "Δεν επιτρέπεται η ενημέρωση του χρήστη \"{name}\"", - - "error.validation.accepted": "Παρακαλώ επιβεβαιώστε", - "error.validation.alpha": "Παρακαλώ εισάγετε μόνο χαρακτήρες μεταξύ των a-z", - "error.validation.alphanum": "Παρακαλώ εισάγετε μόνο χαρακτήρες μεταξύ των a-z ή αριθμούς απο το 0 έως το 9", - "error.validation.between": "Παρακαλώ εισάγετε μια τιμή μεταξύ \"{min}\" και \"{max}\"", - "error.validation.boolean": "Παρακαλώ επιβεβαιώστε ή αρνηθείτε", - "error.validation.contains": "Παρακαλώ καταχωρίστε μια τιμή που περιέχει \"{needle}\"", - "error.validation.date": "Παρακαλώ εισάγετε μία έγκυρη ημερομηνία", - "error.validation.date.after": "Please enter a date after {date}", - "error.validation.date.before": "Please enter a date before {date}", - "error.validation.date.between": "Please enter a date between {min} and {max}", - "error.validation.denied": "Παρακαλώ αρνηθείτε", - "error.validation.different": "Η τιμή δεν μπορεί να είναι \"{other}\"", - "error.validation.email": "Παρακαλώ εισάγετε μια έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου", - "error.validation.endswith": "Η τιμή πρέπει να τελειώνει με \"{end}\"", - "error.validation.filename": "Παρακαλώ εισάγετε ένα έγκυρο όνομα αρχείου", - "error.validation.in": "Παρακαλώ εισάγετε ένα από τα παρακάτω: ({in})", - "error.validation.integer": "Παρακαλώ εισάγετε έναν έγκυρο ακέραιο αριθμό", - "error.validation.ip": "Παρακαλώ εισάγετε μια έγκυρη διεύθυνση IP", - "error.validation.less": "Παρακαλώ εισάγετε μια τιμή μικρότερη από {max}", - "error.validation.match": "Η τιμή δεν ταιριάζει με το αναμενόμενο πρότυπο", - "error.validation.max": "Παρακαλώ εισάγετε μια τιμή ίση ή μικρότερη από {max}", - "error.validation.maxlength": "Παρακαλώ εισάγετε μια μικρότερη τιμή. (max. {max} χαρακτήρες)", - "error.validation.maxwords": "Παρακαλώ εισάγετε το πολύ {max} λέξεις", - "error.validation.min": "Παρακαλώ εισάγετε μια τιμή ίση ή μεγαλύτερη από {min}", - "error.validation.minlength": "Παρακαλώ εισάγετε μεγαλύτερη τιμή. (τουλάχιστον {min} χαρακτήρες)", - "error.validation.minwords": "Παρακαλώ εισάγετε τουλάχιστον {min} λέξεις", - "error.validation.more": "Παρακαλώ εισάγετε τουλάχιστον {min} λέξεις", - "error.validation.notcontains": "Παρακαλώ εισάγετε μια τιμή που δεν περιέχει \"{needle}\"", - "error.validation.notin": "Παρακαλώ μην εισάγετε κανένα από τα παρακάτω: ({notIn})", - "error.validation.option": "Παρακαλώ κάντε μια έγκυρη επιλογή", - "error.validation.num": "Παρακαλώ εισάγετε έναν έγκυρο αριθμό", - "error.validation.required": "Παρακαλώ εισάγετε κάτι", - "error.validation.same": "Παρακαλώ εισάγετε \"{other}\"", - "error.validation.size": "Το μέγεθος της τιμής πρέπει να είναι \"{size}\"", - "error.validation.startswith": "Η τιμή πρέπει να αρχίζει με \"{start}\"", - "error.validation.time": "Παρακαλώ εισάγετε μια έγκυρη ώρα", - "error.validation.time.after": "Please enter a time after {time}", - "error.validation.time.before": "Please enter a time before {time}", - "error.validation.time.between": "Please enter a time between {min} and {max}", - "error.validation.url": "Παρακαλώ εισάγετε μια έγκυρη διεύθυνση URL", - - "expand": "Expand", - "expand.all": "Expand All", - - "field.required": "The field is required", - "field.blocks.changeType": "Change type", - "field.blocks.code.name": "Κώδικας", - "field.blocks.code.language": "Γλώσσα", - "field.blocks.code.placeholder": "Your code …", - "field.blocks.delete.confirm": "Do you really want to delete this block?", - "field.blocks.delete.confirm.all": "Do you really want to delete all blocks?", - "field.blocks.delete.confirm.selected": "Do you really want to delete the selected blocks?", - "field.blocks.empty": "No blocks yet", - "field.blocks.fieldsets.label": "Please select a block type …", - "field.blocks.fieldsets.paste": "Press {{ shortcut }} to paste/import blocks from your clipboard", - "field.blocks.gallery.name": "Gallery", - "field.blocks.gallery.images.empty": "No images yet", - "field.blocks.gallery.images.label": "Images", - "field.blocks.heading.level": "Level", - "field.blocks.heading.name": "Heading", - "field.blocks.heading.text": "Text", - "field.blocks.heading.placeholder": "Heading …", - "field.blocks.image.alt": "Alternative text", - "field.blocks.image.caption": "Caption", - "field.blocks.image.crop": "Crop", - "field.blocks.image.link": "Σύνδεσμος", - "field.blocks.image.location": "Location", - "field.blocks.image.name": "Εικόνα", - "field.blocks.image.placeholder": "Select an image", - "field.blocks.image.ratio": "Ratio", - "field.blocks.image.url": "Image URL", - "field.blocks.line.name": "Line", - "field.blocks.list.name": "List", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Text", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Quote", - "field.blocks.quote.text.label": "Text", - "field.blocks.quote.text.placeholder": "Quote …", - "field.blocks.quote.citation.label": "Citation", - "field.blocks.quote.citation.placeholder": "by …", - "field.blocks.text.name": "Text", - "field.blocks.text.placeholder": "Text …", - "field.blocks.video.caption": "Caption", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Enter a video URL", - "field.blocks.video.url.label": "Video-URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Δεν έχουν επιλεγεί αρχεία ακόμα", - - "field.layout.delete": "Delete layout", - "field.layout.delete.confirm": "Do you really want to delete this layout?", - "field.layout.empty": "No rows yet", - "field.layout.select": "Select a layout", - - "field.pages.empty": "Δεν έχουν επιλεγεί ακόμη σελίδες", - "field.structure.delete.confirm": "\u0395\u03af\u03c3\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03bf\u03c2 \u03cc\u03c4\u03b9 \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03ae\u03bd \u03c4\u03b7\u03bd \u03ba\u03b1\u03c4\u03b1\u03c7\u03ce\u03c1\u03b9\u03c3\u03b7;", - "field.structure.empty": "\u0394\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03bf\u03c5\u03bd \u03b1\u03ba\u03cc\u03bc\u03b7 \u03ba\u03b1\u03c4\u03b1\u03c7\u03c9\u03c1\u03af\u03c3\u03b5\u03b9\u03c2.", - "field.users.empty": "Δεν έχουν επιλεγεί ακόμη χρήστες", - - "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "\u0398\u03ad\u03bb\u03b5\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03b1 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf;", - "file.sort": "Change position", - - "files": "Αρχεία", - "files.empty": "Δεν υπάρχουν ακόμα αρχεία", - - "hide": "Hide", - "hour": "Ώρα", - "import": "Import", - "info": "Info", - "insert": "\u0395\u03b9\u03c3\u03b1\u03b3\u03c9\u03b3\u03ae", - "insert.after": "Insert after", - "insert.before": "Insert before", - "install": "Εγκατάσταση", - - "installation": "Εγκατάσταση", - "installation.completed": "Ο πίνακας ελέγχου έχει εγκατασταθεί", - "installation.disabled": "Η εγκατάσταση του πίνακα ελέγχου είναι απενεργοποιημένη για δημόσιους διακομιστές από προεπιλογή. Εκτελέστε την εγκατάσταση σε ένα τοπικό μηχάνημα ή ενεργοποιήστε την με την επιλογή panel.install.", - "installation.issues.accounts": "\u039f \u03c6\u03ac\u03ba\u03b5\u03bb\u03bf\u03c2 \/site\/accounts \u03b4\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03b3\u03b3\u03c1\u03ac\u03c8\u03b9\u03bc\u03bf\u03c2", - "installation.issues.content": "\u039f \u03c6\u03ac\u03ba\u03b5\u03bb\u03bf\u03c2 content \u03ba\u03b1\u03b9 \u03cc\u03bb\u03bf\u03b9 \u03bf\u03b9 \u03c5\u03c0\u03bf\u03c6\u03ac\u03ba\u03b5\u03bb\u03bf\u03b9 \u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03b3\u03b3\u03c1\u03ac\u03c8\u03b9\u03bc\u03bf\u03b9.", - "installation.issues.curl": "Απαιτείται η επέκταση CURL", - "installation.issues.headline": "Ο πίνακας ελέγχου δεν μπορεί να εγκατασταθεί", - "installation.issues.mbstring": "Απαιτείται η επέκταση MB String ", - "installation.issues.media": "Ο φάκελος /media δεν υπάρχει ή δεν είναι εγγράψιμος", - "installation.issues.php": "Βεβαιωθείτε ότι χρησιμοποιήτε PHP 7+", - "installation.issues.server": "To Kirby απαιτεί Apache, Nginx ή Caddy", - "installation.issues.sessions": "Ο φάκελος /site/sessions δεν υπάρχει ή δεν είναι εγγράψιμος", - - "language": "\u0393\u03bb\u03ce\u03c3\u03c3\u03b1", - "language.code": "Κώδικας", - "language.convert": "Χρήση ως προεπιλογή", - "language.convert.confirm": "

Θέλετε πραγματικά να μετατρέψετε τη {name} στην προεπιλεγμένη γλώσσα; Αυτό δεν μπορεί να ανακληθεί.

Αν το {name} χει μη μεταφρασμένο περιεχόμενο, δεν θα υπάρχει πλέον έγκυρη εναλλακτική λύση και τμήματα του ιστότοπού σας ενδέχεται να είναι κενά.

", - "language.create": "Προσθέστε μια νέα γλώσσα", - "language.delete.confirm": "Θέλετε πραγματικά να διαγράψετε τη γλώσσα {name} συμπεριλαμβανομένων όλων των μεταφράσεων; Αυτό δεν μπορεί να αναιρεθεί!", - "language.deleted": "Η γλώσσα έχει διαγραφεί", - "language.direction": "Κατεύθυνση ανάγνωσης", - "language.direction.ltr": "Αριστερά προς τα δεξιά", - "language.direction.rtl": "Δεξιά προς τα αριστερά", - "language.locale": "Συμβολοσειρά τοπικής γλώσσας PHP", - "language.locale.warning": "You are using a custom locale set up. Please modify it in the language file in /site/languages", - "language.name": "Ονομασία", - "language.updated": "Η γλώσσα έχει ενημερωθεί", - - "languages": "Γλώσσες", - "languages.default": "Προεπιλεγμένη γλώσσα", - "languages.empty": "Δεν υπάρχουν ακόμη γλώσσες", - "languages.secondary": "Δευτερεύουσες γλώσσες", - "languages.secondary.empty": "Δεν υπάρχουν ακόμα δευτερεύουσες γλώσσες", - - "license": "\u0386\u03b4\u03b5\u03b9\u03b1 \u03a7\u03c1\u03ae\u03c3\u03b7\u03c2 \u03c4\u03bf\u03c5 Kirby", - "license.buy": "Αγοράστε μια άδεια", - "license.register": "Εγγραφή", - "license.manage": "Manage your licenses", - "license.register.help": "Έχετε λάβει τον κωδικό άδειας χρήσης μετά την αγορά μέσω ηλεκτρονικού ταχυδρομείου. Παρακαλώ αντιγράψτε και επικολλήστε τον για να εγγραφείτε.", - "license.register.label": "Παρακαλώ εισαγάγετε τον κωδικό άδειας χρήσης", - "license.register.success": "Σας ευχαριστούμε για την υποστήριξη του Kirby", - "license.unregistered": "Αυτό είναι ένα μη καταχωρημένο demo του Kirby", - "license.unregistered.label": "Unregistered", - - "link": "\u03a3\u03cd\u03bd\u03b4\u03b5\u03c3\u03bc\u03bf\u03c2", - "link.text": "\u039a\u03b5\u03af\u03bc\u03b5\u03bd\u03bf \u03c3\u03c5\u03bd\u03b4\u03ad\u03c3\u03bc\u03bf\u03c5", - - "loading": "Φόρτωση", - - "lock.unsaved": "Unsaved changes", - "lock.unsaved.empty": "There are no more unsaved changes", - "lock.isLocked": "Unsaved changes by {email}", - "lock.file.isLocked": "The file is currently being edited by {email} and cannot be changed.", - "lock.page.isLocked": "The page is currently being edited by {email} and cannot be changed.", - "lock.unlock": "Unlock", - "lock.isUnlocked": "Your unsaved changes have been overwritten by another user. You can download your changes to merge them manually.", - - "login": "Σύνδεση", - "login.code.label.login": "Login code", - "login.code.label.password-reset": "Password reset code", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "If your email address is registered, the requested code was sent via email.", - "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.login.subject": "Your login code", - "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.password-reset.subject": "Your password reset code", - "login.remember": "Κρατήστε με συνδεδεμένο", - "login.reset": "Reset password", - "login.toggleText.code.email": "Login via email", - "login.toggleText.code.email-password": "Login with password", - "login.toggleText.password-reset.email": "Forgot your password?", - "login.toggleText.password-reset.email-password": "← Back to login", - - "logout": "\u0391\u03c0\u03bf\u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7", - - "menu": "Μενού", - "meridiem": "Π.Μ./Μ.Μ", - "mime": "Τύπος πολυμέσων", - "minutes": "Λεπτά", - - "month": "Μήνας", - "months.april": "\u0391\u03c0\u03c1\u03af\u03bb\u03b9\u03bf\u03c2", - "months.august": "\u0391\u03cd\u03b3\u03bf\u03c5\u03c3\u03c4\u03bf\u03c2", - "months.december": "\u0394\u03b5\u03ba\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2", - "months.february": "Φεβρουάριος", - "months.january": "\u0399\u03b1\u03bd\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2", - "months.july": "\u0399\u03bf\u03cd\u03bb\u03b9\u03bf\u03c2", - "months.june": "\u0399\u03bf\u03cd\u03bd\u03b9\u03bf\u03c2", - "months.march": "\u039c\u03ac\u03c1\u03c4\u03b9\u03bf\u03c2", - "months.may": "\u039c\u03ac\u03b9\u03bf\u03c2", - "months.november": "\u039d\u03bf\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2", - "months.october": "\u039f\u03ba\u03c4\u03ce\u03b2\u03c1\u03b9\u03bf\u03c2", - "months.september": "\u03a3\u03b5\u03c0\u03c4\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2", - - "more": "Περισσότερα", - "name": "Ονομασία", - "next": "Επόμενο", - "no": "no", - "off": "off", - "on": "on", - "open": "Άνοιγμα", - "open.newWindow": "Open in new window", - "options": "Eπιλογές", - "options.none": "No options", - - "orientation": "Προσανατολισμός", - "orientation.landscape": "Οριζόντιος", - "orientation.portrait": "Κάθετος", - "orientation.square": "Τετράγωνος", - - "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "\u0391\u03bb\u03bb\u03b1\u03b3\u03ae URL", - "page.changeSlug.fromTitle": "\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03b1\u03c0\u03cc \u03c4\u03bf\u03bd \u03c4\u03af\u03c4\u03bb\u03bf", - "page.changeStatus": "Αλλαγή κατάστασης", - "page.changeStatus.position": "Επιλέξτε μια θέση", - "page.changeStatus.select": "Επιλέξτε μια νέα κατάσταση", - "page.changeTemplate": "Αλλαγή προτύπου", - "page.delete.confirm": "\u0398\u03ad\u03bb\u03b5\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03b1 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03ae\u03bd \u03c4\u03b7 \u03c3\u03b5\u03bb\u03af\u03b4\u03b1;", - "page.delete.confirm.subpages": "Αυτή η σελίδα έχει υποσελίδες.
Όλες οι υποσελίδες θα διαγραφούν επίσης.", - "page.delete.confirm.title": "Εισάγετε τον τίτλο της σελίδας για επιβεβαίωση", - "page.draft.create": "Δημιουργία προσχεδίου", - "page.duplicate.appendix": "Αντιγραφή", - "page.duplicate.files": "Copy files", - "page.duplicate.pages": "Copy pages", - "page.sort": "Change position", - "page.status": "Kατάσταση", - "page.status.draft": "Προσχέδιο", - "page.status.draft.description": "The page is in draft mode and only visible for logged in editors or via secret link", - "page.status.listed": "Δημοσιευμένο", - "page.status.listed.description": "Αυτή η σελίδα είναι δημοσιευμένη για οποιονδήποτε", - "page.status.unlisted": "Μη καταχωρημένο", - "page.status.unlisted.description": "Η σελίδα είναι προσβάσιμη μόνο μέσω της διεύθυνσης URL", - - "pages": "Σελίδες", - "pages.empty": "Δεν υπάρχουν ακόμα σελίδες", - "pages.status.draft": "Προσχέδια", - "pages.status.listed": "Δημοσιευμένο", - "pages.status.unlisted": "Μη καταχωρημένο", - - "pagination.page": "Σελίδα", - - "password": "\u039a\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03a0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2", - "paste": "Paste", - "paste.after": "Paste after", - "pixel": "Εικονοστοιχέιο", - "plugins": "Plugins", - "prev": "Προηγούμενο", - "preview": "Preview", - "remove": "Αφαίρεση", - "rename": "Μετονομασία", - "replace": "\u0391\u03bd\u03c4\u03b9\u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7", - "retry": "\u0395\u03c0\u03b1\u03bd\u03ac\u03bb\u03b7\u03c8\u03b7", - "revert": "\u0391\u03b3\u03bd\u03cc\u03b7\u03c3\u03b7", - "revert.confirm": "Do you really want to delete all unsaved changes?", - - "role": "\u03a1\u03cc\u03bb\u03bf\u03c2", - "role.admin.description": "The admin has all rights", - "role.admin.title": "Admin", - "role.all": "Όλα", - "role.empty": "Δεν υπάρχουν χρήστες με αυτόν τον ρόλο", - "role.description.placeholder": "Χωρίς περιγραφή", - "role.nobody.description": "This is a fallback role without any permissions", - "role.nobody.title": "Nobody", - - "save": "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7", - "search": "Αναζήτηση", - "search.min": "Enter {min} characters to search", - "search.all": "Show all", - "search.results.none": "No results", - - "section.required": "The section is required", - - "security": "Security", - "select": "Επιλογή", - "server": "Server", - "settings": "Ρυθμίσεις", - "show": "Show", - "site.blueprint": "The site has no blueprint yet. You can define the setup in /site/blueprints/site.yml", - "size": "Μέγεθος", - "slug": "\u0395\u03c0\u03af\u03b8\u03b5\u03bc\u03b1 URL", - "sort": "Ταξινόμηση", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Τίτλος", - "template": "\u03a0\u03c1\u03cc\u03c4\u03c5\u03c0\u03bf", - "today": "Σήμερα", - - "toolbar.button.code": "Κώδικας", - "toolbar.button.bold": "\u0388\u03bd\u03c4\u03bf\u03bd\u03b7 \u03b3\u03c1\u03b1\u03c6\u03ae", - "toolbar.button.email": "Email", - "toolbar.button.headings": "Επικεφαλίδες", - "toolbar.button.heading.1": "Επικεφαλίδα 1", - "toolbar.button.heading.2": "Επικεφαλίδα 2", - "toolbar.button.heading.3": "Επικεφαλίδα 3", - "toolbar.button.heading.4": "Heading 4", - "toolbar.button.heading.5": "Heading 5", - "toolbar.button.heading.6": "Heading 6", - "toolbar.button.italic": "\u03a0\u03bb\u03ac\u03b3\u03b9\u03b1 \u03b3\u03c1\u03b1\u03c6\u03ae", - "toolbar.button.file": "Αρχείο", - "toolbar.button.file.select": "Select a file", - "toolbar.button.file.upload": "Upload a file", - "toolbar.button.link": "\u03a3\u03cd\u03bd\u03b4\u03b5\u03c3\u03bc\u03bf\u03c2", - "toolbar.button.paragraph": "Paragraph", - "toolbar.button.strike": "Strike-through", - "toolbar.button.ol": "Ταξινομημένη λίστα", - "toolbar.button.underline": "Underline", - "toolbar.button.ul": "Λίστα κουκκίδων", - - "translation.author": "Ομάδα Kirby", - "translation.direction": "ltr", - "translation.name": "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac", - "translation.locale": "el_GR", - - "upload": "Μεταφόρτωση", - "upload.error.cantMove": "The uploaded file could not be moved", - "upload.error.cantWrite": "Failed to write file to disk", - "upload.error.default": "The file could not be uploaded", - "upload.error.extension": "File upload stopped by extension", - "upload.error.formSize": "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the form", - "upload.error.iniPostSize": "The uploaded file exceeds the post_max_size directive in php.ini", - "upload.error.iniSize": "The uploaded file exceeds the upload_max_filesize directive in php.ini", - "upload.error.noFile": "No file was uploaded", - "upload.error.noFiles": "No files were uploaded", - "upload.error.partial": "The uploaded file was only partially uploaded", - "upload.error.tmpDir": "Missing a temporary folder", - "upload.errors": "Σφάλμα", - "upload.progress": "Μεταφόρτωση...", - - "url": "Διεύθινση url", - "url.placeholder": "https://example.com", - - "user": "Χρήστης", - "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Αλλαγή διεύθινσης ηλεκτρονικού ταχυδρομείου", - "user.changeLanguage": "Αλλαγή γλώσσας", - "user.changeName": "Μετονομασία χρήστη", - "user.changePassword": "Αλλαγή κωδικού πρόσβασης", - "user.changePassword.new": "Νέος Κωδικός Πρόσβασης", - "user.changePassword.new.confirm": "Επαληθεύση κωδικού πρόσβασης", - "user.changeRole": "Αλλαγή ρόλου", - "user.changeRole.select": "Επιλογή νέου ρόλου", - "user.create": "Προσθήκη νέου χρήστη", - "user.delete": "Διαγραφή χρήστη", - "user.delete.confirm": "\u0398\u03ad\u03bb\u03b5\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03b1 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03cc\u03bd \u03c4\u03bf\u03bd \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7;", - - "users": "Χρήστες", - - "version": "\u0388\u03ba\u03b4\u03bf\u03c3\u03b7 Kirby", - - "view.account": "\u039f \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2 \u03c3\u03b1\u03c2", - "view.installation": "\u0395\u03b3\u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7", - "view.languages": "Γλώσσες", - "view.resetPassword": "Reset password", - "view.site": "Iστοσελίδα", - "view.system": "System", - "view.users": "\u03a7\u03c1\u03ae\u03c3\u03c4\u03b5\u03c2", - - "welcome": "Καλώς ήρθατε", - "year": "Έτος", - "yes": "yes" + "account.changeName": "Change your name", + "account.delete": "Delete your account", + "account.delete.confirm": "Do you really want to delete your account? You will be logged out immediately. Your account cannot be recovered.", + + "add": "\u03a0\u03c1\u03bf\u03c3\u03b8\u03ae\u03ba\u03b7", + "author": "Author", + "avatar": "\u0395\u03b9\u03ba\u03cc\u03bd\u03b1 \u03c0\u03c1\u03bf\u03c6\u03af\u03bb", + "back": "Πίσω", + "cancel": "\u0391\u03ba\u03cd\u03c1\u03c9\u03c3\u03b7", + "change": "\u0391\u03bb\u03bb\u03b1\u03b3\u03ae", + "close": "\u039a\u03bb\u03b5\u03af\u03c3\u03b9\u03bc\u03bf", + "confirm": "Εντάξει", + "collapse": "Collapse", + "collapse.all": "Collapse All", + "copy": "Αντιγραφή", + "copy.all": "Copy all", + "create": "Δημιουργία", + + "date": "Ημερομηνία", + "date.select": "Επιλογή ημερομηνίας", + + "day": "Ημέρα", + "days.fri": "\u03a0\u03b1\u03c1", + "days.mon": "\u0394\u03b5\u03c5", + "days.sat": "\u03a3\u03ac\u03b2", + "days.sun": "\u039a\u03c5\u03c1", + "days.thu": "\u03a0\u03ad\u03bc", + "days.tue": "\u03a4\u03c1\u03af", + "days.wed": "\u03a4\u03b5\u03c4", + + "debugging": "Debugging", + + "delete": "\u0394\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03ae", + "delete.all": "Delete all", + + "dialog.files.empty": "No files to select", + "dialog.pages.empty": "No pages to select", + "dialog.users.empty": "No users to select", + + "dimensions": "Διαστάσεις", + "disabled": "Disabled", + "discard": "Απόρριψη", + "download": "Λήψη", + "duplicate": "Αντίγραφο", + + "edit": "\u0395\u03c0\u03b5\u03be\u03b5\u03c1\u03b3\u03b1\u03c3\u03af\u03b1", + + "email": "Διεύθυνση ηλεκτρονικού ταχυδρομείου", + "email.placeholder": "mail@example.com", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Environment", + + "error.access.code": "Mη έγκυρος κωδικός", + "error.access.login": "Mη έγκυρη σύνδεση", + "error.access.panel": "Δεν επιτρέπεται η πρόσβαση στον πίνακα ελέγχου", + "error.access.view": "Δεν επιτρέπεται η πρόσβαση σε αυτό το τμήμα του πίνακα ελέγχου", + + "error.avatar.create.fail": "Δεν ήταν δυνατή η μεταφόρτωση της εικόνας προφίλ", + "error.avatar.delete.fail": "Δεν ήταν δυνατή η διαγραφή της εικόνας προφίλ", + "error.avatar.dimensions.invalid": "Διατηρήστε το πλάτος και το ύψος της εικόνας προφίλ κάτω από 3000 εικονοστοιχεία", + "error.avatar.mime.forbidden": "\u039c\u03b7 \u03b1\u03c0\u03bf\u03b4\u03b5\u03ba\u03c4\u03cc\u03c2 \u03c4\u03cd\u03c0\u03bf\u03c2 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5", + + "error.blueprint.notFound": "Δεν ήταν δυνατή η φόρτωση του προσχεδίου \"{name}\"", + + "error.blocks.max.plural": "You must not add more than {max} blocks", + "error.blocks.max.singular": "You must not add more than one block", + "error.blocks.min.plural": "You must add at least {min} blocks", + "error.blocks.min.singular": "You must add at least one block", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "Δεν είναι δυνατή η εύρεση της προεπιλογής διεύθινσης ηλεκτρονικού ταχυδρομείου \"{name}\"", + + "error.field.converter.invalid": "Μη έγκυρος μετατροπέας \"{converter}\"", + + "error.file.changeName.empty": "The name must not be empty", + "error.file.changeName.permission": "Δεν επιτρέπεται να αλλάξετε το όνομα του \"{filename}\"", + "error.file.duplicate": "Ένα αρχείο με το όνομα \"{filename}\" υπάρχει ήδη", + "error.file.extension.forbidden": "\u039c\u03b7 \u03b1\u03c0\u03bf\u03b4\u03b5\u03ba\u03c4\u03ae \u03b5\u03c0\u03ad\u03ba\u03c4\u03b1\u03c3\u03b7 \u03b1\u03c1\u03c7\u03b5\u03af\u03bf\u03c5", + "error.file.extension.invalid": "Invalid extension: {extension}", + "error.file.extension.missing": "Λείπει η επέκταση για το \"{filename}\"", + "error.file.maxheight": "The height of the image must not exceed {height} pixels", + "error.file.maxsize": "The file is too large", + "error.file.maxwidth": "The width of the image must not exceed {width} pixels", + "error.file.mime.differs": "Το αρχείο πρέπει να είναι του ίδιου τύπου mime \"{mime}\"", + "error.file.mime.forbidden": "Ο τύπος μέσου \"{mime}\" δεν επιτρέπεται", + "error.file.mime.invalid": "Invalid mime type: {mime}", + "error.file.mime.missing": "Δεν είναι δυνατό να εντοπιστεί ο τύπος μέσου για το \"{filename}\"", + "error.file.minheight": "The height of the image must be at least {height} pixels", + "error.file.minsize": "The file is too small", + "error.file.minwidth": "The width of the image must be at least {width} pixels", + "error.file.name.missing": "Το όνομα αρχείου δεν μπορεί να είναι άδειο", + "error.file.notFound": "Δεν είναι δυνατό να βρεθεί το αρχείο \"{filename}\"", + "error.file.orientation": "The orientation of the image must be \"{orientation}\"", + "error.file.type.forbidden": "Δεν επιτρέπεται η μεταφόρτωση αρχείων {type}", + "error.file.type.invalid": "Invalid file type: {type}", + "error.file.undefined": "Δεν ήταν δυνατή η εύρεση του αρχείου", + + "error.form.incomplete": "Παρακαλώ διορθώστε τα σφάλματα στη φόρμα...", + "error.form.notSaved": "Δεν ήταν δυνατή η αποθήκευση της φόρμας", + + "error.language.code": "Please enter a valid code for the language", + "error.language.duplicate": "The language already exists", + "error.language.name": "Please enter a valid name for the language", + "error.language.notFound": "The language could not be found", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "There's an error in layout {index} settings", + + "error.license.format": "Please enter a valid license key", + "error.license.email": "Παρακαλώ εισάγετε μια έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου", + "error.license.verification": "The license could not be verified", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "The Panel is currently offline", + + "error.page.changeSlug.permission": "Δεν επιτρέπεται να αλλάξετε το URL της σελίδας \"{slug}\"", + "error.page.changeStatus.incomplete": "Δεν ήταν δυνατή η δημοσίευση της σελίδας καθώς περιέχει σφάλματα", + "error.page.changeStatus.permission": "Δεν είναι δυνατή η αλλαγή κατάστασης για αυτή τη σελίδα", + "error.page.changeStatus.toDraft.invalid": "Δεν είναι δυνατή η μετατροπή της σελίδας \"{slug}\" σε προσχέδιο", + "error.page.changeTemplate.invalid": "Δεν είναι δυνατή η αλλαγή προτύπου για τη σελίδα \"{slug}\"", + "error.page.changeTemplate.permission": "Δεν επιτρέπεται να αλλάξετε το πρότυπο για τη σελίδα \"{slug}\"", + "error.page.changeTitle.empty": "Ο τίτλος δεν μπορεί να είναι κενός", + "error.page.changeTitle.permission": "Δεν επιτρέπεται να αλλάξετε τον τίτλο για τη σελίδα \"{slug}\"", + "error.page.create.permission": "Δεν επιτρέπεται να δημιουργήσετε τη σελίδα \"{slug}\"", + "error.page.delete": "Δεν είναι δυνατή η διαγραφή της σελίδας \"{slug}\"", + "error.page.delete.confirm": "Παρακαλώ εισάγετε τον τίτλο της σελίδας για επιβεβαίωση", + "error.page.delete.hasChildren": "Δεν είναι δυνατή η διαγραφή της σελίδας καθώς περιέχει υποσελίδες", + "error.page.delete.permission": "Δεν επιτρέπεται η διαγραφή της σελίδας \"{slug}\"", + "error.page.draft.duplicate": "Υπάρχει ήδη ένα προσχέδιο σελίδας με την διεύθυνση URL \"{slug}\"", + "error.page.duplicate": "Υπάρχει ήδη μια σελίδα με την διεύθυνση URL \"{slug}\"", + "error.page.duplicate.permission": "You are not allowed to duplicate \"{slug}\"", + "error.page.notFound": "Δεν ήταν δυνατή η εύρεση της σελίδας \"{slug}\"", + "error.page.num.invalid": "Παρακαλώ εισάγετε έναν έγκυρο αριθμό ταξινόμησης. Οι αριθμοί δεν μπορεί να είναι αρνητικοί.", + "error.page.slug.invalid": "Please enter a valid URL appendix", + "error.page.slug.maxlength": "Slug length must be less than \"{length}\" characters", + "error.page.sort.permission": "Δεν είναι δυνατή η ταξινόμηση της σελίδας \"{slug}\"", + "error.page.status.invalid": "Ορίστε μια έγκυρη κατάσταση σελίδας", + "error.page.undefined": "Δεν ήταν δυνατή η εύρεση της σελίδας", + "error.page.update.permission": "Δεν επιτρέπεται η ενημέρωση της σελίδας \"{slug}\"", + + "error.section.files.max.plural": "Δεν πρέπει να προσθέσετε περισσότερα από {max} αρχεία στην ενότητα \"{section}\"", + "error.section.files.max.singular": "Δεν πρέπει να προσθέσετε περισσότερα από ένα αρχεία στην ενότητα \"{section}\"", + "error.section.files.min.plural": "The \"{section}\" section requires at least {min} files", + "error.section.files.min.singular": "The \"{section}\" section requires at least one file", + + "error.section.pages.max.plural": "Δεν μπορείτε να προσθέσετε περισσότερες από {max} σελίδες στην ενότητα \"{section}\"", + "error.section.pages.max.singular": "Δεν μπορείτε να προσθέσετε περισσότερες από μία σελίδες στην ενότητα \"{section}\"", + "error.section.pages.min.plural": "The \"{section}\" section requires at least {min} pages", + "error.section.pages.min.singular": "The \"{section}\" section requires at least one page", + + "error.section.notLoaded": "Δεν ήταν δυνατή η φόρτωση της ενότητας \"{name}\"", + "error.section.type.invalid": "Ο τύπος ενότητας \"{type}\" δεν είναι έγκυρος", + + "error.site.changeTitle.empty": "Ο τίτλος δεν μπορεί να είναι κενός", + "error.site.changeTitle.permission": "Δεν επιτρέπεται να αλλάξετε τον τίτλο του ιστότοπου", + "error.site.update.permission": "Δεν επιτρέπεται η ενημέρωση του ιστότοπου", + + "error.template.default.notFound": "Το προεπιλεγμένο πρότυπο δεν υπάρχει", + + "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Δεν επιτρέπεται να αλλάξετε τη διεύθινση ηλεκτρονικού ταχυδρομείου για τον χρήστη \"{name}\"", + "error.user.changeLanguage.permission": "Δεν επιτρέπεται να αλλάξετε τη γλώσσα για τον χρήστη \"{name}\"", + "error.user.changeName.permission": "Δεν επιτρέπεται να αλλάξετε το όνομα του χρήστη \"{name}", + "error.user.changePassword.permission": "Δεν επιτρέπεται να αλλάξετε τον κωδικό πρόσβασης για τον χρήστη \"{name}\"", + "error.user.changeRole.lastAdmin": "Ο ρόλος του τελευταίου διαχειριστή δεν μπορεί να αλλάξει", + "error.user.changeRole.permission": "Δεν επιτρέπεται να αλλάξετε το ρόλο του χρήστη \"{name}\"", + "error.user.changeRole.toAdmin": "You are not allowed to promote someone to the admin role", + "error.user.create.permission": "Δεν επιτρέπεται η δημιουργία αυτού του χρήστη", + "error.user.delete": "\u039f \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7\u03c2 \u03b4\u03b5\u03bd \u03bc\u03c0\u03bf\u03c1\u03bf\u03cd\u03c3\u03b5 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03b1\u03c6\u03b5\u03af", + "error.user.delete.lastAdmin": "Δεν είναι δυνατή η διαγραφή του τελευταίου διαχειριστή", + "error.user.delete.lastUser": "Δεν είναι δυνατή η διαγραφή του τελευταίου χρήστη", + "error.user.delete.permission": "Δεν επιτρέπεται να διαγράψετ τον χρήστη \"{name}\"", + "error.user.duplicate": "Ένας χρήστης με τη διεύθυνση ηλεκτρονικού ταχυδρομείου \"{email}\" υπάρχει ήδη", + "error.user.email.invalid": "Παρακαλώ εισάγετε μια έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου", + "error.user.language.invalid": "Παρακαλώ εισαγάγετε μια έγκυρη γλώσσα", + "error.user.notFound": "Δεν είναι δυνατή η εύρεση του χρήστη \"{name}\"", + "error.user.password.invalid": "Παρακαλώ εισάγετε έναν έγκυρο κωδικό πρόσβασης. Οι κωδικοί πρόσβασης πρέπει να έχουν μήκος τουλάχιστον 8 χαρακτήρων.", + "error.user.password.notSame": "\u03a0\u03b1\u03c1\u03b1\u03ba\u03b1\u03bb\u03bf\u03cd\u03bc\u03b5 \u03b5\u03c0\u03b9\u03b2\u03b5\u03b2\u03b1\u03b9\u03ce\u03c3\u03c4\u03b5 \u03c4\u03bf\u03bd \u039a\u03c9\u03b4\u03b9\u03ba\u03cc \u03a0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2", + "error.user.password.undefined": "Ο χρήστης δεν έχει κωδικό πρόσβασης", + "error.user.password.wrong": "Wrong password", + "error.user.role.invalid": "Παρακαλώ εισαγάγετε έναν έγκυρο ρόλο", + "error.user.undefined": "Δεν είναι δυνατή η εύρεση του χρήστη", + "error.user.update.permission": "Δεν επιτρέπεται η ενημέρωση του χρήστη \"{name}\"", + + "error.validation.accepted": "Παρακαλώ επιβεβαιώστε", + "error.validation.alpha": "Παρακαλώ εισάγετε μόνο χαρακτήρες μεταξύ των a-z", + "error.validation.alphanum": "Παρακαλώ εισάγετε μόνο χαρακτήρες μεταξύ των a-z ή αριθμούς απο το 0 έως το 9", + "error.validation.between": "Παρακαλώ εισάγετε μια τιμή μεταξύ \"{min}\" και \"{max}\"", + "error.validation.boolean": "Παρακαλώ επιβεβαιώστε ή αρνηθείτε", + "error.validation.contains": "Παρακαλώ καταχωρίστε μια τιμή που περιέχει \"{needle}\"", + "error.validation.date": "Παρακαλώ εισάγετε μία έγκυρη ημερομηνία", + "error.validation.date.after": "Please enter a date after {date}", + "error.validation.date.before": "Please enter a date before {date}", + "error.validation.date.between": "Please enter a date between {min} and {max}", + "error.validation.denied": "Παρακαλώ αρνηθείτε", + "error.validation.different": "Η τιμή δεν μπορεί να είναι \"{other}\"", + "error.validation.email": "Παρακαλώ εισάγετε μια έγκυρη διεύθυνση ηλεκτρονικού ταχυδρομείου", + "error.validation.endswith": "Η τιμή πρέπει να τελειώνει με \"{end}\"", + "error.validation.filename": "Παρακαλώ εισάγετε ένα έγκυρο όνομα αρχείου", + "error.validation.in": "Παρακαλώ εισάγετε ένα από τα παρακάτω: ({in})", + "error.validation.integer": "Παρακαλώ εισάγετε έναν έγκυρο ακέραιο αριθμό", + "error.validation.ip": "Παρακαλώ εισάγετε μια έγκυρη διεύθυνση IP", + "error.validation.less": "Παρακαλώ εισάγετε μια τιμή μικρότερη από {max}", + "error.validation.match": "Η τιμή δεν ταιριάζει με το αναμενόμενο πρότυπο", + "error.validation.max": "Παρακαλώ εισάγετε μια τιμή ίση ή μικρότερη από {max}", + "error.validation.maxlength": "Παρακαλώ εισάγετε μια μικρότερη τιμή. (max. {max} χαρακτήρες)", + "error.validation.maxwords": "Παρακαλώ εισάγετε το πολύ {max} λέξεις", + "error.validation.min": "Παρακαλώ εισάγετε μια τιμή ίση ή μεγαλύτερη από {min}", + "error.validation.minlength": "Παρακαλώ εισάγετε μεγαλύτερη τιμή. (τουλάχιστον {min} χαρακτήρες)", + "error.validation.minwords": "Παρακαλώ εισάγετε τουλάχιστον {min} λέξεις", + "error.validation.more": "Παρακαλώ εισάγετε τουλάχιστον {min} λέξεις", + "error.validation.notcontains": "Παρακαλώ εισάγετε μια τιμή που δεν περιέχει \"{needle}\"", + "error.validation.notin": "Παρακαλώ μην εισάγετε κανένα από τα παρακάτω: ({notIn})", + "error.validation.option": "Παρακαλώ κάντε μια έγκυρη επιλογή", + "error.validation.num": "Παρακαλώ εισάγετε έναν έγκυρο αριθμό", + "error.validation.required": "Παρακαλώ εισάγετε κάτι", + "error.validation.same": "Παρακαλώ εισάγετε \"{other}\"", + "error.validation.size": "Το μέγεθος της τιμής πρέπει να είναι \"{size}\"", + "error.validation.startswith": "Η τιμή πρέπει να αρχίζει με \"{start}\"", + "error.validation.time": "Παρακαλώ εισάγετε μια έγκυρη ώρα", + "error.validation.time.after": "Please enter a time after {time}", + "error.validation.time.before": "Please enter a time before {time}", + "error.validation.time.between": "Please enter a time between {min} and {max}", + "error.validation.url": "Παρακαλώ εισάγετε μια έγκυρη διεύθυνση URL", + + "expand": "Expand", + "expand.all": "Expand All", + + "field.required": "The field is required", + "field.blocks.changeType": "Change type", + "field.blocks.code.name": "Κώδικας", + "field.blocks.code.language": "Γλώσσα", + "field.blocks.code.placeholder": "Your code …", + "field.blocks.delete.confirm": "Do you really want to delete this block?", + "field.blocks.delete.confirm.all": "Do you really want to delete all blocks?", + "field.blocks.delete.confirm.selected": "Do you really want to delete the selected blocks?", + "field.blocks.empty": "No blocks yet", + "field.blocks.fieldsets.label": "Please select a block type …", + "field.blocks.fieldsets.paste": "Press {{ shortcut }} to paste/import blocks from your clipboard", + "field.blocks.gallery.name": "Gallery", + "field.blocks.gallery.images.empty": "No images yet", + "field.blocks.gallery.images.label": "Images", + "field.blocks.heading.level": "Level", + "field.blocks.heading.name": "Heading", + "field.blocks.heading.text": "Text", + "field.blocks.heading.placeholder": "Heading …", + "field.blocks.image.alt": "Alternative text", + "field.blocks.image.caption": "Caption", + "field.blocks.image.crop": "Crop", + "field.blocks.image.link": "Σύνδεσμος", + "field.blocks.image.location": "Location", + "field.blocks.image.name": "Εικόνα", + "field.blocks.image.placeholder": "Select an image", + "field.blocks.image.ratio": "Ratio", + "field.blocks.image.url": "Image URL", + "field.blocks.line.name": "Line", + "field.blocks.list.name": "List", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Text", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Quote", + "field.blocks.quote.text.label": "Text", + "field.blocks.quote.text.placeholder": "Quote …", + "field.blocks.quote.citation.label": "Citation", + "field.blocks.quote.citation.placeholder": "by …", + "field.blocks.text.name": "Text", + "field.blocks.text.placeholder": "Text …", + "field.blocks.video.caption": "Caption", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Enter a video URL", + "field.blocks.video.url.label": "Video-URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Δεν έχουν επιλεγεί αρχεία ακόμα", + + "field.layout.delete": "Delete layout", + "field.layout.delete.confirm": "Do you really want to delete this layout?", + "field.layout.empty": "No rows yet", + "field.layout.select": "Select a layout", + + "field.object.empty": "No information yet", + + "field.pages.empty": "Δεν έχουν επιλεγεί ακόμη σελίδες", + + "field.structure.delete.confirm": "\u0395\u03af\u03c3\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03bf\u03c2 \u03cc\u03c4\u03b9 \u03b8\u03ad\u03bb\u03b5\u03c4\u03b5 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03ae\u03bd \u03c4\u03b7\u03bd \u03ba\u03b1\u03c4\u03b1\u03c7\u03ce\u03c1\u03b9\u03c3\u03b7;", + "field.structure.empty": "\u0394\u03b5\u03bd \u03c5\u03c0\u03ac\u03c1\u03c7\u03bf\u03c5\u03bd \u03b1\u03ba\u03cc\u03bc\u03b7 \u03ba\u03b1\u03c4\u03b1\u03c7\u03c9\u03c1\u03af\u03c3\u03b5\u03b9\u03c2.", + + "field.users.empty": "Δεν έχουν επιλεγεί ακόμη χρήστες", + + "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "\u0398\u03ad\u03bb\u03b5\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03b1 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03cc \u03c4\u03bf \u03b1\u03c1\u03c7\u03b5\u03af\u03bf;", + "file.sort": "Change position", + + "files": "Αρχεία", + "files.empty": "Δεν υπάρχουν ακόμα αρχεία", + + "hide": "Hide", + "hour": "Ώρα", + "import": "Import", + "info": "Info", + "insert": "\u0395\u03b9\u03c3\u03b1\u03b3\u03c9\u03b3\u03ae", + "insert.after": "Insert after", + "insert.before": "Insert before", + "install": "Εγκατάσταση", + + "installation": "Εγκατάσταση", + "installation.completed": "Ο πίνακας ελέγχου έχει εγκατασταθεί", + "installation.disabled": "Η εγκατάσταση του πίνακα ελέγχου είναι απενεργοποιημένη για δημόσιους διακομιστές από προεπιλογή. Εκτελέστε την εγκατάσταση σε ένα τοπικό μηχάνημα ή ενεργοποιήστε την με την επιλογή panel.install.", + "installation.issues.accounts": "\u039f \u03c6\u03ac\u03ba\u03b5\u03bb\u03bf\u03c2 \/site\/accounts \u03b4\u03b5\u03bd \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03b3\u03b3\u03c1\u03ac\u03c8\u03b9\u03bc\u03bf\u03c2", + "installation.issues.content": "\u039f \u03c6\u03ac\u03ba\u03b5\u03bb\u03bf\u03c2 content \u03ba\u03b1\u03b9 \u03cc\u03bb\u03bf\u03b9 \u03bf\u03b9 \u03c5\u03c0\u03bf\u03c6\u03ac\u03ba\u03b5\u03bb\u03bf\u03b9 \u03c0\u03c1\u03ad\u03c0\u03b5\u03b9 \u03bd\u03b1 \u03b5\u03af\u03bd\u03b1\u03b9 \u03b5\u03b3\u03b3\u03c1\u03ac\u03c8\u03b9\u03bc\u03bf\u03b9.", + "installation.issues.curl": "Απαιτείται η επέκταση CURL", + "installation.issues.headline": "Ο πίνακας ελέγχου δεν μπορεί να εγκατασταθεί", + "installation.issues.mbstring": "Απαιτείται η επέκταση MB String ", + "installation.issues.media": "Ο φάκελος /media δεν υπάρχει ή δεν είναι εγγράψιμος", + "installation.issues.php": "Βεβαιωθείτε ότι χρησιμοποιήτε PHP 7+", + "installation.issues.server": "To Kirby απαιτεί Apache, Nginx ή Caddy", + "installation.issues.sessions": "Ο φάκελος /site/sessions δεν υπάρχει ή δεν είναι εγγράψιμος", + + "language": "\u0393\u03bb\u03ce\u03c3\u03c3\u03b1", + "language.code": "Κώδικας", + "language.convert": "Χρήση ως προεπιλογή", + "language.convert.confirm": "

Θέλετε πραγματικά να μετατρέψετε τη {name} στην προεπιλεγμένη γλώσσα; Αυτό δεν μπορεί να ανακληθεί.

Αν το {name} χει μη μεταφρασμένο περιεχόμενο, δεν θα υπάρχει πλέον έγκυρη εναλλακτική λύση και τμήματα του ιστότοπού σας ενδέχεται να είναι κενά.

", + "language.create": "Προσθέστε μια νέα γλώσσα", + "language.delete.confirm": "Θέλετε πραγματικά να διαγράψετε τη γλώσσα {name} συμπεριλαμβανομένων όλων των μεταφράσεων; Αυτό δεν μπορεί να αναιρεθεί!", + "language.deleted": "Η γλώσσα έχει διαγραφεί", + "language.direction": "Κατεύθυνση ανάγνωσης", + "language.direction.ltr": "Αριστερά προς τα δεξιά", + "language.direction.rtl": "Δεξιά προς τα αριστερά", + "language.locale": "Συμβολοσειρά τοπικής γλώσσας PHP", + "language.locale.warning": "You are using a custom locale set up. Please modify it in the language file in /site/languages", + "language.name": "Ονομασία", + "language.updated": "Η γλώσσα έχει ενημερωθεί", + + "languages": "Γλώσσες", + "languages.default": "Προεπιλεγμένη γλώσσα", + "languages.empty": "Δεν υπάρχουν ακόμη γλώσσες", + "languages.secondary": "Δευτερεύουσες γλώσσες", + "languages.secondary.empty": "Δεν υπάρχουν ακόμα δευτερεύουσες γλώσσες", + + "license": "\u0386\u03b4\u03b5\u03b9\u03b1 \u03a7\u03c1\u03ae\u03c3\u03b7\u03c2 \u03c4\u03bf\u03c5 Kirby", + "license.buy": "Αγοράστε μια άδεια", + "license.register": "Εγγραφή", + "license.manage": "Manage your licenses", + "license.register.help": "Έχετε λάβει τον κωδικό άδειας χρήσης μετά την αγορά μέσω ηλεκτρονικού ταχυδρομείου. Παρακαλώ αντιγράψτε και επικολλήστε τον για να εγγραφείτε.", + "license.register.label": "Παρακαλώ εισαγάγετε τον κωδικό άδειας χρήσης", + "license.register.success": "Σας ευχαριστούμε για την υποστήριξη του Kirby", + "license.unregistered": "Αυτό είναι ένα μη καταχωρημένο demo του Kirby", + "license.unregistered.label": "Unregistered", + + "link": "\u03a3\u03cd\u03bd\u03b4\u03b5\u03c3\u03bc\u03bf\u03c2", + "link.text": "\u039a\u03b5\u03af\u03bc\u03b5\u03bd\u03bf \u03c3\u03c5\u03bd\u03b4\u03ad\u03c3\u03bc\u03bf\u03c5", + + "loading": "Φόρτωση", + + "lock.unsaved": "Unsaved changes", + "lock.unsaved.empty": "There are no more unsaved changes", + "lock.isLocked": "Unsaved changes by {email}", + "lock.file.isLocked": "The file is currently being edited by {email} and cannot be changed.", + "lock.page.isLocked": "The page is currently being edited by {email} and cannot be changed.", + "lock.unlock": "Unlock", + "lock.isUnlocked": "Your unsaved changes have been overwritten by another user. You can download your changes to merge them manually.", + + "login": "Σύνδεση", + "login.code.label.login": "Login code", + "login.code.label.password-reset": "Password reset code", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "If your email address is registered, the requested code was sent via email.", + "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.login.subject": "Your login code", + "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.password-reset.subject": "Your password reset code", + "login.remember": "Κρατήστε με συνδεδεμένο", + "login.reset": "Reset password", + "login.toggleText.code.email": "Login via email", + "login.toggleText.code.email-password": "Login with password", + "login.toggleText.password-reset.email": "Forgot your password?", + "login.toggleText.password-reset.email-password": "← Back to login", + + "logout": "\u0391\u03c0\u03bf\u03c3\u03cd\u03bd\u03b4\u03b5\u03c3\u03b7", + + "menu": "Μενού", + "meridiem": "Π.Μ./Μ.Μ", + "mime": "Τύπος πολυμέσων", + "minutes": "Λεπτά", + + "month": "Μήνας", + "months.april": "\u0391\u03c0\u03c1\u03af\u03bb\u03b9\u03bf\u03c2", + "months.august": "\u0391\u03cd\u03b3\u03bf\u03c5\u03c3\u03c4\u03bf\u03c2", + "months.december": "\u0394\u03b5\u03ba\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2", + "months.february": "Φεβρουάριος", + "months.january": "\u0399\u03b1\u03bd\u03bf\u03c5\u03ac\u03c1\u03b9\u03bf\u03c2", + "months.july": "\u0399\u03bf\u03cd\u03bb\u03b9\u03bf\u03c2", + "months.june": "\u0399\u03bf\u03cd\u03bd\u03b9\u03bf\u03c2", + "months.march": "\u039c\u03ac\u03c1\u03c4\u03b9\u03bf\u03c2", + "months.may": "\u039c\u03ac\u03b9\u03bf\u03c2", + "months.november": "\u039d\u03bf\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2", + "months.october": "\u039f\u03ba\u03c4\u03ce\u03b2\u03c1\u03b9\u03bf\u03c2", + "months.september": "\u03a3\u03b5\u03c0\u03c4\u03ad\u03bc\u03b2\u03c1\u03b9\u03bf\u03c2", + + "more": "Περισσότερα", + "name": "Ονομασία", + "next": "Επόμενο", + "no": "no", + "off": "off", + "on": "on", + "open": "Άνοιγμα", + "open.newWindow": "Open in new window", + "options": "Eπιλογές", + "options.none": "No options", + + "orientation": "Προσανατολισμός", + "orientation.landscape": "Οριζόντιος", + "orientation.portrait": "Κάθετος", + "orientation.square": "Τετράγωνος", + + "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "\u0391\u03bb\u03bb\u03b1\u03b3\u03ae URL", + "page.changeSlug.fromTitle": "\u0394\u03b7\u03bc\u03b9\u03bf\u03c5\u03c1\u03b3\u03af\u03b1 \u03b1\u03c0\u03cc \u03c4\u03bf\u03bd \u03c4\u03af\u03c4\u03bb\u03bf", + "page.changeStatus": "Αλλαγή κατάστασης", + "page.changeStatus.position": "Επιλέξτε μια θέση", + "page.changeStatus.select": "Επιλέξτε μια νέα κατάσταση", + "page.changeTemplate": "Αλλαγή προτύπου", + "page.delete.confirm": "\u0398\u03ad\u03bb\u03b5\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03b1 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03ae\u03bd \u03c4\u03b7 \u03c3\u03b5\u03bb\u03af\u03b4\u03b1;", + "page.delete.confirm.subpages": "Αυτή η σελίδα έχει υποσελίδες.
Όλες οι υποσελίδες θα διαγραφούν επίσης.", + "page.delete.confirm.title": "Εισάγετε τον τίτλο της σελίδας για επιβεβαίωση", + "page.draft.create": "Δημιουργία προσχεδίου", + "page.duplicate.appendix": "Αντιγραφή", + "page.duplicate.files": "Copy files", + "page.duplicate.pages": "Copy pages", + "page.sort": "Change position", + "page.status": "Kατάσταση", + "page.status.draft": "Προσχέδιο", + "page.status.draft.description": "The page is in draft mode and only visible for logged in editors or via secret link", + "page.status.listed": "Δημοσιευμένο", + "page.status.listed.description": "Αυτή η σελίδα είναι δημοσιευμένη για οποιονδήποτε", + "page.status.unlisted": "Μη καταχωρημένο", + "page.status.unlisted.description": "Η σελίδα είναι προσβάσιμη μόνο μέσω της διεύθυνσης URL", + + "pages": "Σελίδες", + "pages.empty": "Δεν υπάρχουν ακόμα σελίδες", + "pages.status.draft": "Προσχέδια", + "pages.status.listed": "Δημοσιευμένο", + "pages.status.unlisted": "Μη καταχωρημένο", + + "pagination.page": "Σελίδα", + + "password": "\u039a\u03c9\u03b4\u03b9\u03ba\u03cc\u03c2 \u03a0\u03c1\u03cc\u03c3\u03b2\u03b1\u03c3\u03b7\u03c2", + "paste": "Paste", + "paste.after": "Paste after", + "pixel": "Εικονοστοιχέιο", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "Προηγούμενο", + "preview": "Preview", + "remove": "Αφαίρεση", + "rename": "Μετονομασία", + "replace": "\u0391\u03bd\u03c4\u03b9\u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7", + "retry": "\u0395\u03c0\u03b1\u03bd\u03ac\u03bb\u03b7\u03c8\u03b7", + "revert": "\u0391\u03b3\u03bd\u03cc\u03b7\u03c3\u03b7", + "revert.confirm": "Do you really want to delete all unsaved changes?", + + "role": "\u03a1\u03cc\u03bb\u03bf\u03c2", + "role.admin.description": "The admin has all rights", + "role.admin.title": "Admin", + "role.all": "Όλα", + "role.empty": "Δεν υπάρχουν χρήστες με αυτόν τον ρόλο", + "role.description.placeholder": "Χωρίς περιγραφή", + "role.nobody.description": "This is a fallback role without any permissions", + "role.nobody.title": "Nobody", + + "save": "\u0391\u03c0\u03bf\u03b8\u03ae\u03ba\u03b5\u03c5\u03c3\u03b7", + "search": "Αναζήτηση", + "search.min": "Enter {min} characters to search", + "search.all": "Show all", + "search.results.none": "No results", + + "section.required": "The section is required", + + "security": "Security", + "select": "Επιλογή", + "server": "Server", + "settings": "Ρυθμίσεις", + "show": "Show", + "site.blueprint": "The site has no blueprint yet. You can define the setup in /site/blueprints/site.yml", + "size": "Μέγεθος", + "slug": "\u0395\u03c0\u03af\u03b8\u03b5\u03bc\u03b1 URL", + "sort": "Ταξινόμηση", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Τίτλος", + "template": "\u03a0\u03c1\u03cc\u03c4\u03c5\u03c0\u03bf", + "today": "Σήμερα", + + "toolbar.button.code": "Κώδικας", + "toolbar.button.bold": "\u0388\u03bd\u03c4\u03bf\u03bd\u03b7 \u03b3\u03c1\u03b1\u03c6\u03ae", + "toolbar.button.email": "Email", + "toolbar.button.headings": "Επικεφαλίδες", + "toolbar.button.heading.1": "Επικεφαλίδα 1", + "toolbar.button.heading.2": "Επικεφαλίδα 2", + "toolbar.button.heading.3": "Επικεφαλίδα 3", + "toolbar.button.heading.4": "Heading 4", + "toolbar.button.heading.5": "Heading 5", + "toolbar.button.heading.6": "Heading 6", + "toolbar.button.italic": "\u03a0\u03bb\u03ac\u03b3\u03b9\u03b1 \u03b3\u03c1\u03b1\u03c6\u03ae", + "toolbar.button.file": "Αρχείο", + "toolbar.button.file.select": "Select a file", + "toolbar.button.file.upload": "Upload a file", + "toolbar.button.link": "\u03a3\u03cd\u03bd\u03b4\u03b5\u03c3\u03bc\u03bf\u03c2", + "toolbar.button.paragraph": "Paragraph", + "toolbar.button.strike": "Strike-through", + "toolbar.button.ol": "Ταξινομημένη λίστα", + "toolbar.button.underline": "Underline", + "toolbar.button.ul": "Λίστα κουκκίδων", + + "translation.author": "Ομάδα Kirby", + "translation.direction": "ltr", + "translation.name": "\u0395\u03bb\u03bb\u03b7\u03bd\u03b9\u03ba\u03ac", + "translation.locale": "el_GR", + + "upload": "Μεταφόρτωση", + "upload.error.cantMove": "The uploaded file could not be moved", + "upload.error.cantWrite": "Failed to write file to disk", + "upload.error.default": "The file could not be uploaded", + "upload.error.extension": "File upload stopped by extension", + "upload.error.formSize": "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the form", + "upload.error.iniPostSize": "The uploaded file exceeds the post_max_size directive in php.ini", + "upload.error.iniSize": "The uploaded file exceeds the upload_max_filesize directive in php.ini", + "upload.error.noFile": "No file was uploaded", + "upload.error.noFiles": "No files were uploaded", + "upload.error.partial": "The uploaded file was only partially uploaded", + "upload.error.tmpDir": "Missing a temporary folder", + "upload.errors": "Σφάλμα", + "upload.progress": "Μεταφόρτωση...", + + "url": "Διεύθινση url", + "url.placeholder": "https://example.com", + + "user": "Χρήστης", + "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Αλλαγή διεύθινσης ηλεκτρονικού ταχυδρομείου", + "user.changeLanguage": "Αλλαγή γλώσσας", + "user.changeName": "Μετονομασία χρήστη", + "user.changePassword": "Αλλαγή κωδικού πρόσβασης", + "user.changePassword.new": "Νέος Κωδικός Πρόσβασης", + "user.changePassword.new.confirm": "Επαληθεύση κωδικού πρόσβασης", + "user.changeRole": "Αλλαγή ρόλου", + "user.changeRole.select": "Επιλογή νέου ρόλου", + "user.create": "Προσθήκη νέου χρήστη", + "user.delete": "Διαγραφή χρήστη", + "user.delete.confirm": "\u0398\u03ad\u03bb\u03b5\u03c4\u03b5 \u03c3\u03af\u03b3\u03bf\u03c5\u03c1\u03b1 \u03bd\u03b1 \u03b4\u03b9\u03b1\u03b3\u03c1\u03ac\u03c8\u03b5\u03c4\u03b5 \u03b1\u03c5\u03c4\u03cc\u03bd \u03c4\u03bf\u03bd \u03c7\u03c1\u03ae\u03c3\u03c4\u03b7;", + + "users": "Χρήστες", + + "version": "\u0388\u03ba\u03b4\u03bf\u03c3\u03b7 Kirby", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "\u039f \u03bb\u03bf\u03b3\u03b1\u03c1\u03b9\u03b1\u03c3\u03bc\u03cc\u03c2 \u03c3\u03b1\u03c2", + "view.installation": "\u0395\u03b3\u03ba\u03b1\u03c4\u03ac\u03c3\u03c4\u03b1\u03c3\u03b7", + "view.languages": "Γλώσσες", + "view.resetPassword": "Reset password", + "view.site": "Iστοσελίδα", + "view.system": "System", + "view.users": "\u03a7\u03c1\u03ae\u03c3\u03c4\u03b5\u03c2", + + "welcome": "Καλώς ήρθατε", + "year": "Έτος", + "yes": "yes" } diff --git a/kirby/i18n/translations/en.json b/kirby/i18n/translations/en.json index 8c98cab..96015cf 100644 --- a/kirby/i18n/translations/en.json +++ b/kirby/i18n/translations/en.json @@ -1,573 +1,596 @@ { - "account.changeName": "Change your name", - "account.delete": "Delete your account", - "account.delete.confirm": "Do you really want to delete your account? You will be logged out immediately. Your account cannot be recovered.", - - "add": "Add", - "author": "Author", - "avatar": "Profile picture", - "back": "Back", - "cancel": "Cancel", - "change": "Change", - "close": "Close", - "confirm": "Ok", - "collapse": "Collapse", - "collapse.all": "Collapse All", - "copy": "Copy", - "copy.all": "Copy all", - "create": "Create", - - "date": "Date", - "date.select": "Select a date", - - "day": "Day", - "days.fri": "Fri", - "days.mon": "Mon", - "days.sat": "Sat", - "days.sun": "Sun", - "days.thu": "Thu", - "days.tue": "Tue", - "days.wed": "Wed", - - "debugging": "Debugging", - - "delete": "Delete", - "delete.all": "Delete all", - - "dialog.files.empty": "No files to select", - "dialog.pages.empty": "No pages to select", - "dialog.users.empty": "No users to select", - - "dimensions": "Dimensions", - "disabled": "Disabled", - "discard": "Discard", - "download": "Download", - "duplicate": "Duplicate", - - "edit": "Edit", - - "email": "Email", - "email.placeholder": "mail@example.com", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Environment", - - "error.access.code": "Invalid code", - "error.access.login": "Invalid login", - "error.access.panel": "You are not allowed to access the panel", - "error.access.view": "You are not allowed to access this part of the panel", - - "error.avatar.create.fail": "The profile picture could not be uploaded", - "error.avatar.delete.fail": "The profile picture could not be deleted", - "error.avatar.dimensions.invalid": "Please keep the width and height of the profile picture under 3000 pixels", - "error.avatar.mime.forbidden": "The profile picture must be JPEG or PNG files", - - "error.blueprint.notFound": "The blueprint \"{name}\" could not be loaded", - - "error.blocks.max.plural": "You must not add more than {max} blocks", - "error.blocks.max.singular": "You must not add more than one block", - "error.blocks.min.plural": "You must add at least {min} blocks", - "error.blocks.min.singular": "You must add at least one block", - "error.blocks.validation": "There's an error in block {index}", - - "error.email.preset.notFound": "The email preset \"{name}\" cannot be found", - - "error.field.converter.invalid": "Invalid converter \"{converter}\"", - - "error.file.changeName.empty": "The name must not be empty", - "error.file.changeName.permission": "You are not allowed to change the name of \"{filename}\"", - "error.file.duplicate": "A file with the name \"{filename}\" already exists", - "error.file.extension.forbidden": "The extension \"{extension}\" is not allowed", - "error.file.extension.invalid": "Invalid extension: {extension}", - "error.file.extension.missing": "The extensions for \"{filename}\" is missing", - "error.file.maxheight": "The height of the image must not exceed {height} pixels", - "error.file.maxsize": "The file is too large", - "error.file.maxwidth": "The width of the image must not exceed {width} pixels", - "error.file.mime.differs": "The uploaded file must be of the same mime type \"{mime}\"", - "error.file.mime.forbidden": "The media type \"{mime}\" is not allowed", - "error.file.mime.invalid": "Invalid mime type: {mime}", - "error.file.mime.missing": "The media type for \"{filename}\" cannot be detected", - "error.file.minheight": "The height of the image must be at least {height} pixels", - "error.file.minsize": "The file is too small", - "error.file.minwidth": "The width of the image must be at least {width} pixels", - "error.file.name.missing": "The filename must not be empty", - "error.file.notFound": "The file \"{filename}\" cannot be found", - "error.file.orientation": "The orientation of the image must be \"{orientation}\"", - "error.file.type.forbidden": "You are not allowed to upload {type} files", - "error.file.type.invalid": "Invalid file type: {type}", - "error.file.undefined": "The file cannot be found", - - "error.form.incomplete": "Please fix all form errors…", - "error.form.notSaved": "The form could not be saved", - - "error.language.code": "Please enter a valid code for the language", - "error.language.duplicate": "The language already exists", - "error.language.name": "Please enter a valid name for the language", - "error.language.notFound": "The language could not be found", - - "error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}", - "error.layout.validation.settings": "There's an error in layout {index} settings", - - "error.license.format": "Please enter a valid license key", - "error.license.email": "Please enter a valid email address", - "error.license.verification": "The license could not be verified", - - "error.offline": "The Panel is currently offline", - - "error.page.changeSlug.permission": "You are not allowed to change the URL appendix for \"{slug}\"", - "error.page.changeStatus.incomplete": "The page has errors and cannot be published", - "error.page.changeStatus.permission": "The status for this page cannot be changed", - "error.page.changeStatus.toDraft.invalid": "The page \"{slug}\" cannot be converted to a draft", - "error.page.changeTemplate.invalid": "The template for the page \"{slug}\" cannot be changed", - "error.page.changeTemplate.permission": "You are not allowed to change the template for \"{slug}\"", - "error.page.changeTitle.empty": "The title must not be empty", - "error.page.changeTitle.permission": "You are not allowed to change the title for \"{slug}\"", - "error.page.create.permission": "You are not allowed to create \"{slug}\"", - "error.page.delete": "The page \"{slug}\" cannot be deleted", - "error.page.delete.confirm": "Please enter the page title to confirm", - "error.page.delete.hasChildren": "The page has subpages and cannot be deleted", - "error.page.delete.permission": "You are not allowed to delete \"{slug}\"", - "error.page.draft.duplicate": "A page draft with the URL appendix \"{slug}\" already exists", - "error.page.duplicate": "A page with the URL appendix \"{slug}\" already exists", - "error.page.duplicate.permission": "You are not allowed to duplicate \"{slug}\"", - "error.page.notFound": "The page \"{slug}\" cannot be found", - "error.page.num.invalid": "Please enter a valid sorting number. Numbers must not be negative.", - "error.page.slug.invalid": "Please enter a valid URL appendix", - "error.page.slug.maxlength": "Slug length must be less than \"{length}\" characters", - "error.page.sort.permission": "The page \"{slug}\" cannot be sorted", - "error.page.status.invalid": "Please set a valid page status", - "error.page.undefined": "The page cannot be found", - "error.page.update.permission": "You are not allowed to update \"{slug}\"", - - "error.section.files.max.plural": "You must not add more than {max} files to the \"{section}\" section", - "error.section.files.max.singular": "You must not add more than one file to the \"{section}\" section", - "error.section.files.min.plural": "The \"{section}\" section requires at least {min} files", - "error.section.files.min.singular": "The \"{section}\" section requires at least one file", - - "error.section.pages.max.plural": "You must not add more than {max} pages to the \"{section}\" section", - "error.section.pages.max.singular": "You must not add more than one page to the \"{section}\" section", - "error.section.pages.min.plural": "The \"{section}\" section requires at least {min} pages", - "error.section.pages.min.singular": "The \"{section}\" section requires at least one page", - - "error.section.notLoaded": "The section \"{name}\" could not be loaded", - "error.section.type.invalid": "The section type \"{type}\" is not valid", - - "error.site.changeTitle.empty": "The title must not be empty", - "error.site.changeTitle.permission": "You are not allowed to change the title of the site", - "error.site.update.permission": "You are not allowed to update the site", - - "error.template.default.notFound": "The default template does not exist", - - "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "You are not allowed to change the email for the user \"{name}\"", - "error.user.changeLanguage.permission": "You are not allowed to change the language for the user \"{name}\"", - "error.user.changeName.permission": "You are not allowed to change the name for the user \"{name}\"", - "error.user.changePassword.permission": "You are not allowed to change the password for the user \"{name}\"", - "error.user.changeRole.lastAdmin": "The role for the last admin cannot be changed", - "error.user.changeRole.permission": "You are not allowed to change the role for the user \"{name}\"", - "error.user.changeRole.toAdmin": "You are not allowed to promote someone to the admin role", - "error.user.create.permission": "You are not allowed to create this user", - "error.user.delete": "The user \"{name}\" cannot be deleted", - "error.user.delete.lastAdmin": "The last admin cannot be deleted", - "error.user.delete.lastUser": "The last user cannot be deleted", - "error.user.delete.permission": "You are not allowed to delete the user \"{name}\"", - "error.user.duplicate": "A user with the email address \"{email}\" already exists", - "error.user.email.invalid": "Please enter a valid email address", - "error.user.language.invalid": "Please enter a valid language", - "error.user.notFound": "The user \"{name}\" cannot be found", - "error.user.password.invalid": "Please enter a valid password. Passwords must be at least 8 characters long.", - "error.user.password.notSame": "The passwords do not match", - "error.user.password.undefined": "The user does not have a password", - "error.user.password.wrong": "Wrong password", - "error.user.role.invalid": "Please enter a valid role", - "error.user.undefined": "The user cannot be found", - "error.user.update.permission": "You are not allowed to update the user \"{name}\"", - - "error.validation.accepted": "Please confirm", - "error.validation.alpha": "Please only enter characters between a-z", - "error.validation.alphanum": "Please only enter characters between a-z or numerals 0-9", - "error.validation.between": "Please enter a value between \"{min}\" and \"{max}\"", - "error.validation.boolean": "Please confirm or deny", - "error.validation.contains": "Please enter a value that contains \"{needle}\"", - "error.validation.date": "Please enter a valid date", - "error.validation.date.after": "Please enter a date after {date}", - "error.validation.date.before": "Please enter a date before {date}", - "error.validation.date.between": "Please enter a date between {min} and {max}", - "error.validation.denied": "Please deny", - "error.validation.different": "The value must not be \"{other}\"", - "error.validation.email": "Please enter a valid email address", - "error.validation.endswith": "The value must end with \"{end}\"", - "error.validation.filename": "Please enter a valid filename", - "error.validation.in": "Please enter one of the following: ({in})", - "error.validation.integer": "Please enter a valid integer", - "error.validation.ip": "Please enter a valid IP address", - "error.validation.less": "Please enter a value lower than {max}", - "error.validation.match": "The value does not match the expected pattern", - "error.validation.max": "Please enter a value equal to or lower than {max}", - "error.validation.maxlength": "Please enter a shorter value. (max. {max} characters)", - "error.validation.maxwords": "Please enter no more than {max} word(s)", - "error.validation.min": "Please enter a value equal to or greater than {min}", - "error.validation.minlength": "Please enter a longer value. (min. {min} characters)", - "error.validation.minwords": "Please enter at least {min} word(s)", - "error.validation.more": "Please enter a greater value than {min}", - "error.validation.notcontains": "Please enter a value that does not contain \"{needle}\"", - "error.validation.notin": "Please don't enter any of the following: ({notIn})", - "error.validation.option": "Please select a valid option", - "error.validation.num": "Please enter a valid number", - "error.validation.required": "Please enter something", - "error.validation.same": "Please enter \"{other}\"", - "error.validation.size": "The size of the value must be \"{size}\"", - "error.validation.startswith": "The value must start with \"{start}\"", - "error.validation.time": "Please enter a valid time", - "error.validation.time.after": "Please enter a time after {time}", - "error.validation.time.before": "Please enter a time before {time}", - "error.validation.time.between": "Please enter a time between {min} and {max}", - "error.validation.url": "Please enter a valid URL", - - "expand": "Expand", - "expand.all": "Expand All", - - "field.required": "The field is required", - "field.blocks.changeType": "Change type", - "field.blocks.code.name": "Code", - "field.blocks.code.language": "Language", - "field.blocks.code.placeholder": "Your code …", - "field.blocks.delete.confirm": "Do you really want to delete this block?", - "field.blocks.delete.confirm.all": "Do you really want to delete all blocks?", - "field.blocks.delete.confirm.selected": "Do you really want to delete the selected blocks?", - "field.blocks.empty": "No blocks yet", - "field.blocks.fieldsets.label": "Please select a block type …", - "field.blocks.fieldsets.paste": "Press {{ shortcut }} to paste/import blocks from your clipboard", - "field.blocks.gallery.name": "Gallery", - "field.blocks.gallery.images.empty": "No images yet", - "field.blocks.gallery.images.label": "Images", - "field.blocks.heading.level": "Level", - "field.blocks.heading.name": "Heading", - "field.blocks.heading.text": "Text", - "field.blocks.heading.placeholder": "Heading …", - "field.blocks.image.alt": "Alternative text", - "field.blocks.image.caption": "Caption", - "field.blocks.image.crop": "Crop", - "field.blocks.image.link": "Link", - "field.blocks.image.location": "Location", - "field.blocks.image.name": "Image", - "field.blocks.image.placeholder": "Select an image", - "field.blocks.image.ratio": "Ratio", - "field.blocks.image.url": "Image URL", - "field.blocks.line.name": "Line", - "field.blocks.list.name": "List", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Text", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Quote", - "field.blocks.quote.text.label": "Text", - "field.blocks.quote.text.placeholder": "Quote …", - "field.blocks.quote.citation.label": "Citation", - "field.blocks.quote.citation.placeholder": "by …", - "field.blocks.text.name": "Text", - "field.blocks.text.placeholder": "Text …", - "field.blocks.video.caption": "Caption", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Enter a video URL", - "field.blocks.video.url.label": "Video-URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "No files selected yet", - - "field.layout.delete": "Delete layout", - "field.layout.delete.confirm": "Do you really want to delete this layout?", - "field.layout.empty": "No rows yet", - "field.layout.select": "Select a layout", - - "field.pages.empty": "No pages selected yet", - "field.structure.delete.confirm": "Do you really want to delete this row?", - "field.structure.empty": "No entries yet", - "field.users.empty": "No users selected yet", - - "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Do you really want to delete
{filename}?", - "file.sort": "Change position", - - "files": "Files", - "files.empty": "No files yet", - - "hide": "Hide", - "hour": "Hour", - "import": "Import", - "info": "Info", - "insert": "Insert", - "insert.after": "Insert after", - "insert.before": "Insert before", - "install": "Install", - - "installation": "Installation", - "installation.completed": "The panel has been installed", - "installation.disabled": "The panel installer is disabled on public servers by default. Please run the installer on a local machine or enable it with the panel.install option.", - "installation.issues.accounts": "The /site/accounts folder does not exist or is not writable", - "installation.issues.content": "The /content folder does not exist or is not writable", - "installation.issues.curl": "The CURL extension is required", - "installation.issues.headline": "The panel cannot be installed", - "installation.issues.mbstring": "The MB String extension is required", - "installation.issues.media": "The /media folder does not exist or is not writable", - "installation.issues.php": "Make sure to use PHP 7+", - "installation.issues.server": "Kirby requires Apache, Nginx or Caddy", - "installation.issues.sessions": "The /site/sessions folder does not exist or is not writable", - - "language": "Language", - "language.code": "Code", - "language.convert": "Make default", - "language.convert.confirm": "

Do you really want to convert {name} to the default language? This cannot be undone.

If {name} has untranslated content, there will no longer be a valid fallback and parts of your site might be empty.

", - "language.create": "Add a new language", - "language.delete.confirm": "Do you really want to delete the language {name} including all translations? This cannot be undone!", - "language.deleted": "The language has been deleted", - "language.direction": "Reading direction", - "language.direction.ltr": "Left to right", - "language.direction.rtl": "Right to left", - "language.locale": "PHP locale string", - "language.locale.warning": "You are using a custom locale set up. Please modify it in the language file in /site/languages", - "language.name": "Name", - "language.updated": "The language has been updated", - - "languages": "Languages", - "languages.default": "Default language", - "languages.empty": "There are no languages yet", - "languages.secondary": "Secondary languages", - "languages.secondary.empty": "There are no secondary languages yet", - - "license": "License", - "license.buy": "Buy a license", - "license.register": "Register", - "license.manage": "Manage your licenses", - "license.register.help": "You received your license code after the purchase via email. Please copy and paste it to register.", - "license.register.label": "Please enter your license code", - "license.register.success": "Thank you for supporting Kirby", - "license.unregistered": "This is an unregistered demo of Kirby", - "license.unregistered.label": "Unregistered", - - "link": "Link", - "link.text": "Link text", - - "loading": "Loading", - - "lock.unsaved": "Unsaved changes", - "lock.unsaved.empty": "There are no more unsaved changes", - "lock.isLocked": "Unsaved changes by {email}", - "lock.file.isLocked": "The file is currently being edited by {email} and cannot be changed.", - "lock.page.isLocked": "The page is currently being edited by {email} and cannot be changed.", - "lock.unlock": "Unlock", - "lock.isUnlocked": "Your unsaved changes have been overwritten by another user. You can download your changes to merge them manually.", - - "login": "Log in", - "login.code.label.login": "Login code", - "login.code.label.password-reset": "Password reset code", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "If your email address is registered, the requested code was sent via email.", - "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.login.subject": "Your login code", - "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.password-reset.subject": "Your password reset code", - "login.remember": "Keep me logged in", - "login.reset": "Reset password", - "login.toggleText.code.email": "Login via email", - "login.toggleText.code.email-password": "Login with password", - "login.toggleText.password-reset.email": "Forgot your password?", - "login.toggleText.password-reset.email-password": "← Back to login", - - "logout": "Logout", - - "menu": "Menu", - "meridiem": "AM/PM", - "mime": "Media Type", - "minutes": "Minutes", - - "month": "Month", - "months.april": "April", - "months.august": "August", - "months.december": "December", - "months.february": "Feburary", - "months.january": "January", - "months.july": "July", - "months.june": "June", - "months.march": "March", - "months.may": "May", - "months.november": "November", - "months.october": "October", - "months.september": "September", - - "more": "More", - "name": "Name", - "next": "Next", - "no": "no", - "off": "off", - "on": "on", - "open": "Open", - "open.newWindow": "Open in new window", - "options": "Options", - "options.none": "No options", - - "orientation": "Orientation", - "orientation.landscape": "Landscape", - "orientation.portrait": "Portrait", - "orientation.square": "Square", - - "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Change URL", - "page.changeSlug.fromTitle": "Create from title", - "page.changeStatus": "Change status", - "page.changeStatus.position": "Please select a position", - "page.changeStatus.select": "Select a new status", - "page.changeTemplate": "Change template", - "page.delete.confirm": "Do you really want to delete {title}?", - "page.delete.confirm.subpages": "This page has subpages.
All subpages will be deleted as well.", - "page.delete.confirm.title": "Enter the page title to confirm", - "page.draft.create": "Create draft", - "page.duplicate.appendix": "Copy", - "page.duplicate.files": "Copy files", - "page.duplicate.pages": "Copy pages", - "page.sort": "Change position", - "page.status": "Status", - "page.status.draft": "Draft", - "page.status.draft.description": "The page is in draft mode and only visible for logged in editors or via secret link", - "page.status.listed": "Public", - "page.status.listed.description": "The page is public for anyone", - "page.status.unlisted": "Unlisted", - "page.status.unlisted.description": "The page is only accessible via URL", - - "pages": "Pages", - "pages.empty": "No pages yet", - "pages.status.draft": "Drafts", - "pages.status.listed": "Published", - "pages.status.unlisted": "Unlisted", - - "pagination.page": "Page", - - "password": "Password", - "paste": "Paste", - "paste.after": "Paste after", - "pixel": "Pixel", - "plugins": "Plugins", - "prev": "Previous", - "preview": "Preview", - "remove": "Remove", - "rename": "Rename", - "replace": "Replace", - "retry": "Try again", - "revert": "Revert", - "revert.confirm": "Do you really want to delete all unsaved changes?", - - "role": "Role", - "role.admin.description": "The admin has all rights", - "role.admin.title": "Admin", - "role.all": "All", - "role.empty": "There are no users with this role", - "role.description.placeholder": "No description", - "role.nobody.description": "This is a fallback role without any permissions", - "role.nobody.title": "Nobody", - - "save": "Save", - "search": "Search", - "search.min": "Enter {min} characters to search", - "search.all": "Show all", - "search.results.none": "No results", - - "section.required": "The section is required", - - "security": "Security", - "select": "Select", - "server": "Server", - "settings": "Settings", - "show": "Show", - "site.blueprint": "The site has no blueprint yet. You can define the setup in /site/blueprints/site.yml", - "size": "Size", - "slug": "URL appendix", - "sort": "Sort", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Title", - "template": "Template", - "today": "Today", - - "toolbar.button.code": "Code", - "toolbar.button.bold": "Bold", - "toolbar.button.email": "Email", - "toolbar.button.headings": "Headings", - "toolbar.button.heading.1": "Heading 1", - "toolbar.button.heading.2": "Heading 2", - "toolbar.button.heading.3": "Heading 3", - "toolbar.button.heading.4": "Heading 4", - "toolbar.button.heading.5": "Heading 5", - "toolbar.button.heading.6": "Heading 6", - "toolbar.button.italic": "Italic", - "toolbar.button.file": "File", - "toolbar.button.file.select": "Select a file", - "toolbar.button.file.upload": "Upload a file", - "toolbar.button.link": "Link", - "toolbar.button.paragraph": "Paragraph", - "toolbar.button.strike": "Strike-through", - "toolbar.button.ol": "Ordered list", - "toolbar.button.underline": "Underline", - "toolbar.button.ul": "Bullet list", - - "translation.author": "Kirby Team", - "translation.direction": "ltr", - "translation.name": "English", - "translation.locale": "en_US", - - "upload": "Upload", - "upload.error.cantMove": "The uploaded file could not be moved", - "upload.error.cantWrite": "Failed to write file to disk", - "upload.error.default": "The file could not be uploaded", - "upload.error.extension": "File upload stopped by extension", - "upload.error.formSize": "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the form", - "upload.error.iniPostSize": "The uploaded file exceeds the post_max_size directive in php.ini", - "upload.error.iniSize": "The uploaded file exceeds the upload_max_filesize directive in php.ini", - "upload.error.noFile": "No file was uploaded", - "upload.error.noFiles": "No files were uploaded", - "upload.error.partial": "The uploaded file was only partially uploaded", - "upload.error.tmpDir": "Missing a temporary folder", - "upload.errors": "Error", - "upload.progress": "Uploading…", - - "url": "Url", - "url.placeholder": "https://example.com", - - "user": "User", - "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Change email", - "user.changeLanguage": "Change language", - "user.changeName": "Rename this user", - "user.changePassword": "Change password", - "user.changePassword.new": "New password", - "user.changePassword.new.confirm": "Confirm the new password…", - "user.changeRole": "Change role", - "user.changeRole.select": "Select a new role", - "user.create": "Add a new user", - "user.delete": "Delete this user", - "user.delete.confirm": "Do you really want to delete
{email}?", - - "users": "Users", - - "version": "Version", - - "view.account": "Your account", - "view.installation": "Installation", - "view.languages": "Languages", - "view.resetPassword": "Reset password", - "view.site": "Site", - "view.system": "System", - "view.users": "Users", - - "welcome": "Welcome", - "year": "Year", - "yes": "yes" + "account.changeName": "Change your name", + "account.delete": "Delete your account", + "account.delete.confirm": "Do you really want to delete your account? You will be logged out immediately. Your account cannot be recovered.", + + "add": "Add", + "author": "Author", + "avatar": "Profile picture", + "back": "Back", + "cancel": "Cancel", + "change": "Change", + "close": "Close", + "confirm": "Ok", + "collapse": "Collapse", + "collapse.all": "Collapse All", + "copy": "Copy", + "copy.all": "Copy all", + "create": "Create", + + "date": "Date", + "date.select": "Select a date", + + "day": "Day", + "days.fri": "Fri", + "days.mon": "Mon", + "days.sat": "Sat", + "days.sun": "Sun", + "days.thu": "Thu", + "days.tue": "Tue", + "days.wed": "Wed", + + "debugging": "Debugging", + + "delete": "Delete", + "delete.all": "Delete all", + + "dialog.files.empty": "No files to select", + "dialog.pages.empty": "No pages to select", + "dialog.users.empty": "No users to select", + + "dimensions": "Dimensions", + "disabled": "Disabled", + "discard": "Discard", + "download": "Download", + "duplicate": "Duplicate", + + "edit": "Edit", + + "email": "Email", + "email.placeholder": "mail@example.com", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Environment", + + "error.access.code": "Invalid code", + "error.access.login": "Invalid login", + "error.access.panel": "You are not allowed to access the panel", + "error.access.view": "You are not allowed to access this part of the panel", + + "error.avatar.create.fail": "The profile picture could not be uploaded", + "error.avatar.delete.fail": "The profile picture could not be deleted", + "error.avatar.dimensions.invalid": "Please keep the width and height of the profile picture under 3000 pixels", + "error.avatar.mime.forbidden": "The profile picture must be JPEG or PNG files", + + "error.blueprint.notFound": "The blueprint \"{name}\" could not be loaded", + + "error.blocks.max.plural": "You must not add more than {max} blocks", + "error.blocks.max.singular": "You must not add more than one block", + "error.blocks.min.plural": "You must add at least {min} blocks", + "error.blocks.min.singular": "You must add at least one block", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "The email preset \"{name}\" cannot be found", + + "error.field.converter.invalid": "Invalid converter \"{converter}\"", + + "error.file.changeName.empty": "The name must not be empty", + "error.file.changeName.permission": "You are not allowed to change the name of \"{filename}\"", + "error.file.duplicate": "A file with the name \"{filename}\" already exists", + "error.file.extension.forbidden": "The extension \"{extension}\" is not allowed", + "error.file.extension.invalid": "Invalid extension: {extension}", + "error.file.extension.missing": "The extensions for \"{filename}\" is missing", + "error.file.maxheight": "The height of the image must not exceed {height} pixels", + "error.file.maxsize": "The file is too large", + "error.file.maxwidth": "The width of the image must not exceed {width} pixels", + "error.file.mime.differs": "The uploaded file must be of the same mime type \"{mime}\"", + "error.file.mime.forbidden": "The media type \"{mime}\" is not allowed", + "error.file.mime.invalid": "Invalid mime type: {mime}", + "error.file.mime.missing": "The media type for \"{filename}\" cannot be detected", + "error.file.minheight": "The height of the image must be at least {height} pixels", + "error.file.minsize": "The file is too small", + "error.file.minwidth": "The width of the image must be at least {width} pixels", + "error.file.name.missing": "The filename must not be empty", + "error.file.notFound": "The file \"{filename}\" cannot be found", + "error.file.orientation": "The orientation of the image must be \"{orientation}\"", + "error.file.type.forbidden": "You are not allowed to upload {type} files", + "error.file.type.invalid": "Invalid file type: {type}", + "error.file.undefined": "The file cannot be found", + + "error.form.incomplete": "Please fix all form errors…", + "error.form.notSaved": "The form could not be saved", + + "error.language.code": "Please enter a valid code for the language", + "error.language.duplicate": "The language already exists", + "error.language.name": "Please enter a valid name for the language", + "error.language.notFound": "The language could not be found", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "There's an error in layout {index} settings", + + "error.license.format": "Please enter a valid license key", + "error.license.email": "Please enter a valid email address", + "error.license.verification": "The license could not be verified", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "The Panel is currently offline", + + "error.page.changeSlug.permission": "You are not allowed to change the URL appendix for \"{slug}\"", + "error.page.changeStatus.incomplete": "The page has errors and cannot be published", + "error.page.changeStatus.permission": "The status for this page cannot be changed", + "error.page.changeStatus.toDraft.invalid": "The page \"{slug}\" cannot be converted to a draft", + "error.page.changeTemplate.invalid": "The template for the page \"{slug}\" cannot be changed", + "error.page.changeTemplate.permission": "You are not allowed to change the template for \"{slug}\"", + "error.page.changeTitle.empty": "The title must not be empty", + "error.page.changeTitle.permission": "You are not allowed to change the title for \"{slug}\"", + "error.page.create.permission": "You are not allowed to create \"{slug}\"", + "error.page.delete": "The page \"{slug}\" cannot be deleted", + "error.page.delete.confirm": "Please enter the page title to confirm", + "error.page.delete.hasChildren": "The page has subpages and cannot be deleted", + "error.page.delete.permission": "You are not allowed to delete \"{slug}\"", + "error.page.draft.duplicate": "A page draft with the URL appendix \"{slug}\" already exists", + "error.page.duplicate": "A page with the URL appendix \"{slug}\" already exists", + "error.page.duplicate.permission": "You are not allowed to duplicate \"{slug}\"", + "error.page.notFound": "The page \"{slug}\" cannot be found", + "error.page.num.invalid": "Please enter a valid sorting number. Numbers must not be negative.", + "error.page.slug.invalid": "Please enter a valid URL appendix", + "error.page.slug.maxlength": "Slug length must be less than \"{length}\" characters", + "error.page.sort.permission": "The page \"{slug}\" cannot be sorted", + "error.page.status.invalid": "Please set a valid page status", + "error.page.undefined": "The page cannot be found", + "error.page.update.permission": "You are not allowed to update \"{slug}\"", + + "error.section.files.max.plural": "You must not add more than {max} files to the \"{section}\" section", + "error.section.files.max.singular": "You must not add more than one file to the \"{section}\" section", + "error.section.files.min.plural": "The \"{section}\" section requires at least {min} files", + "error.section.files.min.singular": "The \"{section}\" section requires at least one file", + + "error.section.pages.max.plural": "You must not add more than {max} pages to the \"{section}\" section", + "error.section.pages.max.singular": "You must not add more than one page to the \"{section}\" section", + "error.section.pages.min.plural": "The \"{section}\" section requires at least {min} pages", + "error.section.pages.min.singular": "The \"{section}\" section requires at least one page", + + "error.section.notLoaded": "The section \"{name}\" could not be loaded", + "error.section.type.invalid": "The section type \"{type}\" is not valid", + + "error.site.changeTitle.empty": "The title must not be empty", + "error.site.changeTitle.permission": "You are not allowed to change the title of the site", + "error.site.update.permission": "You are not allowed to update the site", + + "error.template.default.notFound": "The default template does not exist", + + "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "You are not allowed to change the email for the user \"{name}\"", + "error.user.changeLanguage.permission": "You are not allowed to change the language for the user \"{name}\"", + "error.user.changeName.permission": "You are not allowed to change the name for the user \"{name}\"", + "error.user.changePassword.permission": "You are not allowed to change the password for the user \"{name}\"", + "error.user.changeRole.lastAdmin": "The role for the last admin cannot be changed", + "error.user.changeRole.permission": "You are not allowed to change the role for the user \"{name}\"", + "error.user.changeRole.toAdmin": "You are not allowed to promote someone to the admin role", + "error.user.create.permission": "You are not allowed to create this user", + "error.user.delete": "The user \"{name}\" cannot be deleted", + "error.user.delete.lastAdmin": "The last admin cannot be deleted", + "error.user.delete.lastUser": "The last user cannot be deleted", + "error.user.delete.permission": "You are not allowed to delete the user \"{name}\"", + "error.user.duplicate": "A user with the email address \"{email}\" already exists", + "error.user.email.invalid": "Please enter a valid email address", + "error.user.language.invalid": "Please enter a valid language", + "error.user.notFound": "The user \"{name}\" cannot be found", + "error.user.password.invalid": "Please enter a valid password. Passwords must be at least 8 characters long.", + "error.user.password.notSame": "The passwords do not match", + "error.user.password.undefined": "The user does not have a password", + "error.user.password.wrong": "Wrong password", + "error.user.role.invalid": "Please enter a valid role", + "error.user.undefined": "The user cannot be found", + "error.user.update.permission": "You are not allowed to update the user \"{name}\"", + + "error.validation.accepted": "Please confirm", + "error.validation.alpha": "Please only enter characters between a-z", + "error.validation.alphanum": "Please only enter characters between a-z or numerals 0-9", + "error.validation.between": "Please enter a value between \"{min}\" and \"{max}\"", + "error.validation.boolean": "Please confirm or deny", + "error.validation.contains": "Please enter a value that contains \"{needle}\"", + "error.validation.date": "Please enter a valid date", + "error.validation.date.after": "Please enter a date after {date}", + "error.validation.date.before": "Please enter a date before {date}", + "error.validation.date.between": "Please enter a date between {min} and {max}", + "error.validation.denied": "Please deny", + "error.validation.different": "The value must not be \"{other}\"", + "error.validation.email": "Please enter a valid email address", + "error.validation.endswith": "The value must end with \"{end}\"", + "error.validation.filename": "Please enter a valid filename", + "error.validation.in": "Please enter one of the following: ({in})", + "error.validation.integer": "Please enter a valid integer", + "error.validation.ip": "Please enter a valid IP address", + "error.validation.less": "Please enter a value lower than {max}", + "error.validation.match": "The value does not match the expected pattern", + "error.validation.max": "Please enter a value equal to or lower than {max}", + "error.validation.maxlength": "Please enter a shorter value. (max. {max} characters)", + "error.validation.maxwords": "Please enter no more than {max} word(s)", + "error.validation.min": "Please enter a value equal to or greater than {min}", + "error.validation.minlength": "Please enter a longer value. (min. {min} characters)", + "error.validation.minwords": "Please enter at least {min} word(s)", + "error.validation.more": "Please enter a greater value than {min}", + "error.validation.notcontains": "Please enter a value that does not contain \"{needle}\"", + "error.validation.notin": "Please don't enter any of the following: ({notIn})", + "error.validation.option": "Please select a valid option", + "error.validation.num": "Please enter a valid number", + "error.validation.required": "Please enter something", + "error.validation.same": "Please enter \"{other}\"", + "error.validation.size": "The size of the value must be \"{size}\"", + "error.validation.startswith": "The value must start with \"{start}\"", + "error.validation.time": "Please enter a valid time", + "error.validation.time.after": "Please enter a time after {time}", + "error.validation.time.before": "Please enter a time before {time}", + "error.validation.time.between": "Please enter a time between {min} and {max}", + "error.validation.url": "Please enter a valid URL", + + "expand": "Expand", + "expand.all": "Expand All", + + "field.required": "The field is required", + "field.blocks.changeType": "Change type", + "field.blocks.code.name": "Code", + "field.blocks.code.language": "Language", + "field.blocks.code.placeholder": "Your code …", + "field.blocks.delete.confirm": "Do you really want to delete this block?", + "field.blocks.delete.confirm.all": "Do you really want to delete all blocks?", + "field.blocks.delete.confirm.selected": "Do you really want to delete the selected blocks?", + "field.blocks.empty": "No blocks yet", + "field.blocks.fieldsets.label": "Please select a block type …", + "field.blocks.fieldsets.paste": "Press {{ shortcut }} to paste/import blocks from your clipboard", + "field.blocks.gallery.name": "Gallery", + "field.blocks.gallery.images.empty": "No images yet", + "field.blocks.gallery.images.label": "Images", + "field.blocks.heading.level": "Level", + "field.blocks.heading.name": "Heading", + "field.blocks.heading.text": "Text", + "field.blocks.heading.placeholder": "Heading …", + "field.blocks.image.alt": "Alternative text", + "field.blocks.image.caption": "Caption", + "field.blocks.image.crop": "Crop", + "field.blocks.image.link": "Link", + "field.blocks.image.location": "Location", + "field.blocks.image.name": "Image", + "field.blocks.image.placeholder": "Select an image", + "field.blocks.image.ratio": "Ratio", + "field.blocks.image.url": "Image URL", + "field.blocks.line.name": "Line", + "field.blocks.list.name": "List", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Text", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Quote", + "field.blocks.quote.text.label": "Text", + "field.blocks.quote.text.placeholder": "Quote …", + "field.blocks.quote.citation.label": "Citation", + "field.blocks.quote.citation.placeholder": "by …", + "field.blocks.text.name": "Text", + "field.blocks.text.placeholder": "Text …", + "field.blocks.video.caption": "Caption", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Enter a video URL", + "field.blocks.video.url.label": "Video-URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "No files selected yet", + + "field.layout.delete": "Delete layout", + "field.layout.delete.confirm": "Do you really want to delete this layout?", + "field.layout.empty": "No rows yet", + "field.layout.select": "Select a layout", + + "field.object.empty": "No information yet", + + "field.pages.empty": "No pages selected yet", + + "field.structure.delete.confirm": "Do you really want to delete this row?", + "field.structure.empty": "No entries yet", + + "field.users.empty": "No users selected yet", + + "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Do you really want to delete
{filename}?", + "file.sort": "Change position", + + "files": "Files", + "files.empty": "No files yet", + + "hide": "Hide", + "hour": "Hour", + "import": "Import", + "info": "Info", + "insert": "Insert", + "insert.after": "Insert after", + "insert.before": "Insert before", + "install": "Install", + + "installation": "Installation", + "installation.completed": "The panel has been installed", + "installation.disabled": "The panel installer is disabled on public servers by default. Please run the installer on a local machine or enable it with the panel.install option.", + "installation.issues.accounts": "The /site/accounts folder does not exist or is not writable", + "installation.issues.content": "The /content folder does not exist or is not writable", + "installation.issues.curl": "The CURL extension is required", + "installation.issues.headline": "The panel cannot be installed", + "installation.issues.mbstring": "The MB String extension is required", + "installation.issues.media": "The /media folder does not exist or is not writable", + "installation.issues.php": "Make sure to use PHP 7+", + "installation.issues.server": "Kirby requires Apache, Nginx or Caddy", + "installation.issues.sessions": "The /site/sessions folder does not exist or is not writable", + + "language": "Language", + "language.code": "Code", + "language.convert": "Make default", + "language.convert.confirm": "

Do you really want to convert {name} to the default language? This cannot be undone.

If {name} has untranslated content, there will no longer be a valid fallback and parts of your site might be empty.

", + "language.create": "Add a new language", + "language.delete.confirm": "Do you really want to delete the language {name} including all translations? This cannot be undone!", + "language.deleted": "The language has been deleted", + "language.direction": "Reading direction", + "language.direction.ltr": "Left to right", + "language.direction.rtl": "Right to left", + "language.locale": "PHP locale string", + "language.locale.warning": "You are using a custom locale set up. Please modify it in the language file in /site/languages", + "language.name": "Name", + "language.updated": "The language has been updated", + + "languages": "Languages", + "languages.default": "Default language", + "languages.empty": "There are no languages yet", + "languages.secondary": "Secondary languages", + "languages.secondary.empty": "There are no secondary languages yet", + + "license": "License", + "license.buy": "Buy a license", + "license.register": "Register", + "license.manage": "Manage your licenses", + "license.register.help": "You received your license code after the purchase via email. Please copy and paste it to register.", + "license.register.label": "Please enter your license code", + "license.register.success": "Thank you for supporting Kirby", + "license.unregistered": "This is an unregistered demo of Kirby", + "license.unregistered.label": "Unregistered", + + "link": "Link", + "link.text": "Link text", + + "loading": "Loading", + + "lock.unsaved": "Unsaved changes", + "lock.unsaved.empty": "There are no more unsaved changes", + "lock.isLocked": "Unsaved changes by {email}", + "lock.file.isLocked": "The file is currently being edited by {email} and cannot be changed.", + "lock.page.isLocked": "The page is currently being edited by {email} and cannot be changed.", + "lock.unlock": "Unlock", + "lock.isUnlocked": "Your unsaved changes have been overwritten by another user. You can download your changes to merge them manually.", + + "login": "Log in", + "login.code.label.login": "Login code", + "login.code.label.password-reset": "Password reset code", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "If your email address is registered, the requested code was sent via email.", + "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.login.subject": "Your login code", + "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.password-reset.subject": "Your password reset code", + "login.remember": "Keep me logged in", + "login.reset": "Reset password", + "login.toggleText.code.email": "Login via email", + "login.toggleText.code.email-password": "Login with password", + "login.toggleText.password-reset.email": "Forgot your password?", + "login.toggleText.password-reset.email-password": "← Back to login", + + "logout": "Logout", + + "menu": "Menu", + "meridiem": "AM/PM", + "mime": "Media Type", + "minutes": "Minutes", + + "month": "Month", + "months.april": "April", + "months.august": "August", + "months.december": "December", + "months.february": "Feburary", + "months.january": "January", + "months.july": "July", + "months.june": "June", + "months.march": "March", + "months.may": "May", + "months.november": "November", + "months.october": "October", + "months.september": "September", + + "more": "More", + "name": "Name", + "next": "Next", + "no": "no", + "off": "off", + "on": "on", + "open": "Open", + "open.newWindow": "Open in new window", + "options": "Options", + "options.none": "No options", + + "orientation": "Orientation", + "orientation.landscape": "Landscape", + "orientation.portrait": "Portrait", + "orientation.square": "Square", + + "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Change URL", + "page.changeSlug.fromTitle": "Create from title", + "page.changeStatus": "Change status", + "page.changeStatus.position": "Please select a position", + "page.changeStatus.select": "Select a new status", + "page.changeTemplate": "Change template", + "page.delete.confirm": "Do you really want to delete {title}?", + "page.delete.confirm.subpages": "This page has subpages.
All subpages will be deleted as well.", + "page.delete.confirm.title": "Enter the page title to confirm", + "page.draft.create": "Create draft", + "page.duplicate.appendix": "Copy", + "page.duplicate.files": "Copy files", + "page.duplicate.pages": "Copy pages", + "page.sort": "Change position", + "page.status": "Status", + "page.status.draft": "Draft", + "page.status.draft.description": "The page is in draft mode and only visible for logged in editors or via secret link", + "page.status.listed": "Public", + "page.status.listed.description": "The page is public for anyone", + "page.status.unlisted": "Unlisted", + "page.status.unlisted.description": "The page is only accessible via URL", + + "pages": "Pages", + "pages.empty": "No pages yet", + "pages.status.draft": "Drafts", + "pages.status.listed": "Published", + "pages.status.unlisted": "Unlisted", + + "pagination.page": "Page", + + "password": "Password", + "paste": "Paste", + "paste.after": "Paste after", + "pixel": "Pixel", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "Previous", + "preview": "Preview", + "remove": "Remove", + "rename": "Rename", + "replace": "Replace", + "retry": "Try again", + "revert": "Revert", + "revert.confirm": "Do you really want to delete all unsaved changes?", + + "role": "Role", + "role.admin.description": "The admin has all rights", + "role.admin.title": "Admin", + "role.all": "All", + "role.empty": "There are no users with this role", + "role.description.placeholder": "No description", + "role.nobody.description": "This is a fallback role without any permissions", + "role.nobody.title": "Nobody", + + "save": "Save", + "search": "Search", + "search.min": "Enter {min} characters to search", + "search.all": "Show all", + "search.results.none": "No results", + + "section.required": "The section is required", + + "security": "Security", + "select": "Select", + "server": "Server", + "settings": "Settings", + "show": "Show", + "site.blueprint": "The site has no blueprint yet. You can define the setup in /site/blueprints/site.yml", + "size": "Size", + "slug": "URL appendix", + "sort": "Sort", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Title", + "template": "Template", + "today": "Today", + + "toolbar.button.code": "Code", + "toolbar.button.bold": "Bold", + "toolbar.button.email": "Email", + "toolbar.button.headings": "Headings", + "toolbar.button.heading.1": "Heading 1", + "toolbar.button.heading.2": "Heading 2", + "toolbar.button.heading.3": "Heading 3", + "toolbar.button.heading.4": "Heading 4", + "toolbar.button.heading.5": "Heading 5", + "toolbar.button.heading.6": "Heading 6", + "toolbar.button.italic": "Italic", + "toolbar.button.file": "File", + "toolbar.button.file.select": "Select a file", + "toolbar.button.file.upload": "Upload a file", + "toolbar.button.link": "Link", + "toolbar.button.paragraph": "Paragraph", + "toolbar.button.strike": "Strike-through", + "toolbar.button.ol": "Ordered list", + "toolbar.button.underline": "Underline", + "toolbar.button.ul": "Bullet list", + + "translation.author": "Kirby Team", + "translation.direction": "ltr", + "translation.name": "English", + "translation.locale": "en_US", + + "upload": "Upload", + "upload.error.cantMove": "The uploaded file could not be moved", + "upload.error.cantWrite": "Failed to write file to disk", + "upload.error.default": "The file could not be uploaded", + "upload.error.extension": "File upload stopped by extension", + "upload.error.formSize": "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the form", + "upload.error.iniPostSize": "The uploaded file exceeds the post_max_size directive in php.ini", + "upload.error.iniSize": "The uploaded file exceeds the upload_max_filesize directive in php.ini", + "upload.error.noFile": "No file was uploaded", + "upload.error.noFiles": "No files were uploaded", + "upload.error.partial": "The uploaded file was only partially uploaded", + "upload.error.tmpDir": "Missing a temporary folder", + "upload.errors": "Error", + "upload.progress": "Uploading…", + + "url": "Url", + "url.placeholder": "https://example.com", + + "user": "User", + "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Change email", + "user.changeLanguage": "Change language", + "user.changeName": "Rename this user", + "user.changePassword": "Change password", + "user.changePassword.new": "New password", + "user.changePassword.new.confirm": "Confirm the new password…", + "user.changeRole": "Change role", + "user.changeRole.select": "Select a new role", + "user.create": "Add a new user", + "user.delete": "Delete this user", + "user.delete.confirm": "Do you really want to delete
{email}?", + + "users": "Users", + + "version": "Version", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "Your account", + "view.installation": "Installation", + "view.languages": "Languages", + "view.resetPassword": "Reset password", + "view.site": "Site", + "view.system": "System", + "view.users": "Users", + + "welcome": "Welcome", + "year": "Year", + "yes": "yes" } diff --git a/kirby/i18n/translations/eo.json b/kirby/i18n/translations/eo.json index f7bb72f..1ada41f 100644 --- a/kirby/i18n/translations/eo.json +++ b/kirby/i18n/translations/eo.json @@ -1,573 +1,596 @@ { - "account.changeName": "Ŝanĝi vian nomon", - "account.delete": "Forigi vian konton", - "account.delete.confirm": "Ĉu vi certe deziras forigi vian konton? Vi estos tuj elsalutita. Ne eblos malforigi vian konton.", - - "add": "Aldoni", - "author": "Aŭtoro", - "avatar": "Profilbildo", - "back": "Reen", - "cancel": "Nuligi", - "change": "Ŝanĝi", - "close": "Fermi", - "confirm": "Bone", - "collapse": "Fermi", - "collapse.all": "Fermi ĉiujn", - "copy": "Kopii", - "copy.all": "Kopii ĉiujn", - "create": "Krei", - - "date": "Dato", - "date.select": "Elekti daton", - - "day": "Tago", - "days.fri": "Ven", - "days.mon": "Lun", - "days.sat": "Sab", - "days.sun": "Dim", - "days.thu": "Ĵaŭ", - "days.tue": "Mar", - "days.wed": "Mer", - - "debugging": "Sencimigado", - - "delete": "Forigi", - "delete.all": "Forigi ĉiujn", - - "dialog.files.empty": "Neniu dosiero por elekti", - "dialog.pages.empty": "Neniu paĝo por elekti", - "dialog.users.empty": "Neniu uzanto por elekti", - - "dimensions": "Dimensioj", - "disabled": "Malebligita", - "discard": "Forĵeti", - "download": "Elŝuti", - "duplicate": "Duobligi", - - "edit": "Modifi", - - "email": "Retpoŝto", - "email.placeholder": "retpoŝto@ekzemplo.com", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Medio", - - "error.access.code": "Nevalida kodo", - "error.access.login": "Nevalida ensaluto", - "error.access.panel": "Vi ne rajtas eniri la administran panelon", - "error.access.view": "Vi ne rajtas eniri ĉi tiun areon de la panelo", - - "error.avatar.create.fail": "La profilbildo ne povis esti alŝutita", - "error.avatar.delete.fail": "La profilbildo ne povis esti forigita", - "error.avatar.dimensions.invalid": "Bonvolu certigi ke la profilbildo ne estas pli ol 3000 bilderojn larĝa kaj alta", - "error.avatar.mime.forbidden": "La profilbildo devas esti dosiero en dosierformo aŭ JPEG aŭ PNG", - - "error.blueprint.notFound": "La plano \"{name}\" ne povis esti ŝargita", - - "error.blocks.max.plural": "Oni devas ne aldoni pli ol {max} blokoj", - "error.blocks.max.singular": "Vi devas ne aldoni pli ol unu bloko", - "error.blocks.min.plural": "Oni devas aldoni almenaŭ {min} blokojn", - "error.blocks.min.singular": "Oni devas aldoni almenaŭ unu blokon", - "error.blocks.validation": "Estas eraro en bloko {index}", - - "error.email.preset.notFound": "La retpoŝta antaŭagordo \"{name}\" ne estas trovebla", - - "error.field.converter.invalid": "Nevalida konvertilo \"{converter}\"", - - "error.file.changeName.empty": "La nomo ne rajtas esti malplena", - "error.file.changeName.permission": "Vi ne rajtas ŝanĝi la nomon de \"{filename}\"", - "error.file.duplicate": "Jam ekzistas dosiero nomita \"{filename}\"", - "error.file.extension.forbidden": "La dosiersufikso \"{extension}\" ne estas permesita", - "error.file.extension.invalid": "Nevalida dosiersufikso: {extension}", - "error.file.extension.missing": "Mankas la dosiersufiksoj por \"{filename}\"", - "error.file.maxheight": "La bildo ne povas esti pli ol {height} bilderojn alta ", - "error.file.maxsize": "La dosiero estas tro granda", - "error.file.maxwidth": "La bildo ne povas esti pli oll {width} bilderojn larĝa", - "error.file.mime.differs": "La alŝutata dosiero devas havi la saman MIME-tipon \"{mime}\"", - "error.file.mime.forbidden": "La MIME-tipo \"{mime}\" ne povas esti uzata ĉi tie", - "error.file.mime.invalid": "Nevalida MIME-tipo: {mime}", - "error.file.mime.missing": "La MIME-tipo for \"{filename}\" ne estas detektebla", - "error.file.minheight": "La bildo devas esti almenaŭ {height} bilderojn alta", - "error.file.minsize": "La dosiero estas tro malgranda", - "error.file.minwidth": "La bildo devas esti almenaŭ {width} bilderojn larĝa", - "error.file.name.missing": "La dosiernomo ne rajtas esti malplena", - "error.file.notFound": "La dosiero \"{filename}\" ne troveblas", - "error.file.orientation": "La orientiĝo de la bildo devas esti \"{orientation}\"", - "error.file.type.forbidden": "Vi ne rajtas alŝuti dosiertipon {type}", - "error.file.type.invalid": "Nevalida dosiertipo: {type}", - "error.file.undefined": "La dosiero ne troveblas", - - "error.form.incomplete": "Bonvolu korekti ĉiujn erarojn en formularo...", - "error.form.notSaved": "Ne eblis konservi la formularon", - - "error.language.code": "Bonvolu entajpi validan kodon por la lingvo", - "error.language.duplicate": "La lingvo jam ekzistas", - "error.language.name": "Bonvolu entajpi validan nomon por la lingvo", - "error.language.notFound": "La lingvo ne troveblas", - - "error.layout.validation.block": "Estas eraro en bloko {blockIndex}, en blokaranĝo {layoutIndex}", - "error.layout.validation.settings": "Estas eraro en la agordoj de blokaranĝo {index}", - - "error.license.format": "Bonvolu entajpi validan kodon de permisilo", - "error.license.email": "Bonvolu entajpi validan retpoŝtadreson", - "error.license.verification": "Ne eblis kontroli la permisilon", - - "error.offline": "La panelo estas ĉi-momente nekonektita", - - "error.page.changeSlug.permission": "Vi ne rajtas ŝanĝi la URL-nomon de \"{slug}\"", - "error.page.changeStatus.incomplete": "La paĝo havas erarojn, kaj tiel ne povas esti publikigita", - "error.page.changeStatus.permission": "La paĝstato ne estas ŝanĝebla", - "error.page.changeStatus.toDraft.invalid": "Ne eblas konverti la paĝon \"{slug}\" al malneto", - "error.page.changeTemplate.invalid": "Ne eblas ŝanĝi la ŝablonon de la paĝo \"{slug}\"", - "error.page.changeTemplate.permission": "Vi ne rajtas ŝanĝi la ŝablonon de \"{slug}\"", - "error.page.changeTitle.empty": "La titolo ne rajtas esti malplena", - "error.page.changeTitle.permission": "Vi ne rajtas ŝanĝi la titolon de \"{slug}\"", - "error.page.create.permission": "Vi ne rajtas krei \"{slug}\"", - "error.page.delete": "Ne eblas forigi la paĝon \"{slug}\"", - "error.page.delete.confirm": "Bonvolu entajpi la titolon de la paĝo for konfirmi", - "error.page.delete.hasChildren": "Ne eblas forigi la paĝon ĉar ĝi havas subpaĝojn", - "error.page.delete.permission": "Vi ne rajtas forigi \"{slug}\"", - "error.page.draft.duplicate": "Malneto uzanta la URL-nomon \"{slug}\" jam ekzistas", - "error.page.duplicate": "Paĝo uzanta la URL-nomon \"{slug}\" jam ekzistas", - "error.page.duplicate.permission": "Vi ne rajtas duobligi \"{slug}\"", - "error.page.notFound": "La paĝo \"{slug}\" ne troveblas", - "error.page.num.invalid": "Bonvolu entajpi validan ord-numeron. Numeroj devas esti pozitivaj.", - "error.page.slug.invalid": "Bonvolu entajpi validan URL-nomon", - "error.page.slug.maxlength": "URL-nomo devas esti malpli ol \"{length}\" literojn longa", - "error.page.sort.permission": "Ne eblas ordigi la paĝon \"{slug}\" ", - "error.page.status.invalid": "Bonvolu elekti validan paĝstaton", - "error.page.undefined": "La paĝo ne estas trovebla", - "error.page.update.permission": "Vi ne rajtas ĝisdatigi \"{slug}\"", - - "error.section.files.max.plural": "Vi devas aldoni maksimume {max} dosierojn al sekcio \"{section}\"", - "error.section.files.max.singular": "Vi devas aldoni maksimume unu dosieron al sekcio \"{section}\"", - "error.section.files.min.plural": "La sekcio \"{section}\" bezonas almenaŭ {min} dosierojn", - "error.section.files.min.singular": "La sekcio \"{section}\" bezonas almenaŭ unu dosieron", - - "error.section.pages.max.plural": "Vi devas aldoni maksimume {max} paĝojn al sekcio \"{section}\"", - "error.section.pages.max.singular": "Vi devas aldoni maksimume unu paĝon al sekcio \"{section}\"", - "error.section.pages.min.plural": "La sekcio \"{section}\" bezonas almenaŭ {min} paĝojn", - "error.section.pages.min.singular": "La sekcio \"{section}\" bezonas almenaŭ unu paĝon", - - "error.section.notLoaded": "Ne eblis ŝarĝi la sekcion \"{section}\"", - "error.section.type.invalid": "La sekcia tipo \"{type}\" ne estas valida", - - "error.site.changeTitle.empty": "La titolo ne rajtas esti malplena", - "error.site.changeTitle.permission": "Vi ne rajtas ŝanĝi la titolon de la retejo", - "error.site.update.permission": "Vi ne rajtas ĝisdatigi la retejon", - - "error.template.default.notFound": "La defaŭlta ŝablono ne ekzistas", - - "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Vi ne rajtas ŝanĝi la retpoŝtadreson de la uzanto \"{name}\"", - "error.user.changeLanguage.permission": "Vi ne rajtas ŝanĝi la lingvon de la uzanto \"{name}\"", - "error.user.changeName.permission": "Vi ne rajtas ŝanĝi la nomon de la uzanto \"{name}\"", - "error.user.changePassword.permission": "Vi ne rajtas ŝanĝi la pasvorton de la uzanto \"{name}\"", - "error.user.changeRole.lastAdmin": "Ne eblas ŝanĝi la rolon de la lasta administranto", - "error.user.changeRole.permission": "Vi ne rajtas ŝanĝi la rolon de la uzanto \"{name}\"", - "error.user.changeRole.toAdmin": "Vi ne rajtas promocii uzanton al rolo 'administranto'", - "error.user.create.permission": "Vi ne rajtas krei ĉi-tiun uzanton", - "error.user.delete": "Ne eblas forigi uzanton \"{name}\"", - "error.user.delete.lastAdmin": "Ne eblas forigi la lastan administranton", - "error.user.delete.lastUser": "Ne eblas forigi la lastan uzanton", - "error.user.delete.permission": "Vi ne rajtas forigi la uzanton \"{name}\"", - "error.user.duplicate": "Jam ekzistas uzanto kies retpoŝtadreso estas \"{email}\"", - "error.user.email.invalid": "Bonvolu entajpi validan retpoŝtadreson", - "error.user.language.invalid": "Bonvolu entajpi validan lingvon", - "error.user.notFound": "La uzanto \"{name}\" ne troveblas", - "error.user.password.invalid": "Bonvolu entajpi validan pasvorton. Pasvortoj devas esti almenaŭ 8 literojn longaj.", - "error.user.password.notSame": "La pasvortoj ne estas kongruantaj", - "error.user.password.undefined": "La uzanto ne havas pasvorton", - "error.user.password.wrong": "Malĝusta pasvorto", - "error.user.role.invalid": "Bonvolu entajpi validan rolon", - "error.user.undefined": "La uzanto ne troveblas", - "error.user.update.permission": "Vi ne rajtas ĝisdatigi la uzanton \"{name}\"", - - "error.validation.accepted": "Bonvolu konfirmi", - "error.validation.alpha": "Bonvolu entajpi nur literojn inter a-z", - "error.validation.alphanum": "Bonvolu entajpi nur aŭ literojn inter a-z aũ numerojn inter 0-9", - "error.validation.between": "Bonvolu entajpi valoron inter \"{min}\" kaj \"{max}\"", - "error.validation.boolean": "Bonvolu konfirmi aŭ malkonfirmi", - "error.validation.contains": "Bonvolu entajpi valoron kiu enhavas \"{needle}\"", - "error.validation.date": "Bonvolu entajpi validan daton", - "error.validation.date.after": "Bonvolu entajpi daton post {date}", - "error.validation.date.before": "Bonvolu entajpi daton antaũ {date}", - "error.validation.date.between": "Bonvolu entajpi daton inter {min} kaj {max}", - "error.validation.denied": "Bonvolu malkonfirmi", - "error.validation.different": "La valoro ne rajtas esti \"{other}\"", - "error.validation.email": "Bonvolu entajpi validan retpoŝtadreson", - "error.validation.endswith": "La valoro devas finiĝi per \"{end}\"", - "error.validation.filename": "Bonvolu entajpi validan dosiernomon", - "error.validation.in": "Bonvolu entajpi unu el la sekvaj: ({in})", - "error.validation.integer": "Bonvolu entajpi validan entjeron", - "error.validation.ip": "Bonvolu entajpi validan IP-adreson", - "error.validation.less": "Bonvolu entajpi valoron malpli ol {max}", - "error.validation.match": "La valoro ne kongruas al la atendata ŝablono", - "error.validation.max": "Bonvolu entajpi valoron egalan al aũ malpli ol {max}", - "error.validation.maxlength": "Bonvolu entajpi pli mallongan valoron (maksimume {max} literojn)", - "error.validation.maxwords": "Bonvolu entajpi maksimume {max} vorto(j)n", - "error.validation.min": "Bonvolu entajpi valoron egalan al aŭ pli granda ol {min}", - "error.validation.minlength": "Bonvolu entajpi pli longan valoron (minimume {min} literojn)", - "error.validation.minwords": "Bonvolu entajpi almenaŭ {min} vorto(j)n", - "error.validation.more": "Bonvolu entajpi valoron pli grandan ol {min}", - "error.validation.notcontains": "Bonvolu entajpi valoron kiu ne enhavas \"{needle}\"", - "error.validation.notin": "Bonvolu entajpi neniu ajn el la sekvaj: ({notin})", - "error.validation.option": "Bonvolu fari validan elekton", - "error.validation.num": "Bonvolu entajpi validan numeron", - "error.validation.required": "Bonvolu entajpi ion", - "error.validation.same": "Bonvolu entajpi \"{other}\"", - "error.validation.size": "La grando de la valoro devas esti \"{size}\"", - "error.validation.startswith": "La valoro devas komenciĝi per \"{start}\"", - "error.validation.time": "Bonvolu entajpi validan horaron", - "error.validation.time.after": "Bonvolu entajpi horaron post {time}", - "error.validation.time.before": "Bonvolu entajpi horaron antaŭ {time}", - "error.validation.time.between": "Bonvolu entajpi horaron inter {min} kaj {max}", - "error.validation.url": "Bonvolu entajpi validan URL", - - "expand": "Etendi", - "expand.all": "Etendi ĉiujn", - - "field.required": "La kampo ne rajtas esti malplena", - "field.blocks.changeType": "Ŝanĝi tipon", - "field.blocks.code.name": "Kodo", - "field.blocks.code.language": "Lingvo", - "field.blocks.code.placeholder": "Via kodo ...", - "field.blocks.delete.confirm": "Ĉu vi certe volas forigi ĉi tiun blokon?", - "field.blocks.delete.confirm.all": "Ĉu vi certe volas forigi ĉiujn blokojn?", - "field.blocks.delete.confirm.selected": "Ĉu vi certe volas forigi la elektitajn blokojn?", - "field.blocks.empty": "Ankoraŭ neniu bloko", - "field.blocks.fieldsets.label": "Bonvolu elekti tipon de bloko ...", - "field.blocks.fieldsets.paste": "Premu {{ shortcut }}por alglui/importi blokojn el via tondujo", - "field.blocks.gallery.name": "Galerio", - "field.blocks.gallery.images.empty": "Ankoraŭ neniu bildo", - "field.blocks.gallery.images.label": "Bildoj", - "field.blocks.heading.level": "Nivelo", - "field.blocks.heading.name": "Titolo", - "field.blocks.heading.text": "Teksto", - "field.blocks.heading.placeholder": "Titolo ...", - "field.blocks.image.alt": "Alternativa titolo", - "field.blocks.image.caption": "Apudskribo", - "field.blocks.image.crop": "Stuci", - "field.blocks.image.link": "Ligilo", - "field.blocks.image.location": "Loko", - "field.blocks.image.name": "Bildo", - "field.blocks.image.placeholder": "Elekti bildon", - "field.blocks.image.ratio": "Proporcio", - "field.blocks.image.url": "URL de la bildo", - "field.blocks.line.name": "Linio", - "field.blocks.list.name": "Listo", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Teksto", - "field.blocks.markdown.placeholder": "Markdown ...", - "field.blocks.quote.name": "Citaĵo", - "field.blocks.quote.text.label": "Teksto", - "field.blocks.quote.text.placeholder": "Citaĵo ...", - "field.blocks.quote.citation.label": "Citaĵo", - "field.blocks.quote.citation.placeholder": "de ...", - "field.blocks.text.name": "Teksto", - "field.blocks.text.placeholder": "Teksto ...", - "field.blocks.video.caption": "Apudskribo", - "field.blocks.video.name": "Videâjo", - "field.blocks.video.placeholder": "Entajpi URL de videaĵo", - "field.blocks.video.url.label": "Video-URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Ankoraŭ neniu dosiero elektita", - - "field.layout.delete": "Forigi blokaranĝo", - "field.layout.delete.confirm": "Ĉu vi certe volas forigi ĉi tiun blokaranĝon?", - "field.layout.empty": "Ankoraŭ neniu vico", - "field.layout.select": "Elekti blokaranĝon", - - "field.pages.empty": "Ankoraŭ neniu paĝo elektita", - "field.structure.delete.confirm": "Ĉu vi certe volas forigi ĉi tiun vicon?", - "field.structure.empty": "Ankoraŭ neniu enigo", - "field.users.empty": "Ankoraŭ neniu uzanto elektita", - - "file.blueprint": "Ĉi tiu dosiero ankoraŭ havas neniun planon. Vi povas difini planon ĉe /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Ĉu vi certe vollas forigi
{filename}?", - "file.sort": "Ŝanĝi ordon", - - "files": "Dosieroj", - "files.empty": "Ankoraŭ neniu dosiero", - - "hide": "Kaŝi", - "hour": "Horo", - "import": "Importi", - "info": "Info", - "insert": "Enmeti", - "insert.after": "Enmeti post", - "insert.before": "Enmeti antaŭ", - "install": "Instali", - - "installation": "Instalado", - "installation.completed": "La panelo estas instalita", - "installation.disabled": "La instalilo de la panelo estas norme malebligita en publikaj serviloj. Bonvolu uzi la instalilon en via loka komputilo, aŭ ebligu ĝin per la opcio panel.install", - "installation.issues.accounts": "La dosierujo /site/accounts ne ekzistas, aŭ ne estas skribebla", - "installation.issues.content": "La dosierujo /content ne ekzistas, aŭ ne estas skribebla", - "installation.issues.curl": "La kromprogramo CURL estas deviga", - "installation.issues.headline": "Ne eblas instali la panelon", - "installation.issues.mbstring": "La kromprogramo MB String estas deviga", - "installation.issues.media": "La dosierujo /media ne ekzistas, aũ ne estas skribebla", - "installation.issues.php": "Nepre uzu PHP 7+", - "installation.issues.server": "Kirby bezonas Apache, NginxCaddy", - "installation.issues.sessions": "La dosierujo /site/sessions ne ekzistas, aŭ ne estas skribebla", - - "language": "Lingvo", - "language.code": "Kodo", - "language.convert": "Farigi defaŭlton", - "language.convert.confirm": "

Ĉu vi certe volas konverti {name} al la defaŭlta lingvo? Ĉi tion vi ne povos malfari.

Se {name} havas netradukitan enhavon, tiuj tekstoj nun ne havos defaŭlton, kaj simple ne aperos en via retejo.

", - "language.create": "Aldoni novan lingvon", - "language.delete.confirm": "Ĉu vi certe volas forigi la lingvon {name}, inkluzive de ĉiuj tradukoj? Vi ne povos malfari tion!", - "language.deleted": "La lingvo estas forigita", - "language.direction": "Direkto de leĝado", - "language.direction.ltr": "Dekstren", - "language.direction.rtl": "Maldesktren", - "language.locale": "Lokaĵaro de PHP", - "language.locale.warning": "Vi uzas tajloritan agordon de lokaĵaro. Bonvolu ŝanĝi viajn agordojn laŭmende en la lingva dosiero ĉe /site/languages", - "language.name": "Nomo", - "language.updated": "La lingvo estas ĝisdatigita", - - "languages": "Lingvoj", - "languages.default": "Defaŭlta lingvo", - "languages.empty": "Ankoraũ estas neniu lingvo", - "languages.secondary": "Kromlingvoj", - "languages.secondary.empty": "Ankoraŭ estas neniu kromlingvoj", - - "license": "Permisilo", - "license.buy": "Aĉeti permisilon", - "license.register": "Registriĝi", - "license.manage": "Manage your licenses", - "license.register.help": "Vi ricevis vian kodon de permisilo retpoŝte, post aĉeti ĝin. Bonvolu kopii kaj alglui ĝin por registriĝi.", - "license.register.label": "Bonvolu entajpi vian kodon de permisilo", - "license.register.success": "Dankon pro subteni Kirby", - "license.unregistered": "Ĉi tiu estas neregistrita kopio de Kirby", - "license.unregistered.label": "Unregistered", - - "link": "Ligilo", - "link.text": "Ligila teksto", - - "loading": "Ŝargante", - - "lock.unsaved": "Nekonservitaj ŝanĝoj", - "lock.unsaved.empty": "Ĉiuj ŝanĝoj estas nun konservitaj", - "lock.isLocked": "Nekonservitaj ŝanĝoj de {email}", - "lock.file.isLocked": "La dosiero estas ĉi-momente redaktata de {email}, kaj tial ne povas esti ŝanĝita", - "lock.page.isLocked": "La paĝo estas ĉi-momente redaktata de {email}, kaj tial ne povas esti ŝanĝita", - "lock.unlock": "Malŝlosi", - "lock.isUnlocked": "Viaj nekonservitaj ŝanĝoj estas ŝanĝitaj de alia uzanto. Vi povas elŝuti dosieron kun viaj ŝanĝoj por permane kunfandi ilin.", - - "login": "Ensaluti", - "login.code.label.login": "Ensaluta kodo", - "login.code.label.password-reset": "Kodo por restarigi pasvorton", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "Se via retpoŝtadreso estas enregistrita, via kodo estis sendita retpoŝte", - "login.email.login.body": "Saluton {user.nameOrEmail},\n\nVi petis ensalutan kodon por la panelo de la retejo {site}.\nLa sekvanta kodo validos dum {timeout} minutoj:\n\n{code}\n\nSe vi ne petis ensalutan kodon, bonvolu ignori ĉi tiun mesaĝon, aŭ kontaktu vian sistem-administranton se vi havas demandojn.\nPro sekureco, bonvolu NE plusendi ĉi tiun mesaĝon.", - "login.email.login.subject": "Via ensaluta kodo", - "login.email.password-reset.body": "Saluton {user.nameOrEmail},\n\nVi petis kodon por restarigi vian pasvorton por la panelo de la retejo {site}.\nLa sekvanta kodo validos dum {timeout} minutoj:\n\n{code}\n\nSe vi ne petis kodon por restarigi vian pasvorton, bonvolu ignori ĉi tiun mesaĝon, aŭ kontaktu vian sistem-administranton se vi havas demandojn.\nPro sekureco, bonvolu NE plusendi ĉi tiun mesaĝon.", - "login.email.password-reset.subject": "Kodo por restarigi pasvorton", - "login.remember": "Daŭre tenu min ensalutita", - "login.reset": "Restarigi pasvorton", - "login.toggleText.code.email": "Ensaluti retpoŝte", - "login.toggleText.code.email-password": "Ensaluti per pasvorto", - "login.toggleText.password-reset.email": "Ĉu vi forgesis vian pasvorton?", - "login.toggleText.password-reset.email-password": "← Reen al ensaluto", - - "logout": "Elsaluti", - - "menu": "Menuo", - "meridiem": "atm/ptm", - "mime": "Tipo de aŭdvidaĵo", - "minutes": "Minutoj", - - "month": "Monato", - "months.april": "aprilo", - "months.august": "aŭgusto", - "months.december": "decembro", - "months.february": "februaro", - "months.january": "januaro", - "months.july": "julio", - "months.june": "junio", - "months.march": "marto", - "months.may": "majo", - "months.november": "novembro", - "months.october": "oktobro", - "months.september": "septembro", - - "more": "Pli", - "name": "Nomo", - "next": "Sekve", - "no": "ne", - "off": "ne", - "on": "jes", - "open": "Malfermi", - "open.newWindow": "Malfermi novan fenestron", - "options": "Opcioj", - "options.none": "Neniu opcio", - - "orientation": "Orientiĝo", - "orientation.landscape": "Horizontala", - "orientation.portrait": "Vertikala", - "orientation.square": "Kvadrata", - - "page.blueprint": "Ĉi tiu paĝo ankoraŭ ne havas planon. Vi povas difini planon ĉe /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Ŝanĝi URL", - "page.changeSlug.fromTitle": "Krei el titolo", - "page.changeStatus": "Ŝanĝi staton", - "page.changeStatus.position": "Bonvolu elekti ordon", - "page.changeStatus.select": "Elekti novan staton", - "page.changeTemplate": "Ŝanĝi ŝablonon", - "page.delete.confirm": "Ĉu vi certe volas forigi {title}?", - "page.delete.confirm.subpages": "Ĉi tiu paĝo havas subpaĝojn.
Ĉiuj subpaĝoj estos ankaŭ forigitaj.", - "page.delete.confirm.title": "Entajpu la titolon de la paĝo por konfirmi", - "page.draft.create": "Krei malneton", - "page.duplicate.appendix": "Kopii", - "page.duplicate.files": "Kopii dosierojn", - "page.duplicate.pages": "Kopii paĝojn", - "page.sort": "Ŝanĝi ordon", - "page.status": "Stato", - "page.status.draft": "Malneto", - "page.status.draft.description": "La paĝo estas malneto, kaj nur atingebla de ensalutitaj redaktantoj, aŭ per sekreta ligilo", - "page.status.listed": "Publika", - "page.status.listed.description": "La paĝo estas publika por ĉiuj ajn", - "page.status.unlisted": "Nelistata", - "page.status.unlisted.description": "La paĝo estas atingebla nur per URL", - - "pages": "Paĝoj", - "pages.empty": "Ankoraŭ neniu paĝo", - "pages.status.draft": "Malnetoj", - "pages.status.listed": "Publikigita", - "pages.status.unlisted": "Nelistata", - - "pagination.page": "Paĝo", - - "password": "Pasvorto", - "paste": "Alglui", - "paste.after": "Alglui post", - "pixel": "Pikselo", - "plugins": "Kromprogramoj", - "prev": "Antaŭe", - "preview": "Antaŭrigardi", - "remove": "Forigi", - "rename": "Ŝanĝi nomon", - "replace": "Anstataŭi", - "retry": "Provi denove", - "revert": "Malfari", - "revert.confirm": "Ĉu vi certe volas forigi ĉiujn nekonservitajn ŝanĝojn?", - - "role": "Rolo", - "role.admin.description": "La administranto havas ĉiujn rajtojn", - "role.admin.title": "Administranto", - "role.all": "Ĉiuj", - "role.empty": "Neniu uzanto havas ĉi tiun rolon", - "role.description.placeholder": "Neniu priskribo", - "role.nobody.description": "Ĉi tiu estas retrodefaŭlta rolo sen permesoj", - "role.nobody.title": "Neniu", - - "save": "Konservi", - "search": "Serĉi", - "search.min": "Entajpu {min} literojn por serĉi", - "search.all": "Montri ĉiujn", - "search.results.none": "Neniu rezulto", - - "section.required": "La sekcio estas deviga", - - "security": "Security", - "select": "Elekti", - "server": "Servilo", - "settings": "Agordoj", - "show": "Montri", - "site.blueprint": "La retejo ankoraŭ ne havas planon. Vi povas difini planon ĉe /site/blueprints/site.yml", - "size": "Grando", - "slug": "URL-nomo", - "sort": "Ordigi", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Titolo", - "template": "Ŝablono", - "today": "Hodiaŭ", - - "toolbar.button.code": "Kodo", - "toolbar.button.bold": "Grasa", - "toolbar.button.email": "Retpoŝto", - "toolbar.button.headings": "Titoloj", - "toolbar.button.heading.1": "Titolo 1", - "toolbar.button.heading.2": "Titolo 2", - "toolbar.button.heading.3": "Titolo 3", - "toolbar.button.heading.4": "Titolo 4", - "toolbar.button.heading.5": "Titolo 5", - "toolbar.button.heading.6": "Titolo 6", - "toolbar.button.italic": "Kursiva", - "toolbar.button.file": "Dosiero", - "toolbar.button.file.select": "Elekti dosieron", - "toolbar.button.file.upload": "Alŝuti dosieron", - "toolbar.button.link": "Ligilo", - "toolbar.button.paragraph": "Paragrafo", - "toolbar.button.strike": "Trastrekita", - "toolbar.button.ol": "Numerita listo", - "toolbar.button.underline": "Substrekita", - "toolbar.button.ul": "Bula listo", - - "translation.author": "Teamo Kirby", - "translation.direction": "ltr", - "translation.name": "Esperanto", - "translation.locale": "eo", - - "upload": "Alŝuti", - "upload.error.cantMove": "Ne eblis movi la alŝutita dosiero", - "upload.error.cantWrite": "Ne eblis registri la dosieron en la diskon", - "upload.error.default": "Ne eblis alŝuti la dosieron", - "upload.error.extension": "Alŝutado haltita pro la dosiersufikso", - "upload.error.formSize": "La alŝutita dosiero estas pli granda ol la direktivo MAX_FILE_SIZE indikata en la formularo", - "upload.error.iniPostSize": "La alŝutita dosiero estas pli granda ol la direktivo post_max_size de php.ini", - "upload.error.iniSize": "La alŝutita dosiero estas pli granda ol la direktivo upload_max_filesize de php.ini", - "upload.error.noFile": "Neniu dosiero alŝutita", - "upload.error.noFiles": "Neniuj dosieroj alŝutitaj", - "upload.error.partial": "La dosiero estis nur parte alŝutita", - "upload.error.tmpDir": "Mankas provizora dosierujo", - "upload.errors": "Eraro", - "upload.progress": "Alŝutante...", - - "url": "URL", - "url.placeholder": "https://ekzemplo.com", - - "user": "Uzanto", - "user.blueprint": "Vi povas difini pluajn sekciojn kaj kampojn de formularo por ĉi tiu rolo de uzanto ĉe /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Ŝanĝi retpoŝtadreson", - "user.changeLanguage": "Ŝanĝi lingvon", - "user.changeName": "Ŝangi la nomon de la uzanto", - "user.changePassword": "Ŝanĝi pasvorton", - "user.changePassword.new": "Nova pasvorto", - "user.changePassword.new.confirm": "Konfirmi la novan pasvorton...", - "user.changeRole": "Ŝanĝi rolon", - "user.changeRole.select": "Elekti novan rolon", - "user.create": "Aldoni novan uzanton", - "user.delete": "Forigi ĉi tiun uzanton", - "user.delete.confirm": "Ĉu vi certe volas forigi
{email}?", - - "users": "Uzantoj", - - "version": "Versio", - - "view.account": "Via konto", - "view.installation": "Instalado", - "view.languages": "Lingvoj", - "view.resetPassword": "Restarigi pasvorton", - "view.site": "Retejo", - "view.system": "Sistemo", - "view.users": "Uzantoj", - - "welcome": "Bonvenon", - "year": "Jaro", - "yes": "jes" + "account.changeName": "Ŝanĝi vian nomon", + "account.delete": "Forigi vian konton", + "account.delete.confirm": "Ĉu vi certe deziras forigi vian konton? Vi estos tuj elsalutita. Ne eblos malforigi vian konton.", + + "add": "Aldoni", + "author": "Aŭtoro", + "avatar": "Profilbildo", + "back": "Reen", + "cancel": "Nuligi", + "change": "Ŝanĝi", + "close": "Fermi", + "confirm": "Bone", + "collapse": "Fermi", + "collapse.all": "Fermi ĉiujn", + "copy": "Kopii", + "copy.all": "Kopii ĉiujn", + "create": "Krei", + + "date": "Dato", + "date.select": "Elekti daton", + + "day": "Tago", + "days.fri": "Ven", + "days.mon": "Lun", + "days.sat": "Sab", + "days.sun": "Dim", + "days.thu": "Ĵaŭ", + "days.tue": "Mar", + "days.wed": "Mer", + + "debugging": "Sencimigado", + + "delete": "Forigi", + "delete.all": "Forigi ĉiujn", + + "dialog.files.empty": "Neniu dosiero por elekti", + "dialog.pages.empty": "Neniu paĝo por elekti", + "dialog.users.empty": "Neniu uzanto por elekti", + + "dimensions": "Dimensioj", + "disabled": "Malebligita", + "discard": "Forĵeti", + "download": "Elŝuti", + "duplicate": "Duobligi", + + "edit": "Modifi", + + "email": "Retpoŝto", + "email.placeholder": "retpoŝto@ekzemplo.com", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Medio", + + "error.access.code": "Nevalida kodo", + "error.access.login": "Nevalida ensaluto", + "error.access.panel": "Vi ne rajtas eniri la administran panelon", + "error.access.view": "Vi ne rajtas eniri ĉi tiun areon de la panelo", + + "error.avatar.create.fail": "La profilbildo ne povis esti alŝutita", + "error.avatar.delete.fail": "La profilbildo ne povis esti forigita", + "error.avatar.dimensions.invalid": "Bonvolu certigi ke la profilbildo ne estas pli ol 3000 bilderojn larĝa kaj alta", + "error.avatar.mime.forbidden": "La profilbildo devas esti dosiero en dosierformo aŭ JPEG aŭ PNG", + + "error.blueprint.notFound": "La plano \"{name}\" ne povis esti ŝargita", + + "error.blocks.max.plural": "Oni devas ne aldoni pli ol {max} blokoj", + "error.blocks.max.singular": "Vi devas ne aldoni pli ol unu bloko", + "error.blocks.min.plural": "Oni devas aldoni almenaŭ {min} blokojn", + "error.blocks.min.singular": "Oni devas aldoni almenaŭ unu blokon", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "La retpoŝta antaŭagordo \"{name}\" ne estas trovebla", + + "error.field.converter.invalid": "Nevalida konvertilo \"{converter}\"", + + "error.file.changeName.empty": "La nomo ne rajtas esti malplena", + "error.file.changeName.permission": "Vi ne rajtas ŝanĝi la nomon de \"{filename}\"", + "error.file.duplicate": "Jam ekzistas dosiero nomita \"{filename}\"", + "error.file.extension.forbidden": "La dosiersufikso \"{extension}\" ne estas permesita", + "error.file.extension.invalid": "Nevalida dosiersufikso: {extension}", + "error.file.extension.missing": "Mankas la dosiersufiksoj por \"{filename}\"", + "error.file.maxheight": "La bildo ne povas esti pli ol {height} bilderojn alta ", + "error.file.maxsize": "La dosiero estas tro granda", + "error.file.maxwidth": "La bildo ne povas esti pli oll {width} bilderojn larĝa", + "error.file.mime.differs": "La alŝutata dosiero devas havi la saman MIME-tipon \"{mime}\"", + "error.file.mime.forbidden": "La MIME-tipo \"{mime}\" ne povas esti uzata ĉi tie", + "error.file.mime.invalid": "Nevalida MIME-tipo: {mime}", + "error.file.mime.missing": "La MIME-tipo for \"{filename}\" ne estas detektebla", + "error.file.minheight": "La bildo devas esti almenaŭ {height} bilderojn alta", + "error.file.minsize": "La dosiero estas tro malgranda", + "error.file.minwidth": "La bildo devas esti almenaŭ {width} bilderojn larĝa", + "error.file.name.missing": "La dosiernomo ne rajtas esti malplena", + "error.file.notFound": "La dosiero \"{filename}\" ne troveblas", + "error.file.orientation": "La orientiĝo de la bildo devas esti \"{orientation}\"", + "error.file.type.forbidden": "Vi ne rajtas alŝuti dosiertipon {type}", + "error.file.type.invalid": "Nevalida dosiertipo: {type}", + "error.file.undefined": "La dosiero ne troveblas", + + "error.form.incomplete": "Bonvolu korekti ĉiujn erarojn en formularo...", + "error.form.notSaved": "Ne eblis konservi la formularon", + + "error.language.code": "Bonvolu entajpi validan kodon por la lingvo", + "error.language.duplicate": "La lingvo jam ekzistas", + "error.language.name": "Bonvolu entajpi validan nomon por la lingvo", + "error.language.notFound": "La lingvo ne troveblas", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "Estas eraro en la agordoj de blokaranĝo {index}", + + "error.license.format": "Bonvolu entajpi validan kodon de permisilo", + "error.license.email": "Bonvolu entajpi validan retpoŝtadreson", + "error.license.verification": "Ne eblis kontroli la permisilon", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "La panelo estas ĉi-momente nekonektita", + + "error.page.changeSlug.permission": "Vi ne rajtas ŝanĝi la URL-nomon de \"{slug}\"", + "error.page.changeStatus.incomplete": "La paĝo havas erarojn, kaj tiel ne povas esti publikigita", + "error.page.changeStatus.permission": "La paĝstato ne estas ŝanĝebla", + "error.page.changeStatus.toDraft.invalid": "Ne eblas konverti la paĝon \"{slug}\" al malneto", + "error.page.changeTemplate.invalid": "Ne eblas ŝanĝi la ŝablonon de la paĝo \"{slug}\"", + "error.page.changeTemplate.permission": "Vi ne rajtas ŝanĝi la ŝablonon de \"{slug}\"", + "error.page.changeTitle.empty": "La titolo ne rajtas esti malplena", + "error.page.changeTitle.permission": "Vi ne rajtas ŝanĝi la titolon de \"{slug}\"", + "error.page.create.permission": "Vi ne rajtas krei \"{slug}\"", + "error.page.delete": "Ne eblas forigi la paĝon \"{slug}\"", + "error.page.delete.confirm": "Bonvolu entajpi la titolon de la paĝo for konfirmi", + "error.page.delete.hasChildren": "Ne eblas forigi la paĝon ĉar ĝi havas subpaĝojn", + "error.page.delete.permission": "Vi ne rajtas forigi \"{slug}\"", + "error.page.draft.duplicate": "Malneto uzanta la URL-nomon \"{slug}\" jam ekzistas", + "error.page.duplicate": "Paĝo uzanta la URL-nomon \"{slug}\" jam ekzistas", + "error.page.duplicate.permission": "Vi ne rajtas duobligi \"{slug}\"", + "error.page.notFound": "La paĝo \"{slug}\" ne troveblas", + "error.page.num.invalid": "Bonvolu entajpi validan ord-numeron. Numeroj devas esti pozitivaj.", + "error.page.slug.invalid": "Bonvolu entajpi validan URL-nomon", + "error.page.slug.maxlength": "URL-nomo devas esti malpli ol \"{length}\" literojn longa", + "error.page.sort.permission": "Ne eblas ordigi la paĝon \"{slug}\" ", + "error.page.status.invalid": "Bonvolu elekti validan paĝstaton", + "error.page.undefined": "La paĝo ne estas trovebla", + "error.page.update.permission": "Vi ne rajtas ĝisdatigi \"{slug}\"", + + "error.section.files.max.plural": "Vi devas aldoni maksimume {max} dosierojn al sekcio \"{section}\"", + "error.section.files.max.singular": "Vi devas aldoni maksimume unu dosieron al sekcio \"{section}\"", + "error.section.files.min.plural": "La sekcio \"{section}\" bezonas almenaŭ {min} dosierojn", + "error.section.files.min.singular": "La sekcio \"{section}\" bezonas almenaŭ unu dosieron", + + "error.section.pages.max.plural": "Vi devas aldoni maksimume {max} paĝojn al sekcio \"{section}\"", + "error.section.pages.max.singular": "Vi devas aldoni maksimume unu paĝon al sekcio \"{section}\"", + "error.section.pages.min.plural": "La sekcio \"{section}\" bezonas almenaŭ {min} paĝojn", + "error.section.pages.min.singular": "La sekcio \"{section}\" bezonas almenaŭ unu paĝon", + + "error.section.notLoaded": "Ne eblis ŝarĝi la sekcion \"{section}\"", + "error.section.type.invalid": "La sekcia tipo \"{type}\" ne estas valida", + + "error.site.changeTitle.empty": "La titolo ne rajtas esti malplena", + "error.site.changeTitle.permission": "Vi ne rajtas ŝanĝi la titolon de la retejo", + "error.site.update.permission": "Vi ne rajtas ĝisdatigi la retejon", + + "error.template.default.notFound": "La defaŭlta ŝablono ne ekzistas", + + "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Vi ne rajtas ŝanĝi la retpoŝtadreson de la uzanto \"{name}\"", + "error.user.changeLanguage.permission": "Vi ne rajtas ŝanĝi la lingvon de la uzanto \"{name}\"", + "error.user.changeName.permission": "Vi ne rajtas ŝanĝi la nomon de la uzanto \"{name}\"", + "error.user.changePassword.permission": "Vi ne rajtas ŝanĝi la pasvorton de la uzanto \"{name}\"", + "error.user.changeRole.lastAdmin": "Ne eblas ŝanĝi la rolon de la lasta administranto", + "error.user.changeRole.permission": "Vi ne rajtas ŝanĝi la rolon de la uzanto \"{name}\"", + "error.user.changeRole.toAdmin": "Vi ne rajtas promocii uzanton al rolo 'administranto'", + "error.user.create.permission": "Vi ne rajtas krei ĉi-tiun uzanton", + "error.user.delete": "Ne eblas forigi uzanton \"{name}\"", + "error.user.delete.lastAdmin": "Ne eblas forigi la lastan administranton", + "error.user.delete.lastUser": "Ne eblas forigi la lastan uzanton", + "error.user.delete.permission": "Vi ne rajtas forigi la uzanton \"{name}\"", + "error.user.duplicate": "Jam ekzistas uzanto kies retpoŝtadreso estas \"{email}\"", + "error.user.email.invalid": "Bonvolu entajpi validan retpoŝtadreson", + "error.user.language.invalid": "Bonvolu entajpi validan lingvon", + "error.user.notFound": "La uzanto \"{name}\" ne troveblas", + "error.user.password.invalid": "Bonvolu entajpi validan pasvorton. Pasvortoj devas esti almenaŭ 8 literojn longaj.", + "error.user.password.notSame": "La pasvortoj ne estas kongruantaj", + "error.user.password.undefined": "La uzanto ne havas pasvorton", + "error.user.password.wrong": "Malĝusta pasvorto", + "error.user.role.invalid": "Bonvolu entajpi validan rolon", + "error.user.undefined": "La uzanto ne troveblas", + "error.user.update.permission": "Vi ne rajtas ĝisdatigi la uzanton \"{name}\"", + + "error.validation.accepted": "Bonvolu konfirmi", + "error.validation.alpha": "Bonvolu entajpi nur literojn inter a-z", + "error.validation.alphanum": "Bonvolu entajpi nur aŭ literojn inter a-z aũ numerojn inter 0-9", + "error.validation.between": "Bonvolu entajpi valoron inter \"{min}\" kaj \"{max}\"", + "error.validation.boolean": "Bonvolu konfirmi aŭ malkonfirmi", + "error.validation.contains": "Bonvolu entajpi valoron kiu enhavas \"{needle}\"", + "error.validation.date": "Bonvolu entajpi validan daton", + "error.validation.date.after": "Bonvolu entajpi daton post {date}", + "error.validation.date.before": "Bonvolu entajpi daton antaũ {date}", + "error.validation.date.between": "Bonvolu entajpi daton inter {min} kaj {max}", + "error.validation.denied": "Bonvolu malkonfirmi", + "error.validation.different": "La valoro ne rajtas esti \"{other}\"", + "error.validation.email": "Bonvolu entajpi validan retpoŝtadreson", + "error.validation.endswith": "La valoro devas finiĝi per \"{end}\"", + "error.validation.filename": "Bonvolu entajpi validan dosiernomon", + "error.validation.in": "Bonvolu entajpi unu el la sekvaj: ({in})", + "error.validation.integer": "Bonvolu entajpi validan entjeron", + "error.validation.ip": "Bonvolu entajpi validan IP-adreson", + "error.validation.less": "Bonvolu entajpi valoron malpli ol {max}", + "error.validation.match": "La valoro ne kongruas al la atendata ŝablono", + "error.validation.max": "Bonvolu entajpi valoron egalan al aũ malpli ol {max}", + "error.validation.maxlength": "Bonvolu entajpi pli mallongan valoron (maksimume {max} literojn)", + "error.validation.maxwords": "Bonvolu entajpi maksimume {max} vorto(j)n", + "error.validation.min": "Bonvolu entajpi valoron egalan al aŭ pli granda ol {min}", + "error.validation.minlength": "Bonvolu entajpi pli longan valoron (minimume {min} literojn)", + "error.validation.minwords": "Bonvolu entajpi almenaŭ {min} vorto(j)n", + "error.validation.more": "Bonvolu entajpi valoron pli grandan ol {min}", + "error.validation.notcontains": "Bonvolu entajpi valoron kiu ne enhavas \"{needle}\"", + "error.validation.notin": "Bonvolu entajpi neniu ajn el la sekvaj: ({notin})", + "error.validation.option": "Bonvolu fari validan elekton", + "error.validation.num": "Bonvolu entajpi validan numeron", + "error.validation.required": "Bonvolu entajpi ion", + "error.validation.same": "Bonvolu entajpi \"{other}\"", + "error.validation.size": "La grando de la valoro devas esti \"{size}\"", + "error.validation.startswith": "La valoro devas komenciĝi per \"{start}\"", + "error.validation.time": "Bonvolu entajpi validan horaron", + "error.validation.time.after": "Bonvolu entajpi horaron post {time}", + "error.validation.time.before": "Bonvolu entajpi horaron antaŭ {time}", + "error.validation.time.between": "Bonvolu entajpi horaron inter {min} kaj {max}", + "error.validation.url": "Bonvolu entajpi validan URL", + + "expand": "Etendi", + "expand.all": "Etendi ĉiujn", + + "field.required": "La kampo ne rajtas esti malplena", + "field.blocks.changeType": "Ŝanĝi tipon", + "field.blocks.code.name": "Kodo", + "field.blocks.code.language": "Lingvo", + "field.blocks.code.placeholder": "Via kodo ...", + "field.blocks.delete.confirm": "Ĉu vi certe volas forigi ĉi tiun blokon?", + "field.blocks.delete.confirm.all": "Ĉu vi certe volas forigi ĉiujn blokojn?", + "field.blocks.delete.confirm.selected": "Ĉu vi certe volas forigi la elektitajn blokojn?", + "field.blocks.empty": "Ankoraŭ neniu bloko", + "field.blocks.fieldsets.label": "Bonvolu elekti tipon de bloko ...", + "field.blocks.fieldsets.paste": "Premu {{ shortcut }}por alglui/importi blokojn el via tondujo", + "field.blocks.gallery.name": "Galerio", + "field.blocks.gallery.images.empty": "Ankoraŭ neniu bildo", + "field.blocks.gallery.images.label": "Bildoj", + "field.blocks.heading.level": "Nivelo", + "field.blocks.heading.name": "Titolo", + "field.blocks.heading.text": "Teksto", + "field.blocks.heading.placeholder": "Titolo ...", + "field.blocks.image.alt": "Alternativa titolo", + "field.blocks.image.caption": "Apudskribo", + "field.blocks.image.crop": "Stuci", + "field.blocks.image.link": "Ligilo", + "field.blocks.image.location": "Loko", + "field.blocks.image.name": "Bildo", + "field.blocks.image.placeholder": "Elekti bildon", + "field.blocks.image.ratio": "Proporcio", + "field.blocks.image.url": "URL de la bildo", + "field.blocks.line.name": "Linio", + "field.blocks.list.name": "Listo", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Teksto", + "field.blocks.markdown.placeholder": "Markdown ...", + "field.blocks.quote.name": "Citaĵo", + "field.blocks.quote.text.label": "Teksto", + "field.blocks.quote.text.placeholder": "Citaĵo ...", + "field.blocks.quote.citation.label": "Citaĵo", + "field.blocks.quote.citation.placeholder": "de ...", + "field.blocks.text.name": "Teksto", + "field.blocks.text.placeholder": "Teksto ...", + "field.blocks.video.caption": "Apudskribo", + "field.blocks.video.name": "Videâjo", + "field.blocks.video.placeholder": "Entajpi URL de videaĵo", + "field.blocks.video.url.label": "Video-URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Ankoraŭ neniu dosiero elektita", + + "field.layout.delete": "Forigi blokaranĝo", + "field.layout.delete.confirm": "Ĉu vi certe volas forigi ĉi tiun blokaranĝon?", + "field.layout.empty": "Ankoraŭ neniu vico", + "field.layout.select": "Elekti blokaranĝon", + + "field.object.empty": "No information yet", + + "field.pages.empty": "Ankoraŭ neniu paĝo elektita", + + "field.structure.delete.confirm": "Ĉu vi certe volas forigi ĉi tiun vicon?", + "field.structure.empty": "Ankoraŭ neniu enigo", + + "field.users.empty": "Ankoraŭ neniu uzanto elektita", + + "file.blueprint": "Ĉi tiu dosiero ankoraŭ havas neniun planon. Vi povas difini planon ĉe /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Ĉu vi certe vollas forigi
{filename}?", + "file.sort": "Ŝanĝi ordon", + + "files": "Dosieroj", + "files.empty": "Ankoraŭ neniu dosiero", + + "hide": "Kaŝi", + "hour": "Horo", + "import": "Importi", + "info": "Info", + "insert": "Enmeti", + "insert.after": "Enmeti post", + "insert.before": "Enmeti antaŭ", + "install": "Instali", + + "installation": "Instalado", + "installation.completed": "La panelo estas instalita", + "installation.disabled": "La instalilo de la panelo estas norme malebligita en publikaj serviloj. Bonvolu uzi la instalilon en via loka komputilo, aŭ ebligu ĝin per la opcio panel.install", + "installation.issues.accounts": "La dosierujo /site/accounts ne ekzistas, aŭ ne estas skribebla", + "installation.issues.content": "La dosierujo /content ne ekzistas, aŭ ne estas skribebla", + "installation.issues.curl": "La kromprogramo CURL estas deviga", + "installation.issues.headline": "Ne eblas instali la panelon", + "installation.issues.mbstring": "La kromprogramo MB String estas deviga", + "installation.issues.media": "La dosierujo /media ne ekzistas, aũ ne estas skribebla", + "installation.issues.php": "Nepre uzu PHP 7+", + "installation.issues.server": "Kirby bezonas Apache, NginxCaddy", + "installation.issues.sessions": "La dosierujo /site/sessions ne ekzistas, aŭ ne estas skribebla", + + "language": "Lingvo", + "language.code": "Kodo", + "language.convert": "Farigi defaŭlton", + "language.convert.confirm": "

Ĉu vi certe volas konverti {name} al la defaŭlta lingvo? Ĉi tion vi ne povos malfari.

Se {name} havas netradukitan enhavon, tiuj tekstoj nun ne havos defaŭlton, kaj simple ne aperos en via retejo.

", + "language.create": "Aldoni novan lingvon", + "language.delete.confirm": "Ĉu vi certe volas forigi la lingvon {name}, inkluzive de ĉiuj tradukoj? Vi ne povos malfari tion!", + "language.deleted": "La lingvo estas forigita", + "language.direction": "Direkto de leĝado", + "language.direction.ltr": "Dekstren", + "language.direction.rtl": "Maldesktren", + "language.locale": "Lokaĵaro de PHP", + "language.locale.warning": "Vi uzas tajloritan agordon de lokaĵaro. Bonvolu ŝanĝi viajn agordojn laŭmende en la lingva dosiero ĉe /site/languages", + "language.name": "Nomo", + "language.updated": "La lingvo estas ĝisdatigita", + + "languages": "Lingvoj", + "languages.default": "Defaŭlta lingvo", + "languages.empty": "Ankoraũ estas neniu lingvo", + "languages.secondary": "Kromlingvoj", + "languages.secondary.empty": "Ankoraŭ estas neniu kromlingvoj", + + "license": "Permisilo", + "license.buy": "Aĉeti permisilon", + "license.register": "Registriĝi", + "license.manage": "Manage your licenses", + "license.register.help": "Vi ricevis vian kodon de permisilo retpoŝte, post aĉeti ĝin. Bonvolu kopii kaj alglui ĝin por registriĝi.", + "license.register.label": "Bonvolu entajpi vian kodon de permisilo", + "license.register.success": "Dankon pro subteni Kirby", + "license.unregistered": "Ĉi tiu estas neregistrita kopio de Kirby", + "license.unregistered.label": "Unregistered", + + "link": "Ligilo", + "link.text": "Ligila teksto", + + "loading": "Ŝargante", + + "lock.unsaved": "Nekonservitaj ŝanĝoj", + "lock.unsaved.empty": "Ĉiuj ŝanĝoj estas nun konservitaj", + "lock.isLocked": "Nekonservitaj ŝanĝoj de {email}", + "lock.file.isLocked": "La dosiero estas ĉi-momente redaktata de {email}, kaj tial ne povas esti ŝanĝita", + "lock.page.isLocked": "La paĝo estas ĉi-momente redaktata de {email}, kaj tial ne povas esti ŝanĝita", + "lock.unlock": "Malŝlosi", + "lock.isUnlocked": "Viaj nekonservitaj ŝanĝoj estas ŝanĝitaj de alia uzanto. Vi povas elŝuti dosieron kun viaj ŝanĝoj por permane kunfandi ilin.", + + "login": "Log in", + "login.code.label.login": "Ensaluta kodo", + "login.code.label.password-reset": "Kodo por restarigi pasvorton", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "Se via retpoŝtadreso estas enregistrita, via kodo estis sendita retpoŝte", + "login.email.login.body": "Saluton {user.nameOrEmail},\n\nVi petis ensalutan kodon por la panelo de la retejo {site}.\nLa sekvanta kodo validos dum {timeout} minutoj:\n\n{code}\n\nSe vi ne petis ensalutan kodon, bonvolu ignori ĉi tiun mesaĝon, aŭ kontaktu vian sistem-administranton se vi havas demandojn.\nPro sekureco, bonvolu NE plusendi ĉi tiun mesaĝon.", + "login.email.login.subject": "Via ensaluta kodo", + "login.email.password-reset.body": "Saluton {user.nameOrEmail},\n\nVi petis kodon por restarigi vian pasvorton por la panelo de la retejo {site}.\nLa sekvanta kodo validos dum {timeout} minutoj:\n\n{code}\n\nSe vi ne petis kodon por restarigi vian pasvorton, bonvolu ignori ĉi tiun mesaĝon, aŭ kontaktu vian sistem-administranton se vi havas demandojn.\nPro sekureco, bonvolu NE plusendi ĉi tiun mesaĝon.", + "login.email.password-reset.subject": "Kodo por restarigi pasvorton", + "login.remember": "Daŭre tenu min ensalutita", + "login.reset": "Restarigi pasvorton", + "login.toggleText.code.email": "Ensaluti retpoŝte", + "login.toggleText.code.email-password": "Ensaluti per pasvorto", + "login.toggleText.password-reset.email": "Ĉu vi forgesis vian pasvorton?", + "login.toggleText.password-reset.email-password": "← Reen al ensaluto", + + "logout": "Elsaluti", + + "menu": "Menuo", + "meridiem": "atm/ptm", + "mime": "Tipo de aŭdvidaĵo", + "minutes": "Minutoj", + + "month": "Monato", + "months.april": "aprilo", + "months.august": "aŭgusto", + "months.december": "decembro", + "months.february": "februaro", + "months.january": "januaro", + "months.july": "julio", + "months.june": "junio", + "months.march": "marto", + "months.may": "majo", + "months.november": "novembro", + "months.october": "oktobro", + "months.september": "septembro", + + "more": "Pli", + "name": "Nomo", + "next": "Sekve", + "no": "ne", + "off": "ne", + "on": "jes", + "open": "Malfermi", + "open.newWindow": "Malfermi novan fenestron", + "options": "Opcioj", + "options.none": "Neniu opcio", + + "orientation": "Orientiĝo", + "orientation.landscape": "Horizontala", + "orientation.portrait": "Vertikala", + "orientation.square": "Kvadrata", + + "page.blueprint": "Ĉi tiu paĝo ankoraŭ ne havas planon. Vi povas difini planon ĉe /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Ŝanĝi URL", + "page.changeSlug.fromTitle": "Krei el titolo", + "page.changeStatus": "Ŝanĝi staton", + "page.changeStatus.position": "Bonvolu elekti ordon", + "page.changeStatus.select": "Elekti novan staton", + "page.changeTemplate": "Ŝanĝi ŝablonon", + "page.delete.confirm": "Ĉu vi certe volas forigi {title}?", + "page.delete.confirm.subpages": "Ĉi tiu paĝo havas subpaĝojn.
Ĉiuj subpaĝoj estos ankaŭ forigitaj.", + "page.delete.confirm.title": "Entajpu la titolon de la paĝo por konfirmi", + "page.draft.create": "Krei malneton", + "page.duplicate.appendix": "Kopii", + "page.duplicate.files": "Kopii dosierojn", + "page.duplicate.pages": "Kopii paĝojn", + "page.sort": "Ŝanĝi ordon", + "page.status": "Stato", + "page.status.draft": "Malneto", + "page.status.draft.description": "La paĝo estas malneto, kaj nur atingebla de ensalutitaj redaktantoj, aŭ per sekreta ligilo", + "page.status.listed": "Publika", + "page.status.listed.description": "La paĝo estas publika por ĉiuj ajn", + "page.status.unlisted": "Nelistata", + "page.status.unlisted.description": "La paĝo estas atingebla nur per URL", + + "pages": "Paĝoj", + "pages.empty": "Ankoraŭ neniu paĝo", + "pages.status.draft": "Malnetoj", + "pages.status.listed": "Publikigita", + "pages.status.unlisted": "Nelistata", + + "pagination.page": "Paĝo", + + "password": "Pasvorto", + "paste": "Alglui", + "paste.after": "Alglui post", + "pixel": "Pikselo", + "plugin": "Plugin", + "plugins": "Kromprogramoj", + "prev": "Antaŭe", + "preview": "Antaŭrigardi", + "remove": "Forigi", + "rename": "Ŝanĝi nomon", + "replace": "Anstataŭi", + "retry": "Provi denove", + "revert": "Malfari", + "revert.confirm": "Ĉu vi certe volas forigi ĉiujn nekonservitajn ŝanĝojn?", + + "role": "Rolo", + "role.admin.description": "La administranto havas ĉiujn rajtojn", + "role.admin.title": "Administranto", + "role.all": "Ĉiuj", + "role.empty": "Neniu uzanto havas ĉi tiun rolon", + "role.description.placeholder": "Neniu priskribo", + "role.nobody.description": "Ĉi tiu estas retrodefaŭlta rolo sen permesoj", + "role.nobody.title": "Neniu", + + "save": "Konservi", + "search": "Serĉi", + "search.min": "Entajpu {min} literojn por serĉi", + "search.all": "Montri ĉiujn", + "search.results.none": "Neniu rezulto", + + "section.required": "La sekcio estas deviga", + + "security": "Security", + "select": "Elekti", + "server": "Servilo", + "settings": "Agordoj", + "show": "Montri", + "site.blueprint": "La retejo ankoraŭ ne havas planon. Vi povas difini planon ĉe /site/blueprints/site.yml", + "size": "Grando", + "slug": "URL-nomo", + "sort": "Ordigi", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Titolo", + "template": "Ŝablono", + "today": "Hodiaŭ", + + "toolbar.button.code": "Kodo", + "toolbar.button.bold": "Grasa", + "toolbar.button.email": "Retpoŝto", + "toolbar.button.headings": "Titoloj", + "toolbar.button.heading.1": "Titolo 1", + "toolbar.button.heading.2": "Titolo 2", + "toolbar.button.heading.3": "Titolo 3", + "toolbar.button.heading.4": "Titolo 4", + "toolbar.button.heading.5": "Titolo 5", + "toolbar.button.heading.6": "Titolo 6", + "toolbar.button.italic": "Kursiva", + "toolbar.button.file": "Dosiero", + "toolbar.button.file.select": "Elekti dosieron", + "toolbar.button.file.upload": "Alŝuti dosieron", + "toolbar.button.link": "Ligilo", + "toolbar.button.paragraph": "Paragrafo", + "toolbar.button.strike": "Trastrekita", + "toolbar.button.ol": "Numerita listo", + "toolbar.button.underline": "Substrekita", + "toolbar.button.ul": "Bula listo", + + "translation.author": "Teamo Kirby", + "translation.direction": "ltr", + "translation.name": "Esperanto", + "translation.locale": "eo", + + "upload": "Alŝuti", + "upload.error.cantMove": "Ne eblis movi la alŝutita dosiero", + "upload.error.cantWrite": "Ne eblis registri la dosieron en la diskon", + "upload.error.default": "Ne eblis alŝuti la dosieron", + "upload.error.extension": "Alŝutado haltita pro la dosiersufikso", + "upload.error.formSize": "La alŝutita dosiero estas pli granda ol la direktivo MAX_FILE_SIZE indikata en la formularo", + "upload.error.iniPostSize": "La alŝutita dosiero estas pli granda ol la direktivo post_max_size de php.ini", + "upload.error.iniSize": "La alŝutita dosiero estas pli granda ol la direktivo upload_max_filesize de php.ini", + "upload.error.noFile": "Neniu dosiero alŝutita", + "upload.error.noFiles": "Neniuj dosieroj alŝutitaj", + "upload.error.partial": "La dosiero estis nur parte alŝutita", + "upload.error.tmpDir": "Mankas provizora dosierujo", + "upload.errors": "Eraro", + "upload.progress": "Alŝutante...", + + "url": "URL", + "url.placeholder": "https://ekzemplo.com", + + "user": "Uzanto", + "user.blueprint": "Vi povas difini pluajn sekciojn kaj kampojn de formularo por ĉi tiu rolo de uzanto ĉe /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Ŝanĝi retpoŝtadreson", + "user.changeLanguage": "Ŝanĝi lingvon", + "user.changeName": "Ŝangi la nomon de la uzanto", + "user.changePassword": "Ŝanĝi pasvorton", + "user.changePassword.new": "Nova pasvorto", + "user.changePassword.new.confirm": "Konfirmi la novan pasvorton...", + "user.changeRole": "Ŝanĝi rolon", + "user.changeRole.select": "Elekti novan rolon", + "user.create": "Aldoni novan uzanton", + "user.delete": "Forigi ĉi tiun uzanton", + "user.delete.confirm": "Ĉu vi certe volas forigi
{email}?", + + "users": "Uzantoj", + + "version": "Versio", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "Via konto", + "view.installation": "Instalado", + "view.languages": "Lingvoj", + "view.resetPassword": "Restarigi pasvorton", + "view.site": "Retejo", + "view.system": "Sistemo", + "view.users": "Uzantoj", + + "welcome": "Bonvenon", + "year": "Jaro", + "yes": "jes" } diff --git a/kirby/i18n/translations/es_419.json b/kirby/i18n/translations/es_419.json index 57d8b4e..cc2101f 100644 --- a/kirby/i18n/translations/es_419.json +++ b/kirby/i18n/translations/es_419.json @@ -1,573 +1,596 @@ { - "account.changeName": "Cambiar nombre", - "account.delete": "Eliminar cuenta", - "account.delete.confirm": "¿Realmente quieres eliminar tu cuenta? Tu sesión se cerrará inmediatamente. Tu cuenta no podrá ser recuperada. ", - - "add": "Agregar", - "author": "Autor", - "avatar": "Foto de perfil", - "back": "Regresar", - "cancel": "Cancelar", - "change": "Cambiar", - "close": "Cerrar", - "confirm": "De acuerdo", - "collapse": "Colapsar", - "collapse.all": "Colapsar todos", - "copy": "Copiar", - "copy.all": "Copiar todo", - "create": "Crear", - - "date": "Fecha", - "date.select": "Selecciona una fecha", - - "day": "Día", - "days.fri": "Vie", - "days.mon": "Lun", - "days.sat": "S\u00e1b", - "days.sun": "Dom", - "days.thu": "Jue", - "days.tue": "Mar", - "days.wed": "Mi\u00e9", - - "debugging": "Debugging", - - "delete": "Eliminar", - "delete.all": "Eliminar todos", - - "dialog.files.empty": "No has seleccionado ningún archivo", - "dialog.pages.empty": "No has seleccionado ninguna página", - "dialog.users.empty": "No has seleccionado ningún usuario", - - "dimensions": "Dimensiones", - "disabled": "Deshabilitado", - "discard": "Descartar", - "download": "Descargar", - "duplicate": "Duplicar", - - "edit": "Editar", - - "email": "Correo Electrónico", - "email.placeholder": "correo@ejemplo.com", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Ambiente", - - "error.access.code": "Código inválido", - "error.access.login": "Ingreso inválido", - "error.access.panel": "No tienes permitido acceder al panel", - "error.access.view": "No tienes permiso para acceder a esta parte del panel", - - "error.avatar.create.fail": "No se pudo subir la foto de perfil", - "error.avatar.delete.fail": "No se pudo eliminar la foto de perfil", - "error.avatar.dimensions.invalid": "Por favor, mantén el ancho y la altura de la imagen de perfil por debajo de 3000 pixeles", - "error.avatar.mime.forbidden": "La foto de perfil debe de ser un archivo JPG o PNG", - - "error.blueprint.notFound": "El blueprint \"{name}\" no se pudo cargar.", - - "error.blocks.max.plural": "No debes añadir más de {max} bloques", - "error.blocks.max.singular": "No debes añadir más de un bloque", - "error.blocks.min.plural": "Debes añadir al menos {min} bloques ", - "error.blocks.min.singular": "Debes añadir al menos un bloque", - "error.blocks.validation": "Hay un error en el bloque {index}", - - "error.email.preset.notFound": "El preajuste de email \"{name}\" no se pudo encontrar.", - - "error.field.converter.invalid": "Convertidor inválido \"{converter}\"", - - "error.file.changeName.empty": "El nombre no debe estar vacío", - "error.file.changeName.permission": "No tienes permitido cambiar el nombre de \"{filename}\"", - "error.file.duplicate": "Ya existe un archivo con el nombre \"{filename}\".", - "error.file.extension.forbidden": "La extensión \"{extension}\" no está permitida.", - "error.file.extension.invalid": "Extensión inválida: {extension}", - "error.file.extension.missing": "Falta la extensión para \"{filename}\".", - "error.file.maxheight": "La altura de la imagen no debe exceder {height} pixeles", - "error.file.maxsize": "El archivo es muy grande", - "error.file.maxwidth": "El ancho de la imagen no debe exceder {width} pixeles", - "error.file.mime.differs": "El archivo cargado debe ser del mismo tipo mime \"{mime}\".", - "error.file.mime.forbidden": "El tipo de medios \"{mime}\" no está permitido.", - "error.file.mime.invalid": "Tipo invalido de mime: {mime}", - "error.file.mime.missing": "No se puede detectar el tipo de medio para \"{filename}\".", - "error.file.minheight": "La altura de la imagen debe ser de al menos {height} pixeles", - "error.file.minsize": "El archivo es muy pequeño", - "error.file.minwidth": "El ancho de la imagen debe ser de al menos {width} pixeles", - "error.file.name.missing": "El nombre del archivo no debe estar vacío.", - "error.file.notFound": "El archivo \"{filename}\" no pudo ser encontrado.", - "error.file.orientation": "La orientación de la imagen debe ser \"{orientation}\"", - "error.file.type.forbidden": "No está permitido subir archivos {type}.", - "error.file.type.invalid": "Tipo de archivo inválido: {type}", - "error.file.undefined": "El archivo no se puede encontrar", - - "error.form.incomplete": "Por favor, corrige todos los errores del formulario...", - "error.form.notSaved": "No se pudo guardar el formulario", - - "error.language.code": "Por favor introduce un código válido para el idioma", - "error.language.duplicate": "El idioma ya existe", - "error.language.name": "Por favor introduce un nombre válido para el idioma", - "error.language.notFound": "No se pudo encontrar el idioma", - - "error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}", - "error.layout.validation.settings": "There's an error in layout {index} settings", - - "error.license.format": "Por favor introduce una llave de licencia válida", - "error.license.email": "Por favor ingresa un correo electrónico valido", - "error.license.verification": "La licencia no pude ser verificada", - - "error.offline": "El Panel se encuentra fuera de linea ", - - "error.page.changeSlug.permission": "No está permitido cambiar el apéndice de URL para \"{slug}\".", - "error.page.changeStatus.incomplete": "La página tiene errores y no puede ser publicada.", - "error.page.changeStatus.permission": "El estado de esta página no se puede cambiar.", - "error.page.changeStatus.toDraft.invalid": "La página \"{slug}\" no se puede convertir en un borrador", - "error.page.changeTemplate.invalid": "La plantilla para la página \"{slug}\" no se puede cambiar", - "error.page.changeTemplate.permission": "No está permitido cambiar la plantilla para \"{slug}\"", - "error.page.changeTitle.empty": "El título no debe estar vacío.", - "error.page.changeTitle.permission": "No tienes permiso para cambiar el título de \"{slug}\"", - "error.page.create.permission": "No tienes permiso para crear \"{slug}\"", - "error.page.delete": "La página \"{slug}\" no se puede eliminar", - "error.page.delete.confirm": "Por favor, introduce el título de la página para confirmar", - "error.page.delete.hasChildren": "La página tiene subpáginas y no se puede eliminar", - "error.page.delete.permission": "No tienes permiso para borrar \"{slug}\"", - "error.page.draft.duplicate": "Ya existe un borrador de página con el apéndice de URL \"{slug}\"", - "error.page.duplicate": "Ya existe una página con el apéndice de URL \"{slug}\"", - "error.page.duplicate.permission": "No tienes permitido duplicar \"{slug}\"", - "error.page.notFound": "La página \"{slug}\" no se encuentra", - "error.page.num.invalid": "Por favor, introduce un número de posición válido. Los números no deben ser negativos.", - "error.page.slug.invalid": "Please enter a valid URL appendix", - "error.page.slug.maxlength": "Slug length must be less than \"{length}\" characters", - "error.page.sort.permission": "La página \"{slug}\" no se puede ordenar", - "error.page.status.invalid": "Por favor, establece una estado de página válido", - "error.page.undefined": "La p\u00e1gina no fue encontrada", - "error.page.update.permission": "No tienes permiso para actualizar \"{slug}\"", - - "error.section.files.max.plural": "No debes agregar más de {max} archivos a la sección \"{section}\"", - "error.section.files.max.singular": "No debes agregar más de un archivo a la sección \"{section}\"", - "error.section.files.min.plural": "La sección \"{section}\" requiere al menos {min} archivos", - "error.section.files.min.singular": "La sección \"{section}\" requiere al menos un archivo", - - "error.section.pages.max.plural": "No debes agregar más de {max} páginas a la sección \"{section}\"", - "error.section.pages.max.singular": "No debes agregar más de una página a la sección \"{section}\"", - "error.section.pages.min.plural": "La sección \"{section}\" requiere al menos {min} páginas", - "error.section.pages.min.singular": "La sección \"{section}\" requiere al menos una página", - - "error.section.notLoaded": "La sección \"{name}\" no se pudo cargar", - "error.section.type.invalid": "La sección \"{type}\" no es valida", - - "error.site.changeTitle.empty": "El título no debe estar vacío.", - "error.site.changeTitle.permission": "No tienes permiso para cambiar el título del sitio", - "error.site.update.permission": "No tienes permiso de actualizar el sitio", - - "error.template.default.notFound": "La plantilla predeterminada no existe", - - "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "No tienes permiso para cambiar el email del usuario \"{name}\"", - "error.user.changeLanguage.permission": "No tienes permiso para cambiar el idioma del usuario \"{name}\"", - "error.user.changeName.permission": "No tienes permiso para cambiar el nombre del usuario \"{name}\"", - "error.user.changePassword.permission": "No tienes permiso para cambiar la contraseña del usuario \"{name}\"", - "error.user.changeRole.lastAdmin": "El rol del último administrador no puede ser cambiado", - "error.user.changeRole.permission": "No tienes permiso para cambiar el rol del usuario \"{name}\"", - "error.user.changeRole.toAdmin": "No tienes permitido promover a alguien al rol de admin", - "error.user.create.permission": "No tienes permiso de crear este usuario", - "error.user.delete": "El ususario no pudo ser eliminado", - "error.user.delete.lastAdmin": "Usted no puede borrar el \u00faltimo administrador", - "error.user.delete.lastUser": "El último usuario no puede ser borrado", - "error.user.delete.permission": "Usted no tiene permitido borrar este usuario", - "error.user.duplicate": "Ya existe un usuario con el email \"{email}\"", - "error.user.email.invalid": "Por favor ingresa un correo electrónico valido", - "error.user.language.invalid": "Por favor ingresa un idioma valido", - "error.user.notFound": "El usuario no pudo ser encontrado", - "error.user.password.invalid": "Por favor ingresa una contraseña valida. Las contraseñas deben tener al menos 8 caracteres de largo.", - "error.user.password.notSame": "Por favor confirma la contrase\u00f1a", - "error.user.password.undefined": "El usuario no tiene contraseña", - "error.user.password.wrong": "Contraseña incorrecta", - "error.user.role.invalid": "Por favor ingresa un rol valido", - "error.user.undefined": "El usuario no pudo ser encontrado", - "error.user.update.permission": "No tienes permiso para actualizar al usuario \"{name}\"", - - "error.validation.accepted": "Por favor, confirma", - "error.validation.alpha": "Por favor ingrese solo caracteres entre a-z", - "error.validation.alphanum": "Por favor ingrese solo caracteres entre a-z o números entre 0-9", - "error.validation.between": "Por favor ingrese valores entre \"{min}\" y \"{max}\"", - "error.validation.boolean": "Por favor confirme o niegue", - "error.validation.contains": "Por favor ingrese valores que contengan \"{needle}\"", - "error.validation.date": "Por favor ingresa una fecha válida", - "error.validation.date.after": "Por favor introduce una fecha posterior a {date}", - "error.validation.date.before": "Por favor introduce una fecha anterior a {date}", - "error.validation.date.between": "Por favor introduce un número entre {min} y {max}", - "error.validation.denied": "Por favor niegue", - "error.validation.different": "EL valor no debe ser \"{other}\"", - "error.validation.email": "Por favor ingresa un correo electrónico valido", - "error.validation.endswith": "El valor no debe terminar con \"{end}\"", - "error.validation.filename": "Por favor ingresa un nombre de archivo válido", - "error.validation.in": "Por favor ingresa uno de los siguientes: ({in})", - "error.validation.integer": "Por favor ingresa un entero válido", - "error.validation.ip": "Por favor ingresa una dirección IP válida", - "error.validation.less": "Por favor ingresa un valor menor a {max}", - "error.validation.match": "El valor no coincide con el patrón esperado", - "error.validation.max": "Por favor ingresa un valor menor o igual a {max}", - "error.validation.maxlength": "Por favor ingresa un valor mas corto. (max. {max} caracteres)", - "error.validation.maxwords": "Por favor ingresa no mas de {max} palabra(s)", - "error.validation.min": "Por favor ingresa un valor mayor o igual a {min}", - "error.validation.minlength": "Por favor ingresa un valor mas largo. (min. {min} caracteres)", - "error.validation.minwords": "Por favor ingresa al menos {min} palabra(s)", - "error.validation.more": "Por favor ingresa un valor mayor a {min}", - "error.validation.notcontains": "Por favor ingresa un valor que no contenga \"{needle}\"", - "error.validation.notin": "Por favor no ingreses ninguno de las siguientes: ({notIn})", - "error.validation.option": "Por favor selecciona una de las opciones válidas", - "error.validation.num": "Por favor ingresa un numero válido", - "error.validation.required": "Por favor ingresa algo", - "error.validation.same": "Por favor ingresa \"{other}\"", - "error.validation.size": "El tamaño del valor debe ser \"{size}\"", - "error.validation.startswith": "El valor debe comenzar con \"{start}\"", - "error.validation.time": "Por favor ingresa una hora válida", - "error.validation.time.after": "Por favor ingresa una fecha después de {time}", - "error.validation.time.before": "Por favor ingresa una fecha antes de {time}", - "error.validation.time.between": "Por favor ingresa un fecha entre {min} y {max}", - "error.validation.url": "Por favor ingresa un URL válido", - - "expand": "Expandir", - "expand.all": "Expandir todo", - - "field.required": "Este campo es requerido", - "field.blocks.changeType": "Cambiar tipo", - "field.blocks.code.name": "Código", - "field.blocks.code.language": "Idioma", - "field.blocks.code.placeholder": "Tu código...", - "field.blocks.delete.confirm": "¿Seguro que quieres eliminar este bloque?", - "field.blocks.delete.confirm.all": "¿Seguro que quieres eliminar todos los bloques?", - "field.blocks.delete.confirm.selected": "¿Seguro que quieres eliminar los bloques seleccionados?", - "field.blocks.empty": "No hay bloques aún", - "field.blocks.fieldsets.label": "Por favor selecciona un tipo de bloque...", - "field.blocks.fieldsets.paste": "Presiona {{ shortcut }}para pegar/importar bloques en tu portapapeles ", - "field.blocks.gallery.name": "Galería", - "field.blocks.gallery.images.empty": "No hay imágenes aún", - "field.blocks.gallery.images.label": "Imágenes", - "field.blocks.heading.level": "Nivel", - "field.blocks.heading.name": "Encabezado", - "field.blocks.heading.text": "Texto", - "field.blocks.heading.placeholder": "Encabezado...", - "field.blocks.image.alt": "Texto alternativo", - "field.blocks.image.caption": "Leyenda", - "field.blocks.image.crop": "Cortar", - "field.blocks.image.link": "Enlace", - "field.blocks.image.location": "Ubicación", - "field.blocks.image.name": "Imágen", - "field.blocks.image.placeholder": "Selecciona una imagen", - "field.blocks.image.ratio": "Proporción", - "field.blocks.image.url": "URL de imágen", - "field.blocks.line.name": "Linea", - "field.blocks.list.name": "Lista", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Texto", - "field.blocks.markdown.placeholder": "Markdown...", - "field.blocks.quote.name": "Cita", - "field.blocks.quote.text.label": "Texto", - "field.blocks.quote.text.placeholder": "Cita...", - "field.blocks.quote.citation.label": "Citation", - "field.blocks.quote.citation.placeholder": "Por ...", - "field.blocks.text.name": "Texto", - "field.blocks.text.placeholder": "Text …", - "field.blocks.video.caption": "Leyenda", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Enter a video URL", - "field.blocks.video.url.label": "Video-URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Aún no ha seleccionado ningún archivo", - - "field.layout.delete": "Delete layout", - "field.layout.delete.confirm": "Do you really want to delete this layout?", - "field.layout.empty": "No rows yet", - "field.layout.select": "Select a layout", - - "field.pages.empty": "Aún no ha seleccionado ningúna pagina", - "field.structure.delete.confirm": "\u00bfEn realidad desea borrar esta entrada?", - "field.structure.empty": "A\u00fan no existen entradas.", - "field.users.empty": "Aún no ha seleccionado ningún usuario", - - "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "\u00bfEst\u00e1s seguro que deseas eliminar este archivo?", - "file.sort": "Change position", - - "files": "Archivos", - "files.empty": "Aún no existen archivos", - - "hide": "Hide", - "hour": "Hora", - "import": "Import", - "info": "Info", - "insert": "Insertar", - "insert.after": "Insert after", - "insert.before": "Insert before", - "install": "Instalar", - - "installation": "Instalación", - "installation.completed": "El panel ha sido instalado.", - "installation.disabled": "El instalador del panel está deshabilitado en servidores públicos por defecto. Ejecute el instalador en una máquina local o habilítelo con la opción panel.install.", - "installation.issues.accounts": "La carpeta /site/accounts no existe o no posee permisos de escritura.", - "installation.issues.content": "La carpeta /content no existe o no posee permisos de escritura.", - "installation.issues.curl": "Se requiere la extensión CURL.", - "installation.issues.headline": "El panel no puede ser instalado.", - "installation.issues.mbstring": "Se requiere la extensión MB String.", - "installation.issues.media": "La carpeta /media no existe o no posee permisos de escritura.", - "installation.issues.php": "Asegurese de estar usando PHP 7+", - "installation.issues.server": "Kirby requiere Apache, Nginx, Caddy", - "installation.issues.sessions": "La carpeta /site/sessions no existe o no posee permisos de escritura.", - - "language": "Idioma", - "language.code": "Código", - "language.convert": "Hacer por defecto", - "language.convert.confirm": "

Realmente deseas convertir {name} al idioma por defecto? Esta acción no se puede deshacer.

Si {name} tiene contenido sin traducir, no habrá vuelta atras y tu sitio puede quedar con partes sin contenido.

", - "language.create": "Añadir nuevo idioma", - "language.delete.confirm": "

", - "language.deleted": "El idioma ha sido borrado", - "language.direction": "Dirección de lectura", - "language.direction.ltr": "De Izquierda a derecha", - "language.direction.rtl": "De derecha a izquierda", - "language.locale": "Cadena de localización PHP", - "language.locale.warning": "Estas utilizando un configuración local. Por favor modifícalo en el archivo del lenguaje en /site/languages", - "language.name": "Nombre", - "language.updated": "El idioma a sido actualizado", - - "languages": "Idiomas", - "languages.default": "Idioma por defecto", - "languages.empty": "Todavía no hay idiomas", - "languages.secondary": "Idiomas secundarios", - "languages.secondary.empty": "Todavía no hay idiomas secundarios", - - "license": "Licencia", - "license.buy": "Comprar una licencia", - "license.register": "Registrar", - "license.manage": "Manage your licenses", - "license.register.help": "Recibió su código de licencia después de la compra por correo electrónico. Por favor copie y pegue para registrarse.", - "license.register.label": "Por favor, ingresa tu código de licencia", - "license.register.success": "Gracias por apoyar a Kirby", - "license.unregistered": "Este es un demo no registrado de Kirby", - "license.unregistered.label": "Unregistered", - - "link": "Enlace", - "link.text": "Texto de Enlace", - - "loading": "Cargando", - - "lock.unsaved": "Cambios sin guardar", - "lock.unsaved.empty": "No hay más cambios sin guardar", - "lock.isLocked": "Cambios sin guardar por {email}", - "lock.file.isLocked": "El archivo está siendo actualmente editado por {email} y no puede ser cambiado.", - "lock.page.isLocked": "La página está siendo actualmente editada por {email} y no puede ser cambiada.", - "lock.unlock": "Desbloquear", - "lock.isUnlocked": "Tus cambios sin guardar han sido sobrescritos por otro usuario. Puedes descargar los cambios y fusionarlos manualmente.", - - "login": "Iniciar sesión", - "login.code.label.login": "Login code", - "login.code.label.password-reset": "Password reset code", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "If your email address is registered, the requested code was sent via email.", - "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.login.subject": "Your login code", - "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.password-reset.subject": "Your password reset code", - "login.remember": "Mantener mi sesión iniciada", - "login.reset": "Reset password", - "login.toggleText.code.email": "Login via email", - "login.toggleText.code.email-password": "Login with password", - "login.toggleText.password-reset.email": "Forgot your password?", - "login.toggleText.password-reset.email-password": "← Back to login", - - "logout": "Cerrar sesi\u00f3n", - - "menu": "Menù", - "meridiem": "AM/PM", - "mime": "Tipos de medios", - "minutes": "Minutos", - - "month": "Mes", - "months.april": "Abril", - "months.august": "Agosto", - "months.december": "Diciembre", - "months.february": "Febrero", - "months.january": "Enero", - "months.july": "Julio", - "months.june": "Junio", - "months.march": "Marzo", - "months.may": "Mayo", - "months.november": "Noviembre", - "months.october": "Octubre", - "months.september": "Septiembre", - - "more": "Màs", - "name": "Nombre", - "next": "Siguiente", - "no": "no", - "off": "Apagado", - "on": "Encendido", - "open": "Abrir", - "open.newWindow": "Open in new window", - "options": "Opciones", - "options.none": "No options", - - "orientation": "Orientación", - "orientation.landscape": "Paisaje", - "orientation.portrait": "Retrato", - "orientation.square": "Diapositiva", - - "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Cambiar URL", - "page.changeSlug.fromTitle": "Crear a partir del t\u00edtulo", - "page.changeStatus": "Cambiar estado", - "page.changeStatus.position": "Por favor selecciona una posición", - "page.changeStatus.select": "Selecciona un nuevo estado", - "page.changeTemplate": "Cambiar plantilla", - "page.delete.confirm": "¿Estás seguro que deseas eliminar {title}?", - "page.delete.confirm.subpages": "Esta página tiene subpáginas.
Todas las súbpaginas serán eliminadas también.", - "page.delete.confirm.title": "Introduce el título de la página para confirmar", - "page.draft.create": "Crear borrador", - "page.duplicate.appendix": "Copiar", - "page.duplicate.files": "Copiar archivos", - "page.duplicate.pages": "Copiar páginas", - "page.sort": "Change position", - "page.status": "Estado", - "page.status.draft": "Borrador", - "page.status.draft.description": "The page is in draft mode and only visible for logged in editors or via secret link", - "page.status.listed": "Pública", - "page.status.listed.description": "La página es pública para cualquiera", - "page.status.unlisted": "No publicada", - "page.status.unlisted.description": "La página sólo es accesible vía URL", - - "pages": "Páginas", - "pages.empty": "No hay páginas aún", - "pages.status.draft": "Borradores", - "pages.status.listed": "Publicado", - "pages.status.unlisted": "No publicado", - - "pagination.page": "Página", - - "password": "Contrase\u00f1a", - "paste": "Paste", - "paste.after": "Paste after", - "pixel": "Pixel", - "plugins": "Plugins", - "prev": "Anterior", - "preview": "Preview", - "remove": "Eliminar", - "rename": "Renombrar", - "replace": "Reemplazar", - "retry": "Reintentar", - "revert": "Revertir", - "revert.confirm": "Do you really want to delete all unsaved changes?", - - "role": "Rol", - "role.admin.description": "El administrador tiene todos los derechos", - "role.admin.title": "Administrador", - "role.all": "Todos", - "role.empty": "No hay usuarios con este rol", - "role.description.placeholder": "Sin descripción", - "role.nobody.description": "Este es un rol alternativo sin permisos", - "role.nobody.title": "Nadie", - - "save": "Guardar", - "search": "Buscar", - "search.min": "Enter {min} characters to search", - "search.all": "Show all", - "search.results.none": "No results", - - "section.required": "Esta sección es requerida", - - "security": "Security", - "select": "Seleccionar", - "server": "Server", - "settings": "Ajustes", - "show": "Show", - "site.blueprint": "The site has no blueprint yet. You can define the setup in /site/blueprints/site.yml", - "size": "Tamaño", - "slug": "Apéndice URL", - "sort": "Ordenar", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Título", - "template": "Plantilla", - "today": "Hoy", - - "toolbar.button.code": "Código", - "toolbar.button.bold": "Negrita", - "toolbar.button.email": "Email", - "toolbar.button.headings": "Encabezados", - "toolbar.button.heading.1": "Encabezado 1", - "toolbar.button.heading.2": "Encabezado 2", - "toolbar.button.heading.3": "Encabezado 3", - "toolbar.button.heading.4": "Encabezado 4", - "toolbar.button.heading.5": "Encabezado 5", - "toolbar.button.heading.6": "Encabezado 6", - "toolbar.button.italic": "Texto en It\u00e1licas", - "toolbar.button.file": "Archivo", - "toolbar.button.file.select": "Selecciona un archivo", - "toolbar.button.file.upload": "Sube un archivo", - "toolbar.button.link": "Enlace", - "toolbar.button.paragraph": "Paragraph", - "toolbar.button.strike": "Strike-through", - "toolbar.button.ol": "Lista en orden", - "toolbar.button.underline": "Underline", - "toolbar.button.ul": "Lista de viñetas", - - "translation.author": "Equipo Kirby", - "translation.direction": "ltr", - "translation.name": "Español (América Latina)", - "translation.locale": "es_419", - - "upload": "Subir", - "upload.error.cantMove": "El archivo subido no puede ser movido", - "upload.error.cantWrite": "Error al escribir el archivo en el disco", - "upload.error.default": "El archivo no pudo ser subido", - "upload.error.extension": "Subida de archivo detenida por la extensión", - "upload.error.formSize": "El archivo subido excede la directiva MAX_FILE_SIZE que fue especificada en el formulario", - "upload.error.iniPostSize": "El archivo subido excede la directiva post_max_size directive en php.ini", - "upload.error.iniSize": "El archivo subido excede la directiva upload_max_filesize en php.ini", - "upload.error.noFile": "Ningún archivo ha sido subido", - "upload.error.noFiles": "Ningún archivo ha sido subido", - "upload.error.partial": "El archivo ha sido subido solo parcialmente", - "upload.error.tmpDir": "No se encuentra la carpeta temporal", - "upload.errors": "Error", - "upload.progress": "Subiendo...", - - "url": "Url", - "url.placeholder": "https://ejemplo.com", - - "user": "Usuario", - "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Cambiar correo electrónico", - "user.changeLanguage": "Cambiar idioma", - "user.changeName": "Renombrar este usuario", - "user.changePassword": "Cambiar la contraseña", - "user.changePassword.new": "Nueva contraseña", - "user.changePassword.new.confirm": "Confirma la nueva contraseña...", - "user.changeRole": "Cambiar rol", - "user.changeRole.select": "Selecciona un nuevo rol", - "user.create": "Agregar un nuevo usuario", - "user.delete": "Eliminar este usuario", - "user.delete.confirm": "¿Estás seguro que deseas eliminar
{email}?", - - "users": "Usuarios", - - "version": "Versión", - - "view.account": "Tu cuenta", - "view.installation": "Instalaci\u00f3n", - "view.languages": "Idiomas", - "view.resetPassword": "Reset password", - "view.site": "Sitio", - "view.system": "System", - "view.users": "Usuarios", - - "welcome": "Bienvenido", - "year": "Año", - "yes": "yes" + "account.changeName": "Cambiar nombre", + "account.delete": "Eliminar cuenta", + "account.delete.confirm": "¿Realmente quieres eliminar tu cuenta? Tu sesión se cerrará inmediatamente. Tu cuenta no podrá ser recuperada. ", + + "add": "Agregar", + "author": "Autor", + "avatar": "Foto de perfil", + "back": "Regresar", + "cancel": "Cancelar", + "change": "Cambiar", + "close": "Cerrar", + "confirm": "De acuerdo", + "collapse": "Colapsar", + "collapse.all": "Colapsar todos", + "copy": "Copiar", + "copy.all": "Copiar todo", + "create": "Crear", + + "date": "Fecha", + "date.select": "Selecciona una fecha", + + "day": "Día", + "days.fri": "Vie", + "days.mon": "Lun", + "days.sat": "S\u00e1b", + "days.sun": "Dom", + "days.thu": "Jue", + "days.tue": "Mar", + "days.wed": "Mi\u00e9", + + "debugging": "Debugging", + + "delete": "Eliminar", + "delete.all": "Eliminar todos", + + "dialog.files.empty": "No has seleccionado ningún archivo", + "dialog.pages.empty": "No has seleccionado ninguna página", + "dialog.users.empty": "No has seleccionado ningún usuario", + + "dimensions": "Dimensiones", + "disabled": "Deshabilitado", + "discard": "Descartar", + "download": "Descargar", + "duplicate": "Duplicar", + + "edit": "Editar", + + "email": "Correo Electrónico", + "email.placeholder": "correo@ejemplo.com", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Ambiente", + + "error.access.code": "Código inválido", + "error.access.login": "Ingreso inválido", + "error.access.panel": "No tienes permitido acceder al panel", + "error.access.view": "No tienes permiso para acceder a esta parte del panel", + + "error.avatar.create.fail": "No se pudo subir la foto de perfil", + "error.avatar.delete.fail": "No se pudo eliminar la foto de perfil", + "error.avatar.dimensions.invalid": "Por favor, mantén el ancho y la altura de la imagen de perfil por debajo de 3000 pixeles", + "error.avatar.mime.forbidden": "La foto de perfil debe de ser un archivo JPG o PNG", + + "error.blueprint.notFound": "El blueprint \"{name}\" no se pudo cargar.", + + "error.blocks.max.plural": "No debes añadir más de {max} bloques", + "error.blocks.max.singular": "No debes añadir más de un bloque", + "error.blocks.min.plural": "Debes añadir al menos {min} bloques ", + "error.blocks.min.singular": "Debes añadir al menos un bloque", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "El preajuste de email \"{name}\" no se pudo encontrar.", + + "error.field.converter.invalid": "Convertidor inválido \"{converter}\"", + + "error.file.changeName.empty": "El nombre no debe estar vacío", + "error.file.changeName.permission": "No tienes permitido cambiar el nombre de \"{filename}\"", + "error.file.duplicate": "Ya existe un archivo con el nombre \"{filename}\".", + "error.file.extension.forbidden": "La extensión \"{extension}\" no está permitida.", + "error.file.extension.invalid": "Extensión inválida: {extension}", + "error.file.extension.missing": "Falta la extensión para \"{filename}\".", + "error.file.maxheight": "La altura de la imagen no debe exceder {height} pixeles", + "error.file.maxsize": "El archivo es muy grande", + "error.file.maxwidth": "El ancho de la imagen no debe exceder {width} pixeles", + "error.file.mime.differs": "El archivo cargado debe ser del mismo tipo mime \"{mime}\".", + "error.file.mime.forbidden": "El tipo de medios \"{mime}\" no está permitido.", + "error.file.mime.invalid": "Tipo invalido de mime: {mime}", + "error.file.mime.missing": "No se puede detectar el tipo de medio para \"{filename}\".", + "error.file.minheight": "La altura de la imagen debe ser de al menos {height} pixeles", + "error.file.minsize": "El archivo es muy pequeño", + "error.file.minwidth": "El ancho de la imagen debe ser de al menos {width} pixeles", + "error.file.name.missing": "El nombre del archivo no debe estar vacío.", + "error.file.notFound": "El archivo \"{filename}\" no pudo ser encontrado.", + "error.file.orientation": "La orientación de la imagen debe ser \"{orientation}\"", + "error.file.type.forbidden": "No está permitido subir archivos {type}.", + "error.file.type.invalid": "Tipo de archivo inválido: {type}", + "error.file.undefined": "El archivo no se puede encontrar", + + "error.form.incomplete": "Por favor, corrige todos los errores del formulario...", + "error.form.notSaved": "No se pudo guardar el formulario", + + "error.language.code": "Por favor introduce un código válido para el idioma", + "error.language.duplicate": "El idioma ya existe", + "error.language.name": "Por favor introduce un nombre válido para el idioma", + "error.language.notFound": "No se pudo encontrar el idioma", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "There's an error in layout {index} settings", + + "error.license.format": "Por favor introduce una llave de licencia válida", + "error.license.email": "Por favor ingresa un correo electrónico valido", + "error.license.verification": "La licencia no pude ser verificada", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "El Panel se encuentra fuera de linea ", + + "error.page.changeSlug.permission": "No está permitido cambiar el apéndice de URL para \"{slug}\".", + "error.page.changeStatus.incomplete": "La página tiene errores y no puede ser publicada.", + "error.page.changeStatus.permission": "El estado de esta página no se puede cambiar.", + "error.page.changeStatus.toDraft.invalid": "La página \"{slug}\" no se puede convertir en un borrador", + "error.page.changeTemplate.invalid": "La plantilla para la página \"{slug}\" no se puede cambiar", + "error.page.changeTemplate.permission": "No está permitido cambiar la plantilla para \"{slug}\"", + "error.page.changeTitle.empty": "El título no debe estar vacío.", + "error.page.changeTitle.permission": "No tienes permiso para cambiar el título de \"{slug}\"", + "error.page.create.permission": "No tienes permiso para crear \"{slug}\"", + "error.page.delete": "La página \"{slug}\" no se puede eliminar", + "error.page.delete.confirm": "Por favor, introduce el título de la página para confirmar", + "error.page.delete.hasChildren": "La página tiene subpáginas y no se puede eliminar", + "error.page.delete.permission": "No tienes permiso para borrar \"{slug}\"", + "error.page.draft.duplicate": "Ya existe un borrador de página con el apéndice de URL \"{slug}\"", + "error.page.duplicate": "Ya existe una página con el apéndice de URL \"{slug}\"", + "error.page.duplicate.permission": "No tienes permitido duplicar \"{slug}\"", + "error.page.notFound": "La página \"{slug}\" no se encuentra", + "error.page.num.invalid": "Por favor, introduce un número de posición válido. Los números no deben ser negativos.", + "error.page.slug.invalid": "Please enter a valid URL appendix", + "error.page.slug.maxlength": "Slug length must be less than \"{length}\" characters", + "error.page.sort.permission": "La página \"{slug}\" no se puede ordenar", + "error.page.status.invalid": "Por favor, establece una estado de página válido", + "error.page.undefined": "La p\u00e1gina no fue encontrada", + "error.page.update.permission": "No tienes permiso para actualizar \"{slug}\"", + + "error.section.files.max.plural": "No debes agregar más de {max} archivos a la sección \"{section}\"", + "error.section.files.max.singular": "No debes agregar más de un archivo a la sección \"{section}\"", + "error.section.files.min.plural": "La sección \"{section}\" requiere al menos {min} archivos", + "error.section.files.min.singular": "La sección \"{section}\" requiere al menos un archivo", + + "error.section.pages.max.plural": "No debes agregar más de {max} páginas a la sección \"{section}\"", + "error.section.pages.max.singular": "No debes agregar más de una página a la sección \"{section}\"", + "error.section.pages.min.plural": "La sección \"{section}\" requiere al menos {min} páginas", + "error.section.pages.min.singular": "La sección \"{section}\" requiere al menos una página", + + "error.section.notLoaded": "La sección \"{name}\" no se pudo cargar", + "error.section.type.invalid": "La sección \"{type}\" no es valida", + + "error.site.changeTitle.empty": "El título no debe estar vacío.", + "error.site.changeTitle.permission": "No tienes permiso para cambiar el título del sitio", + "error.site.update.permission": "No tienes permiso de actualizar el sitio", + + "error.template.default.notFound": "La plantilla predeterminada no existe", + + "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "No tienes permiso para cambiar el email del usuario \"{name}\"", + "error.user.changeLanguage.permission": "No tienes permiso para cambiar el idioma del usuario \"{name}\"", + "error.user.changeName.permission": "No tienes permiso para cambiar el nombre del usuario \"{name}\"", + "error.user.changePassword.permission": "No tienes permiso para cambiar la contraseña del usuario \"{name}\"", + "error.user.changeRole.lastAdmin": "El rol del último administrador no puede ser cambiado", + "error.user.changeRole.permission": "No tienes permiso para cambiar el rol del usuario \"{name}\"", + "error.user.changeRole.toAdmin": "No tienes permitido promover a alguien al rol de admin", + "error.user.create.permission": "No tienes permiso de crear este usuario", + "error.user.delete": "El ususario no pudo ser eliminado", + "error.user.delete.lastAdmin": "Usted no puede borrar el \u00faltimo administrador", + "error.user.delete.lastUser": "El último usuario no puede ser borrado", + "error.user.delete.permission": "Usted no tiene permitido borrar este usuario", + "error.user.duplicate": "Ya existe un usuario con el email \"{email}\"", + "error.user.email.invalid": "Por favor ingresa un correo electrónico valido", + "error.user.language.invalid": "Por favor ingresa un idioma valido", + "error.user.notFound": "El usuario no pudo ser encontrado", + "error.user.password.invalid": "Por favor ingresa una contraseña valida. Las contraseñas deben tener al menos 8 caracteres de largo.", + "error.user.password.notSame": "Por favor confirma la contrase\u00f1a", + "error.user.password.undefined": "El usuario no tiene contraseña", + "error.user.password.wrong": "Contraseña incorrecta", + "error.user.role.invalid": "Por favor ingresa un rol valido", + "error.user.undefined": "El usuario no pudo ser encontrado", + "error.user.update.permission": "No tienes permiso para actualizar al usuario \"{name}\"", + + "error.validation.accepted": "Por favor, confirma", + "error.validation.alpha": "Por favor ingrese solo caracteres entre a-z", + "error.validation.alphanum": "Por favor ingrese solo caracteres entre a-z o números entre 0-9", + "error.validation.between": "Por favor ingrese valores entre \"{min}\" y \"{max}\"", + "error.validation.boolean": "Por favor confirme o niegue", + "error.validation.contains": "Por favor ingrese valores que contengan \"{needle}\"", + "error.validation.date": "Por favor ingresa una fecha válida", + "error.validation.date.after": "Por favor introduce una fecha posterior a {date}", + "error.validation.date.before": "Por favor introduce una fecha anterior a {date}", + "error.validation.date.between": "Por favor introduce un número entre {min} y {max}", + "error.validation.denied": "Por favor niegue", + "error.validation.different": "EL valor no debe ser \"{other}\"", + "error.validation.email": "Por favor ingresa un correo electrónico valido", + "error.validation.endswith": "El valor no debe terminar con \"{end}\"", + "error.validation.filename": "Por favor ingresa un nombre de archivo válido", + "error.validation.in": "Por favor ingresa uno de los siguientes: ({in})", + "error.validation.integer": "Por favor ingresa un entero válido", + "error.validation.ip": "Por favor ingresa una dirección IP válida", + "error.validation.less": "Por favor ingresa un valor menor a {max}", + "error.validation.match": "El valor no coincide con el patrón esperado", + "error.validation.max": "Por favor ingresa un valor menor o igual a {max}", + "error.validation.maxlength": "Por favor ingresa un valor mas corto. (max. {max} caracteres)", + "error.validation.maxwords": "Por favor ingresa no mas de {max} palabra(s)", + "error.validation.min": "Por favor ingresa un valor mayor o igual a {min}", + "error.validation.minlength": "Por favor ingresa un valor mas largo. (min. {min} caracteres)", + "error.validation.minwords": "Por favor ingresa al menos {min} palabra(s)", + "error.validation.more": "Por favor ingresa un valor mayor a {min}", + "error.validation.notcontains": "Por favor ingresa un valor que no contenga \"{needle}\"", + "error.validation.notin": "Por favor no ingreses ninguno de las siguientes: ({notIn})", + "error.validation.option": "Por favor selecciona una de las opciones válidas", + "error.validation.num": "Por favor ingresa un numero válido", + "error.validation.required": "Por favor ingresa algo", + "error.validation.same": "Por favor ingresa \"{other}\"", + "error.validation.size": "El tamaño del valor debe ser \"{size}\"", + "error.validation.startswith": "El valor debe comenzar con \"{start}\"", + "error.validation.time": "Por favor ingresa una hora válida", + "error.validation.time.after": "Por favor ingresa una fecha después de {time}", + "error.validation.time.before": "Por favor ingresa una fecha antes de {time}", + "error.validation.time.between": "Por favor ingresa un fecha entre {min} y {max}", + "error.validation.url": "Por favor ingresa un URL válido", + + "expand": "Expandir", + "expand.all": "Expandir todo", + + "field.required": "Este campo es requerido", + "field.blocks.changeType": "Cambiar tipo", + "field.blocks.code.name": "Código", + "field.blocks.code.language": "Idioma", + "field.blocks.code.placeholder": "Tu código...", + "field.blocks.delete.confirm": "¿Seguro que quieres eliminar este bloque?", + "field.blocks.delete.confirm.all": "¿Seguro que quieres eliminar todos los bloques?", + "field.blocks.delete.confirm.selected": "¿Seguro que quieres eliminar los bloques seleccionados?", + "field.blocks.empty": "No hay bloques aún", + "field.blocks.fieldsets.label": "Por favor selecciona un tipo de bloque...", + "field.blocks.fieldsets.paste": "Presiona {{ shortcut }}para pegar/importar bloques en tu portapapeles ", + "field.blocks.gallery.name": "Galería", + "field.blocks.gallery.images.empty": "No hay imágenes aún", + "field.blocks.gallery.images.label": "Imágenes", + "field.blocks.heading.level": "Nivel", + "field.blocks.heading.name": "Encabezado", + "field.blocks.heading.text": "Texto", + "field.blocks.heading.placeholder": "Encabezado...", + "field.blocks.image.alt": "Texto alternativo", + "field.blocks.image.caption": "Leyenda", + "field.blocks.image.crop": "Cortar", + "field.blocks.image.link": "Enlace", + "field.blocks.image.location": "Ubicación", + "field.blocks.image.name": "Imágen", + "field.blocks.image.placeholder": "Selecciona una imagen", + "field.blocks.image.ratio": "Proporción", + "field.blocks.image.url": "URL de imágen", + "field.blocks.line.name": "Linea", + "field.blocks.list.name": "Lista", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Texto", + "field.blocks.markdown.placeholder": "Markdown...", + "field.blocks.quote.name": "Cita", + "field.blocks.quote.text.label": "Texto", + "field.blocks.quote.text.placeholder": "Cita...", + "field.blocks.quote.citation.label": "Citation", + "field.blocks.quote.citation.placeholder": "Por ...", + "field.blocks.text.name": "Texto", + "field.blocks.text.placeholder": "Text …", + "field.blocks.video.caption": "Leyenda", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Enter a video URL", + "field.blocks.video.url.label": "Video-URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Aún no ha seleccionado ningún archivo", + + "field.layout.delete": "Delete layout", + "field.layout.delete.confirm": "Do you really want to delete this layout?", + "field.layout.empty": "No rows yet", + "field.layout.select": "Select a layout", + + "field.object.empty": "No information yet", + + "field.pages.empty": "Aún no ha seleccionado ningúna pagina", + + "field.structure.delete.confirm": "\u00bfEn realidad desea borrar esta entrada?", + "field.structure.empty": "A\u00fan no existen entradas.", + + "field.users.empty": "Aún no ha seleccionado ningún usuario", + + "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "\u00bfEst\u00e1s seguro que deseas eliminar este archivo?", + "file.sort": "Change position", + + "files": "Archivos", + "files.empty": "Aún no existen archivos", + + "hide": "Hide", + "hour": "Hora", + "import": "Import", + "info": "Info", + "insert": "Insertar", + "insert.after": "Insert after", + "insert.before": "Insert before", + "install": "Instalar", + + "installation": "Instalación", + "installation.completed": "El panel ha sido instalado.", + "installation.disabled": "El instalador del panel está deshabilitado en servidores públicos por defecto. Ejecute el instalador en una máquina local o habilítelo con la opción panel.install.", + "installation.issues.accounts": "La carpeta /site/accounts no existe o no posee permisos de escritura.", + "installation.issues.content": "La carpeta /content no existe o no posee permisos de escritura.", + "installation.issues.curl": "Se requiere la extensión CURL.", + "installation.issues.headline": "El panel no puede ser instalado.", + "installation.issues.mbstring": "Se requiere la extensión MB String.", + "installation.issues.media": "La carpeta /media no existe o no posee permisos de escritura.", + "installation.issues.php": "Asegurese de estar usando PHP 7+", + "installation.issues.server": "Kirby requiere Apache, Nginx, Caddy", + "installation.issues.sessions": "La carpeta /site/sessions no existe o no posee permisos de escritura.", + + "language": "Idioma", + "language.code": "Código", + "language.convert": "Hacer por defecto", + "language.convert.confirm": "

Realmente deseas convertir {name} al idioma por defecto? Esta acción no se puede deshacer.

Si {name} tiene contenido sin traducir, no habrá vuelta atras y tu sitio puede quedar con partes sin contenido.

", + "language.create": "Añadir nuevo idioma", + "language.delete.confirm": "

", + "language.deleted": "El idioma ha sido borrado", + "language.direction": "Dirección de lectura", + "language.direction.ltr": "De Izquierda a derecha", + "language.direction.rtl": "De derecha a izquierda", + "language.locale": "Cadena de localización PHP", + "language.locale.warning": "Estas utilizando un configuración local. Por favor modifícalo en el archivo del lenguaje en /site/languages", + "language.name": "Nombre", + "language.updated": "El idioma a sido actualizado", + + "languages": "Idiomas", + "languages.default": "Idioma por defecto", + "languages.empty": "Todavía no hay idiomas", + "languages.secondary": "Idiomas secundarios", + "languages.secondary.empty": "Todavía no hay idiomas secundarios", + + "license": "Licencia", + "license.buy": "Comprar una licencia", + "license.register": "Registrar", + "license.manage": "Manage your licenses", + "license.register.help": "Recibió su código de licencia después de la compra por correo electrónico. Por favor copie y pegue para registrarse.", + "license.register.label": "Por favor, ingresa tu código de licencia", + "license.register.success": "Gracias por apoyar a Kirby", + "license.unregistered": "Este es un demo no registrado de Kirby", + "license.unregistered.label": "Unregistered", + + "link": "Enlace", + "link.text": "Texto de Enlace", + + "loading": "Cargando", + + "lock.unsaved": "Cambios sin guardar", + "lock.unsaved.empty": "No hay más cambios sin guardar", + "lock.isLocked": "Cambios sin guardar por {email}", + "lock.file.isLocked": "El archivo está siendo actualmente editado por {email} y no puede ser cambiado.", + "lock.page.isLocked": "La página está siendo actualmente editada por {email} y no puede ser cambiada.", + "lock.unlock": "Desbloquear", + "lock.isUnlocked": "Tus cambios sin guardar han sido sobrescritos por otro usuario. Puedes descargar los cambios y fusionarlos manualmente.", + + "login": "Iniciar sesión", + "login.code.label.login": "Login code", + "login.code.label.password-reset": "Password reset code", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "If your email address is registered, the requested code was sent via email.", + "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.login.subject": "Your login code", + "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.password-reset.subject": "Your password reset code", + "login.remember": "Mantener mi sesión iniciada", + "login.reset": "Reset password", + "login.toggleText.code.email": "Login via email", + "login.toggleText.code.email-password": "Login with password", + "login.toggleText.password-reset.email": "Forgot your password?", + "login.toggleText.password-reset.email-password": "← Back to login", + + "logout": "Cerrar sesi\u00f3n", + + "menu": "Menù", + "meridiem": "AM/PM", + "mime": "Tipos de medios", + "minutes": "Minutos", + + "month": "Mes", + "months.april": "Abril", + "months.august": "Agosto", + "months.december": "Diciembre", + "months.february": "Febrero", + "months.january": "Enero", + "months.july": "Julio", + "months.june": "Junio", + "months.march": "Marzo", + "months.may": "Mayo", + "months.november": "Noviembre", + "months.october": "Octubre", + "months.september": "Septiembre", + + "more": "Màs", + "name": "Nombre", + "next": "Siguiente", + "no": "no", + "off": "Apagado", + "on": "Encendido", + "open": "Abrir", + "open.newWindow": "Open in new window", + "options": "Opciones", + "options.none": "No options", + + "orientation": "Orientación", + "orientation.landscape": "Paisaje", + "orientation.portrait": "Retrato", + "orientation.square": "Diapositiva", + + "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Cambiar URL", + "page.changeSlug.fromTitle": "Crear a partir del t\u00edtulo", + "page.changeStatus": "Cambiar estado", + "page.changeStatus.position": "Por favor selecciona una posición", + "page.changeStatus.select": "Selecciona un nuevo estado", + "page.changeTemplate": "Cambiar plantilla", + "page.delete.confirm": "¿Estás seguro que deseas eliminar {title}?", + "page.delete.confirm.subpages": "Esta página tiene subpáginas.
Todas las súbpaginas serán eliminadas también.", + "page.delete.confirm.title": "Introduce el título de la página para confirmar", + "page.draft.create": "Crear borrador", + "page.duplicate.appendix": "Copiar", + "page.duplicate.files": "Copiar archivos", + "page.duplicate.pages": "Copiar páginas", + "page.sort": "Change position", + "page.status": "Estado", + "page.status.draft": "Borrador", + "page.status.draft.description": "The page is in draft mode and only visible for logged in editors or via secret link", + "page.status.listed": "Pública", + "page.status.listed.description": "La página es pública para cualquiera", + "page.status.unlisted": "No publicada", + "page.status.unlisted.description": "La página sólo es accesible vía URL", + + "pages": "Páginas", + "pages.empty": "No hay páginas aún", + "pages.status.draft": "Borradores", + "pages.status.listed": "Publicado", + "pages.status.unlisted": "No publicado", + + "pagination.page": "Página", + + "password": "Contrase\u00f1a", + "paste": "Paste", + "paste.after": "Paste after", + "pixel": "Pixel", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "Anterior", + "preview": "Preview", + "remove": "Eliminar", + "rename": "Renombrar", + "replace": "Reemplazar", + "retry": "Reintentar", + "revert": "Revertir", + "revert.confirm": "Do you really want to delete all unsaved changes?", + + "role": "Rol", + "role.admin.description": "El administrador tiene todos los derechos", + "role.admin.title": "Administrador", + "role.all": "Todos", + "role.empty": "No hay usuarios con este rol", + "role.description.placeholder": "Sin descripción", + "role.nobody.description": "Este es un rol alternativo sin permisos", + "role.nobody.title": "Nadie", + + "save": "Guardar", + "search": "Buscar", + "search.min": "Enter {min} characters to search", + "search.all": "Show all", + "search.results.none": "No results", + + "section.required": "Esta sección es requerida", + + "security": "Security", + "select": "Seleccionar", + "server": "Server", + "settings": "Ajustes", + "show": "Show", + "site.blueprint": "The site has no blueprint yet. You can define the setup in /site/blueprints/site.yml", + "size": "Tamaño", + "slug": "Apéndice URL", + "sort": "Ordenar", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Título", + "template": "Plantilla", + "today": "Hoy", + + "toolbar.button.code": "Código", + "toolbar.button.bold": "Negrita", + "toolbar.button.email": "Email", + "toolbar.button.headings": "Encabezados", + "toolbar.button.heading.1": "Encabezado 1", + "toolbar.button.heading.2": "Encabezado 2", + "toolbar.button.heading.3": "Encabezado 3", + "toolbar.button.heading.4": "Encabezado 4", + "toolbar.button.heading.5": "Encabezado 5", + "toolbar.button.heading.6": "Encabezado 6", + "toolbar.button.italic": "Texto en It\u00e1licas", + "toolbar.button.file": "Archivo", + "toolbar.button.file.select": "Selecciona un archivo", + "toolbar.button.file.upload": "Sube un archivo", + "toolbar.button.link": "Enlace", + "toolbar.button.paragraph": "Paragraph", + "toolbar.button.strike": "Strike-through", + "toolbar.button.ol": "Lista en orden", + "toolbar.button.underline": "Underline", + "toolbar.button.ul": "Lista de viñetas", + + "translation.author": "Equipo Kirby", + "translation.direction": "ltr", + "translation.name": "Español (América Latina)", + "translation.locale": "es_419", + + "upload": "Subir", + "upload.error.cantMove": "El archivo subido no puede ser movido", + "upload.error.cantWrite": "Error al escribir el archivo en el disco", + "upload.error.default": "El archivo no pudo ser subido", + "upload.error.extension": "Subida de archivo detenida por la extensión", + "upload.error.formSize": "El archivo subido excede la directiva MAX_FILE_SIZE que fue especificada en el formulario", + "upload.error.iniPostSize": "El archivo subido excede la directiva post_max_size directive en php.ini", + "upload.error.iniSize": "El archivo subido excede la directiva upload_max_filesize en php.ini", + "upload.error.noFile": "Ningún archivo ha sido subido", + "upload.error.noFiles": "Ningún archivo ha sido subido", + "upload.error.partial": "El archivo ha sido subido solo parcialmente", + "upload.error.tmpDir": "No se encuentra la carpeta temporal", + "upload.errors": "Error", + "upload.progress": "Subiendo...", + + "url": "Url", + "url.placeholder": "https://ejemplo.com", + + "user": "Usuario", + "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Cambiar correo electrónico", + "user.changeLanguage": "Cambiar idioma", + "user.changeName": "Renombrar este usuario", + "user.changePassword": "Cambiar la contraseña", + "user.changePassword.new": "Nueva contraseña", + "user.changePassword.new.confirm": "Confirma la nueva contraseña...", + "user.changeRole": "Cambiar rol", + "user.changeRole.select": "Selecciona un nuevo rol", + "user.create": "Agregar un nuevo usuario", + "user.delete": "Eliminar este usuario", + "user.delete.confirm": "¿Estás seguro que deseas eliminar
{email}?", + + "users": "Usuarios", + + "version": "Versión", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "Tu cuenta", + "view.installation": "Instalaci\u00f3n", + "view.languages": "Idiomas", + "view.resetPassword": "Reset password", + "view.site": "Sitio", + "view.system": "System", + "view.users": "Usuarios", + + "welcome": "Bienvenido", + "year": "Año", + "yes": "yes" } diff --git a/kirby/i18n/translations/es_ES.json b/kirby/i18n/translations/es_ES.json index 470346a..7fe8012 100644 --- a/kirby/i18n/translations/es_ES.json +++ b/kirby/i18n/translations/es_ES.json @@ -1,573 +1,596 @@ { - "account.changeName": "Cambia tu nombre", - "account.delete": "Borrar tu cuenta", - "account.delete.confirm": "¿Realmente quieres eliminar tu cuenta? Tu sesión se cerrará inmediatamente. La cuenta no podrá ser recuperada.", - - "add": "Añadir", - "author": "Autor", - "avatar": "Foto de perfil", - "back": "Atrás", - "cancel": "Cancelar", - "change": "Cambiar", - "close": "Cerrar", - "confirm": "Confirmar", - "collapse": "Colapsar", - "collapse.all": "Colapsar todos", - "copy": "Copiar", - "copy.all": "Copiar todo", - "create": "Crear", - - "date": "Fecha", - "date.select": "Selecciona una fecha", - - "day": "Día", - "days.fri": "Vi", - "days.mon": "Lu", - "days.sat": "Sá", - "days.sun": "Do", - "days.thu": "Ju", - "days.tue": "Ma", - "days.wed": "Mi", - - "debugging": "Debugging", - - "delete": "Borrar", - "delete.all": "Eliminar todos", - - "dialog.files.empty": "No se ha seleccionado ningún archivo", - "dialog.pages.empty": "No se ha seleccionado ninguna página", - "dialog.users.empty": "No se ha seleccionado ningún usuario", - - "dimensions": "Dimensiones", - "disabled": "Desabilitado", - "discard": "Descartar", - "download": "Descargar", - "duplicate": "Duplicar", - - "edit": "Editar", - - "email": "Correo electrónico", - "email.placeholder": "correo@ejemplo.com", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Ambiente", - - "error.access.code": "Código inválido", - "error.access.login": "Ingreso inválido", - "error.access.panel": "No estás autorizado para acceder al panel", - "error.access.view": "No tienes permiso para acceder a esta parte del panel", - - "error.avatar.create.fail": "No se pudo subir la foto de perfil.", - "error.avatar.delete.fail": "No se pudo borrar la foto de perfil", - "error.avatar.dimensions.invalid": "Por favor, mantenga el ancho y la altura de la imagen de perfil debajo de 3000 píxeles", - "error.avatar.mime.forbidden": "La imagen del perfil debe ser JPEG o PNG.", - - "error.blueprint.notFound": "El blueprint \"{name}\" no pudo ser cargado", - - "error.blocks.max.plural": "No debes añadir más de {max} bloques", - "error.blocks.max.singular": "No debes añadir más de un bloque", - "error.blocks.min.plural": "Debes añadir al menos {min} bloques ", - "error.blocks.min.singular": "Debes añadir al menos un bloque", - "error.blocks.validation": "Hay un error en el bloque {index}", - - "error.email.preset.notFound": "El preset del correo \"{name}\" no pudo ser encontrado", - - "error.field.converter.invalid": "Convertidor \"{converter}\" inválido", - - "error.file.changeName.empty": "El nombre no debe estar vacío", - "error.file.changeName.permission": "No tienes permitido cambiar el nombre de \"{filename}\"", - "error.file.duplicate": "Ya existe un archivo con el nombre \"{filename}\"", - "error.file.extension.forbidden": "La extensión \"{extension}\" no está permitida", - "error.file.extension.invalid": "Extensión inválida: {extension}", - "error.file.extension.missing": "Falta la extensión para \"{filename}\"", - "error.file.maxheight": "La altura de la imagen no debe exceder {height} pixeles", - "error.file.maxsize": "El archivo es muy grande", - "error.file.maxwidth": "El ancho de la imagen no debe exceder {width} pixeles", - "error.file.mime.differs": "El archivo cargado debe ser del mismo tipo mime \"{mime}\"", - "error.file.mime.forbidden": "Los medios tipo \"{mime}\" no están permitidos", - "error.file.mime.invalid": "Tipo invalido de mime: {mime}", - "error.file.mime.missing": "El tipo de medio para \"{filename}\" no pudo ser detectado", - "error.file.minheight": "La altura de la imagen debe ser de al menos {height} pixeles", - "error.file.minsize": "El archivo es muy pequeño", - "error.file.minwidth": "El ancho de la imagen debe ser de al menos {width} pixeles", - "error.file.name.missing": "El nombre de archivo no debe estar vacío", - "error.file.notFound": "El archivo \"{filename}\" no pudo ser encontrado", - "error.file.orientation": "The orientation of the image must be \"{orientation}\"", - "error.file.type.forbidden": "No está permitido subir archivos {type}", - "error.file.type.invalid": "Tipo de archivo inválido: {type}", - "error.file.undefined": "El archivo no pudo ser encontrado", - - "error.form.incomplete": "Por favor, corrija todos los errores del formulario…", - "error.form.notSaved": "El formulario no pudo ser guardado", - - "error.language.code": "Por favor introduce un código válido para el idioma", - "error.language.duplicate": "El idioma ya existe", - "error.language.name": "Por favor introduce un nombre válido para el idioma", - "error.language.notFound": "No se pudo encontrar el idioma", - - "error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}", - "error.layout.validation.settings": "There's an error in layout {index} settings", - - "error.license.format": "Por favor introduce una llave de licencia válida", - "error.license.email": "Por favor, introduce un correo electrónico válido", - "error.license.verification": "La licencia no pude ser verificada", - - "error.offline": "El Panel se encuentra fuera de linea ", - - "error.page.changeSlug.permission": "No está permitido cambiar el apéndice de URL para \"{slug}\"", - "error.page.changeStatus.incomplete": "La página tiene errores y no puede ser publicada.", - "error.page.changeStatus.permission": "El estado de esta página no se puede cambiar", - "error.page.changeStatus.toDraft.invalid": "La página \"{slug}\" no se puede convertir a borrador", - "error.page.changeTemplate.invalid": "La plantilla para la página \"{slug}\" no se puede cambiar", - "error.page.changeTemplate.permission": "No tienes permitido cambiar la plantilla para \"{slug}\"", - "error.page.changeTitle.empty": "El título no debe estar vacío.", - "error.page.changeTitle.permission": "No tienes permitido cambiar el título por \"{slug}\"", - "error.page.create.permission": "No tienes permitido crear \"{slug}\"", - "error.page.delete": "La página \"{slug}\" no puede ser eliminada", - "error.page.delete.confirm": "Por favor, introduzca el título de la página para confirmar", - "error.page.delete.hasChildren": "La página tiene subpáginas y no se puede eliminar", - "error.page.delete.permission": "No tienes permiso de eliminar \"{slug}\"", - "error.page.draft.duplicate": "Un borrador de página con el apéndice de URL \"{slug}\" ya existe", - "error.page.duplicate": "Una página con el apéndice de URL. \"{slug}\" ya existe", - "error.page.duplicate.permission": "You are not allowed to duplicate \"{slug}\"", - "error.page.notFound": "La página \"{slug}\" no puede ser encontrada", - "error.page.num.invalid": "Por favor, introduzca un número válido. Estos no deben ser negativos.", - "error.page.slug.invalid": "Please enter a valid URL appendix", - "error.page.slug.maxlength": "Slug length must be less than \"{length}\" characters", - "error.page.sort.permission": "La página \"{slug}\" no se puede ordenar", - "error.page.status.invalid": "Por favor, establezca un estado de página válido", - "error.page.undefined": "La página no se puede encontrar", - "error.page.update.permission": "No tienes permitido actualizar \"{slug}\"", - - "error.section.files.max.plural": "No debes agregar más de {max} archivos a la sección \"{section}\"", - "error.section.files.max.singular": "No debes agregar más de 1 archivo a la sección \"{section}\"", - "error.section.files.min.plural": "La sección \"{section}\" requiere al menos {min} archivos", - "error.section.files.min.singular": "La sección \"{section}\" requiere al menos un archivo", - - "error.section.pages.max.plural": "No debe agregar más de {max} páginas a la sección \"{section}\"", - "error.section.pages.max.singular": "No debe agregar más de una página a la sección \"{section}\"", - "error.section.pages.min.plural": "La sección \"{section}\" requiere al menos {min} páginas", - "error.section.pages.min.singular": "La sección \"{section}\" requiere al menos una página", - - "error.section.notLoaded": "La sección \"{name}\" no pudo ser cargada", - "error.section.type.invalid": "El sección tipo \"{tipo}\" no es válido", - - "error.site.changeTitle.empty": "El título no debe estar vacío.", - "error.site.changeTitle.permission": "No está permitido cambiar el título del sitio", - "error.site.update.permission": "No tienes permitido actualizar el sitio", - - "error.template.default.notFound": "La plantilla por defecto no existe", - - "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "No tienes permitido cambiar el correo electrónico para el usuario \"{name}\"", - "error.user.changeLanguage.permission": "No tienes permitido cambiar el idioma para el usuario \"{name}\"", - "error.user.changeName.permission": "No tienes permitido cambiar el nombre del usuario \"{name}\"", - "error.user.changePassword.permission": "No tienes permitido cambiar la contraseña del usuario \"{name}\"", - "error.user.changeRole.lastAdmin": "El rol para el último administrador no puede ser cambiado", - "error.user.changeRole.permission": "No tienes permitido cambiar el rol del usuario \"{name}\"", - "error.user.changeRole.toAdmin": "No tienes permitido promover a alguien al rol de admin", - "error.user.create.permission": "No tienes permiso para crear este usuario", - "error.user.delete": "El usuario \"{name}\" no puede ser eliminado", - "error.user.delete.lastAdmin": "El último administrador no puede ser eliminado", - "error.user.delete.lastUser": "El último usuario no puede ser eliminado", - "error.user.delete.permission": "No tienes permitido eliminar el usuario \"{name}\"", - "error.user.duplicate": "Un usuario con la dirección de correo electrónico \"{email}\" ya existe", - "error.user.email.invalid": "Por favor, introduce una dirección de correo electrónico válida", - "error.user.language.invalid": "Por favor ingrese un idioma válido", - "error.user.notFound": "El usuario \"{name}\" no pudo ser encontrado", - "error.user.password.invalid": "Por favor introduce una contraseña válida. Las contraseñas deben tener al menos 8 caracteres de largo.", - "error.user.password.notSame": "Las contraseñas no coinciden", - "error.user.password.undefined": "El usuario no tiene contraseña", - "error.user.password.wrong": "Contraseña incorrecta", - "error.user.role.invalid": "Por favor ingrese un rol válido", - "error.user.undefined": "El usuario no puede ser encontrado", - "error.user.update.permission": "No tienes permitido actualizar al usuario \"{name}\"", - - "error.validation.accepted": "Por favor, confirma", - "error.validation.alpha": "Por favor solo ingresa caracteres entre a-z", - "error.validation.alphanum": "Por favor solo ingrese caracteres entre a-z o numerales 0-9", - "error.validation.between": "Por favor, introduzca un valor entre \"{min}\" y \"{max}\"", - "error.validation.boolean": "Por favor confirme o rechace", - "error.validation.contains": "Por favor ingrese un valor que contenga \"{needle}\"", - "error.validation.date": "Por favor introduzca una fecha valida", - "error.validation.date.after": "Por favor introduce una fecha posterior a {date}", - "error.validation.date.before": "Por favor introduce una fecha anterior a {date}", - "error.validation.date.between": "Por favor introduce un número entre {min} y {max}", - "error.validation.denied": "Por favor, rechace", - "error.validation.different": "El valor no debe ser \"{other}\"", - "error.validation.email": "Por favor, introduce un correo electrónico válido", - "error.validation.endswith": "El valor debe terminar con \"{end}\"", - "error.validation.filename": "Por favor ingrese un nombre de archivo válido", - "error.validation.in": "Por favor ingrese uno de los siguientes: ({in})", - "error.validation.integer": "Por favor, introduce un numero integro válido", - "error.validation.ip": "Por favor ingrese una dirección IP válida", - "error.validation.less": "Por favor, introduzca un valor inferior a {max}", - "error.validation.match": "El valor no coincide con el patrón esperado", - "error.validation.max": "Por favor, introduzca un valor igual o inferior a {max}", - "error.validation.maxlength": "Por favor, introduzca un valor más corto. (max. {max} caracteres)", - "error.validation.maxwords": "Por favor ingrese no más de {max} palabra(s)", - "error.validation.min": "Por favor, introduzca un valor igual o mayor a {min}", - "error.validation.minlength": "Por favor, introduzca un valor más largo. (min. {min} caracteres)", - "error.validation.minwords": "Por favor ingrese al menos {min} palabra(s)", - "error.validation.more": "Por favor, introduzca un valor mayor a {min}", - "error.validation.notcontains": "Por favor ingrese un valor que no contenga \"{needle}\"", - "error.validation.notin": "Por favor, no ingrese ninguno de los siguientes: ({notIn})", - "error.validation.option": "Por favor seleccione una opción válida", - "error.validation.num": "Por favor ingrese un número valido", - "error.validation.required": "Por favor ingrese algo", - "error.validation.same": "Por favor escribe \"{other}\"", - "error.validation.size": "El tamaño del valor debe ser \"{size}\"", - "error.validation.startswith": "El valor debe comenzar con \"{start}\"", - "error.validation.time": "Por favor ingrese una hora válida", - "error.validation.time.after": "Por favor ingresa una fecha después de {time}", - "error.validation.time.before": "Por favor ingresa una fecha antes de {time}", - "error.validation.time.between": "Por favor ingresa un fecha entre {min} y {max}", - "error.validation.url": "Por favor introduzca un URL válido", - - "expand": "Expandir", - "expand.all": "Expandir todo", - - "field.required": "Este campo es requerido", - "field.blocks.changeType": "Cambiar tipo", - "field.blocks.code.name": "Código", - "field.blocks.code.language": "Idioma", - "field.blocks.code.placeholder": "Tu código...", - "field.blocks.delete.confirm": "¿Seguro que quieres eliminar este bloque?", - "field.blocks.delete.confirm.all": "¿Seguro que quieres eliminar todos los bloques?", - "field.blocks.delete.confirm.selected": "¿Seguro que quieres eliminar los bloques seleccionados?", - "field.blocks.empty": "No hay bloques aún", - "field.blocks.fieldsets.label": "Por favor selecciona un tipo de bloque...", - "field.blocks.fieldsets.paste": "Presiona {{ shortcut }}para pegar/importar bloques en tu portapapeles ", - "field.blocks.gallery.name": "Galería", - "field.blocks.gallery.images.empty": "No hay imágenes aún", - "field.blocks.gallery.images.label": "Imágenes", - "field.blocks.heading.level": "Nivel", - "field.blocks.heading.name": "Encabezado", - "field.blocks.heading.text": "Texto", - "field.blocks.heading.placeholder": "Encabezado...", - "field.blocks.image.alt": "Texto alternativo", - "field.blocks.image.caption": "Leyenda", - "field.blocks.image.crop": "Cortar", - "field.blocks.image.link": "Enlace", - "field.blocks.image.location": "Ubicación", - "field.blocks.image.name": "Imágen", - "field.blocks.image.placeholder": "Selecciona una imagen", - "field.blocks.image.ratio": "Proporción", - "field.blocks.image.url": "URL de imágen", - "field.blocks.line.name": "Linea", - "field.blocks.list.name": "Lista", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Texto", - "field.blocks.markdown.placeholder": "Markdown...", - "field.blocks.quote.name": "Cita", - "field.blocks.quote.text.label": "Texto", - "field.blocks.quote.text.placeholder": "Cita...", - "field.blocks.quote.citation.label": "Citation", - "field.blocks.quote.citation.placeholder": "Por ...", - "field.blocks.text.name": "Texto", - "field.blocks.text.placeholder": "Text …", - "field.blocks.video.caption": "Leyenda", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Enter a video URL", - "field.blocks.video.url.label": "Video-URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Aún no hay archivos seleccionados", - - "field.layout.delete": "Delete layout", - "field.layout.delete.confirm": "Do you really want to delete this layout?", - "field.layout.empty": "No rows yet", - "field.layout.select": "Select a layout", - - "field.pages.empty": "Aún no hay páginas seleccionadas", - "field.structure.delete.confirm": "¿Realmente quieres eliminar esta fila?", - "field.structure.empty": "Aún no hay entradas", - "field.users.empty": "Aún no hay usuarios seleccionados", - - "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "¿Realmente quieres eliminar
{filename}?", - "file.sort": "Change position", - - "files": "Archivos", - "files.empty": "Aún no hay archivos", - - "hide": "Hide", - "hour": "Hora", - "import": "Import", - "info": "Info", - "insert": "Insertar", - "insert.after": "Insert after", - "insert.before": "Insert before", - "install": "Instalar", - - "installation": "Instalación", - "installation.completed": "El panel ha sido instalado", - "installation.disabled": "El instalador del panel está deshabilitado en servidores públicos por defecto. Ejecute el instalador en una máquina local o habilítelo con la opción panel.install.", - "installation.issues.accounts": "La carpeta /site/accounts no existe o no se puede escribir", - "installation.issues.content": "La carpeta /content no existe o no se puede escribir", - "installation.issues.curl": "La extensión CURL es requerida", - "installation.issues.headline": "No se pudo instalar el panel", - "installation.issues.mbstring": "La extension MB String es requerida", - "installation.issues.media": "La carpeta /media no existe o no se puede escribir", - "installation.issues.php": "Asegúrate de usar PHP 7+", - "installation.issues.server": "Kirby requiere Apache, Nginx o Caddy", - "installation.issues.sessions": "La carpeta /site/sessions no existe o no se puede escribir", - - "language": "Idioma", - "language.code": "Código", - "language.convert": "Hacer por defecto", - "language.convert.confirm": "{name} al idioma por defecto? Esto no se puede deshacer.

Si {name} tiene contenido sin traducir, ya no habrá un respaldo válido y algunas partes de su sitio podrían estar vacías.

", - "language.create": "Añadir un nuevo idioma", - "language.delete.confirm": "¿De verdad quieres eliminar el idioma {name} incluyendo todas las traducciones? ¡Esto no se puede deshacer!", - "language.deleted": "El idioma ha sido eliminado", - "language.direction": "Leyendo dirección", - "language.direction.ltr": "De izquierda a derecha", - "language.direction.rtl": "De derecha a izquierda", - "language.locale": "PHP locale string", - "language.locale.warning": "Estas utilizando un configuración local. Por favor modifícalo en el archivo del lenguaje en /site/languages", - "language.name": "Nombre", - "language.updated": "El idioma ha sido actualizado", - - "languages": "Idiomas", - "languages.default": "Idioma predeterminado", - "languages.empty": "Todavía no hay idiomas", - "languages.secondary": "Idiomas secundarios", - "languages.secondary.empty": "Todavía no hay idiomas secundarios", - - "license": "Licencia", - "license.buy": "Comprar una licencia", - "license.register": "Registro", - "license.manage": "Manage your licenses", - "license.register.help": "Recibió su código de licencia después de la compra por correo electrónico. Por favor copie y pegue para registrarse.", - "license.register.label": "Por favor ingrese su código de licencia", - "license.register.success": "Gracias por apoyar a Kirby", - "license.unregistered": "Esta es una demo no registrada de Kirby", - "license.unregistered.label": "Unregistered", - - "link": "Enlace", - "link.text": "Texto del enlace", - - "loading": "Cargando", - - "lock.unsaved": "Cambios sin guardar", - "lock.unsaved.empty": "No hay más cambios sin guardar", - "lock.isLocked": "Cambios sin guardar por {email}", - "lock.file.isLocked": "El archivo está siendo actualmente editado por {email} y no puede ser cambiado.", - "lock.page.isLocked": "La página está siendo actualmente editada por {email} y no puede ser cambiada.", - "lock.unlock": "Desbloquear", - "lock.isUnlocked": "Tus cambios sin guardar han sido sobrescritos por otro usuario. Puedes descargar los cambios y fusionarlos manualmente.", - - "login": "Iniciar sesión", - "login.code.label.login": "Login code", - "login.code.label.password-reset": "Password reset code", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "If your email address is registered, the requested code was sent via email.", - "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.login.subject": "Your login code", - "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.password-reset.subject": "Your password reset code", - "login.remember": "Mantener sesión iniciada", - "login.reset": "Reset password", - "login.toggleText.code.email": "Login via email", - "login.toggleText.code.email-password": "Login with password", - "login.toggleText.password-reset.email": "Forgot your password?", - "login.toggleText.password-reset.email-password": "← Back to login", - - "logout": "Cerrar sesión", - - "menu": "Menu", - "meridiem": "AM/PM", - "mime": "Tipos de medios", - "minutes": "Minutos", - - "month": "Mes", - "months.april": "Abril", - "months.august": "Agosto", - "months.december": "Diciembre", - "months.february": "Febrero", - "months.january": "Enero", - "months.july": "Julio", - "months.june": "Junio", - "months.march": "Marzo", - "months.may": "Mayo", - "months.november": "Noviembre", - "months.october": "Octubre", - "months.september": "Septiembre", - - "more": "Más", - "name": "Nombre", - "next": "Siguiente", - "no": "no", - "off": "Apagado", - "on": "Encendido", - "open": "Abrir", - "open.newWindow": "Open in new window", - "options": "Opciones", - "options.none": "No options", - - "orientation": "Orientación", - "orientation.landscape": "Paisaje", - "orientation.portrait": "Retrato", - "orientation.square": "Cuadrado", - - "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Cambiar URL", - "page.changeSlug.fromTitle": "Crear en base al título", - "page.changeStatus": "Cambiar estado", - "page.changeStatus.position": "Por favor seleccione una posición", - "page.changeStatus.select": "Seleccione un nuevo estado", - "page.changeTemplate": "Cambiar plantilla", - "page.delete.confirm": "¿Realmente quieres eliminar {title}?", - "page.delete.confirm.subpages": "Esta página tiene subpáginas.
Todas las subpáginas también serán eliminadas.", - "page.delete.confirm.title": "Introduzca el título de la página para confirmar", - "page.draft.create": "Crear borrador", - "page.duplicate.appendix": "Copiar", - "page.duplicate.files": "Copiar archivos", - "page.duplicate.pages": "Copiar páginas", - "page.sort": "Change position", - "page.status": "Estado", - "page.status.draft": "Borrador", - "page.status.draft.description": "The page is in draft mode and only visible for logged in editors or via secret link", - "page.status.listed": "Publica", - "page.status.listed.description": "La página es pública para cualquiera", - "page.status.unlisted": "Sin publicar", - "page.status.unlisted.description": "La página solo es accesible vía URL", - - "pages": "Paginas", - "pages.empty": "Aún no hay páginas", - "pages.status.draft": "Borradores", - "pages.status.listed": "Publicadas", - "pages.status.unlisted": "Sin publicar", - - "pagination.page": "Página", - - "password": "Contraseña", - "paste": "Paste", - "paste.after": "Paste after", - "pixel": "Pixel", - "plugins": "Plugins", - "prev": "Anterior", - "preview": "Preview", - "remove": "Eliminar", - "rename": "Renombrar", - "replace": "Remplazar", - "retry": "Inténtalo de nuevo", - "revert": "Revertir", - "revert.confirm": "Do you really want to delete all unsaved changes?", - - "role": "Rol", - "role.admin.description": "El administrador tiene todos los derechos", - "role.admin.title": "Administrador", - "role.all": "Todos", - "role.empty": "No hay usuarios con este rol", - "role.description.placeholder": "Sin descripción", - "role.nobody.description": "Este es un rol alternativo sin permisos", - "role.nobody.title": "Nadie", - - "save": "Guardar", - "search": "Buscar", - "search.min": "Enter {min} characters to search", - "search.all": "Show all", - "search.results.none": "No results", - - "section.required": "Esta sección es requerida", - - "security": "Security", - "select": "Seleccionar", - "server": "Server", - "settings": "Ajustes", - "show": "Show", - "site.blueprint": "The site has no blueprint yet. You can define the setup in /site/blueprints/site.yml", - "size": "Tamaño", - "slug": "Apéndice URL", - "sort": "Ordenar", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Titulo", - "template": "Plantilla", - "today": "Hoy", - - "toolbar.button.code": "Código", - "toolbar.button.bold": "Negritas", - "toolbar.button.email": "Correo electrónico", - "toolbar.button.headings": "Encabezados", - "toolbar.button.heading.1": "Encabezado 1", - "toolbar.button.heading.2": "Encabezado 2", - "toolbar.button.heading.3": "Encabezado 3", - "toolbar.button.heading.4": "Encabezado 4", - "toolbar.button.heading.5": "Encabezado 5", - "toolbar.button.heading.6": "Encabezado 6", - "toolbar.button.italic": "Italica", - "toolbar.button.file": "Archivo", - "toolbar.button.file.select": "Seleccione un archivo", - "toolbar.button.file.upload": "Sube un archivo", - "toolbar.button.link": "Enlace", - "toolbar.button.paragraph": "Paragraph", - "toolbar.button.strike": "Strike-through", - "toolbar.button.ol": "Lista ordenada", - "toolbar.button.underline": "Underline", - "toolbar.button.ul": "Lista de viñetas", - - "translation.author": "Turqueso", - "translation.direction": "ltr", - "translation.name": "Español", - "translation.locale": "es_ES", - - "upload": "Subir", - "upload.error.cantMove": "El archivo subido no puede ser movido", - "upload.error.cantWrite": "Error al escribir el archivo en el disco", - "upload.error.default": "El archivo no pudo ser subido", - "upload.error.extension": "Subida de archivo detenida por la extensión", - "upload.error.formSize": "El archivo subido excede la directiva MAX_FILE_SIZE que fue especificada en el formulario", - "upload.error.iniPostSize": "El archivo subido excede la directiva post_max_size directive en php.ini", - "upload.error.iniSize": "El archivo subido excede la directiva upload_max_filesize en php.ini", - "upload.error.noFile": "Ningún archivo ha sido subido", - "upload.error.noFiles": "Ningún archivo ha sido subido", - "upload.error.partial": "El archivo ha sido subido solo parcialmente", - "upload.error.tmpDir": "No se encuentra la carpeta temporal", - "upload.errors": "Error", - "upload.progress": "Cargando…", - - "url": "Url", - "url.placeholder": "https://ejemplo.com", - - "user": "Usuario", - "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Cambiar correo electrónico", - "user.changeLanguage": "Cambiar idioma", - "user.changeName": "Renombrar a este usuario", - "user.changePassword": "Cambia contraseña", - "user.changePassword.new": "Nueva contraseña", - "user.changePassword.new.confirm": "Confirmar nueva contraseña…", - "user.changeRole": "Cambiar rol", - "user.changeRole.select": "Seleccione un nuevo rol", - "user.create": "Añadir un nuevo usuario", - "user.delete": "Eliminar este usuario", - "user.delete.confirm": "¿Realmente quieres eliminar
{email}?", - - "users": "Usuarios", - - "version": "Versión", - - "view.account": "Su cuenta", - "view.installation": "Instalación", - "view.languages": "Idiomas", - "view.resetPassword": "Reset password", - "view.site": "Sitio", - "view.system": "System", - "view.users": "Usuarios", - - "welcome": "Bienvenido(a)", - "year": "Año", - "yes": "yes" + "account.changeName": "Cambia tu nombre", + "account.delete": "Borrar tu cuenta", + "account.delete.confirm": "¿Realmente quieres eliminar tu cuenta? Tu sesión se cerrará inmediatamente. La cuenta no podrá ser recuperada.", + + "add": "Añadir", + "author": "Autor", + "avatar": "Foto de perfil", + "back": "Atrás", + "cancel": "Cancelar", + "change": "Cambiar", + "close": "Cerrar", + "confirm": "Confirmar", + "collapse": "Colapsar", + "collapse.all": "Colapsar todos", + "copy": "Copiar", + "copy.all": "Copiar todo", + "create": "Crear", + + "date": "Fecha", + "date.select": "Selecciona una fecha", + + "day": "Día", + "days.fri": "Vi", + "days.mon": "Lu", + "days.sat": "Sá", + "days.sun": "Do", + "days.thu": "Ju", + "days.tue": "Ma", + "days.wed": "Mi", + + "debugging": "Debugging", + + "delete": "Borrar", + "delete.all": "Eliminar todos", + + "dialog.files.empty": "No se ha seleccionado ningún archivo", + "dialog.pages.empty": "No se ha seleccionado ninguna página", + "dialog.users.empty": "No se ha seleccionado ningún usuario", + + "dimensions": "Dimensiones", + "disabled": "Desabilitado", + "discard": "Descartar", + "download": "Descargar", + "duplicate": "Duplicar", + + "edit": "Editar", + + "email": "Correo electrónico", + "email.placeholder": "correo@ejemplo.com", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Ambiente", + + "error.access.code": "Código inválido", + "error.access.login": "Ingreso inválido", + "error.access.panel": "No estás autorizado para acceder al panel", + "error.access.view": "No tienes permiso para acceder a esta parte del panel", + + "error.avatar.create.fail": "No se pudo subir la foto de perfil.", + "error.avatar.delete.fail": "No se pudo borrar la foto de perfil", + "error.avatar.dimensions.invalid": "Por favor, mantenga el ancho y la altura de la imagen de perfil debajo de 3000 píxeles", + "error.avatar.mime.forbidden": "La imagen del perfil debe ser JPEG o PNG.", + + "error.blueprint.notFound": "El blueprint \"{name}\" no pudo ser cargado", + + "error.blocks.max.plural": "No debes añadir más de {max} bloques", + "error.blocks.max.singular": "No debes añadir más de un bloque", + "error.blocks.min.plural": "Debes añadir al menos {min} bloques ", + "error.blocks.min.singular": "Debes añadir al menos un bloque", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "El preset del correo \"{name}\" no pudo ser encontrado", + + "error.field.converter.invalid": "Convertidor \"{converter}\" inválido", + + "error.file.changeName.empty": "El nombre no debe estar vacío", + "error.file.changeName.permission": "No tienes permitido cambiar el nombre de \"{filename}\"", + "error.file.duplicate": "Ya existe un archivo con el nombre \"{filename}\"", + "error.file.extension.forbidden": "La extensión \"{extension}\" no está permitida", + "error.file.extension.invalid": "Extensión inválida: {extension}", + "error.file.extension.missing": "Falta la extensión para \"{filename}\"", + "error.file.maxheight": "La altura de la imagen no debe exceder {height} pixeles", + "error.file.maxsize": "El archivo es muy grande", + "error.file.maxwidth": "El ancho de la imagen no debe exceder {width} pixeles", + "error.file.mime.differs": "El archivo cargado debe ser del mismo tipo mime \"{mime}\"", + "error.file.mime.forbidden": "Los medios tipo \"{mime}\" no están permitidos", + "error.file.mime.invalid": "Tipo invalido de mime: {mime}", + "error.file.mime.missing": "El tipo de medio para \"{filename}\" no pudo ser detectado", + "error.file.minheight": "La altura de la imagen debe ser de al menos {height} pixeles", + "error.file.minsize": "El archivo es muy pequeño", + "error.file.minwidth": "El ancho de la imagen debe ser de al menos {width} pixeles", + "error.file.name.missing": "El nombre de archivo no debe estar vacío", + "error.file.notFound": "El archivo \"{filename}\" no pudo ser encontrado", + "error.file.orientation": "The orientation of the image must be \"{orientation}\"", + "error.file.type.forbidden": "No está permitido subir archivos {type}", + "error.file.type.invalid": "Tipo de archivo inválido: {type}", + "error.file.undefined": "El archivo no pudo ser encontrado", + + "error.form.incomplete": "Por favor, corrija todos los errores del formulario…", + "error.form.notSaved": "El formulario no pudo ser guardado", + + "error.language.code": "Por favor introduce un código válido para el idioma", + "error.language.duplicate": "El idioma ya existe", + "error.language.name": "Por favor introduce un nombre válido para el idioma", + "error.language.notFound": "No se pudo encontrar el idioma", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "There's an error in layout {index} settings", + + "error.license.format": "Por favor introduce una llave de licencia válida", + "error.license.email": "Por favor, introduce un correo electrónico válido", + "error.license.verification": "La licencia no pude ser verificada", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "El Panel se encuentra fuera de linea ", + + "error.page.changeSlug.permission": "No está permitido cambiar el apéndice de URL para \"{slug}\"", + "error.page.changeStatus.incomplete": "La página tiene errores y no puede ser publicada.", + "error.page.changeStatus.permission": "El estado de esta página no se puede cambiar", + "error.page.changeStatus.toDraft.invalid": "La página \"{slug}\" no se puede convertir a borrador", + "error.page.changeTemplate.invalid": "La plantilla para la página \"{slug}\" no se puede cambiar", + "error.page.changeTemplate.permission": "No tienes permitido cambiar la plantilla para \"{slug}\"", + "error.page.changeTitle.empty": "El título no debe estar vacío.", + "error.page.changeTitle.permission": "No tienes permitido cambiar el título por \"{slug}\"", + "error.page.create.permission": "No tienes permitido crear \"{slug}\"", + "error.page.delete": "La página \"{slug}\" no puede ser eliminada", + "error.page.delete.confirm": "Por favor, introduzca el título de la página para confirmar", + "error.page.delete.hasChildren": "La página tiene subpáginas y no se puede eliminar", + "error.page.delete.permission": "No tienes permiso de eliminar \"{slug}\"", + "error.page.draft.duplicate": "Un borrador de página con el apéndice de URL \"{slug}\" ya existe", + "error.page.duplicate": "Una página con el apéndice de URL. \"{slug}\" ya existe", + "error.page.duplicate.permission": "You are not allowed to duplicate \"{slug}\"", + "error.page.notFound": "La página \"{slug}\" no puede ser encontrada", + "error.page.num.invalid": "Por favor, introduzca un número válido. Estos no deben ser negativos.", + "error.page.slug.invalid": "Please enter a valid URL appendix", + "error.page.slug.maxlength": "Slug length must be less than \"{length}\" characters", + "error.page.sort.permission": "La página \"{slug}\" no se puede ordenar", + "error.page.status.invalid": "Por favor, establezca un estado de página válido", + "error.page.undefined": "La página no se puede encontrar", + "error.page.update.permission": "No tienes permitido actualizar \"{slug}\"", + + "error.section.files.max.plural": "No debes agregar más de {max} archivos a la sección \"{section}\"", + "error.section.files.max.singular": "No debes agregar más de 1 archivo a la sección \"{section}\"", + "error.section.files.min.plural": "La sección \"{section}\" requiere al menos {min} archivos", + "error.section.files.min.singular": "La sección \"{section}\" requiere al menos un archivo", + + "error.section.pages.max.plural": "No debe agregar más de {max} páginas a la sección \"{section}\"", + "error.section.pages.max.singular": "No debe agregar más de una página a la sección \"{section}\"", + "error.section.pages.min.plural": "La sección \"{section}\" requiere al menos {min} páginas", + "error.section.pages.min.singular": "La sección \"{section}\" requiere al menos una página", + + "error.section.notLoaded": "La sección \"{name}\" no pudo ser cargada", + "error.section.type.invalid": "El sección tipo \"{tipo}\" no es válido", + + "error.site.changeTitle.empty": "El título no debe estar vacío.", + "error.site.changeTitle.permission": "No está permitido cambiar el título del sitio", + "error.site.update.permission": "No tienes permitido actualizar el sitio", + + "error.template.default.notFound": "La plantilla por defecto no existe", + + "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "No tienes permitido cambiar el correo electrónico para el usuario \"{name}\"", + "error.user.changeLanguage.permission": "No tienes permitido cambiar el idioma para el usuario \"{name}\"", + "error.user.changeName.permission": "No tienes permitido cambiar el nombre del usuario \"{name}\"", + "error.user.changePassword.permission": "No tienes permitido cambiar la contraseña del usuario \"{name}\"", + "error.user.changeRole.lastAdmin": "El rol para el último administrador no puede ser cambiado", + "error.user.changeRole.permission": "No tienes permitido cambiar el rol del usuario \"{name}\"", + "error.user.changeRole.toAdmin": "No tienes permitido promover a alguien al rol de admin", + "error.user.create.permission": "No tienes permiso para crear este usuario", + "error.user.delete": "El usuario \"{name}\" no puede ser eliminado", + "error.user.delete.lastAdmin": "El último administrador no puede ser eliminado", + "error.user.delete.lastUser": "El último usuario no puede ser eliminado", + "error.user.delete.permission": "No tienes permitido eliminar el usuario \"{name}\"", + "error.user.duplicate": "Un usuario con la dirección de correo electrónico \"{email}\" ya existe", + "error.user.email.invalid": "Por favor, introduce una dirección de correo electrónico válida", + "error.user.language.invalid": "Por favor ingrese un idioma válido", + "error.user.notFound": "El usuario \"{name}\" no pudo ser encontrado", + "error.user.password.invalid": "Por favor introduce una contraseña válida. Las contraseñas deben tener al menos 8 caracteres de largo.", + "error.user.password.notSame": "Las contraseñas no coinciden", + "error.user.password.undefined": "El usuario no tiene contraseña", + "error.user.password.wrong": "Contraseña incorrecta", + "error.user.role.invalid": "Por favor ingrese un rol válido", + "error.user.undefined": "El usuario no puede ser encontrado", + "error.user.update.permission": "No tienes permitido actualizar al usuario \"{name}\"", + + "error.validation.accepted": "Por favor, confirma", + "error.validation.alpha": "Por favor solo ingresa caracteres entre a-z", + "error.validation.alphanum": "Por favor solo ingrese caracteres entre a-z o numerales 0-9", + "error.validation.between": "Por favor, introduzca un valor entre \"{min}\" y \"{max}\"", + "error.validation.boolean": "Por favor confirme o rechace", + "error.validation.contains": "Por favor ingrese un valor que contenga \"{needle}\"", + "error.validation.date": "Por favor introduzca una fecha valida", + "error.validation.date.after": "Por favor introduce una fecha posterior a {date}", + "error.validation.date.before": "Por favor introduce una fecha anterior a {date}", + "error.validation.date.between": "Por favor introduce un número entre {min} y {max}", + "error.validation.denied": "Por favor, rechace", + "error.validation.different": "El valor no debe ser \"{other}\"", + "error.validation.email": "Por favor, introduce un correo electrónico válido", + "error.validation.endswith": "El valor debe terminar con \"{end}\"", + "error.validation.filename": "Por favor ingrese un nombre de archivo válido", + "error.validation.in": "Por favor ingrese uno de los siguientes: ({in})", + "error.validation.integer": "Por favor, introduce un numero integro válido", + "error.validation.ip": "Por favor ingrese una dirección IP válida", + "error.validation.less": "Por favor, introduzca un valor inferior a {max}", + "error.validation.match": "El valor no coincide con el patrón esperado", + "error.validation.max": "Por favor, introduzca un valor igual o inferior a {max}", + "error.validation.maxlength": "Por favor, introduzca un valor más corto. (max. {max} caracteres)", + "error.validation.maxwords": "Por favor ingrese no más de {max} palabra(s)", + "error.validation.min": "Por favor, introduzca un valor igual o mayor a {min}", + "error.validation.minlength": "Por favor, introduzca un valor más largo. (min. {min} caracteres)", + "error.validation.minwords": "Por favor ingrese al menos {min} palabra(s)", + "error.validation.more": "Por favor, introduzca un valor mayor a {min}", + "error.validation.notcontains": "Por favor ingrese un valor que no contenga \"{needle}\"", + "error.validation.notin": "Por favor, no ingrese ninguno de los siguientes: ({notIn})", + "error.validation.option": "Por favor seleccione una opción válida", + "error.validation.num": "Por favor ingrese un número valido", + "error.validation.required": "Por favor ingrese algo", + "error.validation.same": "Por favor escribe \"{other}\"", + "error.validation.size": "El tamaño del valor debe ser \"{size}\"", + "error.validation.startswith": "El valor debe comenzar con \"{start}\"", + "error.validation.time": "Por favor ingrese una hora válida", + "error.validation.time.after": "Por favor ingresa una fecha después de {time}", + "error.validation.time.before": "Por favor ingresa una fecha antes de {time}", + "error.validation.time.between": "Por favor ingresa un fecha entre {min} y {max}", + "error.validation.url": "Por favor introduzca un URL válido", + + "expand": "Expandir", + "expand.all": "Expandir todo", + + "field.required": "Este campo es requerido", + "field.blocks.changeType": "Cambiar tipo", + "field.blocks.code.name": "Código", + "field.blocks.code.language": "Idioma", + "field.blocks.code.placeholder": "Tu código...", + "field.blocks.delete.confirm": "¿Seguro que quieres eliminar este bloque?", + "field.blocks.delete.confirm.all": "¿Seguro que quieres eliminar todos los bloques?", + "field.blocks.delete.confirm.selected": "¿Seguro que quieres eliminar los bloques seleccionados?", + "field.blocks.empty": "No hay bloques aún", + "field.blocks.fieldsets.label": "Por favor selecciona un tipo de bloque...", + "field.blocks.fieldsets.paste": "Presiona {{ shortcut }}para pegar/importar bloques en tu portapapeles ", + "field.blocks.gallery.name": "Galería", + "field.blocks.gallery.images.empty": "No hay imágenes aún", + "field.blocks.gallery.images.label": "Imágenes", + "field.blocks.heading.level": "Nivel", + "field.blocks.heading.name": "Encabezado", + "field.blocks.heading.text": "Texto", + "field.blocks.heading.placeholder": "Encabezado...", + "field.blocks.image.alt": "Texto alternativo", + "field.blocks.image.caption": "Leyenda", + "field.blocks.image.crop": "Cortar", + "field.blocks.image.link": "Enlace", + "field.blocks.image.location": "Ubicación", + "field.blocks.image.name": "Imágen", + "field.blocks.image.placeholder": "Selecciona una imagen", + "field.blocks.image.ratio": "Proporción", + "field.blocks.image.url": "URL de imágen", + "field.blocks.line.name": "Linea", + "field.blocks.list.name": "Lista", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Texto", + "field.blocks.markdown.placeholder": "Markdown...", + "field.blocks.quote.name": "Cita", + "field.blocks.quote.text.label": "Texto", + "field.blocks.quote.text.placeholder": "Cita...", + "field.blocks.quote.citation.label": "Citation", + "field.blocks.quote.citation.placeholder": "Por ...", + "field.blocks.text.name": "Texto", + "field.blocks.text.placeholder": "Text …", + "field.blocks.video.caption": "Leyenda", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Enter a video URL", + "field.blocks.video.url.label": "Video-URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Aún no hay archivos seleccionados", + + "field.layout.delete": "Delete layout", + "field.layout.delete.confirm": "Do you really want to delete this layout?", + "field.layout.empty": "No rows yet", + "field.layout.select": "Select a layout", + + "field.object.empty": "No information yet", + + "field.pages.empty": "Aún no hay páginas seleccionadas", + + "field.structure.delete.confirm": "¿Realmente quieres eliminar esta fila?", + "field.structure.empty": "Aún no hay entradas", + + "field.users.empty": "Aún no hay usuarios seleccionados", + + "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "¿Realmente quieres eliminar
{filename}?", + "file.sort": "Change position", + + "files": "Archivos", + "files.empty": "Aún no hay archivos", + + "hide": "Hide", + "hour": "Hora", + "import": "Import", + "info": "Info", + "insert": "Insertar", + "insert.after": "Insert after", + "insert.before": "Insert before", + "install": "Instalar", + + "installation": "Instalación", + "installation.completed": "El panel ha sido instalado", + "installation.disabled": "El instalador del panel está deshabilitado en servidores públicos por defecto. Ejecute el instalador en una máquina local o habilítelo con la opción panel.install.", + "installation.issues.accounts": "La carpeta /site/accounts no existe o no se puede escribir", + "installation.issues.content": "La carpeta /content no existe o no se puede escribir", + "installation.issues.curl": "La extensión CURL es requerida", + "installation.issues.headline": "No se pudo instalar el panel", + "installation.issues.mbstring": "La extension MB String es requerida", + "installation.issues.media": "La carpeta /media no existe o no se puede escribir", + "installation.issues.php": "Asegúrate de usar PHP 7+", + "installation.issues.server": "Kirby requiere Apache, Nginx o Caddy", + "installation.issues.sessions": "La carpeta /site/sessions no existe o no se puede escribir", + + "language": "Idioma", + "language.code": "Código", + "language.convert": "Hacer por defecto", + "language.convert.confirm": "{name} al idioma por defecto? Esto no se puede deshacer.

Si {name} tiene contenido sin traducir, ya no habrá un respaldo válido y algunas partes de su sitio podrían estar vacías.

", + "language.create": "Añadir un nuevo idioma", + "language.delete.confirm": "¿De verdad quieres eliminar el idioma {name} incluyendo todas las traducciones? ¡Esto no se puede deshacer!", + "language.deleted": "El idioma ha sido eliminado", + "language.direction": "Leyendo dirección", + "language.direction.ltr": "De izquierda a derecha", + "language.direction.rtl": "De derecha a izquierda", + "language.locale": "PHP locale string", + "language.locale.warning": "Estas utilizando un configuración local. Por favor modifícalo en el archivo del lenguaje en /site/languages", + "language.name": "Nombre", + "language.updated": "El idioma ha sido actualizado", + + "languages": "Idiomas", + "languages.default": "Idioma predeterminado", + "languages.empty": "Todavía no hay idiomas", + "languages.secondary": "Idiomas secundarios", + "languages.secondary.empty": "Todavía no hay idiomas secundarios", + + "license": "Licencia", + "license.buy": "Comprar una licencia", + "license.register": "Registro", + "license.manage": "Manage your licenses", + "license.register.help": "Recibió su código de licencia después de la compra por correo electrónico. Por favor copie y pegue para registrarse.", + "license.register.label": "Por favor ingrese su código de licencia", + "license.register.success": "Gracias por apoyar a Kirby", + "license.unregistered": "Esta es una demo no registrada de Kirby", + "license.unregistered.label": "Unregistered", + + "link": "Enlace", + "link.text": "Texto del enlace", + + "loading": "Cargando", + + "lock.unsaved": "Cambios sin guardar", + "lock.unsaved.empty": "No hay más cambios sin guardar", + "lock.isLocked": "Cambios sin guardar por {email}", + "lock.file.isLocked": "El archivo está siendo actualmente editado por {email} y no puede ser cambiado.", + "lock.page.isLocked": "La página está siendo actualmente editada por {email} y no puede ser cambiada.", + "lock.unlock": "Desbloquear", + "lock.isUnlocked": "Tus cambios sin guardar han sido sobrescritos por otro usuario. Puedes descargar los cambios y fusionarlos manualmente.", + + "login": "Iniciar sesión", + "login.code.label.login": "Login code", + "login.code.label.password-reset": "Password reset code", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "If your email address is registered, the requested code was sent via email.", + "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.login.subject": "Your login code", + "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.password-reset.subject": "Your password reset code", + "login.remember": "Mantener sesión iniciada", + "login.reset": "Reset password", + "login.toggleText.code.email": "Login via email", + "login.toggleText.code.email-password": "Login with password", + "login.toggleText.password-reset.email": "Forgot your password?", + "login.toggleText.password-reset.email-password": "← Back to login", + + "logout": "Cerrar sesión", + + "menu": "Menu", + "meridiem": "AM/PM", + "mime": "Tipos de medios", + "minutes": "Minutos", + + "month": "Mes", + "months.april": "Abril", + "months.august": "Agosto", + "months.december": "Diciembre", + "months.february": "Febrero", + "months.january": "Enero", + "months.july": "Julio", + "months.june": "Junio", + "months.march": "Marzo", + "months.may": "Mayo", + "months.november": "Noviembre", + "months.october": "Octubre", + "months.september": "Septiembre", + + "more": "Más", + "name": "Nombre", + "next": "Siguiente", + "no": "no", + "off": "Apagado", + "on": "Encendido", + "open": "Abrir", + "open.newWindow": "Open in new window", + "options": "Opciones", + "options.none": "No options", + + "orientation": "Orientación", + "orientation.landscape": "Paisaje", + "orientation.portrait": "Retrato", + "orientation.square": "Cuadrado", + + "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Cambiar URL", + "page.changeSlug.fromTitle": "Crear en base al título", + "page.changeStatus": "Cambiar estado", + "page.changeStatus.position": "Por favor seleccione una posición", + "page.changeStatus.select": "Seleccione un nuevo estado", + "page.changeTemplate": "Cambiar plantilla", + "page.delete.confirm": "¿Realmente quieres eliminar {title}?", + "page.delete.confirm.subpages": "Esta página tiene subpáginas.
Todas las subpáginas también serán eliminadas.", + "page.delete.confirm.title": "Introduzca el título de la página para confirmar", + "page.draft.create": "Crear borrador", + "page.duplicate.appendix": "Copiar", + "page.duplicate.files": "Copiar archivos", + "page.duplicate.pages": "Copiar páginas", + "page.sort": "Change position", + "page.status": "Estado", + "page.status.draft": "Borrador", + "page.status.draft.description": "The page is in draft mode and only visible for logged in editors or via secret link", + "page.status.listed": "Publica", + "page.status.listed.description": "La página es pública para cualquiera", + "page.status.unlisted": "Sin publicar", + "page.status.unlisted.description": "La página solo es accesible vía URL", + + "pages": "Paginas", + "pages.empty": "Aún no hay páginas", + "pages.status.draft": "Borradores", + "pages.status.listed": "Publicadas", + "pages.status.unlisted": "Sin publicar", + + "pagination.page": "Página", + + "password": "Contraseña", + "paste": "Paste", + "paste.after": "Paste after", + "pixel": "Pixel", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "Anterior", + "preview": "Preview", + "remove": "Eliminar", + "rename": "Renombrar", + "replace": "Remplazar", + "retry": "Inténtalo de nuevo", + "revert": "Revertir", + "revert.confirm": "Do you really want to delete all unsaved changes?", + + "role": "Rol", + "role.admin.description": "El administrador tiene todos los derechos", + "role.admin.title": "Administrador", + "role.all": "Todos", + "role.empty": "No hay usuarios con este rol", + "role.description.placeholder": "Sin descripción", + "role.nobody.description": "Este es un rol alternativo sin permisos", + "role.nobody.title": "Nadie", + + "save": "Guardar", + "search": "Buscar", + "search.min": "Enter {min} characters to search", + "search.all": "Show all", + "search.results.none": "No results", + + "section.required": "Esta sección es requerida", + + "security": "Security", + "select": "Seleccionar", + "server": "Server", + "settings": "Ajustes", + "show": "Show", + "site.blueprint": "The site has no blueprint yet. You can define the setup in /site/blueprints/site.yml", + "size": "Tamaño", + "slug": "Apéndice URL", + "sort": "Ordenar", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Titulo", + "template": "Plantilla", + "today": "Hoy", + + "toolbar.button.code": "Código", + "toolbar.button.bold": "Negritas", + "toolbar.button.email": "Correo electrónico", + "toolbar.button.headings": "Encabezados", + "toolbar.button.heading.1": "Encabezado 1", + "toolbar.button.heading.2": "Encabezado 2", + "toolbar.button.heading.3": "Encabezado 3", + "toolbar.button.heading.4": "Encabezado 4", + "toolbar.button.heading.5": "Encabezado 5", + "toolbar.button.heading.6": "Encabezado 6", + "toolbar.button.italic": "Italica", + "toolbar.button.file": "Archivo", + "toolbar.button.file.select": "Seleccione un archivo", + "toolbar.button.file.upload": "Sube un archivo", + "toolbar.button.link": "Enlace", + "toolbar.button.paragraph": "Paragraph", + "toolbar.button.strike": "Strike-through", + "toolbar.button.ol": "Lista ordenada", + "toolbar.button.underline": "Underline", + "toolbar.button.ul": "Lista de viñetas", + + "translation.author": "Turqueso", + "translation.direction": "ltr", + "translation.name": "Español", + "translation.locale": "es_ES", + + "upload": "Subir", + "upload.error.cantMove": "El archivo subido no puede ser movido", + "upload.error.cantWrite": "Error al escribir el archivo en el disco", + "upload.error.default": "El archivo no pudo ser subido", + "upload.error.extension": "Subida de archivo detenida por la extensión", + "upload.error.formSize": "El archivo subido excede la directiva MAX_FILE_SIZE que fue especificada en el formulario", + "upload.error.iniPostSize": "El archivo subido excede la directiva post_max_size directive en php.ini", + "upload.error.iniSize": "El archivo subido excede la directiva upload_max_filesize en php.ini", + "upload.error.noFile": "Ningún archivo ha sido subido", + "upload.error.noFiles": "Ningún archivo ha sido subido", + "upload.error.partial": "El archivo ha sido subido solo parcialmente", + "upload.error.tmpDir": "No se encuentra la carpeta temporal", + "upload.errors": "Error", + "upload.progress": "Cargando…", + + "url": "Url", + "url.placeholder": "https://ejemplo.com", + + "user": "Usuario", + "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Cambiar correo electrónico", + "user.changeLanguage": "Cambiar idioma", + "user.changeName": "Renombrar a este usuario", + "user.changePassword": "Cambia contraseña", + "user.changePassword.new": "Nueva contraseña", + "user.changePassword.new.confirm": "Confirmar nueva contraseña…", + "user.changeRole": "Cambiar rol", + "user.changeRole.select": "Seleccione un nuevo rol", + "user.create": "Añadir un nuevo usuario", + "user.delete": "Eliminar este usuario", + "user.delete.confirm": "¿Realmente quieres eliminar
{email}?", + + "users": "Usuarios", + + "version": "Versión", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "Su cuenta", + "view.installation": "Instalación", + "view.languages": "Idiomas", + "view.resetPassword": "Reset password", + "view.site": "Sitio", + "view.system": "System", + "view.users": "Usuarios", + + "welcome": "Bienvenido(a)", + "year": "Año", + "yes": "yes" } diff --git a/kirby/i18n/translations/fa.json b/kirby/i18n/translations/fa.json index 3f6e2fc..61acc48 100644 --- a/kirby/i18n/translations/fa.json +++ b/kirby/i18n/translations/fa.json @@ -1,573 +1,596 @@ { - "account.changeName": "Change your name", - "account.delete": "Delete your account", - "account.delete.confirm": "Do you really want to delete your account? You will be logged out immediately. Your account cannot be recovered.", - - "add": "\u0627\u0641\u0632\u0648\u062f\u0646", - "author": "Author", - "avatar": "\u062a\u0635\u0648\u06cc\u0631 \u067e\u0631\u0648\u0641\u0627\u06cc\u0644", - "back": "بازگشت", - "cancel": "\u0627\u0646\u0635\u0631\u0627\u0641", - "change": "\u0627\u0635\u0644\u0627\u062d", - "close": "\u0628\u0633\u062a\u0646", - "confirm": "تایید", - "collapse": "Collapse", - "collapse.all": "Collapse All", - "copy": "کپی", - "copy.all": "Copy all", - "create": "ایجاد", - - "date": "تاریخ", - "date.select": "یک تاریخ را انتخاب کنید", - - "day": "روز", - "days.fri": "\u062c\u0645\u0639\u0647", - "days.mon": "\u062f\u0648\u0634\u0646\u0628\u0647", - "days.sat": "\u0634\u0646\u0628\u0647", - "days.sun": "\u06cc\u06a9\u0634\u0646\u0628\u0647", - "days.thu": "\u067e\u0646\u062c\u0634\u0646\u0628\u0647", - "days.tue": "\u0633\u0647 \u0634\u0646\u0628\u0647", - "days.wed": "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647", - - "debugging": "Debugging", - - "delete": "\u062d\u0630\u0641", - "delete.all": "Delete all", - - "dialog.files.empty": "No files to select", - "dialog.pages.empty": "No pages to select", - "dialog.users.empty": "No users to select", - - "dimensions": "ابعاد", - "disabled": "Disabled", - "discard": "\u0627\u0646\u0635\u0631\u0627\u0641", - "download": "Download", - "duplicate": "Duplicate", - - "edit": "\u0648\u06cc\u0631\u0627\u06cc\u0634", - - "email": "\u067e\u0633\u062a \u0627\u0644\u06a9\u062a\u0631\u0648\u0646\u06cc\u06a9", - "email.placeholder": "mail@example.com", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Environment", - - "error.access.code": "Invalid code", - "error.access.login": "اطلاعات ورودی نامعتبر است", - "error.access.panel": "شما اجازه دسترسی به پانل را ندارید", - "error.access.view": "You are not allowed to access this part of the panel", - - "error.avatar.create.fail": "بارگزاری تصویر پروفایل موفق نبود", - "error.avatar.delete.fail": "\u062a\u0635\u0648\u06cc\u0631 \u067e\u0631\u0648\u0641\u0627\u06cc\u0644 \u0631\u0627 \u0646\u0645\u06cc\u062a\u0648\u0627\u0646 \u062d\u0630\u0641 \u06a9\u0631\u062f", - "error.avatar.dimensions.invalid": "لطفا طول و عرض تصویر پروفایل را زیر 3000 پیکسل انتخاب کنید", - "error.avatar.mime.forbidden": "تصویر پروفایل باید از نوع JPEG یا PNG باشد", - - "error.blueprint.notFound": "بلوپرینت با نام «{name}» قابل بارگذاری نیست", - - "error.blocks.max.plural": "You must not add more than {max} blocks", - "error.blocks.max.singular": "You must not add more than one block", - "error.blocks.min.plural": "You must add at least {min} blocks", - "error.blocks.min.singular": "You must add at least one block", - "error.blocks.validation": "There's an error in block {index}", - - "error.email.preset.notFound": "قالب ایمیل «{name}» پیدا نشد", - - "error.field.converter.invalid": "مبدل «{converter}» نامعتبر است", - - "error.file.changeName.empty": "The name must not be empty", - "error.file.changeName.permission": "شما اجازه تنغییر نام فایل «{filename}» را ندارید", - "error.file.duplicate": "فایلی هم نام با «{filename}» هم اکنون موجود است", - "error.file.extension.forbidden": "پسوند فایل «{extension}» غیرمجاز است", - "error.file.extension.invalid": "Invalid extension: {extension}", - "error.file.extension.missing": "\u0634\u0645\u0627 \u0646\u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u062f \u0641\u0627\u06cc\u0644\u200c\u0647\u0627\u06cc \u0628\u062f\u0648\u0646 \u067e\u0633\u0648\u0646\u062f \u0631\u0627 \u0622\u067e\u0644\u0648\u062f \u06a9\u0646\u06cc\u062f", - "error.file.maxheight": "The height of the image must not exceed {height} pixels", - "error.file.maxsize": "The file is too large", - "error.file.maxwidth": "The width of the image must not exceed {width} pixels", - "error.file.mime.differs": "فایل آپلود شده باید از همان نوع باشد «{mime}»", - "error.file.mime.forbidden": "فرمت فایل «{mime}» غیرمجاز است", - "error.file.mime.invalid": "Invalid mime type: {mime}", - "error.file.mime.missing": "فرمت فایل «{filename}» قابل شناسایی نیست", - "error.file.minheight": "The height of the image must be at least {height} pixels", - "error.file.minsize": "The file is too small", - "error.file.minwidth": "The width of the image must be at least {width} pixels", - "error.file.name.missing": "نام فایل اجباری است", - "error.file.notFound": "فایل «{filename}» پیدا نشد.", - "error.file.orientation": "The orientation of the image must be \"{orientation}\"", - "error.file.type.forbidden": "شما اجازه بارگذاری فایلهای «{type}» را ندارید", - "error.file.type.invalid": "Invalid file type: {type}", - "error.file.undefined": "\u0641\u0627\u06cc\u0644 \u0645\u0648\u0631\u062f \u0646\u0638\u0631 \u067e\u06cc\u062f\u0627 \u0646\u0634\u062f.", - - "error.form.incomplete": "لطفا کلیه خطاهای فرم را برطرف کنید", - "error.form.notSaved": "امکان دخیره فرم وجود ندارد", - - "error.language.code": "Please enter a valid code for the language", - "error.language.duplicate": "The language already exists", - "error.language.name": "Please enter a valid name for the language", - "error.language.notFound": "The language could not be found", - - "error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}", - "error.layout.validation.settings": "There's an error in layout {index} settings", - - "error.license.format": "Please enter a valid license key", - "error.license.email": "لطفا ایمیل صحیحی وارد کنید", - "error.license.verification": "The license could not be verified", - - "error.offline": "The Panel is currently offline", - - "error.page.changeSlug.permission": "شما امکان تغییر پسوند Url صفحه «{slug}» را ندارید", - "error.page.changeStatus.incomplete": "صفحه حاوی خطا است و قابل انتشار نیست", - "error.page.changeStatus.permission": "وضعیت صفحه جاری قابل تغییر نیست", - "error.page.changeStatus.toDraft.invalid": "صفحه «{slug}» قابل تبدیل به پیش نویس نیست", - "error.page.changeTemplate.invalid": "قالب صفحه «{slug}» قابل تغییر نیست", - "error.page.changeTemplate.permission": "شما اجازه تغییر قالب «{slug}» را ندارید", - "error.page.changeTitle.empty": "عنوان اجباری است", - "error.page.changeTitle.permission": "شما اجازه تغییر عنوان «{slug}» را ندارید", - "error.page.create.permission": "شما اجازه ایجاد «{slug}» را ندارید", - "error.page.delete": "حذف صفحه «{slug}» ممکن نیست", - "error.page.delete.confirm": "جهت ادامه عنوان صفحه را وارد کنید", - "error.page.delete.hasChildren": "این صفحه جاوی زیرصفحه است و نمی تواند حذف شود", - "error.page.delete.permission": "شما اجازه حذف «{slug}» را ندارید", - "error.page.draft.duplicate": "صفحه پیش‌نویسی با پسوند Url مشابه «{slug}» هم اکنون موجود است", - "error.page.duplicate": "صفحه‌ای با آدرس Url مشابه «{slug}» هم اکنون موجود است", - "error.page.duplicate.permission": "You are not allowed to duplicate \"{slug}\"", - "error.page.notFound": "صفحه مورد نظر با آدرس «{slug}» پیدا نشد.", - "error.page.num.invalid": "لطفا شماره ترتیب را بدرستی وارد نمایید. اعداد نباید منفی باشند.", - "error.page.slug.invalid": "Please enter a valid URL appendix", - "error.page.slug.maxlength": "Slug length must be less than \"{length}\" characters", - "error.page.sort.permission": "امکان مرتب‌سازی «{slug}» نیست", - "error.page.status.invalid": "لطفا وضعیت صحیحی برای صفحه انتخاب کنید", - "error.page.undefined": "صفحه مورد نظر پیدا نشد", - "error.page.update.permission": "شما اجازه بروزرسانی «{slug}» را ندارید", - - "error.section.files.max.plural": "نباید بیش از {max} فایل به بخش «{section}» اضافه کنید", - "error.section.files.max.singular": "نباید بیش از یک فایل به بخش «{section}» اضافه کنید", - "error.section.files.min.plural": "The \"{section}\" section requires at least {min} files", - "error.section.files.min.singular": "The \"{section}\" section requires at least one file", - - "error.section.pages.max.plural": "نباید بیش از {max} صفحه به بخش «{section}» اضافه کنید", - "error.section.pages.max.singular": "نباید بیش از یک صفحه به بخش «{section}» اضافه کنید", - "error.section.pages.min.plural": "The \"{section}\" section requires at least {min} pages", - "error.section.pages.min.singular": "The \"{section}\" section requires at least one page", - - "error.section.notLoaded": "بخش «{name}» قابل بارکذاری نیست", - "error.section.type.invalid": "نوع بخش «{type}» غیرمجاز است", - - "error.site.changeTitle.empty": "عنوان اجباری است", - "error.site.changeTitle.permission": "شما اجازه تغییر عنوان سایت را ندارید", - "error.site.update.permission": "شما اجازه بروزرسانی سایت را ندارید", - - "error.template.default.notFound": "قالب پیش فرض موجود نیست", - - "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "شما اجازه تغییر ایمیل کاربر «{name}» را ندارید", - "error.user.changeLanguage.permission": "شما اجازه تغییر زبان برای کاربر «{name}» را ندارید", - "error.user.changeName.permission": "شما اجازه تنغییر نام کاربر «{name}» را ندارید", - "error.user.changePassword.permission": "شما اجازه تغییر رمز عبور کاربر «{name}» را ندارید", - "error.user.changeRole.lastAdmin": "نقش آخرین مدیر سیستم قابل تغییر نیست", - "error.user.changeRole.permission": "شما اجازه تغییر نقش کاربر «{name}» را ندارید", - "error.user.changeRole.toAdmin": "You are not allowed to promote someone to the admin role", - "error.user.create.permission": "شما اجازه ایجاد این کاربر را ندارید", - "error.user.delete": "کاربر «{name}» نمی تواند حذف شود", - "error.user.delete.lastAdmin": "\u062d\u0630\u0641 \u0622\u062e\u0631\u06cc\u0646 \u0645\u062f\u06cc\u0631 \u0633\u06cc\u0633\u062a\u0645 \u0645\u0645\u06a9\u0646 \u0646\u06cc\u0633\u062a", - "error.user.delete.lastUser": "حذف آخرین کاربر ممکن نیست", - "error.user.delete.permission": "شما اجازه حذف کاربر «{name}» را ندارید", - "error.user.duplicate": "کاربری با ایمیل «{email}» هم اکنون موجود است", - "error.user.email.invalid": "لطفا یک ایمیل معتبر وارد کنید", - "error.user.language.invalid": "لطفا زبان معتبری انتخاب کنید", - "error.user.notFound": "کاربر «{name}» پیدا نشد", - "error.user.password.invalid": "لطفا گذرواژه صحیحی با حداقل طول 8 حرف وارد کنید. ", - "error.user.password.notSame": "\u0644\u0637\u0641\u0627 \u062a\u06a9\u0631\u0627\u0631 \u06af\u0630\u0631\u0648\u0627\u0698\u0647 \u0631\u0627 \u0648\u0627\u0631\u062f \u0646\u0645\u0627\u06cc\u06cc\u062f", - "error.user.password.undefined": "کاربر فاقد گذرواژه است", - "error.user.password.wrong": "Wrong password", - "error.user.role.invalid": "لطفا نقش صحیحی وارد نمایید", - "error.user.undefined": "کاربر مورد نظر پیدا نشد", - "error.user.update.permission": "شما اجازه بروزرسانی کاربر «{name}» را ندارید", - - "error.validation.accepted": "لطفا تایید کنید", - "error.validation.alpha": "لطفا تنها از بین حروف a-z انتخاب کنید", - "error.validation.alphanum": "لطفا تنها از بین حروف a-z و اعداد 0-9 انتخاب کنید", - "error.validation.between": "لطفا مقداری مابین «{min}» و «{max}» وارد کنید", - "error.validation.boolean": "لطفا تایید یا رد کنید", - "error.validation.contains": "لطفا مقداری شامل «{needle}» وارد کنید", - "error.validation.date": "لطفا تاریخ معتبری وارد کنید", - "error.validation.date.after": "Please enter a date after {date}", - "error.validation.date.before": "Please enter a date before {date}", - "error.validation.date.between": "Please enter a date between {min} and {max}", - "error.validation.denied": "لطفا رد کنید", - "error.validation.different": "مقدار نباید مساوی «{other}» باشد", - "error.validation.email": "لطفا ایمیل صحیحی وارد کنید", - "error.validation.endswith": "مقدار باید با «{end}» ختم شود", - "error.validation.filename": "لطفا نام فایل صحیحی وارد کنید", - "error.validation.in": "لطفا یکی از مقادیر روبرو را وارد کنید: ({in})", - "error.validation.integer": "لطفا عدد صحیحی وارد کنید", - "error.validation.ip": "لطفا IP آدرس صحیحی وارد کنید", - "error.validation.less": "لطفا مقداری کمتر از {max} وارد کنید", - "error.validation.match": "مقدار وارد شده با الگوی مورد نظر همخوانی ندارد", - "error.validation.max": "لطفا مقداری کوچکتر یا مساوی {min} وارد کنید", - "error.validation.maxlength": "لطفا عبارت کوتاه‌تری وارد کنید. (حداکثر {max} حرف)", - "error.validation.maxwords": "لطفا بیش از {max} کلمه وارد نکنید", - "error.validation.min": "لطفا مقداری بزرگتر یا مساوی با {min} وارد کنید", - "error.validation.minlength": "لطفا عبارتی طولانی‌تری وارد کنید. (حداقل {min} حرف)", - "error.validation.minwords": "لطفا حداقل {min} کلمه وارد کنید", - "error.validation.more": "لطفا مقداری بیش از {min} وارد کنید", - "error.validation.notcontains": "لطفا مقداری فاقد «{needle}» وارد کنید", - "error.validation.notin": "لطفا از مقادیر روبرو استفاده نکنید: ({notin})", - "error.validation.option": "لطفا گزینه معتبری انتخاب کنید", - "error.validation.num": "لطفا عدد صحیحی وارد کنید", - "error.validation.required": "لطفا مقداری وارد کنید", - "error.validation.same": "لطفا مقدار «{other}» را وارد کنید", - "error.validation.size": "اندازه ورودی باید معادل «{size}» باشد", - "error.validation.startswith": "مقدار باید با «{start}» شروع شود", - "error.validation.time": "لطفا زمان معتبری وارد کنید", - "error.validation.time.after": "Please enter a time after {time}", - "error.validation.time.before": "Please enter a time before {time}", - "error.validation.time.between": "Please enter a time between {min} and {max}", - "error.validation.url": "لطفا آدرس URL صحیح وارد کنید", - - "expand": "Expand", - "expand.all": "Expand All", - - "field.required": "The field is required", - "field.blocks.changeType": "Change type", - "field.blocks.code.name": "کد", - "field.blocks.code.language": "زبان", - "field.blocks.code.placeholder": "Your code …", - "field.blocks.delete.confirm": "Do you really want to delete this block?", - "field.blocks.delete.confirm.all": "Do you really want to delete all blocks?", - "field.blocks.delete.confirm.selected": "Do you really want to delete the selected blocks?", - "field.blocks.empty": "No blocks yet", - "field.blocks.fieldsets.label": "Please select a block type …", - "field.blocks.fieldsets.paste": "Press {{ shortcut }} to paste/import blocks from your clipboard", - "field.blocks.gallery.name": "Gallery", - "field.blocks.gallery.images.empty": "No images yet", - "field.blocks.gallery.images.label": "Images", - "field.blocks.heading.level": "Level", - "field.blocks.heading.name": "Heading", - "field.blocks.heading.text": "Text", - "field.blocks.heading.placeholder": "Heading …", - "field.blocks.image.alt": "Alternative text", - "field.blocks.image.caption": "Caption", - "field.blocks.image.crop": "Crop", - "field.blocks.image.link": "پیوند", - "field.blocks.image.location": "Location", - "field.blocks.image.name": "تصویر", - "field.blocks.image.placeholder": "Select an image", - "field.blocks.image.ratio": "Ratio", - "field.blocks.image.url": "Image URL", - "field.blocks.line.name": "Line", - "field.blocks.list.name": "List", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Text", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Quote", - "field.blocks.quote.text.label": "Text", - "field.blocks.quote.text.placeholder": "Quote …", - "field.blocks.quote.citation.label": "Citation", - "field.blocks.quote.citation.placeholder": "by …", - "field.blocks.text.name": "Text", - "field.blocks.text.placeholder": "Text …", - "field.blocks.video.caption": "Caption", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Enter a video URL", - "field.blocks.video.url.label": "Video-URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "فایلی انتخاب نشده است", - - "field.layout.delete": "Delete layout", - "field.layout.delete.confirm": "Do you really want to delete this layout?", - "field.layout.empty": "No rows yet", - "field.layout.select": "Select a layout", - - "field.pages.empty": "صفحه‌ای انتخاب نشده است", - "field.structure.delete.confirm": "\u0645\u062f\u062e\u0644 \u062c\u0627\u0631\u06cc \u062d\u0630\u0641 \u0634\u0648\u062f\u061f", - "field.structure.empty": "\u0645\u0648\u0631\u062f\u06cc \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0631\u062f.", - "field.users.empty": "کاربری انتخاب نشده است", - - "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "آیا واقعا می خواهید این فایل را حذف کنید؟
{filename}", - "file.sort": "Change position", - - "files": "فایل‌ها", - "files.empty": "فایلی موجود نیست", - - "hide": "Hide", - "hour": "ساعت", - "import": "Import", - "info": "Info", - "insert": "\u062f\u0631\u062c", - "insert.after": "Insert after", - "insert.before": "Insert before", - "install": "نصب", - - "installation": "نصب و راه اندازی", - "installation.completed": "پنل کاربری نصب شد", - "installation.disabled": "نصب کننده پانل کاربری بصورت پیش‌فرض در سرورهای عمومی غیرفعال است. لطفا نصب را روی یک ماشین محلی اجرا کنید یا آن را با استفاده از panel.install فعال کنید.", - "installation.issues.accounts": "پوشه /site/accounts موجود نیست یا قابل نوشتن نیست.", - "installation.issues.content": "پوشه /content موجود نیست یا قابل نوشتن نیست", - "installation.issues.curl": "افزونه CURL مورد نیاز است", - "installation.issues.headline": "نصب پانل کاربری ممکن نیست", - "installation.issues.mbstring": "افزونه MB String مورد نیاز است", - "installation.issues.media": "پوشه /media موجود نیست یا قابل نوشتن نیست", - "installation.issues.php": "لطفا از پی‌اچ‌پی 7 یا بالاتر استفاده کنید", - "installation.issues.server": "کربی نیاز به Apache، Nginx یا Caddy دارد", - "installation.issues.sessions": "پوشه /site/sessions وجود ندارد یا قابل نوشتن نیست", - - "language": "\u0632\u0628\u0627\u0646", - "language.code": "کد", - "language.convert": "پیش‌فرض شود", - "language.convert.confirm": "

آیا واقعا میخواهید {name} را به زبان پیشفرض تبدیل کنید؟ این عمل برگشت ناپذیر است.

اگر {name} دارای محتوای غیر ترجمه شده باشد، جایگزین معتبر دیگری نخواهد بود و ممکن است بخش‌هایی از سایت شما خالی باشد.

", - "language.create": "افزودن زبان جدید", - "language.delete.confirm": "آیا واقعا میخواهید زبان {name} را به همراه تمام ترجمه‌ها حذف کنید؟ این عمل قابل بازگشت نخواهد بود!", - "language.deleted": "زبان مورد نظر حذف شد", - "language.direction": "rtl", - "language.direction.ltr": "چپ به راست", - "language.direction.rtl": "راست به چپ", - "language.locale": "PHP locale string", - "language.locale.warning": "You are using a custom locale set up. Please modify it in the language file in /site/languages", - "language.name": "پارسی", - "language.updated": "زبان به روز شد", - - "languages": "زبان‌ها", - "languages.default": "زبان پیش‌فرض", - "languages.empty": "هنوز هیچ زبانی موجود نیست", - "languages.secondary": "زبان‌های ثانویه", - "languages.secondary.empty": "هنوز هیچ زبان ثانویه‌ای موجود نیست", - - "license": "\u0645\u062c\u0648\u0632", - "license.buy": "خرید مجوز", - "license.register": "ثبت", - "license.manage": "Manage your licenses", - "license.register.help": "پس از خرید از طریق ایمیل، کد مجوز خود را دریافت کردید. لطفا برای ثبت‌نام آن را کپی و اینجا پیست کنید.", - "license.register.label": "لطفا کد مجوز خود را وارد کنید", - "license.register.success": "با تشکر از شما برای حمایت از کربی", - "license.unregistered": "این یک نسخه آزمایشی ثبت نشده از کربی است", - "license.unregistered.label": "Unregistered", - - "link": "\u067e\u06cc\u0648\u0646\u062f", - "link.text": "\u0645\u062a\u0646 \u067e\u06cc\u0648\u0646\u062f", - - "loading": "بارگزاری", - - "lock.unsaved": "Unsaved changes", - "lock.unsaved.empty": "There are no more unsaved changes", - "lock.isLocked": "Unsaved changes by {email}", - "lock.file.isLocked": "The file is currently being edited by {email} and cannot be changed.", - "lock.page.isLocked": "The page is currently being edited by {email} and cannot be changed.", - "lock.unlock": "Unlock", - "lock.isUnlocked": "Your unsaved changes have been overwritten by another user. You can download your changes to merge them manually.", - - "login": "ورود", - "login.code.label.login": "Login code", - "login.code.label.password-reset": "Password reset code", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "If your email address is registered, the requested code was sent via email.", - "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.login.subject": "Your login code", - "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.password-reset.subject": "Your password reset code", - "login.remember": "مرا به خاطر بسپار", - "login.reset": "Reset password", - "login.toggleText.code.email": "Login via email", - "login.toggleText.code.email-password": "Login with password", - "login.toggleText.password-reset.email": "Forgot your password?", - "login.toggleText.password-reset.email-password": "← Back to login", - - "logout": "خروج", - - "menu": "منو", - "meridiem": "ق.ظ/ب.ظ", - "mime": "نوع رسانه", - "minutes": "دقیقه", - - "month": "ماه", - "months.april": "\u0622\u0648\u0631\u06cc\u0644", - "months.august": "\u0627\u0648\u062a", - "months.december": "\u062f\u0633\u0627\u0645\u0628\u0631", - "months.february": "فوریه", - "months.january": "\u0698\u0627\u0646\u0648\u06cc\u0647", - "months.july": "\u0698\u0648\u0626\u06cc\u0647", - "months.june": "\u0698\u0648\u0626\u0646", - "months.march": "\u0645\u0627\u0631\u0633", - "months.may": "\u0645\u06cc", - "months.november": "\u0646\u0648\u0627\u0645\u0628\u0631", - "months.october": "\u0627\u06a9\u062a\u0628\u0631", - "months.september": "\u0633\u067e\u062a\u0627\u0645\u0628\u0631", - - "more": "بیشتر", - "name": "نام", - "next": "بعدی", - "no": "no", - "off": "off", - "on": "on", - "open": "بازکردن", - "open.newWindow": "Open in new window", - "options": "گزینه‌ها", - "options.none": "No options", - - "orientation": "جهت", - "orientation.landscape": "افقی", - "orientation.portrait": "عمودی", - "orientation.square": "مربع", - - "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "تغییر Url صفحه", - "page.changeSlug.fromTitle": "\u0627\u06cc\u062c\u0627\u062f \u0627\u0632 \u0631\u0648\u06cc \u0639\u0646\u0648\u0627\u0646", - "page.changeStatus": "تغییر وضعیت", - "page.changeStatus.position": "لطفا یک موقعیت را انتخاب کنید", - "page.changeStatus.select": "یک وضعیت جدید را انتخاب کنید", - "page.changeTemplate": "تغییر قالب", - "page.delete.confirm": "صفحه {title} حذف شود؟", - "page.delete.confirm.subpages": "این صفحه دارای زیرصفحه است.
تمام زیر صفحات نیز حذف خواهد شد.", - "page.delete.confirm.title": "جهت ادامه عنوان صفحه را وارد کنید", - "page.draft.create": "ایجاد پیش‌نویس", - "page.duplicate.appendix": "کپی", - "page.duplicate.files": "Copy files", - "page.duplicate.pages": "Copy pages", - "page.sort": "Change position", - "page.status": "وضعیت", - "page.status.draft": "پیش‌نویس", - "page.status.draft.description": "The page is in draft mode and only visible for logged in editors or via secret link", - "page.status.listed": "عمومی", - "page.status.listed.description": "این صفحه برای عموم قابل مشاهده است", - "page.status.unlisted": "فهرست نشده", - "page.status.unlisted.description": "این صفحه فقط از طریق URL قابل دسترسی است", - - "pages": "صفحات", - "pages.empty": "هنوز هیچ صفحه‌ای موجود نیست", - "pages.status.draft": "پیش‌نویس‌ها", - "pages.status.listed": "منتشر شده", - "pages.status.unlisted": "فهرست نشده", - - "pagination.page": "صفحه", - - "password": "\u06af\u0630\u0631\u0648\u0627\u0698\u0647", - "paste": "Paste", - "paste.after": "Paste after", - "pixel": "پیکسل", - "plugins": "Plugins", - "prev": "قبلی", - "preview": "Preview", - "remove": "حذف", - "rename": "تغییر نام", - "replace": "\u062c\u0627\u06cc\u06af\u0632\u06cc\u0646\u06cc", - "retry": "\u062a\u0644\u0627\u0634 \u0645\u062c\u062f\u062f", - "revert": "بازگرداندن تغییرات", - "revert.confirm": "Do you really want to delete all unsaved changes?", - - "role": "\u0646\u0642\u0634", - "role.admin.description": "The admin has all rights", - "role.admin.title": "Admin", - "role.all": "همه", - "role.empty": "هیچ کاربری با این نقش وجود ندارد", - "role.description.placeholder": "فاقد شرح", - "role.nobody.description": "This is a fallback role without any permissions", - "role.nobody.title": "Nobody", - - "save": "\u0630\u062e\u06cc\u0631\u0647", - "search": "جستجو", - "search.min": "Enter {min} characters to search", - "search.all": "Show all", - "search.results.none": "No results", - - "section.required": "The section is required", - - "security": "Security", - "select": "انتخاب", - "server": "Server", - "settings": "تنظیمات", - "show": "Show", - "site.blueprint": "The site has no blueprint yet. You can define the setup in /site/blueprints/site.yml", - "size": "اندازه", - "slug": "پسوند Url", - "sort": "ترتیب", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "عنوان", - "template": "\u0642\u0627\u0644\u0628 \u0635\u0641\u062d\u0647", - "today": "امروز", - - "toolbar.button.code": "کد", - "toolbar.button.bold": "\u0645\u062a\u0646 \u0628\u0627 \u062d\u0631\u0648\u0641 \u062f\u0631\u0634\u062a", - "toolbar.button.email": "\u067e\u0633\u062a \u0627\u0644\u06a9\u062a\u0631\u0648\u0646\u06cc\u06a9", - "toolbar.button.headings": "عنوان‌ها", - "toolbar.button.heading.1": "عنوان 1", - "toolbar.button.heading.2": "عنوان 2", - "toolbar.button.heading.3": "عنوان 3", - "toolbar.button.heading.4": "Heading 4", - "toolbar.button.heading.5": "Heading 5", - "toolbar.button.heading.6": "Heading 6", - "toolbar.button.italic": "\u0645\u062a\u0646 \u0627\u0631\u06cc\u0628", - "toolbar.button.file": "فایل", - "toolbar.button.file.select": "Select a file", - "toolbar.button.file.upload": "Upload a file", - "toolbar.button.link": "\u067e\u06cc\u0648\u0646\u062f", - "toolbar.button.paragraph": "Paragraph", - "toolbar.button.strike": "Strike-through", - "toolbar.button.ol": "لیست مرتب", - "toolbar.button.underline": "Underline", - "toolbar.button.ul": "لیست معمولی", - - "translation.author": "تیم کربی", - "translation.direction": "rtl", - "translation.name": "انگلیسی", - "translation.locale": "fa_IR", - - "upload": "بارگذاری", - "upload.error.cantMove": "The uploaded file could not be moved", - "upload.error.cantWrite": "Failed to write file to disk", - "upload.error.default": "The file could not be uploaded", - "upload.error.extension": "File upload stopped by extension", - "upload.error.formSize": "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the form", - "upload.error.iniPostSize": "The uploaded file exceeds the post_max_size directive in php.ini", - "upload.error.iniSize": "The uploaded file exceeds the upload_max_filesize directive in php.ini", - "upload.error.noFile": "No file was uploaded", - "upload.error.noFiles": "No files were uploaded", - "upload.error.partial": "The uploaded file was only partially uploaded", - "upload.error.tmpDir": "Missing a temporary folder", - "upload.errors": "خطا", - "upload.progress": "در حال بارگذاری...", - - "url": "Url", - "url.placeholder": "https://example.com", - - "user": "کاربر", - "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "تغییر ایمیل", - "user.changeLanguage": "تغییر زبان", - "user.changeName": "تغییر نام این کاربر", - "user.changePassword": "تغییر گذرواژه", - "user.changePassword.new": "گذرواژه جدید", - "user.changePassword.new.confirm": "تایید گذرواژه جدید...", - "user.changeRole": "تغییر نقش", - "user.changeRole.select": "یک نقش جدید را انتخاب کنید", - "user.create": "افزودن کاربر جدید", - "user.delete": "حذف کاربر جاری", - "user.delete.confirm": "آیا واقعا میخواهید {email} را حذف کنید؟", - - "users": "کاربران", - - "version": "\u0646\u0633\u062e\u0647 \u0646\u0631\u0645 \u0627\u0641\u0632\u0627\u0631", - - "view.account": "حساب کاربری شما", - "view.installation": "\u0646\u0635\u0628 \u0648 \u0631\u0627\u0647 \u0627\u0646\u062f\u0627\u0632\u06cc", - "view.languages": "زبان‌ها", - "view.resetPassword": "Reset password", - "view.site": "سایت", - "view.system": "System", - "view.users": "\u06a9\u0627\u0631\u0628\u0631\u0627\u0646", - - "welcome": "خوش آمدید", - "year": "سال", - "yes": "yes" + "account.changeName": "Change your name", + "account.delete": "Delete your account", + "account.delete.confirm": "Do you really want to delete your account? You will be logged out immediately. Your account cannot be recovered.", + + "add": "\u0627\u0641\u0632\u0648\u062f\u0646", + "author": "Author", + "avatar": "\u062a\u0635\u0648\u06cc\u0631 \u067e\u0631\u0648\u0641\u0627\u06cc\u0644", + "back": "بازگشت", + "cancel": "\u0627\u0646\u0635\u0631\u0627\u0641", + "change": "\u0627\u0635\u0644\u0627\u062d", + "close": "\u0628\u0633\u062a\u0646", + "confirm": "تایید", + "collapse": "Collapse", + "collapse.all": "Collapse All", + "copy": "کپی", + "copy.all": "Copy all", + "create": "ایجاد", + + "date": "تاریخ", + "date.select": "یک تاریخ را انتخاب کنید", + + "day": "روز", + "days.fri": "\u062c\u0645\u0639\u0647", + "days.mon": "\u062f\u0648\u0634\u0646\u0628\u0647", + "days.sat": "\u0634\u0646\u0628\u0647", + "days.sun": "\u06cc\u06a9\u0634\u0646\u0628\u0647", + "days.thu": "\u067e\u0646\u062c\u0634\u0646\u0628\u0647", + "days.tue": "\u0633\u0647 \u0634\u0646\u0628\u0647", + "days.wed": "\u0686\u0647\u0627\u0631\u0634\u0646\u0628\u0647", + + "debugging": "Debugging", + + "delete": "\u062d\u0630\u0641", + "delete.all": "Delete all", + + "dialog.files.empty": "No files to select", + "dialog.pages.empty": "No pages to select", + "dialog.users.empty": "No users to select", + + "dimensions": "ابعاد", + "disabled": "Disabled", + "discard": "\u0627\u0646\u0635\u0631\u0627\u0641", + "download": "Download", + "duplicate": "Duplicate", + + "edit": "\u0648\u06cc\u0631\u0627\u06cc\u0634", + + "email": "\u067e\u0633\u062a \u0627\u0644\u06a9\u062a\u0631\u0648\u0646\u06cc\u06a9", + "email.placeholder": "mail@example.com", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Environment", + + "error.access.code": "Invalid code", + "error.access.login": "اطلاعات ورودی نامعتبر است", + "error.access.panel": "شما اجازه دسترسی به پانل را ندارید", + "error.access.view": "You are not allowed to access this part of the panel", + + "error.avatar.create.fail": "بارگزاری تصویر پروفایل موفق نبود", + "error.avatar.delete.fail": "\u062a\u0635\u0648\u06cc\u0631 \u067e\u0631\u0648\u0641\u0627\u06cc\u0644 \u0631\u0627 \u0646\u0645\u06cc\u062a\u0648\u0627\u0646 \u062d\u0630\u0641 \u06a9\u0631\u062f", + "error.avatar.dimensions.invalid": "لطفا طول و عرض تصویر پروفایل را زیر 3000 پیکسل انتخاب کنید", + "error.avatar.mime.forbidden": "تصویر پروفایل باید از نوع JPEG یا PNG باشد", + + "error.blueprint.notFound": "بلوپرینت با نام «{name}» قابل بارگذاری نیست", + + "error.blocks.max.plural": "You must not add more than {max} blocks", + "error.blocks.max.singular": "You must not add more than one block", + "error.blocks.min.plural": "You must add at least {min} blocks", + "error.blocks.min.singular": "You must add at least one block", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "قالب ایمیل «{name}» پیدا نشد", + + "error.field.converter.invalid": "مبدل «{converter}» نامعتبر است", + + "error.file.changeName.empty": "The name must not be empty", + "error.file.changeName.permission": "شما اجازه تنغییر نام فایل «{filename}» را ندارید", + "error.file.duplicate": "فایلی هم نام با «{filename}» هم اکنون موجود است", + "error.file.extension.forbidden": "پسوند فایل «{extension}» غیرمجاز است", + "error.file.extension.invalid": "Invalid extension: {extension}", + "error.file.extension.missing": "\u0634\u0645\u0627 \u0646\u0645\u06cc\u200c\u062a\u0648\u0627\u0646\u06cc\u062f \u0641\u0627\u06cc\u0644\u200c\u0647\u0627\u06cc \u0628\u062f\u0648\u0646 \u067e\u0633\u0648\u0646\u062f \u0631\u0627 \u0622\u067e\u0644\u0648\u062f \u06a9\u0646\u06cc\u062f", + "error.file.maxheight": "The height of the image must not exceed {height} pixels", + "error.file.maxsize": "The file is too large", + "error.file.maxwidth": "The width of the image must not exceed {width} pixels", + "error.file.mime.differs": "فایل آپلود شده باید از همان نوع باشد «{mime}»", + "error.file.mime.forbidden": "فرمت فایل «{mime}» غیرمجاز است", + "error.file.mime.invalid": "Invalid mime type: {mime}", + "error.file.mime.missing": "فرمت فایل «{filename}» قابل شناسایی نیست", + "error.file.minheight": "The height of the image must be at least {height} pixels", + "error.file.minsize": "The file is too small", + "error.file.minwidth": "The width of the image must be at least {width} pixels", + "error.file.name.missing": "نام فایل اجباری است", + "error.file.notFound": "فایل «{filename}» پیدا نشد.", + "error.file.orientation": "The orientation of the image must be \"{orientation}\"", + "error.file.type.forbidden": "شما اجازه بارگذاری فایلهای «{type}» را ندارید", + "error.file.type.invalid": "Invalid file type: {type}", + "error.file.undefined": "\u0641\u0627\u06cc\u0644 \u0645\u0648\u0631\u062f \u0646\u0638\u0631 \u067e\u06cc\u062f\u0627 \u0646\u0634\u062f.", + + "error.form.incomplete": "لطفا کلیه خطاهای فرم را برطرف کنید", + "error.form.notSaved": "امکان دخیره فرم وجود ندارد", + + "error.language.code": "Please enter a valid code for the language", + "error.language.duplicate": "The language already exists", + "error.language.name": "Please enter a valid name for the language", + "error.language.notFound": "The language could not be found", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "There's an error in layout {index} settings", + + "error.license.format": "Please enter a valid license key", + "error.license.email": "لطفا ایمیل صحیحی وارد کنید", + "error.license.verification": "The license could not be verified", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "The Panel is currently offline", + + "error.page.changeSlug.permission": "شما امکان تغییر پسوند Url صفحه «{slug}» را ندارید", + "error.page.changeStatus.incomplete": "صفحه حاوی خطا است و قابل انتشار نیست", + "error.page.changeStatus.permission": "وضعیت صفحه جاری قابل تغییر نیست", + "error.page.changeStatus.toDraft.invalid": "صفحه «{slug}» قابل تبدیل به پیش نویس نیست", + "error.page.changeTemplate.invalid": "قالب صفحه «{slug}» قابل تغییر نیست", + "error.page.changeTemplate.permission": "شما اجازه تغییر قالب «{slug}» را ندارید", + "error.page.changeTitle.empty": "عنوان اجباری است", + "error.page.changeTitle.permission": "شما اجازه تغییر عنوان «{slug}» را ندارید", + "error.page.create.permission": "شما اجازه ایجاد «{slug}» را ندارید", + "error.page.delete": "حذف صفحه «{slug}» ممکن نیست", + "error.page.delete.confirm": "جهت ادامه عنوان صفحه را وارد کنید", + "error.page.delete.hasChildren": "این صفحه جاوی زیرصفحه است و نمی تواند حذف شود", + "error.page.delete.permission": "شما اجازه حذف «{slug}» را ندارید", + "error.page.draft.duplicate": "صفحه پیش‌نویسی با پسوند Url مشابه «{slug}» هم اکنون موجود است", + "error.page.duplicate": "صفحه‌ای با آدرس Url مشابه «{slug}» هم اکنون موجود است", + "error.page.duplicate.permission": "You are not allowed to duplicate \"{slug}\"", + "error.page.notFound": "صفحه مورد نظر با آدرس «{slug}» پیدا نشد.", + "error.page.num.invalid": "لطفا شماره ترتیب را بدرستی وارد نمایید. اعداد نباید منفی باشند.", + "error.page.slug.invalid": "Please enter a valid URL appendix", + "error.page.slug.maxlength": "Slug length must be less than \"{length}\" characters", + "error.page.sort.permission": "امکان مرتب‌سازی «{slug}» نیست", + "error.page.status.invalid": "لطفا وضعیت صحیحی برای صفحه انتخاب کنید", + "error.page.undefined": "صفحه مورد نظر پیدا نشد", + "error.page.update.permission": "شما اجازه بروزرسانی «{slug}» را ندارید", + + "error.section.files.max.plural": "نباید بیش از {max} فایل به بخش «{section}» اضافه کنید", + "error.section.files.max.singular": "نباید بیش از یک فایل به بخش «{section}» اضافه کنید", + "error.section.files.min.plural": "The \"{section}\" section requires at least {min} files", + "error.section.files.min.singular": "The \"{section}\" section requires at least one file", + + "error.section.pages.max.plural": "نباید بیش از {max} صفحه به بخش «{section}» اضافه کنید", + "error.section.pages.max.singular": "نباید بیش از یک صفحه به بخش «{section}» اضافه کنید", + "error.section.pages.min.plural": "The \"{section}\" section requires at least {min} pages", + "error.section.pages.min.singular": "The \"{section}\" section requires at least one page", + + "error.section.notLoaded": "بخش «{name}» قابل بارکذاری نیست", + "error.section.type.invalid": "نوع بخش «{type}» غیرمجاز است", + + "error.site.changeTitle.empty": "عنوان اجباری است", + "error.site.changeTitle.permission": "شما اجازه تغییر عنوان سایت را ندارید", + "error.site.update.permission": "شما اجازه بروزرسانی سایت را ندارید", + + "error.template.default.notFound": "قالب پیش فرض موجود نیست", + + "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "شما اجازه تغییر ایمیل کاربر «{name}» را ندارید", + "error.user.changeLanguage.permission": "شما اجازه تغییر زبان برای کاربر «{name}» را ندارید", + "error.user.changeName.permission": "شما اجازه تنغییر نام کاربر «{name}» را ندارید", + "error.user.changePassword.permission": "شما اجازه تغییر رمز عبور کاربر «{name}» را ندارید", + "error.user.changeRole.lastAdmin": "نقش آخرین مدیر سیستم قابل تغییر نیست", + "error.user.changeRole.permission": "شما اجازه تغییر نقش کاربر «{name}» را ندارید", + "error.user.changeRole.toAdmin": "You are not allowed to promote someone to the admin role", + "error.user.create.permission": "شما اجازه ایجاد این کاربر را ندارید", + "error.user.delete": "کاربر «{name}» نمی تواند حذف شود", + "error.user.delete.lastAdmin": "\u062d\u0630\u0641 \u0622\u062e\u0631\u06cc\u0646 \u0645\u062f\u06cc\u0631 \u0633\u06cc\u0633\u062a\u0645 \u0645\u0645\u06a9\u0646 \u0646\u06cc\u0633\u062a", + "error.user.delete.lastUser": "حذف آخرین کاربر ممکن نیست", + "error.user.delete.permission": "شما اجازه حذف کاربر «{name}» را ندارید", + "error.user.duplicate": "کاربری با ایمیل «{email}» هم اکنون موجود است", + "error.user.email.invalid": "لطفا یک ایمیل معتبر وارد کنید", + "error.user.language.invalid": "لطفا زبان معتبری انتخاب کنید", + "error.user.notFound": "کاربر «{name}» پیدا نشد", + "error.user.password.invalid": "لطفا گذرواژه صحیحی با حداقل طول 8 حرف وارد کنید. ", + "error.user.password.notSame": "\u0644\u0637\u0641\u0627 \u062a\u06a9\u0631\u0627\u0631 \u06af\u0630\u0631\u0648\u0627\u0698\u0647 \u0631\u0627 \u0648\u0627\u0631\u062f \u0646\u0645\u0627\u06cc\u06cc\u062f", + "error.user.password.undefined": "کاربر فاقد گذرواژه است", + "error.user.password.wrong": "Wrong password", + "error.user.role.invalid": "لطفا نقش صحیحی وارد نمایید", + "error.user.undefined": "کاربر مورد نظر پیدا نشد", + "error.user.update.permission": "شما اجازه بروزرسانی کاربر «{name}» را ندارید", + + "error.validation.accepted": "لطفا تایید کنید", + "error.validation.alpha": "لطفا تنها از بین حروف a-z انتخاب کنید", + "error.validation.alphanum": "لطفا تنها از بین حروف a-z و اعداد 0-9 انتخاب کنید", + "error.validation.between": "لطفا مقداری مابین «{min}» و «{max}» وارد کنید", + "error.validation.boolean": "لطفا تایید یا رد کنید", + "error.validation.contains": "لطفا مقداری شامل «{needle}» وارد کنید", + "error.validation.date": "لطفا تاریخ معتبری وارد کنید", + "error.validation.date.after": "Please enter a date after {date}", + "error.validation.date.before": "Please enter a date before {date}", + "error.validation.date.between": "Please enter a date between {min} and {max}", + "error.validation.denied": "لطفا رد کنید", + "error.validation.different": "مقدار نباید مساوی «{other}» باشد", + "error.validation.email": "لطفا ایمیل صحیحی وارد کنید", + "error.validation.endswith": "مقدار باید با «{end}» ختم شود", + "error.validation.filename": "لطفا نام فایل صحیحی وارد کنید", + "error.validation.in": "لطفا یکی از مقادیر روبرو را وارد کنید: ({in})", + "error.validation.integer": "لطفا عدد صحیحی وارد کنید", + "error.validation.ip": "لطفا IP آدرس صحیحی وارد کنید", + "error.validation.less": "لطفا مقداری کمتر از {max} وارد کنید", + "error.validation.match": "مقدار وارد شده با الگوی مورد نظر همخوانی ندارد", + "error.validation.max": "لطفا مقداری کوچکتر یا مساوی {min} وارد کنید", + "error.validation.maxlength": "لطفا عبارت کوتاه‌تری وارد کنید. (حداکثر {max} حرف)", + "error.validation.maxwords": "لطفا بیش از {max} کلمه وارد نکنید", + "error.validation.min": "لطفا مقداری بزرگتر یا مساوی با {min} وارد کنید", + "error.validation.minlength": "لطفا عبارتی طولانی‌تری وارد کنید. (حداقل {min} حرف)", + "error.validation.minwords": "لطفا حداقل {min} کلمه وارد کنید", + "error.validation.more": "لطفا مقداری بیش از {min} وارد کنید", + "error.validation.notcontains": "لطفا مقداری فاقد «{needle}» وارد کنید", + "error.validation.notin": "لطفا از مقادیر روبرو استفاده نکنید: ({notin})", + "error.validation.option": "لطفا گزینه معتبری انتخاب کنید", + "error.validation.num": "لطفا عدد صحیحی وارد کنید", + "error.validation.required": "لطفا مقداری وارد کنید", + "error.validation.same": "لطفا مقدار «{other}» را وارد کنید", + "error.validation.size": "اندازه ورودی باید معادل «{size}» باشد", + "error.validation.startswith": "مقدار باید با «{start}» شروع شود", + "error.validation.time": "لطفا زمان معتبری وارد کنید", + "error.validation.time.after": "Please enter a time after {time}", + "error.validation.time.before": "Please enter a time before {time}", + "error.validation.time.between": "Please enter a time between {min} and {max}", + "error.validation.url": "لطفا آدرس URL صحیح وارد کنید", + + "expand": "Expand", + "expand.all": "Expand All", + + "field.required": "The field is required", + "field.blocks.changeType": "Change type", + "field.blocks.code.name": "کد", + "field.blocks.code.language": "زبان", + "field.blocks.code.placeholder": "Your code …", + "field.blocks.delete.confirm": "Do you really want to delete this block?", + "field.blocks.delete.confirm.all": "Do you really want to delete all blocks?", + "field.blocks.delete.confirm.selected": "Do you really want to delete the selected blocks?", + "field.blocks.empty": "No blocks yet", + "field.blocks.fieldsets.label": "Please select a block type …", + "field.blocks.fieldsets.paste": "Press {{ shortcut }} to paste/import blocks from your clipboard", + "field.blocks.gallery.name": "Gallery", + "field.blocks.gallery.images.empty": "No images yet", + "field.blocks.gallery.images.label": "Images", + "field.blocks.heading.level": "Level", + "field.blocks.heading.name": "Heading", + "field.blocks.heading.text": "Text", + "field.blocks.heading.placeholder": "Heading …", + "field.blocks.image.alt": "Alternative text", + "field.blocks.image.caption": "Caption", + "field.blocks.image.crop": "Crop", + "field.blocks.image.link": "پیوند", + "field.blocks.image.location": "Location", + "field.blocks.image.name": "تصویر", + "field.blocks.image.placeholder": "Select an image", + "field.blocks.image.ratio": "Ratio", + "field.blocks.image.url": "Image URL", + "field.blocks.line.name": "Line", + "field.blocks.list.name": "List", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Text", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Quote", + "field.blocks.quote.text.label": "Text", + "field.blocks.quote.text.placeholder": "Quote …", + "field.blocks.quote.citation.label": "Citation", + "field.blocks.quote.citation.placeholder": "by …", + "field.blocks.text.name": "Text", + "field.blocks.text.placeholder": "Text …", + "field.blocks.video.caption": "Caption", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Enter a video URL", + "field.blocks.video.url.label": "Video-URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "فایلی انتخاب نشده است", + + "field.layout.delete": "Delete layout", + "field.layout.delete.confirm": "Do you really want to delete this layout?", + "field.layout.empty": "No rows yet", + "field.layout.select": "Select a layout", + + "field.object.empty": "No information yet", + + "field.pages.empty": "صفحه‌ای انتخاب نشده است", + + "field.structure.delete.confirm": "\u0645\u062f\u062e\u0644 \u062c\u0627\u0631\u06cc \u062d\u0630\u0641 \u0634\u0648\u062f\u061f", + "field.structure.empty": "\u0645\u0648\u0631\u062f\u06cc \u0648\u062c\u0648\u062f \u0646\u062f\u0627\u0631\u062f.", + + "field.users.empty": "کاربری انتخاب نشده است", + + "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "آیا واقعا می خواهید این فایل را حذف کنید؟
{filename}", + "file.sort": "Change position", + + "files": "فایل‌ها", + "files.empty": "فایلی موجود نیست", + + "hide": "Hide", + "hour": "ساعت", + "import": "Import", + "info": "Info", + "insert": "\u062f\u0631\u062c", + "insert.after": "Insert after", + "insert.before": "Insert before", + "install": "نصب", + + "installation": "نصب و راه اندازی", + "installation.completed": "پنل کاربری نصب شد", + "installation.disabled": "نصب کننده پانل کاربری بصورت پیش‌فرض در سرورهای عمومی غیرفعال است. لطفا نصب را روی یک ماشین محلی اجرا کنید یا آن را با استفاده از panel.install فعال کنید.", + "installation.issues.accounts": "پوشه /site/accounts موجود نیست یا قابل نوشتن نیست.", + "installation.issues.content": "پوشه /content موجود نیست یا قابل نوشتن نیست", + "installation.issues.curl": "افزونه CURL مورد نیاز است", + "installation.issues.headline": "نصب پانل کاربری ممکن نیست", + "installation.issues.mbstring": "افزونه MB String مورد نیاز است", + "installation.issues.media": "پوشه /media موجود نیست یا قابل نوشتن نیست", + "installation.issues.php": "لطفا از پی‌اچ‌پی 7 یا بالاتر استفاده کنید", + "installation.issues.server": "کربی نیاز به Apache، Nginx یا Caddy دارد", + "installation.issues.sessions": "پوشه /site/sessions وجود ندارد یا قابل نوشتن نیست", + + "language": "\u0632\u0628\u0627\u0646", + "language.code": "کد", + "language.convert": "پیش‌فرض شود", + "language.convert.confirm": "

آیا واقعا میخواهید {name} را به زبان پیشفرض تبدیل کنید؟ این عمل برگشت ناپذیر است.

اگر {name} دارای محتوای غیر ترجمه شده باشد، جایگزین معتبر دیگری نخواهد بود و ممکن است بخش‌هایی از سایت شما خالی باشد.

", + "language.create": "افزودن زبان جدید", + "language.delete.confirm": "آیا واقعا میخواهید زبان {name} را به همراه تمام ترجمه‌ها حذف کنید؟ این عمل قابل بازگشت نخواهد بود!", + "language.deleted": "زبان مورد نظر حذف شد", + "language.direction": "rtl", + "language.direction.ltr": "چپ به راست", + "language.direction.rtl": "راست به چپ", + "language.locale": "PHP locale string", + "language.locale.warning": "You are using a custom locale set up. Please modify it in the language file in /site/languages", + "language.name": "پارسی", + "language.updated": "زبان به روز شد", + + "languages": "زبان‌ها", + "languages.default": "زبان پیش‌فرض", + "languages.empty": "هنوز هیچ زبانی موجود نیست", + "languages.secondary": "زبان‌های ثانویه", + "languages.secondary.empty": "هنوز هیچ زبان ثانویه‌ای موجود نیست", + + "license": "\u0645\u062c\u0648\u0632", + "license.buy": "خرید مجوز", + "license.register": "ثبت", + "license.manage": "Manage your licenses", + "license.register.help": "پس از خرید از طریق ایمیل، کد مجوز خود را دریافت کردید. لطفا برای ثبت‌نام آن را کپی و اینجا پیست کنید.", + "license.register.label": "لطفا کد مجوز خود را وارد کنید", + "license.register.success": "با تشکر از شما برای حمایت از کربی", + "license.unregistered": "این یک نسخه آزمایشی ثبت نشده از کربی است", + "license.unregistered.label": "Unregistered", + + "link": "\u067e\u06cc\u0648\u0646\u062f", + "link.text": "\u0645\u062a\u0646 \u067e\u06cc\u0648\u0646\u062f", + + "loading": "بارگزاری", + + "lock.unsaved": "Unsaved changes", + "lock.unsaved.empty": "There are no more unsaved changes", + "lock.isLocked": "Unsaved changes by {email}", + "lock.file.isLocked": "The file is currently being edited by {email} and cannot be changed.", + "lock.page.isLocked": "The page is currently being edited by {email} and cannot be changed.", + "lock.unlock": "Unlock", + "lock.isUnlocked": "Your unsaved changes have been overwritten by another user. You can download your changes to merge them manually.", + + "login": "ورود", + "login.code.label.login": "Login code", + "login.code.label.password-reset": "Password reset code", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "If your email address is registered, the requested code was sent via email.", + "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.login.subject": "Your login code", + "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.password-reset.subject": "Your password reset code", + "login.remember": "مرا به خاطر بسپار", + "login.reset": "Reset password", + "login.toggleText.code.email": "Login via email", + "login.toggleText.code.email-password": "Login with password", + "login.toggleText.password-reset.email": "Forgot your password?", + "login.toggleText.password-reset.email-password": "← Back to login", + + "logout": "خروج", + + "menu": "منو", + "meridiem": "ق.ظ/ب.ظ", + "mime": "نوع رسانه", + "minutes": "دقیقه", + + "month": "ماه", + "months.april": "\u0622\u0648\u0631\u06cc\u0644", + "months.august": "\u0627\u0648\u062a", + "months.december": "\u062f\u0633\u0627\u0645\u0628\u0631", + "months.february": "فوریه", + "months.january": "\u0698\u0627\u0646\u0648\u06cc\u0647", + "months.july": "\u0698\u0648\u0626\u06cc\u0647", + "months.june": "\u0698\u0648\u0626\u0646", + "months.march": "\u0645\u0627\u0631\u0633", + "months.may": "\u0645\u06cc", + "months.november": "\u0646\u0648\u0627\u0645\u0628\u0631", + "months.october": "\u0627\u06a9\u062a\u0628\u0631", + "months.september": "\u0633\u067e\u062a\u0627\u0645\u0628\u0631", + + "more": "بیشتر", + "name": "نام", + "next": "بعدی", + "no": "no", + "off": "off", + "on": "on", + "open": "بازکردن", + "open.newWindow": "Open in new window", + "options": "گزینه‌ها", + "options.none": "No options", + + "orientation": "جهت", + "orientation.landscape": "افقی", + "orientation.portrait": "عمودی", + "orientation.square": "مربع", + + "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "تغییر Url صفحه", + "page.changeSlug.fromTitle": "\u0627\u06cc\u062c\u0627\u062f \u0627\u0632 \u0631\u0648\u06cc \u0639\u0646\u0648\u0627\u0646", + "page.changeStatus": "تغییر وضعیت", + "page.changeStatus.position": "لطفا یک موقعیت را انتخاب کنید", + "page.changeStatus.select": "یک وضعیت جدید را انتخاب کنید", + "page.changeTemplate": "تغییر قالب", + "page.delete.confirm": "صفحه {title} حذف شود؟", + "page.delete.confirm.subpages": "این صفحه دارای زیرصفحه است.
تمام زیر صفحات نیز حذف خواهد شد.", + "page.delete.confirm.title": "جهت ادامه عنوان صفحه را وارد کنید", + "page.draft.create": "ایجاد پیش‌نویس", + "page.duplicate.appendix": "کپی", + "page.duplicate.files": "Copy files", + "page.duplicate.pages": "Copy pages", + "page.sort": "Change position", + "page.status": "وضعیت", + "page.status.draft": "پیش‌نویس", + "page.status.draft.description": "The page is in draft mode and only visible for logged in editors or via secret link", + "page.status.listed": "عمومی", + "page.status.listed.description": "این صفحه برای عموم قابل مشاهده است", + "page.status.unlisted": "فهرست نشده", + "page.status.unlisted.description": "این صفحه فقط از طریق URL قابل دسترسی است", + + "pages": "صفحات", + "pages.empty": "هنوز هیچ صفحه‌ای موجود نیست", + "pages.status.draft": "پیش‌نویس‌ها", + "pages.status.listed": "منتشر شده", + "pages.status.unlisted": "فهرست نشده", + + "pagination.page": "صفحه", + + "password": "\u06af\u0630\u0631\u0648\u0627\u0698\u0647", + "paste": "Paste", + "paste.after": "Paste after", + "pixel": "پیکسل", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "قبلی", + "preview": "Preview", + "remove": "حذف", + "rename": "تغییر نام", + "replace": "\u062c\u0627\u06cc\u06af\u0632\u06cc\u0646\u06cc", + "retry": "\u062a\u0644\u0627\u0634 \u0645\u062c\u062f\u062f", + "revert": "بازگرداندن تغییرات", + "revert.confirm": "Do you really want to delete all unsaved changes?", + + "role": "\u0646\u0642\u0634", + "role.admin.description": "The admin has all rights", + "role.admin.title": "Admin", + "role.all": "همه", + "role.empty": "هیچ کاربری با این نقش وجود ندارد", + "role.description.placeholder": "فاقد شرح", + "role.nobody.description": "This is a fallback role without any permissions", + "role.nobody.title": "Nobody", + + "save": "\u0630\u062e\u06cc\u0631\u0647", + "search": "جستجو", + "search.min": "Enter {min} characters to search", + "search.all": "Show all", + "search.results.none": "No results", + + "section.required": "The section is required", + + "security": "Security", + "select": "انتخاب", + "server": "Server", + "settings": "تنظیمات", + "show": "Show", + "site.blueprint": "The site has no blueprint yet. You can define the setup in /site/blueprints/site.yml", + "size": "اندازه", + "slug": "پسوند Url", + "sort": "ترتیب", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "عنوان", + "template": "\u0642\u0627\u0644\u0628 \u0635\u0641\u062d\u0647", + "today": "امروز", + + "toolbar.button.code": "کد", + "toolbar.button.bold": "\u0645\u062a\u0646 \u0628\u0627 \u062d\u0631\u0648\u0641 \u062f\u0631\u0634\u062a", + "toolbar.button.email": "\u067e\u0633\u062a \u0627\u0644\u06a9\u062a\u0631\u0648\u0646\u06cc\u06a9", + "toolbar.button.headings": "عنوان‌ها", + "toolbar.button.heading.1": "عنوان 1", + "toolbar.button.heading.2": "عنوان 2", + "toolbar.button.heading.3": "عنوان 3", + "toolbar.button.heading.4": "Heading 4", + "toolbar.button.heading.5": "Heading 5", + "toolbar.button.heading.6": "Heading 6", + "toolbar.button.italic": "\u0645\u062a\u0646 \u0627\u0631\u06cc\u0628", + "toolbar.button.file": "فایل", + "toolbar.button.file.select": "Select a file", + "toolbar.button.file.upload": "Upload a file", + "toolbar.button.link": "\u067e\u06cc\u0648\u0646\u062f", + "toolbar.button.paragraph": "Paragraph", + "toolbar.button.strike": "Strike-through", + "toolbar.button.ol": "لیست مرتب", + "toolbar.button.underline": "Underline", + "toolbar.button.ul": "لیست معمولی", + + "translation.author": "تیم کربی", + "translation.direction": "rtl", + "translation.name": "انگلیسی", + "translation.locale": "fa_IR", + + "upload": "بارگذاری", + "upload.error.cantMove": "The uploaded file could not be moved", + "upload.error.cantWrite": "Failed to write file to disk", + "upload.error.default": "The file could not be uploaded", + "upload.error.extension": "File upload stopped by extension", + "upload.error.formSize": "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the form", + "upload.error.iniPostSize": "The uploaded file exceeds the post_max_size directive in php.ini", + "upload.error.iniSize": "The uploaded file exceeds the upload_max_filesize directive in php.ini", + "upload.error.noFile": "No file was uploaded", + "upload.error.noFiles": "No files were uploaded", + "upload.error.partial": "The uploaded file was only partially uploaded", + "upload.error.tmpDir": "Missing a temporary folder", + "upload.errors": "خطا", + "upload.progress": "در حال بارگذاری...", + + "url": "Url", + "url.placeholder": "https://example.com", + + "user": "کاربر", + "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "تغییر ایمیل", + "user.changeLanguage": "تغییر زبان", + "user.changeName": "تغییر نام این کاربر", + "user.changePassword": "تغییر گذرواژه", + "user.changePassword.new": "گذرواژه جدید", + "user.changePassword.new.confirm": "تایید گذرواژه جدید...", + "user.changeRole": "تغییر نقش", + "user.changeRole.select": "یک نقش جدید را انتخاب کنید", + "user.create": "افزودن کاربر جدید", + "user.delete": "حذف کاربر جاری", + "user.delete.confirm": "آیا واقعا میخواهید {email} را حذف کنید؟", + + "users": "کاربران", + + "version": "\u0646\u0633\u062e\u0647 \u0646\u0631\u0645 \u0627\u0641\u0632\u0627\u0631", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "حساب کاربری شما", + "view.installation": "\u0646\u0635\u0628 \u0648 \u0631\u0627\u0647 \u0627\u0646\u062f\u0627\u0632\u06cc", + "view.languages": "زبان‌ها", + "view.resetPassword": "Reset password", + "view.site": "سایت", + "view.system": "System", + "view.users": "\u06a9\u0627\u0631\u0628\u0631\u0627\u0646", + + "welcome": "خوش آمدید", + "year": "سال", + "yes": "yes" } diff --git a/kirby/i18n/translations/fi.json b/kirby/i18n/translations/fi.json index 49b70c1..ccc63eb 100644 --- a/kirby/i18n/translations/fi.json +++ b/kirby/i18n/translations/fi.json @@ -1,573 +1,596 @@ { - "account.changeName": "Muuta nimesi", - "account.delete": "Poista tilisi", - "account.delete.confirm": "Haluatko varmasti poistaa tilisi? Sinut kirjataan ulos välittömästi, eikä tiliäsi voi palauttaa.", - - "add": "Lis\u00e4\u00e4", - "author": "Tekijä", - "avatar": "Profiilikuva", - "back": "Takaisin", - "cancel": "Peruuta", - "change": "Muuta", - "close": "Sulje", - "confirm": "Ok", - "collapse": "Pienennä", - "collapse.all": "Pienennä kaikki", - "copy": "Kopioi", - "copy.all": "Kopioi kaikki", - "create": "Luo", - - "date": "Päivämäärä", - "date.select": "Valitse päivämäärä", - - "day": "Päivä", - "days.fri": "Pe", - "days.mon": "Ma", - "days.sat": "La", - "days.sun": "Su", - "days.thu": "To", - "days.tue": "Ti", - "days.wed": "Ke", - - "debugging": "Debugging", - - "delete": "Poista", - "delete.all": "Poista kaikki", - - "dialog.files.empty": "Ei valittavissa olevia tiedostoja", - "dialog.pages.empty": "Ei valittavissa olevia sivuja", - "dialog.users.empty": "Ei valittavissa olevia käyttäjiä", - - "dimensions": "Mitat", - "disabled": "Pois käytöstä", - "discard": "Hylkää", - "download": "Lataa", - "duplicate": "Kahdenna", - - "edit": "Muokkaa", - - "email": "S\u00e4hk\u00f6posti", - "email.placeholder": "nimi@osoite.fi", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Ympäristö", - - "error.access.code": "Väärä koodi", - "error.access.login": "Kirjautumistiedot eivät kelpaa", - "error.access.panel": "Sinulla ei ole oikeutta käyttää paneelia", - "error.access.view": "Sinulla ei ole oikeutta käyttää tätä osaa paneelista", - - "error.avatar.create.fail": "Profiilikuvaa ei voitu lähettää", - "error.avatar.delete.fail": "Profiilikuvaa ei voitu poistaa", - "error.avatar.dimensions.invalid": "Profiilikuvan leveys ja korkeus voivat olla enintään 3000 pikseliä", - "error.avatar.mime.forbidden": "Profiilikuvan täytyy olla joko JPEG- tai PNG-formaatissa", - - "error.blueprint.notFound": "Suunnitelmaa \"{name}\" ei voitu ladata", - - "error.blocks.max.plural": "Voit lisätä enintään {max} lohkoa", - "error.blocks.max.singular": "Voit lisätä enintään yhden lohkon", - "error.blocks.min.plural": "Lisää vähintään {min} lohkoa", - "error.blocks.min.singular": "Lisää vähintään yksi lohko", - "error.blocks.validation": "Virhe lohkossa {index}", - - "error.email.preset.notFound": "Nimellä \"{name}\" ja kyseisellä verkkotunnuksella ei löydy sähköpostiosoitetta", - - "error.field.converter.invalid": "Muunnin \"{converter}\" ei kelpaa", - - "error.file.changeName.empty": "Nimi ei voi olla tyhjä", - "error.file.changeName.permission": "Sinulla ei ole oikeutta muuttaa tiedoston \"{filename}\" nimeä", - "error.file.duplicate": "Tiedosto nimeltä \"{filename}\" on jo olemassa", - "error.file.extension.forbidden": "Tiedostopääte \"{extension}\" ei ole sallittu", - "error.file.extension.invalid": "Pääte {extension} ei kelpaa", - "error.file.extension.missing": "Tiedoston \"{filename}\" tiedostopääte puuttuu", - "error.file.maxheight": "Kuvan korkeus ei voi ylittää {height} pikseliä", - "error.file.maxsize": "Tiedosto on liian suuri", - "error.file.maxwidth": "Kuvan leveys ei voi ylittää {width} pikseliä", - "error.file.mime.differs": "Lähetetyllä tiedostolla täytyy olla sama mime-tyyppi \"{mime}\"", - "error.file.mime.forbidden": "Median tyyppi \"{mime}\" ei ole sallittu", - "error.file.mime.invalid": "Mime-tyyppi {mime} ei kelpaa", - "error.file.mime.missing": "Tiedoston \"{filename}\" mediatyyppiä ei voida tunnistaa", - "error.file.minheight": "Kuvan korkeus täytyy olla vähintään {height} pikseliä", - "error.file.minsize": "Tiedosto on liian pieni", - "error.file.minwidth": "Kuvan leveys täytyy olla vähintään {width} pikseliä", - "error.file.name.missing": "Tiedostonimi ei voi olla tyhjä", - "error.file.notFound": "Tiedostoa \"{filename}\" ei löytynyt", - "error.file.orientation": "Kuvan suuntaus täytyy olla \"{orientation}\"", - "error.file.type.forbidden": "Sinulla ei ole oikeutta lähettää tiedostoja joiden tyyppi on {type}", - "error.file.type.invalid": "Tiedostotyyppi {type} ei kelpaa", - "error.file.undefined": "Tiedostoa ei l\u00f6ytynyt", - - "error.form.incomplete": "Korjaa kaikki lomakkeen virheet…", - "error.form.notSaved": "Lomaketta ei voitu tallentaa", - - "error.language.code": "Anna kielen lyhenne", - "error.language.duplicate": "Kieli on jo olemassa", - "error.language.name": "Anna kielen nimi", - "error.language.notFound": "Kieltä ei löytynyt", - - "error.layout.validation.block": "Lohkon {blockIndex} asetelmassa {layoutIndex} tapahtui virhe", - "error.layout.validation.settings": "Virhe asetelman {index} asetuksissa", - - "error.license.format": "Anna lisenssiavain", - "error.license.email": "Anna sähköpostiosoite", - "error.license.verification": "Lisenssiä ei voitu vahvistaa", - - "error.offline": "Paneeli on offline-tilassa", - - "error.page.changeSlug.permission": "Sinulla ei ole oikeutta muuttaa URL-liitettä sivulle \"{slug}\"", - "error.page.changeStatus.incomplete": "Sivulla on virheitä eikä sitä voitu julkaista", - "error.page.changeStatus.permission": "Tämän sivun tilaa ei voi muuttaa", - "error.page.changeStatus.toDraft.invalid": "Sivua \"{slug}\" ei voi muuttaa luonnokseksi", - "error.page.changeTemplate.invalid": "Sivun \"{slug}\" pohjaa ei voi muuttaa", - "error.page.changeTemplate.permission": "Sinulla ei ole oikeutta muuttaa sivun \"{slug}\" sivupohjaa", - "error.page.changeTitle.empty": "Nimi ei voi olla tyhjä", - "error.page.changeTitle.permission": "Sinulla ei ole oikeutta muuttaa sivun \"{slug}\" nimeä", - "error.page.create.permission": "Sinulla ei ole oikeutta luoda sivua \"{slug}\"", - "error.page.delete": "Sivua \"{slug}\" ei voi poistaa", - "error.page.delete.confirm": "Anna vahvistuksena sivun nimi", - "error.page.delete.hasChildren": "Sivu sisältää alasivuja eikä sitä voida poistaa", - "error.page.delete.permission": "Sinulla ei ole oikeutta poistaa sivua \"{slug}\"", - "error.page.draft.duplicate": "Sivuluonnos URL-liitteellä \"{slug}\" on jo olemassa", - "error.page.duplicate": "Sivu URL-liitteellä \"{slug}\" on jo olemassa", - "error.page.duplicate.permission": "Sinulla ei ole oikeutta kahdentaa sivua \"{slug}\"", - "error.page.notFound": "Sivua \"{slug}\" ei löytynyt", - "error.page.num.invalid": "Anna kelpaava järjestysnumero. Numero ei voi olla negatiivinen.", - "error.page.slug.invalid": "Anna kelpaava URL-liite", - "error.page.slug.maxlength": "URL-liite täytyy olla vähemmän kuin \"{length}\" merkkiä pitkä", - "error.page.sort.permission": "Sivua \"{slug}\" ei voi järjestellä", - "error.page.status.invalid": "Aseta kelvollinen sivun tila", - "error.page.undefined": "Sivua ei l\u00f6ytynyt", - "error.page.update.permission": "Sinulla ei ole oikeutta päivittää sivua \"{slug}\"", - - "error.section.files.max.plural": "Et voi lisätä enemmän kuin {max} tiedostoa osioon \"{section}\"", - "error.section.files.max.singular": "Et voi lisätä enempää kuin yhden tiedoston osioon \"{section}\"", - "error.section.files.min.plural": "Osio \"{section}\" vaatii ainakin {min} tiedostoa", - "error.section.files.min.singular": "Osio \"{section}\" vaatii ainakin yhden sivun", - - "error.section.pages.max.plural": "Et voi lisätä enemmän kuin {max} sivua osioon \"{section}\"", - "error.section.pages.max.singular": "Et voi lisätä enempää kuin yhden sivun osioon \"{section}\"", - "error.section.pages.min.plural": "Osio \"{section}\" vaatii ainakin {min} sivua", - "error.section.pages.min.singular": "Osio \"{section}\" vaatii ainakin yhden sivun", - - "error.section.notLoaded": "Osiota \"{name}\" ei voitu ladata", - "error.section.type.invalid": "Osion tyyppi \"{type}\" ei ole kelvollinen", - - "error.site.changeTitle.empty": "Nimi ei voi olla tyhjä", - "error.site.changeTitle.permission": "Sinulla ei ole oikeutta päivittää sivuston nimeä", - "error.site.update.permission": "Sinulla ei ole oikeutta päivittää sivuston tietoja", - - "error.template.default.notFound": "Oletussivupohjaa ei ole määritetty", - - "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Sinulla ei ole oikeutta vaihtaa käyttäjän \"{name}\" sähköpostiosoitetta", - "error.user.changeLanguage.permission": "Sinulla ei ole oikeutta vaihtaa käyttäjän \"{name}\" kieltä", - "error.user.changeName.permission": "Sinulla ei ole oikeutta vaihtaa käyttäjän \"{name}\" nimeä", - "error.user.changePassword.permission": "Sinulla ei ole oikeutta vaihtaa käyttäjän \"{name}\" salasanaa", - "error.user.changeRole.lastAdmin": "Ainoan pääkäyttäjän roolia ei voi muuttaa", - "error.user.changeRole.permission": "Sinulla ei ole oikeutta vaihtaa käyttäjän \"{name}\" käyttäjätasoa", - "error.user.changeRole.toAdmin": "Sinulla ei ole oikeutta vaihtaa käyttäjätasoa pääkäyttäjäksi", - "error.user.create.permission": "Sinulla ei ole oikeutta luoda tätä käyttäjää", - "error.user.delete": "Käyttäjää \"{name}\" ei voi poistaa", - "error.user.delete.lastAdmin": "Ainoaa pääkäyttäjää ei voi poistaa", - "error.user.delete.lastUser": "Ainoaa käyttäjää ei voi poistaa", - "error.user.delete.permission": "Sinulla ei ole oikeutta poistaa käyttäjää \"{name}\"", - "error.user.duplicate": "Käyttäjä, jonka sähköpostiosoite on \"{name}\", on jo olemassa", - "error.user.email.invalid": "Anna kelpaava sähköpostiosoite", - "error.user.language.invalid": "Anna kelpaava kieli", - "error.user.notFound": "K\u00e4ytt\u00e4j\u00e4\u00e4 ei l\u00f6ytynyt", - "error.user.password.invalid": "Anna kelpaava salasana. Salasanan täytyy olla ainakin 8 merkkiä pitkä.", - "error.user.password.notSame": "Salasanat eivät täsmää", - "error.user.password.undefined": "Käyttäjällä ei ole salasanaa", - "error.user.password.wrong": "Väärä salasana", - "error.user.role.invalid": "Anna kelpaava käyttäjätaso", - "error.user.undefined": "Käyttäjää ei löytynyt", - "error.user.update.permission": "Sinulla ei ole oikeutta päivittää käyttäjää \"{name}\"", - - "error.validation.accepted": "Ole hyvä ja vahvista", - "error.validation.alpha": "Anna vain merkkejä väliltä a-z", - "error.validation.alphanum": "Anna vain merkkejä väliltä a-z tai/ja numeroita väliltä 0-9", - "error.validation.between": "Anna arvo väliltä \"{min}\" ja \"{max}\"", - "error.validation.boolean": "Vahvista tai peruuta", - "error.validation.contains": "Anna arvo joka sisältää \"{needle}\"", - "error.validation.date": "Anna kelpaava päivämäärä", - "error.validation.date.after": "Anna päivämäärä {date} jälkeen", - "error.validation.date.before": "Anna päivämäärä ennen {date}", - "error.validation.date.between": "Anna päivämäärä väliltä {min} ja {max}", - "error.validation.denied": "Ole hyvä ja peruuta", - "error.validation.different": "Arvo ei voi olla \"{other}\"", - "error.validation.email": "Anna kelpaava sähköpostiosoite", - "error.validation.endswith": "Arvon loppuosa täytyy olla \"{end}\"", - "error.validation.filename": "Anna kelpaava tiedostonimi", - "error.validation.in": "Anna joku seuraavista: ({in})", - "error.validation.integer": "Anna kelpaava kokonaisluku", - "error.validation.ip": "Anna kelpaava IP-osoite", - "error.validation.less": "Anna arvo joka on pienempi kuin {max}", - "error.validation.match": "Arvo ei vastaa vaadittua kaavaa", - "error.validation.max": "Anna arvo joka on enintään {max}", - "error.validation.maxlength": "Anna lyhyempi arvo. (enintään {max} merkkiä)", - "error.validation.maxwords": "Anna korkeintaan {max} sana(a)", - "error.validation.min": "Anna arvo joka on vähintään {min}", - "error.validation.minlength": "Anna pidempi arvo. (vähintään {min} merkkiä)", - "error.validation.minwords": "Anna vähintään {min} sana(a)", - "error.validation.more": "Anna suurempi arvo kuin {min}", - "error.validation.notcontains": "Anna arvo joka ei sisällä \"{needle}\"", - "error.validation.notin": "Arvo ei voi sisältää mitään seuraavista: ({notIn})", - "error.validation.option": "Valitse kelpaava vaihtoehto", - "error.validation.num": "Anna kelpaava numero", - "error.validation.required": "Arvo ei voi olla tyhjä", - "error.validation.same": "Anna \"{other}\"", - "error.validation.size": "Arvon koko täytyy olla \"{size}\"", - "error.validation.startswith": "Arvon alkuosa täytyy olla \"{start}\"", - "error.validation.time": "Anna kelpaava aika", - "error.validation.time.after": "Anna myöhempi aika kuin {time}", - "error.validation.time.before": "Anna aiempi aika kuin {time}", - "error.validation.time.between": "Anna aika väliltä {min} ja {max}", - "error.validation.url": "Anna kelpaava URL", - - "expand": "Laajenna", - "expand.all": "Laajenna kaikki", - - "field.required": "Kenttä on pakollinen", - "field.blocks.changeType": "Vaihda tyyppiä", - "field.blocks.code.name": "Koodi", - "field.blocks.code.language": "Kieli", - "field.blocks.code.placeholder": "Koodisi …", - "field.blocks.delete.confirm": "Haluatko varmasti poistaa tämän lohkon?", - "field.blocks.delete.confirm.all": "Haluatko varmasti poistaa kaikki lohkot?", - "field.blocks.delete.confirm.selected": "Haluatko varmasti poistaa valitut lohkot?", - "field.blocks.empty": "Ei lohkoja", - "field.blocks.fieldsets.label": "Valitse lohkon tyyppi …", - "field.blocks.fieldsets.paste": "Paina {{ shortcut }} liittääksesi tai tuodaksesi lohkoja leikepöydältä", - "field.blocks.gallery.name": "Galleria", - "field.blocks.gallery.images.empty": "Ei kuvia", - "field.blocks.gallery.images.label": "Kuvat", - "field.blocks.heading.level": "Taso", - "field.blocks.heading.name": "Otsikko", - "field.blocks.heading.text": "Teksti", - "field.blocks.heading.placeholder": "Otsikko …", - "field.blocks.image.alt": "Vaihtoehtoinen teksti", - "field.blocks.image.caption": "Kuvateksti", - "field.blocks.image.crop": "Rajaa", - "field.blocks.image.link": "Linkki", - "field.blocks.image.location": "Sijainti", - "field.blocks.image.name": "Kuva", - "field.blocks.image.placeholder": "Valitse kuva", - "field.blocks.image.ratio": "Kuvasuhde", - "field.blocks.image.url": "Kuvan URL", - "field.blocks.line.name": "Line", - "field.blocks.list.name": "Lista", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Teksti", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Lainaus", - "field.blocks.quote.text.label": "Teksti", - "field.blocks.quote.text.placeholder": "Lainaus …", - "field.blocks.quote.citation.label": "Sitaatti", - "field.blocks.quote.citation.placeholder": "Lähde …", - "field.blocks.text.name": "Teksti", - "field.blocks.text.placeholder": "Teksti …", - "field.blocks.video.caption": "Videon teksti", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Anna videon URL", - "field.blocks.video.url.label": "Videon URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Tiedostoja ei ole vielä valittu", - - "field.layout.delete": "Poista asettelu", - "field.layout.delete.confirm": "Halutako varmasti poistaa tämän asettelun?", - "field.layout.empty": "Ei rivejä", - "field.layout.select": "Valitse asettelu", - - "field.pages.empty": " Sivuja ei ole vielä valittu", - "field.structure.delete.confirm": "Haluatko varmasti poistaa tämän rivin?", - "field.structure.empty": "Rivejä ei ole vielä lisätty", - "field.users.empty": "Käyttäjiä ei ole vielä valittu", - - "file.blueprint": "Tällä tiedostolla ei ole vielä suunnitelmaa. Voit määrittää suunnitelman tiedostoon /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Haluatko varmasti poistaa tiedoston
{filename}?", - "file.sort": "Muuta järjestyspaikkaa", - - "files": "Tiedostot", - "files.empty": "Tiedostoja ei ole vielä lisätty", - - "hide": "Piilota", - "hour": "Tunti", - "import": "Tuo", - "info": "Info", - "insert": "Lis\u00e4\u00e4", - "insert.after": "Lisää eteen", - "insert.before": "Lisää jälkeen", - "install": "Asenna", - - "installation": "Asennus", - "installation.completed": "Paneeli on asennettu", - "installation.disabled": "Paneelin asennus on oletuksena poissa käytöstä julkisilla palvelimilla. Aja asennus paikallisella koneella, tai ota paneeli käyttöön panel.install-optiolla.", - "installation.issues.accounts": "/site/accounts -kansio ei ole olemassa tai siihen ei voi kirjoittaa", - "installation.issues.content": "/content -kansio ei ole olemassa tai siihen ei voi kirjoittaa", - "installation.issues.curl": "CURL-laajennos on pakollinen", - "installation.issues.headline": "Paneelia ei voida asentaa", - "installation.issues.mbstring": "MB String-laajennos on pakollinen", - "installation.issues.media": "/media -kansio ei ole olemassa tai siihen ei voi kirjoittaa", - "installation.issues.php": "Varmista että PHP 7+ on käytössä", - "installation.issues.server": "Kirby tarvitsee jonkun seuraavista: Apache, Nginx tai Caddy", - "installation.issues.sessions": "/site/sessions -kansio ei ole olemassa tai siihen ei voi kirjoittaa", - - "language": "Kieli", - "language.code": "Tunniste", - "language.convert": "Muuta oletukseksi", - "language.convert.confirm": "

Haluatko varmasti muuttaa kielen {name} oletuskieleksi? Tätä muutosta ei voi peruuttaa.

Jos{name} sisältää kääntämättömiä kohtia, varakäännöstä ei enää ole näille kohdille ja sivustosi saattaa olla osittain tyhjä.

", - "language.create": "Lisää uusi kieli", - "language.delete.confirm": "Haluatko varmasti poistaa kielen {name}, mukaanlukien kaikki käännökset? Tätä toimintoa ei voi peruuttaa!", - "language.deleted": "Kieli on poistettu", - "language.direction": "Lukusuunta", - "language.direction.ltr": "Vasemmalta oikealle", - "language.direction.rtl": "Oikealta vasemmalle", - "language.locale": "PHP-aluemäärityksen tunniste", - "language.locale.warning": "Käytät mukautettua aluemääritystä. Muokkaa sitä kielitiedostossa /site/languages", - "language.name": "Nimi", - "language.updated": "Kieli on päivitetty", - - "languages": "Kielet", - "languages.default": "Oletuskieli", - "languages.empty": "Kieliä ei ole vielä määritetty", - "languages.secondary": "Toissijaiset kielet", - "languages.secondary.empty": "Toissijaisia kieliä ei ole vielä määritetty", - - "license": "Lisenssi", - "license.buy": "Osta lisenssi", - "license.register": "Rekisteröi", - "license.manage": "Manage your licenses", - "license.register.help": "Lisenssiavain on lähetetty oston jälkeen sähköpostiisi. Kopioi ja liitä avain tähän.", - "license.register.label": "Anna lisenssiavain", - "license.register.success": "Kiitos kun tuet Kirbyä", - "license.unregistered": "Tämä on rekisteröimätön demo Kirbystä", - "license.unregistered.label": "Unregistered", - - "link": "Linkki", - "link.text": "Linkin teksti", - - "loading": "Ladataan", - - "lock.unsaved": "Tallentamattomia muutoksia", - "lock.unsaved.empty": "Ei enempää tallentamattomia muutoksia ", - "lock.isLocked": "Käyttäjällä {email} on tallentamattomia muutoksia", - "lock.file.isLocked": "Tiedostoa ei voi muokata juuri nyt, sillä {email} on muokkaamassa tiedostoa.", - "lock.page.isLocked": "Sivua ei voi muokata juuri nyt, sillä {email} on muokkaamassa sivua.", - "lock.unlock": "Vapauta", - "lock.isUnlocked": "Toinen käyttäjä ylikirjoitti tallentamattomat muutoksesi. Voit ladata tekemäsi muutokset ja lisätä ne käsin.", - - "login": "Kirjaudu", - "login.code.label.login": "Kirjautumiskoodi", - "login.code.label.password-reset": "Salasanan asetuskoodi", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "Jos sähköpostiosoitteesi on rekisteröity, tilaamasi koodi lähetetään tähän osoitteeseen.", - "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.login.subject": "Kirjautumiskoodisi", - "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.password-reset.subject": "Salasanan asetuskoodisi", - "login.remember": "Pidä minut kirjautuneena", - "login.reset": "Aseta salasana", - "login.toggleText.code.email": "Kirjaudu sähköpostiosoitteella", - "login.toggleText.code.email-password": "Kirjaudu salasanalla", - "login.toggleText.password-reset.email": "Unohditko salasanasi?", - "login.toggleText.password-reset.email-password": "← Takaisin kirjautumiseen", - - "logout": "Kirjaudu ulos", - - "menu": "Valikko", - "meridiem": "am/pm", - "mime": "Median tyyppi", - "minutes": "Minuutit", - - "month": "Kuukausi", - "months.april": "Huhtikuu", - "months.august": "Elokuu", - "months.december": "Joulukuu", - "months.february": "Helmikuu", - "months.january": "Tammikuu", - "months.july": "Hein\u00e4kuu", - "months.june": "Kes\u00e4kuu", - "months.march": "Maaliskuu", - "months.may": "Toukokuu", - "months.november": "Marraskuu", - "months.october": "Lokakuu", - "months.september": "Syyskuu", - - "more": "Lisää", - "name": "Nimi", - "next": "Seuraava", - "no": "ei", - "off": "Pois käytöstä", - "on": "Käytössä", - "open": "Avaa", - "open.newWindow": "Avaa uudessa ikkunassa", - "options": "Asetukset", - "options.none": "Ei valintoja", - - "orientation": "Suunta", - "orientation.landscape": "Vaakasuuntainen", - "orientation.portrait": "Pystysuuntainen", - "orientation.square": "Neliskulmainen", - - "page.blueprint": "Tällä sivulla ei ole vielä suunnitelmaa. Voit määrittää suunnitelman tiedostoon /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Vaihda URL-osoite", - "page.changeSlug.fromTitle": "Luo nimen perusteella", - "page.changeStatus": "Muuta tilaa", - "page.changeStatus.position": "Valitse järjestyspaikka", - "page.changeStatus.select": "Valitse uusi tila", - "page.changeTemplate": "Vaihda sivupohja", - "page.delete.confirm": "Haluatko varmasti poistaa sivun {title}?", - "page.delete.confirm.subpages": "Tällä sivulla on alasivuja.
Myös kaikki alasivut poistetaan.", - "page.delete.confirm.title": "Anna vahvistuksena sivun nimi", - "page.draft.create": "Uusi luonnos", - "page.duplicate.appendix": "Kopioi", - "page.duplicate.files": "Kopioi tiedostot", - "page.duplicate.pages": "Kopioi sivut", - "page.sort": "Muuta järjestyspaikkaa", - "page.status": "Tila", - "page.status.draft": "Luonnos", - "page.status.draft.description": "Sivu on luonnostilassa ja näkyvissä vain kirjautuneille editoijille tai yksityisen linkin kautta", - "page.status.listed": "Julkinen", - "page.status.listed.description": "Sivu on julkinen kaikille", - "page.status.unlisted": "Listaamaton", - "page.status.unlisted.description": "Sivulle pääsee vain URL:n kautta", - - "pages": "Sivut", - "pages.empty": "Sivuja ei ole vielä lisätty", - "pages.status.draft": "Luonnokset", - "pages.status.listed": "Julkaistut", - "pages.status.unlisted": "Listaamaton", - - "pagination.page": "Sivu", - - "password": "Salasana", - "paste": "Liitä", - "paste.after": "Liitä jälkeen", - "pixel": "Pikseli", - "plugins": "Liitännäiset", - "prev": "Edellinen", - "preview": "Esikatselu", - "remove": "Poista", - "rename": "Nimeä uudelleen", - "replace": "Korvaa", - "retry": "Yrit\u00e4 uudelleen", - "revert": "Palauta", - "revert.confirm": "Haluatko varmasti poistaa kaikki tallentamattomat muutokset?", - - "role": "K\u00e4ytt\u00e4j\u00e4taso", - "role.admin.description": "Pääkäyttäjällä on kaikki oikeudet", - "role.admin.title": "Pääkäyttäjä", - "role.all": "Kaikki", - "role.empty": "Tällä käyttäjätasolla ei ole yhtään käyttäjää", - "role.description.placeholder": "Ei kuvausta", - "role.nobody.description": "Tämä on vararooli, jolla ei ole mitään oikeuksia", - "role.nobody.title": "Tuntematon", - - "save": "Tallenna", - "search": "Haku", - "search.min": "Anna vähintään {min} merkkiä hakua varten", - "search.all": "Näytä kaikki", - "search.results.none": "Ei tuloksia", - - "section.required": "Osio on pakollinen", - - "security": "Security", - "select": "Valitse", - "server": "Palvelin", - "settings": "Asetukset", - "show": "Näytä", - "site.blueprint": "Tällä sivustolla ei ole vielä suunnitelmaa. Voit määrittää suunnitelman tiedostoon /site/blueprints/site.yml", - "size": "Koko", - "slug": "URL-tunniste", - "sort": "Järjestele", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Nimi", - "template": "Sivupohja", - "today": "Tänään", - - "toolbar.button.code": "Koodi", - "toolbar.button.bold": "Lihavointi", - "toolbar.button.email": "S\u00e4hk\u00f6posti", - "toolbar.button.headings": "Otsikot", - "toolbar.button.heading.1": "Otsikko 1", - "toolbar.button.heading.2": "Otsikko 2", - "toolbar.button.heading.3": "Otsikko 3", - "toolbar.button.heading.4": "Otsikko 4", - "toolbar.button.heading.5": "Otsikko 5", - "toolbar.button.heading.6": "Otsikko 6", - "toolbar.button.italic": "Kursivointi", - "toolbar.button.file": "Tiedosto", - "toolbar.button.file.select": "Valitse tiedosto", - "toolbar.button.file.upload": "Lähetä tiedosto", - "toolbar.button.link": "Linkki", - "toolbar.button.paragraph": "Kappale", - "toolbar.button.strike": "Yliviivaus", - "toolbar.button.ol": "Järjestetty lista", - "toolbar.button.underline": "Alaviiva", - "toolbar.button.ul": "Järjestämätön lista", - - "translation.author": "Kirby-tiimi", - "translation.direction": "ltr", - "translation.name": "Suomi", - "translation.locale": "fi_FI", - - "upload": "Lähetä", - "upload.error.cantMove": "Lähetettyä tiedostoa ei voitu siirtää", - "upload.error.cantWrite": "Tiedoston kirjoitus levylle epäonnistui", - "upload.error.default": "Tiedostoa ei voitu lähettää", - "upload.error.extension": "Tiedostoa ei lähetetty tiedostopäätteen takia", - "upload.error.formSize": "Lähetetyn tiedoston koko ylittää lomakkeen sallitun ylärajan MAX_FILE_SIZE", - "upload.error.iniPostSize": "Lähetetyn tiedoston koko ylittää sallitun ylärajan post_max_size asetustiedostossa php.ini", - "upload.error.iniSize": "Lähetetyn tiedoston koko ylittää sallitun ylärajan upload_max_filesize asetustiedostossa php.ini", - "upload.error.noFile": "Tiedostoa ei lähetetty", - "upload.error.noFiles": "Tiedostoja ei lähetetty", - "upload.error.partial": "Tiedoston lähetys onnistui vain osittain", - "upload.error.tmpDir": "Väliaikainen hakemisto puuttuu", - "upload.errors": "Virhe", - "upload.progress": "Lähetetään...", - - "url": "Url", - "url.placeholder": "https://esimerkki.fi", - - "user": "Käyttäjä", - "user.blueprint": "Voit määrittää lisää osioita ja lomakekenttiä tälle käyttäjälle suunnitelmassa /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Muuta sähköpostiosoite", - "user.changeLanguage": "Vaihda kieli", - "user.changeName": "Nimeä uudelleen", - "user.changePassword": "Vaihda salasana", - "user.changePassword.new": "Uusi salasana", - "user.changePassword.new.confirm": "Vahvista uusi salasana...", - "user.changeRole": "Muuta käyttäjätasoa", - "user.changeRole.select": "Valitse uusi käyttäjätaso", - "user.create": "Lisää uusi käyttäjä", - "user.delete": "Poista tämä käyttäjä", - "user.delete.confirm": "Haluatko varmsti poistaa käyttäjän
{email}?", - - "users": "Käyttäjät", - - "version": "Versio", - - "view.account": "Oma käyttäjätili", - "view.installation": "Asennus", - "view.languages": "Kielet", - "view.resetPassword": "Aseta salasana", - "view.site": "Sivusto", - "view.system": "Järjestelmä", - "view.users": "K\u00e4ytt\u00e4j\u00e4t", - - "welcome": "Tervetuloa", - "year": "Vuosi", - "yes": "kyllä" + "account.changeName": "Muuta nimesi", + "account.delete": "Poista tilisi", + "account.delete.confirm": "Haluatko varmasti poistaa tilisi? Sinut kirjataan ulos välittömästi, eikä tiliäsi voi palauttaa.", + + "add": "Lis\u00e4\u00e4", + "author": "Tekijä", + "avatar": "Profiilikuva", + "back": "Takaisin", + "cancel": "Peruuta", + "change": "Muuta", + "close": "Sulje", + "confirm": "Ok", + "collapse": "Pienennä", + "collapse.all": "Pienennä kaikki", + "copy": "Kopioi", + "copy.all": "Kopioi kaikki", + "create": "Luo", + + "date": "Päivämäärä", + "date.select": "Valitse päivämäärä", + + "day": "Päivä", + "days.fri": "Pe", + "days.mon": "Ma", + "days.sat": "La", + "days.sun": "Su", + "days.thu": "To", + "days.tue": "Ti", + "days.wed": "Ke", + + "debugging": "Virheenkäsittelytila", + + "delete": "Poista", + "delete.all": "Poista kaikki", + + "dialog.files.empty": "Ei valittavissa olevia tiedostoja", + "dialog.pages.empty": "Ei valittavissa olevia sivuja", + "dialog.users.empty": "Ei valittavissa olevia käyttäjiä", + + "dimensions": "Mitat", + "disabled": "Pois käytöstä", + "discard": "Hylkää", + "download": "Lataa", + "duplicate": "Kahdenna", + + "edit": "Muokkaa", + + "email": "S\u00e4hk\u00f6posti", + "email.placeholder": "nimi@osoite.fi", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Ympäristö", + + "error.access.code": "Väärä koodi", + "error.access.login": "Kirjautumistiedot eivät kelpaa", + "error.access.panel": "Sinulla ei ole oikeutta käyttää paneelia", + "error.access.view": "Sinulla ei ole oikeutta käyttää tätä osaa paneelista", + + "error.avatar.create.fail": "Profiilikuvaa ei voitu lähettää", + "error.avatar.delete.fail": "Profiilikuvaa ei voitu poistaa", + "error.avatar.dimensions.invalid": "Profiilikuvan leveys ja korkeus voivat olla enintään 3000 pikseliä", + "error.avatar.mime.forbidden": "Profiilikuvan täytyy olla joko JPEG- tai PNG-formaatissa", + + "error.blueprint.notFound": "Suunnitelmaa \"{name}\" ei voitu ladata", + + "error.blocks.max.plural": "Voit lisätä enintään {max} lohkoa", + "error.blocks.max.singular": "Voit lisätä enintään yhden lohkon", + "error.blocks.min.plural": "Lisää vähintään {min} lohkoa", + "error.blocks.min.singular": "Lisää vähintään yksi lohko", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "Nimellä \"{name}\" ja kyseisellä verkkotunnuksella ei löydy sähköpostiosoitetta", + + "error.field.converter.invalid": "Muunnin \"{converter}\" ei kelpaa", + + "error.file.changeName.empty": "Nimi ei voi olla tyhjä", + "error.file.changeName.permission": "Sinulla ei ole oikeutta muuttaa tiedoston \"{filename}\" nimeä", + "error.file.duplicate": "Tiedosto nimeltä \"{filename}\" on jo olemassa", + "error.file.extension.forbidden": "Tiedostopääte \"{extension}\" ei ole sallittu", + "error.file.extension.invalid": "Pääte {extension} ei kelpaa", + "error.file.extension.missing": "Tiedoston \"{filename}\" tiedostopääte puuttuu", + "error.file.maxheight": "Kuvan korkeus ei voi ylittää {height} pikseliä", + "error.file.maxsize": "Tiedosto on liian suuri", + "error.file.maxwidth": "Kuvan leveys ei voi ylittää {width} pikseliä", + "error.file.mime.differs": "Lähetetyllä tiedostolla täytyy olla sama mime-tyyppi \"{mime}\"", + "error.file.mime.forbidden": "Median tyyppi \"{mime}\" ei ole sallittu", + "error.file.mime.invalid": "Mime-tyyppi {mime} ei kelpaa", + "error.file.mime.missing": "Tiedoston \"{filename}\" mediatyyppiä ei voida tunnistaa", + "error.file.minheight": "Kuvan korkeus täytyy olla vähintään {height} pikseliä", + "error.file.minsize": "Tiedosto on liian pieni", + "error.file.minwidth": "Kuvan leveys täytyy olla vähintään {width} pikseliä", + "error.file.name.missing": "Tiedostonimi ei voi olla tyhjä", + "error.file.notFound": "Tiedostoa \"{filename}\" ei löytynyt", + "error.file.orientation": "Kuvan suuntaus täytyy olla \"{orientation}\"", + "error.file.type.forbidden": "Sinulla ei ole oikeutta lähettää tiedostoja joiden tyyppi on {type}", + "error.file.type.invalid": "Tiedostotyyppi {type} ei kelpaa", + "error.file.undefined": "Tiedostoa ei l\u00f6ytynyt", + + "error.form.incomplete": "Korjaa kaikki lomakkeen virheet…", + "error.form.notSaved": "Lomaketta ei voitu tallentaa", + + "error.language.code": "Anna kielen lyhenne", + "error.language.duplicate": "Kieli on jo olemassa", + "error.language.name": "Anna kielen nimi", + "error.language.notFound": "Kieltä ei löytynyt", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "Virhe asetelman {index} asetuksissa", + + "error.license.format": "Anna lisenssiavain", + "error.license.email": "Anna sähköpostiosoite", + "error.license.verification": "Lisenssiä ei voitu vahvistaa", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "Paneeli on offline-tilassa", + + "error.page.changeSlug.permission": "Sinulla ei ole oikeutta muuttaa URL-liitettä sivulle \"{slug}\"", + "error.page.changeStatus.incomplete": "Sivulla on virheitä eikä sitä voitu julkaista", + "error.page.changeStatus.permission": "Tämän sivun tilaa ei voi muuttaa", + "error.page.changeStatus.toDraft.invalid": "Sivua \"{slug}\" ei voi muuttaa luonnokseksi", + "error.page.changeTemplate.invalid": "Sivun \"{slug}\" pohjaa ei voi muuttaa", + "error.page.changeTemplate.permission": "Sinulla ei ole oikeutta muuttaa sivun \"{slug}\" sivupohjaa", + "error.page.changeTitle.empty": "Nimi ei voi olla tyhjä", + "error.page.changeTitle.permission": "Sinulla ei ole oikeutta muuttaa sivun \"{slug}\" nimeä", + "error.page.create.permission": "Sinulla ei ole oikeutta luoda sivua \"{slug}\"", + "error.page.delete": "Sivua \"{slug}\" ei voi poistaa", + "error.page.delete.confirm": "Anna vahvistuksena sivun nimi", + "error.page.delete.hasChildren": "Sivu sisältää alasivuja eikä sitä voida poistaa", + "error.page.delete.permission": "Sinulla ei ole oikeutta poistaa sivua \"{slug}\"", + "error.page.draft.duplicate": "Sivuluonnos URL-liitteellä \"{slug}\" on jo olemassa", + "error.page.duplicate": "Sivu URL-liitteellä \"{slug}\" on jo olemassa", + "error.page.duplicate.permission": "Sinulla ei ole oikeutta kahdentaa sivua \"{slug}\"", + "error.page.notFound": "Sivua \"{slug}\" ei löytynyt", + "error.page.num.invalid": "Anna kelpaava järjestysnumero. Numero ei voi olla negatiivinen.", + "error.page.slug.invalid": "Anna kelpaava URL-liite", + "error.page.slug.maxlength": "URL-liite täytyy olla vähemmän kuin \"{length}\" merkkiä pitkä", + "error.page.sort.permission": "Sivua \"{slug}\" ei voi järjestellä", + "error.page.status.invalid": "Aseta kelvollinen sivun tila", + "error.page.undefined": "Sivua ei l\u00f6ytynyt", + "error.page.update.permission": "Sinulla ei ole oikeutta päivittää sivua \"{slug}\"", + + "error.section.files.max.plural": "Et voi lisätä enemmän kuin {max} tiedostoa osioon \"{section}\"", + "error.section.files.max.singular": "Et voi lisätä enempää kuin yhden tiedoston osioon \"{section}\"", + "error.section.files.min.plural": "Osio \"{section}\" vaatii ainakin {min} tiedostoa", + "error.section.files.min.singular": "Osio \"{section}\" vaatii ainakin yhden sivun", + + "error.section.pages.max.plural": "Et voi lisätä enemmän kuin {max} sivua osioon \"{section}\"", + "error.section.pages.max.singular": "Et voi lisätä enempää kuin yhden sivun osioon \"{section}\"", + "error.section.pages.min.plural": "Osio \"{section}\" vaatii ainakin {min} sivua", + "error.section.pages.min.singular": "Osio \"{section}\" vaatii ainakin yhden sivun", + + "error.section.notLoaded": "Osiota \"{name}\" ei voitu ladata", + "error.section.type.invalid": "Osion tyyppi \"{type}\" ei ole kelvollinen", + + "error.site.changeTitle.empty": "Nimi ei voi olla tyhjä", + "error.site.changeTitle.permission": "Sinulla ei ole oikeutta päivittää sivuston nimeä", + "error.site.update.permission": "Sinulla ei ole oikeutta päivittää sivuston tietoja", + + "error.template.default.notFound": "Oletussivupohjaa ei ole määritetty", + + "error.unexpected": "Pahus, määrittelemätön virhe! Laita virheenkäsittelytila päälle saadaksesi lisätietoja: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Sinulla ei ole oikeutta vaihtaa käyttäjän \"{name}\" sähköpostiosoitetta", + "error.user.changeLanguage.permission": "Sinulla ei ole oikeutta vaihtaa käyttäjän \"{name}\" kieltä", + "error.user.changeName.permission": "Sinulla ei ole oikeutta vaihtaa käyttäjän \"{name}\" nimeä", + "error.user.changePassword.permission": "Sinulla ei ole oikeutta vaihtaa käyttäjän \"{name}\" salasanaa", + "error.user.changeRole.lastAdmin": "Ainoan pääkäyttäjän roolia ei voi muuttaa", + "error.user.changeRole.permission": "Sinulla ei ole oikeutta vaihtaa käyttäjän \"{name}\" käyttäjätasoa", + "error.user.changeRole.toAdmin": "Sinulla ei ole oikeutta vaihtaa käyttäjätasoa pääkäyttäjäksi", + "error.user.create.permission": "Sinulla ei ole oikeutta luoda tätä käyttäjää", + "error.user.delete": "Käyttäjää \"{name}\" ei voi poistaa", + "error.user.delete.lastAdmin": "Ainoaa pääkäyttäjää ei voi poistaa", + "error.user.delete.lastUser": "Ainoaa käyttäjää ei voi poistaa", + "error.user.delete.permission": "Sinulla ei ole oikeutta poistaa käyttäjää \"{name}\"", + "error.user.duplicate": "Käyttäjä, jonka sähköpostiosoite on \"{name}\", on jo olemassa", + "error.user.email.invalid": "Anna kelpaava sähköpostiosoite", + "error.user.language.invalid": "Anna kelpaava kieli", + "error.user.notFound": "K\u00e4ytt\u00e4j\u00e4\u00e4 ei l\u00f6ytynyt", + "error.user.password.invalid": "Anna kelpaava salasana. Salasanan täytyy olla ainakin 8 merkkiä pitkä.", + "error.user.password.notSame": "Salasanat eivät täsmää", + "error.user.password.undefined": "Käyttäjällä ei ole salasanaa", + "error.user.password.wrong": "Väärä salasana", + "error.user.role.invalid": "Anna kelpaava käyttäjätaso", + "error.user.undefined": "Käyttäjää ei löytynyt", + "error.user.update.permission": "Sinulla ei ole oikeutta päivittää käyttäjää \"{name}\"", + + "error.validation.accepted": "Ole hyvä ja vahvista", + "error.validation.alpha": "Anna vain merkkejä väliltä a-z", + "error.validation.alphanum": "Anna vain merkkejä väliltä a-z tai/ja numeroita väliltä 0-9", + "error.validation.between": "Anna arvo väliltä \"{min}\" ja \"{max}\"", + "error.validation.boolean": "Vahvista tai peruuta", + "error.validation.contains": "Anna arvo joka sisältää \"{needle}\"", + "error.validation.date": "Anna kelpaava päivämäärä", + "error.validation.date.after": "Anna päivämäärä {date} jälkeen", + "error.validation.date.before": "Anna päivämäärä ennen {date}", + "error.validation.date.between": "Anna päivämäärä väliltä {min} ja {max}", + "error.validation.denied": "Ole hyvä ja peruuta", + "error.validation.different": "Arvo ei voi olla \"{other}\"", + "error.validation.email": "Anna kelpaava sähköpostiosoite", + "error.validation.endswith": "Arvon loppuosa täytyy olla \"{end}\"", + "error.validation.filename": "Anna kelpaava tiedostonimi", + "error.validation.in": "Anna joku seuraavista: ({in})", + "error.validation.integer": "Anna kelpaava kokonaisluku", + "error.validation.ip": "Anna kelpaava IP-osoite", + "error.validation.less": "Anna arvo joka on pienempi kuin {max}", + "error.validation.match": "Arvo ei vastaa vaadittua kaavaa", + "error.validation.max": "Anna arvo joka on enintään {max}", + "error.validation.maxlength": "Anna lyhyempi arvo. (enintään {max} merkkiä)", + "error.validation.maxwords": "Anna korkeintaan {max} sana(a)", + "error.validation.min": "Anna arvo joka on vähintään {min}", + "error.validation.minlength": "Anna pidempi arvo. (vähintään {min} merkkiä)", + "error.validation.minwords": "Anna vähintään {min} sana(a)", + "error.validation.more": "Anna suurempi arvo kuin {min}", + "error.validation.notcontains": "Anna arvo joka ei sisällä \"{needle}\"", + "error.validation.notin": "Arvo ei voi sisältää mitään seuraavista: ({notIn})", + "error.validation.option": "Valitse kelpaava vaihtoehto", + "error.validation.num": "Anna kelpaava numero", + "error.validation.required": "Arvo ei voi olla tyhjä", + "error.validation.same": "Anna \"{other}\"", + "error.validation.size": "Arvon koko täytyy olla \"{size}\"", + "error.validation.startswith": "Arvon alkuosa täytyy olla \"{start}\"", + "error.validation.time": "Anna kelpaava aika", + "error.validation.time.after": "Anna myöhempi aika kuin {time}", + "error.validation.time.before": "Anna aiempi aika kuin {time}", + "error.validation.time.between": "Anna aika väliltä {min} ja {max}", + "error.validation.url": "Anna kelpaava URL", + + "expand": "Laajenna", + "expand.all": "Laajenna kaikki", + + "field.required": "Kenttä on pakollinen", + "field.blocks.changeType": "Vaihda tyyppiä", + "field.blocks.code.name": "Koodi", + "field.blocks.code.language": "Kieli", + "field.blocks.code.placeholder": "Koodisi …", + "field.blocks.delete.confirm": "Haluatko varmasti poistaa tämän lohkon?", + "field.blocks.delete.confirm.all": "Haluatko varmasti poistaa kaikki lohkot?", + "field.blocks.delete.confirm.selected": "Haluatko varmasti poistaa valitut lohkot?", + "field.blocks.empty": "Ei lohkoja", + "field.blocks.fieldsets.label": "Valitse lohkon tyyppi …", + "field.blocks.fieldsets.paste": "Paina {{ shortcut }} liittääksesi tai tuodaksesi lohkoja leikepöydältä", + "field.blocks.gallery.name": "Galleria", + "field.blocks.gallery.images.empty": "Ei kuvia", + "field.blocks.gallery.images.label": "Kuvat", + "field.blocks.heading.level": "Taso", + "field.blocks.heading.name": "Otsikko", + "field.blocks.heading.text": "Teksti", + "field.blocks.heading.placeholder": "Otsikko …", + "field.blocks.image.alt": "Vaihtoehtoinen teksti", + "field.blocks.image.caption": "Kuvateksti", + "field.blocks.image.crop": "Rajaa", + "field.blocks.image.link": "Linkki", + "field.blocks.image.location": "Sijainti", + "field.blocks.image.name": "Kuva", + "field.blocks.image.placeholder": "Valitse kuva", + "field.blocks.image.ratio": "Kuvasuhde", + "field.blocks.image.url": "Kuvan URL", + "field.blocks.line.name": "Rivi", + "field.blocks.list.name": "Lista", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Teksti", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Lainaus", + "field.blocks.quote.text.label": "Teksti", + "field.blocks.quote.text.placeholder": "Lainaus …", + "field.blocks.quote.citation.label": "Sitaatti", + "field.blocks.quote.citation.placeholder": "Lähde …", + "field.blocks.text.name": "Teksti", + "field.blocks.text.placeholder": "Teksti …", + "field.blocks.video.caption": "Videon teksti", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Anna videon URL", + "field.blocks.video.url.label": "Videon URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Tiedostoja ei ole vielä valittu", + + "field.layout.delete": "Poista asettelu", + "field.layout.delete.confirm": "Halutako varmasti poistaa tämän asettelun?", + "field.layout.empty": "Ei rivejä", + "field.layout.select": "Valitse asettelu", + + "field.object.empty": "Ei vielä tietoja", + + "field.pages.empty": " Sivuja ei ole vielä valittu", + + "field.structure.delete.confirm": "Haluatko varmasti poistaa tämän rivin?", + "field.structure.empty": "Rivejä ei ole vielä lisätty", + + "field.users.empty": "Käyttäjiä ei ole vielä valittu", + + "file.blueprint": "Tällä tiedostolla ei ole vielä suunnitelmaa. Voit määrittää suunnitelman tiedostoon /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Haluatko varmasti poistaa tiedoston
{filename}?", + "file.sort": "Muuta järjestyspaikkaa", + + "files": "Tiedostot", + "files.empty": "Tiedostoja ei ole vielä lisätty", + + "hide": "Piilota", + "hour": "Tunti", + "import": "Tuo", + "info": "Tietoja", + "insert": "Lis\u00e4\u00e4", + "insert.after": "Lisää eteen", + "insert.before": "Lisää jälkeen", + "install": "Asenna", + + "installation": "Asennus", + "installation.completed": "Paneeli on asennettu", + "installation.disabled": "Paneelin asennus on oletuksena poissa käytöstä julkisilla palvelimilla. Aja asennus paikallisella koneella, tai ota paneeli käyttöön panel.install-optiolla.", + "installation.issues.accounts": "/site/accounts -kansio ei ole olemassa tai siihen ei voi kirjoittaa", + "installation.issues.content": "/content -kansio ei ole olemassa tai siihen ei voi kirjoittaa", + "installation.issues.curl": "CURL-laajennos on pakollinen", + "installation.issues.headline": "Paneelia ei voida asentaa", + "installation.issues.mbstring": "MB String-laajennos on pakollinen", + "installation.issues.media": "/media -kansio ei ole olemassa tai siihen ei voi kirjoittaa", + "installation.issues.php": "Varmista että PHP 7+ on käytössä", + "installation.issues.server": "Kirby tarvitsee jonkun seuraavista: Apache, Nginx tai Caddy", + "installation.issues.sessions": "/site/sessions -kansio ei ole olemassa tai siihen ei voi kirjoittaa", + + "language": "Kieli", + "language.code": "Tunniste", + "language.convert": "Muuta oletukseksi", + "language.convert.confirm": "

Haluatko varmasti muuttaa kielen {name} oletuskieleksi? Tätä muutosta ei voi peruuttaa.

Jos{name} sisältää kääntämättömiä kohtia, varakäännöstä ei enää ole näille kohdille ja sivustosi saattaa olla osittain tyhjä.

", + "language.create": "Lisää uusi kieli", + "language.delete.confirm": "Haluatko varmasti poistaa kielen {name}, mukaanlukien kaikki käännökset? Tätä toimintoa ei voi peruuttaa!", + "language.deleted": "Kieli on poistettu", + "language.direction": "Lukusuunta", + "language.direction.ltr": "Vasemmalta oikealle", + "language.direction.rtl": "Oikealta vasemmalle", + "language.locale": "PHP-aluemäärityksen tunniste", + "language.locale.warning": "Käytät mukautettua aluemääritystä. Muokkaa sitä kielitiedostossa /site/languages", + "language.name": "Nimi", + "language.updated": "Kieli on päivitetty", + + "languages": "Kielet", + "languages.default": "Oletuskieli", + "languages.empty": "Kieliä ei ole vielä määritetty", + "languages.secondary": "Toissijaiset kielet", + "languages.secondary.empty": "Toissijaisia kieliä ei ole vielä määritetty", + + "license": "Lisenssi", + "license.buy": "Osta lisenssi", + "license.register": "Rekisteröi", + "license.manage": "Hallinnoi lisenssejäsi", + "license.register.help": "Lisenssiavain on lähetetty oston jälkeen sähköpostiisi. Kopioi ja liitä avain tähän.", + "license.register.label": "Anna lisenssiavain", + "license.register.success": "Kiitos kun tuet Kirbyä", + "license.unregistered": "Tämä on rekisteröimätön demo Kirbystä", + "license.unregistered.label": "Rekisteröimätön", + + "link": "Linkki", + "link.text": "Linkin teksti", + + "loading": "Ladataan", + + "lock.unsaved": "Tallentamattomia muutoksia", + "lock.unsaved.empty": "Ei enempää tallentamattomia muutoksia ", + "lock.isLocked": "Käyttäjällä {email} on tallentamattomia muutoksia", + "lock.file.isLocked": "Tiedostoa ei voi muokata juuri nyt, sillä {email} on muokkaamassa tiedostoa.", + "lock.page.isLocked": "Sivua ei voi muokata juuri nyt, sillä {email} on muokkaamassa sivua.", + "lock.unlock": "Vapauta", + "lock.isUnlocked": "Toinen käyttäjä ylikirjoitti tallentamattomat muutoksesi. Voit ladata tekemäsi muutokset ja lisätä ne käsin.", + + "login": "Kirjaudu", + "login.code.label.login": "Kirjautumiskoodi", + "login.code.label.password-reset": "Salasanan asetuskoodi", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "Jos sähköpostiosoitteesi on rekisteröity, tilaamasi koodi lähetetään tähän osoitteeseen.", + "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.login.subject": "Kirjautumiskoodisi", + "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.password-reset.subject": "Salasanan asetuskoodisi", + "login.remember": "Pidä minut kirjautuneena", + "login.reset": "Aseta salasana", + "login.toggleText.code.email": "Kirjaudu sähköpostiosoitteella", + "login.toggleText.code.email-password": "Kirjaudu salasanalla", + "login.toggleText.password-reset.email": "Unohditko salasanasi?", + "login.toggleText.password-reset.email-password": "← Takaisin kirjautumiseen", + + "logout": "Kirjaudu ulos", + + "menu": "Valikko", + "meridiem": "am/pm", + "mime": "Median tyyppi", + "minutes": "Minuutit", + + "month": "Kuukausi", + "months.april": "Huhtikuu", + "months.august": "Elokuu", + "months.december": "Joulukuu", + "months.february": "Helmikuu", + "months.january": "Tammikuu", + "months.july": "Hein\u00e4kuu", + "months.june": "Kes\u00e4kuu", + "months.march": "Maaliskuu", + "months.may": "Toukokuu", + "months.november": "Marraskuu", + "months.october": "Lokakuu", + "months.september": "Syyskuu", + + "more": "Lisää", + "name": "Nimi", + "next": "Seuraava", + "no": "ei", + "off": "Pois käytöstä", + "on": "Käytössä", + "open": "Avaa", + "open.newWindow": "Avaa uudessa ikkunassa", + "options": "Asetukset", + "options.none": "Ei valintoja", + + "orientation": "Suunta", + "orientation.landscape": "Vaakasuuntainen", + "orientation.portrait": "Pystysuuntainen", + "orientation.square": "Neliskulmainen", + + "page.blueprint": "Tällä sivulla ei ole vielä suunnitelmaa. Voit määrittää suunnitelman tiedostoon /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Vaihda URL-osoite", + "page.changeSlug.fromTitle": "Luo nimen perusteella", + "page.changeStatus": "Muuta tilaa", + "page.changeStatus.position": "Valitse järjestyspaikka", + "page.changeStatus.select": "Valitse uusi tila", + "page.changeTemplate": "Vaihda sivupohja", + "page.delete.confirm": "Haluatko varmasti poistaa sivun {title}?", + "page.delete.confirm.subpages": "Tällä sivulla on alasivuja.
Myös kaikki alasivut poistetaan.", + "page.delete.confirm.title": "Anna vahvistuksena sivun nimi", + "page.draft.create": "Uusi luonnos", + "page.duplicate.appendix": "Kopioi", + "page.duplicate.files": "Kopioi tiedostot", + "page.duplicate.pages": "Kopioi sivut", + "page.sort": "Muuta järjestyspaikkaa", + "page.status": "Tila", + "page.status.draft": "Luonnos", + "page.status.draft.description": "Sivu on luonnostilassa ja näkyvissä vain kirjautuneille editoijille tai yksityisen linkin kautta", + "page.status.listed": "Julkinen", + "page.status.listed.description": "Sivu on julkinen kaikille", + "page.status.unlisted": "Listaamaton", + "page.status.unlisted.description": "Sivulle pääsee vain URL:n kautta", + + "pages": "Sivut", + "pages.empty": "Sivuja ei ole vielä lisätty", + "pages.status.draft": "Luonnokset", + "pages.status.listed": "Julkaistut", + "pages.status.unlisted": "Listaamaton", + + "pagination.page": "Sivu", + + "password": "Salasana", + "paste": "Liitä", + "paste.after": "Liitä jälkeen", + "pixel": "Pikseli", + "plugin": "Liitännäinen", + "plugins": "Liitännäiset", + "prev": "Edellinen", + "preview": "Esikatselu", + "remove": "Poista", + "rename": "Nimeä uudelleen", + "replace": "Korvaa", + "retry": "Yrit\u00e4 uudelleen", + "revert": "Palauta", + "revert.confirm": "Haluatko varmasti poistaa kaikki tallentamattomat muutokset?", + + "role": "K\u00e4ytt\u00e4j\u00e4taso", + "role.admin.description": "Pääkäyttäjällä on kaikki oikeudet", + "role.admin.title": "Pääkäyttäjä", + "role.all": "Kaikki", + "role.empty": "Tällä käyttäjätasolla ei ole yhtään käyttäjää", + "role.description.placeholder": "Ei kuvausta", + "role.nobody.description": "Tämä on vararooli, jolla ei ole mitään oikeuksia", + "role.nobody.title": "Tuntematon", + + "save": "Tallenna", + "search": "Haku", + "search.min": "Anna vähintään {min} merkkiä hakua varten", + "search.all": "Näytä kaikki", + "search.results.none": "Ei tuloksia", + + "section.required": "Osio on pakollinen", + + "security": "Tietoturva", + "select": "Valitse", + "server": "Palvelin", + "settings": "Asetukset", + "show": "Näytä", + "site.blueprint": "Tällä sivustolla ei ole vielä suunnitelmaa. Voit määrittää suunnitelman tiedostoon /site/blueprints/site.yml", + "size": "Koko", + "slug": "URL-tunniste", + "sort": "Järjestele", + + "stats.empty": "Ei raportteja", + "system.issues.content": "Content-kansio näyttäisi olevan julkinen", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Virheenkäsittelytila pitää poistaa käytöstä tuotantoympäristössä", + "system.issues.git": ".git-kansio näyttäisi olevan julkinen", + "system.issues.https": "Suosittelemme HTTPS:n käyttöä kaikilla sivustoillasi", + "system.issues.kirby": "Kirby-kansio näyttäisi olevan julkinen", + "system.issues.site": "Site-kansio näyttäisi olevan julkinen", + "system.issues.vulnerability.kirby": "Asennuksesi voi olla altis seuraaville haavoittuvuuksille ({ severity } vakavuus): { description }", + "system.issues.vulnerability.plugin": "Asennuksesi käyttämä liitännäinen { plugin } voi olla altis haavoittuvuudelle ({ severity } vakavuus): { description }", + "system.updateStatus": "Päivitysten tilanne", + "system.updateStatus.error": "Päivityksiä ei voitu tarkistaa", + "system.updateStatus.not-vulnerable": "Ei tunnettuja haavoittuvuuksia", + "system.updateStatus.security-update": "Ilmainen tietoturvapäivitys { version } saatavilla", + "system.updateStatus.security-upgrade": "Tietoturvakorjauksia sisältävä päivitys { version } saatavilla", + "system.updateStatus.unreleased": "Julkaisematon versio", + "system.updateStatus.up-to-date": "Ajan tasalla", + "system.updateStatus.update": "Ilmainen päivitys { version } saatavilla", + "system.updateStatus.upgrade": "Päivitys { version } saatavilla", + + "title": "Nimi", + "template": "Sivupohja", + "today": "Tänään", + + "toolbar.button.code": "Koodi", + "toolbar.button.bold": "Lihavointi", + "toolbar.button.email": "S\u00e4hk\u00f6posti", + "toolbar.button.headings": "Otsikot", + "toolbar.button.heading.1": "Otsikko 1", + "toolbar.button.heading.2": "Otsikko 2", + "toolbar.button.heading.3": "Otsikko 3", + "toolbar.button.heading.4": "Otsikko 4", + "toolbar.button.heading.5": "Otsikko 5", + "toolbar.button.heading.6": "Otsikko 6", + "toolbar.button.italic": "Kursivointi", + "toolbar.button.file": "Tiedosto", + "toolbar.button.file.select": "Valitse tiedosto", + "toolbar.button.file.upload": "Lähetä tiedosto", + "toolbar.button.link": "Linkki", + "toolbar.button.paragraph": "Kappale", + "toolbar.button.strike": "Yliviivaus", + "toolbar.button.ol": "Järjestetty lista", + "toolbar.button.underline": "Alaviiva", + "toolbar.button.ul": "Järjestämätön lista", + + "translation.author": "Kirby-tiimi", + "translation.direction": "ltr", + "translation.name": "Suomi", + "translation.locale": "fi_FI", + + "upload": "Lähetä", + "upload.error.cantMove": "Lähetettyä tiedostoa ei voitu siirtää", + "upload.error.cantWrite": "Tiedoston kirjoitus levylle epäonnistui", + "upload.error.default": "Tiedostoa ei voitu lähettää", + "upload.error.extension": "Tiedostoa ei lähetetty tiedostopäätteen takia", + "upload.error.formSize": "Lähetetyn tiedoston koko ylittää lomakkeen sallitun ylärajan MAX_FILE_SIZE", + "upload.error.iniPostSize": "Lähetetyn tiedoston koko ylittää sallitun ylärajan post_max_size asetustiedostossa php.ini", + "upload.error.iniSize": "Lähetetyn tiedoston koko ylittää sallitun ylärajan upload_max_filesize asetustiedostossa php.ini", + "upload.error.noFile": "Tiedostoa ei lähetetty", + "upload.error.noFiles": "Tiedostoja ei lähetetty", + "upload.error.partial": "Tiedoston lähetys onnistui vain osittain", + "upload.error.tmpDir": "Väliaikainen hakemisto puuttuu", + "upload.errors": "Virhe", + "upload.progress": "Lähetetään...", + + "url": "Url", + "url.placeholder": "https://esimerkki.fi", + + "user": "Käyttäjä", + "user.blueprint": "Voit määrittää lisää osioita ja lomakekenttiä tälle käyttäjälle suunnitelmassa /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Muuta sähköpostiosoite", + "user.changeLanguage": "Vaihda kieli", + "user.changeName": "Nimeä uudelleen", + "user.changePassword": "Vaihda salasana", + "user.changePassword.new": "Uusi salasana", + "user.changePassword.new.confirm": "Vahvista uusi salasana...", + "user.changeRole": "Muuta käyttäjätasoa", + "user.changeRole.select": "Valitse uusi käyttäjätaso", + "user.create": "Lisää uusi käyttäjä", + "user.delete": "Poista tämä käyttäjä", + "user.delete.confirm": "Haluatko varmsti poistaa käyttäjän
{email}?", + + "users": "Käyttäjät", + + "version": "Versio", + "version.current": "Nykyinen versio ", + "version.latest": "Uusin versio ", + "versionInformation": "Version tiedot", + + "view.account": "Oma käyttäjätili", + "view.installation": "Asennus", + "view.languages": "Kielet", + "view.resetPassword": "Aseta salasana", + "view.site": "Sivusto", + "view.system": "Järjestelmä", + "view.users": "K\u00e4ytt\u00e4j\u00e4t", + + "welcome": "Tervetuloa", + "year": "Vuosi", + "yes": "kyllä" } diff --git a/kirby/i18n/translations/fr.json b/kirby/i18n/translations/fr.json index 9ccec12..41ee52b 100644 --- a/kirby/i18n/translations/fr.json +++ b/kirby/i18n/translations/fr.json @@ -1,573 +1,596 @@ { - "account.changeName": "Modifier votre nom", - "account.delete": "Supprimer votre compte", - "account.delete.confirm": "Voulez-vous vraiment supprimer votre compte ? Vous serez déconnecté immédiatement. Votre compte ne pourra pas être récupéré.", - - "add": "Ajouter", - "author": "Auteur", - "avatar": "Image du profil", - "back": "Retour", - "cancel": "Annuler", - "change": "Changer", - "close": "Fermer", - "confirm": "Ok", - "collapse": "Replier", - "collapse.all": "Tout replier", - "copy": "Copier", - "copy.all": "Tout copier", - "create": "Créer", - - "date": "Date", - "date.select": "Choisir une date", - - "day": "Jour", - "days.fri": "Ven", - "days.mon": "Lun", - "days.sat": "Sam", - "days.sun": "Dim", - "days.thu": "Jeu", - "days.tue": "Mar", - "days.wed": "Mer", - - "debugging": "Débogage", - - "delete": "Supprimer", - "delete.all": "Tout supprimer", - - "dialog.files.empty": "Aucun fichier à sélectionner", - "dialog.pages.empty": "Aucune page à sélectionner", - "dialog.users.empty": "Aucun utilisateur à sélectionner", - - "dimensions": "Dimensions", - "disabled": "Désactivé", - "discard": "Supprimer", - "download": "Télécharger", - "duplicate": "Dupliquer", - - "edit": "Éditer", - - "email": "Courriel", - "email.placeholder": "mail@example.com", - - "entries": "Entrées", - "entry": "Entrée", - - "environment": "Environnement", - - "error.access.code": "Code incorrect", - "error.access.login": "Identifiant incorrect", - "error.access.panel": "Vous n’êtes pas autorisé à accéder au Panel", - "error.access.view": "Vous n’êtes pas autorisé à accéder à cette section du Panel", - - "error.avatar.create.fail": "L’image du profil n’a pu être transférée", - "error.avatar.delete.fail": "L’image du profil n’a pu être supprimée", - "error.avatar.dimensions.invalid": "Veuillez choisir une image de profil de largeur et hauteur inférieures à 3000 pixels", - "error.avatar.mime.forbidden": "L'image du profil utilisateur doit être un fichier JPEG ou PNG", - - "error.blueprint.notFound": "Le blueprint « {name} » n’a pu être chargé", - - "error.blocks.max.plural": "Vous ne devez pas ajouter plus de {max} blocs", - "error.blocks.max.singular": "Vous ne devez pas ajouter plus d'un bloc", - "error.blocks.min.plural": "Vous devez ajouter au moins {min} blocs", - "error.blocks.min.singular": "Vous devez ajouter au moins un bloc", - "error.blocks.validation": "Il y a une erreur dans le bloc {index}", - - "error.email.preset.notFound": "La configuration de courriel « {name} » n’a pu être trouvé ", - - "error.field.converter.invalid": "Convertisseur « {converter} » incorrect", - - "error.file.changeName.empty": "Le nom ne peut être vide", - "error.file.changeName.permission": "Vous n’êtes pas autorisé à modifier le nom de « {filename} »", - "error.file.duplicate": "Un fichier nommé « {filename} » existe déjà", - "error.file.extension.forbidden": "L’extension « {extension} » n’est pas autorisée", - "error.file.extension.invalid": "Extension non valide : {extension}", - "error.file.extension.missing": "L’extension pour « {filename} » est manquante", - "error.file.maxheight": "La hauteur de l'image ne doit pas excéder {height} pixels", - "error.file.maxsize": "Le fichier est trop volumineux", - "error.file.maxwidth": "La largeur de l'image ne doit pas excéder {width} pixels", - "error.file.mime.differs": "Le fichier transféré doit être du même type de média « {mime} »", - "error.file.mime.forbidden": "Le type de média « {mime} » n’est pas autorisé", - "error.file.mime.invalid": "Type de média non valide : {mime}", - "error.file.mime.missing": "Le type de média de « {filename} » n’a pu être détecté", - "error.file.minheight": "La hauteur de l'image doit être au moins {height} pixels", - "error.file.minsize": "Le fichier n'est pas assez volumineux", - "error.file.minwidth": "La largeur de l'image doit être au moins {width} pixels", - "error.file.name.missing": "Veuillez entrer un titre", - "error.file.notFound": "Le fichier « {filename} » n’a pu être trouvé", - "error.file.orientation": "L'orientation de l'image doit être « {orientation} »", - "error.file.type.forbidden": "Vous n’êtes pas autorisé à transférer des fichiers {type}", - "error.file.type.invalid": "Type de fichier non valide : {type}", - "error.file.undefined": "Le fichier n’a pu être trouvé", - - "error.form.incomplete": "Veuillez corriger toutes les erreurs du formulaire…", - "error.form.notSaved": "Le formulaire n’a pu être enregistré", - - "error.language.code": "Veuillez saisir un code valide pour cette langue", - "error.language.duplicate": "Cette langue existe déjà", - "error.language.name": "Veuillez saisir un nom valide pour cette langue", - "error.language.notFound": "La langue n’a pu être trouvée", - - "error.layout.validation.block": "Il y a une erreur dans le block {blockIndex} de la disposition {layoutIndex}", - "error.layout.validation.settings": "Il y a une erreur dans les paramètres de la disposition {index}", - - "error.license.format": "Veuillez saisir un numéro de licence valide", - "error.license.email": "Veuillez saisir un courriel valide", - "error.license.verification": "La licence n’a pu être vérifiée", - - "error.offline": "Le Panel est actuellement hors ligne", - - "error.page.changeSlug.permission": "Vous n’êtes pas autorisé à modifier l’identifiant d’URL pour « {slug} »", - "error.page.changeStatus.incomplete": "La page comporte des erreurs et ne peut pas être publiée", - "error.page.changeStatus.permission": "Le statut de cette page ne peut être modifié", - "error.page.changeStatus.toDraft.invalid": "La page « {slug} » ne peut être convertie en brouillon", - "error.page.changeTemplate.invalid": "Le modèle de la page « {slug} » ne peut être changé", - "error.page.changeTemplate.permission": "Vous n’êtes pas autorisé à changer le modèle de « {slug} »", - "error.page.changeTitle.empty": "Le titre ne peut être vide", - "error.page.changeTitle.permission": "Vous n’êtes pas autorisé à modifier le titre de « {slug} »", - "error.page.create.permission": "Vous n’êtes pas autorisé à créer « {slug} »", - "error.page.delete": "La page « {slug} » ne peut être supprimée", - "error.page.delete.confirm": "Veuillez saisir le titre de la page pour confirmer", - "error.page.delete.hasChildren": "La page comporte des sous-pages et ne peut pas être supprimée", - "error.page.delete.permission": "Vous n’êtes pas autorisé à supprimer « {slug} »", - "error.page.draft.duplicate": "Un brouillon avec l’identifiant d’URL « {slug} » existe déjà", - "error.page.duplicate": "Une page avec l’identifiant d’URL « {slug} » existe déjà", - "error.page.duplicate.permission": "Vous n'êtes pas autorisé à dupliquer « {slug} »", - "error.page.notFound": "La page « {slug} » n’a pu être trouvée", - "error.page.num.invalid": "Veuillez saisir un numéro de position valide. Les numéros ne doivent pas être négatifs.", - "error.page.slug.invalid": "Veuillez entrer un identifiant d’URL valide", - "error.page.slug.maxlength": "L’identifiant d’URL doit faire moins de « {length} » caractères", - "error.page.sort.permission": "La page « {slug} » ne peut être réordonnée", - "error.page.status.invalid": "Veuillez choisir un statut de page valide", - "error.page.undefined": "La page n’a pu être trouvée", - "error.page.update.permission": "Vous n’êtes pas autorisé à modifier « {slug} »", - - "error.section.files.max.plural": "Vous ne pouvez ajouter plus de {max} fichier(s) à la section « {section} »", - "error.section.files.max.singular": "Vous ne pouvez ajouter plus d’un fichier à la section « {section} »", - "error.section.files.min.plural": "La section « {section} » requiert au moins {min} fichiers", - "error.section.files.min.singular": "La section « {section} » requiert au moins un fichier", - - "error.section.pages.max.plural": "Vous ne pouvez ajouter plus de {max} pages à la section « {section} »", - "error.section.pages.max.singular": "Vous ne pouvez ajouter plus d’une page à la section « {section} »", - "error.section.pages.min.plural": "La section « {section} » requiert au moins {min} pages", - "error.section.pages.min.singular": "La section « {section} » requiert au moins une page", - - "error.section.notLoaded": "La section « {name} » n’a pu être chargée", - "error.section.type.invalid": "Le type de section « {type} » est incorrect", - - "error.site.changeTitle.empty": "Le titre ne peut être vide", - "error.site.changeTitle.permission": "Vous n’êtes pas autorisé à modifier le titre du site", - "error.site.update.permission": "Vous n’êtes pas autorisé à modifier le contenu global du site", - - "error.template.default.notFound": "Le modèle par défaut n’existe pas", - - "error.unexpected": "Une erreur inattendue est survenue ! Activez le mode de débogage pour plus d'informations : https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Vous n’êtes pas autorisé à modifier le courriel de l’utilisateur « {name} »", - "error.user.changeLanguage.permission": "Vous n’êtes pas autorisé à changer la langue de l’utilisateur « {name} »", - "error.user.changeName.permission": "Vous n’êtes pas autorisé à modifier le nom de l’utilisateur « {name} »", - "error.user.changePassword.permission": "Vous n’êtes pas autorisé à changer le mot de passe de l’utilisateur « {name} »", - "error.user.changeRole.lastAdmin": "Le rôle du dernier administrateur ne peut être modifié", - "error.user.changeRole.permission": "Vous n’êtes pas autorisé à changer le rôle de l’utilisateur « {name} »", - "error.user.changeRole.toAdmin": "Vous n’êtes pas autorisé à attribuer le rôle d’administrateur aux utilisateurs", - "error.user.create.permission": "Vous n’êtes pas autorisé à créer cet utilisateur", - "error.user.delete": "L’utilisateur « {name} » ne peut être supprimé", - "error.user.delete.lastAdmin": "Le dernier administrateur ne peut être supprimé", - "error.user.delete.lastUser": "Le dernier utilisateur ne peut être supprimé", - "error.user.delete.permission": "Vous n’êtes pas autorisé à supprimer l’utilisateur « {name} »", - "error.user.duplicate": "Un utilisateur avec le courriel « {email} » existe déjà", - "error.user.email.invalid": "Veuillez saisir un courriel valide", - "error.user.language.invalid": "Veuillez saisir une langue valide", - "error.user.notFound": "L’utilisateur « {name} » n’a pu être trouvé", - "error.user.password.invalid": "Veuillez saisir un mot de passe valide. Les mots de passe doivent comporter au moins 8 caractères.", - "error.user.password.notSame": "Les mots de passe ne sont pas identiques", - "error.user.password.undefined": "Cet utilisateur n’a pas de mot de passe", - "error.user.password.wrong": "Mot de passe incorrect", - "error.user.role.invalid": "Veuillez saisir un rôle valide", - "error.user.undefined": "L’utilisateur n’a pu être trouvé", - "error.user.update.permission": "Vous n’êtes pas autorisé à modifier l’utilisateur « {name} »", - - "error.validation.accepted": "Veuillez confirmer", - "error.validation.alpha": "Veuillez saisir uniquement des caractères alphabétiques minuscules", - "error.validation.alphanum": "Veuillez ne saisir que des minuscules de a à z et des chiffres de 0 à 9", - "error.validation.between": "Veuillez saisir une valeur entre « {min} » et « {max} »", - "error.validation.boolean": "Veuillez confirmer ou refuser", - "error.validation.contains": "Veuillez saisir une valeur contenant « {needle} »", - "error.validation.date": "Veuillez saisir une date valide", - "error.validation.date.after": "Veuillez saisir une date après {date}", - "error.validation.date.before": "Veuillez saisir une date avant {date}", - "error.validation.date.between": "Veuillez saisir une date entre {min} et {max}", - "error.validation.denied": "Veuillez refuser", - "error.validation.different": "La valeur ne doit pas être « {other} »", - "error.validation.email": "Veuillez saisir un courriel valide", - "error.validation.endswith": "La valeur doit se terminer par « {end} »", - "error.validation.filename": "Veuillez saisir un nom de fichier valide", - "error.validation.in": "Veuillez saisir l’un des éléments suivants: ({in})", - "error.validation.integer": "Veuillez saisir un entier valide", - "error.validation.ip": "Veuillez saisir une adresse IP valide", - "error.validation.less": "Veuillez saisir une valeur inférieure à {max}", - "error.validation.match": "La valeur ne correspond pas au modèle attendu", - "error.validation.max": "Veuillez saisir une valeur inférieure ou égale à {max}", - "error.validation.maxlength": "Veuillez saisir une valeur plus courte (max. {max} caractères)", - "error.validation.maxwords": "Veuillez ne pas saisir plus de {max} mot(s)", - "error.validation.min": "Veuillez saisir une valeur supérieure ou égale à {min}", - "error.validation.minlength": "Veuillez saisir une valeur plus longue (min. {min} caractères)", - "error.validation.minwords": "Veuillez saisir au moins {min} mot(s)", - "error.validation.more": "Veuillez saisir une valeur supérieure à {min}", - "error.validation.notcontains": "Veuillez saisir une valeur ne contenant pas « {needle} »", - "error.validation.notin": "Veuillez ne saisir aucun des éléments suivants: ({notIn})", - "error.validation.option": "Veuillez sélectionner une option valide", - "error.validation.num": "Veuillez saisir un nombre valide", - "error.validation.required": "Veuillez saisir quelque chose", - "error.validation.same": "Veuillez saisir « {other} »", - "error.validation.size": "La grandeur de la valeur doit être « {size} »", - "error.validation.startswith": "La valeur doit commencer par « {start} »", - "error.validation.time": "Veuillez saisir une heure valide", - "error.validation.time.after": "Veuillez entrer une heure après {time}", - "error.validation.time.before": "Veuillez entrer une heure avant {time}", - "error.validation.time.between": "Veuillez entrer une heure entre {min} et {max}", - "error.validation.url": "Veuillez saisir une URL valide", - - "expand": "Déplier", - "expand.all": "Tout déplier", - - "field.required": "Le champ est obligatoire", - "field.blocks.changeType": "Changer le type", - "field.blocks.code.name": "Code", - "field.blocks.code.language": "Langue", - "field.blocks.code.placeholder": "Votre code…", - "field.blocks.delete.confirm": "Voulez-vous vraiment supprimer ce bloc ?", - "field.blocks.delete.confirm.all": "Voulez-vous vraiment supprimer tous les blocs ?", - "field.blocks.delete.confirm.selected": "Voulez-vous vraiment supprimer les blocs sélectionnés ?", - "field.blocks.empty": "Pas encore de blocs", - "field.blocks.fieldsets.label": "Veuillez sélectionner un type de bloc…", - "field.blocks.fieldsets.paste": "Presser {{ shortcut }} pour coller/importer des blocks depuis votre presse-papier", - "field.blocks.gallery.name": "Galerie", - "field.blocks.gallery.images.empty": "Pas encore d’images", - "field.blocks.gallery.images.label": "Images", - "field.blocks.heading.level": "Niveau", - "field.blocks.heading.name": "Titre", - "field.blocks.heading.text": "Texte", - "field.blocks.heading.placeholder": "Titre…", - "field.blocks.image.alt": "Texte alternatif", - "field.blocks.image.caption": "Légende", - "field.blocks.image.crop": "Recadrer", - "field.blocks.image.link": "Lien", - "field.blocks.image.location": "Emplacement", - "field.blocks.image.name": "Image", - "field.blocks.image.placeholder": "Sélectionnez une image", - "field.blocks.image.ratio": "Proportions", - "field.blocks.image.url": "URL de l'image", - "field.blocks.line.name": "Ligne", - "field.blocks.list.name": "Liste", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Texte", - "field.blocks.markdown.placeholder": "Markdown…", - "field.blocks.quote.name": "Citation", - "field.blocks.quote.text.label": "Texte", - "field.blocks.quote.text.placeholder": "Citation…", - "field.blocks.quote.citation.label": "Citation", - "field.blocks.quote.citation.placeholder": "par…", - "field.blocks.text.name": "Texte", - "field.blocks.text.placeholder": "Texte…", - "field.blocks.video.caption": "Légende", - "field.blocks.video.name": "Vidéo", - "field.blocks.video.placeholder": "Entrez l’URL d’une vidéo", - "field.blocks.video.url.label": "URL de la vidéo", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Pas encore de fichier sélectionné", - - "field.layout.delete": "Supprimer cette disposition", - "field.layout.delete.confirm": "Voulez-vous vraiment supprimer cette disposition ?", - "field.layout.empty": "Pas encore de rangées", - "field.layout.select": "Choisir une disposition", - - "field.pages.empty": "Pas encore de page sélectionnée", - "field.structure.delete.confirm": "Voulez-vous vraiment supprimer cette ligne ?", - "field.structure.empty": "Pas encore d’entrée", - "field.users.empty": "Pas encore d’utilisateur sélectionné", - - "file.blueprint": "Ce fichier n’a pas encore de blueprint. Vous pouvez en définir les paramètres dans /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Voulez-vous vraiment supprimer
{filename} ?", - "file.sort": "Modifier la position", - - "files": "Fichiers", - "files.empty": "Pas encore de fichier", - - "hide": "Masquer", - "hour": "Heure", - "import": "Importer", - "info": "Info", - "insert": "Insérer", - "insert.after": "Insérer après", - "insert.before": "Insérer avant", - "install": "Installer", - - "installation": "Installation", - "installation.completed": "Le Panel a été installé", - "installation.disabled": "L'installation du Panel est désactivée par défaut sur les serveurs publics. Veuillez lancer l'installation sur un serveur local, ou activez-la avec l'option panel.install.", - "installation.issues.accounts": "Le dossier /site/accounts n’existe pas ou n’est pas accessible en écriture", - "installation.issues.content": "Le dossier /content n’existe pas ou n’est pas accessible en écriture", - "installation.issues.curl": "L’extension CURL est requise", - "installation.issues.headline": "Le Panel ne peut être installé", - "installation.issues.mbstring": "L’extension MB String est requise", - "installation.issues.media": "Le dossier /media n’existe pas ou n’est pas accessible en écriture", - "installation.issues.php": "Veuillez utiliser PHP 7+", - "installation.issues.server": "Kirby requiert Apache, Nginx ou Caddy", - "installation.issues.sessions": "Le dossier /site/sessions n’existe pas ou n’est pas accessible en écriture", - - "language": "Langue", - "language.code": "Code", - "language.convert": "Choisir comme langue par défaut", - "language.convert.confirm": "

Souhaitez-vous vraiment convertir {name} vers la langue par défaut ? Cette action ne peut pas être annulée.

Si {name} a un contenu non traduit, il n’y aura plus de solution de secours possible et certaines parties de votre site pourraient être vides.

", - "language.create": "Ajouter une nouvelle langue", - "language.delete.confirm": "Voulez-vous vraiment supprimer la langue {name}, ainsi que toutes ses traductions ? Cette action ne peut être annulée !", - "language.deleted": "La langue a été supprimée", - "language.direction": "Sens de lecture", - "language.direction.ltr": "De gauche à droite", - "language.direction.rtl": "De droite à gauche", - "language.locale": "Locales PHP", - "language.locale.warning": "Vous utilisez une Locale PHP personnalisée. Veuillez la modifier dans le fichier de langue situé dans /site/languages", - "language.name": "Nom", - "language.updated": "La langue a été mise à jour", - - "languages": "Langages", - "languages.default": "Langue par défaut", - "languages.empty": "Il n’y a pas encore de langues", - "languages.secondary": "Langues secondaires", - "languages.secondary.empty": "Il n’y a pas encore de langues secondaires", - - "license": "Licence", - "license.buy": "Acheter une licence", - "license.register": "S’enregistrer", - "license.manage": "Gérer vos licences", - "license.register.help": "Vous avez reçu votre numéro de licence par courriel après l'achat. Veuillez le copier et le coller ici pour l'enregistrer.", - "license.register.label": "Veuillez saisir votre numéro de licence", - "license.register.success": "Merci pour votre soutien à Kirby", - "license.unregistered": "Ceci est une démo non enregistrée de Kirby", - "license.unregistered.label": "Non enregistré", - - "link": "Lien", - "link.text": "Texte du lien", - - "loading": "Chargement", - - "lock.unsaved": "Modifications non enregistrées", - "lock.unsaved.empty": "Il n’y a plus de modifications non enregistrées", - "lock.isLocked": "Modifications non enregistrées par {email}", - "lock.file.isLocked": "Le fichier est actuellement édité par {email} et ne peut être modifié.", - "lock.page.isLocked": "La page est actuellement éditée par {email} et ne peut être modifiée.", - "lock.unlock": "Déverrouiller", - "lock.isUnlocked": "Vos modifications non enregistrées ont été écrasées pas un autre utilisateur. Vous pouvez télécharger vos modifications pour les fusionner manuellement.", - - "login": "Connexion", - "login.code.label.login": "Code de connexion", - "login.code.label.password-reset": "Code de réinitialisation du mot de passe", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "Si votre adresse de courriel est enregistrée, le code demandé vous sera envoyé par courriel.", - "login.email.login.body": "Bonjour {user.nameOrEmail},\n\nVous avez récemment demandé un code de connexion pour le Panel de {site}.\nLe codede connexion suivant sera valide pendant {timeout} minutes :\n\n{code}\n\nSi vous n’avez pas demandé de codede connexion, veuillez ignorer cet email ou contacter votre administrateur si vous avez des questions.\nPar sécurité, merci de ne PAS faire suivre cet email.", - "login.email.login.subject": "Votre code de connexion", - "login.email.password-reset.body": "Bonjour {user.nameOrEmail},\n\nVous avez récemment demandé un code de réinitialisation de mot de passe pour le Panel de {site}.\nLe code de réinitialisation de mot de passe suivant sera valide pendant {timeout} minutes :\n\n{code}\n\nSi vous n’avez pas demandé de code de réinitialisation de mot de passe, veuillez ignorer cet email ou contacter votre administrateur si vous avez des questions.\nPar sécurité, merci de ne PAS faire suivre cet email.", - "login.email.password-reset.subject": "Votre code de réinitialisation du mot de passe", - "login.remember": "Rester connecté", - "login.reset": "Réinitialiser le mot de passe", - "login.toggleText.code.email": "Se connecter par courriel", - "login.toggleText.code.email-password": "Se connecter avec un mot de passe", - "login.toggleText.password-reset.email": "Mot de passe oublié ?", - "login.toggleText.password-reset.email-password": "← Retour à la connexion", - - "logout": "Se déconnecter", - - "menu": "Menu", - "meridiem": "AM/PM", - "mime": "Type de médias", - "minutes": "Minutes", - - "month": "Mois", - "months.april": "Avril", - "months.august": "Août", - "months.december": "Décembre", - "months.february": "Février", - "months.january": "Janvier", - "months.july": "Juillet", - "months.june": "Juin", - "months.march": "Mars", - "months.may": "Mai", - "months.november": "Novembre", - "months.october": "Octobre", - "months.september": "Septembre", - - "more": "Plus", - "name": "Nom", - "next": "Suivant", - "no": "non", - "off": "off", - "on": "on", - "open": "Ouvrir", - "open.newWindow": "Ouvrir dans une nouvelle fenêtre", - "options": "Options", - "options.none": "Pas d’options", - - "orientation": "Orientation", - "orientation.landscape": "Paysage", - "orientation.portrait": "Portrait", - "orientation.square": "Carré", - - "page.blueprint": "Cette page n’a pas encore de blueprint. Vous pouvez en définir les paramètres dans /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Modifier l’URL", - "page.changeSlug.fromTitle": "Créer à partir du titre", - "page.changeStatus": "Changer le statut", - "page.changeStatus.position": "Veuillez sélectionner une position", - "page.changeStatus.select": "Sélectionner un nouveau statut", - "page.changeTemplate": "Changer de modèle", - "page.delete.confirm": "Voulez-vous vraiment supprimer {title} ?", - "page.delete.confirm.subpages": "Cette page contient des sous-pages.
Toutes les sous-pages seront également supprimées.", - "page.delete.confirm.title": "Veuillez saisir le titre de la page pour confirmer", - "page.draft.create": "Créer un brouillon", - "page.duplicate.appendix": "Copier", - "page.duplicate.files": "Copier les fichiers", - "page.duplicate.pages": "Copier les pages", - "page.sort": "Modifier la position", - "page.status": "Statut", - "page.status.draft": "Brouillon", - "page.status.draft.description": "Cette page est un brouillon et n’est visible que pour les éditeurs connectés ou par un lien secret", - "page.status.listed": "Public", - "page.status.listed.description": "La page est publique pour tout le monde", - "page.status.unlisted": "Non listé", - "page.status.unlisted.description": "La page est uniquement accessible par son URL", - - "pages": "Pages", - "pages.empty": "Pas encore de pages", - "pages.status.draft": "Brouillons", - "pages.status.listed": "Publié", - "pages.status.unlisted": "Non listé", - - "pagination.page": "Page", - - "password": "Mot de passe", - "paste": "Coller", - "paste.after": "Coller après", - "pixel": "Pixel", - "plugins": "Plugins", - "prev": "Précédent", - "preview": "Prévisualiser", - "remove": "Supprimer", - "rename": "Renommer", - "replace": "Remplacer", - "retry": "Essayer à nouveau", - "revert": "Revenir", - "revert.confirm": "Voulez-vous vraiment supprimer toutes les modifications non-enregistrées ?", - - "role": "Rôle", - "role.admin.description": "L’administrateur dispose de tous les droits", - "role.admin.title": "Administrateur", - "role.all": "Tous", - "role.empty": "Il n’y a aucun utilisateur avec ce rôle", - "role.description.placeholder": "Pas de description", - "role.nobody.description": "Ceci est un rôle de secours sans aucune permission.", - "role.nobody.title": "Personne", - - "save": "Enregistrer", - "search": "Rechercher", - "search.min": "Entrez {min} caractères pour rechercher", - "search.all": "Tout afficher", - "search.results.none": "Pas de résultats", - - "section.required": "Cette section est obligatoire", - - "security": "Sécurité", - "select": "Sélectionner", - "server": "Serveur", - "settings": "Paramètres", - "show": "Afficher", - "site.blueprint": "Ce site n’a pas encore de blueprint. Vous pouvez en définir les paramètres dans /site/blueprints/site.yml", - "size": "Poids", - "slug": "Identifiant de l’URL", - "sort": "Trier", - - "stats.empty": "Aucun rapport", - "system.issues.content": "Le dossier content semble exposé", - "system.issues.debug": "Le débogage doit être désactivé en production", - "system.issues.git": "Le dossier .git semble exposé", - "system.issues.https": "Nous recommandons HTTPS pour tous vos sites", - "system.issues.kirby": "Le dossier kirby semble exposé", - "system.issues.site": "Le dossier site semble exposé", - - "title": "Titre", - "template": "Modèle", - "today": "Aujourd’hui", - - "toolbar.button.code": "Code", - "toolbar.button.bold": "Gras", - "toolbar.button.email": "Courriel", - "toolbar.button.headings": "Titres", - "toolbar.button.heading.1": "Titre 1", - "toolbar.button.heading.2": "Titre 2", - "toolbar.button.heading.3": "Titre 3", - "toolbar.button.heading.4": "Titre 4", - "toolbar.button.heading.5": "Titre 5", - "toolbar.button.heading.6": "Titre 6", - "toolbar.button.italic": "Italique", - "toolbar.button.file": "Fichier", - "toolbar.button.file.select": "Sélectionner un fichier", - "toolbar.button.file.upload": "Transférer un fichier", - "toolbar.button.link": "Lien", - "toolbar.button.paragraph": "Paragraphe", - "toolbar.button.strike": "Barré", - "toolbar.button.ol": "Liste ordonnée", - "toolbar.button.underline": "Souligné", - "toolbar.button.ul": "Liste non-ordonnée", - - "translation.author": "Kirby Team", - "translation.direction": "ltr", - "translation.name": "Français", - "translation.locale": "fr_FR", - - "upload": "Transférer", - "upload.error.cantMove": "Le fichier transféré n’a pu être déplacé", - "upload.error.cantWrite": "Le fichier n’a pu être écrit sur le disque", - "upload.error.default": "Le fichier n’a pu être transféré", - "upload.error.extension": "Le transfert de fichier a été stoppé par une extension", - "upload.error.formSize": "Le fichier transféré excède la directive MAX_FILE_SIZE spécifiée dans le formulaire", - "upload.error.iniPostSize": "Le fichier transféré excède la directive post_max_size spécifiée dans php.ini", - "upload.error.iniSize": "Le fichier transféré excède la directive upload_max_filesize spécifiée dans php.ini", - "upload.error.noFile": "Aucun fichier n’a été transféré", - "upload.error.noFiles": "Aucun fichier n’a été transféré", - "upload.error.partial": "Le fichier n’a été que partiellement transféré", - "upload.error.tmpDir": "Un dossier temporaire est manquant", - "upload.errors": "Erreur", - "upload.progress": "Transfert en cours…", - - "url": "Url", - "url.placeholder": "https://example.com", - - "user": "Utilisateur", - "user.blueprint": "Vous pouvez définir de nouvelles sections et champs de formulaires pour ce rôle d'utilisateur dans /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Modifier le courriel", - "user.changeLanguage": "Modifier la langue", - "user.changeName": "Renommer cet utilisateur", - "user.changePassword": "Modifier le mot de passe", - "user.changePassword.new": "Nouveau mot de passe", - "user.changePassword.new.confirm": "Confirmer le nouveau mot de passe…", - "user.changeRole": "Modifier le rôle", - "user.changeRole.select": "Sélectionner un nouveau rôle", - "user.create": "Ajouter un nouvel utilisateur", - "user.delete": "Supprimer cet utilisateur", - "user.delete.confirm": "Voulez-vous vraiment supprimer
{email} ?", - - "users": "Utilisateurs", - - "version": "Version", - - "view.account": "Votre compte", - "view.installation": "Installation", - "view.languages": "Langages", - "view.resetPassword": "Réinitialiser le mot de passe", - "view.site": "Site", - "view.system": "Système", - "view.users": "Utilisateurs", - - "welcome": "Bienvenue", - "year": "Année", - "yes": "oui" + "account.changeName": "Modifier votre nom", + "account.delete": "Supprimer votre compte", + "account.delete.confirm": "Voulez-vous vraiment supprimer votre compte ? Vous serez déconnecté immédiatement. Votre compte ne pourra pas être récupéré.", + + "add": "Ajouter", + "author": "Auteur", + "avatar": "Image du profil", + "back": "Retour", + "cancel": "Annuler", + "change": "Changer", + "close": "Fermer", + "confirm": "Ok", + "collapse": "Replier", + "collapse.all": "Tout replier", + "copy": "Copier", + "copy.all": "Tout copier", + "create": "Créer", + + "date": "Date", + "date.select": "Choisir une date", + + "day": "Jour", + "days.fri": "Ven", + "days.mon": "Lun", + "days.sat": "Sam", + "days.sun": "Dim", + "days.thu": "Jeu", + "days.tue": "Mar", + "days.wed": "Mer", + + "debugging": "Débogage", + + "delete": "Supprimer", + "delete.all": "Tout supprimer", + + "dialog.files.empty": "Aucun fichier à sélectionner", + "dialog.pages.empty": "Aucune page à sélectionner", + "dialog.users.empty": "Aucun utilisateur à sélectionner", + + "dimensions": "Dimensions", + "disabled": "Désactivé", + "discard": "Supprimer", + "download": "Télécharger", + "duplicate": "Dupliquer", + + "edit": "Éditer", + + "email": "Courriel", + "email.placeholder": "mail@example.com", + + "entries": "Entrées", + "entry": "Entrée", + + "environment": "Environnement", + + "error.access.code": "Code incorrect", + "error.access.login": "Identifiant incorrect", + "error.access.panel": "Vous n’êtes pas autorisé à accéder au Panel", + "error.access.view": "Vous n’êtes pas autorisé à accéder à cette section du Panel", + + "error.avatar.create.fail": "L’image du profil n’a pu être transférée", + "error.avatar.delete.fail": "L’image du profil n’a pu être supprimée", + "error.avatar.dimensions.invalid": "Veuillez choisir une image de profil de largeur et hauteur inférieures à 3000 pixels", + "error.avatar.mime.forbidden": "L'image du profil utilisateur doit être un fichier JPEG ou PNG", + + "error.blueprint.notFound": "Le blueprint « {name} » n’a pu être chargé", + + "error.blocks.max.plural": "Vous ne devez pas ajouter plus de {max} blocs", + "error.blocks.max.singular": "Vous ne devez pas ajouter plus d'un bloc", + "error.blocks.min.plural": "Vous devez ajouter au moins {min} blocs", + "error.blocks.min.singular": "Vous devez ajouter au moins un bloc", + "error.blocks.validation": "Il y a une erreur sur le champ \"{field}\" du bloc {index} utilisant le type de bloc \"{fieldset}\"", + + "error.email.preset.notFound": "La configuration de courriel « {name} » n’a pu être trouvé ", + + "error.field.converter.invalid": "Convertisseur « {converter} » incorrect", + + "error.file.changeName.empty": "Le nom ne peut être vide", + "error.file.changeName.permission": "Vous n’êtes pas autorisé à modifier le nom de « {filename} »", + "error.file.duplicate": "Un fichier nommé « {filename} » existe déjà", + "error.file.extension.forbidden": "L’extension « {extension} » n’est pas autorisée", + "error.file.extension.invalid": "Extension non valide : {extension}", + "error.file.extension.missing": "L’extension pour « {filename} » est manquante", + "error.file.maxheight": "La hauteur de l'image ne doit pas excéder {height} pixels", + "error.file.maxsize": "Le fichier est trop volumineux", + "error.file.maxwidth": "La largeur de l'image ne doit pas excéder {width} pixels", + "error.file.mime.differs": "Le fichier transféré doit être du même type de média « {mime} »", + "error.file.mime.forbidden": "Le type de média « {mime} » n’est pas autorisé", + "error.file.mime.invalid": "Type de média non valide : {mime}", + "error.file.mime.missing": "Le type de média de « {filename} » n’a pu être détecté", + "error.file.minheight": "La hauteur de l'image doit être au moins {height} pixels", + "error.file.minsize": "Le fichier n'est pas assez volumineux", + "error.file.minwidth": "La largeur de l'image doit être au moins {width} pixels", + "error.file.name.missing": "Veuillez entrer un titre", + "error.file.notFound": "Le fichier « {filename} » n’a pu être trouvé", + "error.file.orientation": "L'orientation de l'image doit être « {orientation} »", + "error.file.type.forbidden": "Vous n’êtes pas autorisé à transférer des fichiers {type}", + "error.file.type.invalid": "Type de fichier non valide : {type}", + "error.file.undefined": "Le fichier n’a pu être trouvé", + + "error.form.incomplete": "Veuillez corriger toutes les erreurs du formulaire…", + "error.form.notSaved": "Le formulaire n’a pu être enregistré", + + "error.language.code": "Veuillez saisir un code valide pour cette langue", + "error.language.duplicate": "Cette langue existe déjà", + "error.language.name": "Veuillez saisir un nom valide pour cette langue", + "error.language.notFound": "La langue n’a pu être trouvée", + + "error.layout.validation.block": "Il y a une erreur sur le champ \"{field}\" du bloc {blockIndex} utilisant le type de bloc \"{fieldset}\" dans le layout {layoutIndex}.", + "error.layout.validation.settings": "Il y a une erreur dans les paramètres de la disposition {index}", + + "error.license.format": "Veuillez saisir un numéro de licence valide", + "error.license.email": "Veuillez saisir un courriel valide", + "error.license.verification": "La licence n’a pu être vérifiée", + + "error.object.validation": "Il y a une erreur dans le champ \"{label}\" :\n{message}", + + "error.offline": "Le Panel est actuellement hors ligne", + + "error.page.changeSlug.permission": "Vous n’êtes pas autorisé à modifier l’identifiant d’URL pour « {slug} »", + "error.page.changeStatus.incomplete": "La page comporte des erreurs et ne peut pas être publiée", + "error.page.changeStatus.permission": "Le statut de cette page ne peut être modifié", + "error.page.changeStatus.toDraft.invalid": "La page « {slug} » ne peut être convertie en brouillon", + "error.page.changeTemplate.invalid": "Le modèle de la page « {slug} » ne peut être changé", + "error.page.changeTemplate.permission": "Vous n’êtes pas autorisé à changer le modèle de « {slug} »", + "error.page.changeTitle.empty": "Le titre ne peut être vide", + "error.page.changeTitle.permission": "Vous n’êtes pas autorisé à modifier le titre de « {slug} »", + "error.page.create.permission": "Vous n’êtes pas autorisé à créer « {slug} »", + "error.page.delete": "La page « {slug} » ne peut être supprimée", + "error.page.delete.confirm": "Veuillez saisir le titre de la page pour confirmer", + "error.page.delete.hasChildren": "La page comporte des sous-pages et ne peut pas être supprimée", + "error.page.delete.permission": "Vous n’êtes pas autorisé à supprimer « {slug} »", + "error.page.draft.duplicate": "Un brouillon avec l’identifiant d’URL « {slug} » existe déjà", + "error.page.duplicate": "Une page avec l’identifiant d’URL « {slug} » existe déjà", + "error.page.duplicate.permission": "Vous n'êtes pas autorisé à dupliquer « {slug} »", + "error.page.notFound": "La page « {slug} » n’a pu être trouvée", + "error.page.num.invalid": "Veuillez saisir un numéro de position valide. Les numéros ne doivent pas être négatifs.", + "error.page.slug.invalid": "Veuillez entrer un identifiant d’URL valide", + "error.page.slug.maxlength": "L’identifiant d’URL doit faire moins de « {length} » caractères", + "error.page.sort.permission": "La page « {slug} » ne peut être réordonnée", + "error.page.status.invalid": "Veuillez choisir un statut de page valide", + "error.page.undefined": "La page n’a pu être trouvée", + "error.page.update.permission": "Vous n’êtes pas autorisé à modifier « {slug} »", + + "error.section.files.max.plural": "Vous ne pouvez ajouter plus de {max} fichier(s) à la section « {section} »", + "error.section.files.max.singular": "Vous ne pouvez ajouter plus d’un fichier à la section « {section} »", + "error.section.files.min.plural": "La section « {section} » requiert au moins {min} fichiers", + "error.section.files.min.singular": "La section « {section} » requiert au moins un fichier", + + "error.section.pages.max.plural": "Vous ne pouvez ajouter plus de {max} pages à la section « {section} »", + "error.section.pages.max.singular": "Vous ne pouvez ajouter plus d’une page à la section « {section} »", + "error.section.pages.min.plural": "La section « {section} » requiert au moins {min} pages", + "error.section.pages.min.singular": "La section « {section} » requiert au moins une page", + + "error.section.notLoaded": "La section « {name} » n’a pu être chargée", + "error.section.type.invalid": "Le type de section « {type} » est incorrect", + + "error.site.changeTitle.empty": "Le titre ne peut être vide", + "error.site.changeTitle.permission": "Vous n’êtes pas autorisé à modifier le titre du site", + "error.site.update.permission": "Vous n’êtes pas autorisé à modifier le contenu global du site", + + "error.template.default.notFound": "Le modèle par défaut n’existe pas", + + "error.unexpected": "Une erreur inattendue est survenue ! Activez le mode de débogage pour plus d'informations : https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Vous n’êtes pas autorisé à modifier le courriel de l’utilisateur « {name} »", + "error.user.changeLanguage.permission": "Vous n’êtes pas autorisé à changer la langue de l’utilisateur « {name} »", + "error.user.changeName.permission": "Vous n’êtes pas autorisé à modifier le nom de l’utilisateur « {name} »", + "error.user.changePassword.permission": "Vous n’êtes pas autorisé à changer le mot de passe de l’utilisateur « {name} »", + "error.user.changeRole.lastAdmin": "Le rôle du dernier administrateur ne peut être modifié", + "error.user.changeRole.permission": "Vous n’êtes pas autorisé à changer le rôle de l’utilisateur « {name} »", + "error.user.changeRole.toAdmin": "Vous n’êtes pas autorisé à attribuer le rôle d’administrateur aux utilisateurs", + "error.user.create.permission": "Vous n’êtes pas autorisé à créer cet utilisateur", + "error.user.delete": "L’utilisateur « {name} » ne peut être supprimé", + "error.user.delete.lastAdmin": "Le dernier administrateur ne peut être supprimé", + "error.user.delete.lastUser": "Le dernier utilisateur ne peut être supprimé", + "error.user.delete.permission": "Vous n’êtes pas autorisé à supprimer l’utilisateur « {name} »", + "error.user.duplicate": "Un utilisateur avec le courriel « {email} » existe déjà", + "error.user.email.invalid": "Veuillez saisir un courriel valide", + "error.user.language.invalid": "Veuillez saisir une langue valide", + "error.user.notFound": "L’utilisateur « {name} » n’a pu être trouvé", + "error.user.password.invalid": "Veuillez saisir un mot de passe valide. Les mots de passe doivent comporter au moins 8 caractères.", + "error.user.password.notSame": "Les mots de passe ne sont pas identiques", + "error.user.password.undefined": "Cet utilisateur n’a pas de mot de passe", + "error.user.password.wrong": "Mot de passe incorrect", + "error.user.role.invalid": "Veuillez saisir un rôle valide", + "error.user.undefined": "L’utilisateur n’a pu être trouvé", + "error.user.update.permission": "Vous n’êtes pas autorisé à modifier l’utilisateur « {name} »", + + "error.validation.accepted": "Veuillez confirmer", + "error.validation.alpha": "Veuillez saisir uniquement des caractères alphabétiques minuscules", + "error.validation.alphanum": "Veuillez ne saisir que des minuscules de a à z et des chiffres de 0 à 9", + "error.validation.between": "Veuillez saisir une valeur entre « {min} » et « {max} »", + "error.validation.boolean": "Veuillez confirmer ou refuser", + "error.validation.contains": "Veuillez saisir une valeur contenant « {needle} »", + "error.validation.date": "Veuillez saisir une date valide", + "error.validation.date.after": "Veuillez saisir une date après {date}", + "error.validation.date.before": "Veuillez saisir une date avant {date}", + "error.validation.date.between": "Veuillez saisir une date entre {min} et {max}", + "error.validation.denied": "Veuillez refuser", + "error.validation.different": "La valeur ne doit pas être « {other} »", + "error.validation.email": "Veuillez saisir un courriel valide", + "error.validation.endswith": "La valeur doit se terminer par « {end} »", + "error.validation.filename": "Veuillez saisir un nom de fichier valide", + "error.validation.in": "Veuillez saisir l’un des éléments suivants: ({in})", + "error.validation.integer": "Veuillez saisir un entier valide", + "error.validation.ip": "Veuillez saisir une adresse IP valide", + "error.validation.less": "Veuillez saisir une valeur inférieure à {max}", + "error.validation.match": "La valeur ne correspond pas au modèle attendu", + "error.validation.max": "Veuillez saisir une valeur inférieure ou égale à {max}", + "error.validation.maxlength": "Veuillez saisir une valeur plus courte (max. {max} caractères)", + "error.validation.maxwords": "Veuillez ne pas saisir plus de {max} mot(s)", + "error.validation.min": "Veuillez saisir une valeur supérieure ou égale à {min}", + "error.validation.minlength": "Veuillez saisir une valeur plus longue (min. {min} caractères)", + "error.validation.minwords": "Veuillez saisir au moins {min} mot(s)", + "error.validation.more": "Veuillez saisir une valeur supérieure à {min}", + "error.validation.notcontains": "Veuillez saisir une valeur ne contenant pas « {needle} »", + "error.validation.notin": "Veuillez ne saisir aucun des éléments suivants: ({notIn})", + "error.validation.option": "Veuillez sélectionner une option valide", + "error.validation.num": "Veuillez saisir un nombre valide", + "error.validation.required": "Veuillez saisir quelque chose", + "error.validation.same": "Veuillez saisir « {other} »", + "error.validation.size": "La grandeur de la valeur doit être « {size} »", + "error.validation.startswith": "La valeur doit commencer par « {start} »", + "error.validation.time": "Veuillez saisir une heure valide", + "error.validation.time.after": "Veuillez entrer une heure après {time}", + "error.validation.time.before": "Veuillez entrer une heure avant {time}", + "error.validation.time.between": "Veuillez entrer une heure entre {min} et {max}", + "error.validation.url": "Veuillez saisir une URL valide", + + "expand": "Déplier", + "expand.all": "Tout déplier", + + "field.required": "Le champ est obligatoire", + "field.blocks.changeType": "Changer le type", + "field.blocks.code.name": "Code", + "field.blocks.code.language": "Langue", + "field.blocks.code.placeholder": "Votre code…", + "field.blocks.delete.confirm": "Voulez-vous vraiment supprimer ce bloc ?", + "field.blocks.delete.confirm.all": "Voulez-vous vraiment supprimer tous les blocs ?", + "field.blocks.delete.confirm.selected": "Voulez-vous vraiment supprimer les blocs sélectionnés ?", + "field.blocks.empty": "Pas encore de blocs", + "field.blocks.fieldsets.label": "Veuillez sélectionner un type de bloc…", + "field.blocks.fieldsets.paste": "Presser {{ shortcut }} pour coller/importer des blocks depuis votre presse-papier", + "field.blocks.gallery.name": "Galerie", + "field.blocks.gallery.images.empty": "Pas encore d’images", + "field.blocks.gallery.images.label": "Images", + "field.blocks.heading.level": "Niveau", + "field.blocks.heading.name": "Titre", + "field.blocks.heading.text": "Texte", + "field.blocks.heading.placeholder": "Titre…", + "field.blocks.image.alt": "Texte alternatif", + "field.blocks.image.caption": "Légende", + "field.blocks.image.crop": "Recadrer", + "field.blocks.image.link": "Lien", + "field.blocks.image.location": "Emplacement", + "field.blocks.image.name": "Image", + "field.blocks.image.placeholder": "Sélectionnez une image", + "field.blocks.image.ratio": "Proportions", + "field.blocks.image.url": "URL de l'image", + "field.blocks.line.name": "Ligne", + "field.blocks.list.name": "Liste", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Texte", + "field.blocks.markdown.placeholder": "Markdown…", + "field.blocks.quote.name": "Citation", + "field.blocks.quote.text.label": "Texte", + "field.blocks.quote.text.placeholder": "Citation…", + "field.blocks.quote.citation.label": "Citation", + "field.blocks.quote.citation.placeholder": "par…", + "field.blocks.text.name": "Texte", + "field.blocks.text.placeholder": "Texte…", + "field.blocks.video.caption": "Légende", + "field.blocks.video.name": "Vidéo", + "field.blocks.video.placeholder": "Entrez l’URL d’une vidéo", + "field.blocks.video.url.label": "URL de la vidéo", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Pas encore de fichier sélectionné", + + "field.layout.delete": "Supprimer cette disposition", + "field.layout.delete.confirm": "Voulez-vous vraiment supprimer cette disposition ?", + "field.layout.empty": "Pas encore de rangées", + "field.layout.select": "Choisir une disposition", + + "field.object.empty": "Pas encore d‘information", + + "field.pages.empty": "Pas encore de page sélectionnée", + + "field.structure.delete.confirm": "Voulez-vous vraiment supprimer cette ligne ?", + "field.structure.empty": "Pas encore d’entrée", + + "field.users.empty": "Pas encore d’utilisateur sélectionné", + + "file.blueprint": "Ce fichier n’a pas encore de blueprint. Vous pouvez en définir les paramètres dans /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Voulez-vous vraiment supprimer
{filename} ?", + "file.sort": "Modifier la position", + + "files": "Fichiers", + "files.empty": "Pas encore de fichier", + + "hide": "Masquer", + "hour": "Heure", + "import": "Importer", + "info": "Info", + "insert": "Insérer", + "insert.after": "Insérer après", + "insert.before": "Insérer avant", + "install": "Installer", + + "installation": "Installation", + "installation.completed": "Le Panel a été installé", + "installation.disabled": "L'installation du Panel est désactivée par défaut sur les serveurs publics. Veuillez lancer l'installation sur un serveur local, ou activez-la avec l'option panel.install.", + "installation.issues.accounts": "Le dossier /site/accounts n’existe pas ou n’est pas accessible en écriture", + "installation.issues.content": "Le dossier /content n’existe pas ou n’est pas accessible en écriture", + "installation.issues.curl": "L’extension CURL est requise", + "installation.issues.headline": "Le Panel ne peut être installé", + "installation.issues.mbstring": "L’extension MB String est requise", + "installation.issues.media": "Le dossier /media n’existe pas ou n’est pas accessible en écriture", + "installation.issues.php": "Veuillez utiliser PHP 7+", + "installation.issues.server": "Kirby requiert Apache, Nginx ou Caddy", + "installation.issues.sessions": "Le dossier /site/sessions n’existe pas ou n’est pas accessible en écriture", + + "language": "Langue", + "language.code": "Code", + "language.convert": "Choisir comme langue par défaut", + "language.convert.confirm": "

Souhaitez-vous vraiment convertir {name} vers la langue par défaut ? Cette action ne peut pas être annulée.

Si {name} a un contenu non traduit, il n’y aura plus de solution de secours possible et certaines parties de votre site pourraient être vides.

", + "language.create": "Ajouter une nouvelle langue", + "language.delete.confirm": "Voulez-vous vraiment supprimer la langue {name}, ainsi que toutes ses traductions ? Cette action ne peut être annulée !", + "language.deleted": "La langue a été supprimée", + "language.direction": "Sens de lecture", + "language.direction.ltr": "De gauche à droite", + "language.direction.rtl": "De droite à gauche", + "language.locale": "Locales PHP", + "language.locale.warning": "Vous utilisez une Locale PHP personnalisée. Veuillez la modifier dans le fichier de langue situé dans /site/languages", + "language.name": "Nom", + "language.updated": "La langue a été mise à jour", + + "languages": "Langages", + "languages.default": "Langue par défaut", + "languages.empty": "Il n’y a pas encore de langues", + "languages.secondary": "Langues secondaires", + "languages.secondary.empty": "Il n’y a pas encore de langues secondaires", + + "license": "Licence", + "license.buy": "Acheter une licence", + "license.register": "S’enregistrer", + "license.manage": "Gérer vos licences", + "license.register.help": "Vous avez reçu votre numéro de licence par courriel après l'achat. Veuillez le copier et le coller ici pour l'enregistrer.", + "license.register.label": "Veuillez saisir votre numéro de licence", + "license.register.success": "Merci pour votre soutien à Kirby", + "license.unregistered": "Ceci est une démo non enregistrée de Kirby", + "license.unregistered.label": "Non enregistré", + + "link": "Lien", + "link.text": "Texte du lien", + + "loading": "Chargement", + + "lock.unsaved": "Modifications non enregistrées", + "lock.unsaved.empty": "Il n’y a plus de modifications non enregistrées", + "lock.isLocked": "Modifications non enregistrées par {email}", + "lock.file.isLocked": "Le fichier est actuellement édité par {email} et ne peut être modifié.", + "lock.page.isLocked": "La page est actuellement éditée par {email} et ne peut être modifiée.", + "lock.unlock": "Déverrouiller", + "lock.isUnlocked": "Vos modifications non enregistrées ont été écrasées pas un autre utilisateur. Vous pouvez télécharger vos modifications pour les fusionner manuellement.", + + "login": "Connexion", + "login.code.label.login": "Code de connexion", + "login.code.label.password-reset": "Code de réinitialisation du mot de passe", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "Si votre adresse de courriel est enregistrée, le code demandé vous sera envoyé par courriel.", + "login.email.login.body": "Bonjour {user.nameOrEmail},\n\nVous avez récemment demandé un code de connexion pour le Panel de {site}.\nLe code de connexion suivant sera valide pendant {timeout} minutes :\n\n{code}\n\nSi vous n’avez pas demandé de code de connexion, veuillez ignorer cet email ou contacter votre administrateur si vous avez des questions.\nPar sécurité, merci de ne PAS faire suivre cet email.", + "login.email.login.subject": "Votre code de connexion", + "login.email.password-reset.body": "Bonjour {user.nameOrEmail},\n\nVous avez récemment demandé un code de réinitialisation de mot de passe pour le Panel de {site}.\nLe code de réinitialisation de mot de passe suivant sera valide pendant {timeout} minutes :\n\n{code}\n\nSi vous n’avez pas demandé de code de réinitialisation de mot de passe, veuillez ignorer cet email ou contacter votre administrateur si vous avez des questions.\nPar sécurité, merci de ne PAS faire suivre cet email.", + "login.email.password-reset.subject": "Votre code de réinitialisation du mot de passe", + "login.remember": "Rester connecté", + "login.reset": "Réinitialiser le mot de passe", + "login.toggleText.code.email": "Se connecter par courriel", + "login.toggleText.code.email-password": "Se connecter avec un mot de passe", + "login.toggleText.password-reset.email": "Mot de passe oublié ?", + "login.toggleText.password-reset.email-password": "← Retour à la connexion", + + "logout": "Se déconnecter", + + "menu": "Menu", + "meridiem": "AM/PM", + "mime": "Type de médias", + "minutes": "Minutes", + + "month": "Mois", + "months.april": "Avril", + "months.august": "Août", + "months.december": "Décembre", + "months.february": "Février", + "months.january": "Janvier", + "months.july": "Juillet", + "months.june": "Juin", + "months.march": "Mars", + "months.may": "Mai", + "months.november": "Novembre", + "months.october": "Octobre", + "months.september": "Septembre", + + "more": "Plus", + "name": "Nom", + "next": "Suivant", + "no": "non", + "off": "off", + "on": "on", + "open": "Ouvrir", + "open.newWindow": "Ouvrir dans une nouvelle fenêtre", + "options": "Options", + "options.none": "Pas d’options", + + "orientation": "Orientation", + "orientation.landscape": "Paysage", + "orientation.portrait": "Portrait", + "orientation.square": "Carré", + + "page.blueprint": "Cette page n’a pas encore de blueprint. Vous pouvez en définir les paramètres dans /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Modifier l’URL", + "page.changeSlug.fromTitle": "Créer à partir du titre", + "page.changeStatus": "Changer le statut", + "page.changeStatus.position": "Veuillez sélectionner une position", + "page.changeStatus.select": "Sélectionner un nouveau statut", + "page.changeTemplate": "Changer de modèle", + "page.delete.confirm": "Voulez-vous vraiment supprimer {title} ?", + "page.delete.confirm.subpages": "Cette page contient des sous-pages.
Toutes les sous-pages seront également supprimées.", + "page.delete.confirm.title": "Veuillez saisir le titre de la page pour confirmer", + "page.draft.create": "Créer un brouillon", + "page.duplicate.appendix": "Copier", + "page.duplicate.files": "Copier les fichiers", + "page.duplicate.pages": "Copier les pages", + "page.sort": "Modifier la position", + "page.status": "Statut", + "page.status.draft": "Brouillon", + "page.status.draft.description": "Cette page est un brouillon et n’est visible que pour les éditeurs connectés ou par un lien secret", + "page.status.listed": "Public", + "page.status.listed.description": "La page est publique pour tout le monde", + "page.status.unlisted": "Non listé", + "page.status.unlisted.description": "La page est uniquement accessible par son URL", + + "pages": "Pages", + "pages.empty": "Pas encore de pages", + "pages.status.draft": "Brouillons", + "pages.status.listed": "Publié", + "pages.status.unlisted": "Non listé", + + "pagination.page": "Page", + + "password": "Mot de passe", + "paste": "Coller", + "paste.after": "Coller après", + "pixel": "Pixel", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "Précédent", + "preview": "Prévisualiser", + "remove": "Supprimer", + "rename": "Renommer", + "replace": "Remplacer", + "retry": "Essayer à nouveau", + "revert": "Revenir", + "revert.confirm": "Voulez-vous vraiment supprimer toutes les modifications non-enregistrées ?", + + "role": "Rôle", + "role.admin.description": "L’administrateur dispose de tous les droits", + "role.admin.title": "Administrateur", + "role.all": "Tous", + "role.empty": "Il n’y a aucun utilisateur avec ce rôle", + "role.description.placeholder": "Pas de description", + "role.nobody.description": "Ceci est un rôle de secours sans aucune permission.", + "role.nobody.title": "Personne", + + "save": "Enregistrer", + "search": "Rechercher", + "search.min": "Entrez {min} caractères pour rechercher", + "search.all": "Tout afficher", + "search.results.none": "Pas de résultats", + + "section.required": "Cette section est obligatoire", + + "security": "Sécurité", + "select": "Sélectionner", + "server": "Serveur", + "settings": "Paramètres", + "show": "Afficher", + "site.blueprint": "Ce site n’a pas encore de blueprint. Vous pouvez en définir les paramètres dans /site/blueprints/site.yml", + "size": "Poids", + "slug": "Identifiant de l’URL", + "sort": "Trier", + + "stats.empty": "Aucun rapport", + "system.issues.content": "Le dossier content semble exposé", + "system.issues.eol.kirby": "La version de Kirby installée a atteint la fin de son cycle de vie et ne recevra plus de mises à jour de sécurité", + "system.issues.eol.plugin": "La version du plugin { plugin } installée a atteint la fin de son cycle de vie et ne recevra plus de mises à jour de sécurité", + "system.issues.debug": "Le débogage doit être désactivé en production", + "system.issues.git": "Le dossier .git semble exposé", + "system.issues.https": "Nous recommandons HTTPS pour tous vos sites", + "system.issues.kirby": "Le dossier kirby semble exposé", + "system.issues.site": "Le dossier site semble exposé", + "system.issues.vulnerability.kirby": "Votre installation pourrait être affectée par la vulnérabilité suivante ({ severity } gravité) : { description }", + "system.issues.vulnerability.plugin": "Votre installation pourrait être affectée par la vulnérabilité suivante du plugin { plugin } ({ severity } gravité) : { description }", + "system.updateStatus": "Statut des mises à jour", + "system.updateStatus.error": "Les mises à jour n'ont pu être vérifiées", + "system.updateStatus.not-vulnerable": "Aucune vulnérabilité connue", + "system.updateStatus.security-update": "Mise à jour gratuite { version } disponible", + "system.updateStatus.security-upgrade": "Mise à jour { version } avec correctifs de sécurité disponible", + "system.updateStatus.unreleased": "Version non diffusée", + "system.updateStatus.up-to-date": "À jour", + "system.updateStatus.update": "Mise à jour gratuite { version } disponible", + "system.updateStatus.upgrade": "Mise à jour { version } disponible", + + "title": "Titre", + "template": "Modèle", + "today": "Aujourd’hui", + + "toolbar.button.code": "Code", + "toolbar.button.bold": "Gras", + "toolbar.button.email": "Courriel", + "toolbar.button.headings": "Titres", + "toolbar.button.heading.1": "Titre 1", + "toolbar.button.heading.2": "Titre 2", + "toolbar.button.heading.3": "Titre 3", + "toolbar.button.heading.4": "Titre 4", + "toolbar.button.heading.5": "Titre 5", + "toolbar.button.heading.6": "Titre 6", + "toolbar.button.italic": "Italique", + "toolbar.button.file": "Fichier", + "toolbar.button.file.select": "Sélectionner un fichier", + "toolbar.button.file.upload": "Transférer un fichier", + "toolbar.button.link": "Lien", + "toolbar.button.paragraph": "Paragraphe", + "toolbar.button.strike": "Barré", + "toolbar.button.ol": "Liste ordonnée", + "toolbar.button.underline": "Souligné", + "toolbar.button.ul": "Liste non-ordonnée", + + "translation.author": "Kirby Team", + "translation.direction": "ltr", + "translation.name": "Français", + "translation.locale": "fr_FR", + + "upload": "Transférer", + "upload.error.cantMove": "Le fichier transféré n’a pu être déplacé", + "upload.error.cantWrite": "Le fichier n’a pu être écrit sur le disque", + "upload.error.default": "Le fichier n’a pu être transféré", + "upload.error.extension": "Le transfert de fichier a été stoppé par une extension", + "upload.error.formSize": "Le fichier transféré excède la directive MAX_FILE_SIZE spécifiée dans le formulaire", + "upload.error.iniPostSize": "Le fichier transféré excède la directive post_max_size spécifiée dans php.ini", + "upload.error.iniSize": "Le fichier transféré excède la directive upload_max_filesize spécifiée dans php.ini", + "upload.error.noFile": "Aucun fichier n’a été transféré", + "upload.error.noFiles": "Aucun fichier n’a été transféré", + "upload.error.partial": "Le fichier n’a été que partiellement transféré", + "upload.error.tmpDir": "Un dossier temporaire est manquant", + "upload.errors": "Erreur", + "upload.progress": "Transfert en cours…", + + "url": "Url", + "url.placeholder": "https://example.com", + + "user": "Utilisateur", + "user.blueprint": "Vous pouvez définir de nouvelles sections et champs de formulaires pour ce rôle d'utilisateur dans /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Modifier le courriel", + "user.changeLanguage": "Modifier la langue", + "user.changeName": "Renommer cet utilisateur", + "user.changePassword": "Modifier le mot de passe", + "user.changePassword.new": "Nouveau mot de passe", + "user.changePassword.new.confirm": "Confirmer le nouveau mot de passe…", + "user.changeRole": "Modifier le rôle", + "user.changeRole.select": "Sélectionner un nouveau rôle", + "user.create": "Ajouter un nouvel utilisateur", + "user.delete": "Supprimer cet utilisateur", + "user.delete.confirm": "Voulez-vous vraiment supprimer
{email} ?", + + "users": "Utilisateurs", + + "version": "Version", + "version.current": "Version actuelle", + "version.latest": "Dernière version", + "versionInformation": "Informations de version", + + "view.account": "Votre compte", + "view.installation": "Installation", + "view.languages": "Langages", + "view.resetPassword": "Réinitialiser le mot de passe", + "view.site": "Site", + "view.system": "Système", + "view.users": "Utilisateurs", + + "welcome": "Bienvenue", + "year": "Année", + "yes": "oui" } diff --git a/kirby/i18n/translations/hu.json b/kirby/i18n/translations/hu.json index aee0b7e..626df00 100644 --- a/kirby/i18n/translations/hu.json +++ b/kirby/i18n/translations/hu.json @@ -1,573 +1,596 @@ { - "account.changeName": "Név megváltoztatása", - "account.delete": "Fiók törlése", - "account.delete.confirm": "Tényleg törölni szeretnéd a fiókodat? Azonnal kijelentkeztetünk és ez a folyamat visszavonhatatlan.", - - "add": "Hozz\u00e1ad", - "author": "Szerző", - "avatar": "Profilkép", - "back": "Vissza", - "cancel": "M\u00e9gsem", - "change": "M\u00f3dos\u00edt\u00e1s", - "close": "Bez\u00e1r", - "confirm": "Mentés", - "collapse": "Bezárás", - "collapse.all": "Összes bezárása", - "copy": "Másol", - "copy.all": "Összes másolása", - "create": "Létrehoz", - - "date": "Dátum", - "date.select": "Dátum kiválasztása", - - "day": "Nap", - "days.fri": "p\u00e9", - "days.mon": "h\u00e9", - "days.sat": "szo", - "days.sun": "va", - "days.thu": "cs\u00fc", - "days.tue": "ke", - "days.wed": "sze", - - "debugging": "Hibakeresés", - - "delete": "T\u00f6rl\u00e9s", - "delete.all": "Összes törlése", - - "dialog.files.empty": "Nincsenek fájlok kiválasztva", - "dialog.pages.empty": "Nincsenek oldalak kiválasztva", - "dialog.users.empty": "Nincsenek felhasználók kiválasztva", - - "dimensions": "Méretek", - "disabled": "Inaktív", - "discard": "Visszavon\u00e1s", - "download": "Letöltés", - "duplicate": "Másolat", - - "edit": "Aloldal szerkeszt\u00e9se", - - "email": "Email", - "email.placeholder": "mail@pelda.hu", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Környezet", - - "error.access.code": "Érvénytelen kód", - "error.access.login": "Érvénytelen bejelentkezés", - "error.access.panel": "Nincs jogosultságod megnyitni a panelt", - "error.access.view": "Nincs hozzáférésed a panel ezen részéhez", - - "error.avatar.create.fail": "A profilkép feltöltése nem sikerült", - "error.avatar.delete.fail": "A profilkép nem törölhető", - "error.avatar.dimensions.invalid": "A profilkép maximális szélessége és magassága 3000 pixel lehet", - "error.avatar.mime.forbidden": "A profilkép formátuma csak JPEG vagy PNG lehet", - - "error.blueprint.notFound": "A \"{name}\" oldalsablon nem tölthető be", - - "error.blocks.max.plural": "Legfeljebb {max} blokk adható hozzá", - "error.blocks.max.singular": "Csak egyetlen blokk adható hozzá", - "error.blocks.min.plural": "Legalább {min} blokkot hozzá kell adnod", - "error.blocks.min.singular": "Legalább egy blokkot hozzá kell adnod", - "error.blocks.validation": "Hiba van az alábbi blokkban: {index}", - - "error.email.preset.notFound": "A \"{name}\" email-beállítás nem található", - - "error.field.converter.invalid": "Érvénytelen konverter: \"{converter}\"", - - "error.file.changeName.empty": "A név nem lehet üres", - "error.file.changeName.permission": "Nincs jogosultságod megváltoztatni a \"{filename}\" fájl nevét", - "error.file.duplicate": "Már létezik \"{filename}\" nevű fájl", - "error.file.extension.forbidden": "Tiltott kiterjeszt\u00e9s\u0171 f\u00e1jl", - "error.file.extension.invalid": "Érvénytelen kiterjesztés: {extension}", - "error.file.extension.missing": "Kiterjeszt\u00e9s n\u00e9lk\u00fcli f\u00e1jl nem t\u00f6lthet\u0151 fel", - "error.file.maxheight": "A kép nem lehet magasabb {height} pixelnél", - "error.file.maxsize": "A fájl túl nagy", - "error.file.maxwidth": "A kép nem lehet szélesebb {width} pixelnél", - "error.file.mime.differs": "A feltöltött fájlnak azonos \"{mime}\" típusúnak kell lennie", - "error.file.mime.forbidden": "A \"{mime}\" típusú médiafájlok nem engedélyezettek", - "error.file.mime.invalid": "Érvénytelen mime-típus: {mime}", - "error.file.mime.missing": "A \"{filename}\" fájl típusa nem állapítható meg", - "error.file.minheight": "A képnek legalább {height} pixel magasnak kell lennie", - "error.file.minsize": "A fájl túl kicsi", - "error.file.minwidth": "A képnek legalább {width} pixel szélesnek kell lennie", - "error.file.name.missing": "A fálj neve nem lehet üres", - "error.file.notFound": "A \"{filename}\" fájl nem található", - "error.file.orientation": "A képnek \"{orientation}\" tájolásúnak kell lennie", - "error.file.type.forbidden": "Nem tölthetsz fel \"{type}\" típusú fájlokat", - "error.file.type.invalid": "Érvénytelen fájltípus: {type}", - "error.file.undefined": "A f\u00e1jl nem tal\u00e1lhat\u00f3", - - "error.form.incomplete": "Kérlek javítsd ki az összes hibát az űrlapon", - "error.form.notSaved": "Az űrlap nem menthető", - - "error.language.code": "Kérlek, add meg a nyelv érvényes kódját", - "error.language.duplicate": "A nyelv már létezik", - "error.language.name": "Kérlek, add meg a nyelv érvényes nevét", - "error.language.notFound": "A nyelv nem található", - - "error.layout.validation.block": "Hibát találtunk az alábbi blokkban: {blockIndex} az alábbi elrendezésben: {layoutIndex}", - "error.layout.validation.settings": "Hibát találtunk a(z) {index} elrendezés beállításaiban", - - "error.license.format": "Kérlek, add meg az évényes lincensz kulcsot", - "error.license.email": "Kérlek adj meg egy valós email-címet", - "error.license.verification": "A licensz nem ellenőrizhető", - - "error.offline": "A Panel jelenleg nem elérhető", - - "error.page.changeSlug.permission": "Nem változtathatod meg az URL-előtagot: \"{slug}\"", - "error.page.changeStatus.incomplete": "Az oldal hibákat tartalmaz és nem publikálható", - "error.page.changeStatus.permission": "Az oldal státusza nem változtatható meg", - "error.page.changeStatus.toDraft.invalid": "A(z) \"{slug}\" oldalt nem lehet piszkozattá alakítani", - "error.page.changeTemplate.invalid": "A \"{slug}\" oldal sablonját nem lehet megváltoztatni", - "error.page.changeTemplate.permission": "Nincs jogosultságod megváltoztatni a sablont ehhez: \"{slug}\"", - "error.page.changeTitle.empty": "A cím nem lehet üres", - "error.page.changeTitle.permission": "Nincs jogosultságod megváltoztatni a címet: \"{slug}\"", - "error.page.create.permission": "Nincs jogosultságod az oldal létrehozásához: \"{slug}\"", - "error.page.delete": "A(z) \"{slug}\" oldal nem törölhető", - "error.page.delete.confirm": "Megerősítéshez add meg az oldal címét", - "error.page.delete.hasChildren": "Az oldalnak vannak aloldalai és nem törölhető", - "error.page.delete.permission": "Nincs jogosultságod a(z) \"{slug}\" oldal törléséhez", - "error.page.draft.duplicate": "Van már egy másik oldal ezzel az URL-lel: \"{slug}\"", - "error.page.duplicate": "Van már egy másik oldal ezzel az URL-lel: \"{slug}\"", - "error.page.duplicate.permission": "Nincs engedélyed a(z) \"{slug}\" másolat keszítéséhez", - "error.page.notFound": "Az oldal nem tal\u00e1lhat\u00f3", - "error.page.num.invalid": "Kérlek megfelelő oldalszámozást adj meg. Negatív szám itt nem használható.", - "error.page.slug.invalid": "Kérlek érvényes URL-kiterjesztést adj meg", - "error.page.slug.maxlength": "Az URL maximum \"{length}\" karakter hosszúságú lehet", - "error.page.sort.permission": "A(z) \"{slug}\" oldal nem illeszthető a sorrendbe", - "error.page.status.invalid": "Kérlek add meg a megfelelő oldalstátuszt", - "error.page.undefined": "Az oldal nem tal\u00e1lhat\u00f3", - "error.page.update.permission": "Nincs jogosultságod a(z) \"{slug}\" oldal frissítéséhez", - - "error.section.files.max.plural": "Maximum {max} fájlt adhatsz hozzá a(z) \"{section}\" szekcióhoz", - "error.section.files.max.singular": "Nem adhatsz hozzá egynél több fájlt a(z) \"{section}\" szekcióhoz", - "error.section.files.min.plural": "A \"{section}\" szakasz legalább {min} fájlt igényel", - "error.section.files.min.singular": "A \"{section}\" szakasz legalább egy fájlt igényel", - - "error.section.pages.max.plural": "Maximum {max} oldalt adhatsz hozzá a(z) \"{section}\" szekcióhoz", - "error.section.pages.max.singular": "Nem adhatsz hozzá egynél több oldalt a(z) \"{section}\" szekcióhoz", - "error.section.pages.min.plural": "A \"{section}\" szakasz legalább {min} oldalt igényel", - "error.section.pages.min.singular": "A \"{section}\" szakasz legalább egy oldalt igényel", - - "error.section.notLoaded": "A(z) \"{name}\" szekció nem tölthető be", - "error.section.type.invalid": "A szekció típusa (\"{type}\") nem megfelelő", - - "error.site.changeTitle.empty": "A cím nem lehet üres", - "error.site.changeTitle.permission": "Nincs jogosultságod megváltoztatni az honlap címét", - "error.site.update.permission": "Nincs jogosultságod frissíteni a honlapot", - - "error.template.default.notFound": "Az alapértelmezett sablon nem létezik", - - "error.unexpected": "Váratlan hiba történt! További információért engedélyezd a hibakeresés módot: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Nincs jogosultságod megváltoztatni \"{name}\" felhasználó email-címét", - "error.user.changeLanguage.permission": "Nincs jogosultságod megváltoztatni \"{name}\" felhasználó nyelvi beállításait", - "error.user.changeName.permission": "Nincs jogosultságod megváltoztatni \"{name}\" felhasználó nevét", - "error.user.changePassword.permission": "Nincs jogosultságod megváltoztatni \"{name}\" felhasználó jelszavát", - "error.user.changeRole.lastAdmin": "Az egyedüli adminisztrátor szerepkörét nem lehet megváltoztatni", - "error.user.changeRole.permission": "Nincs jogosultságod megváltoztatni \"{name}\" felhasználó szerepkörét", - "error.user.changeRole.toAdmin": "Nincs jogosultságod előléptetni a felhasználót adminisztrátorrá", - "error.user.create.permission": "Nincs jogosultságod létrehozni ezt a felhasználót", - "error.user.delete": "A felhaszn\u00e1l\u00f3 nem t\u00f6r\u00f6lhet\u0151", - "error.user.delete.lastAdmin": "Nem t\u00f6r\u00f6lheted az egyetlen adminisztr\u00e1tort", - "error.user.delete.lastUser": "Nem törölheted az egyetlen felhasználót", - "error.user.delete.permission": "Nincs jogosults\u00e1god t\u00f6r\u00f6lni ezt a felhaszn\u00e1l\u00f3t", - "error.user.duplicate": "Már létezik felhasználó \"{email}\" email-címmel", - "error.user.email.invalid": "Kérlek adj meg egy valós email-címet", - "error.user.language.invalid": "Kérlek add meg a megfelelő nyelvi beállítást", - "error.user.notFound": "A felhaszn\u00e1l\u00f3 nem tal\u00e1lhat\u00f3", - "error.user.password.invalid": "Kérlek adj meg egy megfelelő jelszót. A jelszónak legalább 8 karakter hosszúságúnak kell lennie.", - "error.user.password.notSame": "K\u00e9rlek er\u0151s\u00edtsd meg a jelsz\u00f3t", - "error.user.password.undefined": "A felhasználónak nincs jelszó megadva", - "error.user.password.wrong": "Hibás jelszó", - "error.user.role.invalid": "Kérlek adj meg egy megfelelő szerepkört", - "error.user.undefined": "A felhasználó nem található", - "error.user.update.permission": "Nincs jogosultságod frissíteni \"{name}\" felhasználó adatait", - - "error.validation.accepted": "Kérlek erősítsd meg", - "error.validation.alpha": "Kérlek csak kis betűket használj (a-z)", - "error.validation.alphanum": "Kérlek csak kis betűket és számjegyeket használj (a-z, 0-9)", - "error.validation.between": "Kérlek egy \"{min}\" és \"{max}\" közötti értéket adj meg", - "error.validation.boolean": "Kérlek erősítsd meg vagy vesd el", - "error.validation.contains": "Kérlek olyan értéket adj meg, amely tartalmazza ezt: \"{needle}\"", - "error.validation.date": "Kérlek megfelelő dátumot adj meg", - "error.validation.date.after": "Kérlek olyan dátumot adj meg, amely későbbi ennél: {date}", - "error.validation.date.before": "Kérlek olyan dátumot adj meg, amely korábbi ennél: {date}", - "error.validation.date.between": "Kérlek {min} és {max} közötti dátumot adj meg", - "error.validation.denied": "Kérlek vesd el", - "error.validation.different": "Az érték nem lehet \"{other}\"", - "error.validation.email": "Kérlek adj meg egy valós email-címet", - "error.validation.endswith": "Az értéknek erre kell végződnie: \"{end}\"", - "error.validation.filename": "Kérlek megfelelő fájlnevet adj meg", - "error.validation.in": "Kérlek adj meg egyet az alábbiak közül: ({in})", - "error.validation.integer": "Kérlek valós számot adj meg", - "error.validation.ip": "Kérlek megfelelő IP-címet adj meg", - "error.validation.less": "A megadott érték kevesebb legyen, mint {max}", - "error.validation.match": "A megadott érték nem felel meg az elvárt struktúrának", - "error.validation.max": "A megadott érték egyenlő vagy kevesebb legyen, mint {max}", - "error.validation.maxlength": "Kérlek rövidebb értéket adj meg (legfeljebb {max} karakter)", - "error.validation.maxwords": "Kérlek ide legfeljebb {max} szót írj", - "error.validation.min": "A megadott érték egyenlő vagy nagyobb legyen, mint {min}", - "error.validation.minlength": "Kérlek hosszabb értéket adj meg (legalább {min} karakter)", - "error.validation.minwords": "Kérlek ide legalább {min} szót írj", - "error.validation.more": "A megadott érték legyen nagyobb, mint {min} ", - "error.validation.notcontains": "Kérlek olyan értéket adj meg, amely nem tartalmazza ezt: \"{needle}\" ", - "error.validation.notin": "Kérlek egyiket se használd az alábbiak közül: ({notIn})", - "error.validation.option": "Kérlek válassz egy megfelelő opciót", - "error.validation.num": "Kérlek adj meg egy megfelelő számot", - "error.validation.required": "Kérlek írj be valamit", - "error.validation.same": "Kérlek írd be: \"{other}\"", - "error.validation.size": "Az értéknek az alábbi méretűnek kell lennie: \"{size}\"", - "error.validation.startswith": "Az értéknek ezzel kell kezdődnie: \"{start}\"", - "error.validation.time": "Kérlek megfelelő időt adj meg", - "error.validation.time.after": "Kérlek olyan időpontot adj meg, amely későbbi ennél: {time}", - "error.validation.time.before": "Kérlek olyan időpontot adj meg, amely korábbi ennél: {time}", - "error.validation.time.between": "Kérlek {min} és {max} közötti időpontot adj meg", - "error.validation.url": "Kérlek megfelelő URL-t adj meg", - - "expand": "Kinyitás", - "expand.all": "Összes kinyitása", - - "field.required": "Kötelező mező", - "field.blocks.changeType": "Típus megváltoztatása", - "field.blocks.code.name": "Kód", - "field.blocks.code.language": "Nyelv", - "field.blocks.code.placeholder": "A megjelenítendő kód …", - "field.blocks.delete.confirm": "Tényleg törölni szeretnéd ezt a blokkot?", - "field.blocks.delete.confirm.all": "Tényleg minden blokkot törölni szeretnél?", - "field.blocks.delete.confirm.selected": "Tényleg törölni szeretnéd a kijelölt blokkokat?", - "field.blocks.empty": "Még nincsenek blokkok", - "field.blocks.fieldsets.label": "Kérlek válassz blokktípust …", - "field.blocks.fieldsets.paste": "Blokk beszúrásához a vágólapról használd a {{ shortcut }} billentyűkombinációt", - "field.blocks.gallery.name": "Galéria", - "field.blocks.gallery.images.empty": "Még nincsenek képek", - "field.blocks.gallery.images.label": "Képek", - "field.blocks.heading.level": "Szint", - "field.blocks.heading.name": "Címsor", - "field.blocks.heading.text": "Szöveg", - "field.blocks.heading.placeholder": "Címsor …", - "field.blocks.image.alt": "Alternatív szöveg", - "field.blocks.image.caption": "Képaláírás", - "field.blocks.image.crop": "Körülvágás", - "field.blocks.image.link": "Link", - "field.blocks.image.location": "A kép helye", - "field.blocks.image.name": "Kép", - "field.blocks.image.placeholder": "Kép kiválasztása", - "field.blocks.image.ratio": "Képarány", - "field.blocks.image.url": "Kép URL-je", - "field.blocks.line.name": "Vonal", - "field.blocks.list.name": "Lista", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Szöveg", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Idézet", - "field.blocks.quote.text.label": "Szöveg", - "field.blocks.quote.text.placeholder": "Idézet szövege …", - "field.blocks.quote.citation.label": "Idézet szerzője", - "field.blocks.quote.citation.placeholder": "Szerző …", - "field.blocks.text.name": "Szöveg", - "field.blocks.text.placeholder": "Szöveg …", - "field.blocks.video.caption": "Képaláírás", - "field.blocks.video.name": "Videó", - "field.blocks.video.placeholder": "Videó URL-jének megadása", - "field.blocks.video.url.label": "Videó URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Nincs fálj kiválasztva", - - "field.layout.delete": "Elrendezés törlése", - "field.layout.delete.confirm": "Tényleg törölni szeretnéd ezt az elrendezést?", - "field.layout.empty": "Még nincsenek sorok", - "field.layout.select": "Válassz elrendezést", - - "field.pages.empty": "Nincs oldal kiválasztva", - "field.structure.delete.confirm": "Biztos t\u00f6r\u00f6lni szeretn\u00e9d ezt a bejegyz\u00e9st?", - "field.structure.empty": "Nincs m\u00e9g bejegyz\u00e9s", - "field.users.empty": "Nincs felhasználó kiválasztva", - - "file.blueprint": "Ehhez a fájlhoz még nem tartozik oldalsablon. Itt hozhatod létre: /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Biztos törölni akarod ezt a fájlt:
{filename}?", - "file.sort": "Sorrend megváltoztatása", - - "files": "Fájlok", - "files.empty": "Még nincsenek fájlok", - - "hide": "Elrejtés", - "hour": "Óra", - "import": "Importálás", - "info": "Info", - "insert": "Beilleszt", - "insert.after": "Beszúrás mögé", - "insert.before": "Beszúrás elé", - "install": "Telepítés", - - "installation": "Telepítés", - "installation.completed": "A panel sikeresen telepítve", - "installation.disabled": "A panel telepítője alapértelmezés szerint le van tiltva a nyilvános szervereken. Kérlek, futtassd a telepítőt egy helyi gépen vagy engedélyezze a panel.install opcióval.", - "installation.issues.accounts": "A /site/accounts mappa nem létezik, vagy nem írható", - "installation.issues.content": "A /content mappa nem létezik vagy nem írható", - "installation.issues.curl": "A CURL bővítmény engedélyezése szükséges", - "installation.issues.headline": "A panel telepítése sikertelen", - "installation.issues.mbstring": "Az MB String bővítmény engedélyezése szükséges", - "installation.issues.media": "A /media mappa nem létezik vagy nem írható", - "installation.issues.php": "Bizonyosodj meg róla, hogy az általad használt PHP-verzió PHP 7+", - "installation.issues.server": "A Kirby az alábbi szervereken futtatható: Apache, Nginx vagy Caddy", - "installation.issues.sessions": "A /site/sessions könyvtár nem létezik vagy nem írható", - - "language": "Nyelv", - "language.code": "Kód", - "language.convert": "Alapértelmezettnek jelölés", - "language.convert.confirm": "

Tényleg az alaőértelmezett nyelvre szeretnéd konvertálni ezt: {name}? Ez a művelet nem vonható vissza.

Ha{name} olyat is tartalmaz, amelynek nincs megfelelő fordítása, a honlapod egyes részei az új alapértelmezett nyelv hiányosságai miatt üresek maradhatnak.

", - "language.create": "Új nyelv hozzáadása", - "language.delete.confirm": "Tényleg törölni szeretnéd a(z) {name} nyelvet, annak minden fordításával együtt? Ez a művelet nem vonható vissza!", - "language.deleted": "A nyelv törölve lett", - "language.direction": "Olvasási irány", - "language.direction.ltr": "Balról jobbra", - "language.direction.rtl": "Jobbról balra", - "language.locale": "PHP locale sztring", - "language.locale.warning": "Egyedi nyelvi készletet használsz. Kérlek módosítsd a nyelvhez tartozó fájlt az alábbi mappában: /site/languages", - "language.name": "Név", - "language.updated": "A nyelv frissítve lett", - - "languages": "Nyelvek", - "languages.default": "Alapértelmezett nyelv", - "languages.empty": "Nincsnek még nyelvek", - "languages.secondary": "Másodlagos nyelvek", - "languages.secondary.empty": "Nincsnek még másodlagos nyelvek", - - "license": "Kirby licenc", - "license.buy": "Licenc vásárlása", - "license.register": "Regisztráció", - "license.manage": "Manage your licenses", - "license.register.help": "A vásárlás után emailben küldjük el a licenc-kódot. Regisztrációhoz másold ide a kapott kódot.", - "license.register.label": "Kérlek írd be a licenc-kódot", - "license.register.success": "Köszönjük, hogy támogatod a Kirby-t", - "license.unregistered": "Jelenleg a Kirby nem regisztrált próbaverzióját használod", - "license.unregistered.label": "Unregistered", - - "link": "Link", - "link.text": "Link szövege", - - "loading": "Betöltés", - - "lock.unsaved": "Nem mentett változások", - "lock.unsaved.empty": "Nincsenek nem mentett változások", - "lock.isLocked": "Nem mentett {email} változások", - "lock.file.isLocked": "A fájlt jelenleg {email} szerkeszti és nem módosítható.", - "lock.page.isLocked": "Az oldalt jelenleg {email} szerkeszti és nem módosítható.", - "lock.unlock": "Kinyit", - "lock.isUnlocked": "A nem mentett módosításokat egy másik felhasználó felülírta. A módosításokat manuálisan egyesítheted.", - - "login": "Bejelentkezés", - "login.code.label.login": "Bejelentkezéshez szükséges kód", - "login.code.label.password-reset": "Jelszóvisszaállításhoz szükséges kód", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "Amennyiben az email-címed létezik a rendszerben, a kódot oda küldjük el.", - "login.email.login.body": "Helló {user.nameOrEmail},\n\nNemrégiben bejelentkezési kódot igényeltél a(z) {site} Paneljéhez.\nAz alábbi kód {timeout} percig lesz érvényes:\n\n{code}\n\nHa nem te igényelted a kódot, kérlek hagyd figyelmen kívül ezt az emailt, kérdések esetén pedig vedd fel a kapcsolatot az oldal Adminisztrátorával.\nBiztonsági okokból kérjük NE továbbítsd ezt az emailt.", - "login.email.login.subject": "Bejelentkezési kódod", - "login.email.password-reset.body": "Helló {user.nameOrEmail},\n\nNemrégiben jelszóvisszaállítási kódot igényeltél a(z) {site} Paneljéhez.\nAz alábbi jelszóvisszaállítási kód {timeout} percig lesz érvényes:\n\n{code}\n\nHa nem te igényelted a jelszóvisszaállítási kódot, kérlek hagyd figyelmen kívül ezt az emailt, kérdések esetén pedig vedd fel a kapcsolatot az oldal Adminisztrátorával.\nBiztonsági okokból kérjük NE továbbítsd ezt az emailt.", - "login.email.password-reset.subject": "Jelszóvisszaállítási kódod", - "login.remember": "Maradjak bejelentkezve", - "login.reset": "Jelszó visszaállítása", - "login.toggleText.code.email": "Bejelentkezés emaillel", - "login.toggleText.code.email-password": "Bejelentkezés jelszóval", - "login.toggleText.password-reset.email": "Elfelejtetted a jelszavad?", - "login.toggleText.password-reset.email-password": "← Vissza a bejelentkezéshez", - - "logout": "Kijelentkezés", - - "menu": "Menü", - "meridiem": "DE/DU", - "mime": "Média-típus", - "minutes": "Perc", - - "month": "Hónap", - "months.april": "\u00e1prilis", - "months.august": "augusztus", - "months.december": "december", - "months.february": "február", - "months.january": "janu\u00e1r", - "months.july": "j\u00falius", - "months.june": "j\u00fanius", - "months.march": "m\u00e1rcius", - "months.may": "m\u00e1jus", - "months.november": "november", - "months.october": "okt\u00f3ber", - "months.september": "szeptember", - - "more": "Több", - "name": "Név", - "next": "Következő", - "no": "nem", - "off": "ki", - "on": "be", - "open": "Megnyitás", - "open.newWindow": "Megnyitás új ablakban", - "options": "Beállítások", - "options.none": "Nincsnek beállítások", - - "orientation": "Tájolás", - "orientation.landscape": "Fekvő", - "orientation.portrait": "Álló", - "orientation.square": "Négyzetes", - - "page.blueprint": "Ehhez az oldalhoz még nem tartozik oldalsablon. Itt hozhatod létre: /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "URL v\u00e1ltoztat\u00e1sa", - "page.changeSlug.fromTitle": "L\u00e9trehoz\u00e1s c\u00edmb\u0151l", - "page.changeStatus": "Állapot módosítása", - "page.changeStatus.position": "Kérlek válaszd ki a pozíciót", - "page.changeStatus.select": "Új állapot kiválasztása", - "page.changeTemplate": "Sablon módosítása", - "page.delete.confirm": "Biztos vagy benne, hogy törlöd az alábbi oldalt: {title}?", - "page.delete.confirm.subpages": "Ehhez az oldalhoz aloldalak tartoznak.
Az oldal törlésekor a hozzá tartozó aloldalak is törlődnek.", - "page.delete.confirm.title": "Megerősítéshez add meg az oldal címét", - "page.draft.create": "Piszkozat létrehozása", - "page.duplicate.appendix": "Másol", - "page.duplicate.files": "Fájlok másolása", - "page.duplicate.pages": "Oldalak másolása", - "page.sort": "Sorrend megváltoztatása", - "page.status": "Állapot", - "page.status.draft": "Piszkozat", - "page.status.draft.description": "Ez az oldal jelenleg piszkozat és csak bejelentkezett szerkesztők számára, vagy egy titkos linken keresztül érhető el", - "page.status.listed": "Publikus", - "page.status.listed.description": "Az oldal mindenki számára elérhető", - "page.status.unlisted": "Nem listázott", - "page.status.unlisted.description": "Az oldal csak URL-en keresztül érhető el", - - "pages": "Oldalak", - "pages.empty": "Nincs még bejegyzés", - "pages.status.draft": "Piszkozatok", - "pages.status.listed": "Publikálva", - "pages.status.unlisted": "Nem listázott", - - "pagination.page": "Oldal", - - "password": "Jelsz\u00f3", - "paste": "Beillesztés", - "paste.after": "Beillesztés utána", - "pixel": "Pixel", - "plugins": "Pluginek", - "prev": "Előző", - "preview": "Előnézet", - "remove": "Eltávolítás", - "rename": "Átnevezés", - "replace": "Cser\u00e9l", - "retry": "Próbáld újra", - "revert": "Visszavon\u00e1s", - "revert.confirm": "Tényleg törölni szeretnél minden nem mentett változtatást?", - - "role": "Szerepkör", - "role.admin.description": "Az adminisztrátornak minden joga van", - "role.admin.title": "Admin", - "role.all": "Összes", - "role.empty": "Nincsenek felhasználók ilyen szerepkörrel", - "role.description.placeholder": "Nincs leírás", - "role.nobody.description": "Ez a visszatérő szabály a nem rendelkező jogosultsághoz", - "role.nobody.title": "Senki", - - "save": "Ment\u00e9s", - "search": "Keresés", - "search.min": "A kereséshez írj be minimum {min} karaktert", - "search.all": "Összes mutatása", - "search.results.none": "Nincs találat", - - "section.required": "Ez a szakasz kötelező", - - "security": "Security", - "select": "Kiválasztás", - "server": "Szerver", - "settings": "Beállítások", - "show": "Mutat", - "site.blueprint": "Ehhez a weblaphoz még nem tartozik oldalsablon. Itt hozhatod létre: /site/blueprints/site.yml", - "size": "Méret", - "slug": "URL n\u00e9v", - "sort": "Rendezés", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Cím", - "template": "Sablon", - "today": "Ma", - - "toolbar.button.code": "Kód", - "toolbar.button.bold": "F\u00e9lk\u00f6v\u00e9r sz\u00f6veg", - "toolbar.button.email": "Email", - "toolbar.button.headings": "Címsor", - "toolbar.button.heading.1": "Címsor 1", - "toolbar.button.heading.2": "Címsor 2", - "toolbar.button.heading.3": "Címsor 3", - "toolbar.button.heading.4": "Címsor 4", - "toolbar.button.heading.5": "Címsor 5", - "toolbar.button.heading.6": "Címsor 6", - "toolbar.button.italic": "Dőlt szöveg", - "toolbar.button.file": "Fájl", - "toolbar.button.file.select": "Válassz egy fájlt", - "toolbar.button.file.upload": "Fájl feltöltése", - "toolbar.button.link": "Link", - "toolbar.button.paragraph": "Bekezdés", - "toolbar.button.strike": "Áthúzott szöveg", - "toolbar.button.ol": "Rendezett lista", - "toolbar.button.underline": "Aláhúzott szöveg", - "toolbar.button.ul": "Rendezetlen lista", - - "translation.author": "A Kirby csapata", - "translation.direction": "ltr", - "translation.name": "Magyar", - "translation.locale": "hu_HU", - - "upload": "Feltöltés", - "upload.error.cantMove": "A feltöltött fájlt nem sikerült áthelyezni", - "upload.error.cantWrite": "Hiba a fájl lemezre írása közben", - "upload.error.default": "A fájlt nem sikerült feltölteni", - "upload.error.extension": "A fájlfeltöltés egy kiterjesztés miatt megszakadt", - "upload.error.formSize": "A feltöltendő fájl mérete nagyobb, mint az űrlap MAX_FILE_SIZE szabályában beállított érték", - "upload.error.iniPostSize": "A feltöltendő fájl mérete nagyobb, mint a php.ini post_max_size szabályában beállított érték", - "upload.error.iniSize": "A feltöltendő fájl mérete nagyobb, mint a php.ini upload_max_filesize szabályában beállított érték", - "upload.error.noFile": "Nem lett fájl feltöltve", - "upload.error.noFiles": "Nem lettek fájlok feltöltve", - "upload.error.partial": "A fájl feltöltése csak részben sikerült", - "upload.error.tmpDir": "Hiányzik egy átmeneti mappa", - "upload.errors": "Hiba", - "upload.progress": "Feltöltés...", - - "url": "Url", - "url.placeholder": "https://pelda.hu", - - "user": "Felhasználó", - "user.blueprint": "További szakaszokat és mezőket adhatsz meg ehhez a felhasználói szerepkörhöz itt: /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Email módosítása", - "user.changeLanguage": "Nyelv módosítása", - "user.changeName": "Felhasználó átnevezése", - "user.changePassword": "Jelszó módosítása", - "user.changePassword.new": "Új jelszó", - "user.changePassword.new.confirm": "Az új jelszó megerősítése", - "user.changeRole": "Szerepkör módosítása", - "user.changeRole.select": "Új szerepkör kiválasztása", - "user.create": "Új felhasználó hozzáadása", - "user.delete": "Felhasználó törlése", - "user.delete.confirm": "Biztos törlöd ezt a felhasználót:
{email}?", - - "users": "Felhasználók", - - "version": "Kirby verzi\u00f3", - - "view.account": "Fi\u00f3kod", - "view.installation": "Telep\u00edt\u00e9s", - "view.languages": "Nyelvek", - "view.resetPassword": "Jelszó visszaállítása", - "view.site": "Weboldal", - "view.system": "Rendszer", - "view.users": "Felhaszn\u00e1l\u00f3k", - - "welcome": "Üdvözlünk", - "year": "Év", - "yes": "igen" + "account.changeName": "Név megváltoztatása", + "account.delete": "Fiók törlése", + "account.delete.confirm": "Tényleg törölni szeretnéd a fiókodat? Azonnal kijelentkeztetünk és ez a folyamat visszavonhatatlan.", + + "add": "Hozz\u00e1ad", + "author": "Szerző", + "avatar": "Profilkép", + "back": "Vissza", + "cancel": "M\u00e9gsem", + "change": "M\u00f3dos\u00edt\u00e1s", + "close": "Bez\u00e1r", + "confirm": "Mentés", + "collapse": "Bezárás", + "collapse.all": "Összes bezárása", + "copy": "Másol", + "copy.all": "Összes másolása", + "create": "Létrehoz", + + "date": "Dátum", + "date.select": "Dátum kiválasztása", + + "day": "Nap", + "days.fri": "p\u00e9", + "days.mon": "h\u00e9", + "days.sat": "szo", + "days.sun": "va", + "days.thu": "cs\u00fc", + "days.tue": "ke", + "days.wed": "sze", + + "debugging": "Hibakeresés", + + "delete": "T\u00f6rl\u00e9s", + "delete.all": "Összes törlése", + + "dialog.files.empty": "Nincsenek fájlok kiválasztva", + "dialog.pages.empty": "Nincsenek oldalak kiválasztva", + "dialog.users.empty": "Nincsenek felhasználók kiválasztva", + + "dimensions": "Méretek", + "disabled": "Inaktív", + "discard": "Visszavon\u00e1s", + "download": "Letöltés", + "duplicate": "Másolat", + + "edit": "Aloldal szerkeszt\u00e9se", + + "email": "Email", + "email.placeholder": "mail@pelda.hu", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Környezet", + + "error.access.code": "Érvénytelen kód", + "error.access.login": "Érvénytelen bejelentkezés", + "error.access.panel": "Nincs jogosultságod megnyitni a panelt", + "error.access.view": "Nincs hozzáférésed a panel ezen részéhez", + + "error.avatar.create.fail": "A profilkép feltöltése nem sikerült", + "error.avatar.delete.fail": "A profilkép nem törölhető", + "error.avatar.dimensions.invalid": "A profilkép maximális szélessége és magassága 3000 pixel lehet", + "error.avatar.mime.forbidden": "A profilkép formátuma csak JPEG vagy PNG lehet", + + "error.blueprint.notFound": "A \"{name}\" oldalsablon nem tölthető be", + + "error.blocks.max.plural": "Legfeljebb {max} blokk adható hozzá", + "error.blocks.max.singular": "Csak egyetlen blokk adható hozzá", + "error.blocks.min.plural": "Legalább {min} blokkot hozzá kell adnod", + "error.blocks.min.singular": "Legalább egy blokkot hozzá kell adnod", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "A \"{name}\" email-beállítás nem található", + + "error.field.converter.invalid": "Érvénytelen konverter: \"{converter}\"", + + "error.file.changeName.empty": "A név nem lehet üres", + "error.file.changeName.permission": "Nincs jogosultságod megváltoztatni a \"{filename}\" fájl nevét", + "error.file.duplicate": "Már létezik \"{filename}\" nevű fájl", + "error.file.extension.forbidden": "Tiltott kiterjeszt\u00e9s\u0171 f\u00e1jl", + "error.file.extension.invalid": "Érvénytelen kiterjesztés: {extension}", + "error.file.extension.missing": "Kiterjeszt\u00e9s n\u00e9lk\u00fcli f\u00e1jl nem t\u00f6lthet\u0151 fel", + "error.file.maxheight": "A kép nem lehet magasabb {height} pixelnél", + "error.file.maxsize": "A fájl túl nagy", + "error.file.maxwidth": "A kép nem lehet szélesebb {width} pixelnél", + "error.file.mime.differs": "A feltöltött fájlnak azonos \"{mime}\" típusúnak kell lennie", + "error.file.mime.forbidden": "A \"{mime}\" típusú médiafájlok nem engedélyezettek", + "error.file.mime.invalid": "Érvénytelen mime-típus: {mime}", + "error.file.mime.missing": "A \"{filename}\" fájl típusa nem állapítható meg", + "error.file.minheight": "A képnek legalább {height} pixel magasnak kell lennie", + "error.file.minsize": "A fájl túl kicsi", + "error.file.minwidth": "A képnek legalább {width} pixel szélesnek kell lennie", + "error.file.name.missing": "A fálj neve nem lehet üres", + "error.file.notFound": "A \"{filename}\" fájl nem található", + "error.file.orientation": "A képnek \"{orientation}\" tájolásúnak kell lennie", + "error.file.type.forbidden": "Nem tölthetsz fel \"{type}\" típusú fájlokat", + "error.file.type.invalid": "Érvénytelen fájltípus: {type}", + "error.file.undefined": "A f\u00e1jl nem tal\u00e1lhat\u00f3", + + "error.form.incomplete": "Kérlek javítsd ki az összes hibát az űrlapon", + "error.form.notSaved": "Az űrlap nem menthető", + + "error.language.code": "Kérlek, add meg a nyelv érvényes kódját", + "error.language.duplicate": "A nyelv már létezik", + "error.language.name": "Kérlek, add meg a nyelv érvényes nevét", + "error.language.notFound": "A nyelv nem található", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "Hibát találtunk a(z) {index} elrendezés beállításaiban", + + "error.license.format": "Kérlek, add meg az évényes lincensz kulcsot", + "error.license.email": "Kérlek adj meg egy valós email-címet", + "error.license.verification": "A licensz nem ellenőrizhető", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "A Panel jelenleg nem elérhető", + + "error.page.changeSlug.permission": "Nem változtathatod meg az URL-előtagot: \"{slug}\"", + "error.page.changeStatus.incomplete": "Az oldal hibákat tartalmaz és nem publikálható", + "error.page.changeStatus.permission": "Az oldal státusza nem változtatható meg", + "error.page.changeStatus.toDraft.invalid": "A(z) \"{slug}\" oldalt nem lehet piszkozattá alakítani", + "error.page.changeTemplate.invalid": "A \"{slug}\" oldal sablonját nem lehet megváltoztatni", + "error.page.changeTemplate.permission": "Nincs jogosultságod megváltoztatni a sablont ehhez: \"{slug}\"", + "error.page.changeTitle.empty": "A cím nem lehet üres", + "error.page.changeTitle.permission": "Nincs jogosultságod megváltoztatni a címet: \"{slug}\"", + "error.page.create.permission": "Nincs jogosultságod az oldal létrehozásához: \"{slug}\"", + "error.page.delete": "A(z) \"{slug}\" oldal nem törölhető", + "error.page.delete.confirm": "Megerősítéshez add meg az oldal címét", + "error.page.delete.hasChildren": "Az oldalnak vannak aloldalai és nem törölhető", + "error.page.delete.permission": "Nincs jogosultságod a(z) \"{slug}\" oldal törléséhez", + "error.page.draft.duplicate": "Van már egy másik oldal ezzel az URL-lel: \"{slug}\"", + "error.page.duplicate": "Van már egy másik oldal ezzel az URL-lel: \"{slug}\"", + "error.page.duplicate.permission": "Nincs engedélyed a(z) \"{slug}\" másolat keszítéséhez", + "error.page.notFound": "Az oldal nem tal\u00e1lhat\u00f3", + "error.page.num.invalid": "Kérlek megfelelő oldalszámozást adj meg. Negatív szám itt nem használható.", + "error.page.slug.invalid": "Kérlek érvényes URL-kiterjesztést adj meg", + "error.page.slug.maxlength": "Az URL maximum \"{length}\" karakter hosszúságú lehet", + "error.page.sort.permission": "A(z) \"{slug}\" oldal nem illeszthető a sorrendbe", + "error.page.status.invalid": "Kérlek add meg a megfelelő oldalstátuszt", + "error.page.undefined": "Az oldal nem tal\u00e1lhat\u00f3", + "error.page.update.permission": "Nincs jogosultságod a(z) \"{slug}\" oldal frissítéséhez", + + "error.section.files.max.plural": "Maximum {max} fájlt adhatsz hozzá a(z) \"{section}\" szekcióhoz", + "error.section.files.max.singular": "Nem adhatsz hozzá egynél több fájlt a(z) \"{section}\" szekcióhoz", + "error.section.files.min.plural": "A \"{section}\" szakasz legalább {min} fájlt igényel", + "error.section.files.min.singular": "A \"{section}\" szakasz legalább egy fájlt igényel", + + "error.section.pages.max.plural": "Maximum {max} oldalt adhatsz hozzá a(z) \"{section}\" szekcióhoz", + "error.section.pages.max.singular": "Nem adhatsz hozzá egynél több oldalt a(z) \"{section}\" szekcióhoz", + "error.section.pages.min.plural": "A \"{section}\" szakasz legalább {min} oldalt igényel", + "error.section.pages.min.singular": "A \"{section}\" szakasz legalább egy oldalt igényel", + + "error.section.notLoaded": "A(z) \"{name}\" szekció nem tölthető be", + "error.section.type.invalid": "A szekció típusa (\"{type}\") nem megfelelő", + + "error.site.changeTitle.empty": "A cím nem lehet üres", + "error.site.changeTitle.permission": "Nincs jogosultságod megváltoztatni az honlap címét", + "error.site.update.permission": "Nincs jogosultságod frissíteni a honlapot", + + "error.template.default.notFound": "Az alapértelmezett sablon nem létezik", + + "error.unexpected": "Váratlan hiba történt! További információért engedélyezd a hibakeresés módot: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Nincs jogosultságod megváltoztatni \"{name}\" felhasználó email-címét", + "error.user.changeLanguage.permission": "Nincs jogosultságod megváltoztatni \"{name}\" felhasználó nyelvi beállításait", + "error.user.changeName.permission": "Nincs jogosultságod megváltoztatni \"{name}\" felhasználó nevét", + "error.user.changePassword.permission": "Nincs jogosultságod megváltoztatni \"{name}\" felhasználó jelszavát", + "error.user.changeRole.lastAdmin": "Az egyedüli adminisztrátor szerepkörét nem lehet megváltoztatni", + "error.user.changeRole.permission": "Nincs jogosultságod megváltoztatni \"{name}\" felhasználó szerepkörét", + "error.user.changeRole.toAdmin": "Nincs jogosultságod előléptetni a felhasználót adminisztrátorrá", + "error.user.create.permission": "Nincs jogosultságod létrehozni ezt a felhasználót", + "error.user.delete": "A felhaszn\u00e1l\u00f3 nem t\u00f6r\u00f6lhet\u0151", + "error.user.delete.lastAdmin": "Nem t\u00f6r\u00f6lheted az egyetlen adminisztr\u00e1tort", + "error.user.delete.lastUser": "Nem törölheted az egyetlen felhasználót", + "error.user.delete.permission": "Nincs jogosults\u00e1god t\u00f6r\u00f6lni ezt a felhaszn\u00e1l\u00f3t", + "error.user.duplicate": "Már létezik felhasználó \"{email}\" email-címmel", + "error.user.email.invalid": "Kérlek adj meg egy valós email-címet", + "error.user.language.invalid": "Kérlek add meg a megfelelő nyelvi beállítást", + "error.user.notFound": "A felhaszn\u00e1l\u00f3 nem tal\u00e1lhat\u00f3", + "error.user.password.invalid": "Kérlek adj meg egy megfelelő jelszót. A jelszónak legalább 8 karakter hosszúságúnak kell lennie.", + "error.user.password.notSame": "K\u00e9rlek er\u0151s\u00edtsd meg a jelsz\u00f3t", + "error.user.password.undefined": "A felhasználónak nincs jelszó megadva", + "error.user.password.wrong": "Hibás jelszó", + "error.user.role.invalid": "Kérlek adj meg egy megfelelő szerepkört", + "error.user.undefined": "A felhasználó nem található", + "error.user.update.permission": "Nincs jogosultságod frissíteni \"{name}\" felhasználó adatait", + + "error.validation.accepted": "Kérlek erősítsd meg", + "error.validation.alpha": "Kérlek csak kis betűket használj (a-z)", + "error.validation.alphanum": "Kérlek csak kis betűket és számjegyeket használj (a-z, 0-9)", + "error.validation.between": "Kérlek egy \"{min}\" és \"{max}\" közötti értéket adj meg", + "error.validation.boolean": "Kérlek erősítsd meg vagy vesd el", + "error.validation.contains": "Kérlek olyan értéket adj meg, amely tartalmazza ezt: \"{needle}\"", + "error.validation.date": "Kérlek megfelelő dátumot adj meg", + "error.validation.date.after": "Kérlek olyan dátumot adj meg, amely későbbi ennél: {date}", + "error.validation.date.before": "Kérlek olyan dátumot adj meg, amely korábbi ennél: {date}", + "error.validation.date.between": "Kérlek {min} és {max} közötti dátumot adj meg", + "error.validation.denied": "Kérlek vesd el", + "error.validation.different": "Az érték nem lehet \"{other}\"", + "error.validation.email": "Kérlek adj meg egy valós email-címet", + "error.validation.endswith": "Az értéknek erre kell végződnie: \"{end}\"", + "error.validation.filename": "Kérlek megfelelő fájlnevet adj meg", + "error.validation.in": "Kérlek adj meg egyet az alábbiak közül: ({in})", + "error.validation.integer": "Kérlek valós számot adj meg", + "error.validation.ip": "Kérlek megfelelő IP-címet adj meg", + "error.validation.less": "A megadott érték kevesebb legyen, mint {max}", + "error.validation.match": "A megadott érték nem felel meg az elvárt struktúrának", + "error.validation.max": "A megadott érték egyenlő vagy kevesebb legyen, mint {max}", + "error.validation.maxlength": "Kérlek rövidebb értéket adj meg (legfeljebb {max} karakter)", + "error.validation.maxwords": "Kérlek ide legfeljebb {max} szót írj", + "error.validation.min": "A megadott érték egyenlő vagy nagyobb legyen, mint {min}", + "error.validation.minlength": "Kérlek hosszabb értéket adj meg (legalább {min} karakter)", + "error.validation.minwords": "Kérlek ide legalább {min} szót írj", + "error.validation.more": "A megadott érték legyen nagyobb, mint {min} ", + "error.validation.notcontains": "Kérlek olyan értéket adj meg, amely nem tartalmazza ezt: \"{needle}\" ", + "error.validation.notin": "Kérlek egyiket se használd az alábbiak közül: ({notIn})", + "error.validation.option": "Kérlek válassz egy megfelelő opciót", + "error.validation.num": "Kérlek adj meg egy megfelelő számot", + "error.validation.required": "Kérlek írj be valamit", + "error.validation.same": "Kérlek írd be: \"{other}\"", + "error.validation.size": "Az értéknek az alábbi méretűnek kell lennie: \"{size}\"", + "error.validation.startswith": "Az értéknek ezzel kell kezdődnie: \"{start}\"", + "error.validation.time": "Kérlek megfelelő időt adj meg", + "error.validation.time.after": "Kérlek olyan időpontot adj meg, amely későbbi ennél: {time}", + "error.validation.time.before": "Kérlek olyan időpontot adj meg, amely korábbi ennél: {time}", + "error.validation.time.between": "Kérlek {min} és {max} közötti időpontot adj meg", + "error.validation.url": "Kérlek megfelelő URL-t adj meg", + + "expand": "Kinyitás", + "expand.all": "Összes kinyitása", + + "field.required": "Kötelező mező", + "field.blocks.changeType": "Típus megváltoztatása", + "field.blocks.code.name": "Kód", + "field.blocks.code.language": "Nyelv", + "field.blocks.code.placeholder": "A megjelenítendő kód …", + "field.blocks.delete.confirm": "Tényleg törölni szeretnéd ezt a blokkot?", + "field.blocks.delete.confirm.all": "Tényleg minden blokkot törölni szeretnél?", + "field.blocks.delete.confirm.selected": "Tényleg törölni szeretnéd a kijelölt blokkokat?", + "field.blocks.empty": "Még nincsenek blokkok", + "field.blocks.fieldsets.label": "Kérlek válassz blokktípust …", + "field.blocks.fieldsets.paste": "Blokk beszúrásához a vágólapról használd a {{ shortcut }} billentyűkombinációt", + "field.blocks.gallery.name": "Galéria", + "field.blocks.gallery.images.empty": "Még nincsenek képek", + "field.blocks.gallery.images.label": "Képek", + "field.blocks.heading.level": "Szint", + "field.blocks.heading.name": "Címsor", + "field.blocks.heading.text": "Szöveg", + "field.blocks.heading.placeholder": "Címsor …", + "field.blocks.image.alt": "Alternatív szöveg", + "field.blocks.image.caption": "Képaláírás", + "field.blocks.image.crop": "Körülvágás", + "field.blocks.image.link": "Link", + "field.blocks.image.location": "A kép helye", + "field.blocks.image.name": "Kép", + "field.blocks.image.placeholder": "Kép kiválasztása", + "field.blocks.image.ratio": "Képarány", + "field.blocks.image.url": "Kép URL-je", + "field.blocks.line.name": "Vonal", + "field.blocks.list.name": "Lista", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Szöveg", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Idézet", + "field.blocks.quote.text.label": "Szöveg", + "field.blocks.quote.text.placeholder": "Idézet szövege …", + "field.blocks.quote.citation.label": "Idézet szerzője", + "field.blocks.quote.citation.placeholder": "Szerző …", + "field.blocks.text.name": "Szöveg", + "field.blocks.text.placeholder": "Szöveg …", + "field.blocks.video.caption": "Képaláírás", + "field.blocks.video.name": "Videó", + "field.blocks.video.placeholder": "Videó URL-jének megadása", + "field.blocks.video.url.label": "Videó URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Nincs fálj kiválasztva", + + "field.layout.delete": "Elrendezés törlése", + "field.layout.delete.confirm": "Tényleg törölni szeretnéd ezt az elrendezést?", + "field.layout.empty": "Még nincsenek sorok", + "field.layout.select": "Válassz elrendezést", + + "field.object.empty": "No information yet", + + "field.pages.empty": "Nincs oldal kiválasztva", + + "field.structure.delete.confirm": "Biztos t\u00f6r\u00f6lni szeretn\u00e9d ezt a bejegyz\u00e9st?", + "field.structure.empty": "Nincs m\u00e9g bejegyz\u00e9s", + + "field.users.empty": "Nincs felhasználó kiválasztva", + + "file.blueprint": "Ehhez a fájlhoz még nem tartozik oldalsablon. Itt hozhatod létre: /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Biztos törölni akarod ezt a fájlt:
{filename}?", + "file.sort": "Sorrend megváltoztatása", + + "files": "Fájlok", + "files.empty": "Még nincsenek fájlok", + + "hide": "Elrejtés", + "hour": "Óra", + "import": "Importálás", + "info": "Info", + "insert": "Beilleszt", + "insert.after": "Beszúrás mögé", + "insert.before": "Beszúrás elé", + "install": "Telepítés", + + "installation": "Telepítés", + "installation.completed": "A panel sikeresen telepítve", + "installation.disabled": "A panel telepítője alapértelmezés szerint le van tiltva a nyilvános szervereken. Kérlek, futtassd a telepítőt egy helyi gépen vagy engedélyezze a panel.install opcióval.", + "installation.issues.accounts": "A /site/accounts mappa nem létezik, vagy nem írható", + "installation.issues.content": "A /content mappa nem létezik vagy nem írható", + "installation.issues.curl": "A CURL bővítmény engedélyezése szükséges", + "installation.issues.headline": "A panel telepítése sikertelen", + "installation.issues.mbstring": "Az MB String bővítmény engedélyezése szükséges", + "installation.issues.media": "A /media mappa nem létezik vagy nem írható", + "installation.issues.php": "Bizonyosodj meg róla, hogy az általad használt PHP-verzió PHP 7+", + "installation.issues.server": "A Kirby az alábbi szervereken futtatható: Apache, Nginx vagy Caddy", + "installation.issues.sessions": "A /site/sessions könyvtár nem létezik vagy nem írható", + + "language": "Nyelv", + "language.code": "Kód", + "language.convert": "Alapértelmezettnek jelölés", + "language.convert.confirm": "

Tényleg az alaőértelmezett nyelvre szeretnéd konvertálni ezt: {name}? Ez a művelet nem vonható vissza.

Ha{name} olyat is tartalmaz, amelynek nincs megfelelő fordítása, a honlapod egyes részei az új alapértelmezett nyelv hiányosságai miatt üresek maradhatnak.

", + "language.create": "Új nyelv hozzáadása", + "language.delete.confirm": "Tényleg törölni szeretnéd a(z) {name} nyelvet, annak minden fordításával együtt? Ez a művelet nem vonható vissza!", + "language.deleted": "A nyelv törölve lett", + "language.direction": "Olvasási irány", + "language.direction.ltr": "Balról jobbra", + "language.direction.rtl": "Jobbról balra", + "language.locale": "PHP locale sztring", + "language.locale.warning": "Egyedi nyelvi készletet használsz. Kérlek módosítsd a nyelvhez tartozó fájlt az alábbi mappában: /site/languages", + "language.name": "Név", + "language.updated": "A nyelv frissítve lett", + + "languages": "Nyelvek", + "languages.default": "Alapértelmezett nyelv", + "languages.empty": "Nincsnek még nyelvek", + "languages.secondary": "Másodlagos nyelvek", + "languages.secondary.empty": "Nincsnek még másodlagos nyelvek", + + "license": "Kirby licenc", + "license.buy": "Licenc vásárlása", + "license.register": "Regisztráció", + "license.manage": "Manage your licenses", + "license.register.help": "A vásárlás után emailben küldjük el a licenc-kódot. Regisztrációhoz másold ide a kapott kódot.", + "license.register.label": "Kérlek írd be a licenc-kódot", + "license.register.success": "Köszönjük, hogy támogatod a Kirby-t", + "license.unregistered": "Jelenleg a Kirby nem regisztrált próbaverzióját használod", + "license.unregistered.label": "Unregistered", + + "link": "Link", + "link.text": "Link szövege", + + "loading": "Betöltés", + + "lock.unsaved": "Nem mentett változások", + "lock.unsaved.empty": "Nincsenek nem mentett változások", + "lock.isLocked": "Nem mentett {email} változások", + "lock.file.isLocked": "A fájlt jelenleg {email} szerkeszti és nem módosítható.", + "lock.page.isLocked": "Az oldalt jelenleg {email} szerkeszti és nem módosítható.", + "lock.unlock": "Kinyit", + "lock.isUnlocked": "A nem mentett módosításokat egy másik felhasználó felülírta. A módosításokat manuálisan egyesítheted.", + + "login": "Bejelentkezés", + "login.code.label.login": "Bejelentkezéshez szükséges kód", + "login.code.label.password-reset": "Jelszóvisszaállításhoz szükséges kód", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "Amennyiben az email-címed létezik a rendszerben, a kódot oda küldjük el.", + "login.email.login.body": "Helló {user.nameOrEmail},\n\nNemrégiben bejelentkezési kódot igényeltél a(z) {site} Paneljéhez.\nAz alábbi kód {timeout} percig lesz érvényes:\n\n{code}\n\nHa nem te igényelted a kódot, kérlek hagyd figyelmen kívül ezt az emailt, kérdések esetén pedig vedd fel a kapcsolatot az oldal Adminisztrátorával.\nBiztonsági okokból kérjük NE továbbítsd ezt az emailt.", + "login.email.login.subject": "Bejelentkezési kódod", + "login.email.password-reset.body": "Helló {user.nameOrEmail},\n\nNemrégiben jelszóvisszaállítási kódot igényeltél a(z) {site} Paneljéhez.\nAz alábbi jelszóvisszaállítási kód {timeout} percig lesz érvényes:\n\n{code}\n\nHa nem te igényelted a jelszóvisszaállítási kódot, kérlek hagyd figyelmen kívül ezt az emailt, kérdések esetén pedig vedd fel a kapcsolatot az oldal Adminisztrátorával.\nBiztonsági okokból kérjük NE továbbítsd ezt az emailt.", + "login.email.password-reset.subject": "Jelszóvisszaállítási kódod", + "login.remember": "Maradjak bejelentkezve", + "login.reset": "Jelszó visszaállítása", + "login.toggleText.code.email": "Bejelentkezés emaillel", + "login.toggleText.code.email-password": "Bejelentkezés jelszóval", + "login.toggleText.password-reset.email": "Elfelejtetted a jelszavad?", + "login.toggleText.password-reset.email-password": "← Vissza a bejelentkezéshez", + + "logout": "Kijelentkezés", + + "menu": "Menü", + "meridiem": "DE/DU", + "mime": "Média-típus", + "minutes": "Perc", + + "month": "Hónap", + "months.april": "\u00e1prilis", + "months.august": "augusztus", + "months.december": "december", + "months.february": "február", + "months.january": "janu\u00e1r", + "months.july": "j\u00falius", + "months.june": "j\u00fanius", + "months.march": "m\u00e1rcius", + "months.may": "m\u00e1jus", + "months.november": "november", + "months.october": "okt\u00f3ber", + "months.september": "szeptember", + + "more": "Több", + "name": "Név", + "next": "Következő", + "no": "nem", + "off": "ki", + "on": "be", + "open": "Megnyitás", + "open.newWindow": "Megnyitás új ablakban", + "options": "Beállítások", + "options.none": "Nincsnek beállítások", + + "orientation": "Tájolás", + "orientation.landscape": "Fekvő", + "orientation.portrait": "Álló", + "orientation.square": "Négyzetes", + + "page.blueprint": "Ehhez az oldalhoz még nem tartozik oldalsablon. Itt hozhatod létre: /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "URL v\u00e1ltoztat\u00e1sa", + "page.changeSlug.fromTitle": "L\u00e9trehoz\u00e1s c\u00edmb\u0151l", + "page.changeStatus": "Állapot módosítása", + "page.changeStatus.position": "Kérlek válaszd ki a pozíciót", + "page.changeStatus.select": "Új állapot kiválasztása", + "page.changeTemplate": "Sablon módosítása", + "page.delete.confirm": "Biztos vagy benne, hogy törlöd az alábbi oldalt: {title}?", + "page.delete.confirm.subpages": "Ehhez az oldalhoz aloldalak tartoznak.
Az oldal törlésekor a hozzá tartozó aloldalak is törlődnek.", + "page.delete.confirm.title": "Megerősítéshez add meg az oldal címét", + "page.draft.create": "Piszkozat létrehozása", + "page.duplicate.appendix": "Másol", + "page.duplicate.files": "Fájlok másolása", + "page.duplicate.pages": "Oldalak másolása", + "page.sort": "Sorrend megváltoztatása", + "page.status": "Állapot", + "page.status.draft": "Piszkozat", + "page.status.draft.description": "Ez az oldal jelenleg piszkozat és csak bejelentkezett szerkesztők számára, vagy egy titkos linken keresztül érhető el", + "page.status.listed": "Publikus", + "page.status.listed.description": "Az oldal mindenki számára elérhető", + "page.status.unlisted": "Nem listázott", + "page.status.unlisted.description": "Az oldal csak URL-en keresztül érhető el", + + "pages": "Oldalak", + "pages.empty": "Nincs még bejegyzés", + "pages.status.draft": "Piszkozatok", + "pages.status.listed": "Publikálva", + "pages.status.unlisted": "Nem listázott", + + "pagination.page": "Oldal", + + "password": "Jelsz\u00f3", + "paste": "Beillesztés", + "paste.after": "Beillesztés utána", + "pixel": "Pixel", + "plugin": "Plugin", + "plugins": "Pluginek", + "prev": "Előző", + "preview": "Előnézet", + "remove": "Eltávolítás", + "rename": "Átnevezés", + "replace": "Cser\u00e9l", + "retry": "Próbáld újra", + "revert": "Visszavon\u00e1s", + "revert.confirm": "Tényleg törölni szeretnél minden nem mentett változtatást?", + + "role": "Szerepkör", + "role.admin.description": "Az adminisztrátornak minden joga van", + "role.admin.title": "Admin", + "role.all": "Összes", + "role.empty": "Nincsenek felhasználók ilyen szerepkörrel", + "role.description.placeholder": "Nincs leírás", + "role.nobody.description": "Ez a visszatérő szabály a nem rendelkező jogosultsághoz", + "role.nobody.title": "Senki", + + "save": "Ment\u00e9s", + "search": "Keresés", + "search.min": "A kereséshez írj be minimum {min} karaktert", + "search.all": "Összes mutatása", + "search.results.none": "Nincs találat", + + "section.required": "Ez a szakasz kötelező", + + "security": "Security", + "select": "Kiválasztás", + "server": "Szerver", + "settings": "Beállítások", + "show": "Mutat", + "site.blueprint": "Ehhez a weblaphoz még nem tartozik oldalsablon. Itt hozhatod létre: /site/blueprints/site.yml", + "size": "Méret", + "slug": "URL n\u00e9v", + "sort": "Rendezés", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Cím", + "template": "Sablon", + "today": "Ma", + + "toolbar.button.code": "Kód", + "toolbar.button.bold": "F\u00e9lk\u00f6v\u00e9r sz\u00f6veg", + "toolbar.button.email": "Email", + "toolbar.button.headings": "Címsor", + "toolbar.button.heading.1": "Címsor 1", + "toolbar.button.heading.2": "Címsor 2", + "toolbar.button.heading.3": "Címsor 3", + "toolbar.button.heading.4": "Címsor 4", + "toolbar.button.heading.5": "Címsor 5", + "toolbar.button.heading.6": "Címsor 6", + "toolbar.button.italic": "Dőlt szöveg", + "toolbar.button.file": "Fájl", + "toolbar.button.file.select": "Válassz egy fájlt", + "toolbar.button.file.upload": "Fájl feltöltése", + "toolbar.button.link": "Link", + "toolbar.button.paragraph": "Bekezdés", + "toolbar.button.strike": "Áthúzott szöveg", + "toolbar.button.ol": "Rendezett lista", + "toolbar.button.underline": "Aláhúzott szöveg", + "toolbar.button.ul": "Rendezetlen lista", + + "translation.author": "A Kirby csapata", + "translation.direction": "ltr", + "translation.name": "Magyar", + "translation.locale": "hu_HU", + + "upload": "Feltöltés", + "upload.error.cantMove": "A feltöltött fájlt nem sikerült áthelyezni", + "upload.error.cantWrite": "Hiba a fájl lemezre írása közben", + "upload.error.default": "A fájlt nem sikerült feltölteni", + "upload.error.extension": "A fájlfeltöltés egy kiterjesztés miatt megszakadt", + "upload.error.formSize": "A feltöltendő fájl mérete nagyobb, mint az űrlap MAX_FILE_SIZE szabályában beállított érték", + "upload.error.iniPostSize": "A feltöltendő fájl mérete nagyobb, mint a php.ini post_max_size szabályában beállított érték", + "upload.error.iniSize": "A feltöltendő fájl mérete nagyobb, mint a php.ini upload_max_filesize szabályában beállított érték", + "upload.error.noFile": "Nem lett fájl feltöltve", + "upload.error.noFiles": "Nem lettek fájlok feltöltve", + "upload.error.partial": "A fájl feltöltése csak részben sikerült", + "upload.error.tmpDir": "Hiányzik egy átmeneti mappa", + "upload.errors": "Hiba", + "upload.progress": "Feltöltés...", + + "url": "Url", + "url.placeholder": "https://pelda.hu", + + "user": "Felhasználó", + "user.blueprint": "További szakaszokat és mezőket adhatsz meg ehhez a felhasználói szerepkörhöz itt: /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Email módosítása", + "user.changeLanguage": "Nyelv módosítása", + "user.changeName": "Felhasználó átnevezése", + "user.changePassword": "Jelszó módosítása", + "user.changePassword.new": "Új jelszó", + "user.changePassword.new.confirm": "Az új jelszó megerősítése", + "user.changeRole": "Szerepkör módosítása", + "user.changeRole.select": "Új szerepkör kiválasztása", + "user.create": "Új felhasználó hozzáadása", + "user.delete": "Felhasználó törlése", + "user.delete.confirm": "Biztos törlöd ezt a felhasználót:
{email}?", + + "users": "Felhasználók", + + "version": "Kirby verzi\u00f3", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "Fi\u00f3kod", + "view.installation": "Telep\u00edt\u00e9s", + "view.languages": "Nyelvek", + "view.resetPassword": "Jelszó visszaállítása", + "view.site": "Weboldal", + "view.system": "Rendszer", + "view.users": "Felhaszn\u00e1l\u00f3k", + + "welcome": "Üdvözlünk", + "year": "Év", + "yes": "igen" } diff --git a/kirby/i18n/translations/id.json b/kirby/i18n/translations/id.json index 596e92a..e04e0ea 100644 --- a/kirby/i18n/translations/id.json +++ b/kirby/i18n/translations/id.json @@ -1,573 +1,596 @@ { - "account.changeName": "Change your name", - "account.delete": "Delete your account", - "account.delete.confirm": "Do you really want to delete your account? You will be logged out immediately. Your account cannot be recovered.", - - "add": "Tambah", - "author": "Author", - "avatar": "Gambar profil", - "back": "Kembali", - "cancel": "Batal", - "change": "Ubah", - "close": "Tutup", - "confirm": "Oke", - "collapse": "Lipat", - "collapse.all": "Lipat Semua", - "copy": "Salin", - "copy.all": "Copy all", - "create": "Buat", - - "date": "Tanggal", - "date.select": "Pilih tanggal", - - "day": "Hari", - "days.fri": "Jum", - "days.mon": "Sen", - "days.sat": "Sab", - "days.sun": "Min", - "days.thu": "Kam", - "days.tue": "Sel", - "days.wed": "Rab", - - "debugging": "Debugging", - - "delete": "Hapus", - "delete.all": "Hapus semua", - - "dialog.files.empty": "Tidak ada berkas untuk dipilih", - "dialog.pages.empty": "Tidak ada halaman untuk dipilih", - "dialog.users.empty": "Tidak ada pengguna untuk dipilih", - - "dimensions": "Dimensi", - "disabled": "Dimatikan", - "discard": "Buang", - "download": "Unduh", - "duplicate": "Duplikasi", - - "edit": "Sunting", - - "email": "Surel", - "email.placeholder": "surel@contoh.com", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Environment", - - "error.access.code": "Kode tidak valid", - "error.access.login": "Upaya masuk tidak valid", - "error.access.panel": "Anda tidak diizinkan mengakses panel", - "error.access.view": "Anda tidak diizinkan mengakses bagian panel ini", - - "error.avatar.create.fail": "Gambar profil tidak dapat diunggah", - "error.avatar.delete.fail": "Gambar profil tidak dapat dihapus", - "error.avatar.dimensions.invalid": "Pastikan lebar dan tinggi gambar profil di bawah 3000 piksel", - "error.avatar.mime.forbidden": "Gambar profil harus berupa berkas JPEG atau PNG", - - "error.blueprint.notFound": "Cetak biru \"{name}\" tidak dapat dimuat", - - "error.blocks.max.plural": "Anda tidak boleh menambahkan lebih dari {max} blok", - "error.blocks.max.singular": "Anda tidak boleh menambahkan lebih dari satu blok", - "error.blocks.min.plural": "Anda setidaknya menambahkan {min} blok", - "error.blocks.min.singular": "Anda setidaknya menambahkan satu blok", - "error.blocks.validation": "Ada kesalahan di blok {index}", - - "error.email.preset.notFound": "Surel \"{name}\" tidak dapat ditemukan", - - "error.field.converter.invalid": "Konverter \"{converter}\" tidak valid", - - "error.file.changeName.empty": "Nama harus diisi", - "error.file.changeName.permission": "Anda tidak diizinkan mengubah nama berkas \"{filename}\"", - "error.file.duplicate": "Berkas dengan nama \"{filename}\" sudah ada", - "error.file.extension.forbidden": "Ekstensi \"{extension}\" tidak diizinkan", - "error.file.extension.invalid": "Ekstensi tidak valid: {extension}", - "error.file.extension.missing": "Berkas \"{filename}\" harus memiliki ekstensi", - "error.file.maxheight": "Tinggi gambar tidak boleh melebihi {height} piksel", - "error.file.maxsize": "Berkas terlalu besar", - "error.file.maxwidth": "Lebar gambar tidak boleh melebihi {width} piksel", - "error.file.mime.differs": "Berkas yang diunggah harus memiliki tipe mime sama \"{mime}\"", - "error.file.mime.forbidden": "Media dengan tipe mime \"{mime}\" tidak diizinkan", - "error.file.mime.invalid": "Tipe mime tidak valid: {mime}", - "error.file.mime.missing": "Tipe media untuk \"{filename}\" tidak dapat dideteksi", - "error.file.minheight": "Tinggi gambar setidaknya {height} piksel", - "error.file.minsize": "Berkas terlalu kecil", - "error.file.minwidth": "Lebar gambar setidaknya {width} piksel", - "error.file.name.missing": "Nama berkas harus diisi", - "error.file.notFound": "Berkas \"{filename}\" tidak dapat ditemukan", - "error.file.orientation": "Orientasi gambar harus \"{orientation}\"", - "error.file.type.forbidden": "Anda tidak diizinkan mengunggah berkas dengan tipe {type}", - "error.file.type.invalid": "Tipe berkas tidak valid: {type}", - "error.file.undefined": "Berkas tidak dapat ditemukan", - - "error.form.incomplete": "Pastikan semua bidang telah diisi dengan benar…", - "error.form.notSaved": "Formulir tidak dapat disimpan", - - "error.language.code": "Masukkan kode bahasa yang valid", - "error.language.duplicate": "Bahasa sudah ada", - "error.language.name": "Masukkan nama bahasa yang valid", - "error.language.notFound": "The language could not be found", - - "error.layout.validation.block": "Ada kesalahan di blok {blockIndex} di tata letak {layoutIndex}", - "error.layout.validation.settings": "Ada kesalahan di pengaturan tata letak {index}", - - "error.license.format": "Masukkan kode lisensi yang valid", - "error.license.email": "Masukkan surel yang valid", - "error.license.verification": "Lisensi tidak dapat diverifikasi", - - "error.offline": "The Panel is currently offline", - - "error.page.changeSlug.permission": "Anda tidak diizinkan mengubah akhiran URL untuk \"{slug}\"", - "error.page.changeStatus.incomplete": "Halaman memiliki kesalahan dan tidak dapat diterbitkan", - "error.page.changeStatus.permission": "Status halaman ini tidak dapat diubah", - "error.page.changeStatus.toDraft.invalid": "Halaman \"{slug}\" tidak dapat dikonversi menjadi draf", - "error.page.changeTemplate.invalid": "Templat untuk halaman \"{slug}\" tidak dapat diubah", - "error.page.changeTemplate.permission": "Anda tidak diizinkan mengubah templat dari \"{slug}\"", - "error.page.changeTitle.empty": "Judul harus diisi", - "error.page.changeTitle.permission": "Anda tidak diizinkan mengubah judul dari \"{slug}\"", - "error.page.create.permission": "Anda tidak diizinkan membuat \"{slug}\"", - "error.page.delete": "Halaman \"{slug}\" tidak dapat dihapus", - "error.page.delete.confirm": "Masukkan judul halaman untuk mengonfirmasi", - "error.page.delete.hasChildren": "Halaman ini memiliki sub-halaman dan tidak dapat dihapus", - "error.page.delete.permission": "Anda tidak diizinkan menghapus \"{slug}\"", - "error.page.draft.duplicate": "Draf halaman dengan akhiran URL \"{slug}\" sudah ada", - "error.page.duplicate": "Halaman dengan akhiran URL \"{slug}\" sudah ada", - "error.page.duplicate.permission": "Anda tidak diizinkan menduplikasi \"{slug}\"", - "error.page.notFound": "Halaman \"{slug}\" tidak dapat ditemukan", - "error.page.num.invalid": "Masukkan nomor urut yang valid. Nomor tidak boleh negatif.", - "error.page.slug.invalid": "Masukkan akhiran URL yang valid", - "error.page.slug.maxlength": "Panjang slug harus kurang dari \"{length}\" karakter", - "error.page.sort.permission": "Halaman \"{slug}\" tidak dapat diurutkan", - "error.page.status.invalid": "Atur status halaman yang valid", - "error.page.undefined": "Halaman tidak dapat ditemukan", - "error.page.update.permission": "Anda tidak diizinkan memperbaharui \"{slug}\"", - - "error.section.files.max.plural": "Anda hanya boleh menambahkan maksimal {max} berkas ke bagian \"{section}\"", - "error.section.files.max.singular": "Anda hanya boleh menambahkan satu berkas ke bagian \"{section}\"", - "error.section.files.min.plural": "Bagian \"{section}\" setidaknya memiliki {min} berkas", - "error.section.files.min.singular": "Bagian \"{section}\" setidaknya memiliki satu berkas", - - "error.section.pages.max.plural": "Anda hanya boleh menambahkan maksimal {max} halaman ke bagian \"{section}\"", - "error.section.pages.max.singular": "Anda hanya boleh menambahkan satu halaman ke bagian \"{section}\"", - "error.section.pages.min.plural": "Bagian \"{section}\" setidaknya memiliki {min} halaman", - "error.section.pages.min.singular": "Bagian \"{section}\" setidaknya memiliki satu halaman", - - "error.section.notLoaded": "Bagian \"{name}\" tidak dapat dimuat", - "error.section.type.invalid": "Tipe bagian \"{type}\" tidak valid", - - "error.site.changeTitle.empty": "Judul harus diisi", - "error.site.changeTitle.permission": "Anda tidak diizinkan mengubah judul situs", - "error.site.update.permission": "Anda tidak diizinkan memperbaharui situs", - - "error.template.default.notFound": "Templat bawaan tidak ada", - - "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Anda tidak diizinkan mengubah surel dari pengguna \"{name}\"", - "error.user.changeLanguage.permission": "Anda tidak diizinkan mengubah bahasa dari pengguna \"{name}\"", - "error.user.changeName.permission": "Anda tidak diizinkan mengubah nama dari pengguna \"{name}\"", - "error.user.changePassword.permission": "Anda tidak diizinkan mengubah sandi dari pengguna \"{name}\"", - "error.user.changeRole.lastAdmin": "Peran dari admin satu-satunya tidak dapat diubah", - "error.user.changeRole.permission": "Anda tidak diizinkan mengubah peran dari pengguna \"{name}\"", - "error.user.changeRole.toAdmin": "Anda tidak diizinkan mempromosikan seseorang menjadi admin", - "error.user.create.permission": "Anda tidak diizinkan membuat pengguna ini", - "error.user.delete": "Pengguna \"{nama}\" tidak dapat dihapus", - "error.user.delete.lastAdmin": "Admin satu-satunya tidak dapat dihapus", - "error.user.delete.lastUser": "Pengguna satu-satunya tidak dapat dihapus", - "error.user.delete.permission": "Anda tidak diizinkan menghapus pengguna \"{name}\"", - "error.user.duplicate": "Pengguna dengan surel \"{email}\" sudah ada", - "error.user.email.invalid": "Masukkan surel yang valid", - "error.user.language.invalid": "Masukkan bahasa yang valid", - "error.user.notFound": "Pengguna \"{name}\" tidak dapat ditemukan", - "error.user.password.invalid": "Masukkan sandi yang valid. Sandi setidaknya mengandung 8 karakter.", - "error.user.password.notSame": "Sandi tidak cocok", - "error.user.password.undefined": "Pengguna tidak memiliki sandi", - "error.user.password.wrong": "Kata sandi salah", - "error.user.role.invalid": "Masukkan peran yang valid", - "error.user.undefined": "Pengguna tidak dapat ditemukan", - "error.user.update.permission": "Anda tidak diizinkan memperbaharui pengguna \"{name}\"", - - "error.validation.accepted": "Mohon konfirmasi", - "error.validation.alpha": "Masukkan hanya karakter a-z", - "error.validation.alphanum": "Masukkan hanya karakter a-z atau 0-9", - "error.validation.between": "Masukkan nilai antara \"{min}\" dan \"{max}\"", - "error.validation.boolean": "Mohon konfirmasi atau tolak", - "error.validation.contains": "Masukkan nilai yang mengandung \"{needle}\"", - "error.validation.date": "Masukkan tanggal yang valid", - "error.validation.date.after": "Masukkan tanggal setelah {date}", - "error.validation.date.before": "Masukkan tanggal sebelum {date}", - "error.validation.date.between": "Masukkan tanggal antara {min} dan {max}", - "error.validation.denied": "Mohon tolak", - "error.validation.different": "Nilai harus selain \"{other}\"", - "error.validation.email": "Masukkan surel yang valid", - "error.validation.endswith": "Nilai harus diakhiri dengan \"{end}\"", - "error.validation.filename": "Masukkan nama berkas yang valid", - "error.validation.in": "Masukkan satu dari berikut: ({in})", - "error.validation.integer": "Masukkan bilangan bulat yang valid", - "error.validation.ip": "Masukkan IP yang valid", - "error.validation.less": "Masukkan nilai kurang dari {max}", - "error.validation.match": "Nilai tidak cocok dengan pola yang semestinya", - "error.validation.max": "Masukkan nilai yang sama dengan atau kurang dari {max}", - "error.validation.maxlength": "Masukkan nilai yang lebih pendek. (maksimal {max} karakter)", - "error.validation.maxwords": "Masukkan tidak lebih dari {max} kata", - "error.validation.min": "Masukkan nilai yang sama dengan atau lebih dari {min}", - "error.validation.minlength": "Masukkan nilai yang lebih panjang. (minimal {min} karakter)", - "error.validation.minwords": "Masukkan setidaknya {min} kata", - "error.validation.more": "Masukkan nilai yang lebih besar dari {min}", - "error.validation.notcontains": "Masukkan nilai yang tidak mengandung \"{needle}\"", - "error.validation.notin": "Jangan masukkan satupun: ({notIn})", - "error.validation.option": "Pilih opsi yang valid", - "error.validation.num": "Masukkan nomor yang valid", - "error.validation.required": "Masukkan sesuatu", - "error.validation.same": "Masukkan \"{other}\"", - "error.validation.size": "Ukuran dari nilai harus \"{size}\"", - "error.validation.startswith": "Nilai harus diawali dengan \"{start}\"", - "error.validation.time": "Masukkan waktu yang valid", - "error.validation.time.after": "Masukkan waktu setelah {time}", - "error.validation.time.before": "Masukkan waktu sebelum {time}", - "error.validation.time.between": "Masukkan waktu antara {min} dan {max}", - "error.validation.url": "Masukkan URL yang valid", - - "expand": "Luaskan", - "expand.all": "Luaskan Semua", - - "field.required": "Bidang ini wajib", - "field.blocks.changeType": "Ubah tipe", - "field.blocks.code.name": "Kode", - "field.blocks.code.language": "Bahasa", - "field.blocks.code.placeholder": "Kode Anda …", - "field.blocks.delete.confirm": "Anda yakin menghapus blok ini?", - "field.blocks.delete.confirm.all": "Anda yakin menghapus semua blok?", - "field.blocks.delete.confirm.selected": "Anda yakin menghapus blok yang dipilih?", - "field.blocks.empty": "Belum ada blok", - "field.blocks.fieldsets.label": "Pilih tipe blok …", - "field.blocks.fieldsets.paste": "Press {{ shortcut }} to paste/import blocks from your clipboard", - "field.blocks.gallery.name": "Galeri", - "field.blocks.gallery.images.empty": "Belum ada gambar", - "field.blocks.gallery.images.label": "Gambar", - "field.blocks.heading.level": "Level", - "field.blocks.heading.name": "Penajukan", - "field.blocks.heading.text": "Teks", - "field.blocks.heading.placeholder": "Penajukan …", - "field.blocks.image.alt": "Teks alternatif", - "field.blocks.image.caption": "Keterangan", - "field.blocks.image.crop": "Pangkas", - "field.blocks.image.link": "Tautan", - "field.blocks.image.location": "Lokasi", - "field.blocks.image.name": "Gambar", - "field.blocks.image.placeholder": "Pilih gambar", - "field.blocks.image.ratio": "Rasio", - "field.blocks.image.url": "URL Gambar", - "field.blocks.line.name": "Line", - "field.blocks.list.name": "Daftar", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Teks", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Kutipan", - "field.blocks.quote.text.label": "Teks", - "field.blocks.quote.text.placeholder": "Kutipan …", - "field.blocks.quote.citation.label": "Sitasi", - "field.blocks.quote.citation.placeholder": "oleh …", - "field.blocks.text.name": "Teks", - "field.blocks.text.placeholder": "Teks …", - "field.blocks.video.caption": "Deskripsi", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Masukkan URL video", - "field.blocks.video.url.label": "URL Video", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Belum ada berkas yang dipilih", - - "field.layout.delete": "Hapus tata letak", - "field.layout.delete.confirm": "Anda yakin menghapus tata letak ini?", - "field.layout.empty": "Belum ada baris", - "field.layout.select": "Pilih tata letak", - - "field.pages.empty": "Belum ada halaman yang dipilih", - "field.structure.delete.confirm": "Anda yakin menghapus baris ini?", - "field.structure.empty": "Belum ada entri", - "field.users.empty": "Belum ada pengguna yang dipilih", - - "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Anda yakin menghapus
{filename}?", - "file.sort": "Ubah posisi", - - "files": "Berkas", - "files.empty": "Belum ada berkas", - - "hide": "Sembunyikan", - "hour": "Jam", - "import": "Import", - "info": "Info", - "insert": "Sisipkan", - "insert.after": "Sisipkan setelah", - "insert.before": "Sisipkan sebelum", - "install": "Pasang", - - "installation": "Pemasangan", - "installation.completed": "Panel sudah dipasang", - "installation.disabled": "Pemasang panel dimatikan di server publik secara bawaan. Mohon jalankan di server lokal atau ubah opsi panel.install untuk menjalankan di server saat ini.", - "installation.issues.accounts": "Folder /site/accounts tidak ada atau tidak dapat ditulis", - "installation.issues.content": "Folder /content tidak ada atau tidak dapat ditulis", - "installation.issues.curl": "Ekstensi CURL diperlukan", - "installation.issues.headline": "Panel tidak dapat dipasang", - "installation.issues.mbstring": "Ekstensi MB String diperlukan", - "installation.issues.media": "Folder /media tidak ada atau tidak dapat ditulis", - "installation.issues.php": "Pastikan Anda menggunakan PHP 7+", - "installation.issues.server": "Kirby memerlukan Apache, Nginx, atau Caddy", - "installation.issues.sessions": "Folder /site/sessions tidak ada atau tidak dapat ditulis", - - "language": "Bahasa", - "language.code": "Kode", - "language.convert": "Atur sebagai bawaan", - "language.convert.confirm": "

Anda yakin mengubah {name} menjadi bahasa bawaan? Ini tidak dapat dibatalkan.

Jika {name} memiliki konten yang tidak diterjemahkan, tidak akan ada pengganti yang valid dan dapat menyebabkan beberapa bagian dari situs Anda menjadi kosong.

", - "language.create": "Tambah bahasa baru", - "language.delete.confirm": "Anda yakin menghapus bahasa {name} termasuk semua terjemahannya? Ini tidak dapat dibatalkan!", - "language.deleted": "Bahasa sudah dihapus", - "language.direction": "Arah baca", - "language.direction.ltr": "Kiri ke kanan", - "language.direction.rtl": "Kanan ke kiri", - "language.locale": "String \"PHP locale\"", - "language.locale.warning": "Anda menggunakan pengaturan lokal ubah suaian. Ubah di berkas bahasa di /site/languages", - "language.name": "Nama", - "language.updated": "Bahasa sudah diperbaharui", - - "languages": "Bahasa", - "languages.default": "Bahasa bawaan", - "languages.empty": "Belum ada bahasa", - "languages.secondary": "Bahasa sekunder", - "languages.secondary.empty": "Belum ada bahasa sekunder", - - "license": "Lisensi Kirby", - "license.buy": "Beli lisensi", - "license.register": "Daftar", - "license.manage": "Manage your licenses", - "license.register.help": "Anda menerima kode lisensi via surel setelah pembelian. Salin dan tempel kode tersebut untuk mendaftarkan.", - "license.register.label": "Masukkan kode lisensi Anda", - "license.register.success": "Terima kasih atas dukungan untuk Kirby", - "license.unregistered": "Ini adalah demo tidak diregistrasi dari Kirby", - "license.unregistered.label": "Unregistered", - - "link": "Tautan", - "link.text": "Teks tautan", - - "loading": "Memuat", - - "lock.unsaved": "Perubahan belum tersimpan", - "lock.unsaved.empty": "Tidak ada lagi perubahan belum tersimpan", - "lock.isLocked": "Perubahan belum tersimpan oleh {email}", - "lock.file.isLocked": "Berkas sedang disunting oleh {email} dan tidak dapat diubah.", - "lock.page.isLocked": "Halaman sedang disunting oleh {email} dan tidak dapat diubah.", - "lock.unlock": "Buka kunci", - "lock.isUnlocked": "Perubahan Anda yang belum tersimpan telah terubah oleh pengguna lain. Anda dapat mengunduh perubahan Anda untuk menggabungkannya manual.", - - "login": "Masuk", - "login.code.label.login": "Kode masuk", - "login.code.label.password-reset": "Kode atur ulang sandi", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "Jika alamat surel terdaftar, kode yang diminta dikirim via surel", - "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.login.subject": "Kode masuk Anda", - "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.password-reset.subject": "Kode atur ulang sandi Anda", - "login.remember": "Biarkan tetap masuk", - "login.reset": "Atur ulang sandi", - "login.toggleText.code.email": "Masuk via surel", - "login.toggleText.code.email-password": "Masuk dengan sandi", - "login.toggleText.password-reset.email": "Lupa sandi Anda?", - "login.toggleText.password-reset.email-password": "← Kembali ke masuk", - - "logout": "Keluar", - - "menu": "Menu", - "meridiem": "AM/PM", - "mime": "Tipe Media", - "minutes": "Menit", - - "month": "Bulan", - "months.april": "April", - "months.august": "Agustus", - "months.december": "Desember", - "months.february": "Februari", - "months.january": "Januari", - "months.july": "Juli", - "months.june": "Juni", - "months.march": "Maret", - "months.may": "Mei", - "months.november": "November", - "months.october": "Oktober", - "months.september": "September", - - "more": "Lebih lanjut", - "name": "Nama", - "next": "Selanjutnya", - "no": "tidak", - "off": "mati", - "on": "hidup", - "open": "Buka", - "open.newWindow": "Buka di jendela baru", - "options": "Opsi", - "options.none": "Tidak ada opsi", - - "orientation": "Orientasi", - "orientation.landscape": "Rebah", - "orientation.portrait": "Tegak", - "orientation.square": "Persegi", - - "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Ubah URL", - "page.changeSlug.fromTitle": "Buat dari judul", - "page.changeStatus": "Ubah status", - "page.changeStatus.position": "Pilih posisi", - "page.changeStatus.select": "Pilih status baru", - "page.changeTemplate": "Ubah templat", - "page.delete.confirm": "Anda yakin menghapus {title}?", - "page.delete.confirm.subpages": "Halaman ini memiliki sub-halaman.
Semua sub-halaman akan ikut dihapus.", - "page.delete.confirm.title": "Masukkan judul halaman untuk mengonfirmasi", - "page.draft.create": "Buat draf", - "page.duplicate.appendix": "Salin", - "page.duplicate.files": "Salin berkas", - "page.duplicate.pages": "Salin halaman", - "page.sort": "Ubah posisi", - "page.status": "Status", - "page.status.draft": "Draf", - "page.status.draft.description": "Halaman ini ada pada mode draf dan hanya dapat dilihat oleh penyunting atau via tautan rahasia", - "page.status.listed": "Publik", - "page.status.listed.description": "Halaman publik untuk siapapun", - "page.status.unlisted": "Tidak tercantum", - "page.status.unlisted.description": "Halaman hanya dapat diakses via URL", - - "pages": "Halaman", - "pages.empty": "Belum ada halaman", - "pages.status.draft": "Draf", - "pages.status.listed": "Dipublikasikan", - "pages.status.unlisted": "Tidak tercantum", - - "pagination.page": "Halaman", - - "password": "Sandi", - "paste": "Paste", - "paste.after": "Paste after", - "pixel": "Piksel", - "plugins": "Plugins", - "prev": "Sebelumnya", - "preview": "Pratinjau", - "remove": "Hapus", - "rename": "Ubah nama", - "replace": "Ganti", - "retry": "Coba lagi", - "revert": "Kembalikan", - "revert.confirm": "Anda yakin menghapus semua perubahan yang belum tersimpan?", - - "role": "Peran", - "role.admin.description": "Admin memiliki semua izin", - "role.admin.title": "Admin", - "role.all": "Semua", - "role.empty": "Tidak ada pengguna dengan peran ini", - "role.description.placeholder": "Tidak ada deskripsi", - "role.nobody.description": "Ini adalah peran cadangan tanpa permisi apapun", - "role.nobody.title": "Tidak siapapun", - - "save": "Simpan", - "search": "Cari", - "search.min": "Masukkan {min} karakter untuk mencari", - "search.all": "Tampilkan semua", - "search.results.none": "Tidak ada hasil", - - "section.required": "Bagian ini wajib", - - "security": "Security", - "select": "Pilih", - "server": "Server", - "settings": "Pengaturan", - "show": "Tampilkan", - "site.blueprint": "Situs ini belum memiliki cetak biru. Anda dapat mendefinisikannya di /site/blueprints/site.yml", - "size": "Ukuran", - "slug": "Akhiran URL", - "sort": "Urutkan", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Judul", - "template": "Templat", - "today": "Hari ini", - - "toolbar.button.code": "Kode", - "toolbar.button.bold": "Tebal", - "toolbar.button.email": "Surel", - "toolbar.button.headings": "Penajukan", - "toolbar.button.heading.1": "Penajukan 1", - "toolbar.button.heading.2": "Penajukan 2", - "toolbar.button.heading.3": "Penajukan 3", - "toolbar.button.heading.4": "Heading 4", - "toolbar.button.heading.5": "Heading 5", - "toolbar.button.heading.6": "Heading 6", - "toolbar.button.italic": "Miring", - "toolbar.button.file": "Berkas", - "toolbar.button.file.select": "Pilih berkas", - "toolbar.button.file.upload": "Unggah berkas", - "toolbar.button.link": "Tautan", - "toolbar.button.paragraph": "Paragraph", - "toolbar.button.strike": "Coret", - "toolbar.button.ol": "Daftar berurut", - "toolbar.button.underline": "Garis bawah", - "toolbar.button.ul": "Daftar tidak berurut", - - "translation.author": "Tim Kirby", - "translation.direction": "ltr", - "translation.name": "Bahasa Indonesia", - "translation.locale": "id_ID", - - "upload": "Unggah", - "upload.error.cantMove": "Berkas unggahan tidak dapat dipindahkan", - "upload.error.cantWrite": "Gagal menyimpan berkas", - "upload.error.default": "Berkas tidak dapat diunggah", - "upload.error.extension": "Unggahan berkas diblokir dengan ekstensi", - "upload.error.formSize": "Berkas unggahan mencapai acuan MAX_FILE_SIZE yang diatur di formulir", - "upload.error.iniPostSize": "Berkas unggahan mencapai acuan post_max_size di php.ini", - "upload.error.iniSize": "Berkas unggahan mencapai acuan upload_max_filesize di php.ini", - "upload.error.noFile": "Tidak ada berkas diunggah", - "upload.error.noFiles": "Tidak ada berkas diunggah", - "upload.error.partial": "Berkas unggahan hanya berhasil diunggah sebagian", - "upload.error.tmpDir": "Folder sementara tidak ada", - "upload.errors": "Kesalahan", - "upload.progress": "Mengunggah…", - - "url": "Url", - "url.placeholder": "https://contoh.com", - - "user": "Pengguna", - "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Ubah surel", - "user.changeLanguage": "Ubah bahasa", - "user.changeName": "Ubah nama pengguna ini", - "user.changePassword": "Ubah sandi", - "user.changePassword.new": "Sandi baru", - "user.changePassword.new.confirm": "Konfirmasi sandi baru…", - "user.changeRole": "Ubah peran", - "user.changeRole.select": "Pilih peran baru", - "user.create": "Tambah pengguna baru", - "user.delete": "Hapus pengguna ini", - "user.delete.confirm": "Anda yakin menghapus
{email}?", - - "users": "Pengguna", - - "version": "Versi", - - "view.account": "Akun Anda", - "view.installation": "Pemasangan", - "view.languages": "Bahasa", - "view.resetPassword": "Atur ulang sandi", - "view.site": "Situs", - "view.system": "System", - "view.users": "Pengguna", - - "welcome": "Selamat datang", - "year": "Tahun", - "yes": "ya" + "account.changeName": "Change your name", + "account.delete": "Delete your account", + "account.delete.confirm": "Do you really want to delete your account? You will be logged out immediately. Your account cannot be recovered.", + + "add": "Tambah", + "author": "Author", + "avatar": "Gambar profil", + "back": "Kembali", + "cancel": "Batal", + "change": "Ubah", + "close": "Tutup", + "confirm": "Oke", + "collapse": "Lipat", + "collapse.all": "Lipat Semua", + "copy": "Salin", + "copy.all": "Copy all", + "create": "Buat", + + "date": "Tanggal", + "date.select": "Pilih tanggal", + + "day": "Hari", + "days.fri": "Jum", + "days.mon": "Sen", + "days.sat": "Sab", + "days.sun": "Min", + "days.thu": "Kam", + "days.tue": "Sel", + "days.wed": "Rab", + + "debugging": "Debugging", + + "delete": "Hapus", + "delete.all": "Hapus semua", + + "dialog.files.empty": "Tidak ada berkas untuk dipilih", + "dialog.pages.empty": "Tidak ada halaman untuk dipilih", + "dialog.users.empty": "Tidak ada pengguna untuk dipilih", + + "dimensions": "Dimensi", + "disabled": "Dimatikan", + "discard": "Buang", + "download": "Unduh", + "duplicate": "Duplikasi", + + "edit": "Sunting", + + "email": "Surel", + "email.placeholder": "surel@contoh.com", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Environment", + + "error.access.code": "Kode tidak valid", + "error.access.login": "Upaya masuk tidak valid", + "error.access.panel": "Anda tidak diizinkan mengakses panel", + "error.access.view": "Anda tidak diizinkan mengakses bagian panel ini", + + "error.avatar.create.fail": "Gambar profil tidak dapat diunggah", + "error.avatar.delete.fail": "Gambar profil tidak dapat dihapus", + "error.avatar.dimensions.invalid": "Pastikan lebar dan tinggi gambar profil di bawah 3000 piksel", + "error.avatar.mime.forbidden": "Gambar profil harus berupa berkas JPEG atau PNG", + + "error.blueprint.notFound": "Cetak biru \"{name}\" tidak dapat dimuat", + + "error.blocks.max.plural": "Anda tidak boleh menambahkan lebih dari {max} blok", + "error.blocks.max.singular": "Anda tidak boleh menambahkan lebih dari satu blok", + "error.blocks.min.plural": "Anda setidaknya menambahkan {min} blok", + "error.blocks.min.singular": "Anda setidaknya menambahkan satu blok", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "Surel \"{name}\" tidak dapat ditemukan", + + "error.field.converter.invalid": "Konverter \"{converter}\" tidak valid", + + "error.file.changeName.empty": "Nama harus diisi", + "error.file.changeName.permission": "Anda tidak diizinkan mengubah nama berkas \"{filename}\"", + "error.file.duplicate": "Berkas dengan nama \"{filename}\" sudah ada", + "error.file.extension.forbidden": "Ekstensi \"{extension}\" tidak diizinkan", + "error.file.extension.invalid": "Ekstensi tidak valid: {extension}", + "error.file.extension.missing": "Berkas \"{filename}\" harus memiliki ekstensi", + "error.file.maxheight": "Tinggi gambar tidak boleh melebihi {height} piksel", + "error.file.maxsize": "Berkas terlalu besar", + "error.file.maxwidth": "Lebar gambar tidak boleh melebihi {width} piksel", + "error.file.mime.differs": "Berkas yang diunggah harus memiliki tipe mime sama \"{mime}\"", + "error.file.mime.forbidden": "Media dengan tipe mime \"{mime}\" tidak diizinkan", + "error.file.mime.invalid": "Tipe mime tidak valid: {mime}", + "error.file.mime.missing": "Tipe media untuk \"{filename}\" tidak dapat dideteksi", + "error.file.minheight": "Tinggi gambar setidaknya {height} piksel", + "error.file.minsize": "Berkas terlalu kecil", + "error.file.minwidth": "Lebar gambar setidaknya {width} piksel", + "error.file.name.missing": "Nama berkas harus diisi", + "error.file.notFound": "Berkas \"{filename}\" tidak dapat ditemukan", + "error.file.orientation": "Orientasi gambar harus \"{orientation}\"", + "error.file.type.forbidden": "Anda tidak diizinkan mengunggah berkas dengan tipe {type}", + "error.file.type.invalid": "Tipe berkas tidak valid: {type}", + "error.file.undefined": "Berkas tidak dapat ditemukan", + + "error.form.incomplete": "Pastikan semua bidang telah diisi dengan benar…", + "error.form.notSaved": "Formulir tidak dapat disimpan", + + "error.language.code": "Masukkan kode bahasa yang valid", + "error.language.duplicate": "Bahasa sudah ada", + "error.language.name": "Masukkan nama bahasa yang valid", + "error.language.notFound": "The language could not be found", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "Ada kesalahan di pengaturan tata letak {index}", + + "error.license.format": "Masukkan kode lisensi yang valid", + "error.license.email": "Masukkan surel yang valid", + "error.license.verification": "Lisensi tidak dapat diverifikasi", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "The Panel is currently offline", + + "error.page.changeSlug.permission": "Anda tidak diizinkan mengubah akhiran URL untuk \"{slug}\"", + "error.page.changeStatus.incomplete": "Halaman memiliki kesalahan dan tidak dapat diterbitkan", + "error.page.changeStatus.permission": "Status halaman ini tidak dapat diubah", + "error.page.changeStatus.toDraft.invalid": "Halaman \"{slug}\" tidak dapat dikonversi menjadi draf", + "error.page.changeTemplate.invalid": "Templat untuk halaman \"{slug}\" tidak dapat diubah", + "error.page.changeTemplate.permission": "Anda tidak diizinkan mengubah templat dari \"{slug}\"", + "error.page.changeTitle.empty": "Judul harus diisi", + "error.page.changeTitle.permission": "Anda tidak diizinkan mengubah judul dari \"{slug}\"", + "error.page.create.permission": "Anda tidak diizinkan membuat \"{slug}\"", + "error.page.delete": "Halaman \"{slug}\" tidak dapat dihapus", + "error.page.delete.confirm": "Masukkan judul halaman untuk mengonfirmasi", + "error.page.delete.hasChildren": "Halaman ini memiliki sub-halaman dan tidak dapat dihapus", + "error.page.delete.permission": "Anda tidak diizinkan menghapus \"{slug}\"", + "error.page.draft.duplicate": "Draf halaman dengan akhiran URL \"{slug}\" sudah ada", + "error.page.duplicate": "Halaman dengan akhiran URL \"{slug}\" sudah ada", + "error.page.duplicate.permission": "Anda tidak diizinkan menduplikasi \"{slug}\"", + "error.page.notFound": "Halaman \"{slug}\" tidak dapat ditemukan", + "error.page.num.invalid": "Masukkan nomor urut yang valid. Nomor tidak boleh negatif.", + "error.page.slug.invalid": "Masukkan akhiran URL yang valid", + "error.page.slug.maxlength": "Panjang slug harus kurang dari \"{length}\" karakter", + "error.page.sort.permission": "Halaman \"{slug}\" tidak dapat diurutkan", + "error.page.status.invalid": "Atur status halaman yang valid", + "error.page.undefined": "Halaman tidak dapat ditemukan", + "error.page.update.permission": "Anda tidak diizinkan memperbaharui \"{slug}\"", + + "error.section.files.max.plural": "Anda hanya boleh menambahkan maksimal {max} berkas ke bagian \"{section}\"", + "error.section.files.max.singular": "Anda hanya boleh menambahkan satu berkas ke bagian \"{section}\"", + "error.section.files.min.plural": "Bagian \"{section}\" setidaknya memiliki {min} berkas", + "error.section.files.min.singular": "Bagian \"{section}\" setidaknya memiliki satu berkas", + + "error.section.pages.max.plural": "Anda hanya boleh menambahkan maksimal {max} halaman ke bagian \"{section}\"", + "error.section.pages.max.singular": "Anda hanya boleh menambahkan satu halaman ke bagian \"{section}\"", + "error.section.pages.min.plural": "Bagian \"{section}\" setidaknya memiliki {min} halaman", + "error.section.pages.min.singular": "Bagian \"{section}\" setidaknya memiliki satu halaman", + + "error.section.notLoaded": "Bagian \"{name}\" tidak dapat dimuat", + "error.section.type.invalid": "Tipe bagian \"{type}\" tidak valid", + + "error.site.changeTitle.empty": "Judul harus diisi", + "error.site.changeTitle.permission": "Anda tidak diizinkan mengubah judul situs", + "error.site.update.permission": "Anda tidak diizinkan memperbaharui situs", + + "error.template.default.notFound": "Templat bawaan tidak ada", + + "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Anda tidak diizinkan mengubah surel dari pengguna \"{name}\"", + "error.user.changeLanguage.permission": "Anda tidak diizinkan mengubah bahasa dari pengguna \"{name}\"", + "error.user.changeName.permission": "Anda tidak diizinkan mengubah nama dari pengguna \"{name}\"", + "error.user.changePassword.permission": "Anda tidak diizinkan mengubah sandi dari pengguna \"{name}\"", + "error.user.changeRole.lastAdmin": "Peran dari admin satu-satunya tidak dapat diubah", + "error.user.changeRole.permission": "Anda tidak diizinkan mengubah peran dari pengguna \"{name}\"", + "error.user.changeRole.toAdmin": "Anda tidak diizinkan mempromosikan seseorang menjadi admin", + "error.user.create.permission": "Anda tidak diizinkan membuat pengguna ini", + "error.user.delete": "Pengguna \"{nama}\" tidak dapat dihapus", + "error.user.delete.lastAdmin": "Admin satu-satunya tidak dapat dihapus", + "error.user.delete.lastUser": "Pengguna satu-satunya tidak dapat dihapus", + "error.user.delete.permission": "Anda tidak diizinkan menghapus pengguna \"{name}\"", + "error.user.duplicate": "Pengguna dengan surel \"{email}\" sudah ada", + "error.user.email.invalid": "Masukkan surel yang valid", + "error.user.language.invalid": "Masukkan bahasa yang valid", + "error.user.notFound": "Pengguna \"{name}\" tidak dapat ditemukan", + "error.user.password.invalid": "Masukkan sandi yang valid. Sandi setidaknya mengandung 8 karakter.", + "error.user.password.notSame": "Sandi tidak cocok", + "error.user.password.undefined": "Pengguna tidak memiliki sandi", + "error.user.password.wrong": "Kata sandi salah", + "error.user.role.invalid": "Masukkan peran yang valid", + "error.user.undefined": "Pengguna tidak dapat ditemukan", + "error.user.update.permission": "Anda tidak diizinkan memperbaharui pengguna \"{name}\"", + + "error.validation.accepted": "Mohon konfirmasi", + "error.validation.alpha": "Masukkan hanya karakter a-z", + "error.validation.alphanum": "Masukkan hanya karakter a-z atau 0-9", + "error.validation.between": "Masukkan nilai antara \"{min}\" dan \"{max}\"", + "error.validation.boolean": "Mohon konfirmasi atau tolak", + "error.validation.contains": "Masukkan nilai yang mengandung \"{needle}\"", + "error.validation.date": "Masukkan tanggal yang valid", + "error.validation.date.after": "Masukkan tanggal setelah {date}", + "error.validation.date.before": "Masukkan tanggal sebelum {date}", + "error.validation.date.between": "Masukkan tanggal antara {min} dan {max}", + "error.validation.denied": "Mohon tolak", + "error.validation.different": "Nilai harus selain \"{other}\"", + "error.validation.email": "Masukkan surel yang valid", + "error.validation.endswith": "Nilai harus diakhiri dengan \"{end}\"", + "error.validation.filename": "Masukkan nama berkas yang valid", + "error.validation.in": "Masukkan satu dari berikut: ({in})", + "error.validation.integer": "Masukkan bilangan bulat yang valid", + "error.validation.ip": "Masukkan IP yang valid", + "error.validation.less": "Masukkan nilai kurang dari {max}", + "error.validation.match": "Nilai tidak cocok dengan pola yang semestinya", + "error.validation.max": "Masukkan nilai yang sama dengan atau kurang dari {max}", + "error.validation.maxlength": "Masukkan nilai yang lebih pendek. (maksimal {max} karakter)", + "error.validation.maxwords": "Masukkan tidak lebih dari {max} kata", + "error.validation.min": "Masukkan nilai yang sama dengan atau lebih dari {min}", + "error.validation.minlength": "Masukkan nilai yang lebih panjang. (minimal {min} karakter)", + "error.validation.minwords": "Masukkan setidaknya {min} kata", + "error.validation.more": "Masukkan nilai yang lebih besar dari {min}", + "error.validation.notcontains": "Masukkan nilai yang tidak mengandung \"{needle}\"", + "error.validation.notin": "Jangan masukkan satupun: ({notIn})", + "error.validation.option": "Pilih opsi yang valid", + "error.validation.num": "Masukkan nomor yang valid", + "error.validation.required": "Masukkan sesuatu", + "error.validation.same": "Masukkan \"{other}\"", + "error.validation.size": "Ukuran dari nilai harus \"{size}\"", + "error.validation.startswith": "Nilai harus diawali dengan \"{start}\"", + "error.validation.time": "Masukkan waktu yang valid", + "error.validation.time.after": "Masukkan waktu setelah {time}", + "error.validation.time.before": "Masukkan waktu sebelum {time}", + "error.validation.time.between": "Masukkan waktu antara {min} dan {max}", + "error.validation.url": "Masukkan URL yang valid", + + "expand": "Luaskan", + "expand.all": "Luaskan Semua", + + "field.required": "Bidang ini wajib", + "field.blocks.changeType": "Ubah tipe", + "field.blocks.code.name": "Kode", + "field.blocks.code.language": "Bahasa", + "field.blocks.code.placeholder": "Kode Anda …", + "field.blocks.delete.confirm": "Anda yakin menghapus blok ini?", + "field.blocks.delete.confirm.all": "Anda yakin menghapus semua blok?", + "field.blocks.delete.confirm.selected": "Anda yakin menghapus blok yang dipilih?", + "field.blocks.empty": "Belum ada blok", + "field.blocks.fieldsets.label": "Pilih tipe blok …", + "field.blocks.fieldsets.paste": "Press {{ shortcut }} to paste/import blocks from your clipboard", + "field.blocks.gallery.name": "Galeri", + "field.blocks.gallery.images.empty": "Belum ada gambar", + "field.blocks.gallery.images.label": "Gambar", + "field.blocks.heading.level": "Level", + "field.blocks.heading.name": "Penajukan", + "field.blocks.heading.text": "Teks", + "field.blocks.heading.placeholder": "Penajukan …", + "field.blocks.image.alt": "Teks alternatif", + "field.blocks.image.caption": "Keterangan", + "field.blocks.image.crop": "Pangkas", + "field.blocks.image.link": "Tautan", + "field.blocks.image.location": "Lokasi", + "field.blocks.image.name": "Gambar", + "field.blocks.image.placeholder": "Pilih gambar", + "field.blocks.image.ratio": "Rasio", + "field.blocks.image.url": "URL Gambar", + "field.blocks.line.name": "Line", + "field.blocks.list.name": "Daftar", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Teks", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Kutipan", + "field.blocks.quote.text.label": "Teks", + "field.blocks.quote.text.placeholder": "Kutipan …", + "field.blocks.quote.citation.label": "Sitasi", + "field.blocks.quote.citation.placeholder": "oleh …", + "field.blocks.text.name": "Teks", + "field.blocks.text.placeholder": "Teks …", + "field.blocks.video.caption": "Deskripsi", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Masukkan URL video", + "field.blocks.video.url.label": "URL Video", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Belum ada berkas yang dipilih", + + "field.layout.delete": "Hapus tata letak", + "field.layout.delete.confirm": "Anda yakin menghapus tata letak ini?", + "field.layout.empty": "Belum ada baris", + "field.layout.select": "Pilih tata letak", + + "field.object.empty": "No information yet", + + "field.pages.empty": "Belum ada halaman yang dipilih", + + "field.structure.delete.confirm": "Anda yakin menghapus baris ini?", + "field.structure.empty": "Belum ada entri", + + "field.users.empty": "Belum ada pengguna yang dipilih", + + "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Anda yakin menghapus
{filename}?", + "file.sort": "Ubah posisi", + + "files": "Berkas", + "files.empty": "Belum ada berkas", + + "hide": "Sembunyikan", + "hour": "Jam", + "import": "Import", + "info": "Info", + "insert": "Sisipkan", + "insert.after": "Sisipkan setelah", + "insert.before": "Sisipkan sebelum", + "install": "Pasang", + + "installation": "Pemasangan", + "installation.completed": "Panel sudah dipasang", + "installation.disabled": "Pemasang panel dimatikan di server publik secara bawaan. Mohon jalankan di server lokal atau ubah opsi panel.install untuk menjalankan di server saat ini.", + "installation.issues.accounts": "Folder /site/accounts tidak ada atau tidak dapat ditulis", + "installation.issues.content": "Folder /content tidak ada atau tidak dapat ditulis", + "installation.issues.curl": "Ekstensi CURL diperlukan", + "installation.issues.headline": "Panel tidak dapat dipasang", + "installation.issues.mbstring": "Ekstensi MB String diperlukan", + "installation.issues.media": "Folder /media tidak ada atau tidak dapat ditulis", + "installation.issues.php": "Pastikan Anda menggunakan PHP 7+", + "installation.issues.server": "Kirby memerlukan Apache, Nginx, atau Caddy", + "installation.issues.sessions": "Folder /site/sessions tidak ada atau tidak dapat ditulis", + + "language": "Bahasa", + "language.code": "Kode", + "language.convert": "Atur sebagai bawaan", + "language.convert.confirm": "

Anda yakin mengubah {name} menjadi bahasa bawaan? Ini tidak dapat dibatalkan.

Jika {name} memiliki konten yang tidak diterjemahkan, tidak akan ada pengganti yang valid dan dapat menyebabkan beberapa bagian dari situs Anda menjadi kosong.

", + "language.create": "Tambah bahasa baru", + "language.delete.confirm": "Anda yakin menghapus bahasa {name} termasuk semua terjemahannya? Ini tidak dapat dibatalkan!", + "language.deleted": "Bahasa sudah dihapus", + "language.direction": "Arah baca", + "language.direction.ltr": "Kiri ke kanan", + "language.direction.rtl": "Kanan ke kiri", + "language.locale": "String \"PHP locale\"", + "language.locale.warning": "Anda menggunakan pengaturan lokal ubah suaian. Ubah di berkas bahasa di /site/languages", + "language.name": "Nama", + "language.updated": "Bahasa sudah diperbaharui", + + "languages": "Bahasa", + "languages.default": "Bahasa bawaan", + "languages.empty": "Belum ada bahasa", + "languages.secondary": "Bahasa sekunder", + "languages.secondary.empty": "Belum ada bahasa sekunder", + + "license": "Lisensi Kirby", + "license.buy": "Beli lisensi", + "license.register": "Daftar", + "license.manage": "Manage your licenses", + "license.register.help": "Anda menerima kode lisensi via surel setelah pembelian. Salin dan tempel kode tersebut untuk mendaftarkan.", + "license.register.label": "Masukkan kode lisensi Anda", + "license.register.success": "Terima kasih atas dukungan untuk Kirby", + "license.unregistered": "Ini adalah demo tidak diregistrasi dari Kirby", + "license.unregistered.label": "Unregistered", + + "link": "Tautan", + "link.text": "Teks tautan", + + "loading": "Memuat", + + "lock.unsaved": "Perubahan belum tersimpan", + "lock.unsaved.empty": "Tidak ada lagi perubahan belum tersimpan", + "lock.isLocked": "Perubahan belum tersimpan oleh {email}", + "lock.file.isLocked": "Berkas sedang disunting oleh {email} dan tidak dapat diubah.", + "lock.page.isLocked": "Halaman sedang disunting oleh {email} dan tidak dapat diubah.", + "lock.unlock": "Buka kunci", + "lock.isUnlocked": "Perubahan Anda yang belum tersimpan telah terubah oleh pengguna lain. Anda dapat mengunduh perubahan Anda untuk menggabungkannya manual.", + + "login": "Masuk", + "login.code.label.login": "Kode masuk", + "login.code.label.password-reset": "Kode atur ulang sandi", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "Jika alamat surel terdaftar, kode yang diminta dikirim via surel", + "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.login.subject": "Kode masuk Anda", + "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.password-reset.subject": "Kode atur ulang sandi Anda", + "login.remember": "Biarkan tetap masuk", + "login.reset": "Atur ulang sandi", + "login.toggleText.code.email": "Masuk via surel", + "login.toggleText.code.email-password": "Masuk dengan sandi", + "login.toggleText.password-reset.email": "Lupa sandi Anda?", + "login.toggleText.password-reset.email-password": "← Kembali ke masuk", + + "logout": "Keluar", + + "menu": "Menu", + "meridiem": "AM/PM", + "mime": "Tipe Media", + "minutes": "Menit", + + "month": "Bulan", + "months.april": "April", + "months.august": "Agustus", + "months.december": "Desember", + "months.february": "Februari", + "months.january": "Januari", + "months.july": "Juli", + "months.june": "Juni", + "months.march": "Maret", + "months.may": "Mei", + "months.november": "November", + "months.october": "Oktober", + "months.september": "September", + + "more": "Lebih lanjut", + "name": "Nama", + "next": "Selanjutnya", + "no": "tidak", + "off": "mati", + "on": "hidup", + "open": "Buka", + "open.newWindow": "Buka di jendela baru", + "options": "Opsi", + "options.none": "Tidak ada opsi", + + "orientation": "Orientasi", + "orientation.landscape": "Rebah", + "orientation.portrait": "Tegak", + "orientation.square": "Persegi", + + "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Ubah URL", + "page.changeSlug.fromTitle": "Buat dari judul", + "page.changeStatus": "Ubah status", + "page.changeStatus.position": "Pilih posisi", + "page.changeStatus.select": "Pilih status baru", + "page.changeTemplate": "Ubah templat", + "page.delete.confirm": "Anda yakin menghapus {title}?", + "page.delete.confirm.subpages": "Halaman ini memiliki sub-halaman.
Semua sub-halaman akan ikut dihapus.", + "page.delete.confirm.title": "Masukkan judul halaman untuk mengonfirmasi", + "page.draft.create": "Buat draf", + "page.duplicate.appendix": "Salin", + "page.duplicate.files": "Salin berkas", + "page.duplicate.pages": "Salin halaman", + "page.sort": "Ubah posisi", + "page.status": "Status", + "page.status.draft": "Draf", + "page.status.draft.description": "Halaman ini ada pada mode draf dan hanya dapat dilihat oleh penyunting atau via tautan rahasia", + "page.status.listed": "Publik", + "page.status.listed.description": "Halaman publik untuk siapapun", + "page.status.unlisted": "Tidak tercantum", + "page.status.unlisted.description": "Halaman hanya dapat diakses via URL", + + "pages": "Halaman", + "pages.empty": "Belum ada halaman", + "pages.status.draft": "Draf", + "pages.status.listed": "Dipublikasikan", + "pages.status.unlisted": "Tidak tercantum", + + "pagination.page": "Halaman", + + "password": "Sandi", + "paste": "Paste", + "paste.after": "Paste after", + "pixel": "Piksel", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "Sebelumnya", + "preview": "Pratinjau", + "remove": "Hapus", + "rename": "Ubah nama", + "replace": "Ganti", + "retry": "Coba lagi", + "revert": "Kembalikan", + "revert.confirm": "Anda yakin menghapus semua perubahan yang belum tersimpan?", + + "role": "Peran", + "role.admin.description": "Admin memiliki semua izin", + "role.admin.title": "Admin", + "role.all": "Semua", + "role.empty": "Tidak ada pengguna dengan peran ini", + "role.description.placeholder": "Tidak ada deskripsi", + "role.nobody.description": "Ini adalah peran cadangan tanpa permisi apapun", + "role.nobody.title": "Tidak siapapun", + + "save": "Simpan", + "search": "Cari", + "search.min": "Masukkan {min} karakter untuk mencari", + "search.all": "Tampilkan semua", + "search.results.none": "Tidak ada hasil", + + "section.required": "Bagian ini wajib", + + "security": "Security", + "select": "Pilih", + "server": "Server", + "settings": "Pengaturan", + "show": "Tampilkan", + "site.blueprint": "Situs ini belum memiliki cetak biru. Anda dapat mendefinisikannya di /site/blueprints/site.yml", + "size": "Ukuran", + "slug": "Akhiran URL", + "sort": "Urutkan", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Judul", + "template": "Templat", + "today": "Hari ini", + + "toolbar.button.code": "Kode", + "toolbar.button.bold": "Tebal", + "toolbar.button.email": "Surel", + "toolbar.button.headings": "Penajukan", + "toolbar.button.heading.1": "Penajukan 1", + "toolbar.button.heading.2": "Penajukan 2", + "toolbar.button.heading.3": "Penajukan 3", + "toolbar.button.heading.4": "Heading 4", + "toolbar.button.heading.5": "Heading 5", + "toolbar.button.heading.6": "Heading 6", + "toolbar.button.italic": "Miring", + "toolbar.button.file": "Berkas", + "toolbar.button.file.select": "Pilih berkas", + "toolbar.button.file.upload": "Unggah berkas", + "toolbar.button.link": "Tautan", + "toolbar.button.paragraph": "Paragraph", + "toolbar.button.strike": "Coret", + "toolbar.button.ol": "Daftar berurut", + "toolbar.button.underline": "Garis bawah", + "toolbar.button.ul": "Daftar tidak berurut", + + "translation.author": "Tim Kirby", + "translation.direction": "ltr", + "translation.name": "Bahasa Indonesia", + "translation.locale": "id_ID", + + "upload": "Unggah", + "upload.error.cantMove": "Berkas unggahan tidak dapat dipindahkan", + "upload.error.cantWrite": "Gagal menyimpan berkas", + "upload.error.default": "Berkas tidak dapat diunggah", + "upload.error.extension": "Unggahan berkas diblokir dengan ekstensi", + "upload.error.formSize": "Berkas unggahan mencapai acuan MAX_FILE_SIZE yang diatur di formulir", + "upload.error.iniPostSize": "Berkas unggahan mencapai acuan post_max_size di php.ini", + "upload.error.iniSize": "Berkas unggahan mencapai acuan upload_max_filesize di php.ini", + "upload.error.noFile": "Tidak ada berkas diunggah", + "upload.error.noFiles": "Tidak ada berkas diunggah", + "upload.error.partial": "Berkas unggahan hanya berhasil diunggah sebagian", + "upload.error.tmpDir": "Folder sementara tidak ada", + "upload.errors": "Kesalahan", + "upload.progress": "Mengunggah…", + + "url": "Url", + "url.placeholder": "https://contoh.com", + + "user": "Pengguna", + "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Ubah surel", + "user.changeLanguage": "Ubah bahasa", + "user.changeName": "Ubah nama pengguna ini", + "user.changePassword": "Ubah sandi", + "user.changePassword.new": "Sandi baru", + "user.changePassword.new.confirm": "Konfirmasi sandi baru…", + "user.changeRole": "Ubah peran", + "user.changeRole.select": "Pilih peran baru", + "user.create": "Tambah pengguna baru", + "user.delete": "Hapus pengguna ini", + "user.delete.confirm": "Anda yakin menghapus
{email}?", + + "users": "Pengguna", + + "version": "Versi", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "Akun Anda", + "view.installation": "Pemasangan", + "view.languages": "Bahasa", + "view.resetPassword": "Atur ulang sandi", + "view.site": "Situs", + "view.system": "System", + "view.users": "Pengguna", + + "welcome": "Selamat datang", + "year": "Tahun", + "yes": "ya" } diff --git a/kirby/i18n/translations/is_IS.json b/kirby/i18n/translations/is_IS.json index 59fab9b..338aa61 100644 --- a/kirby/i18n/translations/is_IS.json +++ b/kirby/i18n/translations/is_IS.json @@ -1,573 +1,596 @@ { - "account.changeName": "Breyta nafninu þínu", - "account.delete": "Eyða reikningnum þínum", - "account.delete.confirm": "Ertu alveg viss um að þú viljir endanlega eyða reikningnum þínum? Þú munt verða útskráð/ur án tafar. Ómögulegt verður að endurheimta reikninginn þinn.", - - "add": "Bæta við", - "author": "Höfundur", - "avatar": "Prófíl mynd", - "back": "Til baka", - "cancel": "Hætta við", - "change": "Breyta", - "close": "Loka", - "confirm": "Ok", - "collapse": "Collapse", - "collapse.all": "Collapse All", - "copy": "Afrita", - "copy.all": "Afrita allt", - "create": "Stofna", - - "date": "Dagsetning", - "date.select": "Veldu dagsetningu", - - "day": "Dagur", - "days.fri": "Fös", - "days.mon": "Mán", - "days.sat": "Lau", - "days.sun": "Sun", - "days.thu": "Fim", - "days.tue": "Þri", - "days.wed": "Mið", - - "debugging": "Aflúsun", - - "delete": "Eyða", - "delete.all": "Eyða hreint öllu", - - "dialog.files.empty": "Engar skrár til að velja úr", - "dialog.pages.empty": "Engar síður til að velja úr", - "dialog.users.empty": "Engir notendur til að velja úr", - - "dimensions": "Rýmd", - "disabled": "Óvirkt", - "discard": "Hunsa", - "download": "Hlaða niður", - "duplicate": "Klóna", - - "edit": "Breyta", - - "email": "Netfang", - "email.placeholder": "nafn@netfang.is", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Umhverfi", - - "error.access.code": "Ógildur kóði", - "error.access.login": "Ógild innskráning", - "error.access.panel": "Þú hefur ekkert leyfi til að nota panelinn", - "error.access.view": "Þú hefur ekkert leyfi til að nota þennan hluta panelsins", - - "error.avatar.create.fail": "Það gekk ekki að hlaða inn prófílmyndinni", - "error.avatar.delete.fail": "Ekki tókst að eyða prófílmyndinni", - "error.avatar.dimensions.invalid": "Vinsamlegast hafðu myndina ekki breiðari né hærri en 3000 punkta", - "error.avatar.mime.forbidden": "Snið myndarinnar þarf að vera af gerðinni JPEG eða PNG", - - "error.blueprint.notFound": "Ekki tókst að hlaða bláprentið: \"{name}\". Reyndu aftur?", - - "error.blocks.max.plural": "Ekki fleiri en {max} bálka", - "error.blocks.max.singular": "Ekki meira en einn bálkur", - "error.blocks.min.plural": "Minnst {min}. bálka", - "error.blocks.min.singular": "Allavegana einn bálkur takk", - "error.blocks.validation": "Það er villa í bálki númer {index}. Klikkaðu á bálkinn og finndu villuna. Það er væntanlega rauðlitur rammi utan um villuna.", - - "error.email.preset.notFound": "Netfangstillingarnar: \"{name}\" fundust ekki", - - "error.field.converter.invalid": "Ógildur umbreytari \"{converter}\"", - - "error.file.changeName.empty": "Nafn skal fylla út", - "error.file.changeName.permission": "Þú mátt ekkert breyta nafninu á skránni \"{filename}\"", - "error.file.duplicate": "Skrá með nafninu \"{filename}\" er nú þegar til", - "error.file.extension.forbidden": "Skrárendingin \"{extension}\" er ekki leyfð", - "error.file.extension.invalid": "Óleyfilegt skrársnið hér: {extension}", - "error.file.extension.missing": "Skrárendinguna fyrir \"{filename}\" vantar", - "error.file.maxheight": "Hæð myndarinnar má ekki vera meiri en {height} punktar", - "error.file.maxsize": "Skráinn er alltof stór", - "error.file.maxwidth": "Breydd myndarinnar má alls ekki vera meiri en {width} punktar", - "error.file.mime.differs": "Upphlaðna skráin þarf að vera sömu tegundar: \"{mime}\"", - "error.file.mime.forbidden": "Gagnasniðið \"{mime}\" er ekki leyft hér", - "error.file.mime.invalid": "Ógyllt gagnasnið: {mime}", - "error.file.mime.missing": "Gagnasnið skránnar \"{filename}\" er óþekkt", - "error.file.minheight": "Hæð myndarinnar þarf að vera minnst {height} punktar", - "error.file.minsize": "Skráin er of smá", - "error.file.minwidth": "Breidd myndarinnar þarf að vera minnst {width} punktar", - "error.file.name.missing": "Skrárnafnið má ekki skilja eftir tómt", - "error.file.notFound": "Skráin \"{filename}\" fannst ekki", - "error.file.orientation": "Snið myndarinnar þarf að vera \"{orientation}\"", - "error.file.type.forbidden": "Þú mátt ekkert hlaða inn {type} skrám", - "error.file.type.invalid": "Ógild skrártegund: {type}", - "error.file.undefined": "Skráin fannst ekki", - - "error.form.incomplete": "Vinsamlegast lagfærðu villurnar í forminu…", - "error.form.notSaved": "Ekki tókst að vista upplýsingar úr forminu", - - "error.language.code": "Gófúslega settu inn gildan kóða fyrir tungumál", - "error.language.duplicate": "Þetta tungumál er nú þegar skráð", - "error.language.name": "Gott og gyllt nafn fyrir tungumálið", - "error.language.notFound": "Tungumálið fannst ekkert", - - "error.layout.validation.block": "Það er villa í bálki {blockIndex} í rammanum {layoutIndex}", - "error.layout.validation.settings": "Hér er villa í sitllingum fyrir ramman {index}", - - "error.license.format": "Gildur leyfiskóði hér", - "error.license.email": "Almennilegt netfang hér", - "error.license.verification": "Ekki heppnaðist að staðfesta leyfið", - - "error.offline": "Stjórnborðið er óvirkt eins og stendur.", - - "error.page.changeSlug.permission": "Þú hefur ekkert leyfi til þess að breyta slóðarforskeytinu fyrir \"{slug}\"", - "error.page.changeStatus.incomplete": "Það eru villur á síðunni og við getum ekki gefið hana út", - "error.page.changeStatus.permission": "Stöðu síðunnar var ekki hægt að breyta", - "error.page.changeStatus.toDraft.invalid": "Síðunni \"{slug}\" er ekki hægt að breyta í uppkast", - "error.page.changeTemplate.invalid": "Sniðmáti fyrir síðuna \"{slug}\" er ekki hægt að breyta", - "error.page.changeTemplate.permission": "Þú hefur engan veginn leyfi til að breyta sniðmáti fyrir síðuna \"{slug}\"", - "error.page.changeTitle.empty": "Titillinn getur ekki verið óskilgreindur", - "error.page.changeTitle.permission": "Þú mátt ekki breyta titlinum fyrir \"{slug}\"", - "error.page.create.permission": "Þú hefur ekki leyfi til að stofna \"{slug}\"", - "error.page.delete": "Síðunni \"{slug}\" er ekki hægt að eyða", - "error.page.delete.confirm": "Ritaðu titil síðunnar til að staðfesta", - "error.page.delete.hasChildren": "Síðan hefur undirsíður og er því ekki hægt að eyða", - "error.page.delete.permission": "Þú mátt ekkert eyða \"{slug}\"", - "error.page.draft.duplicate": "Uppkast með slóðinni \"{slug}\" er þegar til", - "error.page.duplicate": "Síða með slóðinni \"{slug}\" er þegar til", - "error.page.duplicate.permission": "Þú mátt ekki klóna \"{slug}\"", - "error.page.notFound": "Síðan \"{slug}\" fannst ekkert", - "error.page.num.invalid": "Veldu ákjósanlega raðtölu. Neikvæðar tölur bannaðar.", - "error.page.slug.invalid": "Veldu ákjósanlega vefslóð", - "error.page.slug.maxlength": "Vefslóð þarf að vera a.m.k. \"{length}\" stafir", - "error.page.sort.permission": "Ekki reyndist unnt að raða síðunni \"{slug}\"", - "error.page.status.invalid": "Ákjósanlega síðustöðu takk", - "error.page.undefined": "Síðan fannst ekkert", - "error.page.update.permission": "Þú mátt ekkert uppfæra síðuna \"{slug}\"", - - "error.section.files.max.plural": "Ekki fleiri en {max} skrár í \"{section}\" svæðið", - "error.section.files.max.singular": "Aðeins ein skrá í \"{section}\" svæðið", - "error.section.files.min.plural": "\"{section}\" svæðið krefst a.m.k. {min} skrá sem innihalds", - "error.section.files.min.singular": "\"{section}\" þarf minnst eina skrá til að það virki", - - "error.section.pages.max.plural": "Alls ekki fleiri en {max} síður í \"{section}\" svæðið", - "error.section.pages.max.singular": "Ekki fleiri en ein síða í \"{section}\" svæðið", - "error.section.pages.min.plural": "\"{section}\" svæðið krefst a.m.k {min}. síðna", - "error.section.pages.min.singular": "\"{section}\" krefst a.m.k. einnar síðu", - - "error.section.notLoaded": "Svæðið \"{name}\" var því miður ekki hægt að sækja", - "error.section.type.invalid": "Svæðiðsgerðin \"{type}\" er því miður ekki gild", - - "error.site.changeTitle.empty": "Ekki skilja titilinn eftir tóman", - "error.site.changeTitle.permission": "Þú mátt ekkert breyta titil vefsvæðisins", - "error.site.update.permission": "Þú mátt ekkert uppfæra vefsvæðið", - - "error.template.default.notFound": "Ekkert sjálfgefið sniðmát fannst", - - "error.unexpected": "Það átti sér stað óvænt villa. Notaðu lúsarleitarhaminn (e. debug mode) til að skilja þetta betur. \nFyrir nánari upplýsingar: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Þú mátt ekkert breyta netfangi notandans \"{name}\"", - "error.user.changeLanguage.permission": "Þú hefur ekki leyfi til að breyta tungumáli notandans \"{name}\"", - "error.user.changeName.permission": "Þú mátt alls ekki breyta nafni notandans \"{name}\"", - "error.user.changePassword.permission": "Þér er harðbannað að breyta lykilorði notandans \"{name}\"", - "error.user.changeRole.lastAdmin": "Þetta er síðasti stjórinn og því má ekki breyta hlutverki", - "error.user.changeRole.permission": "Þú hefur ekki leyfi til að breyta hlutverki fyrir notandan \"{name}\"", - "error.user.changeRole.toAdmin": "Þú hefur ekkert leyfi til að gera notendur að stjórum", - "error.user.create.permission": "Þú mátt ekki stofna þennan notanda", - "error.user.delete": "Ekki reyndist unnt að eyða notandanum \"{name}\"", - "error.user.delete.lastAdmin": "Síðasta stjóranum er ekki hægt að eyða", - "error.user.delete.lastUser": "Síðasta notandanum er ekki hægt að eyða", - "error.user.delete.permission": "Þú mátt ekkert eyða notandanum \"{name}\"", - "error.user.duplicate": "Nú þegar finnst notandi með þetta netfang: \"{email}\"", - "error.user.email.invalid": "Vinsamlegast ákjósanlegt netfang", - "error.user.language.invalid": "Vinsamlegast ákjósanlegt tungumál", - "error.user.notFound": "Þessi notandi; \"{name}\" fannst ekki", - "error.user.password.invalid": "Veldu ákjósanlegt lykilorð. Minnst 8 stafa langt.", - "error.user.password.notSame": "Lykilorðin stemma ekki", - "error.user.password.undefined": "Þessi notandi hefur ekki lykilorð", - "error.user.password.wrong": "Rangt lykilorð", - "error.user.role.invalid": "Veldu ákjósanlegt hlutverk", - "error.user.undefined": "Notandinn fannst ekkert", - "error.user.update.permission": "Þú mátt ekkert breyta notandanum \"{name}\"", - - "error.validation.accepted": "Staðfestu", - "error.validation.alpha": "Aðeins stafir úr Enska stafrófinu, a-z", - "error.validation.alphanum": "Aðeins stafir úr Enska stafrófinu, a-z eða tölustafir 0-9", - "error.validation.between": "Gildi milli \"{min}\" og \"{max}\"", - "error.validation.boolean": "Staðfestu eða hafnaðu þessu", - "error.validation.contains": "Settu inni gildi er inniheldur \"{needle}\"", - "error.validation.date": "Ákjósanlega dagsetningu", - "error.validation.date.after": "Dagsetningu eftir {date}", - "error.validation.date.before": "Dagsetningu fyrir {date}", - "error.validation.date.between": "Dagsetningu milli {min} og {max}", - "error.validation.denied": "Hafnaðu", - "error.validation.different": "Gildið má ekki vera \"{other}\"", - "error.validation.email": "Ákjósanlegt netfang", - "error.validation.endswith": "Gildið verður að enda á \"{end}\"", - "error.validation.filename": "Ákjósanlegt skrárnafn", - "error.validation.in": "Vinsamlegast skráðu eitt af eftirfarandi: ({in})", - "error.validation.integer": "Skráðu heiltölu", - "error.validation.ip": "Skráðu ákjósanlega IP tölu", - "error.validation.less": "Skráðu gildi lægra en {max}", - "error.validation.match": "Gildið er ekki eftir væntingum", - "error.validation.max": "Skráðu gildi sem er ekki hærra en {max}", - "error.validation.maxlength": "Veldu eitthvað styttra. (hámark {max} stafir)", - "error.validation.maxwords": "Ekki skrá fleiri en {max}. orð", - "error.validation.min": "Skráðu gildi ekki lægra en {min}", - "error.validation.minlength": "Hafðu þetta lengra en {min}. stafi", - "error.validation.minwords": "Lágmark {min}. orð", - "error.validation.more": "Eitthvað hærra en {min}", - "error.validation.notcontains": "Skráðu eitthvað sem inniheldur ekki \"{needle}\"", - "error.validation.notin": "Ekki skrá neitt af þessu: ({notIn})", - "error.validation.option": "Veldu ákjósanlegan kost", - "error.validation.num": "Notaðu tölugildi", - "error.validation.required": "Skráðu eitthvað", - "error.validation.same": "Skráðu \"{other}\"", - "error.validation.size": "Gildið þarf að vera \"{size}\"", - "error.validation.startswith": "Þetta þarf að byrja á \"{start}\"", - "error.validation.time": "Ákjósanlegur tími", - "error.validation.time.after": "Veldu tíma eftir {time}", - "error.validation.time.before": "Veldu tíma fyrir{time}", - "error.validation.time.between": "Veldu tíma milli {min} og {max}", - "error.validation.url": "Ákjósanleg vefslóð", - - "expand": "Þenja út", - "expand.all": "Þenja allt út", - - "field.required": "Þetta svið er nauðsynlegt", - "field.blocks.changeType": "Breyta um bálkagerð", - "field.blocks.code.name": "Kóði", - "field.blocks.code.language": "Tungumal", - "field.blocks.code.placeholder": "Kóðinn þinn …", - "field.blocks.delete.confirm": "Ætlarðu virkilega að eyða þessum bálk?", - "field.blocks.delete.confirm.all": "Ertu nú alveg viss um að þú viljir eyða öllum þessum bálkum?", - "field.blocks.delete.confirm.selected": "Viltu virkilega eyða völdum bálkum?", - "field.blocks.empty": "Öngvir bálkar enn", - "field.blocks.fieldsets.label": "Veldu bálkagerð …", - "field.blocks.fieldsets.paste": "Notaðu {{ shortcut }} flýtilyklaaðgerðina til að setja blokkina hér.", - "field.blocks.gallery.name": "Myndasafn", - "field.blocks.gallery.images.empty": "Engar myndir enn", - "field.blocks.gallery.images.label": "Myndir", - "field.blocks.heading.level": "Stig", - "field.blocks.heading.name": "Fyrirsögn", - "field.blocks.heading.text": "Texti/Prósi", - "field.blocks.heading.placeholder": "Fyrirsögn …", - "field.blocks.image.alt": "ALT texti", - "field.blocks.image.caption": "Myndartexti", - "field.blocks.image.crop": "Kroppa", - "field.blocks.image.link": "Tengill", - "field.blocks.image.location": "Staðsetning", - "field.blocks.image.name": "Mynd", - "field.blocks.image.placeholder": "Veldu mynd", - "field.blocks.image.ratio": "Hlutfall", - "field.blocks.image.url": "Slóð myndar", - "field.blocks.line.name": "Lína", - "field.blocks.list.name": "Listi", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Texti", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Tilvitnun", - "field.blocks.quote.text.label": "Innihald tilvitnunar", - "field.blocks.quote.text.placeholder": "Þessi tilvitnun …", - "field.blocks.quote.citation.label": "Heimild", - "field.blocks.quote.citation.placeholder": "eftir …", - "field.blocks.text.name": "Prósi", - "field.blocks.text.placeholder": "Þessi prósi …", - "field.blocks.video.caption": "Myndskeiðstexti", - "field.blocks.video.name": "Myndskeið", - "field.blocks.video.placeholder": "Vefslóð myndskeiðs (URL)", - "field.blocks.video.url.label": "Vefslóð", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Engar skrár valdar ennþá", - - "field.layout.delete": "Eyða ramma", - "field.layout.delete.confirm": "Ætlarðu virkilega að eyða þessum ramma?", - "field.layout.empty": "Nei. Engir rammar enn.", - "field.layout.select": "Veldu rammategund", - - "field.pages.empty": "Engar síður valdar ennþá", - "field.structure.delete.confirm": "Viltu virkilega eyða þessari röð?", - "field.structure.empty": "Engar færslur enn", - "field.users.empty": "Engir notendur valdir enn", - - "file.blueprint": "Þessi skrá hefur ekki skipan (e. blueprint) ennþá. Þú mátt skilgreina skipanina í /site/blueprints/{template}.yml", - "file.delete.confirm": "Ætlarðu virkilega að eyða
{filename}?", - "file.sort": "Breyta röðun", - - "files": "Skrár", - "files.empty": "Engar skrár enn", - - "hide": "Fela", - "hour": "Klukkustund", - "import": "Hlaða inn", - "info": "Info", - "insert": "Setja inn", - "insert.after": "Setja eftir", - "insert.before": "Setja fyrir", - "install": "Setja upp", - - "installation": "Uppsettning", - "installation.completed": "Panellinn er uppsettur", - "installation.disabled": "Paneluppsetning er sjálfgefið óvirk á vefþjónum á Veraldarvefnum. Reyndu frekar að setja Panelinn upp í lokuðu umhverfi eða virkjaðu panel.install möguleikan.", - "installation.issues.accounts": "/site/accounts mappan er annaðhvort ekki til eða er ekki skrifanleg.", - "installation.issues.content": "/content mappan er annaðhvort ekki til eða er ekki skrifanleg", - "installation.issues.curl": "CURL viðbótin er hér bráðnauðsynleg", - "installation.issues.headline": "Uppsetning Panelsins mistókst hrapalega", - "installation.issues.mbstring": "MB String er hér bráðnauðsynleg", - "installation.issues.media": "/media mappan er annaðhvort ekki til eða er ekki skrifanleg", - "installation.issues.php": "Notaðu PHP 7+", - "installation.issues.server": "Kirby krefst Apache, Nginx eða Caddy", - "installation.issues.sessions": "/site/sessions mappan er annaðhvort ekki til eða er ekki skrifanleg", - - "language": "Tungumál", - "language.code": "Kóði", - "language.convert": "Gera sjálfgefið", - "language.convert.confirm": "

Ertu viss um að þú viljir breyta {name} í sjálfgefið (lesist aðal) tungumál? Þessu verður ekki viðsnúið.

Ef {name} hefur innihald sem ekki hefur verið þýtt, þá verða engir möguleikar til þrautarvara og hluti vefsins gæti birtst tómur.

", - "language.create": "Bættu við nýju tungumáli", - "language.delete.confirm": "Ertu nú viss um að þú viljir eyða {name} og öllum tilheyrandi þýðingum? Þetta verður ekki tekið til baka!", - "language.deleted": "Tungumálinu hefur verið eytt", - "language.direction": "Lestursátt (hægri, vinstri)", - "language.direction.ltr": "Vinstra til hægri", - "language.direction.rtl": "Hægra til vinstri", - "language.locale": "PHP locale strengur", - "language.locale.warning": "Þú ert að nota sérsniðna locale uppsetningu. Vinsamlegast breyttu tungumálaskránni á slóðinni /site/languages", - "language.name": "Nafn tungumáls", - "language.updated": "Tungumálið hefur verið uppfært", - - "languages": "Tungumál", - "languages.default": "Aðal tungumál", - "languages.empty": "Það eru engin frekari tungumál skilgreind enn", - "languages.secondary": "Auka tungumál", - "languages.secondary.empty": "Það eru engin auka tungumál skilgreind enn", - - "license": "Leyfi", - "license.buy": "Kaupa leyfi", - "license.register": "Skr\u00E1 Kirby", - "license.manage": "Manage your licenses", - "license.register.help": "Þú fékkst sendan tölvupóst með leyfiskóðanum þegar þú keyptir leyfi. Vinsamlegast afritaðu hann og settu hann hingað til að skrá þig.", - "license.register.label": "Vinsamlegast settu inn leyfiskóðan", - "license.register.success": "Þakka þér fyrir að velja Kirby", - "license.unregistered": "Þetta er óskráð prufueintak af Kirby", - "license.unregistered.label": "Unregistered", - - "link": "Tengill", - "link.text": "Tengilstexti", - - "loading": "Hleð", - - "lock.unsaved": "Óvistað breytingar", - "lock.unsaved.empty": "Það eru öngvar óvistaðar breytingar", - "lock.isLocked": "Óvistaðar breytingar frá {email}", - "lock.file.isLocked": "{email} er að vinna í skránni og þú breytir henni ekki á meðan.", - "lock.page.isLocked": "{email} er að vinna í síðunni og þú breytir henni ekki á meðan.", - "lock.unlock": "Aflæsa", - "lock.isUnlocked": "Þær breytingar sem þú gerðir hafa verið yfirskrifaðar af öðrum notanda. Þú getur sótt þær breytingar og splæst þeim saman við þínar breytingar. Handvirkt.", - - "login": "Innskrá", - "login.code.label.login": "Innskráningarkóði", - "login.code.label.password-reset": "Kóði fyrir endurstillingu lykilorðs", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "Ef netfangið þitt er skráð þá bíður þín nýr tölvupóstur.", - "login.email.login.body": "Já halló {user.nameOrEmail},\n\nNýlega baðstu um innskráningarkóða fyrir bakendan á sorli.is.\nEftirfarandi kóði er virkur í {timeout} mínútur:\n\n{code}\n\nEf þú óskaðir ekki eftir þessu þá hunsaðu þennan tölvupóst eða talaðu við vefstjóran ef þú vilt fræðast nánar.\nAf öryggisástæðum vinsamlegast áframsendu þennan tölvupóst ALLS EKKI.", - "login.email.login.subject": "Innskráningarkóðinn þinn", - "login.email.password-reset.body": "Nei halló {user.nameOrEmail},\n\nNýverið baðstu um að lykilorði þínu væri endurstillt fyrir bakendan á sorli.is. \nEftirfarandi kóði er virkur í {timeout} mínútur:\n\n{code}\n\nEf þú óskaðir ekki eftir þessu þá hunsaðu þennan tölvupóst eða talaðu við vefstjóran ef þú vilt fræðast nánar.\nAf öryggisástæðum vinsamlegast áframsendu þennan tölvupóst ALLS EKKI.", - "login.email.password-reset.subject": "Kóðinn þinn fyrir endurstillingu lykilorðs", - "login.remember": "Vista innskráningu", - "login.reset": "Endurheimta lykilorð takk", - "login.toggleText.code.email": "Innskrá með netfangi", - "login.toggleText.code.email-password": "Innskrá með lykilorði", - "login.toggleText.password-reset.email": "Mannstu ekki lykilorðið?", - "login.toggleText.password-reset.email-password": "← Aftur í innskráningu", - - "logout": "Útskrá", - - "menu": "Valmynd", - "meridiem": "AM/PM", - "mime": "Miðilsgerð", - "minutes": "Mínútur", - - "month": "Mánuður", - "months.april": "Apríl", - "months.august": "Ágúst", - "months.december": "Desember", - "months.february": "Febrúar", - "months.january": "Janúar", - "months.july": "Júlí", - "months.june": "Júní", - "months.march": "Mars", - "months.may": "Maí", - "months.november": "Nóvember", - "months.october": "Október", - "months.september": "September", - - "more": "Meira", - "name": "Nafn", - "next": "Næst", - "no": "nei", - "off": "Af", - "on": "Á", - "open": "Opna", - "open.newWindow": "Opna í nýjum glugga", - "options": "Valmöguleikar", - "options.none": "Engir valmöguleikar", - - "orientation": "Snúningur", - "orientation.landscape": "Langsnið", - "orientation.portrait": "Skammsnið", - "orientation.square": "Ferningur", - - "page.blueprint": "Þessi síða hefur ekki skipan (e. blueprint) ennþá. Þú mátt skilgreina skipanina í /site/blueprints/{template}.yml", - "page.changeSlug": "Breyta vefslóð", - "page.changeSlug.fromTitle": "Slóð af titli", - "page.changeStatus": "Breyta stöðu", - "page.changeStatus.position": "Veldu ákjósanlega röðun", - "page.changeStatus.select": "Veldu nýja stöðu", - "page.changeTemplate": "Breyta sniðmáti", - "page.delete.confirm": "Viltu virkilega farga {title}?", - "page.delete.confirm.subpages": "Þessi síða hefur undirsíður.
Þeim mun verða fargað líka.", - "page.delete.confirm.title": "Skráðu síðutitilinn til staðfestingar", - "page.draft.create": "Stofna uppkast", - "page.duplicate.appendix": "Afrita", - "page.duplicate.files": "Afrita skrár", - "page.duplicate.pages": "Afrita síður", - "page.sort": "Breyta röðun", - "page.status": "Staða", - "page.status.draft": "Uppkast", - "page.status.draft.description": "Þessi síða er uppkast og er aðeins sýnileg höfundum og stjórum eða gegnum falinn tengil.", - "page.status.listed": "Útgefin og listuð", - "page.status.listed.description": "Síðan er aðgengileg öllum og sýnleg í leiðarkerfi vefsins", - "page.status.unlisted": "Útgefin", - "page.status.unlisted.description": "Síðan er aðgengileg öllum en þó ekki sýnileg í leiðarkerfi vefsins", - - "pages": "Síður", - "pages.empty": "Engar síður enn", - "pages.status.draft": "Uppköst", - "pages.status.listed": "Útgefnar og listaðar", - "pages.status.unlisted": "Útgefnar", - - "pagination.page": "Síða", - - "password": "Lykilorð", - "paste": "Líma", - "paste.after": "Líma eftir", - "pixel": "Punkta", - "plugins": "Viðbætur", - "prev": "Fyrri", - "preview": "Forskoða", - "remove": "Fjarlægja", - "rename": "Endurnefna", - "replace": "Setja í stað", - "retry": "Reyndu aftur", - "revert": "Taka upp fyrri siði", - "revert.confirm": "Viltu virkilega eyða öllum óvistuðum breytingum?", - - "role": "Hlutverk", - "role.admin.description": "Stjórinn hefur öll réttindi", - "role.admin.title": "Stjóri", - "role.all": "Öll", - "role.empty": "Það eru engir notendur með þetta hlutverk", - "role.description.placeholder": "Engin lýsing", - "role.nobody.description": "Þetta hlutverk er til þrautarvara en hefur engin réttindi", - "role.nobody.title": "Enginn", - - "save": "Vista", - "search": "Leita", - "search.min": "Lágmark {min} stafir til að leita", - "search.all": "Sýna allt", - "search.results.none": "Engar niðurstöður", - - "section.required": "Þetta svæði er nauðsynlegt", - - "security": "Security", - "select": "Velja", - "server": "Vefþjónn", - "settings": "Stillingar", - "show": "Sýna", - "site.blueprint": "Þessi vefur hefur ekki skipan (e. blueprint) ennþá. Þú mátt skilgreina skipanina í /site/blueprints/site.yml", - "size": "Stærð", - "slug": "Slögg", - "sort": "Raða", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Titill", - "template": "Sniðmát", - "today": "Núna", - - "toolbar.button.code": "Kóðasnið", - "toolbar.button.bold": "Feitletrun", - "toolbar.button.email": "Netfang", - "toolbar.button.headings": "Fyrirsagnir", - "toolbar.button.heading.1": "Fyrirsögn 1", - "toolbar.button.heading.2": "Fyrirsögn 2", - "toolbar.button.heading.3": "Fyrirsögn 3", - "toolbar.button.heading.4": "Fyrirsögn 4", - "toolbar.button.heading.5": "Fyrirsögn 5", - "toolbar.button.heading.6": "Fyrirsögn 6", - "toolbar.button.italic": "Skáletrun", - "toolbar.button.file": "Skrár", - "toolbar.button.file.select": "Veldu skrá", - "toolbar.button.file.upload": "Hlaða inn skrá", - "toolbar.button.link": "Tengill", - "toolbar.button.paragraph": "Efnisgrein", - "toolbar.button.strike": "Gegnumstrika", - "toolbar.button.ol": "Raðaður listi", - "toolbar.button.underline": "Undirstrika", - "toolbar.button.ul": "Áherslumerktur listi", - - "translation.author": "Kirby Teymið", - "translation.direction": "ltr", - "translation.name": "Íslenska", - "translation.locale": "is_IS", - - "upload": "Hlaða inn", - "upload.error.cantMove": "Innhlöðnu skránni var ekki haggað", - "upload.error.cantWrite": "Það mistókst að skrifa skránna í geymslu", - "upload.error.default": "Ekki heppnaðist að hlaða inn skránni", - "upload.error.extension": "Innhleðsla stöðvuð vegna skrárendingar", - "upload.error.formSize": "Innhlaðna skráin er stærri en MAX_FILE_SIZE leyfilegt er.", - "upload.error.iniPostSize": "Innhlaðna skráin er stærri en því sem nemur í post_max_size stillingunni í php.ini", - "upload.error.iniSize": "Innhlaðna skráin er stærri en því sem nemur í upload_max_filesize stillingunni í php.ini", - "upload.error.noFile": "Engri skrá far hlaðið inn", - "upload.error.noFiles": "Engum skrám var hlaðið inn", - "upload.error.partial": "Innhlöðnu skránni var aðeins sótt að hluta", - "upload.error.tmpDir": "Vantar skruggumöppu", - "upload.errors": "Villa", - "upload.progress": "Hleð inn…", - - "url": "Slóð", - "url.placeholder": "https://tildaem.is/", - - "user": "Notandi", - "user.blueprint": "Þér er óhætt að skilgreina fleiri svæði fyrir þetta notenda hlutverk í /site/blueprints/users/{role}.yml", - "user.changeEmail": "Breyta netfangi", - "user.changeLanguage": "Breyta tungumáli", - "user.changeName": "Endurnefna þennan notanda", - "user.changePassword": "Breyta lykilorð", - "user.changePassword.new": "Nýtt lykilorð", - "user.changePassword.new.confirm": "Staðfestu nýtt lykilorð…", - "user.changeRole": "Breyta hlutverki", - "user.changeRole.select": "Veldu nýtt hlutverk", - "user.create": "Bæta við nýjum notenda", - "user.delete": "Farga þessum notenda", - "user.delete.confirm": "Viltu virkilega eyða
{email}?", - - "users": "Notendur", - - "version": "Útgáfa", - - "view.account": "Notandareikningurinn þinn", - "view.installation": "Uppsetning", - "view.languages": "Tungumál", - "view.resetPassword": "Endurstilla lykilorð", - "view.site": "Vefsvæðið", - "view.system": "Kerfi", - "view.users": "Notendur", - - "welcome": "Komið þér fagnandi", - "year": "Ár", - "yes": "já" + "account.changeName": "Breyta nafninu þínu", + "account.delete": "Eyða reikningnum þínum", + "account.delete.confirm": "Ertu alveg viss um að þú viljir endanlega eyða reikningnum þínum? Þú munt verða útskráð/ur án tafar. Ómögulegt verður að endurheimta reikninginn þinn.", + + "add": "Bæta við", + "author": "Höfundur", + "avatar": "Prófíl mynd", + "back": "Til baka", + "cancel": "Hætta við", + "change": "Breyta", + "close": "Loka", + "confirm": "Ok", + "collapse": "Collapse", + "collapse.all": "Collapse All", + "copy": "Afrita", + "copy.all": "Afrita allt", + "create": "Stofna", + + "date": "Dagsetning", + "date.select": "Veldu dagsetningu", + + "day": "Dagur", + "days.fri": "Fös", + "days.mon": "Mán", + "days.sat": "Lau", + "days.sun": "Sun", + "days.thu": "Fim", + "days.tue": "Þri", + "days.wed": "Mið", + + "debugging": "Aflúsun", + + "delete": "Eyða", + "delete.all": "Eyða hreint öllu", + + "dialog.files.empty": "Engar skrár til að velja úr", + "dialog.pages.empty": "Engar síður til að velja úr", + "dialog.users.empty": "Engir notendur til að velja úr", + + "dimensions": "Rýmd", + "disabled": "Óvirkt", + "discard": "Hunsa", + "download": "Hlaða niður", + "duplicate": "Klóna", + + "edit": "Breyta", + + "email": "Netfang", + "email.placeholder": "nafn@netfang.is", + + "entries": "Færslur", + "entry": "Færsla", + + "environment": "Umhverfi", + + "error.access.code": "Ógildur kóði", + "error.access.login": "Ógild innskráning", + "error.access.panel": "Þú hefur ekkert leyfi til að nota panelinn", + "error.access.view": "Þú hefur ekkert leyfi til að nota þennan hluta panelsins", + + "error.avatar.create.fail": "Það gekk ekki að hlaða inn prófílmyndinni", + "error.avatar.delete.fail": "Ekki tókst að eyða prófílmyndinni", + "error.avatar.dimensions.invalid": "Vinsamlegast hafðu myndina ekki breiðari né hærri en 3000 punkta", + "error.avatar.mime.forbidden": "Snið myndarinnar þarf að vera af gerðinni JPEG eða PNG", + + "error.blueprint.notFound": "Ekki tókst að hlaða bláprentið: \"{name}\". Reyndu aftur?", + + "error.blocks.max.plural": "Ekki fleiri en {max} bálka", + "error.blocks.max.singular": "Ekki meira en einn bálkur", + "error.blocks.min.plural": "Minnst {min}. bálka", + "error.blocks.min.singular": "Allavegana einn bálkur takk", + "error.blocks.validation": "Það er villa í {field} sviðinu í bálkinum {index} sem notar {fieldset} bálkgerðina", + + "error.email.preset.notFound": "Netfangstillingarnar: \"{name}\" fundust ekki", + + "error.field.converter.invalid": "Ógildur umbreytari \"{converter}\"", + + "error.file.changeName.empty": "Nafn skal fylla út", + "error.file.changeName.permission": "Þú mátt ekkert breyta nafninu á skránni \"{filename}\"", + "error.file.duplicate": "Skrá með nafninu \"{filename}\" er nú þegar til", + "error.file.extension.forbidden": "Skrárendingin \"{extension}\" er ekki leyfð", + "error.file.extension.invalid": "Óleyfilegt skrársnið hér: {extension}", + "error.file.extension.missing": "Skrárendinguna fyrir \"{filename}\" vantar", + "error.file.maxheight": "Hæð myndarinnar má ekki vera meiri en {height} punktar", + "error.file.maxsize": "Skráinn er alltof stór", + "error.file.maxwidth": "Breydd myndarinnar má alls ekki vera meiri en {width} punktar", + "error.file.mime.differs": "Upphlaðna skráin þarf að vera sömu tegundar: \"{mime}\"", + "error.file.mime.forbidden": "Gagnasniðið \"{mime}\" er ekki leyft hér", + "error.file.mime.invalid": "Ógyllt gagnasnið: {mime}", + "error.file.mime.missing": "Gagnasnið skránnar \"{filename}\" er óþekkt", + "error.file.minheight": "Hæð myndarinnar þarf að vera minnst {height} punktar", + "error.file.minsize": "Skráin er of smá", + "error.file.minwidth": "Breidd myndarinnar þarf að vera minnst {width} punktar", + "error.file.name.missing": "Skrárnafnið má ekki skilja eftir tómt", + "error.file.notFound": "Skráin \"{filename}\" fannst ekki", + "error.file.orientation": "Snið myndarinnar þarf að vera \"{orientation}\"", + "error.file.type.forbidden": "Þú mátt ekkert hlaða inn {type} skrám", + "error.file.type.invalid": "Ógild skrártegund: {type}", + "error.file.undefined": "Skráin fannst ekki", + + "error.form.incomplete": "Vinsamlegast lagfærðu villurnar í forminu…", + "error.form.notSaved": "Ekki tókst að vista upplýsingar úr forminu", + + "error.language.code": "Gófúslega settu inn gildan kóða fyrir tungumál", + "error.language.duplicate": "Þetta tungumál er nú þegar skráð", + "error.language.name": "Gott og gyllt nafn fyrir tungumálið", + "error.language.notFound": "Tungumálið fannst ekkert", + + "error.layout.validation.block": "Það er villa í {field} sviðinu í bálkinum {blockIndex} sem notar {fieldset} bálkgerðina í rammanum {layoutIndex}", + "error.layout.validation.settings": "Hér er villa í sitllingum fyrir ramman {index}", + + "error.license.format": "Gildur leyfiskóði hér", + "error.license.email": "Almennilegt netfang hér", + "error.license.verification": "Ekki heppnaðist að staðfesta leyfið", + + "error.object.validation": "Það er villa í \"{label}\" sviðinu:\n{message}", + + "error.offline": "Stjórnborðið er óvirkt eins og stendur.", + + "error.page.changeSlug.permission": "Þú hefur ekkert leyfi til þess að breyta slóðarforskeytinu fyrir \"{slug}\"", + "error.page.changeStatus.incomplete": "Það eru villur á síðunni og við getum ekki gefið hana út", + "error.page.changeStatus.permission": "Stöðu síðunnar var ekki hægt að breyta", + "error.page.changeStatus.toDraft.invalid": "Síðunni \"{slug}\" er ekki hægt að breyta í uppkast", + "error.page.changeTemplate.invalid": "Sniðmáti fyrir síðuna \"{slug}\" er ekki hægt að breyta", + "error.page.changeTemplate.permission": "Þú hefur engan veginn leyfi til að breyta sniðmáti fyrir síðuna \"{slug}\"", + "error.page.changeTitle.empty": "Titillinn getur ekki verið óskilgreindur", + "error.page.changeTitle.permission": "Þú mátt ekki breyta titlinum fyrir \"{slug}\"", + "error.page.create.permission": "Þú hefur ekki leyfi til að stofna \"{slug}\"", + "error.page.delete": "Síðunni \"{slug}\" er ekki hægt að eyða", + "error.page.delete.confirm": "Ritaðu titil síðunnar til að staðfesta", + "error.page.delete.hasChildren": "Síðan hefur undirsíður og er því ekki hægt að eyða", + "error.page.delete.permission": "Þú mátt ekkert eyða \"{slug}\"", + "error.page.draft.duplicate": "Uppkast með slóðinni \"{slug}\" er þegar til", + "error.page.duplicate": "Síða með slóðinni \"{slug}\" er þegar til", + "error.page.duplicate.permission": "Þú mátt ekki klóna \"{slug}\"", + "error.page.notFound": "Síðan \"{slug}\" fannst ekkert", + "error.page.num.invalid": "Veldu ákjósanlega raðtölu. Neikvæðar tölur bannaðar.", + "error.page.slug.invalid": "Veldu ákjósanlega vefslóð", + "error.page.slug.maxlength": "Vefslóð þarf að vera a.m.k. \"{length}\" stafir", + "error.page.sort.permission": "Ekki reyndist unnt að raða síðunni \"{slug}\"", + "error.page.status.invalid": "Ákjósanlega síðustöðu takk", + "error.page.undefined": "Síðan fannst ekkert", + "error.page.update.permission": "Þú mátt ekkert uppfæra síðuna \"{slug}\"", + + "error.section.files.max.plural": "Ekki fleiri en {max} skrár í \"{section}\" svæðið", + "error.section.files.max.singular": "Aðeins ein skrá í \"{section}\" svæðið", + "error.section.files.min.plural": "\"{section}\" svæðið krefst a.m.k. {min} skrá sem innihalds", + "error.section.files.min.singular": "\"{section}\" þarf minnst eina skrá til að það virki", + + "error.section.pages.max.plural": "Alls ekki fleiri en {max} síður í \"{section}\" svæðið", + "error.section.pages.max.singular": "Ekki fleiri en ein síða í \"{section}\" svæðið", + "error.section.pages.min.plural": "\"{section}\" svæðið krefst a.m.k {min}. síðna", + "error.section.pages.min.singular": "\"{section}\" krefst a.m.k. einnar síðu", + + "error.section.notLoaded": "Svæðið \"{name}\" var því miður ekki hægt að sækja", + "error.section.type.invalid": "Svæðiðsgerðin \"{type}\" er því miður ekki gild", + + "error.site.changeTitle.empty": "Ekki skilja titilinn eftir tóman", + "error.site.changeTitle.permission": "Þú mátt ekkert breyta titil vefsvæðisins", + "error.site.update.permission": "Þú mátt ekkert uppfæra vefsvæðið", + + "error.template.default.notFound": "Ekkert sjálfgefið sniðmát fannst", + + "error.unexpected": "Það átti sér stað óvænt villa. Notaðu lúsarleitarhaminn (e. debug mode) til að skilja þetta betur. \nFyrir nánari upplýsingar: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Þú mátt ekkert breyta netfangi notandans \"{name}\"", + "error.user.changeLanguage.permission": "Þú hefur ekki leyfi til að breyta tungumáli notandans \"{name}\"", + "error.user.changeName.permission": "Þú mátt alls ekki breyta nafni notandans \"{name}\"", + "error.user.changePassword.permission": "Þér er harðbannað að breyta lykilorði notandans \"{name}\"", + "error.user.changeRole.lastAdmin": "Þetta er síðasti stjórinn og því má ekki breyta hlutverki", + "error.user.changeRole.permission": "Þú hefur ekki leyfi til að breyta hlutverki fyrir notandan \"{name}\"", + "error.user.changeRole.toAdmin": "Þú hefur ekkert leyfi til að gera notendur að stjórum", + "error.user.create.permission": "Þú mátt ekki stofna þennan notanda", + "error.user.delete": "Ekki reyndist unnt að eyða notandanum \"{name}\"", + "error.user.delete.lastAdmin": "Síðasta stjóranum er ekki hægt að eyða", + "error.user.delete.lastUser": "Síðasta notandanum er ekki hægt að eyða", + "error.user.delete.permission": "Þú mátt ekkert eyða notandanum \"{name}\"", + "error.user.duplicate": "Nú þegar finnst notandi með þetta netfang: \"{email}\"", + "error.user.email.invalid": "Vinsamlegast ákjósanlegt netfang", + "error.user.language.invalid": "Vinsamlegast ákjósanlegt tungumál", + "error.user.notFound": "Þessi notandi; \"{name}\" fannst ekki", + "error.user.password.invalid": "Veldu ákjósanlegt lykilorð. Minnst 8 stafa langt.", + "error.user.password.notSame": "Lykilorðin stemma ekki", + "error.user.password.undefined": "Þessi notandi hefur ekki lykilorð", + "error.user.password.wrong": "Rangt lykilorð", + "error.user.role.invalid": "Veldu ákjósanlegt hlutverk", + "error.user.undefined": "Notandinn fannst ekkert", + "error.user.update.permission": "Þú mátt ekkert breyta notandanum \"{name}\"", + + "error.validation.accepted": "Staðfestu", + "error.validation.alpha": "Aðeins stafir úr Enska stafrófinu, a-z", + "error.validation.alphanum": "Aðeins stafir úr Enska stafrófinu, a-z eða tölustafir 0-9", + "error.validation.between": "Gildi milli \"{min}\" og \"{max}\"", + "error.validation.boolean": "Staðfestu eða hafnaðu þessu", + "error.validation.contains": "Settu inni gildi er inniheldur \"{needle}\"", + "error.validation.date": "Ákjósanlega dagsetningu", + "error.validation.date.after": "Dagsetningu eftir {date}", + "error.validation.date.before": "Dagsetningu fyrir {date}", + "error.validation.date.between": "Dagsetningu milli {min} og {max}", + "error.validation.denied": "Hafnaðu", + "error.validation.different": "Gildið má ekki vera \"{other}\"", + "error.validation.email": "Ákjósanlegt netfang", + "error.validation.endswith": "Gildið verður að enda á \"{end}\"", + "error.validation.filename": "Ákjósanlegt skrárnafn", + "error.validation.in": "Vinsamlegast skráðu eitt af eftirfarandi: ({in})", + "error.validation.integer": "Skráðu heiltölu", + "error.validation.ip": "Skráðu ákjósanlega IP tölu", + "error.validation.less": "Skráðu gildi lægra en {max}", + "error.validation.match": "Gildið er ekki eftir væntingum", + "error.validation.max": "Skráðu gildi sem er ekki hærra en {max}", + "error.validation.maxlength": "Veldu eitthvað styttra. (hámark {max} stafir)", + "error.validation.maxwords": "Ekki skrá fleiri en {max}. orð", + "error.validation.min": "Skráðu gildi ekki lægra en {min}", + "error.validation.minlength": "Hafðu þetta lengra en {min}. stafi", + "error.validation.minwords": "Lágmark {min}. orð", + "error.validation.more": "Eitthvað hærra en {min}", + "error.validation.notcontains": "Skráðu eitthvað sem inniheldur ekki \"{needle}\"", + "error.validation.notin": "Ekki skrá neitt af þessu: ({notIn})", + "error.validation.option": "Veldu ákjósanlegan kost", + "error.validation.num": "Notaðu tölugildi", + "error.validation.required": "Skráðu eitthvað", + "error.validation.same": "Skráðu \"{other}\"", + "error.validation.size": "Gildið þarf að vera \"{size}\"", + "error.validation.startswith": "Þetta þarf að byrja á \"{start}\"", + "error.validation.time": "Ákjósanlegur tími", + "error.validation.time.after": "Veldu tíma eftir {time}", + "error.validation.time.before": "Veldu tíma fyrir{time}", + "error.validation.time.between": "Veldu tíma milli {min} og {max}", + "error.validation.url": "Ákjósanleg vefslóð", + + "expand": "Þenja út", + "expand.all": "Þenja allt út", + + "field.required": "Þetta svið er nauðsynlegt", + "field.blocks.changeType": "Breyta um bálkagerð", + "field.blocks.code.name": "Kóði", + "field.blocks.code.language": "Tungumal", + "field.blocks.code.placeholder": "Kóðinn þinn …", + "field.blocks.delete.confirm": "Ætlarðu virkilega að eyða þessum bálk?", + "field.blocks.delete.confirm.all": "Ertu nú alveg viss um að þú viljir eyða öllum þessum bálkum?", + "field.blocks.delete.confirm.selected": "Viltu virkilega eyða völdum bálkum?", + "field.blocks.empty": "Öngvir bálkar enn", + "field.blocks.fieldsets.label": "Veldu bálkagerð …", + "field.blocks.fieldsets.paste": "Notaðu {{ shortcut }} flýtilyklaaðgerðina til að setja blokkina hér.", + "field.blocks.gallery.name": "Myndasafn", + "field.blocks.gallery.images.empty": "Engar myndir enn", + "field.blocks.gallery.images.label": "Myndir", + "field.blocks.heading.level": "Stig", + "field.blocks.heading.name": "Fyrirsögn", + "field.blocks.heading.text": "Texti/Prósi", + "field.blocks.heading.placeholder": "Fyrirsögn …", + "field.blocks.image.alt": "ALT texti", + "field.blocks.image.caption": "Myndartexti", + "field.blocks.image.crop": "Kroppa", + "field.blocks.image.link": "Tengill", + "field.blocks.image.location": "Staðsetning", + "field.blocks.image.name": "Mynd", + "field.blocks.image.placeholder": "Veldu mynd", + "field.blocks.image.ratio": "Hlutfall", + "field.blocks.image.url": "Slóð myndar", + "field.blocks.line.name": "Lína", + "field.blocks.list.name": "Listi", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Texti", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Tilvitnun", + "field.blocks.quote.text.label": "Innihald tilvitnunar", + "field.blocks.quote.text.placeholder": "Þessi tilvitnun …", + "field.blocks.quote.citation.label": "Heimild", + "field.blocks.quote.citation.placeholder": "eftir …", + "field.blocks.text.name": "Prósi", + "field.blocks.text.placeholder": "Þessi prósi …", + "field.blocks.video.caption": "Myndskeiðstexti", + "field.blocks.video.name": "Myndskeið", + "field.blocks.video.placeholder": "Vefslóð myndskeiðs (URL)", + "field.blocks.video.url.label": "Vefslóð", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Engar skrár valdar ennþá", + + "field.layout.delete": "Eyða ramma", + "field.layout.delete.confirm": "Ætlarðu virkilega að eyða þessum ramma?", + "field.layout.empty": "Nei. Engir rammar enn.", + "field.layout.select": "Veldu rammategund", + + "field.object.empty": "Engar upplýsingar enn", + + "field.pages.empty": "Engar síður valdar ennþá", + + "field.structure.delete.confirm": "Viltu virkilega eyða þessari röð?", + "field.structure.empty": "Engar færslur enn", + + "field.users.empty": "Engir notendur valdir enn", + + "file.blueprint": "Þessi skrá hefur ekki skipan (e. blueprint) ennþá. Þú mátt skilgreina skipanina í /site/blueprints/{template}.yml", + "file.delete.confirm": "Ætlarðu virkilega að eyða
{filename}?", + "file.sort": "Breyta röðun", + + "files": "Skrár", + "files.empty": "Engar skrár enn", + + "hide": "Fela", + "hour": "Klukkustund", + "import": "Hlaða inn", + "info": "Upplýsingar", + "insert": "Setja inn", + "insert.after": "Setja eftir", + "insert.before": "Setja fyrir", + "install": "Setja upp", + + "installation": "Uppsettning", + "installation.completed": "Panellinn er uppsettur", + "installation.disabled": "Paneluppsetning er sjálfgefið óvirk á vefþjónum á Veraldarvefnum. Reyndu frekar að setja Panelinn upp í lokuðu umhverfi eða virkjaðu panel.install möguleikan.", + "installation.issues.accounts": "/site/accounts mappan er annaðhvort ekki til eða er ekki skrifanleg.", + "installation.issues.content": "/content mappan er annaðhvort ekki til eða er ekki skrifanleg", + "installation.issues.curl": "CURL viðbótin er hér bráðnauðsynleg", + "installation.issues.headline": "Uppsetning Panelsins mistókst hrapalega", + "installation.issues.mbstring": "MB String er hér bráðnauðsynleg", + "installation.issues.media": "/media mappan er annaðhvort ekki til eða er ekki skrifanleg", + "installation.issues.php": "Notaðu PHP 7+", + "installation.issues.server": "Kirby krefst Apache, Nginx eða Caddy", + "installation.issues.sessions": "/site/sessions mappan er annaðhvort ekki til eða er ekki skrifanleg", + + "language": "Tungumál", + "language.code": "Kóði", + "language.convert": "Gera sjálfgefið", + "language.convert.confirm": "

Ertu viss um að þú viljir breyta {name} í sjálfgefið (lesist aðal) tungumál? Þessu verður ekki viðsnúið.

Ef {name} hefur innihald sem ekki hefur verið þýtt, þá verða engir möguleikar til þrautarvara og hluti vefsins gæti birtst tómur.

", + "language.create": "Bættu við nýju tungumáli", + "language.delete.confirm": "Ertu nú viss um að þú viljir eyða {name} og öllum tilheyrandi þýðingum? Þetta verður ekki tekið til baka!", + "language.deleted": "Tungumálinu hefur verið eytt", + "language.direction": "Lestursátt (hægri, vinstri)", + "language.direction.ltr": "Vinstra til hægri", + "language.direction.rtl": "Hægra til vinstri", + "language.locale": "PHP locale strengur", + "language.locale.warning": "Þú ert að nota sérsniðna locale uppsetningu. Vinsamlegast breyttu tungumálaskránni á slóðinni /site/languages", + "language.name": "Nafn tungumáls", + "language.updated": "Tungumálið hefur verið uppfært", + + "languages": "Tungumál", + "languages.default": "Aðal tungumál", + "languages.empty": "Það eru engin frekari tungumál skilgreind enn", + "languages.secondary": "Auka tungumál", + "languages.secondary.empty": "Það eru engin auka tungumál skilgreind enn", + + "license": "Leyfi", + "license.buy": "Kaupa leyfi", + "license.register": "Skr\u00E1 Kirby", + "license.manage": "Sýslaðu með leyfin þín", + "license.register.help": "Þú fékkst sendan tölvupóst með leyfiskóðanum þegar þú keyptir leyfi. Vinsamlegast afritaðu hann og settu hann hingað til að skrá þig.", + "license.register.label": "Vinsamlegast settu inn leyfiskóðan", + "license.register.success": "Þakka þér fyrir að velja Kirby", + "license.unregistered": "Þetta er óskráð prufueintak af Kirby", + "license.unregistered.label": "Óskráð", + + "link": "Tengill", + "link.text": "Tengilstexti", + + "loading": "Hleð", + + "lock.unsaved": "Óvistað breytingar", + "lock.unsaved.empty": "Það eru öngvar óvistaðar breytingar", + "lock.isLocked": "Óvistaðar breytingar frá {email}", + "lock.file.isLocked": "{email} er að vinna í skránni og þú breytir henni ekki á meðan.", + "lock.page.isLocked": "{email} er að vinna í síðunni og þú breytir henni ekki á meðan.", + "lock.unlock": "Aflæsa", + "lock.isUnlocked": "Þær breytingar sem þú gerðir hafa verið yfirskrifaðar af öðrum notanda. Þú getur sótt þær breytingar og splæst þeim saman við þínar breytingar. Handvirkt.", + + "login": "Innskrá", + "login.code.label.login": "Innskráningarkóði", + "login.code.label.password-reset": "Kóði fyrir endurstillingu lykilorðs", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "Ef netfangið þitt er skráð þá bíður þín nýr tölvupóstur.", + "login.email.login.body": "Já halló {user.nameOrEmail},\n\nNýlega baðstu um innskráningarkóða fyrir bakendan á {site}.\nEftirfarandi kóði er virkur í {timeout} mínútur:\n\n{code}\n\nEf þú óskaðir ekki eftir þessu þá hunsaðu þennan tölvupóst eða talaðu við vefstjóran ef þú vilt fræðast nánar.\nAf öryggisástæðum vinsamlegast áframsendu þennan tölvupóst ALLS EKKI.", + "login.email.login.subject": "Innskráningarkóðinn þinn", + "login.email.password-reset.body": "Nei halló {user.nameOrEmail},\n\nNýverið baðstu um að lykilorði þínu væri endurstillt fyrir bakendan á {site}. \nEftirfarandi kóði er virkur í {timeout} mínútur:\n\n{code}\n\nEf þú óskaðir ekki eftir þessu þá hunsaðu þennan tölvupóst eða talaðu við vefstjóran ef þú vilt fræðast nánar.\nAf öryggisástæðum vinsamlegast áframsendu þennan tölvupóst ALLS EKKI.", + "login.email.password-reset.subject": "Kóðinn þinn fyrir endurstillingu lykilorðs", + "login.remember": "Vista innskráningu", + "login.reset": "Endurheimta lykilorð takk", + "login.toggleText.code.email": "Innskrá með netfangi", + "login.toggleText.code.email-password": "Innskrá með lykilorði", + "login.toggleText.password-reset.email": "Mannstu ekki lykilorðið?", + "login.toggleText.password-reset.email-password": "← Aftur í innskráningu", + + "logout": "Útskrá", + + "menu": "Valmynd", + "meridiem": "AM/PM", + "mime": "Miðilsgerð", + "minutes": "Mínútur", + + "month": "Mánuður", + "months.april": "Apríl", + "months.august": "Ágúst", + "months.december": "Desember", + "months.february": "Febrúar", + "months.january": "Janúar", + "months.july": "Júlí", + "months.june": "Júní", + "months.march": "Mars", + "months.may": "Maí", + "months.november": "Nóvember", + "months.october": "Október", + "months.september": "September", + + "more": "Meira", + "name": "Nafn", + "next": "Næst", + "no": "nei", + "off": "Af", + "on": "Á", + "open": "Opna", + "open.newWindow": "Opna í nýjum glugga", + "options": "Valmöguleikar", + "options.none": "Engir valmöguleikar", + + "orientation": "Snúningur", + "orientation.landscape": "Langsnið", + "orientation.portrait": "Skammsnið", + "orientation.square": "Ferningur", + + "page.blueprint": "Þessi síða hefur ekki skipan (e. blueprint) ennþá. Þú mátt skilgreina skipanina í /site/blueprints/{template}.yml", + "page.changeSlug": "Breyta vefslóð", + "page.changeSlug.fromTitle": "Slóð af titli", + "page.changeStatus": "Breyta stöðu", + "page.changeStatus.position": "Veldu ákjósanlega röðun", + "page.changeStatus.select": "Veldu nýja stöðu", + "page.changeTemplate": "Breyta sniðmáti", + "page.delete.confirm": "Viltu virkilega farga {title}?", + "page.delete.confirm.subpages": "Þessi síða hefur undirsíður.
Þeim mun verða fargað líka.", + "page.delete.confirm.title": "Skráðu síðutitilinn til staðfestingar", + "page.draft.create": "Stofna uppkast", + "page.duplicate.appendix": "Afrita", + "page.duplicate.files": "Afrita skrár", + "page.duplicate.pages": "Afrita síður", + "page.sort": "Breyta röðun", + "page.status": "Staða", + "page.status.draft": "Uppkast", + "page.status.draft.description": "Þessi síða er uppkast og er aðeins sýnileg vefstjórum eða gegnum laumu tengil.", + "page.status.listed": "Útgefin og listuð", + "page.status.listed.description": "Síðan er útgefin og listuð.", + "page.status.unlisted": "Útgefin", + "page.status.unlisted.description": "Síðan er útgefin en þó ólistuð.", + + "pages": "Síður", + "pages.empty": "Engar síður enn", + "pages.status.draft": "Uppköst", + "pages.status.listed": "Útgefnar og listaðar", + "pages.status.unlisted": "Útgefnar", + + "pagination.page": "Síða", + + "password": "Lykilorð", + "paste": "Líma", + "paste.after": "Líma eftir", + "pixel": "Punkta", + "plugin": "Viðbót", + "plugins": "Viðbætur", + "prev": "Fyrri", + "preview": "Forskoða", + "remove": "Fjarlægja", + "rename": "Endurnefna", + "replace": "Setja í stað", + "retry": "Reyndu aftur", + "revert": "Taka upp fyrri siði", + "revert.confirm": "Viltu virkilega eyða öllum óvistuðum breytingum?", + + "role": "Hlutverk", + "role.admin.description": "Stjórinn hefur öll réttindi", + "role.admin.title": "Stjóri", + "role.all": "Öll", + "role.empty": "Það eru engir notendur með þetta hlutverk", + "role.description.placeholder": "Engin lýsing", + "role.nobody.description": "Þetta hlutverk er til þrautarvara en hefur engin réttindi", + "role.nobody.title": "Enginn", + + "save": "Vista", + "search": "Leita", + "search.min": "Lágmark {min} stafir til að leita", + "search.all": "Sýna allt", + "search.results.none": "Engar niðurstöður", + + "section.required": "Þetta svæði er nauðsynlegt", + + "security": "Öryggi", + "select": "Velja", + "server": "Vefþjónn", + "settings": "Stillingar", + "show": "Sýna", + "site.blueprint": "Þessi vefur hefur ekki skipan (e. blueprint) ennþá. Þú mátt skilgreina skipanina í /site/blueprints/site.yml", + "size": "Stærð", + "slug": "Slögg", + "sort": "Raða", + + "stats.empty": "Engar skýrslur", + "system.issues.content": "Efnismappan virðist vera berskjölduð", + "system.issues.eol.kirby": "Uppsett Kirby eintak þitt hefur runnið sitt skeið á enda og mun ekki verða uppfært framar", + "system.issues.eol.plugin": "Uppsett eintak þitt af viðbótinni { plugin } hefur runnið sitt skeið á enda og mun ekki verða uppfærð framar", + "system.issues.debug": "Aflúsun ætti alltaf að vera óvrikt í útgefnum vef", + "system.issues.git": ".git mappan virðist vera berskjölduð", + "system.issues.https": "Við mælum harðlega með því að þú notir HTTPS fyrir öll þín vefsvæði", + "system.issues.kirby": "Kirby mappan virðist vera berskjölduð", + "system.issues.site": "Mappa vefsvæðisins virðist vera berskjölduð", + "system.issues.vulnerability.kirby": "Uppsetningin þín gæti verið berskjölduð gagnvart eftirfarandi veikleika: ({ severity } veikleikinn): { description }", + "system.issues.vulnerability.plugin": "Uppsetningin þín gæti verið berskjölduð gagnvart eftirfarandi veikleika í viðbótinni { plugin }: ({ severity } veikleikinn): { description }", + "system.updateStatus": "Uppfærslustaða", + "system.updateStatus.error": "Gat því miður ekki athugað með uppfærslur", + "system.updateStatus.not-vulnerable": "Engir þekktir veikleikar", + "system.updateStatus.security-update": "Ókeypis öryggisuppfærsla { version } fáanleg", + "system.updateStatus.security-upgrade": "Uppfærsla { version } með öryggisuppfærslum fáanleg", + "system.updateStatus.unreleased": "Óútgefin útgáfa", + "system.updateStatus.up-to-date": "Allt spikk og span", + "system.updateStatus.update": "Ókeypis uppfærsla { version } fáanleg", + "system.updateStatus.upgrade": "Uppfærsla fyrir { version } fáanleg", + + "title": "Titill", + "template": "Sniðmát", + "today": "Núna", + + "toolbar.button.code": "Kóðasnið", + "toolbar.button.bold": "Feitletrun", + "toolbar.button.email": "Netfang", + "toolbar.button.headings": "Fyrirsagnir", + "toolbar.button.heading.1": "Fyrirsögn 1", + "toolbar.button.heading.2": "Fyrirsögn 2", + "toolbar.button.heading.3": "Fyrirsögn 3", + "toolbar.button.heading.4": "Fyrirsögn 4", + "toolbar.button.heading.5": "Fyrirsögn 5", + "toolbar.button.heading.6": "Fyrirsögn 6", + "toolbar.button.italic": "Skáletrun", + "toolbar.button.file": "Skrár", + "toolbar.button.file.select": "Veldu skrá", + "toolbar.button.file.upload": "Hlaða inn skrá", + "toolbar.button.link": "Tengill", + "toolbar.button.paragraph": "Efnisgrein", + "toolbar.button.strike": "Gegnumstrika", + "toolbar.button.ol": "Raðaður listi", + "toolbar.button.underline": "Undirstrika", + "toolbar.button.ul": "Áherslumerktur listi", + + "translation.author": "Kirby Teymið", + "translation.direction": "ltr", + "translation.name": "Íslenska", + "translation.locale": "is_IS", + + "upload": "Hlaða inn", + "upload.error.cantMove": "Innhlöðnu skránni var ekki haggað", + "upload.error.cantWrite": "Það mistókst að skrifa skránna í geymslu", + "upload.error.default": "Ekki heppnaðist að hlaða inn skránni", + "upload.error.extension": "Innhleðsla stöðvuð vegna skrárendingar", + "upload.error.formSize": "Innhlaðna skráin er stærri en MAX_FILE_SIZE leyfilegt er.", + "upload.error.iniPostSize": "Innhlaðna skráin er stærri en því sem nemur í post_max_size stillingunni í php.ini", + "upload.error.iniSize": "Innhlaðna skráin er stærri en því sem nemur í upload_max_filesize stillingunni í php.ini", + "upload.error.noFile": "Engri skrá far hlaðið inn", + "upload.error.noFiles": "Engum skrám var hlaðið inn", + "upload.error.partial": "Innhlöðnu skránni var aðeins sótt að hluta", + "upload.error.tmpDir": "Vantar skruggumöppu", + "upload.errors": "Villa", + "upload.progress": "Hleð inn…", + + "url": "Slóð", + "url.placeholder": "https://tildaem.is/", + + "user": "Notandi", + "user.blueprint": "Þér er óhætt að skilgreina fleiri svæði fyrir þetta notenda hlutverk í /site/blueprints/users/{role}.yml", + "user.changeEmail": "Breyta netfangi", + "user.changeLanguage": "Breyta tungumáli", + "user.changeName": "Endurnefna þennan notanda", + "user.changePassword": "Breyta lykilorð", + "user.changePassword.new": "Nýtt lykilorð", + "user.changePassword.new.confirm": "Staðfestu nýtt lykilorð…", + "user.changeRole": "Breyta hlutverki", + "user.changeRole.select": "Veldu nýtt hlutverk", + "user.create": "Bæta við nýjum notenda", + "user.delete": "Farga þessum notenda", + "user.delete.confirm": "Viltu virkilega eyða
{email}?", + + "users": "Notendur", + + "version": "Útgáfa", + "version.current": "Núverandi útgáfa", + "version.latest": "Nýjasta útgáfa", + "versionInformation": "Útgáfuupplýsingar", + + "view.account": "Notandareikningurinn þinn", + "view.installation": "Uppsetning", + "view.languages": "Tungumál", + "view.resetPassword": "Endurstilla lykilorð", + "view.site": "Vefsvæðið", + "view.system": "Kerfi", + "view.users": "Notendur", + + "welcome": "Komið þér fagnandi", + "year": "Ár", + "yes": "já" } diff --git a/kirby/i18n/translations/it.json b/kirby/i18n/translations/it.json index 60151cb..a58b22c 100644 --- a/kirby/i18n/translations/it.json +++ b/kirby/i18n/translations/it.json @@ -1,573 +1,596 @@ { - "account.changeName": "Cambia il tuo nome", - "account.delete": "Elimina l'account", - "account.delete.confirm": "Vuoi davvero eliminare il tuo account? Verrai disconnesso immediatamente. Il tuo account non potrà essere recuperato.", - - "add": "Aggiungi", - "author": "Autore", - "avatar": "Immagine del profilo", - "back": "Indietro", - "cancel": "Annulla", - "change": "Cambia", - "close": "Chiudi", - "confirm": "OK", - "collapse": "Comprimi", - "collapse.all": "Comprimi tutto", - "copy": "Copia", - "copy.all": "Copia tutto", - "create": "Crea", - - "date": "Data", - "date.select": "Scegli una data", - - "day": "Giorno", - "days.fri": "Ve", - "days.mon": "Lu", - "days.sat": "Sa", - "days.sun": "Do", - "days.thu": "Gi", - "days.tue": "Ma", - "days.wed": "Me", - - "debugging": "Debugging", - - "delete": "Elimina", - "delete.all": "Elimina tutti", - - "dialog.files.empty": "Nessun file selezionabile", - "dialog.pages.empty": "Nessuna pagina selezionabile", - "dialog.users.empty": "Nessuno user selezionabile", - - "dimensions": "Dimensioni", - "disabled": "Disabilitato", - "discard": "Abbandona", - "download": "Scarica", - "duplicate": "Duplica", - - "edit": "Modifica", - - "email": "Email", - "email.placeholder": "mail@esempio.com", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Ambiente", - - "error.access.code": "Codice non valido", - "error.access.login": "Login Invalido", - "error.access.panel": "Non ti è permesso accedere al pannello", - "error.access.view": "Non ti è permesso accedere a questa parte del pannello", - - "error.avatar.create.fail": "Non è stato possibile caricare l'immagine del profilo", - "error.avatar.delete.fail": "Non è stato possibile eliminare l'immagine del profilo", - "error.avatar.dimensions.invalid": "Per favore mantieni l'altezza e la larghezza dell'immagine del profilo inferiore ai 3000 pixel", - "error.avatar.mime.forbidden": "L'immagine del profilo dev'essere un file JPEG o PNG", - - "error.blueprint.notFound": "Non è stato possibile caricare il blueprint \"{name}\"", - - "error.blocks.max.plural": "Non puoi aggiungere più di {max} blocchi", - "error.blocks.max.singular": "Non puoi aggiungere più di un blocco", - "error.blocks.min.plural": "Devi aggiungere almeno {min} blocchi", - "error.blocks.min.singular": "Devi aggiungere almeno un blocco", - "error.blocks.validation": "C'è un errore nel blocco {index}", - - "error.email.preset.notFound": "Non è stato possibile trovare il preset email \"{name}\"", - - "error.field.converter.invalid": "Convertitore \"{converter}\" non valido", - - "error.file.changeName.empty": "Il nome non dev'essere vuoto", - "error.file.changeName.permission": "Non ti è permesso modificare il nome di \"{filename}\"", - "error.file.duplicate": "Un file con il nome \"{filename}\" esiste già", - "error.file.extension.forbidden": "L'estensione \"{extension}\" non è consentita", - "error.file.extension.invalid": "Estensione non valida: {extension}", - "error.file.extension.missing": "Il file \"{filename}\" non ha estensione", - "error.file.maxheight": "L'immagine non dev'essere più alta di {height} pixel", - "error.file.maxsize": "Il file è troppo pesante", - "error.file.maxwidth": "L'immagine non dev'essere più larga di {width} pixel", - "error.file.mime.differs": "Il file caricato dev'essere dello stesso MIME type \"{mime}\"", - "error.file.mime.forbidden": "Il MIME type \"{mime}\" non è consentito", - "error.file.mime.invalid": "Tipo mime non valido: {mime}", - "error.file.mime.missing": "Il MIME type per \"{filename}\" non può essere rilevato", - "error.file.minheight": "L'immagine dev'essere alta almeno {height} pixel", - "error.file.minsize": "Il file è troppo leggero", - "error.file.minwidth": "L'immagine dev'essere larga almeno {width} pixel", - "error.file.name.missing": "Il nome del file non può essere vuoto", - "error.file.notFound": "Il file non \u00e8 stato trovato", - "error.file.orientation": "L'imaggine dev'essere orientata in \"{orientation}\"", - "error.file.type.forbidden": "Non ti è permesso caricare file {type}", - "error.file.type.invalid": "Tipo di file non valido: {type}", - "error.file.undefined": "Il file non \u00e8 stato trovato", - - "error.form.incomplete": "Correggi tutti gli errori nel form...", - "error.form.notSaved": "Non è stato possibile salvare il form", - - "error.language.code": "Inserisci un codice valido per la lingua", - "error.language.duplicate": "La lingua esiste già", - "error.language.name": "Inserisci un nome valido per la lingua", - "error.language.notFound": "La lingua non è stata trovata", - - "error.layout.validation.block": "C'è un errore nel blocco {blockIndex} nel layout {layoutIndex}", - "error.layout.validation.settings": "C'è un errore nelle impostazioni del layout {index}", - - "error.license.format": "Inserisci un codice di licenza valido", - "error.license.email": "Inserisci un indirizzo email valido", - "error.license.verification": "Non è stato possibile verificare la licenza", - - "error.offline": "Il pannello di controllo è attualmente offline", - - "error.page.changeSlug.permission": "Non ti è permesso cambiare l'URL di \"{slug}\"", - "error.page.changeStatus.incomplete": "La pagina contiene errori e non può essere pubblicata", - "error.page.changeStatus.permission": "Lo stato di questa pagina non può essere cambiato", - "error.page.changeStatus.toDraft.invalid": "La pagina \"{slug}\" non può essere convertita in bozza", - "error.page.changeTemplate.invalid": "Il template della pagina \"{slug}\" non può essere cambiato", - "error.page.changeTemplate.permission": "Non ti è permesso modificare il template di \"{slug}\"", - "error.page.changeTitle.empty": "Il titolo non può essere vuoto", - "error.page.changeTitle.permission": "Non ti è permesso modificare il titolo di \"{slug}\"", - "error.page.create.permission": "Non ti è permesso creare \"{slug}\"", - "error.page.delete": "La pagina \"{slug}\" non può essere eliminata", - "error.page.delete.confirm": "Inserisci il titolo della pagina per confermare", - "error.page.delete.hasChildren": "La pagina ha sottopagine e non può essere eliminata", - "error.page.delete.permission": "Non ti è permesso eliminare \"{slug}\"", - "error.page.draft.duplicate": "Una bozza di pagina con l'URL \"{slug}\" esiste già", - "error.page.duplicate": "Una pagina con l'URL \"{slug}\" esiste già", - "error.page.duplicate.permission": "Non ti è permesso duplicare \"{slug}\"", - "error.page.notFound": "La pagina \"{slug}\" non è stata trovata", - "error.page.num.invalid": "Inserisci un numero di ordinamento valido. I numeri non devono essere negativi", - "error.page.slug.invalid": "Per favore inserisci un suffisso valido per l'URL", - "error.page.slug.maxlength": "Lo \"slug\" dev'essere più corto di \"{length}\" caratteri", - "error.page.sort.permission": "La pagina \"{slug}\" non può essere ordinata", - "error.page.status.invalid": "Imposta uno stato valido per la pagina", - "error.page.undefined": "La pagina non \u00e8 stata trovata", - "error.page.update.permission": "Non ti è permesso modificare \"{slug}\"", - - "error.section.files.max.plural": "Non puoi aggiungere più di {max} file alla sezione \"{section}\"", - "error.section.files.max.singular": "Non puoi aggiungere più di un file alla sezione \"{section}\"", - "error.section.files.min.plural": "La sezione \"{section}\" richiede almeno {min} file", - "error.section.files.min.singular": "La sezione \"{section}\" richiede almeno un file", - - "error.section.pages.max.plural": "Non puoi aggiungere più di {max} pagine alla sezione \"{section}\"", - "error.section.pages.max.singular": "Non puoi aggiungere più di una pagina alla sezione \"{section}\"", - "error.section.pages.min.plural": "La sezione \"{section}\" richiede almeno {min} pagine", - "error.section.pages.min.singular": "La sezione \"{section}\" richiede almeno una pagina", - - "error.section.notLoaded": "Non è stato possibile caricare la sezione \"{name}\"", - "error.section.type.invalid": "Il tipo di sezione \"{type}\" non è valido", - - "error.site.changeTitle.empty": "Il titolo non può essere vuoto", - "error.site.changeTitle.permission": "Non ti è permesso modificare il titolo del sito", - "error.site.update.permission": "Non ti è permesso modificare i contenuti globali del sito", - - "error.template.default.notFound": "Il template \"default\" non esiste", - - "error.unexpected": "Si è verificato un errore inaspettato! Abilita la modalità \"debug\" per ulteriori informazioni: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Non ti è permesso modificare l'indirizzo email di \"{name}\"", - "error.user.changeLanguage.permission": "Non ti è permesso modificare la lingua per l'utente \"{name}\"", - "error.user.changeName.permission": "Non ti è permesso modificare il nome dell'utente \"{name}\"", - "error.user.changePassword.permission": "Non ti è permesso modificare la password dell'utente \"{name}\"", - "error.user.changeRole.lastAdmin": "Il ruolo dell'ultimo amministratore non può esser cambiato", - "error.user.changeRole.permission": "Non ti è permesso modificare il ruolo dell'utente \"{name}\"", - "error.user.changeRole.toAdmin": "Non ti è permesso assegnare il ruolo di amministratore ad altri utenti", - "error.user.create.permission": "Non ti è permesso creare questo utente", - "error.user.delete": "L'utente non pu\u00f2 essere eliminato", - "error.user.delete.lastAdmin": "L'ultimo amministratore non può essere eliminato", - "error.user.delete.lastUser": "L'ultimo utente non può essere eliminato", - "error.user.delete.permission": "Non ti \u00e8 permesso eliminare questo utente ", - "error.user.duplicate": "Esiste già un utente con l'indirizzo email \"{email}\"", - "error.user.email.invalid": "Inserisci un indirizzo email valido", - "error.user.language.invalid": "Inserisci una lingua valida", - "error.user.notFound": "L'utente non \u00e8 stato trovato", - "error.user.password.invalid": "Per favore inserisci una password valida. Le password devono essere lunghe almeno 8 caratteri", - "error.user.password.notSame": "Le password non corrispondono", - "error.user.password.undefined": "L'utente non ha una password", - "error.user.password.wrong": "Password sbagliata", - "error.user.role.invalid": "Inserisci un ruolo valido", - "error.user.undefined": "L'utente non è stato trovato", - "error.user.update.permission": "Non ti è permesso aggiornare l'utente \"{name}\"", - - "error.validation.accepted": "Per favore conferma", - "error.validation.alpha": "Puoi inserire solo caratteri tra a-z", - "error.validation.alphanum": "Puoi inserire solo caratteri tra a-z e numeri 0-9", - "error.validation.between": "Inserisci un valore tra \"{min}\" e \"{max}\"", - "error.validation.boolean": "Per favore conferma o nega", - "error.validation.contains": "Inserisci un valore che contiene \"{needle}\"", - "error.validation.date": "Inserisci una data valida", - "error.validation.date.after": "Inserisci una data dopo il {date}", - "error.validation.date.before": "Inserisci una data prima del {date}", - "error.validation.date.between": "Inserisci una data tra {min} e {max}", - "error.validation.denied": "Per favore nega", - "error.validation.different": "Il valore non dev'essere \"{other}\"", - "error.validation.email": "Inserisci un indirizzo email valido", - "error.validation.endswith": "Il valore non deve finire con \"{end}\"", - "error.validation.filename": "Inserisci un nome del file valido", - "error.validation.in": "Inserisci uno dei seguenti valori: ({in})", - "error.validation.integer": "Inserisci un numero intero", - "error.validation.ip": "Inserisci un indirizzo IP valido", - "error.validation.less": "Inserisci un valore inferiore a {max}", - "error.validation.match": "Il valore non corrisponde al pattern previsto", - "error.validation.max": "Inserisci un valore inferiore o uguale a {max}", - "error.validation.maxlength": "Inserisci un testo più corto. (max. {max} caratteri)", - "error.validation.maxwords": "Non inserire più di {max} parola/e", - "error.validation.min": "Inserisci un valore superiore o uguale a {min}", - "error.validation.minlength": "Inserisci un testo più lungo. (min. {min} caratteri)", - "error.validation.minwords": "Inserisci almeno {min} parola/e", - "error.validation.more": "Inserisci un valore superiore a {min}", - "error.validation.notcontains": "Inserisci un valore che non contenga \"{needle}\"", - "error.validation.notin": "Non inserire nessuno dei valori seguenti: ({notIn})", - "error.validation.option": "Seleziona un'opzione valida", - "error.validation.num": "Inserisci un numero valido", - "error.validation.required": "Inserisci qualcosa", - "error.validation.same": "Inserisci \"{other}\"", - "error.validation.size": "La dimensione del valore dev'essere \"{size}\"", - "error.validation.startswith": "Il valore deve iniziare con \"{start}\"", - "error.validation.time": "Inserisci un orario valido", - "error.validation.time.after": "Inserisci un orario dopo le {time}", - "error.validation.time.before": "Inserisci un orario prima delle {time}", - "error.validation.time.between": "Inserisci un orario tra le {min} e le {max}", - "error.validation.url": "Inserisci un URL valido", - - "expand": "Espandi", - "expand.all": "Espandi tutto", - - "field.required": "Il campo è obbligatorio", - "field.blocks.changeType": "Cambia tipo", - "field.blocks.code.name": "Codice", - "field.blocks.code.language": "Lingua", - "field.blocks.code.placeholder": "Il tuo codice …", - "field.blocks.delete.confirm": "Vuoi veramente eliminare questo blocco?", - "field.blocks.delete.confirm.all": "Vuoi veramente eliminare tutti i blocchi? ", - "field.blocks.delete.confirm.selected": "Vuoi veramente eliminare i blocchi selezionati?", - "field.blocks.empty": "Nessun blocco inserito", - "field.blocks.fieldsets.label": "Seleziona il tipo di blocco …", - "field.blocks.fieldsets.paste": "Premi {{ shortcut }} per incollare/importare i blocchi dagli appunti", - "field.blocks.gallery.name": "Galleria", - "field.blocks.gallery.images.empty": "Nessuna immagine inserita", - "field.blocks.gallery.images.label": "Immagini", - "field.blocks.heading.level": "Livello", - "field.blocks.heading.name": "Titolo", - "field.blocks.heading.text": "Testo", - "field.blocks.heading.placeholder": "Titolo …", - "field.blocks.image.alt": "Testo alternativo", - "field.blocks.image.caption": "Didascalia", - "field.blocks.image.crop": "Ritaglio", - "field.blocks.image.link": "Link", - "field.blocks.image.location": "Posizione", - "field.blocks.image.name": "Immagine", - "field.blocks.image.placeholder": "Seleziona un'immagine", - "field.blocks.image.ratio": "Rapporto", - "field.blocks.image.url": "URL immagine", - "field.blocks.line.name": "Linea", - "field.blocks.list.name": "Lista", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Testo", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Citazione", - "field.blocks.quote.text.label": "Testo", - "field.blocks.quote.text.placeholder": "Citazione …", - "field.blocks.quote.citation.label": "Fonte", - "field.blocks.quote.citation.placeholder": "di …", - "field.blocks.text.name": "Testo", - "field.blocks.text.placeholder": "Testo …", - "field.blocks.video.caption": "Didascalia", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Inserisci un URL di un video", - "field.blocks.video.url.label": "URL Video", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Nessun file selezionato", - - "field.layout.delete": "Elimina layout", - "field.layout.delete.confirm": "Vuoi veramente eliminare questo layout?", - "field.layout.empty": "Nessuna riga inserita", - "field.layout.select": "Scegli un layout", - - "field.pages.empty": "Nessuna pagina selezionata", - "field.structure.delete.confirm": "Vuoi veramente eliminare questo elemento?", - "field.structure.empty": "Non ci sono ancora elementi.", - "field.users.empty": "Nessun utente selezionato", - - "file.blueprint": "Questo file non ha ancora un blueprint. Puoi definire la sua configurazione in /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Sei sicuro di voler eliminare questo file?", - "file.sort": "Cambia posizione", - - "files": "Files", - "files.empty": "Nessun file caricato", - - "hide": "Nascondi", - "hour": "Ora", - "import": "Importa", - "info": "Info", - "insert": "Inserisci", - "insert.after": "Inserisci dopo", - "insert.before": "Inserisci prima", - "install": "Installa", - - "installation": "Installazione", - "installation.completed": "Il pannello è stato installato", - "installation.disabled": "L'installazione del pannello è disabilitata di default sui server pubblici. Esegui l'installazione in locale oppure abilitala usando l'opzione panel.install.", - "installation.issues.accounts": "/site/accounts non esiste o non dispone dei permessi di scrittura", - "installation.issues.content": "La cartella /content non esiste o non dispone dei permessi di scrittura", - "installation.issues.curl": "È necessaria l'estensione CURL", - "installation.issues.headline": "Il pannello non può esser installato", - "installation.issues.mbstring": "È necessaria l'estensione MB String", - "installation.issues.media": "La cartella /media non esiste o non dispone dei permessi di scrittura", - "installation.issues.php": "Assicurati di utilizzare PHP 7.1+", - "installation.issues.server": "Kirby necessita di Apache, Nginx o Caddy", - "installation.issues.sessions": "La cartella /site/sessionsnon esiste o non dispone dei permessi di scrittura", - - "language": "Lingua", - "language.code": "Codice", - "language.convert": "Imposta come predefinito", - "language.convert.confirm": "

Sei sicuro di voler convertire {name} nella lingua predefinita? Questa operazione non può essere annullata.

Se {name} non contiene tutte le traduzioni, non ci sarà più una versione alternativa valida e parti del sito potrebbero rimanere vuote.

", - "language.create": "Aggiungi una nuova lingua", - "language.delete.confirm": "Sei sicuro di voler eliminare la lingua {name} con tutte le traduzioni? Non sarà possibile annullare!", - "language.deleted": "La lingua è stata eliminata", - "language.direction": "Direzione di lettura", - "language.direction.ltr": "Sinistra a destra", - "language.direction.rtl": "Destra a sinistra", - "language.locale": "Stringa \"PHP locale\"", - "language.locale.warning": "Stai usando una impostazione personalizzata per il locale. Modificalo nel file della lingua situato in /site/languages", - "language.name": "Nome", - "language.updated": "La lingua è stata aggiornata", - - "languages": "Lingue", - "languages.default": "Lingua di default", - "languages.empty": "Non ci sono lingue impostate", - "languages.secondary": "Lingue secondarie", - "languages.secondary.empty": "Non ci sono lingue secondarie impostate", - - "license": "Licenza di Kirby", - "license.buy": "Acquista una licenza", - "license.register": "Registra", - "license.manage": "Manage your licenses", - "license.register.help": "Hai ricevuto il codice di licenza tramite email dopo l'acquisto. Per favore inseriscilo per registrare Kirby.", - "license.register.label": "Inserisci il codice di licenza", - "license.register.success": "Ti ringraziamo per aver supportato Kirby", - "license.unregistered": "Questa è una versione demo di Kirby non registrata", - "license.unregistered.label": "Unregistered", - - "link": "Link", - "link.text": "Testo del link", - - "loading": "Caricamento", - - "lock.unsaved": "Modifiche non salvate", - "lock.unsaved.empty": "Non ci sono altre modifiche non salvate", - "lock.isLocked": "Modifiche non salvate di {email}", - "lock.file.isLocked": "Il file viene attualmente modificato da {email} e non può essere cambiato.", - "lock.page.isLocked": "la pagina viene attualmente modificata da {email} e non può essere cambiata.", - "lock.unlock": "Sblocca", - "lock.isUnlocked": "Un altro utente ha sovrascritto le tue modifiche non salvate. Puoi scaricarle per recuperarle e quindi incorporarle manualmente. ", - - "login": "Accedi", - "login.code.label.login": "Codice di accesso", - "login.code.label.password-reset": "Codice per reimpostare la password", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "Qualora il tuo indirizzo email fosse registrato, il codice richiesto è stato inviato tramite email.", - "login.email.login.body": "Ciao {user.nameOrEmail},\n\nHai recentemente richiesto un codice di login per il pannello di controllo di {site}.\nIl seguente codice di login sarà valido per {timeout} minuti:\n\n{code}\n\nSe non hai richiesto un codice di login, per favore ignora questa mail o contatta il tuo amministratore in caso di domande.\nPer sicurezza, per favore NON inoltrare questa email.", - "login.email.login.subject": "Il tuo codice di accesso", - "login.email.password-reset.body": "Ciao {user.nameOrEmail},\n\nHai recentemente richiesto di resettare la password per il pannello di controllo di {site}.\nIl seguente codice di reset della password sarà valido per {timeout} minuti:\n\n{code}\n\nSe non hai richiesto di resettare la password per favore ignora questa email o contatta il tuo amministratore in caso di domande.\nPer sicurezza, per favore NON inoltrare questa email.", - "login.email.password-reset.subject": "Il tuo codice di reimpostazione della password", - "login.remember": "Resta collegato", - "login.reset": "Reimposta la password", - "login.toggleText.code.email": "Accedi tramite email", - "login.toggleText.code.email-password": "Accedi con la password", - "login.toggleText.password-reset.email": "Hai dimenticato la password?", - "login.toggleText.password-reset.email-password": "← Torna al login", - - "logout": "Esci", - - "menu": "Menu", - "meridiem": "AM/PM", - "mime": "MIME Type", - "minutes": "Minuti", - - "month": "Mese", - "months.april": "Aprile", - "months.august": "Agosto", - "months.december": "Dicembre", - "months.february": "Febbraio", - "months.january": "Gennaio", - "months.july": "Luglio", - "months.june": "Giugno", - "months.march": "Marzo", - "months.may": "Maggio", - "months.november": "Novembre", - "months.october": "Ottobre", - "months.september": "Settembre", - - "more": "Di più", - "name": "Nome", - "next": "Prossimo", - "no": "no", - "off": "off", - "on": "on", - "open": "Apri", - "open.newWindow": "Apri in una finestra nuova", - "options": "Opzioni", - "options.none": "Nessuna opzione", - - "orientation": "Orientamento", - "orientation.landscape": "Orizzontale", - "orientation.portrait": "Verticale", - "orientation.square": "Quadrato", - - "page.blueprint": "Questa pagina non ha ancora un blueprint. Puoi definire la sua configurazione in /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Modifica URL", - "page.changeSlug.fromTitle": "Crea in base al titolo", - "page.changeStatus": "Cambia stato", - "page.changeStatus.position": "Scegli una posizione", - "page.changeStatus.select": "Seleziona un nuovo stato", - "page.changeTemplate": "Cambia template", - "page.delete.confirm": "Sei sicuro di voler eliminare questa pagina?", - "page.delete.confirm.subpages": "Questa pagina ha sottopagine.
Anche tutte le sottopagine verranno eliminate.", - "page.delete.confirm.title": "Inserisci il titolo della pagina per confermare", - "page.draft.create": "Crea bozza", - "page.duplicate.appendix": "Copia", - "page.duplicate.files": "Copia file", - "page.duplicate.pages": "Copia pagine", - "page.sort": "Cambia posizione", - "page.status": "Stato", - "page.status.draft": "Bozza", - "page.status.draft.description": "Questa pagina è una bozza ed è visibile soltanto agli utenti registrati o tramite link segreto", - "page.status.listed": "Pubblico", - "page.status.listed.description": "La pagina è pubblicata per tutti", - "page.status.unlisted": "Non in elenco", - "page.status.unlisted.description": "La pagina è accessibile soltanto tramite URL", - - "pages": "Pagine", - "pages.empty": "Nessuna pagina", - "pages.status.draft": "Bozza", - "pages.status.listed": "Pubblicato", - "pages.status.unlisted": "Non in elenco", - - "pagination.page": "Pagina", - - "password": "Password", - "paste": "Incolla", - "paste.after": "Incolla dopo", - "pixel": "Pixel", - "plugins": "Plugins", - "prev": "Precedente", - "preview": "Anteprima", - "remove": "Rimuovi", - "rename": "Rinomina", - "replace": "Sostituisci", - "retry": "Riprova", - "revert": "Abbandona", - "revert.confirm": "Sei sicuro di voler cancellare tutte le modifiche non salvate?", - - "role": "Ruolo", - "role.admin.description": "L'amministratore ha tutti i permessi", - "role.admin.title": "Amministratore", - "role.all": "Tutti", - "role.empty": "Non ci sono utenti con questo ruolo", - "role.description.placeholder": "Nessuna descrizione", - "role.nobody.description": "Questo è un ruolo \"fallback\" senza permessi", - "role.nobody.title": "Nessuno", - - "save": "Salva", - "search": "Cerca", - "search.min": "Inserisci almeno {min} caratteri per la ricerca", - "search.all": "Mostra tutti", - "search.results.none": "Nessun risultato", - - "section.required": "La sezione è obbligatoria", - - "security": "Security", - "select": "Seleziona", - "server": "Server", - "settings": "Impostazioni", - "show": "Mostra", - "site.blueprint": "Il sito non ha ancora un \"blueprint\". Puoi impostarne uno in /site/blueprints/site.yml", - "size": "Dimensioni", - "slug": "URL", - "sort": "Ordina", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Titolo", - "template": "Template", - "today": "Oggi", - - "toolbar.button.code": "Codice", - "toolbar.button.bold": "Grassetto", - "toolbar.button.email": "Email", - "toolbar.button.headings": "Titoli", - "toolbar.button.heading.1": "Titolo 1", - "toolbar.button.heading.2": "Titolo 2", - "toolbar.button.heading.3": "Titolo 3", - "toolbar.button.heading.4": "Titolo 4", - "toolbar.button.heading.5": "Titolo 5", - "toolbar.button.heading.6": "Titolo 6", - "toolbar.button.italic": "Corsivo", - "toolbar.button.file": "File", - "toolbar.button.file.select": "Seleziona un file", - "toolbar.button.file.upload": "Carica un file", - "toolbar.button.link": "Link", - "toolbar.button.paragraph": "Paragrafo", - "toolbar.button.strike": "Barrato", - "toolbar.button.ol": "Elenco numerato", - "toolbar.button.underline": "Sottolinea", - "toolbar.button.ul": "Elenco puntato", - - "translation.author": "Kirby Team, Roman Steiner, Manu Moreale", - "translation.direction": "ltr", - "translation.name": "Italiano", - "translation.locale": "it_IT", - - "upload": "Carica", - "upload.error.cantMove": "Non è stato possibile spostare il file caricato", - "upload.error.cantWrite": "Impossibile scrivere il file su disco", - "upload.error.default": "Impossibile caricare il file", - "upload.error.extension": "Caricamento del file interrotto per via dell'estensione", - "upload.error.formSize": "La dimensione del file caricato supera la direttiva MAX_FILE_SIZE specificata nel form", - "upload.error.iniPostSize": "La dimensione del file caricato supera la direttiva post_max_size specificata in php.ini", - "upload.error.iniSize": "La dimensione del file caricato supera la direttiva upload_max_filesize specificata in php.ini", - "upload.error.noFile": "Il file non è stato caricato", - "upload.error.noFiles": "Nessun file è stato caricato", - "upload.error.partial": "Il file è stato caricato solo parzialmente", - "upload.error.tmpDir": "Manca la cartella temporanea", - "upload.errors": "Errore", - "upload.progress": "Caricamento...", - - "url": "URL", - "url.placeholder": "https://esempio.com", - - "user": "Utente", - "user.blueprint": "Puoi definire ulteriori sezioni e campi del form aggiuntivi per questo ruolo in /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Modifica email", - "user.changeLanguage": "Cambia lingua", - "user.changeName": "Rinomina questo utente", - "user.changePassword": "Cambia password", - "user.changePassword.new": "Nuova password", - "user.changePassword.new.confirm": "Conferma la nuova password...", - "user.changeRole": "Cambia ruolo", - "user.changeRole.select": "Seleziona un nuovo ruolo", - "user.create": "Aggiungi nuovo utente", - "user.delete": "Elimina questo utente", - "user.delete.confirm": "Sei sicuro di voler eliminare l'utente
{email}?", - - "users": "Utenti", - - "version": "Versione di Kirby", - - "view.account": "Il tuo account", - "view.installation": "Installazione", - "view.languages": "Lingue", - "view.resetPassword": "Reimposta la password", - "view.site": "Sito", - "view.system": "Sistema", - "view.users": "Utenti", - - "welcome": "Benvenuto", - "year": "Anno", - "yes": "sì" + "account.changeName": "Cambia il tuo nome", + "account.delete": "Elimina l'account", + "account.delete.confirm": "Vuoi davvero eliminare il tuo account? Verrai disconnesso immediatamente. Il tuo account non potrà essere recuperato.", + + "add": "Aggiungi", + "author": "Autore", + "avatar": "Immagine del profilo", + "back": "Indietro", + "cancel": "Annulla", + "change": "Cambia", + "close": "Chiudi", + "confirm": "OK", + "collapse": "Comprimi", + "collapse.all": "Comprimi tutto", + "copy": "Copia", + "copy.all": "Copia tutto", + "create": "Crea", + + "date": "Data", + "date.select": "Scegli una data", + + "day": "Giorno", + "days.fri": "Ve", + "days.mon": "Lu", + "days.sat": "Sa", + "days.sun": "Do", + "days.thu": "Gi", + "days.tue": "Ma", + "days.wed": "Me", + + "debugging": "Debugging", + + "delete": "Elimina", + "delete.all": "Elimina tutti", + + "dialog.files.empty": "Nessun file selezionabile", + "dialog.pages.empty": "Nessuna pagina selezionabile", + "dialog.users.empty": "Nessuno user selezionabile", + + "dimensions": "Dimensioni", + "disabled": "Disabilitato", + "discard": "Abbandona", + "download": "Scarica", + "duplicate": "Duplica", + + "edit": "Modifica", + + "email": "Email", + "email.placeholder": "mail@esempio.com", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Ambiente", + + "error.access.code": "Codice non valido", + "error.access.login": "Login Invalido", + "error.access.panel": "Non ti è permesso accedere al pannello", + "error.access.view": "Non ti è permesso accedere a questa parte del pannello", + + "error.avatar.create.fail": "Non è stato possibile caricare l'immagine del profilo", + "error.avatar.delete.fail": "Non è stato possibile eliminare l'immagine del profilo", + "error.avatar.dimensions.invalid": "Per favore mantieni l'altezza e la larghezza dell'immagine del profilo inferiore ai 3000 pixel", + "error.avatar.mime.forbidden": "L'immagine del profilo dev'essere un file JPEG o PNG", + + "error.blueprint.notFound": "Non è stato possibile caricare il blueprint \"{name}\"", + + "error.blocks.max.plural": "Non puoi aggiungere più di {max} blocchi", + "error.blocks.max.singular": "Non puoi aggiungere più di un blocco", + "error.blocks.min.plural": "Devi aggiungere almeno {min} blocchi", + "error.blocks.min.singular": "Devi aggiungere almeno un blocco", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "Non è stato possibile trovare il preset email \"{name}\"", + + "error.field.converter.invalid": "Convertitore \"{converter}\" non valido", + + "error.file.changeName.empty": "Il nome non dev'essere vuoto", + "error.file.changeName.permission": "Non ti è permesso modificare il nome di \"{filename}\"", + "error.file.duplicate": "Un file con il nome \"{filename}\" esiste già", + "error.file.extension.forbidden": "L'estensione \"{extension}\" non è consentita", + "error.file.extension.invalid": "Estensione non valida: {extension}", + "error.file.extension.missing": "Il file \"{filename}\" non ha estensione", + "error.file.maxheight": "L'immagine non dev'essere più alta di {height} pixel", + "error.file.maxsize": "Il file è troppo pesante", + "error.file.maxwidth": "L'immagine non dev'essere più larga di {width} pixel", + "error.file.mime.differs": "Il file caricato dev'essere dello stesso MIME type \"{mime}\"", + "error.file.mime.forbidden": "Il MIME type \"{mime}\" non è consentito", + "error.file.mime.invalid": "Tipo mime non valido: {mime}", + "error.file.mime.missing": "Il MIME type per \"{filename}\" non può essere rilevato", + "error.file.minheight": "L'immagine dev'essere alta almeno {height} pixel", + "error.file.minsize": "Il file è troppo leggero", + "error.file.minwidth": "L'immagine dev'essere larga almeno {width} pixel", + "error.file.name.missing": "Il nome del file non può essere vuoto", + "error.file.notFound": "Il file non \u00e8 stato trovato", + "error.file.orientation": "L'imaggine dev'essere orientata in \"{orientation}\"", + "error.file.type.forbidden": "Non ti è permesso caricare file {type}", + "error.file.type.invalid": "Tipo di file non valido: {type}", + "error.file.undefined": "Il file non \u00e8 stato trovato", + + "error.form.incomplete": "Correggi tutti gli errori nel form...", + "error.form.notSaved": "Non è stato possibile salvare il form", + + "error.language.code": "Inserisci un codice valido per la lingua", + "error.language.duplicate": "La lingua esiste già", + "error.language.name": "Inserisci un nome valido per la lingua", + "error.language.notFound": "La lingua non è stata trovata", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "C'è un errore nelle impostazioni del layout {index}", + + "error.license.format": "Inserisci un codice di licenza valido", + "error.license.email": "Inserisci un indirizzo email valido", + "error.license.verification": "Non è stato possibile verificare la licenza", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "Il pannello di controllo è attualmente offline", + + "error.page.changeSlug.permission": "Non ti è permesso cambiare l'URL di \"{slug}\"", + "error.page.changeStatus.incomplete": "La pagina contiene errori e non può essere pubblicata", + "error.page.changeStatus.permission": "Lo stato di questa pagina non può essere cambiato", + "error.page.changeStatus.toDraft.invalid": "La pagina \"{slug}\" non può essere convertita in bozza", + "error.page.changeTemplate.invalid": "Il template della pagina \"{slug}\" non può essere cambiato", + "error.page.changeTemplate.permission": "Non ti è permesso modificare il template di \"{slug}\"", + "error.page.changeTitle.empty": "Il titolo non può essere vuoto", + "error.page.changeTitle.permission": "Non ti è permesso modificare il titolo di \"{slug}\"", + "error.page.create.permission": "Non ti è permesso creare \"{slug}\"", + "error.page.delete": "La pagina \"{slug}\" non può essere eliminata", + "error.page.delete.confirm": "Inserisci il titolo della pagina per confermare", + "error.page.delete.hasChildren": "La pagina ha sottopagine e non può essere eliminata", + "error.page.delete.permission": "Non ti è permesso eliminare \"{slug}\"", + "error.page.draft.duplicate": "Una bozza di pagina con l'URL \"{slug}\" esiste già", + "error.page.duplicate": "Una pagina con l'URL \"{slug}\" esiste già", + "error.page.duplicate.permission": "Non ti è permesso duplicare \"{slug}\"", + "error.page.notFound": "La pagina \"{slug}\" non è stata trovata", + "error.page.num.invalid": "Inserisci un numero di ordinamento valido. I numeri non devono essere negativi", + "error.page.slug.invalid": "Per favore inserisci un suffisso valido per l'URL", + "error.page.slug.maxlength": "Lo \"slug\" dev'essere più corto di \"{length}\" caratteri", + "error.page.sort.permission": "La pagina \"{slug}\" non può essere ordinata", + "error.page.status.invalid": "Imposta uno stato valido per la pagina", + "error.page.undefined": "La pagina non \u00e8 stata trovata", + "error.page.update.permission": "Non ti è permesso modificare \"{slug}\"", + + "error.section.files.max.plural": "Non puoi aggiungere più di {max} file alla sezione \"{section}\"", + "error.section.files.max.singular": "Non puoi aggiungere più di un file alla sezione \"{section}\"", + "error.section.files.min.plural": "La sezione \"{section}\" richiede almeno {min} file", + "error.section.files.min.singular": "La sezione \"{section}\" richiede almeno un file", + + "error.section.pages.max.plural": "Non puoi aggiungere più di {max} pagine alla sezione \"{section}\"", + "error.section.pages.max.singular": "Non puoi aggiungere più di una pagina alla sezione \"{section}\"", + "error.section.pages.min.plural": "La sezione \"{section}\" richiede almeno {min} pagine", + "error.section.pages.min.singular": "La sezione \"{section}\" richiede almeno una pagina", + + "error.section.notLoaded": "Non è stato possibile caricare la sezione \"{name}\"", + "error.section.type.invalid": "Il tipo di sezione \"{type}\" non è valido", + + "error.site.changeTitle.empty": "Il titolo non può essere vuoto", + "error.site.changeTitle.permission": "Non ti è permesso modificare il titolo del sito", + "error.site.update.permission": "Non ti è permesso modificare i contenuti globali del sito", + + "error.template.default.notFound": "Il template \"default\" non esiste", + + "error.unexpected": "Si è verificato un errore inaspettato! Abilita la modalità \"debug\" per ulteriori informazioni: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Non ti è permesso modificare l'indirizzo email di \"{name}\"", + "error.user.changeLanguage.permission": "Non ti è permesso modificare la lingua per l'utente \"{name}\"", + "error.user.changeName.permission": "Non ti è permesso modificare il nome dell'utente \"{name}\"", + "error.user.changePassword.permission": "Non ti è permesso modificare la password dell'utente \"{name}\"", + "error.user.changeRole.lastAdmin": "Il ruolo dell'ultimo amministratore non può esser cambiato", + "error.user.changeRole.permission": "Non ti è permesso modificare il ruolo dell'utente \"{name}\"", + "error.user.changeRole.toAdmin": "Non ti è permesso assegnare il ruolo di amministratore ad altri utenti", + "error.user.create.permission": "Non ti è permesso creare questo utente", + "error.user.delete": "L'utente non pu\u00f2 essere eliminato", + "error.user.delete.lastAdmin": "L'ultimo amministratore non può essere eliminato", + "error.user.delete.lastUser": "L'ultimo utente non può essere eliminato", + "error.user.delete.permission": "Non ti \u00e8 permesso eliminare questo utente ", + "error.user.duplicate": "Esiste già un utente con l'indirizzo email \"{email}\"", + "error.user.email.invalid": "Inserisci un indirizzo email valido", + "error.user.language.invalid": "Inserisci una lingua valida", + "error.user.notFound": "L'utente non \u00e8 stato trovato", + "error.user.password.invalid": "Per favore inserisci una password valida. Le password devono essere lunghe almeno 8 caratteri", + "error.user.password.notSame": "Le password non corrispondono", + "error.user.password.undefined": "L'utente non ha una password", + "error.user.password.wrong": "Password sbagliata", + "error.user.role.invalid": "Inserisci un ruolo valido", + "error.user.undefined": "L'utente non è stato trovato", + "error.user.update.permission": "Non ti è permesso aggiornare l'utente \"{name}\"", + + "error.validation.accepted": "Per favore conferma", + "error.validation.alpha": "Puoi inserire solo caratteri tra a-z", + "error.validation.alphanum": "Puoi inserire solo caratteri tra a-z e numeri 0-9", + "error.validation.between": "Inserisci un valore tra \"{min}\" e \"{max}\"", + "error.validation.boolean": "Per favore conferma o nega", + "error.validation.contains": "Inserisci un valore che contiene \"{needle}\"", + "error.validation.date": "Inserisci una data valida", + "error.validation.date.after": "Inserisci una data dopo il {date}", + "error.validation.date.before": "Inserisci una data prima del {date}", + "error.validation.date.between": "Inserisci una data tra {min} e {max}", + "error.validation.denied": "Per favore nega", + "error.validation.different": "Il valore non dev'essere \"{other}\"", + "error.validation.email": "Inserisci un indirizzo email valido", + "error.validation.endswith": "Il valore non deve finire con \"{end}\"", + "error.validation.filename": "Inserisci un nome del file valido", + "error.validation.in": "Inserisci uno dei seguenti valori: ({in})", + "error.validation.integer": "Inserisci un numero intero", + "error.validation.ip": "Inserisci un indirizzo IP valido", + "error.validation.less": "Inserisci un valore inferiore a {max}", + "error.validation.match": "Il valore non corrisponde al pattern previsto", + "error.validation.max": "Inserisci un valore inferiore o uguale a {max}", + "error.validation.maxlength": "Inserisci un testo più corto. (max. {max} caratteri)", + "error.validation.maxwords": "Non inserire più di {max} parola/e", + "error.validation.min": "Inserisci un valore superiore o uguale a {min}", + "error.validation.minlength": "Inserisci un testo più lungo. (min. {min} caratteri)", + "error.validation.minwords": "Inserisci almeno {min} parola/e", + "error.validation.more": "Inserisci un valore superiore a {min}", + "error.validation.notcontains": "Inserisci un valore che non contenga \"{needle}\"", + "error.validation.notin": "Non inserire nessuno dei valori seguenti: ({notIn})", + "error.validation.option": "Seleziona un'opzione valida", + "error.validation.num": "Inserisci un numero valido", + "error.validation.required": "Inserisci qualcosa", + "error.validation.same": "Inserisci \"{other}\"", + "error.validation.size": "La dimensione del valore dev'essere \"{size}\"", + "error.validation.startswith": "Il valore deve iniziare con \"{start}\"", + "error.validation.time": "Inserisci un orario valido", + "error.validation.time.after": "Inserisci un orario dopo le {time}", + "error.validation.time.before": "Inserisci un orario prima delle {time}", + "error.validation.time.between": "Inserisci un orario tra le {min} e le {max}", + "error.validation.url": "Inserisci un URL valido", + + "expand": "Espandi", + "expand.all": "Espandi tutto", + + "field.required": "Il campo è obbligatorio", + "field.blocks.changeType": "Cambia tipo", + "field.blocks.code.name": "Codice", + "field.blocks.code.language": "Lingua", + "field.blocks.code.placeholder": "Il tuo codice …", + "field.blocks.delete.confirm": "Vuoi veramente eliminare questo blocco?", + "field.blocks.delete.confirm.all": "Vuoi veramente eliminare tutti i blocchi? ", + "field.blocks.delete.confirm.selected": "Vuoi veramente eliminare i blocchi selezionati?", + "field.blocks.empty": "Nessun blocco inserito", + "field.blocks.fieldsets.label": "Seleziona il tipo di blocco …", + "field.blocks.fieldsets.paste": "Premi {{ shortcut }} per incollare/importare i blocchi dagli appunti", + "field.blocks.gallery.name": "Galleria", + "field.blocks.gallery.images.empty": "Nessuna immagine inserita", + "field.blocks.gallery.images.label": "Immagini", + "field.blocks.heading.level": "Livello", + "field.blocks.heading.name": "Titolo", + "field.blocks.heading.text": "Testo", + "field.blocks.heading.placeholder": "Titolo …", + "field.blocks.image.alt": "Testo alternativo", + "field.blocks.image.caption": "Didascalia", + "field.blocks.image.crop": "Ritaglio", + "field.blocks.image.link": "Link", + "field.blocks.image.location": "Posizione", + "field.blocks.image.name": "Immagine", + "field.blocks.image.placeholder": "Seleziona un'immagine", + "field.blocks.image.ratio": "Rapporto", + "field.blocks.image.url": "URL immagine", + "field.blocks.line.name": "Linea", + "field.blocks.list.name": "Lista", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Testo", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Citazione", + "field.blocks.quote.text.label": "Testo", + "field.blocks.quote.text.placeholder": "Citazione …", + "field.blocks.quote.citation.label": "Fonte", + "field.blocks.quote.citation.placeholder": "di …", + "field.blocks.text.name": "Testo", + "field.blocks.text.placeholder": "Testo …", + "field.blocks.video.caption": "Didascalia", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Inserisci un URL di un video", + "field.blocks.video.url.label": "URL Video", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Nessun file selezionato", + + "field.layout.delete": "Elimina layout", + "field.layout.delete.confirm": "Vuoi veramente eliminare questo layout?", + "field.layout.empty": "Nessuna riga inserita", + "field.layout.select": "Scegli un layout", + + "field.object.empty": "No information yet", + + "field.pages.empty": "Nessuna pagina selezionata", + + "field.structure.delete.confirm": "Vuoi veramente eliminare questo elemento?", + "field.structure.empty": "Non ci sono ancora elementi.", + + "field.users.empty": "Nessun utente selezionato", + + "file.blueprint": "Questo file non ha ancora un blueprint. Puoi definire la sua configurazione in /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Sei sicuro di voler eliminare questo file?", + "file.sort": "Cambia posizione", + + "files": "Files", + "files.empty": "Nessun file caricato", + + "hide": "Nascondi", + "hour": "Ora", + "import": "Importa", + "info": "Info", + "insert": "Inserisci", + "insert.after": "Inserisci dopo", + "insert.before": "Inserisci prima", + "install": "Installa", + + "installation": "Installazione", + "installation.completed": "Il pannello è stato installato", + "installation.disabled": "L'installazione del pannello è disabilitata di default sui server pubblici. Esegui l'installazione in locale oppure abilitala usando l'opzione panel.install.", + "installation.issues.accounts": "/site/accounts non esiste o non dispone dei permessi di scrittura", + "installation.issues.content": "La cartella /content non esiste o non dispone dei permessi di scrittura", + "installation.issues.curl": "È necessaria l'estensione CURL", + "installation.issues.headline": "Il pannello non può esser installato", + "installation.issues.mbstring": "È necessaria l'estensione MB String", + "installation.issues.media": "La cartella /media non esiste o non dispone dei permessi di scrittura", + "installation.issues.php": "Assicurati di utilizzare PHP 7.1+", + "installation.issues.server": "Kirby necessita di Apache, Nginx o Caddy", + "installation.issues.sessions": "La cartella /site/sessionsnon esiste o non dispone dei permessi di scrittura", + + "language": "Lingua", + "language.code": "Codice", + "language.convert": "Imposta come predefinito", + "language.convert.confirm": "

Sei sicuro di voler convertire {name} nella lingua predefinita? Questa operazione non può essere annullata.

Se {name} non contiene tutte le traduzioni, non ci sarà più una versione alternativa valida e parti del sito potrebbero rimanere vuote.

", + "language.create": "Aggiungi una nuova lingua", + "language.delete.confirm": "Sei sicuro di voler eliminare la lingua {name} con tutte le traduzioni? Non sarà possibile annullare!", + "language.deleted": "La lingua è stata eliminata", + "language.direction": "Direzione di lettura", + "language.direction.ltr": "Sinistra a destra", + "language.direction.rtl": "Destra a sinistra", + "language.locale": "Stringa \"PHP locale\"", + "language.locale.warning": "Stai usando una impostazione personalizzata per il locale. Modificalo nel file della lingua situato in /site/languages", + "language.name": "Nome", + "language.updated": "La lingua è stata aggiornata", + + "languages": "Lingue", + "languages.default": "Lingua di default", + "languages.empty": "Non ci sono lingue impostate", + "languages.secondary": "Lingue secondarie", + "languages.secondary.empty": "Non ci sono lingue secondarie impostate", + + "license": "Licenza di Kirby", + "license.buy": "Acquista una licenza", + "license.register": "Registra", + "license.manage": "Manage your licenses", + "license.register.help": "Hai ricevuto il codice di licenza tramite email dopo l'acquisto. Per favore inseriscilo per registrare Kirby.", + "license.register.label": "Inserisci il codice di licenza", + "license.register.success": "Ti ringraziamo per aver supportato Kirby", + "license.unregistered": "Questa è una versione demo di Kirby non registrata", + "license.unregistered.label": "Unregistered", + + "link": "Link", + "link.text": "Testo del link", + + "loading": "Caricamento", + + "lock.unsaved": "Modifiche non salvate", + "lock.unsaved.empty": "Non ci sono altre modifiche non salvate", + "lock.isLocked": "Modifiche non salvate di {email}", + "lock.file.isLocked": "Il file viene attualmente modificato da {email} e non può essere cambiato.", + "lock.page.isLocked": "la pagina viene attualmente modificata da {email} e non può essere cambiata.", + "lock.unlock": "Sblocca", + "lock.isUnlocked": "Un altro utente ha sovrascritto le tue modifiche non salvate. Puoi scaricarle per recuperarle e quindi incorporarle manualmente. ", + + "login": "Accedi", + "login.code.label.login": "Codice di accesso", + "login.code.label.password-reset": "Codice per reimpostare la password", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "Qualora il tuo indirizzo email fosse registrato, il codice richiesto è stato inviato tramite email.", + "login.email.login.body": "Ciao {user.nameOrEmail},\n\nHai recentemente richiesto un codice di login per il pannello di controllo di {site}.\nIl seguente codice di login sarà valido per {timeout} minuti:\n\n{code}\n\nSe non hai richiesto un codice di login, per favore ignora questa mail o contatta il tuo amministratore in caso di domande.\nPer sicurezza, per favore NON inoltrare questa email.", + "login.email.login.subject": "Il tuo codice di accesso", + "login.email.password-reset.body": "Ciao {user.nameOrEmail},\n\nHai recentemente richiesto di resettare la password per il pannello di controllo di {site}.\nIl seguente codice di reset della password sarà valido per {timeout} minuti:\n\n{code}\n\nSe non hai richiesto di resettare la password per favore ignora questa email o contatta il tuo amministratore in caso di domande.\nPer sicurezza, per favore NON inoltrare questa email.", + "login.email.password-reset.subject": "Il tuo codice di reimpostazione della password", + "login.remember": "Resta collegato", + "login.reset": "Reimposta la password", + "login.toggleText.code.email": "Accedi tramite email", + "login.toggleText.code.email-password": "Accedi con la password", + "login.toggleText.password-reset.email": "Hai dimenticato la password?", + "login.toggleText.password-reset.email-password": "← Torna al login", + + "logout": "Esci", + + "menu": "Menu", + "meridiem": "AM/PM", + "mime": "MIME Type", + "minutes": "Minuti", + + "month": "Mese", + "months.april": "Aprile", + "months.august": "Agosto", + "months.december": "Dicembre", + "months.february": "Febbraio", + "months.january": "Gennaio", + "months.july": "Luglio", + "months.june": "Giugno", + "months.march": "Marzo", + "months.may": "Maggio", + "months.november": "Novembre", + "months.october": "Ottobre", + "months.september": "Settembre", + + "more": "Di più", + "name": "Nome", + "next": "Prossimo", + "no": "no", + "off": "off", + "on": "on", + "open": "Apri", + "open.newWindow": "Apri in una finestra nuova", + "options": "Opzioni", + "options.none": "Nessuna opzione", + + "orientation": "Orientamento", + "orientation.landscape": "Orizzontale", + "orientation.portrait": "Verticale", + "orientation.square": "Quadrato", + + "page.blueprint": "Questa pagina non ha ancora un blueprint. Puoi definire la sua configurazione in /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Modifica URL", + "page.changeSlug.fromTitle": "Crea in base al titolo", + "page.changeStatus": "Cambia stato", + "page.changeStatus.position": "Scegli una posizione", + "page.changeStatus.select": "Seleziona un nuovo stato", + "page.changeTemplate": "Cambia template", + "page.delete.confirm": "Sei sicuro di voler eliminare questa pagina?", + "page.delete.confirm.subpages": "Questa pagina ha sottopagine.
Anche tutte le sottopagine verranno eliminate.", + "page.delete.confirm.title": "Inserisci il titolo della pagina per confermare", + "page.draft.create": "Crea bozza", + "page.duplicate.appendix": "Copia", + "page.duplicate.files": "Copia file", + "page.duplicate.pages": "Copia pagine", + "page.sort": "Cambia posizione", + "page.status": "Stato", + "page.status.draft": "Bozza", + "page.status.draft.description": "Questa pagina è una bozza ed è visibile soltanto agli utenti registrati o tramite link segreto", + "page.status.listed": "Pubblico", + "page.status.listed.description": "La pagina è pubblicata per tutti", + "page.status.unlisted": "Non in elenco", + "page.status.unlisted.description": "La pagina è accessibile soltanto tramite URL", + + "pages": "Pagine", + "pages.empty": "Nessuna pagina", + "pages.status.draft": "Bozza", + "pages.status.listed": "Pubblicato", + "pages.status.unlisted": "Non in elenco", + + "pagination.page": "Pagina", + + "password": "Password", + "paste": "Incolla", + "paste.after": "Incolla dopo", + "pixel": "Pixel", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "Precedente", + "preview": "Anteprima", + "remove": "Rimuovi", + "rename": "Rinomina", + "replace": "Sostituisci", + "retry": "Riprova", + "revert": "Abbandona", + "revert.confirm": "Sei sicuro di voler cancellare tutte le modifiche non salvate?", + + "role": "Ruolo", + "role.admin.description": "L'amministratore ha tutti i permessi", + "role.admin.title": "Amministratore", + "role.all": "Tutti", + "role.empty": "Non ci sono utenti con questo ruolo", + "role.description.placeholder": "Nessuna descrizione", + "role.nobody.description": "Questo è un ruolo \"fallback\" senza permessi", + "role.nobody.title": "Nessuno", + + "save": "Salva", + "search": "Cerca", + "search.min": "Inserisci almeno {min} caratteri per la ricerca", + "search.all": "Mostra tutti", + "search.results.none": "Nessun risultato", + + "section.required": "La sezione è obbligatoria", + + "security": "Security", + "select": "Seleziona", + "server": "Server", + "settings": "Impostazioni", + "show": "Mostra", + "site.blueprint": "Il sito non ha ancora un \"blueprint\". Puoi impostarne uno in /site/blueprints/site.yml", + "size": "Dimensioni", + "slug": "URL", + "sort": "Ordina", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Titolo", + "template": "Template", + "today": "Oggi", + + "toolbar.button.code": "Codice", + "toolbar.button.bold": "Grassetto", + "toolbar.button.email": "Email", + "toolbar.button.headings": "Titoli", + "toolbar.button.heading.1": "Titolo 1", + "toolbar.button.heading.2": "Titolo 2", + "toolbar.button.heading.3": "Titolo 3", + "toolbar.button.heading.4": "Titolo 4", + "toolbar.button.heading.5": "Titolo 5", + "toolbar.button.heading.6": "Titolo 6", + "toolbar.button.italic": "Corsivo", + "toolbar.button.file": "File", + "toolbar.button.file.select": "Seleziona un file", + "toolbar.button.file.upload": "Carica un file", + "toolbar.button.link": "Link", + "toolbar.button.paragraph": "Paragrafo", + "toolbar.button.strike": "Barrato", + "toolbar.button.ol": "Elenco numerato", + "toolbar.button.underline": "Sottolinea", + "toolbar.button.ul": "Elenco puntato", + + "translation.author": "Kirby Team, Roman Steiner, Manu Moreale", + "translation.direction": "ltr", + "translation.name": "Italiano", + "translation.locale": "it_IT", + + "upload": "Carica", + "upload.error.cantMove": "Non è stato possibile spostare il file caricato", + "upload.error.cantWrite": "Impossibile scrivere il file su disco", + "upload.error.default": "Impossibile caricare il file", + "upload.error.extension": "Caricamento del file interrotto per via dell'estensione", + "upload.error.formSize": "La dimensione del file caricato supera la direttiva MAX_FILE_SIZE specificata nel form", + "upload.error.iniPostSize": "La dimensione del file caricato supera la direttiva post_max_size specificata in php.ini", + "upload.error.iniSize": "La dimensione del file caricato supera la direttiva upload_max_filesize specificata in php.ini", + "upload.error.noFile": "Il file non è stato caricato", + "upload.error.noFiles": "Nessun file è stato caricato", + "upload.error.partial": "Il file è stato caricato solo parzialmente", + "upload.error.tmpDir": "Manca la cartella temporanea", + "upload.errors": "Errore", + "upload.progress": "Caricamento...", + + "url": "URL", + "url.placeholder": "https://esempio.com", + + "user": "Utente", + "user.blueprint": "Puoi definire ulteriori sezioni e campi del form aggiuntivi per questo ruolo in /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Modifica email", + "user.changeLanguage": "Cambia lingua", + "user.changeName": "Rinomina questo utente", + "user.changePassword": "Cambia password", + "user.changePassword.new": "Nuova password", + "user.changePassword.new.confirm": "Conferma la nuova password...", + "user.changeRole": "Cambia ruolo", + "user.changeRole.select": "Seleziona un nuovo ruolo", + "user.create": "Aggiungi nuovo utente", + "user.delete": "Elimina questo utente", + "user.delete.confirm": "Sei sicuro di voler eliminare l'utente
{email}?", + + "users": "Utenti", + + "version": "Versione di Kirby", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "Il tuo account", + "view.installation": "Installazione", + "view.languages": "Lingue", + "view.resetPassword": "Reimposta la password", + "view.site": "Sito", + "view.system": "Sistema", + "view.users": "Utenti", + + "welcome": "Benvenuto", + "year": "Anno", + "yes": "sì" } diff --git a/kirby/i18n/translations/ko.json b/kirby/i18n/translations/ko.json index 3891554..6bdc0dd 100644 --- a/kirby/i18n/translations/ko.json +++ b/kirby/i18n/translations/ko.json @@ -1,573 +1,596 @@ { - "account.changeName": "이름 변경", - "account.delete": "계정 삭제", - "account.delete.confirm": "계정을 삭제할까요? 계정을 삭제한 뒤에는 복구할 수 없습니다.", - - "add": "\ucd94\uac00", - "author": "저자", - "avatar": "프로필 이미지", - "back": "뒤로", - "cancel": "\ucde8\uc18c", - "change": "\ubcc0\uacbd", - "close": "\ub2eb\uae30", - "confirm": "확인", - "collapse": "접기", - "collapse.all": "모두 접기", - "copy": "복사", - "copy.all": "모두 복사", - "create": "등록", - - "date": "날짜", - "date.select": "날짜 지정", - - "day": "일", - "days.fri": "\uae08", - "days.mon": "\uc6d4", - "days.sat": "\ud1a0", - "days.sun": "\uc77c", - "days.thu": "\ubaa9", - "days.tue": "\ud654", - "days.wed": "\uc218", - - "debugging": "디버그", - - "delete": "\uc0ad\uc81c", - "delete.all": "모두 삭제", - - "dialog.files.empty": "선택할 파일이 없습니다.", - "dialog.pages.empty": "선택할 페이지가 없습니다.", - "dialog.users.empty": "선택할 사용자가 없습니다.", - - "dimensions": "크기", - "disabled": "비활성화", - "discard": "무시", - "download": "다운로드", - "duplicate": "복제", - - "edit": "\ud3b8\uc9d1", - - "email": "\uc774\uba54\uc77c \uc8fc\uc18c", - "email.placeholder": "mail@example.com", - - "entries": "항목", - "entry": "항목", - - "environment": "구동 환경", - - "error.access.code": "코드가 올바르지 않습니다.", - "error.access.login": "로그인할 수 없습니다.", - "error.access.panel": "패널에 접근할 권한이 없습니다.", - "error.access.view": "패널에 접근할 권한이 없습니다.", - - "error.avatar.create.fail": "프로필 이미지를 업로드할 수 없습니다.", - "error.avatar.delete.fail": "\ud504\ub85c\ud544 \uc774\ubbf8\uc9c0\ub97c \uc0ad\uc81c\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.", - "error.avatar.dimensions.invalid": "프로필 이미지의 너비와 높이를 3,000픽셀 이하로 설정하세요.", - "error.avatar.mime.forbidden": "프로필 이미지의 확장자(JPG, JPEG, PNG)를 확인하세요.", - - "error.blueprint.notFound": "블루프린트({name})를 불러올 수 없습니다.", - - "error.blocks.max.plural": "블록을 {max}개 이상 추가할 수 없습니다.", - "error.blocks.max.singular": "블록을 하나 이상 추가할 수 없습니다.", - "error.blocks.min.plural": "블록을 {min}개 이상 추가하세요.", - "error.blocks.min.singular": "블록을 하나 이상 추가하세요.", - "error.blocks.validation": "블록({index})이 올바르지 않습니다.", - - "error.email.preset.notFound": "기본 이메일 주소({name})가 없습니다.", - - "error.field.converter.invalid": "컨버터({converter})가 올바르지 않습니다.", - - "error.file.changeName.empty": "이름을 입력하세요.", - "error.file.changeName.permission": "파일명({filename})을 변경할 권한이 없습니다.", - "error.file.duplicate": "파일명이 같은 파일({filename})이 있습니다.", - "error.file.extension.forbidden": "이 확장자({extension})는 업로드할 수 없습니다.", - "error.file.extension.invalid": "확장자({extension})가 올바르지 않습니다.", - "error.file.extension.missing": "파일({filename})에 확장자가 없습니다.", - "error.file.maxheight": "이미지의 높이는 {height}픽셀을 초과할 수 없습니다.", - "error.file.maxsize": "파일이 너무 큽니다.", - "error.file.maxwidth": "이미지의 너비는 {width}픽셀을 초과할 수 없습니다.", - "error.file.mime.differs": "기존 파일과 MIME 형식({mime})이 다릅니다.", - "error.file.mime.forbidden": "이 MIME 형식({mime})은 업로드할 수 없습니다.", - "error.file.mime.invalid": "MIME 형식({mime})이 올바르지 않습니다.", - "error.file.mime.missing": "파일({filename})의 MIME 형식을 확인할 수 없습니다.", - "error.file.minheight": "이미지의 높이를 {height}픽셀 이상으로 설정하세요.", - "error.file.minsize": "파일이 너무 작습니다.", - "error.file.minwidth": "이미지의 너비를 {width}픽셀 이상으로 설정하세요.", - "error.file.name.missing": "파일명을 입력하세요.", - "error.file.notFound": "파일({filename})이 없습니다.", - "error.file.orientation": "이미지의 비율({orientation})을 확인하세요.", - "error.file.type.forbidden": "이 형식({type})의 파일을 업로드할 권한이 없습니다.", - "error.file.type.invalid": "파일의 형식({type})이 올바르지 않습니다.", - "error.file.undefined": "\ud30c\uc77c\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.", - - "error.form.incomplete": "항목에 오류가 있습니다.", - "error.form.notSaved": "항목을 저장할 수 없습니다.", - - "error.language.code": "올바른 언어 코드를 입력하세요.", - "error.language.duplicate": "이미 등록한 언어입니다.", - "error.language.name": "올바른 언어명을 입력하세요.", - "error.language.notFound": "언어를 찾을 수 없습니다.", - - "error.layout.validation.block": "레이아웃({layoutIndex})의 블록({blockIndex})을 확인하세요.", - "error.layout.validation.settings": "레이아웃({index})의 옵션을 확인하세요.", - - "error.license.format": "올바른 라이선스 키를 입력하세요.", - "error.license.email": "올바른 이메일 주소를 입력하세요.", - "error.license.verification": "라이선스 키가 올바르지 않습니다.", - - "error.offline": "패널이 오프라인 상태입니다.", - - "error.page.changeSlug.permission": "고유 주소({slug})를 변경할 권한이 없습니다.", - "error.page.changeStatus.incomplete": "페이지를 공개할 수 없습니다.", - "error.page.changeStatus.permission": "페이지의 상태를 변경할 수 없습니다.", - "error.page.changeStatus.toDraft.invalid": "페이지({slug})의 상태를 초안으로 변경할 수 없습니다.", - "error.page.changeTemplate.invalid": "페이지({slug})의 템플릿을 변경할 수 없습니다.", - "error.page.changeTemplate.permission": "페이지({slug})의 템플릿을 변경할 권한이 없습니다.", - "error.page.changeTitle.empty": "제목을 입력하세요.", - "error.page.changeTitle.permission": "페이지({slug})의 제목을 변경할 권한이 없습니다.", - "error.page.create.permission": "페이지({slug})를 등록할 권한이 없습니다.", - "error.page.delete": "페이지({slug})를 삭제할 수 없습니다.", - "error.page.delete.confirm": "페이지를 삭제하려면 페이지의 제목을 입력하세요.", - "error.page.delete.hasChildren": "하위 페이지가 있는 페이지는 삭제할 수 없습니다.", - "error.page.delete.permission": "페이지({slug})를 삭제할 권한이 없습니다.", - "error.page.draft.duplicate": "고유 주소({slug})가 같은 초안 페이지가 있습니다.", - "error.page.duplicate": "고유 주소({slug})가 같은 페이지가 있습니다.", - "error.page.duplicate.permission": "페이지({slug})를 복제할 권한이 없습니다.", - "error.page.notFound": "페이지({slug})가 없습니다.", - "error.page.num.invalid": "올바른 정수를 입력하세요.", - "error.page.slug.invalid": "올바른 URL을 입력하세요.", - "error.page.slug.maxlength": "고유 주소를 {length}자 이하로 입력하세요.", - "error.page.sort.permission": "페이지({slug})를 정렬할 수 없습니다.", - "error.page.status.invalid": "올바른 상태를 설정하세요.", - "error.page.undefined": "\ud398\uc774\uc9c0\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.", - "error.page.update.permission": "페이지({slug})를 변경할 권한이 없습니다.", - - "error.section.files.max.plural": "이 섹션({section})에는 파일을 {max}개 이상 추가할 수 없습니다.", - "error.section.files.max.singular": "이 섹션({section})에는 파일을 하나 이상 추가할 수 없습니다.", - "error.section.files.min.plural": "이 섹션({section})에는 파일이 {min}개 이상 필요합니다.", - "error.section.files.min.singular": "이 섹션({section})에는 파일이 하나 이상 필요합니다.", - - "error.section.pages.max.plural": "이 섹션({section})에는 페이지를 {max}개 이상 추가할 수 없습니다.", - "error.section.pages.max.singular": "이 섹션({section})에는 페이지를 하나 이상 추가할 수 없습니다.", - "error.section.pages.min.plural": "이 섹션({section})에는 페이지가 {min}개 이상 필요합니다.", - "error.section.pages.min.singular": "이 섹션({section})에는 페이지가 하나 이상 필요합니다.", - - "error.section.notLoaded": "섹션({name})을 확인할 수 없습니다.", - "error.section.type.invalid": "섹션의 형식({type})이 올바르지 않습니다.", - - "error.site.changeTitle.empty": "제목을 입력하세요.", - "error.site.changeTitle.permission": "사이트명을 변경할 권한이 없습니다.", - "error.site.update.permission": "사이트의 정보를 변경할 권한이 없습니다.", - - "error.template.default.notFound": "기본 템플릿이 없습니다.", - - "error.unexpected": "오류가 발생했습니다. 디버그 모드를 활성화해 오류를 확인하세요. https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "사용자({name})의 이메일 주소를 변경할 권한이 없습니다.", - "error.user.changeLanguage.permission": "사용자({name})의 언어를 변경할 권한이 없습니다.", - "error.user.changeName.permission": "사용자명({name})을 변경할 권한이 없습니다.", - "error.user.changePassword.permission": "사용자({name})의 암호를 변경할 권한이 없습니다.", - "error.user.changeRole.lastAdmin": "최종 관리자의 역할은 변경할 수 없습니다.", - "error.user.changeRole.permission": "사용자({name})의 역할을 변경할 권한이 없습니다.", - "error.user.changeRole.toAdmin": "다른 사용자를 관리자로 지정할 권한이 없습니다.", - "error.user.create.permission": "사용자를 등록할 권한이 없습니다.", - "error.user.delete": "사용자({name})를 삭제할 수 없습니다.", - "error.user.delete.lastAdmin": "\ucd5c\uc885 \uad00\ub9ac\uc790\ub294 \uc0ad\uc81c\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.", - "error.user.delete.lastUser": "최종 사용자는 삭제할 수 없습니다.", - "error.user.delete.permission": "사용자({name})를 삭제할 권한이 없습니다.", - "error.user.duplicate": "이메일 주소({email})가 같은 사용자가 있습니다.", - "error.user.email.invalid": "올바른 이메일 주소를 입력하세요.", - "error.user.language.invalid": "올바른 언어를 입력하세요.", - "error.user.notFound": "사용자({name})가 없습니다.", - "error.user.password.invalid": "암호를 8자 이상으로 설정하세요.", - "error.user.password.notSame": "\uc554\ud638\ub97c \ud655\uc778\ud558\uc138\uc694.", - "error.user.password.undefined": "암호가 설정되지 않았습니다.", - "error.user.password.wrong": "암호가 올바르지 않습니다.", - "error.user.role.invalid": "올바른 역할을 지정하세요.", - "error.user.undefined": "사용자가 없습니다.", - "error.user.update.permission": "사용자({name})의 정보를 변경할 권한이 없습니다.", - - "error.validation.accepted": "확인하세요.", - "error.validation.alpha": "로마자(a~z)만 입력할 수 있습니다.", - "error.validation.alphanum": "로마자(a~z) 또는 숫자(0~9)만 입력할 수 있습니다.", - "error.validation.between": "{min}, {max} 사이의 값을 입력하세요.", - "error.validation.boolean": "확인하거나 취소하세요.", - "error.validation.contains": "{needle}에 포함된 값을 입력하세요.", - "error.validation.date": "올바른 날짜를 입력하세요.", - "error.validation.date.after": "{date} 이후 날짜를 입력하세요.", - "error.validation.date.before": "{date} 이전 날짜를 입력하세요.", - "error.validation.date.between": "{min}, {max} 사이의 날짜를 입력하세요.", - "error.validation.denied": "취소하세요.", - "error.validation.different": "{other}에 포함된 값은 입력할 수 없습니다.", - "error.validation.email": "올바른 이메일 주소를 입력하세요.", - "error.validation.endswith": "값은 다음({end})으로 끝나야 합니다.", - "error.validation.filename": "올바른 파일명을 입력하세요.", - "error.validation.in": "{in} 중 하나를 입력하세요.", - "error.validation.integer": "올바른 정수를 입력하세요.", - "error.validation.ip": "올바른 IP 주소를 입력하세요.", - "error.validation.less": "{max} 미만의 값을 입력하세요.", - "error.validation.match": "입력한 값이 예상 패턴과 일치하지 않습니다.", - "error.validation.max": "{max} 이하의 값을 입력하세요.", - "error.validation.maxlength": "{max}자 이하의 값을 입력하세요.", - "error.validation.maxwords": "{max}자 이하를 입력하세요.", - "error.validation.min": "{min} 이상의 값을 입력하세요.", - "error.validation.minlength": "{min}자 이상의 값을 입력하세요.", - "error.validation.minwords": "{min}자 이상을 입력하세요.", - "error.validation.more": "{min} 이상의 값을 입력하세요.", - "error.validation.notcontains": "{needle}에 포함된 값은 입력할 수 없습니다.", - "error.validation.notin": "{notIn}에 포함된 값은 입력할 수 없습니다.", - "error.validation.option": "올바른 옵션을 선택하세요.", - "error.validation.num": "올바른 숫자를 입력하세요.", - "error.validation.required": "해당 항목을 확인하세요.", - "error.validation.same": "이 값({other})을 입력하세요.", - "error.validation.size": "값의 크기({size})를 확인하세요. ", - "error.validation.startswith": "값은 다음({start})으로 시작해야 합니다.", - "error.validation.time": "올바른 시각을 입력하세요.", - "error.validation.time.after": "{time} 이후 시각을 입력하세요.", - "error.validation.time.before": "{time} 이전 시각을 입력하세요.", - "error.validation.time.between": "{min}, {max} 사이의 시각을 입력하세요.", - "error.validation.url": "올바른 URL을 입력하세요.", - - "expand": "열기", - "expand.all": "모두 열기", - - "field.required": "필드를 채우세요.", - "field.blocks.changeType": "유형 변경", - "field.blocks.code.name": "코드", - "field.blocks.code.language": "언어", - "field.blocks.code.placeholder": "코드", - "field.blocks.delete.confirm": "블록을 삭제할까요?", - "field.blocks.delete.confirm.all": "모든 블록을 삭제할까요?", - "field.blocks.delete.confirm.selected": "선택한 블록을 삭제할까요?", - "field.blocks.empty": "블록이 없습니다.", - "field.blocks.fieldsets.label": "블록의 유형을 선택하세요.", - "field.blocks.fieldsets.paste": "단축키({{ shortcut }})로 클립보드에서 블록을 가져올 수 있습니다.", - "field.blocks.gallery.name": "갤러리", - "field.blocks.gallery.images.empty": "이미지가 없습니다.", - "field.blocks.gallery.images.label": "이미지", - "field.blocks.heading.level": "단계", - "field.blocks.heading.name": "제목", - "field.blocks.heading.text": "제목", - "field.blocks.heading.placeholder": "제목", - "field.blocks.image.alt": "대체 텍스트", - "field.blocks.image.caption": "캡션", - "field.blocks.image.crop": "자르기", - "field.blocks.image.link": "링크", - "field.blocks.image.location": "위치", - "field.blocks.image.name": "이미지", - "field.blocks.image.placeholder": "이미지 선택", - "field.blocks.image.ratio": "비율", - "field.blocks.image.url": "이미지 URL", - "field.blocks.line.name": "가로줄", - "field.blocks.list.name": "목록", - "field.blocks.markdown.name": "마크다운", - "field.blocks.markdown.label": "마크다운", - "field.blocks.markdown.placeholder": "마크다운", - "field.blocks.quote.name": "인용문", - "field.blocks.quote.text.label": "인용문", - "field.blocks.quote.text.placeholder": "인용문", - "field.blocks.quote.citation.label": "출처", - "field.blocks.quote.citation.placeholder": "출처", - "field.blocks.text.name": "텍스트", - "field.blocks.text.placeholder": "텍스트", - "field.blocks.video.caption": "캡션", - "field.blocks.video.name": "영상", - "field.blocks.video.placeholder": "영상 URL 입력", - "field.blocks.video.url.label": "영상 URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "선택한 파일이 없습니다.", - - "field.layout.delete": "레이아웃 삭제", - "field.layout.delete.confirm": "레이아웃을 삭제할까요?", - "field.layout.empty": "행이 없습니다.", - "field.layout.select": "레이아웃 선택", - - "field.pages.empty": "선택한 페이지가 없습니다.", - "field.structure.delete.confirm": "이 항목을 삭제할까요?", - "field.structure.empty": "항목이 없습니다.", - "field.users.empty": "선택한 사용자가 없습니다.", - - "file.blueprint": "블루프린트(/site/blueprints/files/{blueprint}.yml)를 설정하세요.", - "file.delete.confirm": "파일({filename})을 삭제할까요?", - "file.sort": "순서 변경", - - "files": "파일", - "files.empty": "파일이 없습니다.", - - "hide": "숨기기", - "hour": "시", - "import": "가져오기", - "info": "정보", - "insert": "\uc0bd\uc785", - "insert.after": "뒤에 삽입", - "insert.before": "앞에 삽입", - "install": "설치", - - "installation": "설치", - "installation.completed": "패널을 설치했습니다.", - "installation.disabled": "패널 설치 관리자는 로컬 서버에서 실행하거나 panel.install 옵션을 설정하세요.", - "installation.issues.accounts": "/site/accounts 폴더의 쓰기 권한을 확인하세요.", - "installation.issues.content": "/content 폴더의 쓰기 권한을 확인하세요.", - "installation.issues.curl": "cURL 확장 모듈이 필요합니다.", - "installation.issues.headline": "패널을 설치할 수 없습니다.", - "installation.issues.mbstring": "MB String 확장 모듈이 필요합니다.", - "installation.issues.media": "/media 폴더의 쓰기 권한을 확인하세요.", - "installation.issues.php": "PHP 버전이 7 이상인지 확인하세요.", - "installation.issues.server": "Kirby를 실행하려면 Apache, Nginx, 또는 Caddy가 필요합니다.", - "installation.issues.sessions": "/site/sessions 폴더의 쓰기 권한을 확인하세요.", - - "language": "\uc5b8\uc5b4", - "language.code": "언어 코드", - "language.convert": "기본 언어로 지정", - "language.convert.confirm": "이 언어({name})를 기본 언어로 지정할까요? 지정한 뒤에는 복원할 수 없으며, 이 언어로 번역되지 않은 항목은 올바르게 표시되지 않을 수 있습니다.", - "language.create": "새 언어 추가", - "language.delete.confirm": "언어({name})를 삭제할까요? 삭제한 뒤에는 복원할 수 없습니다.", - "language.deleted": "언어를 삭제했습니다.", - "language.direction": "읽기 방향", - "language.direction.ltr": "왼쪽에서 오른쪽", - "language.direction.rtl": "오른쪽에서 왼쪽", - "language.locale": "PHP 로캘 문자열", - "language.locale.warning": "사용자 지정 로캘을 사용 중입니다. /site/languages 폴더의 언어 파일을 수정하세요.", - "language.name": "언어명", - "language.updated": "언어를 변경했습니다.", - - "languages": "언어", - "languages.default": "기본 언어", - "languages.empty": "언어가 없습니다.", - "languages.secondary": "보조 언어", - "languages.secondary.empty": "보조 언어가 없습니다.", - - "license": "라이선스", - "license.buy": "라이선스 구매", - "license.register": "등록", - "license.manage": "라이선스 관리", - "license.register.help": "Kirby를 등록하려면 이메일로 전송받은 라이선스 코드와 이메일 주소를 입력하세요.", - "license.register.label": "라이선스 코드를 입력하세요.", - "license.register.success": "Kirby와 함께해주셔서 감사합니다.", - "license.unregistered": "Kirby가 등록되지 않았습니다.", - "license.unregistered.label": "Kirby가 등록되지 않았습니다.", - - "link": "\uc77c\ubc18 \ub9c1\ud06c", - "link.text": "\ubb38\uc790", - - "loading": "로딩 중…", - - "lock.unsaved": "저장되지 않은 항목이 있습니다.", - "lock.unsaved.empty": "모든 페이지를 저장했습니다.", - "lock.isLocked": "다른 사용자({email})가 수정한 사항이 저장되지 않았습니다.", - "lock.file.isLocked": "파일을 편집할 수 없습니다. 다른 사용자({email})가 편집 중입니다.", - "lock.page.isLocked": "페이지를 편집할 수 없습니다. 다른 사용자({email})가 편집 중입니다.", - "lock.unlock": "잠금 해제", - "lock.isUnlocked": "다른 사용자가 이미 내용을 수정했으므로 현재 내용이 올바르게 저장되지 않았습니다. 저장되지 않은 내용은 다운로드해 수동으로 대치할 수 있습니다.", - - "login": "로그인", - "login.code.label.login": "로그인 코드", - "login.code.label.password-reset": "암호 초기화 코드", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "입력한 이메일 주소로 코드를 전송했습니다.", - "login.email.login.body": "{user.nameOrEmail} 님,\n\n{site} 패널에서 요청한 로그인 코드는 다음과 같습니다. 로그인 코드는 {timeout}분 동안 유효합니다.\n\n{code}\n\n로그인 코드를 요청한 적이 없다면, 이 이메일을 무시하거나 관리자에게 문의하세요. 보안을 위해 이 이메일은 다른 사람과 공유하지 마세요.", - "login.email.login.subject": "로그인 코드", - "login.email.password-reset.body": "{user.nameOrEmail} 님,\n\n{site} 패널에서 요청한 암호 초기화 코드는 다음과 같습니다. 암호 초기화 코드는 {timeout}분 동안 유효합니다.\n\n{code}\n\n암호 초기화 코드를 요청한 적이 없다면, 이 이메일을 무시하거나 관리자에게 문의하세요. 보안을 위해 이 이메일은 다른 사람과 공유하지 마세요.", - "login.email.password-reset.subject": "암호 초기화 코드", - "login.remember": "로그인 유지", - "login.reset": "암호 초기화", - "login.toggleText.code.email": "이메일 주소로 로그인", - "login.toggleText.code.email-password": "암호로 로그인", - "login.toggleText.password-reset.email": "암호 찾기", - "login.toggleText.password-reset.email-password": "로그인 화면으로", - - "logout": "\ub85c\uadf8\uc544\uc6c3", - - "menu": "메뉴", - "meridiem": "오전/오후", - "mime": "MIME 형식", - "minutes": "분", - - "month": "월", - "months.april": "4\uc6d4", - "months.august": "8\uc6d4", - "months.december": "12\uc6d4", - "months.february": "2월", - "months.january": "1\uc6d4", - "months.july": "7\uc6d4", - "months.june": "6\uc6d4", - "months.march": "3\uc6d4", - "months.may": "5\uc6d4", - "months.november": "11\uc6d4", - "months.october": "10\uc6d4", - "months.september": "9\uc6d4", - - "more": "더 보기", - "name": "이름", - "next": "다음", - "no": "아니요", - "off": "끔", - "on": "켬", - "open": "열기", - "open.newWindow": "새 창에서 열기", - "options": "옵션", - "options.none": "옵션이 없습니다.", - - "orientation": "비율", - "orientation.landscape": "가로로 긴 사각형", - "orientation.portrait": "세로로 긴 사각형", - "orientation.square": "정사각형", - - "page.blueprint": "블루프린트(/site/blueprints/pages/{blueprint}.yml)를 설정하세요.", - "page.changeSlug": "고유 주소 변경", - "page.changeSlug.fromTitle": "제목에서 가져오기", - "page.changeStatus": "상태 변경", - "page.changeStatus.position": "순서를 지정하세요.", - "page.changeStatus.select": "새 상태 선택", - "page.changeTemplate": "템플릿 변경", - "page.delete.confirm": "페이지({title})를 삭제할까요?", - "page.delete.confirm.subpages": "페이지에 하위 페이지가 있습니다. 모든 하위 페이지가 삭제됩니다.", - "page.delete.confirm.title": "페이지의 제목을 입력하세요.", - "page.draft.create": "초안 등록", - "page.duplicate.appendix": "복사", - "page.duplicate.files": "파일 복사", - "page.duplicate.pages": "페이지 복사", - "page.sort": "순서 변경", - "page.status": "상태", - "page.status.draft": "초안", - "page.status.draft.description": "로그인한 사용자나 URL을 통해 접근할 수 있습니다.", - "page.status.listed": "공개", - "page.status.listed.description": "누구나 읽을 수 있습니다.", - "page.status.unlisted": "비공개", - "page.status.unlisted.description": "URL을 통해 접근할 수 있습니다.", - - "pages": "페이지", - "pages.empty": "페이지가 없습니다.", - "pages.status.draft": "초안", - "pages.status.listed": "발행", - "pages.status.unlisted": "비공개", - - "pagination.page": "페이지", - - "password": "\uc554\ud638", - "paste": "붙여넣기", - "paste.after": "뒤로 붙여넣기", - "pixel": "픽셀", - "plugins": "플러그인", - "prev": "이전", - "preview": "미리 보기", - "remove": "삭제", - "rename": "이름 변경", - "replace": "\uad50\uccb4", - "retry": "\ub2e4\uc2dc \uc2dc\ub3c4", - "revert": "복원", - "revert.confirm": "저장되지 않은 내용을 삭제할까요?", - - "role": "역할", - "role.admin.description": "관리자는 모든 권한이 있습니다.", - "role.admin.title": "관리자", - "role.all": "전체", - "role.empty": "이 역할에 해당하는 사용자가 없습니다.", - "role.description.placeholder": "설명이 없습니다.", - "role.nobody.description": "대체 사용자는 아무 권한이 없습니다.", - "role.nobody.title": "사용자가 없습니다.", - - "save": "\uc800\uc7a5", - "search": "검색", - "search.min": "{min}자 이상 입력하세요.", - "search.all": "모두 보기", - "search.results.none": "해당하는 결과가 없습니다.", - - "section.required": "섹션이 필요합니다.", - - "security": "보안", - "select": "선택", - "server": "서버", - "settings": "설정", - "show": "보기", - "site.blueprint": "블루프린트(/site/blueprints/site.yml)를 설정하세요.", - "size": "크기", - "slug": "고유 주소", - "sort": "정렬", - - "stats.empty": "관련 기록이 없습니다.", - "system.issues.content": "/content 폴더의 권한을 확인하세요.", - "system.issues.debug": "공개 서버상에서는 디버그 모드를 해제하세요.", - "system.issues.git": "/.git 폴더의 권한을 확인하세요.", - "system.issues.https": "HTTPS를 권장합니다.", - "system.issues.kirby": "/kirby 폴더의 권한을 확인하세요.", - "system.issues.site": "/site 폴더의 권한을 확인하세요.", - - "title": "제목", - "template": "\ud15c\ud50c\ub9bf", - "today": "오늘", - - "toolbar.button.code": "코드", - "toolbar.button.bold": "강조", - "toolbar.button.email": "이메일 주소", - "toolbar.button.headings": "제목", - "toolbar.button.heading.1": "제목 1", - "toolbar.button.heading.2": "제목 2", - "toolbar.button.heading.3": "제목 3", - "toolbar.button.heading.4": "제목 4", - "toolbar.button.heading.5": "제목 5", - "toolbar.button.heading.6": "제목 6", - "toolbar.button.italic": "강조 2", - "toolbar.button.file": "파일", - "toolbar.button.file.select": "파일 선택", - "toolbar.button.file.upload": "파일 업로드", - "toolbar.button.link": "링크", - "toolbar.button.paragraph": "문단", - "toolbar.button.strike": "취소선", - "toolbar.button.ol": "숫자 목록", - "toolbar.button.underline": "밑줄", - "toolbar.button.ul": "기호 목록", - - "translation.author": "Kirby 팀", - "translation.direction": "ltr", - "translation.name": "한국어", - "translation.locale": "ko_KR", - - "upload": "업로드", - "upload.error.cantMove": "파일을 이동할 수 없습니다.", - "upload.error.cantWrite": "디스크를 읽을 수 없습니다.", - "upload.error.default": "파일을 업로드할 수 없습니다.", - "upload.error.extension": "파일 확장자를 확인하세요.", - "upload.error.formSize": "업로드한 파일이 허용된 크기(MAX_FILE_SIZE)를 초과했습니다.", - "upload.error.iniPostSize": "업로드한 파일이 PHP 환경 설정 파일(php.ini)에서 허용된 크기(post_max_size)를 초과했습니다.", - "upload.error.iniSize": "업로드한 파일이 PHP 환경 설정 파일(php.ini)에서 허용된 크기(upload_max_filesize)를 초과했습니다.", - "upload.error.noFile": "업로드한 파일이 없습니다.", - "upload.error.noFiles": "업로드한 파일이 없습니다.", - "upload.error.partial": "일부 파일을 업로드했습니다.", - "upload.error.tmpDir": "임시 폴더가 없습니다.", - "upload.errors": "오류", - "upload.progress": "업로드 중…", - - "url": "URL", - "url.placeholder": "https://example.com", - - "user": "사용자", - "user.blueprint": "블루프린트(/site/blueprints/users/{blueprint}.yml)에 섹션과 필드를 추가할 수 있습니다.", - "user.changeEmail": "이메일 주소 변경", - "user.changeLanguage": "언어 변경", - "user.changeName": "사용자명 변경", - "user.changePassword": "암호 변경", - "user.changePassword.new": "새 암호", - "user.changePassword.new.confirm": "새 암호 확인", - "user.changeRole": "역할 변경", - "user.changeRole.select": "새 역할 선택", - "user.create": "사용자 추가", - "user.delete": "사용자 삭제", - "user.delete.confirm": "사용자({email})를 삭제할까요?", - - "users": "사용자", - - "version": "버전", - - "view.account": "계정", - "view.installation": "\uc124\uce58", - "view.languages": "언어", - "view.resetPassword": "암호 초기화", - "view.site": "사이트", - "view.system": "시스템", - "view.users": "\uc0ac\uc6a9\uc790", - - "welcome": "반갑습니다.", - "year": "년", - "yes": "네" + "account.changeName": "이름 변경", + "account.delete": "계정 삭제", + "account.delete.confirm": "계정을 삭제할까요? 계정을 삭제한 뒤에는 복구할 수 없습니다.", + + "add": "\ucd94\uac00", + "author": "저자", + "avatar": "프로필 이미지", + "back": "뒤로", + "cancel": "\ucde8\uc18c", + "change": "\ubcc0\uacbd", + "close": "\ub2eb\uae30", + "confirm": "확인", + "collapse": "접기", + "collapse.all": "모두 접기", + "copy": "복사", + "copy.all": "모두 복사", + "create": "등록", + + "date": "날짜", + "date.select": "날짜 지정", + + "day": "일", + "days.fri": "\uae08", + "days.mon": "\uc6d4", + "days.sat": "\ud1a0", + "days.sun": "\uc77c", + "days.thu": "\ubaa9", + "days.tue": "\ud654", + "days.wed": "\uc218", + + "debugging": "디버그", + + "delete": "\uc0ad\uc81c", + "delete.all": "모두 삭제", + + "dialog.files.empty": "선택할 파일이 없습니다.", + "dialog.pages.empty": "선택할 페이지가 없습니다.", + "dialog.users.empty": "선택할 사용자가 없습니다.", + + "dimensions": "크기", + "disabled": "비활성화", + "discard": "무시", + "download": "다운로드", + "duplicate": "복제", + + "edit": "\ud3b8\uc9d1", + + "email": "\uc774\uba54\uc77c \uc8fc\uc18c", + "email.placeholder": "mail@example.com", + + "entries": "항목", + "entry": "항목", + + "environment": "구동 환경", + + "error.access.code": "코드가 올바르지 않습니다.", + "error.access.login": "로그인할 수 없습니다.", + "error.access.panel": "패널에 접근할 권한이 없습니다.", + "error.access.view": "패널에 접근할 권한이 없습니다.", + + "error.avatar.create.fail": "프로필 이미지를 업로드할 수 없습니다.", + "error.avatar.delete.fail": "\ud504\ub85c\ud544 \uc774\ubbf8\uc9c0\ub97c \uc0ad\uc81c\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.", + "error.avatar.dimensions.invalid": "프로필 이미지의 너비와 높이를 3,000픽셀 이하로 설정하세요.", + "error.avatar.mime.forbidden": "프로필 이미지의 확장자(JPG, JPEG, PNG)를 확인하세요.", + + "error.blueprint.notFound": "블루프린트({name})를 불러올 수 없습니다.", + + "error.blocks.max.plural": "블록을 {max}개 이상 추가할 수 없습니다.", + "error.blocks.max.singular": "블록을 하나 이상 추가할 수 없습니다.", + "error.blocks.min.plural": "블록을 {min}개 이상 추가하세요.", + "error.blocks.min.singular": "블록을 하나 이상 추가하세요.", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "기본 이메일 주소({name})가 없습니다.", + + "error.field.converter.invalid": "컨버터({converter})가 올바르지 않습니다.", + + "error.file.changeName.empty": "이름을 입력하세요.", + "error.file.changeName.permission": "파일명({filename})을 변경할 권한이 없습니다.", + "error.file.duplicate": "파일명이 같은 파일({filename})이 있습니다.", + "error.file.extension.forbidden": "이 확장자({extension})는 업로드할 수 없습니다.", + "error.file.extension.invalid": "확장자({extension})가 올바르지 않습니다.", + "error.file.extension.missing": "파일({filename})에 확장자가 없습니다.", + "error.file.maxheight": "이미지의 높이는 {height}픽셀을 초과할 수 없습니다.", + "error.file.maxsize": "파일이 너무 큽니다.", + "error.file.maxwidth": "이미지의 너비는 {width}픽셀을 초과할 수 없습니다.", + "error.file.mime.differs": "기존 파일과 MIME 형식({mime})이 다릅니다.", + "error.file.mime.forbidden": "이 MIME 형식({mime})은 업로드할 수 없습니다.", + "error.file.mime.invalid": "MIME 형식({mime})이 올바르지 않습니다.", + "error.file.mime.missing": "파일({filename})의 MIME 형식을 확인할 수 없습니다.", + "error.file.minheight": "이미지의 높이를 {height}픽셀 이상으로 설정하세요.", + "error.file.minsize": "파일이 너무 작습니다.", + "error.file.minwidth": "이미지의 너비를 {width}픽셀 이상으로 설정하세요.", + "error.file.name.missing": "파일명을 입력하세요.", + "error.file.notFound": "파일({filename})이 없습니다.", + "error.file.orientation": "이미지의 비율({orientation})을 확인하세요.", + "error.file.type.forbidden": "이 형식({type})의 파일을 업로드할 권한이 없습니다.", + "error.file.type.invalid": "파일의 형식({type})이 올바르지 않습니다.", + "error.file.undefined": "\ud30c\uc77c\uc774 \uc5c6\uc2b5\ub2c8\ub2e4.", + + "error.form.incomplete": "항목에 오류가 있습니다.", + "error.form.notSaved": "항목을 저장할 수 없습니다.", + + "error.language.code": "올바른 언어 코드를 입력하세요.", + "error.language.duplicate": "이미 등록한 언어입니다.", + "error.language.name": "올바른 언어명을 입력하세요.", + "error.language.notFound": "언어를 찾을 수 없습니다.", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "레이아웃({index})의 옵션을 확인하세요.", + + "error.license.format": "올바른 라이선스 키를 입력하세요.", + "error.license.email": "올바른 이메일 주소를 입력하세요.", + "error.license.verification": "라이선스 키가 올바르지 않습니다.", + + "error.object.validation": "{label} 필드에 오류가 있습니다.\n{message}", + + "error.offline": "패널이 오프라인 상태입니다.", + + "error.page.changeSlug.permission": "고유 주소({slug})를 변경할 권한이 없습니다.", + "error.page.changeStatus.incomplete": "페이지를 공개할 수 없습니다.", + "error.page.changeStatus.permission": "페이지의 상태를 변경할 수 없습니다.", + "error.page.changeStatus.toDraft.invalid": "페이지({slug})의 상태를 초안으로 변경할 수 없습니다.", + "error.page.changeTemplate.invalid": "페이지({slug})의 템플릿을 변경할 수 없습니다.", + "error.page.changeTemplate.permission": "페이지({slug})의 템플릿을 변경할 권한이 없습니다.", + "error.page.changeTitle.empty": "제목을 입력하세요.", + "error.page.changeTitle.permission": "페이지({slug})의 제목을 변경할 권한이 없습니다.", + "error.page.create.permission": "페이지({slug})를 등록할 권한이 없습니다.", + "error.page.delete": "페이지({slug})를 삭제할 수 없습니다.", + "error.page.delete.confirm": "페이지를 삭제하려면 페이지의 제목을 입력하세요.", + "error.page.delete.hasChildren": "하위 페이지가 있는 페이지는 삭제할 수 없습니다.", + "error.page.delete.permission": "페이지({slug})를 삭제할 권한이 없습니다.", + "error.page.draft.duplicate": "고유 주소({slug})가 같은 초안 페이지가 있습니다.", + "error.page.duplicate": "고유 주소({slug})가 같은 페이지가 있습니다.", + "error.page.duplicate.permission": "페이지({slug})를 복제할 권한이 없습니다.", + "error.page.notFound": "페이지({slug})가 없습니다.", + "error.page.num.invalid": "올바른 정수를 입력하세요.", + "error.page.slug.invalid": "올바른 URL을 입력하세요.", + "error.page.slug.maxlength": "고유 주소를 {length}자 이하로 입력하세요.", + "error.page.sort.permission": "페이지({slug})를 정렬할 수 없습니다.", + "error.page.status.invalid": "올바른 상태를 설정하세요.", + "error.page.undefined": "\ud398\uc774\uc9c0\uac00 \uc5c6\uc2b5\ub2c8\ub2e4.", + "error.page.update.permission": "페이지({slug})를 변경할 권한이 없습니다.", + + "error.section.files.max.plural": "이 섹션({section})에는 파일을 {max}개 이상 추가할 수 없습니다.", + "error.section.files.max.singular": "이 섹션({section})에는 파일을 하나 이상 추가할 수 없습니다.", + "error.section.files.min.plural": "이 섹션({section})에는 파일이 {min}개 이상 필요합니다.", + "error.section.files.min.singular": "이 섹션({section})에는 파일이 하나 이상 필요합니다.", + + "error.section.pages.max.plural": "이 섹션({section})에는 페이지를 {max}개 이상 추가할 수 없습니다.", + "error.section.pages.max.singular": "이 섹션({section})에는 페이지를 하나 이상 추가할 수 없습니다.", + "error.section.pages.min.plural": "이 섹션({section})에는 페이지가 {min}개 이상 필요합니다.", + "error.section.pages.min.singular": "이 섹션({section})에는 페이지가 하나 이상 필요합니다.", + + "error.section.notLoaded": "섹션({name})을 확인할 수 없습니다.", + "error.section.type.invalid": "섹션의 형식({type})이 올바르지 않습니다.", + + "error.site.changeTitle.empty": "제목을 입력하세요.", + "error.site.changeTitle.permission": "사이트명을 변경할 권한이 없습니다.", + "error.site.update.permission": "사이트의 정보를 변경할 권한이 없습니다.", + + "error.template.default.notFound": "기본 템플릿이 없습니다.", + + "error.unexpected": "오류가 발생했습니다. 디버그 모드를 활성화해 오류를 확인하세요. https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "사용자({name})의 이메일 주소를 변경할 권한이 없습니다.", + "error.user.changeLanguage.permission": "사용자({name})의 언어를 변경할 권한이 없습니다.", + "error.user.changeName.permission": "사용자명({name})을 변경할 권한이 없습니다.", + "error.user.changePassword.permission": "사용자({name})의 암호를 변경할 권한이 없습니다.", + "error.user.changeRole.lastAdmin": "최종 관리자의 역할은 변경할 수 없습니다.", + "error.user.changeRole.permission": "사용자({name})의 역할을 변경할 권한이 없습니다.", + "error.user.changeRole.toAdmin": "다른 사용자를 관리자로 지정할 권한이 없습니다.", + "error.user.create.permission": "사용자를 등록할 권한이 없습니다.", + "error.user.delete": "사용자({name})를 삭제할 수 없습니다.", + "error.user.delete.lastAdmin": "\ucd5c\uc885 \uad00\ub9ac\uc790\ub294 \uc0ad\uc81c\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4.", + "error.user.delete.lastUser": "최종 사용자는 삭제할 수 없습니다.", + "error.user.delete.permission": "사용자({name})를 삭제할 권한이 없습니다.", + "error.user.duplicate": "이메일 주소({email})가 같은 사용자가 있습니다.", + "error.user.email.invalid": "올바른 이메일 주소를 입력하세요.", + "error.user.language.invalid": "올바른 언어를 입력하세요.", + "error.user.notFound": "사용자({name})가 없습니다.", + "error.user.password.invalid": "암호를 8자 이상으로 설정하세요.", + "error.user.password.notSame": "\uc554\ud638\ub97c \ud655\uc778\ud558\uc138\uc694.", + "error.user.password.undefined": "암호가 설정되지 않았습니다.", + "error.user.password.wrong": "암호가 올바르지 않습니다.", + "error.user.role.invalid": "올바른 역할을 지정하세요.", + "error.user.undefined": "사용자가 없습니다.", + "error.user.update.permission": "사용자({name})의 정보를 변경할 권한이 없습니다.", + + "error.validation.accepted": "확인하세요.", + "error.validation.alpha": "로마자(a~z)만 입력할 수 있습니다.", + "error.validation.alphanum": "로마자(a~z) 또는 숫자(0~9)만 입력할 수 있습니다.", + "error.validation.between": "{min}, {max} 사이의 값을 입력하세요.", + "error.validation.boolean": "확인하거나 취소하세요.", + "error.validation.contains": "{needle}에 포함된 값을 입력하세요.", + "error.validation.date": "올바른 날짜를 입력하세요.", + "error.validation.date.after": "{date} 이후 날짜를 입력하세요.", + "error.validation.date.before": "{date} 이전 날짜를 입력하세요.", + "error.validation.date.between": "{min}, {max} 사이의 날짜를 입력하세요.", + "error.validation.denied": "취소하세요.", + "error.validation.different": "{other}에 포함된 값은 입력할 수 없습니다.", + "error.validation.email": "올바른 이메일 주소를 입력하세요.", + "error.validation.endswith": "값은 다음({end})으로 끝나야 합니다.", + "error.validation.filename": "올바른 파일명을 입력하세요.", + "error.validation.in": "{in} 중 하나를 입력하세요.", + "error.validation.integer": "올바른 정수를 입력하세요.", + "error.validation.ip": "올바른 IP 주소를 입력하세요.", + "error.validation.less": "{max} 미만의 값을 입력하세요.", + "error.validation.match": "입력한 값이 예상 패턴과 일치하지 않습니다.", + "error.validation.max": "{max} 이하의 값을 입력하세요.", + "error.validation.maxlength": "{max}자 이하의 값을 입력하세요.", + "error.validation.maxwords": "{max}자 이하를 입력하세요.", + "error.validation.min": "{min} 이상의 값을 입력하세요.", + "error.validation.minlength": "{min}자 이상의 값을 입력하세요.", + "error.validation.minwords": "{min}자 이상을 입력하세요.", + "error.validation.more": "{min} 이상의 값을 입력하세요.", + "error.validation.notcontains": "{needle}에 포함된 값은 입력할 수 없습니다.", + "error.validation.notin": "{notIn}에 포함된 값은 입력할 수 없습니다.", + "error.validation.option": "올바른 옵션을 선택하세요.", + "error.validation.num": "올바른 숫자를 입력하세요.", + "error.validation.required": "해당 항목을 확인하세요.", + "error.validation.same": "이 값({other})을 입력하세요.", + "error.validation.size": "값의 크기({size})를 확인하세요. ", + "error.validation.startswith": "값은 다음({start})으로 시작해야 합니다.", + "error.validation.time": "올바른 시각을 입력하세요.", + "error.validation.time.after": "{time} 이후 시각을 입력하세요.", + "error.validation.time.before": "{time} 이전 시각을 입력하세요.", + "error.validation.time.between": "{min}, {max} 사이의 시각을 입력하세요.", + "error.validation.url": "올바른 URL을 입력하세요.", + + "expand": "열기", + "expand.all": "모두 열기", + + "field.required": "필드를 채우세요.", + "field.blocks.changeType": "유형 변경", + "field.blocks.code.name": "코드", + "field.blocks.code.language": "언어", + "field.blocks.code.placeholder": "코드", + "field.blocks.delete.confirm": "블록을 삭제할까요?", + "field.blocks.delete.confirm.all": "모든 블록을 삭제할까요?", + "field.blocks.delete.confirm.selected": "선택한 블록을 삭제할까요?", + "field.blocks.empty": "블록이 없습니다.", + "field.blocks.fieldsets.label": "블록의 유형을 선택하세요.", + "field.blocks.fieldsets.paste": "단축키({{ shortcut }})로 클립보드에서 블록을 가져올 수 있습니다.", + "field.blocks.gallery.name": "갤러리", + "field.blocks.gallery.images.empty": "이미지가 없습니다.", + "field.blocks.gallery.images.label": "이미지", + "field.blocks.heading.level": "단계", + "field.blocks.heading.name": "제목", + "field.blocks.heading.text": "제목", + "field.blocks.heading.placeholder": "제목", + "field.blocks.image.alt": "대체 텍스트", + "field.blocks.image.caption": "캡션", + "field.blocks.image.crop": "자르기", + "field.blocks.image.link": "링크", + "field.blocks.image.location": "위치", + "field.blocks.image.name": "이미지", + "field.blocks.image.placeholder": "이미지 선택", + "field.blocks.image.ratio": "비율", + "field.blocks.image.url": "이미지 URL", + "field.blocks.line.name": "가로줄", + "field.blocks.list.name": "목록", + "field.blocks.markdown.name": "마크다운", + "field.blocks.markdown.label": "마크다운", + "field.blocks.markdown.placeholder": "마크다운", + "field.blocks.quote.name": "인용문", + "field.blocks.quote.text.label": "인용문", + "field.blocks.quote.text.placeholder": "인용문", + "field.blocks.quote.citation.label": "출처", + "field.blocks.quote.citation.placeholder": "출처", + "field.blocks.text.name": "텍스트", + "field.blocks.text.placeholder": "텍스트", + "field.blocks.video.caption": "캡션", + "field.blocks.video.name": "영상", + "field.blocks.video.placeholder": "영상 URL 입력", + "field.blocks.video.url.label": "영상 URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "선택한 파일이 없습니다.", + + "field.layout.delete": "레이아웃 삭제", + "field.layout.delete.confirm": "레이아웃을 삭제할까요?", + "field.layout.empty": "행이 없습니다.", + "field.layout.select": "레이아웃 선택", + + "field.object.empty": "정보가 없습니다.", + + "field.pages.empty": "선택한 페이지가 없습니다.", + + "field.structure.delete.confirm": "이 항목을 삭제할까요?", + "field.structure.empty": "항목이 없습니다.", + + "field.users.empty": "선택한 사용자가 없습니다.", + + "file.blueprint": "블루프린트(/site/blueprints/files/{blueprint}.yml)를 설정하세요.", + "file.delete.confirm": "파일({filename})을 삭제할까요?", + "file.sort": "순서 변경", + + "files": "파일", + "files.empty": "파일이 없습니다.", + + "hide": "숨기기", + "hour": "시", + "import": "가져오기", + "info": "정보", + "insert": "\uc0bd\uc785", + "insert.after": "뒤에 삽입", + "insert.before": "앞에 삽입", + "install": "설치", + + "installation": "설치", + "installation.completed": "패널을 설치했습니다.", + "installation.disabled": "패널 설치 관리자는 로컬 서버에서 실행하거나 panel.install 옵션을 설정하세요.", + "installation.issues.accounts": "/site/accounts 폴더의 쓰기 권한을 확인하세요.", + "installation.issues.content": "/content 폴더의 쓰기 권한을 확인하세요.", + "installation.issues.curl": "cURL 확장 모듈이 필요합니다.", + "installation.issues.headline": "패널을 설치할 수 없습니다.", + "installation.issues.mbstring": "MB String 확장 모듈이 필요합니다.", + "installation.issues.media": "/media 폴더의 쓰기 권한을 확인하세요.", + "installation.issues.php": "PHP 버전이 7 이상인지 확인하세요.", + "installation.issues.server": "Kirby를 실행하려면 Apache, Nginx, 또는 Caddy가 필요합니다.", + "installation.issues.sessions": "/site/sessions 폴더의 쓰기 권한을 확인하세요.", + + "language": "\uc5b8\uc5b4", + "language.code": "언어 코드", + "language.convert": "기본 언어로 지정", + "language.convert.confirm": "이 언어({name})를 기본 언어로 지정할까요? 지정한 뒤에는 복원할 수 없으며, 이 언어로 번역되지 않은 항목은 올바르게 표시되지 않을 수 있습니다.", + "language.create": "새 언어 추가", + "language.delete.confirm": "언어({name})를 삭제할까요? 삭제한 뒤에는 복원할 수 없습니다.", + "language.deleted": "언어를 삭제했습니다.", + "language.direction": "읽기 방향", + "language.direction.ltr": "왼쪽에서 오른쪽", + "language.direction.rtl": "오른쪽에서 왼쪽", + "language.locale": "PHP 로캘 문자열", + "language.locale.warning": "사용자 지정 로캘을 사용 중입니다. /site/languages 폴더의 언어 파일을 수정하세요.", + "language.name": "언어명", + "language.updated": "언어를 변경했습니다.", + + "languages": "언어", + "languages.default": "기본 언어", + "languages.empty": "언어가 없습니다.", + "languages.secondary": "보조 언어", + "languages.secondary.empty": "보조 언어가 없습니다.", + + "license": "라이선스", + "license.buy": "라이선스 구매", + "license.register": "등록", + "license.manage": "라이선스 관리", + "license.register.help": "Kirby를 등록하려면 이메일로 전송받은 라이선스 코드와 이메일 주소를 입력하세요.", + "license.register.label": "라이선스 코드를 입력하세요.", + "license.register.success": "Kirby와 함께해주셔서 감사합니다.", + "license.unregistered": "Kirby가 등록되지 않았습니다.", + "license.unregistered.label": "Kirby가 등록되지 않았습니다.", + + "link": "\uc77c\ubc18 \ub9c1\ud06c", + "link.text": "\ubb38\uc790", + + "loading": "로딩 중…", + + "lock.unsaved": "저장되지 않은 항목이 있습니다.", + "lock.unsaved.empty": "모든 페이지를 저장했습니다.", + "lock.isLocked": "다른 사용자({email})가 수정한 사항이 저장되지 않았습니다.", + "lock.file.isLocked": "파일을 편집할 수 없습니다. 다른 사용자({email})가 편집 중입니다.", + "lock.page.isLocked": "페이지를 편집할 수 없습니다. 다른 사용자({email})가 편집 중입니다.", + "lock.unlock": "잠금 해제", + "lock.isUnlocked": "다른 사용자가 이미 내용을 수정했으므로 현재 내용이 올바르게 저장되지 않았습니다. 저장되지 않은 내용은 다운로드해 수동으로 대치할 수 있습니다.", + + "login": "로그인", + "login.code.label.login": "로그인 코드", + "login.code.label.password-reset": "암호 초기화 코드", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "입력한 이메일 주소로 코드를 전송했습니다.", + "login.email.login.body": "{user.nameOrEmail} 님,\n\n{site} 패널에서 요청한 로그인 코드는 다음과 같습니다. 로그인 코드는 {timeout}분 동안 유효합니다.\n\n{code}\n\n로그인 코드를 요청한 적이 없다면, 이 이메일을 무시하거나 관리자에게 문의하세요. 보안을 위해 이 이메일은 다른 사람과 공유하지 마세요.", + "login.email.login.subject": "로그인 코드", + "login.email.password-reset.body": "{user.nameOrEmail} 님,\n\n{site} 패널에서 요청한 암호 초기화 코드는 다음과 같습니다. 암호 초기화 코드는 {timeout}분 동안 유효합니다.\n\n{code}\n\n암호 초기화 코드를 요청한 적이 없다면, 이 이메일을 무시하거나 관리자에게 문의하세요. 보안을 위해 이 이메일은 다른 사람과 공유하지 마세요.", + "login.email.password-reset.subject": "암호 초기화 코드", + "login.remember": "로그인 유지", + "login.reset": "암호 초기화", + "login.toggleText.code.email": "이메일 주소로 로그인", + "login.toggleText.code.email-password": "암호로 로그인", + "login.toggleText.password-reset.email": "암호 찾기", + "login.toggleText.password-reset.email-password": "로그인 화면으로", + + "logout": "\ub85c\uadf8\uc544\uc6c3", + + "menu": "메뉴", + "meridiem": "오전/오후", + "mime": "MIME 형식", + "minutes": "분", + + "month": "월", + "months.april": "4\uc6d4", + "months.august": "8\uc6d4", + "months.december": "12\uc6d4", + "months.february": "2월", + "months.january": "1\uc6d4", + "months.july": "7\uc6d4", + "months.june": "6\uc6d4", + "months.march": "3\uc6d4", + "months.may": "5\uc6d4", + "months.november": "11\uc6d4", + "months.october": "10\uc6d4", + "months.september": "9\uc6d4", + + "more": "더 보기", + "name": "이름", + "next": "다음", + "no": "아니요", + "off": "끔", + "on": "켬", + "open": "열기", + "open.newWindow": "새 창에서 열기", + "options": "옵션", + "options.none": "옵션이 없습니다.", + + "orientation": "비율", + "orientation.landscape": "가로로 긴 사각형", + "orientation.portrait": "세로로 긴 사각형", + "orientation.square": "정사각형", + + "page.blueprint": "블루프린트(/site/blueprints/pages/{blueprint}.yml)를 설정하세요.", + "page.changeSlug": "고유 주소 변경", + "page.changeSlug.fromTitle": "제목에서 가져오기", + "page.changeStatus": "상태 변경", + "page.changeStatus.position": "순서를 지정하세요.", + "page.changeStatus.select": "새 상태 선택", + "page.changeTemplate": "템플릿 변경", + "page.delete.confirm": "페이지({title})를 삭제할까요?", + "page.delete.confirm.subpages": "페이지에 하위 페이지가 있습니다. 모든 하위 페이지가 삭제됩니다.", + "page.delete.confirm.title": "페이지의 제목을 입력하세요.", + "page.draft.create": "초안 등록", + "page.duplicate.appendix": "복사", + "page.duplicate.files": "파일 복사", + "page.duplicate.pages": "페이지 복사", + "page.sort": "순서 변경", + "page.status": "상태", + "page.status.draft": "초안", + "page.status.draft.description": "로그인한 사용자나 URL을 통해 접근할 수 있습니다.", + "page.status.listed": "공개", + "page.status.listed.description": "누구나 읽을 수 있습니다.", + "page.status.unlisted": "비공개", + "page.status.unlisted.description": "URL을 통해 접근할 수 있습니다.", + + "pages": "페이지", + "pages.empty": "페이지가 없습니다.", + "pages.status.draft": "초안", + "pages.status.listed": "발행", + "pages.status.unlisted": "비공개", + + "pagination.page": "페이지", + + "password": "\uc554\ud638", + "paste": "붙여넣기", + "paste.after": "뒤로 붙여넣기", + "pixel": "픽셀", + "plugin": "플러그인", + "plugins": "플러그인", + "prev": "이전", + "preview": "미리 보기", + "remove": "삭제", + "rename": "이름 변경", + "replace": "\uad50\uccb4", + "retry": "\ub2e4\uc2dc \uc2dc\ub3c4", + "revert": "복원", + "revert.confirm": "저장되지 않은 내용을 삭제할까요?", + + "role": "역할", + "role.admin.description": "관리자는 모든 권한이 있습니다.", + "role.admin.title": "관리자", + "role.all": "전체", + "role.empty": "이 역할에 해당하는 사용자가 없습니다.", + "role.description.placeholder": "설명이 없습니다.", + "role.nobody.description": "대체 사용자는 아무 권한이 없습니다.", + "role.nobody.title": "사용자가 없습니다.", + + "save": "\uc800\uc7a5", + "search": "검색", + "search.min": "{min}자 이상 입력하세요.", + "search.all": "모두 보기", + "search.results.none": "해당하는 결과가 없습니다.", + + "section.required": "섹션이 필요합니다.", + + "security": "보안", + "select": "선택", + "server": "서버", + "settings": "설정", + "show": "보기", + "site.blueprint": "블루프린트(/site/blueprints/site.yml)를 설정하세요.", + "size": "크기", + "slug": "고유 주소", + "sort": "정렬", + + "stats.empty": "관련 기록이 없습니다.", + "system.issues.content": "/content 폴더의 권한을 확인하세요.", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "공개 서버상에서는 디버그 모드를 해제하세요.", + "system.issues.git": "/.git 폴더의 권한을 확인하세요.", + "system.issues.https": "HTTPS를 권장합니다.", + "system.issues.kirby": "/kirby 폴더의 권한을 확인하세요.", + "system.issues.site": "/site 폴더의 권한을 확인하세요.", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "업데이트 상태", + "system.updateStatus.error": "업데이트를 확인할 수 없습니다.", + "system.updateStatus.not-vulnerable": "알려진 취약성이 없습니다.", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "출시 전 버전", + "system.updateStatus.up-to-date": "최신 버전입니다.", + "system.updateStatus.update": "{ version } 버전으로 무료 업데이트", + "system.updateStatus.upgrade": "{ version } 버전으로 업그레이드", + + "title": "제목", + "template": "\ud15c\ud50c\ub9bf", + "today": "오늘", + + "toolbar.button.code": "코드", + "toolbar.button.bold": "강조", + "toolbar.button.email": "이메일 주소", + "toolbar.button.headings": "제목", + "toolbar.button.heading.1": "제목 1", + "toolbar.button.heading.2": "제목 2", + "toolbar.button.heading.3": "제목 3", + "toolbar.button.heading.4": "제목 4", + "toolbar.button.heading.5": "제목 5", + "toolbar.button.heading.6": "제목 6", + "toolbar.button.italic": "강조 2", + "toolbar.button.file": "파일", + "toolbar.button.file.select": "파일 선택", + "toolbar.button.file.upload": "파일 업로드", + "toolbar.button.link": "링크", + "toolbar.button.paragraph": "문단", + "toolbar.button.strike": "취소선", + "toolbar.button.ol": "숫자 목록", + "toolbar.button.underline": "밑줄", + "toolbar.button.ul": "기호 목록", + + "translation.author": "Kirby 팀", + "translation.direction": "ltr", + "translation.name": "한국어", + "translation.locale": "ko_KR", + + "upload": "업로드", + "upload.error.cantMove": "파일을 이동할 수 없습니다.", + "upload.error.cantWrite": "디스크를 읽을 수 없습니다.", + "upload.error.default": "파일을 업로드할 수 없습니다.", + "upload.error.extension": "파일 확장자를 확인하세요.", + "upload.error.formSize": "업로드한 파일이 허용된 크기(MAX_FILE_SIZE)를 초과했습니다.", + "upload.error.iniPostSize": "업로드한 파일이 PHP 환경 설정 파일(php.ini)에서 허용된 크기(post_max_size)를 초과했습니다.", + "upload.error.iniSize": "업로드한 파일이 PHP 환경 설정 파일(php.ini)에서 허용된 크기(upload_max_filesize)를 초과했습니다.", + "upload.error.noFile": "업로드한 파일이 없습니다.", + "upload.error.noFiles": "업로드한 파일이 없습니다.", + "upload.error.partial": "일부 파일을 업로드했습니다.", + "upload.error.tmpDir": "임시 폴더가 없습니다.", + "upload.errors": "오류", + "upload.progress": "업로드 중…", + + "url": "URL", + "url.placeholder": "https://example.com", + + "user": "사용자", + "user.blueprint": "블루프린트(/site/blueprints/users/{blueprint}.yml)에 섹션과 필드를 추가할 수 있습니다.", + "user.changeEmail": "이메일 주소 변경", + "user.changeLanguage": "언어 변경", + "user.changeName": "사용자명 변경", + "user.changePassword": "암호 변경", + "user.changePassword.new": "새 암호", + "user.changePassword.new.confirm": "새 암호 확인", + "user.changeRole": "역할 변경", + "user.changeRole.select": "새 역할 선택", + "user.create": "사용자 추가", + "user.delete": "사용자 삭제", + "user.delete.confirm": "사용자({email})를 삭제할까요?", + + "users": "사용자", + + "version": "버전", + "version.current": "현재 버전", + "version.latest": "최신 버전", + "versionInformation": "버전 정보", + + "view.account": "계정", + "view.installation": "\uc124\uce58", + "view.languages": "언어", + "view.resetPassword": "암호 초기화", + "view.site": "사이트", + "view.system": "시스템", + "view.users": "\uc0ac\uc6a9\uc790", + + "welcome": "반갑습니다.", + "year": "년", + "yes": "네" } diff --git a/kirby/i18n/translations/lt.json b/kirby/i18n/translations/lt.json index 8741d72..fdd78f5 100644 --- a/kirby/i18n/translations/lt.json +++ b/kirby/i18n/translations/lt.json @@ -1,573 +1,596 @@ { - "account.changeName": "Change your name", - "account.delete": "Delete your account", - "account.delete.confirm": "Do you really want to delete your account? You will be logged out immediately. Your account cannot be recovered.", - - "add": "Pridėti", - "author": "Author", - "avatar": "Profilio nuotrauka", - "back": "Atgal", - "cancel": "Atšaukti", - "change": "Keisti", - "close": "Uždaryti", - "confirm": "Ok", - "collapse": "Sutraukti", - "collapse.all": "Sutraukti viską", - "copy": "Kopijuoti", - "copy.all": "Kopijuoti visus", - "create": "Sukurti", - - "date": "Data", - "date.select": "Pasirinkite datą", - - "day": "Diena", - "days.fri": "Pen", - "days.mon": "Pir", - "days.sat": "Šeš", - "days.sun": "Sek", - "days.thu": "Ket", - "days.tue": "Ant", - "days.wed": "Tre", - - "debugging": "Debugging", - - "delete": "Pašalinti", - "delete.all": "Pašalinti viską", - - "dialog.files.empty": "Nėra failų pasirinkimui", - "dialog.pages.empty": "Nėra puslapių pasirinkimui", - "dialog.users.empty": "Nėra vartotojų pasirinkimui", - - "dimensions": "Išmatavimai", - "disabled": "Išjungta", - "discard": "Atšaukti", - "download": "Parsisiųsti", - "duplicate": "Dublikuoti", - - "edit": "Redaguoti", - - "email": "El. paštas", - "email.placeholder": "mail@example.com", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Environment", - - "error.access.code": "Neteisinas kodas", - "error.access.login": "Neteisingas prisijungimo vardas", - "error.access.panel": "Neturite teisės prisijungti prie valdymo pulto", - "error.access.view": "Neturite teisės peržiūrėti šios valdymo pulto dalies", - - "error.avatar.create.fail": "Nepavyko įkelti profilio nuotraukos", - "error.avatar.delete.fail": "Nepavyko pašalinti profilio nuotraukos", - "error.avatar.dimensions.invalid": "Profilio nuotraukos plotis ar aukštis turėtų būti iki 3000 pikselių", - "error.avatar.mime.forbidden": "Profilio nuotrauka turi būti JPEG arba PNG", - - "error.blueprint.notFound": "Blueprint \"{name}\" negali būti užkrautas", - - "error.blocks.max.plural": "Didžiausias įmanomas blokų kiekis: {max}", - "error.blocks.max.singular": "Jūs galite pridėti daugiausiai vieną bloką", - "error.blocks.min.plural": "Minimalus blokų kiekis: {min}", - "error.blocks.min.singular": "Jūs turite pridėti bent vieną bloką", - "error.blocks.validation": "Bloke {index} yra klaida", - - "error.email.preset.notFound": "El. pašto paruoštukas \"{name}\" nerastas", - - "error.field.converter.invalid": "Neteisingas konverteris \"{converter}\"", - - "error.file.changeName.empty": "Pavadinimas negali būti tuščias", - "error.file.changeName.permission": "Neturite teisės pakeisti failo pavadinimo \"{filename}\"", - "error.file.duplicate": "Failas su pavadinimu \"{filename}\" jau yra", - "error.file.extension.forbidden": "Failo tipas (plėtinys) \"{extension}\" neleidžiamas", - "error.file.extension.invalid": "Neteisingas plėtinys: {extension}", - "error.file.extension.missing": "Failui \"{filename}\" trūksta tipo (plėtinio)", - "error.file.maxheight": "Failo aukštis neturi viršyti {height} px", - "error.file.maxsize": "Failas per didelis", - "error.file.maxwidth": "Failo plotis neturi viršyti {width} px", - "error.file.mime.differs": "Įkėliamas failas turi būti tokio pat mime tipo \"{mime}\"", - "error.file.mime.forbidden": "Media tipas \"{mime}\" neleidžiamas", - "error.file.mime.invalid": "Neteisingas mime tipas: {mime}", - "error.file.mime.missing": "Failui \"{filename}\" nepavyko atpažinti media (mime) tipo", - "error.file.minheight": "Failo aukštis turi būti bent {height} px", - "error.file.minsize": "Failas per mažas", - "error.file.minwidth": "Failo plotis turi būti bent {width} px", - "error.file.name.missing": "Failo pavadinimas negali būti tuščias", - "error.file.notFound": "Failas \"{filename}\" nerastas", - "error.file.orientation": "Failo orientacija turi būti \"{orientation}\"", - "error.file.type.forbidden": "Jūs neturite teisės įkelti {type} tipo failų", - "error.file.type.invalid": "Neteisingas failo tipas: {type}", - "error.file.undefined": "Failas nerastas", - - "error.form.incomplete": "🙏 Prašome ištaisyti visas formos klaidas…", - "error.form.notSaved": "Formos nepavyko išsaugoti", - - "error.language.code": "Prašome įrašyti teisingą kalbos kodą", - "error.language.duplicate": "Tokia kalba jau yra", - "error.language.name": "Prašome įrašyti teisingą kalbos pavadinimą", - "error.language.notFound": "Nepavyko rasti šios kalbos", - - "error.layout.validation.block": "Yra klaida bloke {blockIndex} išdėstyme {layoutIndex}", - "error.layout.validation.settings": "Yra klaida išdėstymo {index} nustatymuose", - - "error.license.format": "Prašome įrašyti teisingą licenzijos kodą", - "error.license.email": "Prašome įrašyti teisingą el. pašto adresą", - "error.license.verification": "Nepavyko patikrinti licenzijos", - - "error.offline": "The Panel is currently offline", - - "error.page.changeSlug.permission": "Neturite teisės pakeisti \"{slug}\" URL", - "error.page.changeStatus.incomplete": "Puslapis turi klaidų ir negali būti paskelbtas", - "error.page.changeStatus.permission": "Šiam puslapiui negalima pakeisti statuso", - "error.page.changeStatus.toDraft.invalid": "Puslapio \"{slug}\" negalima paversti juodraščiu", - "error.page.changeTemplate.invalid": "Šablono puslapiui \"{slug}\" negalima keisti", - "error.page.changeTemplate.permission": "Neturite leidimo keisti šabloną puslapiui \"{slug}\"", - "error.page.changeTitle.empty": "Pavadinimas negali būti tuščias", - "error.page.changeTitle.permission": "Neturite leidimo keisti pavadinimo puslapiui \"{slug}\"", - "error.page.create.permission": "Neturite leidimo sukurti \"{slug}\"", - "error.page.delete": "Puslapio \"{slug}\" negalima pašalinti", - "error.page.delete.confirm": "Įrašykite puslapio pavadinimą, tam kad patvirtintumėte", - "error.page.delete.hasChildren": "Puslapis turi vidinių puslapių, dėl to negalima jo pašalinti", - "error.page.delete.permission": "Neturite leidimo šalinti \"{slug}\"", - "error.page.draft.duplicate": "Puslapio juodraštis su URL pabaiga \"{slug}\" jau yra", - "error.page.duplicate": "Puslapis su URL pabaiga \"{slug}\" jau yra", - "error.page.duplicate.permission": "Neturite leidimo dubliuoti \"{slug}\"", - "error.page.notFound": "Puslapis \"{slug}\" nerastas", - "error.page.num.invalid": "Įrašykite teisingą eiliškumo numerį. Numeris negali būti neigiamas.", - "error.page.slug.invalid": "Įrašykite teisingą URL priedą", - "error.page.slug.maxlength": "url adreso maksimalus simbolių kiekis: \"{length}\"", - "error.page.sort.permission": "Puslapiui \"{slug}\" negalima pakeisti eiliškumo", - "error.page.status.invalid": "Nustatykite teisingą puslapio statusą", - "error.page.undefined": "Puslapis nerastas", - "error.page.update.permission": "Neturite leidimo atnaujinti \"{slug}\"", - - "error.section.files.max.plural": "Į sekciją \"{section}\" negalima pridėti daugiau nei {max} failų", - "error.section.files.max.singular": "Į sekciją \"{section}\" negalima pridėti daugiau nei vieną failą", - "error.section.files.min.plural": "Sekcija \"{section}\" reikalauja bent {min} failų", - "error.section.files.min.singular": "Sekcija \"{section}\" reikalauja bent vieno failo", - - "error.section.pages.max.plural": "Į sekciją \"{section}\" negalima pridėti daugiau nei {max} puslapių", - "error.section.pages.max.singular": "Į sekciją \"{section}\" negalima pridėti daugiau nei vieną puslapį", - "error.section.pages.min.plural": "Sekcija \"{section}\" reikalauja bent {min} puslapių", - "error.section.pages.min.singular": "Sekcija \"{section}\" reikalauja bent vieno puslapio", - - "error.section.notLoaded": "Sekcija \"{name}\" negali būti užkrauta", - "error.section.type.invalid": "Sekcijos tipas \"{type}\" yra neteisingas", - - "error.site.changeTitle.empty": "Pavadinimas negali būti tuščias", - "error.site.changeTitle.permission": "Neturite leidimo keisti svetainės pavadinimo", - "error.site.update.permission": "Neturite leidimo atnaujinti svetainės", - - "error.template.default.notFound": "Nėra šablono pagal nutylėjimą", - - "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Neturite leidimo keisti vartotojo \"{name}\" el. paštą", - "error.user.changeLanguage.permission": "Neturite leidimo keisti vartotojo \"{name}\" kalbą", - "error.user.changeName.permission": "Neturite leidimo keisti vartotojo \"{name}\" vardą", - "error.user.changePassword.permission": "Neturite leidimo keisti vartotojo \"{name}\" slaptažodį", - "error.user.changeRole.lastAdmin": "Vienintelio administratoriaus rolės negalima pakeisti", - "error.user.changeRole.permission": "Neturite leidimo pakeisti vartotojo \"{name}\" rolės", - "error.user.changeRole.toAdmin": "Jūs neturite teisių suteikti administratoriaus rolę", - "error.user.create.permission": "Neturite leidimo sukurti šį vartotoją", - "error.user.delete": "Vartotojo \"{name}\" negalima pašalinti", - "error.user.delete.lastAdmin": "Vienintelio administratoriaus negalima pašalinti", - "error.user.delete.lastUser": "Vienintelio vartotojo negalima pašalinti", - "error.user.delete.permission": "Neturite leidimo pašalinti vartotoją \"{name}\"", - "error.user.duplicate": "Vartotojas su el. paštu \"{email}\" jau yra", - "error.user.email.invalid": "Įrašykite teisingą el. pašto adresą", - "error.user.language.invalid": "Įrašykite teisingą kalbą", - "error.user.notFound": "Vartotojas \"{name}\" nerastas", - "error.user.password.invalid": "Prašome įrašyti galiojantį slaptažodį. Slaptažodį turi sudaryti bent 8 simboliai.", - "error.user.password.notSame": "Slaptažodžiai nesutampa", - "error.user.password.undefined": "Vartotojas neturi slaptažodžio", - "error.user.password.wrong": "Neteisingas slaptažodis", - "error.user.role.invalid": "Įrašykite teisingą rolę", - "error.user.undefined": "Vartotojas nerastas", - "error.user.update.permission": "Neturite teisės keisti vartotojo \"{name}\"", - - "error.validation.accepted": "Prašome patvirtinti", - "error.validation.alpha": "Prašome įrašyti tik raides a-z", - "error.validation.alphanum": "Prašome įrašyti tik raides a-z arba skaičius 0-9", - "error.validation.between": "Prašome įrašyti reikšmę tarp \"{min}\" ir \"{max}\"", - "error.validation.boolean": "Patvirtinkite arba atšaukite", - "error.validation.contains": "Prašome įrašyti reikšmę, kuri turėtų \"{needle}\"", - "error.validation.date": "Prašome įrašyti korektišką datą", - "error.validation.date.after": "Įrašykite datą nuo {date}", - "error.validation.date.before": "Įrašykite datą iki {date}", - "error.validation.date.between": "Įrašykite datą tarp {min} ir {max}", - "error.validation.denied": "Prašome neleisti", - "error.validation.different": "Reikšmė neturi būti \"{other}\"", - "error.validation.email": "Prašome įrašyti korektišką el. paštą", - "error.validation.endswith": "Reikšmė turi baigtis su \"{end}\"", - "error.validation.filename": "Prašome įrašyti teisingą failo pavadinimą", - "error.validation.in": "Prašome įrašyti vieną iš šių: ({in})", - "error.validation.integer": "Prašome įrašyti teisingą sveiką skaičių", - "error.validation.ip": "Prašome įrašyti teisingą IP adresą", - "error.validation.less": "Prašome įrašyti mažiau nei {max}", - "error.validation.match": "Reikšmė nesutampa su laukiamu šablonu", - "error.validation.max": "Prašome įrašyti reikšmę lygią arba didesnę, nei {max}", - "error.validation.maxlength": "Prašome įrašyti trumpesnę reikšmę. (max. {max} characters)", - "error.validation.maxwords": "Please enter no more than {max} word(s)", - "error.validation.min": "Please enter a value equal to or greater than {min}", - "error.validation.minlength": "Prašome įrašyti ilgesnę reikšmę. (min. {min} characters)", - "error.validation.minwords": "Prašome įrašyti bent {min} žodžius", - "error.validation.more": "Prašome įrašyti daugiau nei {min}", - "error.validation.notcontains": "Prašome įrašyti reikšmę, kuri neturi \"{needle}\"", - "error.validation.notin": "Prašome neįrašyti vieną iš šių: ({notIn})", - "error.validation.option": "Prašome pasirinkti korektišką opciją", - "error.validation.num": "Prašome įrašyti teisingą numerį", - "error.validation.required": "Prašome įrašyti ką nors", - "error.validation.same": "Prašome įrašyti \"{other}\"", - "error.validation.size": "Reikšmės dydis turi būti \"{size}\"", - "error.validation.startswith": "Reikšmė turi prasidėti su \"{start}\"", - "error.validation.time": "Prašome įrašyti korektišką laiką", - "error.validation.time.after": "Įrašykite laiką po {time}", - "error.validation.time.before": "Įrašykite laiką prieš {time}", - "error.validation.time.between": "Įrašykite laiką tarp {min} ir {max}", - "error.validation.url": "Prašome įrašyti teisingą URL", - - "expand": "Išskleisti", - "expand.all": "Išskleisti viską", - - "field.required": "Laukas privalomas", - "field.blocks.changeType": "Pakeisti tipą", - "field.blocks.code.name": "Kodas", - "field.blocks.code.language": "Kalba", - "field.blocks.code.placeholder": "Jūsų kodas ...", - "field.blocks.delete.confirm": "Ar tikrai norite pašalinti šį bloką?", - "field.blocks.delete.confirm.all": "Ar tikrai norite pašalinti visus blokus?", - "field.blocks.delete.confirm.selected": "Ar tikrai norite pašalinti pasirinktus blokus?", - "field.blocks.empty": "Dar nėra blokų", - "field.blocks.fieldsets.label": "Pasirinkite bloko tipą ...", - "field.blocks.fieldsets.paste": "Spauskite {{ shortcut }} įterpti/importuoti nukopijuotus blokus", - "field.blocks.gallery.name": "Galerija", - "field.blocks.gallery.images.empty": "Dar nėra nuotraukų", - "field.blocks.gallery.images.label": "Nuotraukos", - "field.blocks.heading.level": "Lygis", - "field.blocks.heading.name": "Antraštė", - "field.blocks.heading.text": "Tekstas", - "field.blocks.heading.placeholder": "Antraštė ...", - "field.blocks.image.alt": "Alternatyvus tekstas", - "field.blocks.image.caption": "Aprašymas", - "field.blocks.image.crop": "Kirpti", - "field.blocks.image.link": "Nuoroda", - "field.blocks.image.location": "Šaltinis", - "field.blocks.image.name": "Nuotrauka", - "field.blocks.image.placeholder": "Pasirinkite nuotrauką", - "field.blocks.image.ratio": "Proporcijos", - "field.blocks.image.url": "Nuotraukos URL", - "field.blocks.line.name": "Linija", - "field.blocks.list.name": "Sąrašas", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Tekstas", - "field.blocks.markdown.placeholder": "Markdown ...", - "field.blocks.quote.name": "Citata", - "field.blocks.quote.text.label": "Tekstas", - "field.blocks.quote.text.placeholder": "Citata ...", - "field.blocks.quote.citation.label": "Citatos turinys", - "field.blocks.quote.citation.placeholder": "autorius", - "field.blocks.text.name": "Tekstas", - "field.blocks.text.placeholder": "Tekstas ...", - "field.blocks.video.caption": "Aprašymas", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Įrašykite video URL", - "field.blocks.video.url.label": "Video-URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Pasirinkti", - - "field.layout.delete": "Pašalinti eilutę", - "field.layout.delete.confirm": "Ar tikrai norite pašalinti šią eilutę", - "field.layout.empty": "Dar nėra eilučių", - "field.layout.select": "Pasirinkite išdėstymą", - - "field.pages.empty": "Dar nėra puslapių", - "field.structure.delete.confirm": "Ar tikrai norite pašalinti šią eilutę?", - "field.structure.empty": "Dar nėra įrašų", - "field.users.empty": "Dar nėra vartotojų", - - "file.blueprint": "Šis failas dar neturi blueprint. Galite nustatyti jį per /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Ar tikrai norite pašalinti
{filename}?", - "file.sort": "Pakeisti poziciją", - - "files": "Failai", - "files.empty": "Įkelti", - - "hide": "Paslėpti", - "hour": "Valanda", - "import": "Importuoti", - "info": "Info", - "insert": "Įterpti", - "insert.after": "Įterpti po", - "insert.before": "Įterpti prieš", - "install": "Įdiegti", - - "installation": "Įdiegimas", - "installation.completed": "Valdymo pultas įdiegtas", - "installation.disabled": "Pagal nutylėjimą valdymo pulto įdiegimas viešuose serveriuose yra negalimas. Prašome įdiegti lokalioje aplinkoje arba įgalinkite jį su panel.install opcija.", - "installation.issues.accounts": "Katalogas /site/accounts neegzistuoja arba neturi įrašymo teisių", - "installation.issues.content": "Katalogas /content neegzistuoja arba neturi įrašymo teisių", - "installation.issues.curl": "Plėtinys CURL yra privalomas", - "installation.issues.headline": "Nepavyko įdiegti valdymo pulto", - "installation.issues.mbstring": "Plėtinys MB String yra privalomas", - "installation.issues.media": "Katalogas /media neegzistuoja arba neturi įrašymo teisių", - "installation.issues.php": "Įsitikinkite, kad naudojama PHP 7+", - "installation.issues.server": "Kirby reikalauja Apache, Nginx arba Caddy", - "installation.issues.sessions": "Katalogas /site/sessions neegzistuoja arba neturi įrašymo teisių", - - "language": "Kalba", - "language.code": "Kodas", - "language.convert": "Padaryti pagrindinį", - "language.convert.confirm": "

Do you really want to convert {name} to the default language? This cannot be undone.

If {name} has untranslated content, there will no longer be a valid fallback and parts of your site might be empty.

", - "language.create": "Pridėti naują kalbą", - "language.delete.confirm": "Ar tikrai norite pašalinti {name} kalbą, kartu su visais vertimais? Grąžinti nebus įmanoma! 🙀", - "language.deleted": "Kalba pašalinta", - "language.direction": "Skaitymo kryptis", - "language.direction.ltr": "Iš kairės į dešinę", - "language.direction.rtl": "Iš dešinės į kairę", - "language.locale": "PHP locale string", - "language.locale.warning": "Jūs naudojate pasirinktinį lokalės nustatymą. Prašome pakeisti jį faile /site/languages", - "language.name": "Pavadinimas", - "language.updated": "Kalba atnaujinta", - - "languages": "Kalbos", - "languages.default": "Pagrindinė kalba", - "languages.empty": "Dar nėra kalbų", - "languages.secondary": "Papildomos kalbos", - "languages.secondary.empty": "Dar nėra papildomų kalbų", - - "license": "Licenzija", - "license.buy": "Pirkti licenziją", - "license.register": "Registruoti", - "license.manage": "Manage your licenses", - "license.register.help": "Licenzijos kodą gavote el. paštu po apmokėjimo. Prašome įterpti čia, kad sistema būtų užregistruota.", - "license.register.label": "Prašome įrašyti jūsų licenzijos kodą", - "license.register.success": "Ačiū, kad palaikote Kirby", - "license.unregistered": "Tai neregistruota Kirby demo versija", - "license.unregistered.label": "Unregistered", - - "link": "Nuoroda", - "link.text": "Nuorodos tekstas", - - "loading": "Kraunasi", - - "lock.unsaved": "Neišsaugoti pakeitimai", - "lock.unsaved.empty": "Nebeliko neišsaugotų pakeitimų", - "lock.isLocked": "Vartotojo {email} neišsaugoti pakeitimai", - "lock.file.isLocked": "Šį failą dabar redaguoja kitas vartotojas {email}, tad jo negalima pekeisti.", - "lock.page.isLocked": "Šį puslapį dabar redaguoja kitas vartotojas {email}, tad jo negalima pekeisti.", - "lock.unlock": "Atrakinti", - "lock.isUnlocked": "Jūsų neišsaugoti pakeitimai buvo perrašyti kito vartotojo. Galite parsisiųsti savo pakeitimus ir įkelti juos rankiniu būdu.", - - "login": "Prisijungti", - "login.code.label.login": "Prisijungimo kodas", - "login.code.label.password-reset": "Slaptažodžio atstatymo kodas", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "Jei jūsų el. paštas yra užregistruotas, užklaistas kodas buvo išsiųstas el. paštu.", - "login.email.login.body": "Sveiki, {user.nameOrEmail},\n\nNeseniai užklausėte prisijungimo kodo svetainėje {site}.\nŠis kodas galios {timeout} min.:\n\n{code}\n\nJei neprašėte šio kodo, tiesiog ignoruokite, arba susisiekite su administratoriumi.\nDėl saugumo, prašome NEPERSIŲSTI šio laiško.", - "login.email.login.subject": "Jūsų prisijungimo kodas", - "login.email.password-reset.body": "Sveiki, {user.nameOrEmail},\n\nNeseniai užklausėte naujo slaptažodžio kūrimo kodo svetainėje {site}.\nŠis kodas galios {timeout} min.:\n\n{code}\n\nJei neprašėte šio kodo, tiesiog ignoruokite, arba susisiekite su administratoriumi.\nDėl saugumo, prašome NEPERSIŲSTI šio laiško", - "login.email.password-reset.subject": "Jūsų slaptažodžio atstatymo kodas ", - "login.remember": "Likti prisijungus", - "login.reset": "Sukurti naują slaptažodį", - "login.toggleText.code.email": "Prisijungti su el. paštu", - "login.toggleText.code.email-password": "Prisijungti su slaptažodžiu", - "login.toggleText.password-reset.email": "Pamiršote slaptažodį?", - "login.toggleText.password-reset.email-password": "← Atgal į prisijungimą", - - "logout": "Atsijungti", - - "menu": "Meniu", - "meridiem": "AM/PM", - "mime": "Media Tipas", - "minutes": "Minutės", - - "month": "Mėnuo", - "months.april": "Balandis", - "months.august": "August", - "months.december": "Gruodis", - "months.february": "Vasaris", - "months.january": "Sausis", - "months.july": "Liepa", - "months.june": "Birželis", - "months.march": "Kovas", - "months.may": "Gegužė", - "months.november": "Lapkritis", - "months.october": "Spalis", - "months.september": "Rugsėjis", - - "more": "Daugiau", - "name": "Pavadinimas", - "next": "Toliau", - "no": "ne", - "off": "ne", - "on": "taip", - "open": "Atidaryti", - "open.newWindow": "Atidaryti naujame lange", - "options": "Pasirinkimai", - "options.none": "Nėra pasirinkimų", - - "orientation": "Orientacija", - "orientation.landscape": "Horizontali", - "orientation.portrait": "Portretas", - "orientation.square": "Kvadratas", - - "page.blueprint": "Šis puslapis dar neturi blueprint. Galite jį nustatyti per /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Pakeisti URL", - "page.changeSlug.fromTitle": "Sukurti URL pagal pavadinimą", - "page.changeStatus": "Pakeisti statusą", - "page.changeStatus.position": "Pasirinkite poziciją", - "page.changeStatus.select": "Pasirinkite statusą", - "page.changeTemplate": "Pakeisti šabloną", - "page.delete.confirm": "🙀 Ar tikrai norite pašalinti puslapį {title}?", - "page.delete.confirm.subpages": "Šis puslapis turi sub-puslapių.
Visi sub-puslapiai taip pat bus pašalinti.", - "page.delete.confirm.title": "Įrašykite puslapio pavadinimą tam, kad patvirtinti", - "page.draft.create": "Sukurti juodraštį", - "page.duplicate.appendix": "Kopijuoti", - "page.duplicate.files": "Kopijuoti failus", - "page.duplicate.pages": "Kopijuoti puslapius", - "page.sort": "Pakeisti poziciją", - "page.status": "Statusas", - "page.status.draft": "Juodraštis", - "page.status.draft.description": "Šis puslapis yra juodraščio režime ir prieinamas tik redaktoriams arba per slaptą nuorodą", - "page.status.listed": "Paskelbtas", - "page.status.listed.description": "Matomas viešai visiems", - "page.status.unlisted": "Nerodomas", - "page.status.unlisted.description": "Rodomas viešai visiems, bet tik per URL", - - "pages": "Puslapiai", - "pages.empty": "Dar nėra puslapių", - "pages.status.draft": "Juodraščiai", - "pages.status.listed": "Paskelbti", - "pages.status.unlisted": "Nerodomi", - - "pagination.page": "Puslapis", - - "password": "Slaptažodis", - "paste": "Įterpti", - "paste.after": "Įterpti po", - "pixel": "Pikselis", - "plugins": "Plugins", - "prev": "Ankstesnis", - "preview": "Peržiūra", - "remove": "Pašalinti", - "rename": "Pervadinti", - "replace": "Apkeisti", - "retry": "Bandyti dar", - "revert": "Grąžinti", - "revert.confirm": "Ar tikrai norite atšaukti visus neišsaugotus pakeitimus?", - - "role": "Rolė", - "role.admin.description": "Admin turi visas teises", - "role.admin.title": "Admin", - "role.all": "Visos", - "role.empty": "Nėra vartotojų su tokia role", - "role.description.placeholder": "Be aprašymo", - "role.nobody.description": "Ši rolė bus naudojama jei nenustatytos jokios teisės", - "role.nobody.title": "Niekas", - - "save": "Išsaugoti", - "search": "Ieškoti", - "search.min": "Minimalus simbolių kiekis paieškai: {min}", - "search.all": "Rodyti viską", - "search.results.none": "Nėra rezultatų", - - "section.required": "Sekcija privaloma", - - "security": "Security", - "select": "Pasirinkti", - "server": "Server", - "settings": "Nustatymai", - "show": "Rodyti", - "site.blueprint": "Svetainė neturi blueprint. Jūs galite nustatyti jį /site/blueprints/site.yml", - "size": "Dydis", - "slug": "URL pabaiga", - "sort": "Rikiuoti", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Pavadinimas", - "template": "Puslapio šablonas", - "today": "Šiandien", - - "toolbar.button.code": "Kodas", - "toolbar.button.bold": "Bold", - "toolbar.button.email": "El. paštas", - "toolbar.button.headings": "Antraštės", - "toolbar.button.heading.1": "Heading 1", - "toolbar.button.heading.2": "Heading 2", - "toolbar.button.heading.3": "Heading 3", - "toolbar.button.heading.4": "Antrašte 4", - "toolbar.button.heading.5": "Antrašte 5", - "toolbar.button.heading.6": "Antrašte 6", - "toolbar.button.italic": "Italic", - "toolbar.button.file": "Failas", - "toolbar.button.file.select": "Pasirinkite failą", - "toolbar.button.file.upload": "Įkelti failą", - "toolbar.button.link": "Nuoroda", - "toolbar.button.paragraph": "Paragrafas", - "toolbar.button.strike": "Perbraukimas", - "toolbar.button.ol": "Sąrašas su skaičiais", - "toolbar.button.underline": "Pabraukimas", - "toolbar.button.ul": "Sąrašas su taškais", - - "translation.author": "Roman U", - "translation.direction": "ltr", - "translation.name": "Lietuvių", - "translation.locale": "lt_LT", - - "upload": "Įkelti", - "upload.error.cantMove": "Įkeltas failas negali būti perkeltas", - "upload.error.cantWrite": "Nepavyko įrašyti failo į diską", - "upload.error.default": "Nepavyko įkelti failo", - "upload.error.extension": "Neįmanoma įkelti tokio tipo failo", - "upload.error.formSize": "Įkeltas failas viršija MAX_FILE_SIZE nustatymą, kuris buvo nurodytas formoje", - "upload.error.iniPostSize": "Įkeliamas failas viršija post_max_size nustatymą iš php.ini", - "upload.error.iniSize": "Įkeltas failas viršija upload_max_filesize nustatymą faile php.ini", - "upload.error.noFile": "Failas nebuvo įkeltas", - "upload.error.noFiles": "Failai nebuvo įkelti", - "upload.error.partial": "Failas įkeltas tik iš dalies", - "upload.error.tmpDir": "Trūksta laikinojo katalogo", - "upload.errors": "Klaida", - "upload.progress": "Įkėlimas…", - - "url": "Url", - "url.placeholder": "https://example.com", - - "user": "Vartotojas", - "user.blueprint": "Galite nustatyti papildomas sekcijas ir formos laukelius šiam vartotojui per /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Keisti el. paštą", - "user.changeLanguage": "Keisti kalbą", - "user.changeName": "Pervadinti vartotoją", - "user.changePassword": "Keisti slaptažodį", - "user.changePassword.new": "Naujas slaptažodis", - "user.changePassword.new.confirm": "Patvirtinti naują slaptažodį…", - "user.changeRole": "Keisti rolę", - "user.changeRole.select": "Pasirinkti naują rolę", - "user.create": "Pridėti naują vartotoją", - "user.delete": "Pašalinti šį vartotoją", - "user.delete.confirm": "Ar tikrai norite pašalinti vartotoją
{email}?", - - "users": "Vartotojai", - - "version": "Versija", - - "view.account": "Jūsų paskyra", - "view.installation": "Installation", - "view.languages": "Kalbos", - "view.resetPassword": "Sukurti naują slaptažodį", - "view.site": "Svetainė", - "view.system": "System", - "view.users": "Vartotojai", - - "welcome": "Sveiki", - "year": "Metai", - "yes": "taip" + "account.changeName": "Pakeisti savo vardą", + "account.delete": "Panaikinti savo paskyrą", + "account.delete.confirm": "Ar tikrai norite panaikinti savo paskyrą? Jūs iš karto atsijungsite. Paskyros bus neįmanoma atstatyti.", + + "add": "Pridėti", + "author": "Autorius", + "avatar": "Profilio nuotrauka", + "back": "Atgal", + "cancel": "Atšaukti", + "change": "Keisti", + "close": "Uždaryti", + "confirm": "Ok", + "collapse": "Sutraukti", + "collapse.all": "Sutraukti viską", + "copy": "Kopijuoti", + "copy.all": "Kopijuoti visus", + "create": "Sukurti", + + "date": "Data", + "date.select": "Pasirinkite datą", + + "day": "Diena", + "days.fri": "Pen", + "days.mon": "Pir", + "days.sat": "Šeš", + "days.sun": "Sek", + "days.thu": "Ket", + "days.tue": "Ant", + "days.wed": "Tre", + + "debugging": "Debugging", + + "delete": "Pašalinti", + "delete.all": "Pašalinti viską", + + "dialog.files.empty": "Nėra failų pasirinkimui", + "dialog.pages.empty": "Nėra puslapių pasirinkimui", + "dialog.users.empty": "Nėra vartotojų pasirinkimui", + + "dimensions": "Išmatavimai", + "disabled": "Išjungta", + "discard": "Atšaukti", + "download": "Parsisiųsti", + "duplicate": "Dublikuoti", + + "edit": "Redaguoti", + + "email": "El. paštas", + "email.placeholder": "mail@example.com", + + "entries": "Įrašai", + "entry": "Įrašas", + + "environment": "Aplinka", + + "error.access.code": "Neteisinas kodas", + "error.access.login": "Neteisingas prisijungimo vardas", + "error.access.panel": "Neturite teisės prisijungti prie valdymo pulto", + "error.access.view": "Neturite teisės peržiūrėti šios valdymo pulto dalies", + + "error.avatar.create.fail": "Nepavyko įkelti profilio nuotraukos", + "error.avatar.delete.fail": "Nepavyko pašalinti profilio nuotraukos", + "error.avatar.dimensions.invalid": "Profilio nuotraukos plotis ar aukštis turėtų būti iki 3000 pikselių", + "error.avatar.mime.forbidden": "Profilio nuotrauka turi būti JPEG arba PNG", + + "error.blueprint.notFound": "Blueprint \"{name}\" negali būti užkrautas", + + "error.blocks.max.plural": "Didžiausias įmanomas blokų kiekis: {max}", + "error.blocks.max.singular": "Jūs galite pridėti daugiausiai vieną bloką", + "error.blocks.min.plural": "Minimalus blokų kiekis: {min}", + "error.blocks.min.singular": "Jūs turite pridėti bent vieną bloką", + "error.blocks.validation": "Yra klaida laukelyje \"{field}\" bloke {index} naudojant bloko tipą \"{fieldset}\"", + + "error.email.preset.notFound": "El. pašto paruoštukas \"{name}\" nerastas", + + "error.field.converter.invalid": "Neteisingas konverteris \"{converter}\"", + + "error.file.changeName.empty": "Pavadinimas negali būti tuščias", + "error.file.changeName.permission": "Neturite teisės pakeisti failo pavadinimo \"{filename}\"", + "error.file.duplicate": "Failas su pavadinimu \"{filename}\" jau yra", + "error.file.extension.forbidden": "Failo tipas (plėtinys) \"{extension}\" neleidžiamas", + "error.file.extension.invalid": "Neteisingas plėtinys: {extension}", + "error.file.extension.missing": "Failui \"{filename}\" trūksta tipo (plėtinio)", + "error.file.maxheight": "Failo aukštis neturi viršyti {height} px", + "error.file.maxsize": "Failas per didelis", + "error.file.maxwidth": "Failo plotis neturi viršyti {width} px", + "error.file.mime.differs": "Įkėliamas failas turi būti tokio pat mime tipo \"{mime}\"", + "error.file.mime.forbidden": "Media tipas \"{mime}\" neleidžiamas", + "error.file.mime.invalid": "Neteisingas mime tipas: {mime}", + "error.file.mime.missing": "Failui \"{filename}\" nepavyko atpažinti media (mime) tipo", + "error.file.minheight": "Failo aukštis turi būti bent {height} px", + "error.file.minsize": "Failas per mažas", + "error.file.minwidth": "Failo plotis turi būti bent {width} px", + "error.file.name.missing": "Failo pavadinimas negali būti tuščias", + "error.file.notFound": "Failas \"{filename}\" nerastas", + "error.file.orientation": "Failo orientacija turi būti \"{orientation}\"", + "error.file.type.forbidden": "Jūs neturite teisės įkelti {type} tipo failų", + "error.file.type.invalid": "Neteisingas failo tipas: {type}", + "error.file.undefined": "Failas nerastas", + + "error.form.incomplete": "🙏 Prašome ištaisyti visas formos klaidas…", + "error.form.notSaved": "Formos nepavyko išsaugoti", + + "error.language.code": "Prašome įrašyti teisingą kalbos kodą", + "error.language.duplicate": "Tokia kalba jau yra", + "error.language.name": "Prašome įrašyti teisingą kalbos pavadinimą", + "error.language.notFound": "Nepavyko rasti šios kalbos", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "Yra klaida išdėstymo {index} nustatymuose", + + "error.license.format": "Prašome įrašyti teisingą licenzijos kodą", + "error.license.email": "Prašome įrašyti teisingą el. pašto adresą", + "error.license.verification": "Nepavyko patikrinti licenzijos", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "Valdymo pultas dabar yra offline", + + "error.page.changeSlug.permission": "Neturite teisės pakeisti \"{slug}\" URL", + "error.page.changeStatus.incomplete": "Puslapis turi klaidų ir negali būti paskelbtas", + "error.page.changeStatus.permission": "Šiam puslapiui negalima pakeisti statuso", + "error.page.changeStatus.toDraft.invalid": "Puslapio \"{slug}\" negalima paversti juodraščiu", + "error.page.changeTemplate.invalid": "Šablono puslapiui \"{slug}\" negalima keisti", + "error.page.changeTemplate.permission": "Neturite leidimo keisti šabloną puslapiui \"{slug}\"", + "error.page.changeTitle.empty": "Pavadinimas negali būti tuščias", + "error.page.changeTitle.permission": "Neturite leidimo keisti pavadinimo puslapiui \"{slug}\"", + "error.page.create.permission": "Neturite leidimo sukurti \"{slug}\"", + "error.page.delete": "Puslapio \"{slug}\" negalima pašalinti", + "error.page.delete.confirm": "Įrašykite puslapio pavadinimą, tam kad patvirtintumėte", + "error.page.delete.hasChildren": "Puslapis turi vidinių puslapių, dėl to negalima jo pašalinti", + "error.page.delete.permission": "Neturite leidimo šalinti \"{slug}\"", + "error.page.draft.duplicate": "Puslapio juodraštis su URL pabaiga \"{slug}\" jau yra", + "error.page.duplicate": "Puslapis su URL pabaiga \"{slug}\" jau yra", + "error.page.duplicate.permission": "Neturite leidimo dubliuoti \"{slug}\"", + "error.page.notFound": "Puslapis \"{slug}\" nerastas", + "error.page.num.invalid": "Įrašykite teisingą eiliškumo numerį. Numeris negali būti neigiamas.", + "error.page.slug.invalid": "Įrašykite teisingą URL priedą", + "error.page.slug.maxlength": "url adreso maksimalus simbolių kiekis: \"{length}\"", + "error.page.sort.permission": "Puslapiui \"{slug}\" negalima pakeisti eiliškumo", + "error.page.status.invalid": "Nustatykite teisingą puslapio statusą", + "error.page.undefined": "Puslapis nerastas", + "error.page.update.permission": "Neturite leidimo atnaujinti \"{slug}\"", + + "error.section.files.max.plural": "Į sekciją \"{section}\" negalima pridėti daugiau nei {max} failų", + "error.section.files.max.singular": "Į sekciją \"{section}\" negalima pridėti daugiau nei vieną failą", + "error.section.files.min.plural": "Sekcija \"{section}\" reikalauja bent {min} failų", + "error.section.files.min.singular": "Sekcija \"{section}\" reikalauja bent vieno failo", + + "error.section.pages.max.plural": "Į sekciją \"{section}\" negalima pridėti daugiau nei {max} puslapių", + "error.section.pages.max.singular": "Į sekciją \"{section}\" negalima pridėti daugiau nei vieną puslapį", + "error.section.pages.min.plural": "Sekcija \"{section}\" reikalauja bent {min} puslapių", + "error.section.pages.min.singular": "Sekcija \"{section}\" reikalauja bent vieno puslapio", + + "error.section.notLoaded": "Sekcija \"{name}\" negali būti užkrauta", + "error.section.type.invalid": "Sekcijos tipas \"{type}\" yra neteisingas", + + "error.site.changeTitle.empty": "Pavadinimas negali būti tuščias", + "error.site.changeTitle.permission": "Neturite leidimo keisti svetainės pavadinimo", + "error.site.update.permission": "Neturite leidimo atnaujinti svetainės", + + "error.template.default.notFound": "Nėra šablono pagal nutylėjimą", + + "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Neturite leidimo keisti vartotojo \"{name}\" el. paštą", + "error.user.changeLanguage.permission": "Neturite leidimo keisti vartotojo \"{name}\" kalbą", + "error.user.changeName.permission": "Neturite leidimo keisti vartotojo \"{name}\" vardą", + "error.user.changePassword.permission": "Neturite leidimo keisti vartotojo \"{name}\" slaptažodį", + "error.user.changeRole.lastAdmin": "Vienintelio administratoriaus rolės negalima pakeisti", + "error.user.changeRole.permission": "Neturite leidimo pakeisti vartotojo \"{name}\" rolės", + "error.user.changeRole.toAdmin": "Jūs neturite teisių suteikti administratoriaus rolę", + "error.user.create.permission": "Neturite leidimo sukurti šį vartotoją", + "error.user.delete": "Vartotojo \"{name}\" negalima pašalinti", + "error.user.delete.lastAdmin": "Vienintelio administratoriaus negalima pašalinti", + "error.user.delete.lastUser": "Vienintelio vartotojo negalima pašalinti", + "error.user.delete.permission": "Neturite leidimo pašalinti vartotoją \"{name}\"", + "error.user.duplicate": "Vartotojas su el. paštu \"{email}\" jau yra", + "error.user.email.invalid": "Įrašykite teisingą el. pašto adresą", + "error.user.language.invalid": "Įrašykite teisingą kalbą", + "error.user.notFound": "Vartotojas \"{name}\" nerastas", + "error.user.password.invalid": "Prašome įrašyti galiojantį slaptažodį. Slaptažodį turi sudaryti bent 8 simboliai.", + "error.user.password.notSame": "Slaptažodžiai nesutampa", + "error.user.password.undefined": "Vartotojas neturi slaptažodžio", + "error.user.password.wrong": "Neteisingas slaptažodis", + "error.user.role.invalid": "Įrašykite teisingą rolę", + "error.user.undefined": "Vartotojas nerastas", + "error.user.update.permission": "Neturite teisės keisti vartotojo \"{name}\"", + + "error.validation.accepted": "Prašome patvirtinti", + "error.validation.alpha": "Prašome įrašyti tik raides a-z", + "error.validation.alphanum": "Prašome įrašyti tik raides a-z arba skaičius 0-9", + "error.validation.between": "Prašome įrašyti reikšmę tarp \"{min}\" ir \"{max}\"", + "error.validation.boolean": "Patvirtinkite arba atšaukite", + "error.validation.contains": "Prašome įrašyti reikšmę, kuri turėtų \"{needle}\"", + "error.validation.date": "Prašome įrašyti korektišką datą", + "error.validation.date.after": "Įrašykite datą nuo {date}", + "error.validation.date.before": "Įrašykite datą iki {date}", + "error.validation.date.between": "Įrašykite datą tarp {min} ir {max}", + "error.validation.denied": "Prašome neleisti", + "error.validation.different": "Reikšmė neturi būti \"{other}\"", + "error.validation.email": "Prašome įrašyti korektišką el. paštą", + "error.validation.endswith": "Reikšmė turi baigtis su \"{end}\"", + "error.validation.filename": "Prašome įrašyti teisingą failo pavadinimą", + "error.validation.in": "Prašome įrašyti vieną iš šių: ({in})", + "error.validation.integer": "Prašome įrašyti teisingą sveiką skaičių", + "error.validation.ip": "Prašome įrašyti teisingą IP adresą", + "error.validation.less": "Prašome įrašyti mažiau nei {max}", + "error.validation.match": "Reikšmė nesutampa su laukiamu šablonu", + "error.validation.max": "Prašome įrašyti reikšmę lygią arba didesnę, nei {max}", + "error.validation.maxlength": "Prašome įrašyti trumpesnę reikšmę. (max. {max} characters)", + "error.validation.maxwords": "Please enter no more than {max} word(s)", + "error.validation.min": "Please enter a value equal to or greater than {min}", + "error.validation.minlength": "Prašome įrašyti ilgesnę reikšmę. (min. {min} characters)", + "error.validation.minwords": "Prašome įrašyti bent {min} žodžius", + "error.validation.more": "Prašome įrašyti daugiau nei {min}", + "error.validation.notcontains": "Prašome įrašyti reikšmę, kuri neturi \"{needle}\"", + "error.validation.notin": "Prašome neįrašyti vieną iš šių: ({notIn})", + "error.validation.option": "Prašome pasirinkti korektišką opciją", + "error.validation.num": "Prašome įrašyti teisingą numerį", + "error.validation.required": "Prašome įrašyti ką nors", + "error.validation.same": "Prašome įrašyti \"{other}\"", + "error.validation.size": "Reikšmės dydis turi būti \"{size}\"", + "error.validation.startswith": "Reikšmė turi prasidėti su \"{start}\"", + "error.validation.time": "Prašome įrašyti korektišką laiką", + "error.validation.time.after": "Įrašykite laiką po {time}", + "error.validation.time.before": "Įrašykite laiką prieš {time}", + "error.validation.time.between": "Įrašykite laiką tarp {min} ir {max}", + "error.validation.url": "Prašome įrašyti teisingą URL", + + "expand": "Išskleisti", + "expand.all": "Išskleisti viską", + + "field.required": "Laukas privalomas", + "field.blocks.changeType": "Pakeisti tipą", + "field.blocks.code.name": "Kodas", + "field.blocks.code.language": "Kalba", + "field.blocks.code.placeholder": "Jūsų kodas ...", + "field.blocks.delete.confirm": "Ar tikrai norite pašalinti šį bloką?", + "field.blocks.delete.confirm.all": "Ar tikrai norite pašalinti visus blokus?", + "field.blocks.delete.confirm.selected": "Ar tikrai norite pašalinti pasirinktus blokus?", + "field.blocks.empty": "Dar nėra blokų", + "field.blocks.fieldsets.label": "Pasirinkite bloko tipą ...", + "field.blocks.fieldsets.paste": "Spauskite {{ shortcut }} įterpti/importuoti nukopijuotus blokus", + "field.blocks.gallery.name": "Galerija", + "field.blocks.gallery.images.empty": "Dar nėra nuotraukų", + "field.blocks.gallery.images.label": "Nuotraukos", + "field.blocks.heading.level": "Lygis", + "field.blocks.heading.name": "Antraštė", + "field.blocks.heading.text": "Tekstas", + "field.blocks.heading.placeholder": "Antraštė ...", + "field.blocks.image.alt": "Alternatyvus tekstas", + "field.blocks.image.caption": "Aprašymas", + "field.blocks.image.crop": "Kirpti", + "field.blocks.image.link": "Nuoroda", + "field.blocks.image.location": "Šaltinis", + "field.blocks.image.name": "Nuotrauka", + "field.blocks.image.placeholder": "Pasirinkite nuotrauką", + "field.blocks.image.ratio": "Proporcijos", + "field.blocks.image.url": "Nuotraukos URL", + "field.blocks.line.name": "Linija", + "field.blocks.list.name": "Sąrašas", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Tekstas", + "field.blocks.markdown.placeholder": "Markdown ...", + "field.blocks.quote.name": "Citata", + "field.blocks.quote.text.label": "Tekstas", + "field.blocks.quote.text.placeholder": "Citata ...", + "field.blocks.quote.citation.label": "Citatos turinys", + "field.blocks.quote.citation.placeholder": "autorius", + "field.blocks.text.name": "Tekstas", + "field.blocks.text.placeholder": "Tekstas ...", + "field.blocks.video.caption": "Aprašymas", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Įrašykite video URL", + "field.blocks.video.url.label": "Video-URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Pasirinkti", + + "field.layout.delete": "Pašalinti eilutę", + "field.layout.delete.confirm": "Ar tikrai norite pašalinti šią eilutę", + "field.layout.empty": "Dar nėra eilučių", + "field.layout.select": "Pasirinkite išdėstymą", + + "field.object.empty": "Dar nėra informacijos", + + "field.pages.empty": "Dar nėra puslapių", + + "field.structure.delete.confirm": "Ar tikrai norite pašalinti šią eilutę?", + "field.structure.empty": "Dar nėra įrašų", + + "field.users.empty": "Dar nėra vartotojų", + + "file.blueprint": "Šis failas dar neturi blueprint. Galite nustatyti jį per /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Ar tikrai norite pašalinti
{filename}?", + "file.sort": "Pakeisti poziciją", + + "files": "Failai", + "files.empty": "Įkelti", + + "hide": "Paslėpti", + "hour": "Valanda", + "import": "Importuoti", + "info": "Info", + "insert": "Įterpti", + "insert.after": "Įterpti po", + "insert.before": "Įterpti prieš", + "install": "Įdiegti", + + "installation": "Įdiegimas", + "installation.completed": "Valdymo pultas įdiegtas", + "installation.disabled": "Pagal nutylėjimą valdymo pulto įdiegimas viešuose serveriuose yra negalimas. Prašome įdiegti lokalioje aplinkoje arba įgalinkite jį su panel.install opcija.", + "installation.issues.accounts": "Katalogas /site/accounts neegzistuoja arba neturi įrašymo teisių", + "installation.issues.content": "Katalogas /content neegzistuoja arba neturi įrašymo teisių", + "installation.issues.curl": "Plėtinys CURL yra privalomas", + "installation.issues.headline": "Nepavyko įdiegti valdymo pulto", + "installation.issues.mbstring": "Plėtinys MB String yra privalomas", + "installation.issues.media": "Katalogas /media neegzistuoja arba neturi įrašymo teisių", + "installation.issues.php": "Įsitikinkite, kad naudojama PHP 7+", + "installation.issues.server": "Kirby reikalauja Apache, Nginx arba Caddy", + "installation.issues.sessions": "Katalogas /site/sessions neegzistuoja arba neturi įrašymo teisių", + + "language": "Kalba", + "language.code": "Kodas", + "language.convert": "Padaryti pagrindinį", + "language.convert.confirm": "

Do you really want to convert {name} to the default language? This cannot be undone.

If {name} has untranslated content, there will no longer be a valid fallback and parts of your site might be empty.

", + "language.create": "Pridėti naują kalbą", + "language.delete.confirm": "Ar tikrai norite pašalinti {name} kalbą, kartu su visais vertimais? Grąžinti nebus įmanoma! 🙀", + "language.deleted": "Kalba pašalinta", + "language.direction": "Skaitymo kryptis", + "language.direction.ltr": "Iš kairės į dešinę", + "language.direction.rtl": "Iš dešinės į kairę", + "language.locale": "PHP locale string", + "language.locale.warning": "Jūs naudojate pasirinktinį lokalės nustatymą. Prašome pakeisti jį faile /site/languages", + "language.name": "Pavadinimas", + "language.updated": "Kalba atnaujinta", + + "languages": "Kalbos", + "languages.default": "Pagrindinė kalba", + "languages.empty": "Dar nėra kalbų", + "languages.secondary": "Papildomos kalbos", + "languages.secondary.empty": "Dar nėra papildomų kalbų", + + "license": "Licenzija", + "license.buy": "Pirkti licenziją", + "license.register": "Registruoti", + "license.manage": "Valdyti savo licencijas", + "license.register.help": "Licenzijos kodą gavote el. paštu po apmokėjimo. Prašome įterpti čia, kad sistema būtų užregistruota.", + "license.register.label": "Prašome įrašyti jūsų licenzijos kodą", + "license.register.success": "Ačiū, kad palaikote Kirby", + "license.unregistered": "Tai neregistruota Kirby demo versija", + "license.unregistered.label": "Neregistruota", + + "link": "Nuoroda", + "link.text": "Nuorodos tekstas", + + "loading": "Kraunasi", + + "lock.unsaved": "Neišsaugoti pakeitimai", + "lock.unsaved.empty": "Nebeliko neišsaugotų pakeitimų", + "lock.isLocked": "Vartotojo {email} neišsaugoti pakeitimai", + "lock.file.isLocked": "Šį failą dabar redaguoja kitas vartotojas {email}, tad jo negalima pekeisti.", + "lock.page.isLocked": "Šį puslapį dabar redaguoja kitas vartotojas {email}, tad jo negalima pekeisti.", + "lock.unlock": "Atrakinti", + "lock.isUnlocked": "Jūsų neišsaugoti pakeitimai buvo perrašyti kito vartotojo. Galite parsisiųsti savo pakeitimus ir įkelti juos rankiniu būdu.", + + "login": "Prisijungti", + "login.code.label.login": "Prisijungimo kodas", + "login.code.label.password-reset": "Slaptažodžio atstatymo kodas", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "Jei jūsų el. paštas yra užregistruotas, užklaistas kodas buvo išsiųstas el. paštu.", + "login.email.login.body": "Sveiki, {user.nameOrEmail},\n\nNeseniai užklausėte prisijungimo kodo svetainėje {site}.\nŠis kodas galios {timeout} min.:\n\n{code}\n\nJei neprašėte šio kodo, tiesiog ignoruokite, arba susisiekite su administratoriumi.\nDėl saugumo, prašome NEPERSIŲSTI šio laiško.", + "login.email.login.subject": "Jūsų prisijungimo kodas", + "login.email.password-reset.body": "Sveiki, {user.nameOrEmail},\n\nNeseniai užklausėte naujo slaptažodžio kūrimo kodo svetainėje {site}.\nŠis kodas galios {timeout} min.:\n\n{code}\n\nJei neprašėte šio kodo, tiesiog ignoruokite, arba susisiekite su administratoriumi.\nDėl saugumo, prašome NEPERSIŲSTI šio laiško", + "login.email.password-reset.subject": "Jūsų slaptažodžio atstatymo kodas ", + "login.remember": "Likti prisijungus", + "login.reset": "Sukurti naują slaptažodį", + "login.toggleText.code.email": "Prisijungti su el. paštu", + "login.toggleText.code.email-password": "Prisijungti su slaptažodžiu", + "login.toggleText.password-reset.email": "Pamiršote slaptažodį?", + "login.toggleText.password-reset.email-password": "← Atgal į prisijungimą", + + "logout": "Atsijungti", + + "menu": "Meniu", + "meridiem": "AM/PM", + "mime": "Media Tipas", + "minutes": "Minutės", + + "month": "Mėnuo", + "months.april": "Balandis", + "months.august": "August", + "months.december": "Gruodis", + "months.february": "Vasaris", + "months.january": "Sausis", + "months.july": "Liepa", + "months.june": "Birželis", + "months.march": "Kovas", + "months.may": "Gegužė", + "months.november": "Lapkritis", + "months.october": "Spalis", + "months.september": "Rugsėjis", + + "more": "Daugiau", + "name": "Pavadinimas", + "next": "Toliau", + "no": "ne", + "off": "ne", + "on": "taip", + "open": "Atidaryti", + "open.newWindow": "Atidaryti naujame lange", + "options": "Pasirinkimai", + "options.none": "Nėra pasirinkimų", + + "orientation": "Orientacija", + "orientation.landscape": "Horizontali", + "orientation.portrait": "Portretas", + "orientation.square": "Kvadratas", + + "page.blueprint": "Šis puslapis dar neturi blueprint. Galite jį nustatyti per /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Pakeisti URL", + "page.changeSlug.fromTitle": "Sukurti URL pagal pavadinimą", + "page.changeStatus": "Pakeisti statusą", + "page.changeStatus.position": "Pasirinkite poziciją", + "page.changeStatus.select": "Pasirinkite statusą", + "page.changeTemplate": "Pakeisti šabloną", + "page.delete.confirm": "🙀 Ar tikrai norite pašalinti puslapį {title}?", + "page.delete.confirm.subpages": "Šis puslapis turi sub-puslapių.
Visi sub-puslapiai taip pat bus pašalinti.", + "page.delete.confirm.title": "Įrašykite puslapio pavadinimą tam, kad patvirtinti", + "page.draft.create": "Sukurti juodraštį", + "page.duplicate.appendix": "Kopijuoti", + "page.duplicate.files": "Kopijuoti failus", + "page.duplicate.pages": "Kopijuoti puslapius", + "page.sort": "Pakeisti poziciją", + "page.status": "Statusas", + "page.status.draft": "Juodraštis", + "page.status.draft.description": "Šis puslapis yra juodraščio režime ir prieinamas tik redaktoriams arba per slaptą nuorodą", + "page.status.listed": "Paskelbtas", + "page.status.listed.description": "Matomas viešai visiems", + "page.status.unlisted": "Nerodomas", + "page.status.unlisted.description": "Rodomas viešai visiems, bet tik per URL", + + "pages": "Puslapiai", + "pages.empty": "Dar nėra puslapių", + "pages.status.draft": "Juodraščiai", + "pages.status.listed": "Paskelbti", + "pages.status.unlisted": "Nerodomi", + + "pagination.page": "Puslapis", + + "password": "Slaptažodis", + "paste": "Įterpti", + "paste.after": "Įterpti po", + "pixel": "Pikselis", + "plugin": "Įskiepas", + "plugins": "Įskiepai", + "prev": "Ankstesnis", + "preview": "Peržiūra", + "remove": "Pašalinti", + "rename": "Pervadinti", + "replace": "Apkeisti", + "retry": "Bandyti dar", + "revert": "Grąžinti", + "revert.confirm": "Ar tikrai norite atšaukti visus neišsaugotus pakeitimus?", + + "role": "Rolė", + "role.admin.description": "Admin turi visas teises", + "role.admin.title": "Admin", + "role.all": "Visos", + "role.empty": "Nėra vartotojų su tokia role", + "role.description.placeholder": "Be aprašymo", + "role.nobody.description": "Ši rolė bus naudojama jei nenustatytos jokios teisės", + "role.nobody.title": "Niekas", + + "save": "Išsaugoti", + "search": "Ieškoti", + "search.min": "Minimalus simbolių kiekis paieškai: {min}", + "search.all": "Rodyti viską", + "search.results.none": "Nėra rezultatų", + + "section.required": "Sekcija privaloma", + + "security": "Saugumas", + "select": "Pasirinkti", + "server": "Serveris", + "settings": "Nustatymai", + "show": "Rodyti", + "site.blueprint": "Svetainė neturi blueprint. Jūs galite nustatyti jį /site/blueprints/site.yml", + "size": "Dydis", + "slug": "URL pabaiga", + "sort": "Rikiuoti", + + "stats.empty": "Nėra pranešimų", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Atnaujinimų statusas", + "system.updateStatus.error": "Nepavyko patikrinti atnaujinimų", + "system.updateStatus.not-vulnerable": "Nėra žinomų saugumo spragų", + "system.updateStatus.security-update": "Prieinamas nemokamas saugumo atnaujinimas { version }", + "system.updateStatus.security-upgrade": "Prieinama nauja { version } versija su saugumo atnaujinimais", + "system.updateStatus.unreleased": "Neišleista versija", + "system.updateStatus.up-to-date": "Naujausia versija", + "system.updateStatus.update": "Prieinamas nemokamas atnaujinimas { version }", + "system.updateStatus.upgrade": "Prieinamas atnaujinimas { version }", + + "title": "Pavadinimas", + "template": "Puslapio šablonas", + "today": "Šiandien", + + "toolbar.button.code": "Kodas", + "toolbar.button.bold": "Bold", + "toolbar.button.email": "El. paštas", + "toolbar.button.headings": "Antraštės", + "toolbar.button.heading.1": "Heading 1", + "toolbar.button.heading.2": "Heading 2", + "toolbar.button.heading.3": "Heading 3", + "toolbar.button.heading.4": "Antrašte 4", + "toolbar.button.heading.5": "Antrašte 5", + "toolbar.button.heading.6": "Antrašte 6", + "toolbar.button.italic": "Italic", + "toolbar.button.file": "Failas", + "toolbar.button.file.select": "Pasirinkite failą", + "toolbar.button.file.upload": "Įkelti failą", + "toolbar.button.link": "Nuoroda", + "toolbar.button.paragraph": "Paragrafas", + "toolbar.button.strike": "Perbraukimas", + "toolbar.button.ol": "Sąrašas su skaičiais", + "toolbar.button.underline": "Pabraukimas", + "toolbar.button.ul": "Sąrašas su taškais", + + "translation.author": "Roman U", + "translation.direction": "ltr", + "translation.name": "Lietuvių", + "translation.locale": "lt_LT", + + "upload": "Įkelti", + "upload.error.cantMove": "Įkeltas failas negali būti perkeltas", + "upload.error.cantWrite": "Nepavyko įrašyti failo į diską", + "upload.error.default": "Nepavyko įkelti failo", + "upload.error.extension": "Neįmanoma įkelti tokio tipo failo", + "upload.error.formSize": "Įkeltas failas viršija MAX_FILE_SIZE nustatymą, kuris buvo nurodytas formoje", + "upload.error.iniPostSize": "Įkeliamas failas viršija post_max_size nustatymą iš php.ini", + "upload.error.iniSize": "Įkeltas failas viršija upload_max_filesize nustatymą faile php.ini", + "upload.error.noFile": "Failas nebuvo įkeltas", + "upload.error.noFiles": "Failai nebuvo įkelti", + "upload.error.partial": "Failas įkeltas tik iš dalies", + "upload.error.tmpDir": "Trūksta laikinojo katalogo", + "upload.errors": "Klaida", + "upload.progress": "Įkėlimas…", + + "url": "Url", + "url.placeholder": "https://example.com", + + "user": "Vartotojas", + "user.blueprint": "Galite nustatyti papildomas sekcijas ir formos laukelius šiam vartotojui per /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Keisti el. paštą", + "user.changeLanguage": "Keisti kalbą", + "user.changeName": "Pervadinti vartotoją", + "user.changePassword": "Keisti slaptažodį", + "user.changePassword.new": "Naujas slaptažodis", + "user.changePassword.new.confirm": "Patvirtinti naują slaptažodį…", + "user.changeRole": "Keisti rolę", + "user.changeRole.select": "Pasirinkti naują rolę", + "user.create": "Pridėti naują vartotoją", + "user.delete": "Pašalinti šį vartotoją", + "user.delete.confirm": "Ar tikrai norite pašalinti vartotoją
{email}?", + + "users": "Vartotojai", + + "version": "Versija", + "version.current": "Dabartinė versija", + "version.latest": "Naujausia versija", + "versionInformation": "Versijos informacija", + + "view.account": "Jūsų paskyra", + "view.installation": "Installation", + "view.languages": "Kalbos", + "view.resetPassword": "Sukurti naują slaptažodį", + "view.site": "Svetainė", + "view.system": "Sistema", + "view.users": "Vartotojai", + + "welcome": "Sveiki", + "year": "Metai", + "yes": "taip" } diff --git a/kirby/i18n/translations/nb.json b/kirby/i18n/translations/nb.json index a4f9048..4b99b6d 100644 --- a/kirby/i18n/translations/nb.json +++ b/kirby/i18n/translations/nb.json @@ -1,573 +1,596 @@ { - "account.changeName": "Endre navnet ditt", - "account.delete": "Slett kontoen din", - "account.delete.confirm": "Er du sikker på at du vil slette kontoen din? Du vil bli logget ut umiddelbart. Kontoen din kan ikke gjenopprettes.", - - "add": "Legg til", - "author": "Forfatter", - "avatar": "Profilbilde", - "back": "Tilbake", - "cancel": "Avbryt", - "change": "Endre", - "close": "Lukk", - "confirm": "Lagre", - "collapse": "Skjul", - "collapse.all": "Skjule alle", - "copy": "Kopier", - "copy.all": "Kopier alle", - "create": "Opprett", - - "date": "Dato", - "date.select": "Velg dato", - - "day": "Dag", - "days.fri": "Fre", - "days.mon": "Man", - "days.sat": "L\u00f8r", - "days.sun": "S\u00f8n", - "days.thu": "Tor", - "days.tue": "Tir", - "days.wed": "Ons", - - "debugging": "Feilsøker", - - "delete": "Slett", - "delete.all": "Slett alle", - - "dialog.files.empty": "Ingen filer å velge", - "dialog.pages.empty": "Ingen sider å velge", - "dialog.users.empty": "Ingen brukere å velge", - - "dimensions": "Dimensjoner", - "disabled": "Deaktivert", - "discard": "Forkast", - "download": "Last ned", - "duplicate": "Dupliser", - - "edit": "Rediger", - - "email": "Epost", - "email.placeholder": "epost@eksempel.no", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Miljø", - - "error.access.code": "Ugyldig kode", - "error.access.login": "Ugyldig innlogging", - "error.access.panel": "Du har ikke tilgang til panelet", - "error.access.view": "Du har ikke tilgang til denne delen av panelet", - - "error.avatar.create.fail": "Profilbildet kunne ikke lastes opp", - "error.avatar.delete.fail": "Profilbildet kunne ikke slettes", - "error.avatar.dimensions.invalid": "Vennligst hold profilbildets bredde og høyde under 3000 piksler", - "error.avatar.mime.forbidden": "Ugyldig MIME-type", - - "error.blueprint.notFound": "Blueprint \"{name}\" kunne ikke lastes inn", - - "error.blocks.max.plural": "Du kan ikke legge til flere enn {max} blokker", - "error.blocks.max.singular": "Du kan ikke legge til mer enn en blokk", - "error.blocks.min.plural": "Du må legge til minst {min} blokker", - "error.blocks.min.singular": "Du må legge til minst en blokk", - "error.blocks.validation": "Det er en feil i blokken {index}", - - "error.email.preset.notFound": "E-postinnstillingen \"{name}\" ble ikke funnet", - - "error.field.converter.invalid": "Ugyldig omformer \"{converter}\"", - - "error.file.changeName.empty": "Navnet kan ikke være tomt", - "error.file.changeName.permission": "Du har ikke rettighet til å endre navnet til \"{filename}\"", - "error.file.duplicate": "En fil med navnet \"{filename}\" eksisterer allerede", - "error.file.extension.forbidden": "Ugyldig filtype", - "error.file.extension.invalid": "Ugyldig utvidelse: {extension}", - "error.file.extension.missing": "Du kan ikke laste opp filer uten filtype", - "error.file.maxheight": "Høyden til bildet kan ikke overgå {height} piksler", - "error.file.maxsize": "Filen er for stor", - "error.file.maxwidth": "Bredden til bildet kan ikke overgå {width} piksler", - "error.file.mime.differs": "Den opplastede filen må være av samme MIME-type \"{mime}\"", - "error.file.mime.forbidden": "Mediatypen \"{mime}\" er ikke tillatt", - "error.file.mime.invalid": "Ugyldig mediatype: {mime}", - "error.file.mime.missing": "Mediatypen for \"{filename}\" kan ikke gjenkjennes", - "error.file.minheight": "Høyden til bildet må være minst {height} piksler", - "error.file.minsize": "Filen er for liten", - "error.file.minwidth": "Bredden til bildet må være minst {width} piksler", - "error.file.name.missing": "Filnavnet kan ikke være tomt", - "error.file.notFound": "Finner ikke filen", - "error.file.orientation": "Bilderetningen må være \"{orientation}\"", - "error.file.type.forbidden": "Du har ikke lov til å laste opp filer av typen {type}", - "error.file.type.invalid": "Ugyldig filtype: {type}", - "error.file.undefined": "Finner ikke filen", - - "error.form.incomplete": "Vennligst fiks alle feil…", - "error.form.notSaved": "Skjemaet kunne ikke lagres", - - "error.language.code": "Vennligst skriv inn gyldig språkkode", - "error.language.duplicate": "Språket eksisterer allerede", - "error.language.name": "Vennligst skriv inn et gyldig navn for språket", - "error.language.notFound": "Finner ikke språket", - - "error.layout.validation.block": "Det er en feil i blokk {blockIndex} i layout {layoutIndex}", - "error.layout.validation.settings": "Det er en feil i layout {index} innstillinger", - - "error.license.format": "Vennligst skriv inn gyldig lisensnøkkel", - "error.license.email": "Vennligst skriv inn en gyldig e-postadresse", - "error.license.verification": "Lisensen kunne ikke verifiseres", - - "error.offline": "Panelet er i øyeblikket offline", - - "error.page.changeSlug.permission": "Du kan ikke endre URLen for denne siden", - "error.page.changeStatus.incomplete": "Siden har feil og kan ikke publiseres", - "error.page.changeStatus.permission": "Sidens status kan ikke endres", - "error.page.changeStatus.toDraft.invalid": "Siden \"{slug}\" kan ikke konverteres til et utkast", - "error.page.changeTemplate.invalid": "Malen for siden \"{slug}\" kan ikke endres", - "error.page.changeTemplate.permission": "Du har ikke tillatelse til å endre malen for \"{slug}\"", - "error.page.changeTitle.empty": "Tittelen kan ikke være tom", - "error.page.changeTitle.permission": "Du har ikke tillatelse til å endre tittelen for \"{slug}\"", - "error.page.create.permission": "Du har ikke tillatelse til å opprette \"{slug}\"", - "error.page.delete": "Siden \"{slug}\" kan ikke slettes", - "error.page.delete.confirm": "Vennligst skriv inn sidens tittel for å bekrefte", - "error.page.delete.hasChildren": "Siden har undersider og kan derfor ikke slettes", - "error.page.delete.permission": "Du har ikke til å slette \"{slug}\"", - "error.page.draft.duplicate": "Et sideutkast med URL-tillegget \"{slug}\" eksisterer allerede", - "error.page.duplicate": "En side med URL-tillegget \"{slug}\" eksisterer allerede", - "error.page.duplicate.permission": "Du har ikke tillatelse til å duplisere \"{slug}\"", - "error.page.notFound": "Siden \"{slug}\" ble ikke funnet", - "error.page.num.invalid": "Vennligst skriv inn et gyldig sorteringsnummer. Tallet må ikke være negativt.", - "error.page.slug.invalid": "Vennligst skriv inn en gyldig URL endelse", - "error.page.slug.maxlength": "Slug lengden må være mindre enn \"{length}\" karakterer", - "error.page.sort.permission": "Siden \"{slug}\" kan ikke sorteres", - "error.page.status.invalid": "Vennligst angi en gyldig sidestatus", - "error.page.undefined": "Siden kunne ikke bli funnet", - "error.page.update.permission": "Du har ikke tillatelse til å oppdatere \"{slug}\"", - - "error.section.files.max.plural": "Det er ikke mulig å legge til mer enn {max} filer i seksjonen \"{section}\"", - "error.section.files.max.singular": "Det er ikke mulig å legge til mer enn én fil i seksjonen \"{section}\"", - "error.section.files.min.plural": "Seksjonen \"{section}\" krever minst {min} filer", - "error.section.files.min.singular": "Seksjonen \"{section}\" krever minst en fil", - - "error.section.pages.max.plural": "Det er ikke mulig å legge til mer enn {max} sider i \"{section}\" seksjonen", - "error.section.pages.max.singular": "Det er ikke mulig å legge til mer enn én side i \"{section}\" seksjonen", - "error.section.pages.min.plural": "Seksjonen \"{section}\" krever minst {min} sider", - "error.section.pages.min.singular": "Seksjonen \"{section}\" krever minst en side", - - "error.section.notLoaded": "Seksjonen \"{name}\" kunne ikke lastes inn", - "error.section.type.invalid": "Seksjonstypen \"{type}\" er ikke gyldig", - - "error.site.changeTitle.empty": "Tittelen kan ikke være tom", - "error.site.changeTitle.permission": "Du har ikke tillatelse til å endre tittel på siden", - "error.site.update.permission": "Du har ikke tillatelse til å oppdatere denne siden", - - "error.template.default.notFound": "Standardmalen eksisterer ikke", - - "error.unexpected": "En uventet feil oppstod! Aktiver feilsøkmodus for mer info: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Du har ikke tillatelse til å endre e-post for brukeren \"{name}\"", - "error.user.changeLanguage.permission": "Du har ikke tillatelse til å endre språk for brukeren \"{name}\"", - "error.user.changeName.permission": "Du har ikke tillatelse til å endre navn for brukeren \"{name}\"", - "error.user.changePassword.permission": "Du har ikke tillatelse til å endre passord for brukeren \"{name}\"", - "error.user.changeRole.lastAdmin": "Rollen for den siste administratoren kan ikke endres", - "error.user.changeRole.permission": "Du har ikke tillatelse til å endre rollen for brukeren \"{name}\"", - "error.user.changeRole.toAdmin": "Du har ikke tillatelse til å endre noen til adminrolle", - "error.user.create.permission": "Du har ikke tillatelse til å opprette denne brukeren", - "error.user.delete": "Denne brukeren kunne ikke bli slettet", - "error.user.delete.lastAdmin": "Siste administrator kan ikke slettes", - "error.user.delete.lastUser": "Den siste brukeren kan ikke slettes", - "error.user.delete.permission": "Du er ikke tillat \u00e5 slette denne brukeren", - "error.user.duplicate": "En bruker med e-postadresse \"{email}\" eksisterer allerede", - "error.user.email.invalid": "Vennligst skriv inn en gyldig e-postadresse", - "error.user.language.invalid": "Vennligst skriv inn et gyldig språk", - "error.user.notFound": "Brukeren kunne ikke bli funnet", - "error.user.password.invalid": "Vennligst skriv inn et gyldig passord. Passordet må minst være 8 tegn langt.", - "error.user.password.notSame": "Vennligst bekreft passordet", - "error.user.password.undefined": "Brukeren har ikke et passord", - "error.user.password.wrong": "Feil passord", - "error.user.role.invalid": "Vennligst skriv inn en gyldig rolle", - "error.user.undefined": "Brukeren kunne ikke bli funnet", - "error.user.update.permission": "Du har ikke tillatelse til å oppdatere brukeren \"{name}\"", - - "error.validation.accepted": "Vennligst bekreft", - "error.validation.alpha": "Vennligst skriv kun tegn mellom a-z", - "error.validation.alphanum": "Vennligst skriv kun tegn mellom a-z eller tall mellom 0-9", - "error.validation.between": "Vennligst angi en verdi mellom \"{min}\" og \"{max}\"", - "error.validation.boolean": "Vennligst bekreft eller avslå", - "error.validation.contains": "Vennligst skriv inn en verdi som inneholder \"{needle}\"", - "error.validation.date": "Vennligst skriv inn en gyldig dato", - "error.validation.date.after": "Vennligst angi en dato etter {date}", - "error.validation.date.before": "Vennligst angi en dato før {date}", - "error.validation.date.between": "Vennligst angi en dato mellom {min} og {max}", - "error.validation.denied": "Vennligst avslå", - "error.validation.different": "Verdien kan ikke være \"{other}\"", - "error.validation.email": "Vennligst skriv inn en gyldig e-postadresse", - "error.validation.endswith": "Verdien må ende med \"{end}\"", - "error.validation.filename": "Vennligst skriv inn et gyldig filnavn", - "error.validation.in": "Vennligst skriv inn en av følgende: ({in})", - "error.validation.integer": "Vennligst skriv inn et gyldig tall", - "error.validation.ip": "Vennligst skriv inn en gyldig IP-adresse", - "error.validation.less": "Vennligst angi en verdi lavere enn {max}", - "error.validation.match": "Verdien samsvarer ikke med det forventede mønsteret", - "error.validation.max": "Vennligst angi en verdi lik eller lavere enn {max}", - "error.validation.maxlength": "Vennligst angi en kortere verdi. (maks. {max} tegn)", - "error.validation.maxwords": "Vennligst ikke skriv inn mer enn {max} ord", - "error.validation.min": "Vennligst angi en verdi lik eller større enn {min}", - "error.validation.minlength": "Vennligst angi en lengre verdi. (minimum. {min} tegn)", - "error.validation.minwords": "Vennligst skriv inn minst {min} ord", - "error.validation.more": "Vennligst angi en verdi større enn {min}", - "error.validation.notcontains": "Vennligst angi en verdi som ikke inneholder \"{needle}\"", - "error.validation.notin": "Vennligst ikke angi noen av følgende:({notIn})", - "error.validation.option": "Vennligst velg et gyldig alternativ", - "error.validation.num": "Vennligst angi et gyldig nummer", - "error.validation.required": "Vennligst skriv inn noe", - "error.validation.same": "Vennligst angi \"{other}\"", - "error.validation.size": "Størrelsen på verdien må være \"{size}\"", - "error.validation.startswith": "Verdien må starte med \"{start}\"", - "error.validation.time": "Vennligst angi et gyldig tidspunkt", - "error.validation.time.after": "Vennligst angi et tidspunkt etter {time}", - "error.validation.time.before": "Vennligst angi et tidspunkt før {time}", - "error.validation.time.between": "Vennligst angi et tidspunkt mellom {min} og {max}", - "error.validation.url": "Vennligst skriv inn en gyldig URL", - - "expand": "Utvid", - "expand.all": "Utvid alle", - - "field.required": "Feltet er påkrevd", - "field.blocks.changeType": "Endre type", - "field.blocks.code.name": "Kode", - "field.blocks.code.language": "Språk", - "field.blocks.code.placeholder": "Din kode…", - "field.blocks.delete.confirm": "Er du sikker på at du vil slette denne blokken?", - "field.blocks.delete.confirm.all": "Er du sikker på at du vil slette alle blokkene?", - "field.blocks.delete.confirm.selected": "Er du sikker på at du vil slette de valgte blokkene?", - "field.blocks.empty": "Ingen blokker enda", - "field.blocks.fieldsets.label": "Vennligst velg en blokktype…", - "field.blocks.fieldsets.paste": "Trykk {{ shortcut }} for å lime/importere blokker fra din utklippstavle", - "field.blocks.gallery.name": "Galleri", - "field.blocks.gallery.images.empty": "Ingen bilder enda", - "field.blocks.gallery.images.label": "Bilder", - "field.blocks.heading.level": "Nivå", - "field.blocks.heading.name": "Overskrift", - "field.blocks.heading.text": "Tekst", - "field.blocks.heading.placeholder": "Overskrift…", - "field.blocks.image.alt": "Alternativ tekst", - "field.blocks.image.caption": "Caption", - "field.blocks.image.crop": "Beskjær", - "field.blocks.image.link": "Adresse", - "field.blocks.image.location": "Plassering", - "field.blocks.image.name": "Bilde", - "field.blocks.image.placeholder": "Velg et bilde", - "field.blocks.image.ratio": "Ratio", - "field.blocks.image.url": "Bilde URL", - "field.blocks.line.name": "Linje", - "field.blocks.list.name": "Liste", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Tekst", - "field.blocks.markdown.placeholder": "Markdown…", - "field.blocks.quote.name": "Sitat", - "field.blocks.quote.text.label": "Tekst", - "field.blocks.quote.text.placeholder": "Sitat…", - "field.blocks.quote.citation.label": "Kildehenvisning", - "field.blocks.quote.citation.placeholder": "av…", - "field.blocks.text.name": "Tekst", - "field.blocks.text.placeholder": "Tekst…", - "field.blocks.video.caption": "Caption", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Legg til en video URL", - "field.blocks.video.url.label": "Video-URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Ingen filer har blitt valgt", - - "field.layout.delete": "Slett layout", - "field.layout.delete.confirm": "Er du sikker på at du vil slette denne layouten?", - "field.layout.empty": "Ingen rader enda", - "field.layout.select": "Velg en layout", - - "field.pages.empty": "Ingen side har blitt valgt", - "field.structure.delete.confirm": "\u00d8nsker du virkelig \u00e5 slette denne oppf\u00f8ringen?", - "field.structure.empty": "Ingen oppf\u00f8ringer enda", - "field.users.empty": "Ingen bruker har blitt valgt", - - "file.blueprint": "Denne filen har ikke en blueprint enda. Du kan definere oppsettet i /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Vil du virkelig slette denne filen?", - "file.sort": "Endre plassering", - - "files": "Filer", - "files.empty": "Ingen filer ennå", - - "hide": "Skjul", - "hour": "Tid", - "import": "Importer", - "info": "Info", - "insert": "Sett Inn", - "insert.after": "Sett inn etter", - "insert.before": "Sett inn før", - "install": "Installer", - - "installation": "Installasjon", - "installation.completed": "Panelet har blitt installert", - "installation.disabled": "Installasjonsprogrammet for Panelet er deaktivert på offentlige servere som standard. Vennligst kjør installasjonsprogrammet på en lokal maskin eller aktiver den med panel.install innstillingen.", - "installation.issues.accounts": "\/site\/accounts er ikke skrivbar", - "installation.issues.content": "Mappen content og alt av innhold m\u00e5 v\u00e6re skrivbar.", - "installation.issues.curl": "Utvidelsen CURL er nødvendig", - "installation.issues.headline": "Panelet kan ikke installeres", - "installation.issues.mbstring": "Utvidelsen MB String er nødvendig", - "installation.issues.media": "Mappen /media eksisterer ikke eller er ikke skrivbar", - "installation.issues.php": "Pass på at du bruker PHP 7+", - "installation.issues.server": "Kirby krever Apache, Nginx eller Caddy", - "installation.issues.sessions": "Mappen /site/sessions eksisterer ikke eller er ikke skrivbar", - - "language": "Spr\u00e5k", - "language.code": "Kode", - "language.convert": "Gjør til standard", - "language.convert.confirm": "

Vil du virkelig konvertere {name} til standardspråk? Dette kan ikke angres.

Dersom {name} har innhold som ikke er oversatt, vil nettstedet mangle innhold å falle tilbake på. Dette kan resultere i at deler av nettstedet fremstår som tomt.

", - "language.create": "Legg til språk", - "language.delete.confirm": "Vil du virkelig slette språket {name} inkludert alle oversettelser? Dette kan ikke angres!", - "language.deleted": "Språket har blitt slettet", - "language.direction": "Leseretning", - "language.direction.ltr": "Venstre til høyre", - "language.direction.rtl": "Høyre til venstre", - "language.locale": "PHP locale streng", - "language.locale.warning": "Du bruker et egendefinert lokalt oppsett. Vennligst endre det i språkfilen i /site/languages", - "language.name": "Navn", - "language.updated": "Språk har blitt oppdatert", - - "languages": "Språk", - "languages.default": "Standardspråk", - "languages.empty": "Det er ingen språk ennå", - "languages.secondary": "Sekundære språk", - "languages.secondary.empty": "Det er ingen andre språk ennå", - - "license": "Kirby lisens", - "license.buy": "Kjøp lisens", - "license.register": "Registrer", - "license.manage": "Manage your licenses", - "license.register.help": "Du skal ha mottatt din lisenskode for kjøpet via e-post. Vennligst kopier og lim inn denne for å registrere deg.", - "license.register.label": "Vennligst skriv inn din lisenskode", - "license.register.success": "Takk for at du støtter Kirby", - "license.unregistered": "Dette er en uregistrert demo av Kirby", - "license.unregistered.label": "Unregistered", - - "link": "Adresse", - "link.text": "Koblingstekst", - - "loading": "Laster inn", - - "lock.unsaved": "Ulagrede endringer", - "lock.unsaved.empty": "Det er ingen flere ulagrede endringer", - "lock.isLocked": "Ulagrede endringer av {email}", - "lock.file.isLocked": "Filen redigeres for øyeblikket av {email} og kan ikke endres.", - "lock.page.isLocked": "Siden redigeres for øyeblikket av {email} og kan ikke endres.", - "lock.unlock": "Lås opp", - "lock.isUnlocked": "Dine ulagrede endringer har blitt overskrevet av en annen bruker. Du kan laste ned dine endringer for å sammenslå dem manuelt", - - "login": "Logg Inn", - "login.code.label.login": "Login kode", - "login.code.label.password-reset": "Passord tilbakestillingskode", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "Dersom din e-post er registrert vil den forespurte koden bli sendt via e-post.", - "login.email.login.body": "Hei {user.nameOrEmail},\n\nDu ba nylig om en innloggingskode til panelet til {site}.\nFølgende innloggingskode vil være gyldig i {timeout} minutter:\n\n{code}\n\nDersom du ikke ba om en innloggingskode, vennligst ignorer denne e-posten eller kontakt din administrator hvis du har spørsmål.\nFor sikkerhets skyld, vennligst IKKE videresend denne e-posten.", - "login.email.login.subject": "Din innloggingskode", - "login.email.password-reset.body": "Hei {user.nameOrEmail},\n\nDu ba nylig om en tilbakestilling av passord til panelet til {site}.\nFølgende tilbakestillingskode vil være gyldig i {timeout} minutter:\n\n{code}\n\nDersom du ikke ba om en tilbakestillingskode, vennligst ignorer denne e-posten eller kontakt din administrator hvis du har spørsmål.\nFor sikkerhets skyld, vennligst IKKE videresend denne e-posten.", - "login.email.password-reset.subject": "Din kode for tilbakestilling av passord", - "login.remember": "Hold meg innlogget", - "login.reset": "Tilbakestill passord", - "login.toggleText.code.email": "Logg inn via e-post", - "login.toggleText.code.email-password": "Logg inn med passord", - "login.toggleText.password-reset.email": "Glemt passord?", - "login.toggleText.password-reset.email-password": "← Tilbake til innlogging", - - "logout": "Logg ut", - - "menu": "Meny", - "meridiem": "AM/PM", - "mime": "Mediatype", - "minutes": "Minutter", - - "month": "Måned", - "months.april": "April", - "months.august": "August", - "months.december": "Desember", - "months.february": "Februar", - "months.january": "Januar", - "months.july": "July", - "months.june": "Juni", - "months.march": "Mars", - "months.may": "Mai", - "months.november": "November", - "months.october": "Oktober", - "months.september": "September", - - "more": "Mer", - "name": "Navn", - "next": "Neste", - "no": "nei", - "off": "av", - "on": "på", - "open": "Åpne", - "open.newWindow": "Åpne i nytt vindu", - "options": "Alternativer", - "options.none": "Ingen alternativer", - - "orientation": "Orientering", - "orientation.landscape": "Landskap", - "orientation.portrait": "Portrett", - "orientation.square": "Kvadrat", - - "page.blueprint": "Denne siden har ikke en blueprint enda. Du kan definere oppsettet i /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Endre URL", - "page.changeSlug.fromTitle": "Opprett fra tittel", - "page.changeStatus": "Endre status", - "page.changeStatus.position": "Vennligst velg en posisjon", - "page.changeStatus.select": "Velg ny status", - "page.changeTemplate": "Endre mal", - "page.delete.confirm": "Vil du virkelig slette denne siden?", - "page.delete.confirm.subpages": "Denne siden har undersider.
Alle undersider vil også bli slettet.", - "page.delete.confirm.title": "Skriv inn sidetittel for å bekrefte", - "page.draft.create": "Lag utkast", - "page.duplicate.appendix": "Kopier", - "page.duplicate.files": "Kopier filer", - "page.duplicate.pages": "Kopier sider", - "page.sort": "Endre plassering", - "page.status": "Status", - "page.status.draft": "Utkast", - "page.status.draft.description": "Denne siden er i kladdmodus og er kun synlig for innloggede brukere eller via en hemmelig lenke.", - "page.status.listed": "Offentlig", - "page.status.listed.description": "Siden er offentlig og synlig for alle", - "page.status.unlisted": "Unotert", - "page.status.unlisted.description": "Siden er ikke er oppført og er kun tilgjengelig via URL", - - "pages": "Sider", - "pages.empty": "Ingen sider ennå", - "pages.status.draft": "Utkast", - "pages.status.listed": "Publisert", - "pages.status.unlisted": "Unotert", - - "pagination.page": "Side", - - "password": "Passord", - "paste": "Lim inn", - "paste.after": "Lim inn etter", - "pixel": "Piksel", - "plugins": "Plugins", - "prev": "Forrige", - "preview": "Forhåndsvisning", - "remove": "Fjern", - "rename": "Endre navn", - "replace": "Erstatt", - "retry": "Pr\u00f8v p\u00e5 nytt", - "revert": "Forkast", - "revert.confirm": "Er du sikker på at vil slette alle ulagrede endringer?", - - "role": "Rolle", - "role.admin.description": "Administrator har alle rettigheter", - "role.admin.title": "Admin", - "role.all": "Alle", - "role.empty": "Det er ingen brukere med denne rollen", - "role.description.placeholder": "Ingen beskrivelse", - "role.nobody.description": "Dette er en fallback rolle uten noen rettigheter.", - "role.nobody.title": "Ingen", - - "save": "Lagre", - "search": "Søk", - "search.min": "Skriv inn {min} tegn for å søke", - "search.all": "Vis alle", - "search.results.none": "Ingen resultater", - - "section.required": "Denne seksjonen er påkrevd", - - "security": "Security", - "select": "Velg", - "server": "Server", - "settings": "Innstillinger", - "show": "Vis", - "site.blueprint": "Denne siden har ikke en blueprint enda. Du kan definere oppsettet i /site/blueprints/site.yml", - "size": "Størrelse", - "slug": "URL-appendiks", - "sort": "Sortere", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Tittel", - "template": "Mal", - "today": "I dag", - - "toolbar.button.code": "Kode", - "toolbar.button.bold": "Fet tekst", - "toolbar.button.email": "Epost", - "toolbar.button.headings": "Overskrifter", - "toolbar.button.heading.1": "Overskrift 1", - "toolbar.button.heading.2": "Overskrift 2", - "toolbar.button.heading.3": "Overskrift 3", - "toolbar.button.heading.4": "Overskrift 4", - "toolbar.button.heading.5": "Overskrift 5", - "toolbar.button.heading.6": "Overskrift 6", - "toolbar.button.italic": "Kursiv tekst", - "toolbar.button.file": "Fil", - "toolbar.button.file.select": "Velg en fil", - "toolbar.button.file.upload": "Last opp en fil", - "toolbar.button.link": "Adresse", - "toolbar.button.paragraph": "Avsnitt", - "toolbar.button.strike": "Gjennomstreking", - "toolbar.button.ol": "Ordnet liste", - "toolbar.button.underline": "Understrek", - "toolbar.button.ul": "Punktliste", - - "translation.author": "Kirby Team", - "translation.direction": "ltr", - "translation.name": "Norsk Bokm\u00e5l", - "translation.locale": "nb_NO", - - "upload": "Last opp", - "upload.error.cantMove": "Den opplastede filen kunne ikke flyttes", - "upload.error.cantWrite": "Kunne ikke skrive fil til disk", - "upload.error.default": "Kunne ikke laste opp fil", - "upload.error.extension": "Filopplasting stoppet av en utvidelse", - "upload.error.formSize": "Den opplastede filen overskrider MAX_FILE_SIZE direktivet som er spesifisert i skjemaet", - "upload.error.iniPostSize": "Den opplastede filen overskrider post_max_size direktivet i php.ini", - "upload.error.iniSize": "Den opplastede filen overskrider upload_max_filesize direktivet i php.ini", - "upload.error.noFile": "Ingen fil ble lastet opp", - "upload.error.noFiles": "Ingen filer ble lastet opp", - "upload.error.partial": "Den opplastede filen ble bare delvis lastet opp", - "upload.error.tmpDir": "Mangler en midlertidig mappe", - "upload.errors": "Feil", - "upload.progress": "Laster opp…", - - "url": "Nettadresse", - "url.placeholder": "https://example.com", - - "user": "Bruker", - "user.blueprint": "Du kan definere flere seksjoner og skjemafelter for denne brukerrollen i /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Endre e-post", - "user.changeLanguage": "Endre språk", - "user.changeName": "Angi nytt navn for denne brukeren", - "user.changePassword": "Bytt passord", - "user.changePassword.new": "Nytt passord", - "user.changePassword.new.confirm": "Bekreft nytt passord…", - "user.changeRole": "Bytt rolle", - "user.changeRole.select": "Velg en ny rolle", - "user.create": "Legg til ny bruker", - "user.delete": "Slett denne brukeren", - "user.delete.confirm": "Vil du virkelig slette denne konten?", - - "users": "Brukere", - - "version": "Kirby versjon", - - "view.account": "Din konto", - "view.installation": "Installasjon", - "view.languages": "Språk", - "view.resetPassword": "Tilbakestill passord", - "view.site": "Side", - "view.system": "System", - "view.users": "Brukere", - - "welcome": "Velkommen", - "year": "År", - "yes": "ja" + "account.changeName": "Endre navnet ditt", + "account.delete": "Slett kontoen din", + "account.delete.confirm": "Er du sikker på at du vil slette kontoen din? Du vil bli logget ut umiddelbart. Kontoen din kan ikke gjenopprettes.", + + "add": "Legg til", + "author": "Forfatter", + "avatar": "Profilbilde", + "back": "Tilbake", + "cancel": "Avbryt", + "change": "Endre", + "close": "Lukk", + "confirm": "Lagre", + "collapse": "Skjul", + "collapse.all": "Skjule alle", + "copy": "Kopier", + "copy.all": "Kopier alle", + "create": "Opprett", + + "date": "Dato", + "date.select": "Velg dato", + + "day": "Dag", + "days.fri": "Fre", + "days.mon": "Man", + "days.sat": "L\u00f8r", + "days.sun": "S\u00f8n", + "days.thu": "Tor", + "days.tue": "Tir", + "days.wed": "Ons", + + "debugging": "Feilsøker", + + "delete": "Slett", + "delete.all": "Slett alle", + + "dialog.files.empty": "Ingen filer å velge", + "dialog.pages.empty": "Ingen sider å velge", + "dialog.users.empty": "Ingen brukere å velge", + + "dimensions": "Dimensjoner", + "disabled": "Deaktivert", + "discard": "Forkast", + "download": "Last ned", + "duplicate": "Dupliser", + + "edit": "Rediger", + + "email": "Epost", + "email.placeholder": "epost@eksempel.no", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Miljø", + + "error.access.code": "Ugyldig kode", + "error.access.login": "Ugyldig innlogging", + "error.access.panel": "Du har ikke tilgang til panelet", + "error.access.view": "Du har ikke tilgang til denne delen av panelet", + + "error.avatar.create.fail": "Profilbildet kunne ikke lastes opp", + "error.avatar.delete.fail": "Profilbildet kunne ikke slettes", + "error.avatar.dimensions.invalid": "Vennligst hold profilbildets bredde og høyde under 3000 piksler", + "error.avatar.mime.forbidden": "Ugyldig MIME-type", + + "error.blueprint.notFound": "Blueprint \"{name}\" kunne ikke lastes inn", + + "error.blocks.max.plural": "Du kan ikke legge til flere enn {max} blokker", + "error.blocks.max.singular": "Du kan ikke legge til mer enn en blokk", + "error.blocks.min.plural": "Du må legge til minst {min} blokker", + "error.blocks.min.singular": "Du må legge til minst en blokk", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "E-postinnstillingen \"{name}\" ble ikke funnet", + + "error.field.converter.invalid": "Ugyldig omformer \"{converter}\"", + + "error.file.changeName.empty": "Navnet kan ikke være tomt", + "error.file.changeName.permission": "Du har ikke rettighet til å endre navnet til \"{filename}\"", + "error.file.duplicate": "En fil med navnet \"{filename}\" eksisterer allerede", + "error.file.extension.forbidden": "Ugyldig filtype", + "error.file.extension.invalid": "Ugyldig utvidelse: {extension}", + "error.file.extension.missing": "Du kan ikke laste opp filer uten filtype", + "error.file.maxheight": "Høyden til bildet kan ikke overgå {height} piksler", + "error.file.maxsize": "Filen er for stor", + "error.file.maxwidth": "Bredden til bildet kan ikke overgå {width} piksler", + "error.file.mime.differs": "Den opplastede filen må være av samme MIME-type \"{mime}\"", + "error.file.mime.forbidden": "Mediatypen \"{mime}\" er ikke tillatt", + "error.file.mime.invalid": "Ugyldig mediatype: {mime}", + "error.file.mime.missing": "Mediatypen for \"{filename}\" kan ikke gjenkjennes", + "error.file.minheight": "Høyden til bildet må være minst {height} piksler", + "error.file.minsize": "Filen er for liten", + "error.file.minwidth": "Bredden til bildet må være minst {width} piksler", + "error.file.name.missing": "Filnavnet kan ikke være tomt", + "error.file.notFound": "Finner ikke filen", + "error.file.orientation": "Bilderetningen må være \"{orientation}\"", + "error.file.type.forbidden": "Du har ikke lov til å laste opp filer av typen {type}", + "error.file.type.invalid": "Ugyldig filtype: {type}", + "error.file.undefined": "Finner ikke filen", + + "error.form.incomplete": "Vennligst fiks alle feil…", + "error.form.notSaved": "Skjemaet kunne ikke lagres", + + "error.language.code": "Vennligst skriv inn gyldig språkkode", + "error.language.duplicate": "Språket eksisterer allerede", + "error.language.name": "Vennligst skriv inn et gyldig navn for språket", + "error.language.notFound": "Finner ikke språket", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "Det er en feil i layout {index} innstillinger", + + "error.license.format": "Vennligst skriv inn gyldig lisensnøkkel", + "error.license.email": "Vennligst skriv inn en gyldig e-postadresse", + "error.license.verification": "Lisensen kunne ikke verifiseres", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "Panelet er i øyeblikket offline", + + "error.page.changeSlug.permission": "Du kan ikke endre URLen for denne siden", + "error.page.changeStatus.incomplete": "Siden har feil og kan ikke publiseres", + "error.page.changeStatus.permission": "Sidens status kan ikke endres", + "error.page.changeStatus.toDraft.invalid": "Siden \"{slug}\" kan ikke konverteres til et utkast", + "error.page.changeTemplate.invalid": "Malen for siden \"{slug}\" kan ikke endres", + "error.page.changeTemplate.permission": "Du har ikke tillatelse til å endre malen for \"{slug}\"", + "error.page.changeTitle.empty": "Tittelen kan ikke være tom", + "error.page.changeTitle.permission": "Du har ikke tillatelse til å endre tittelen for \"{slug}\"", + "error.page.create.permission": "Du har ikke tillatelse til å opprette \"{slug}\"", + "error.page.delete": "Siden \"{slug}\" kan ikke slettes", + "error.page.delete.confirm": "Vennligst skriv inn sidens tittel for å bekrefte", + "error.page.delete.hasChildren": "Siden har undersider og kan derfor ikke slettes", + "error.page.delete.permission": "Du har ikke til å slette \"{slug}\"", + "error.page.draft.duplicate": "Et sideutkast med URL-tillegget \"{slug}\" eksisterer allerede", + "error.page.duplicate": "En side med URL-tillegget \"{slug}\" eksisterer allerede", + "error.page.duplicate.permission": "Du har ikke tillatelse til å duplisere \"{slug}\"", + "error.page.notFound": "Siden \"{slug}\" ble ikke funnet", + "error.page.num.invalid": "Vennligst skriv inn et gyldig sorteringsnummer. Tallet må ikke være negativt.", + "error.page.slug.invalid": "Vennligst skriv inn en gyldig URL endelse", + "error.page.slug.maxlength": "Slug lengden må være mindre enn \"{length}\" karakterer", + "error.page.sort.permission": "Siden \"{slug}\" kan ikke sorteres", + "error.page.status.invalid": "Vennligst angi en gyldig sidestatus", + "error.page.undefined": "Siden kunne ikke bli funnet", + "error.page.update.permission": "Du har ikke tillatelse til å oppdatere \"{slug}\"", + + "error.section.files.max.plural": "Det er ikke mulig å legge til mer enn {max} filer i seksjonen \"{section}\"", + "error.section.files.max.singular": "Det er ikke mulig å legge til mer enn én fil i seksjonen \"{section}\"", + "error.section.files.min.plural": "Seksjonen \"{section}\" krever minst {min} filer", + "error.section.files.min.singular": "Seksjonen \"{section}\" krever minst en fil", + + "error.section.pages.max.plural": "Det er ikke mulig å legge til mer enn {max} sider i \"{section}\" seksjonen", + "error.section.pages.max.singular": "Det er ikke mulig å legge til mer enn én side i \"{section}\" seksjonen", + "error.section.pages.min.plural": "Seksjonen \"{section}\" krever minst {min} sider", + "error.section.pages.min.singular": "Seksjonen \"{section}\" krever minst en side", + + "error.section.notLoaded": "Seksjonen \"{name}\" kunne ikke lastes inn", + "error.section.type.invalid": "Seksjonstypen \"{type}\" er ikke gyldig", + + "error.site.changeTitle.empty": "Tittelen kan ikke være tom", + "error.site.changeTitle.permission": "Du har ikke tillatelse til å endre tittel på siden", + "error.site.update.permission": "Du har ikke tillatelse til å oppdatere denne siden", + + "error.template.default.notFound": "Standardmalen eksisterer ikke", + + "error.unexpected": "En uventet feil oppstod! Aktiver feilsøkmodus for mer info: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Du har ikke tillatelse til å endre e-post for brukeren \"{name}\"", + "error.user.changeLanguage.permission": "Du har ikke tillatelse til å endre språk for brukeren \"{name}\"", + "error.user.changeName.permission": "Du har ikke tillatelse til å endre navn for brukeren \"{name}\"", + "error.user.changePassword.permission": "Du har ikke tillatelse til å endre passord for brukeren \"{name}\"", + "error.user.changeRole.lastAdmin": "Rollen for den siste administratoren kan ikke endres", + "error.user.changeRole.permission": "Du har ikke tillatelse til å endre rollen for brukeren \"{name}\"", + "error.user.changeRole.toAdmin": "Du har ikke tillatelse til å endre noen til adminrolle", + "error.user.create.permission": "Du har ikke tillatelse til å opprette denne brukeren", + "error.user.delete": "Denne brukeren kunne ikke bli slettet", + "error.user.delete.lastAdmin": "Siste administrator kan ikke slettes", + "error.user.delete.lastUser": "Den siste brukeren kan ikke slettes", + "error.user.delete.permission": "Du er ikke tillat \u00e5 slette denne brukeren", + "error.user.duplicate": "En bruker med e-postadresse \"{email}\" eksisterer allerede", + "error.user.email.invalid": "Vennligst skriv inn en gyldig e-postadresse", + "error.user.language.invalid": "Vennligst skriv inn et gyldig språk", + "error.user.notFound": "Brukeren kunne ikke bli funnet", + "error.user.password.invalid": "Vennligst skriv inn et gyldig passord. Passordet må minst være 8 tegn langt.", + "error.user.password.notSame": "Vennligst bekreft passordet", + "error.user.password.undefined": "Brukeren har ikke et passord", + "error.user.password.wrong": "Feil passord", + "error.user.role.invalid": "Vennligst skriv inn en gyldig rolle", + "error.user.undefined": "Brukeren kunne ikke bli funnet", + "error.user.update.permission": "Du har ikke tillatelse til å oppdatere brukeren \"{name}\"", + + "error.validation.accepted": "Vennligst bekreft", + "error.validation.alpha": "Vennligst skriv kun tegn mellom a-z", + "error.validation.alphanum": "Vennligst skriv kun tegn mellom a-z eller tall mellom 0-9", + "error.validation.between": "Vennligst angi en verdi mellom \"{min}\" og \"{max}\"", + "error.validation.boolean": "Vennligst bekreft eller avslå", + "error.validation.contains": "Vennligst skriv inn en verdi som inneholder \"{needle}\"", + "error.validation.date": "Vennligst skriv inn en gyldig dato", + "error.validation.date.after": "Vennligst angi en dato etter {date}", + "error.validation.date.before": "Vennligst angi en dato før {date}", + "error.validation.date.between": "Vennligst angi en dato mellom {min} og {max}", + "error.validation.denied": "Vennligst avslå", + "error.validation.different": "Verdien kan ikke være \"{other}\"", + "error.validation.email": "Vennligst skriv inn en gyldig e-postadresse", + "error.validation.endswith": "Verdien må ende med \"{end}\"", + "error.validation.filename": "Vennligst skriv inn et gyldig filnavn", + "error.validation.in": "Vennligst skriv inn en av følgende: ({in})", + "error.validation.integer": "Vennligst skriv inn et gyldig tall", + "error.validation.ip": "Vennligst skriv inn en gyldig IP-adresse", + "error.validation.less": "Vennligst angi en verdi lavere enn {max}", + "error.validation.match": "Verdien samsvarer ikke med det forventede mønsteret", + "error.validation.max": "Vennligst angi en verdi lik eller lavere enn {max}", + "error.validation.maxlength": "Vennligst angi en kortere verdi. (maks. {max} tegn)", + "error.validation.maxwords": "Vennligst ikke skriv inn mer enn {max} ord", + "error.validation.min": "Vennligst angi en verdi lik eller større enn {min}", + "error.validation.minlength": "Vennligst angi en lengre verdi. (minimum. {min} tegn)", + "error.validation.minwords": "Vennligst skriv inn minst {min} ord", + "error.validation.more": "Vennligst angi en verdi større enn {min}", + "error.validation.notcontains": "Vennligst angi en verdi som ikke inneholder \"{needle}\"", + "error.validation.notin": "Vennligst ikke angi noen av følgende:({notIn})", + "error.validation.option": "Vennligst velg et gyldig alternativ", + "error.validation.num": "Vennligst angi et gyldig nummer", + "error.validation.required": "Vennligst skriv inn noe", + "error.validation.same": "Vennligst angi \"{other}\"", + "error.validation.size": "Størrelsen på verdien må være \"{size}\"", + "error.validation.startswith": "Verdien må starte med \"{start}\"", + "error.validation.time": "Vennligst angi et gyldig tidspunkt", + "error.validation.time.after": "Vennligst angi et tidspunkt etter {time}", + "error.validation.time.before": "Vennligst angi et tidspunkt før {time}", + "error.validation.time.between": "Vennligst angi et tidspunkt mellom {min} og {max}", + "error.validation.url": "Vennligst skriv inn en gyldig URL", + + "expand": "Utvid", + "expand.all": "Utvid alle", + + "field.required": "Feltet er påkrevd", + "field.blocks.changeType": "Endre type", + "field.blocks.code.name": "Kode", + "field.blocks.code.language": "Språk", + "field.blocks.code.placeholder": "Din kode…", + "field.blocks.delete.confirm": "Er du sikker på at du vil slette denne blokken?", + "field.blocks.delete.confirm.all": "Er du sikker på at du vil slette alle blokkene?", + "field.blocks.delete.confirm.selected": "Er du sikker på at du vil slette de valgte blokkene?", + "field.blocks.empty": "Ingen blokker enda", + "field.blocks.fieldsets.label": "Vennligst velg en blokktype…", + "field.blocks.fieldsets.paste": "Trykk {{ shortcut }} for å lime/importere blokker fra din utklippstavle", + "field.blocks.gallery.name": "Galleri", + "field.blocks.gallery.images.empty": "Ingen bilder enda", + "field.blocks.gallery.images.label": "Bilder", + "field.blocks.heading.level": "Nivå", + "field.blocks.heading.name": "Overskrift", + "field.blocks.heading.text": "Tekst", + "field.blocks.heading.placeholder": "Overskrift…", + "field.blocks.image.alt": "Alternativ tekst", + "field.blocks.image.caption": "Caption", + "field.blocks.image.crop": "Beskjær", + "field.blocks.image.link": "Adresse", + "field.blocks.image.location": "Plassering", + "field.blocks.image.name": "Bilde", + "field.blocks.image.placeholder": "Velg et bilde", + "field.blocks.image.ratio": "Ratio", + "field.blocks.image.url": "Bilde URL", + "field.blocks.line.name": "Linje", + "field.blocks.list.name": "Liste", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Tekst", + "field.blocks.markdown.placeholder": "Markdown…", + "field.blocks.quote.name": "Sitat", + "field.blocks.quote.text.label": "Tekst", + "field.blocks.quote.text.placeholder": "Sitat…", + "field.blocks.quote.citation.label": "Kildehenvisning", + "field.blocks.quote.citation.placeholder": "av…", + "field.blocks.text.name": "Tekst", + "field.blocks.text.placeholder": "Tekst…", + "field.blocks.video.caption": "Caption", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Legg til en video URL", + "field.blocks.video.url.label": "Video-URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Ingen filer har blitt valgt", + + "field.layout.delete": "Slett layout", + "field.layout.delete.confirm": "Er du sikker på at du vil slette denne layouten?", + "field.layout.empty": "Ingen rader enda", + "field.layout.select": "Velg en layout", + + "field.object.empty": "No information yet", + + "field.pages.empty": "Ingen side har blitt valgt", + + "field.structure.delete.confirm": "\u00d8nsker du virkelig \u00e5 slette denne oppf\u00f8ringen?", + "field.structure.empty": "Ingen oppf\u00f8ringer enda", + + "field.users.empty": "Ingen bruker har blitt valgt", + + "file.blueprint": "Denne filen har ikke en blueprint enda. Du kan definere oppsettet i /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Vil du virkelig slette denne filen?", + "file.sort": "Endre plassering", + + "files": "Filer", + "files.empty": "Ingen filer ennå", + + "hide": "Skjul", + "hour": "Tid", + "import": "Importer", + "info": "Info", + "insert": "Sett Inn", + "insert.after": "Sett inn etter", + "insert.before": "Sett inn før", + "install": "Installer", + + "installation": "Installasjon", + "installation.completed": "Panelet har blitt installert", + "installation.disabled": "Installasjonsprogrammet for Panelet er deaktivert på offentlige servere som standard. Vennligst kjør installasjonsprogrammet på en lokal maskin eller aktiver den med panel.install innstillingen.", + "installation.issues.accounts": "\/site\/accounts er ikke skrivbar", + "installation.issues.content": "Mappen content og alt av innhold m\u00e5 v\u00e6re skrivbar.", + "installation.issues.curl": "Utvidelsen CURL er nødvendig", + "installation.issues.headline": "Panelet kan ikke installeres", + "installation.issues.mbstring": "Utvidelsen MB String er nødvendig", + "installation.issues.media": "Mappen /media eksisterer ikke eller er ikke skrivbar", + "installation.issues.php": "Pass på at du bruker PHP 7+", + "installation.issues.server": "Kirby krever Apache, Nginx eller Caddy", + "installation.issues.sessions": "Mappen /site/sessions eksisterer ikke eller er ikke skrivbar", + + "language": "Spr\u00e5k", + "language.code": "Kode", + "language.convert": "Gjør til standard", + "language.convert.confirm": "

Vil du virkelig konvertere {name} til standardspråk? Dette kan ikke angres.

Dersom {name} har innhold som ikke er oversatt, vil nettstedet mangle innhold å falle tilbake på. Dette kan resultere i at deler av nettstedet fremstår som tomt.

", + "language.create": "Legg til språk", + "language.delete.confirm": "Vil du virkelig slette språket {name} inkludert alle oversettelser? Dette kan ikke angres!", + "language.deleted": "Språket har blitt slettet", + "language.direction": "Leseretning", + "language.direction.ltr": "Venstre til høyre", + "language.direction.rtl": "Høyre til venstre", + "language.locale": "PHP locale streng", + "language.locale.warning": "Du bruker et egendefinert lokalt oppsett. Vennligst endre det i språkfilen i /site/languages", + "language.name": "Navn", + "language.updated": "Språk har blitt oppdatert", + + "languages": "Språk", + "languages.default": "Standardspråk", + "languages.empty": "Det er ingen språk ennå", + "languages.secondary": "Sekundære språk", + "languages.secondary.empty": "Det er ingen andre språk ennå", + + "license": "Kirby lisens", + "license.buy": "Kjøp lisens", + "license.register": "Registrer", + "license.manage": "Manage your licenses", + "license.register.help": "Du skal ha mottatt din lisenskode for kjøpet via e-post. Vennligst kopier og lim inn denne for å registrere deg.", + "license.register.label": "Vennligst skriv inn din lisenskode", + "license.register.success": "Takk for at du støtter Kirby", + "license.unregistered": "Dette er en uregistrert demo av Kirby", + "license.unregistered.label": "Unregistered", + + "link": "Adresse", + "link.text": "Koblingstekst", + + "loading": "Laster inn", + + "lock.unsaved": "Ulagrede endringer", + "lock.unsaved.empty": "Det er ingen flere ulagrede endringer", + "lock.isLocked": "Ulagrede endringer av {email}", + "lock.file.isLocked": "Filen redigeres for øyeblikket av {email} og kan ikke endres.", + "lock.page.isLocked": "Siden redigeres for øyeblikket av {email} og kan ikke endres.", + "lock.unlock": "Lås opp", + "lock.isUnlocked": "Dine ulagrede endringer har blitt overskrevet av en annen bruker. Du kan laste ned dine endringer for å sammenslå dem manuelt", + + "login": "Logg Inn", + "login.code.label.login": "Login kode", + "login.code.label.password-reset": "Passord tilbakestillingskode", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "Dersom din e-post er registrert vil den forespurte koden bli sendt via e-post.", + "login.email.login.body": "Hei {user.nameOrEmail},\n\nDu ba nylig om en innloggingskode til panelet til {site}.\nFølgende innloggingskode vil være gyldig i {timeout} minutter:\n\n{code}\n\nDersom du ikke ba om en innloggingskode, vennligst ignorer denne e-posten eller kontakt din administrator hvis du har spørsmål.\nFor sikkerhets skyld, vennligst IKKE videresend denne e-posten.", + "login.email.login.subject": "Din innloggingskode", + "login.email.password-reset.body": "Hei {user.nameOrEmail},\n\nDu ba nylig om en tilbakestilling av passord til panelet til {site}.\nFølgende tilbakestillingskode vil være gyldig i {timeout} minutter:\n\n{code}\n\nDersom du ikke ba om en tilbakestillingskode, vennligst ignorer denne e-posten eller kontakt din administrator hvis du har spørsmål.\nFor sikkerhets skyld, vennligst IKKE videresend denne e-posten.", + "login.email.password-reset.subject": "Din kode for tilbakestilling av passord", + "login.remember": "Hold meg innlogget", + "login.reset": "Tilbakestill passord", + "login.toggleText.code.email": "Logg inn via e-post", + "login.toggleText.code.email-password": "Logg inn med passord", + "login.toggleText.password-reset.email": "Glemt passord?", + "login.toggleText.password-reset.email-password": "← Tilbake til innlogging", + + "logout": "Logg ut", + + "menu": "Meny", + "meridiem": "AM/PM", + "mime": "Mediatype", + "minutes": "Minutter", + + "month": "Måned", + "months.april": "April", + "months.august": "August", + "months.december": "Desember", + "months.february": "Februar", + "months.january": "Januar", + "months.july": "July", + "months.june": "Juni", + "months.march": "Mars", + "months.may": "Mai", + "months.november": "November", + "months.october": "Oktober", + "months.september": "September", + + "more": "Mer", + "name": "Navn", + "next": "Neste", + "no": "nei", + "off": "av", + "on": "på", + "open": "Åpne", + "open.newWindow": "Åpne i nytt vindu", + "options": "Alternativer", + "options.none": "Ingen alternativer", + + "orientation": "Orientering", + "orientation.landscape": "Landskap", + "orientation.portrait": "Portrett", + "orientation.square": "Kvadrat", + + "page.blueprint": "Denne siden har ikke en blueprint enda. Du kan definere oppsettet i /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Endre URL", + "page.changeSlug.fromTitle": "Opprett fra tittel", + "page.changeStatus": "Endre status", + "page.changeStatus.position": "Vennligst velg en posisjon", + "page.changeStatus.select": "Velg ny status", + "page.changeTemplate": "Endre mal", + "page.delete.confirm": "Vil du virkelig slette denne siden?", + "page.delete.confirm.subpages": "Denne siden har undersider.
Alle undersider vil også bli slettet.", + "page.delete.confirm.title": "Skriv inn sidetittel for å bekrefte", + "page.draft.create": "Lag utkast", + "page.duplicate.appendix": "Kopier", + "page.duplicate.files": "Kopier filer", + "page.duplicate.pages": "Kopier sider", + "page.sort": "Endre plassering", + "page.status": "Status", + "page.status.draft": "Utkast", + "page.status.draft.description": "Denne siden er i kladdmodus og er kun synlig for innloggede brukere eller via en hemmelig lenke.", + "page.status.listed": "Offentlig", + "page.status.listed.description": "Siden er offentlig og synlig for alle", + "page.status.unlisted": "Unotert", + "page.status.unlisted.description": "Siden er ikke er oppført og er kun tilgjengelig via URL", + + "pages": "Sider", + "pages.empty": "Ingen sider ennå", + "pages.status.draft": "Utkast", + "pages.status.listed": "Publisert", + "pages.status.unlisted": "Unotert", + + "pagination.page": "Side", + + "password": "Passord", + "paste": "Lim inn", + "paste.after": "Lim inn etter", + "pixel": "Piksel", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "Forrige", + "preview": "Forhåndsvisning", + "remove": "Fjern", + "rename": "Endre navn", + "replace": "Erstatt", + "retry": "Pr\u00f8v p\u00e5 nytt", + "revert": "Forkast", + "revert.confirm": "Er du sikker på at vil slette alle ulagrede endringer?", + + "role": "Rolle", + "role.admin.description": "Administrator har alle rettigheter", + "role.admin.title": "Admin", + "role.all": "Alle", + "role.empty": "Det er ingen brukere med denne rollen", + "role.description.placeholder": "Ingen beskrivelse", + "role.nobody.description": "Dette er en fallback rolle uten noen rettigheter.", + "role.nobody.title": "Ingen", + + "save": "Lagre", + "search": "Søk", + "search.min": "Skriv inn {min} tegn for å søke", + "search.all": "Vis alle", + "search.results.none": "Ingen resultater", + + "section.required": "Denne seksjonen er påkrevd", + + "security": "Security", + "select": "Velg", + "server": "Server", + "settings": "Innstillinger", + "show": "Vis", + "site.blueprint": "Denne siden har ikke en blueprint enda. Du kan definere oppsettet i /site/blueprints/site.yml", + "size": "Størrelse", + "slug": "URL-appendiks", + "sort": "Sortere", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Tittel", + "template": "Mal", + "today": "I dag", + + "toolbar.button.code": "Kode", + "toolbar.button.bold": "Fet tekst", + "toolbar.button.email": "Epost", + "toolbar.button.headings": "Overskrifter", + "toolbar.button.heading.1": "Overskrift 1", + "toolbar.button.heading.2": "Overskrift 2", + "toolbar.button.heading.3": "Overskrift 3", + "toolbar.button.heading.4": "Overskrift 4", + "toolbar.button.heading.5": "Overskrift 5", + "toolbar.button.heading.6": "Overskrift 6", + "toolbar.button.italic": "Kursiv tekst", + "toolbar.button.file": "Fil", + "toolbar.button.file.select": "Velg en fil", + "toolbar.button.file.upload": "Last opp en fil", + "toolbar.button.link": "Adresse", + "toolbar.button.paragraph": "Avsnitt", + "toolbar.button.strike": "Gjennomstreking", + "toolbar.button.ol": "Ordnet liste", + "toolbar.button.underline": "Understrek", + "toolbar.button.ul": "Punktliste", + + "translation.author": "Kirby Team", + "translation.direction": "ltr", + "translation.name": "Norsk Bokm\u00e5l", + "translation.locale": "nb_NO", + + "upload": "Last opp", + "upload.error.cantMove": "Den opplastede filen kunne ikke flyttes", + "upload.error.cantWrite": "Kunne ikke skrive fil til disk", + "upload.error.default": "Kunne ikke laste opp fil", + "upload.error.extension": "Filopplasting stoppet av en utvidelse", + "upload.error.formSize": "Den opplastede filen overskrider MAX_FILE_SIZE direktivet som er spesifisert i skjemaet", + "upload.error.iniPostSize": "Den opplastede filen overskrider post_max_size direktivet i php.ini", + "upload.error.iniSize": "Den opplastede filen overskrider upload_max_filesize direktivet i php.ini", + "upload.error.noFile": "Ingen fil ble lastet opp", + "upload.error.noFiles": "Ingen filer ble lastet opp", + "upload.error.partial": "Den opplastede filen ble bare delvis lastet opp", + "upload.error.tmpDir": "Mangler en midlertidig mappe", + "upload.errors": "Feil", + "upload.progress": "Laster opp…", + + "url": "Nettadresse", + "url.placeholder": "https://example.com", + + "user": "Bruker", + "user.blueprint": "Du kan definere flere seksjoner og skjemafelter for denne brukerrollen i /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Endre e-post", + "user.changeLanguage": "Endre språk", + "user.changeName": "Angi nytt navn for denne brukeren", + "user.changePassword": "Bytt passord", + "user.changePassword.new": "Nytt passord", + "user.changePassword.new.confirm": "Bekreft nytt passord…", + "user.changeRole": "Bytt rolle", + "user.changeRole.select": "Velg en ny rolle", + "user.create": "Legg til ny bruker", + "user.delete": "Slett denne brukeren", + "user.delete.confirm": "Vil du virkelig slette denne konten?", + + "users": "Brukere", + + "version": "Kirby versjon", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "Din konto", + "view.installation": "Installasjon", + "view.languages": "Språk", + "view.resetPassword": "Tilbakestill passord", + "view.site": "Side", + "view.system": "System", + "view.users": "Brukere", + + "welcome": "Velkommen", + "year": "År", + "yes": "ja" } diff --git a/kirby/i18n/translations/nl.json b/kirby/i18n/translations/nl.json index e9fee94..1e6cee3 100644 --- a/kirby/i18n/translations/nl.json +++ b/kirby/i18n/translations/nl.json @@ -1,573 +1,596 @@ { - "account.changeName": "Wijzig je naam", - "account.delete": "Verwijder je account", - "account.delete.confirm": "Wil je echt je account verwijderen? Je wordt direct uitgelogd. Uw account kan niet worden hersteld.", - - "add": "Voeg toe", - "author": "Auteur", - "avatar": "Avatar", - "back": "Terug", - "cancel": "Annuleren", - "change": "Wijzigen", - "close": "Sluiten", - "confirm": "OK", - "collapse": "Sluit", - "collapse.all": "Sluit alles", - "copy": "Kopiëren", - "copy.all": "Kopieer alles", - "create": "Aanmaken", - - "date": "Datum", - "date.select": "Selecteer een datum", - - "day": "Dag", - "days.fri": "Vr", - "days.mon": "Ma", - "days.sat": "Za", - "days.sun": "Zo", - "days.thu": "Do", - "days.tue": "Di", - "days.wed": "Wo", - - "debugging": "Foutopsporing", - - "delete": "Verwijderen", - "delete.all": "Verwijder alles", - - "dialog.files.empty": "Geen bestanden om te selecteren", - "dialog.pages.empty": "Geen pagina's om te selecteren", - "dialog.users.empty": "Geen gebruikers om te selecteren", - - "dimensions": "Dimensies", - "disabled": "Uitgeschakeld", - "discard": "Annuleren", - "download": "Download", - "duplicate": "Dupliceren", - - "edit": "Wijzig", - - "email": "E-mailadres", - "email.placeholder": "mail@voorbeeld.nl", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Omgeving", - - "error.access.code": "Ongeldige code", - "error.access.login": "Ongeldige login", - "error.access.panel": "Je hebt geen toegang tot het Panel", - "error.access.view": "Je hebt geen toegangsrechten voor deze zone van het Panel", - - "error.avatar.create.fail": "De avatar kon niet worden geupload", - "error.avatar.delete.fail": "De avatar kan niet worden verwijderd", - "error.avatar.dimensions.invalid": "Houd de breedte en hoogte van de avatar onder 3000 pixels", - "error.avatar.mime.forbidden": "De avatar moet een JPEG of PNG bestand zijn", - - "error.blueprint.notFound": "De blueprint \"{name}\" kon niet geladen worden", - - "error.blocks.max.plural": "Je kunt niet meer dan {max} blokken toevoegen", - "error.blocks.max.singular": "Je kunt niet meer dan één blok toevoegen", - "error.blocks.min.plural": "Je moet ten minste {min} blok toevoegen", - "error.blocks.min.singular": "Je moet ten minste één blok toevoegen", - "error.blocks.validation": "Er is een fout gevonden in blok {index}", - - "error.email.preset.notFound": "De e-mailvoorinstelling \"{name}\" kan niet worden gevonden", - - "error.field.converter.invalid": "Ongeldige converter \"{converter}\"", - - "error.file.changeName.empty": "De naam mag niet leeg zijn", - "error.file.changeName.permission": "Je hebt geen rechten om de naam te wijzigen van \"{filename}\"", - "error.file.duplicate": "Er bestaat al een bestand met de naam \"{filename}\"", - "error.file.extension.forbidden": "Bestandsextensie \"{extension}\" is niet toegestaan", - "error.file.extension.invalid": "Ongeldige extensie: {extension}", - "error.file.extension.missing": "Je kunt geen bestanden uploaden zonder bestandsextensie", - "error.file.maxheight": "De hoogte van de afbeelding mag niet groter zijn dan {height} pixels", - "error.file.maxsize": "Het bestand is te groot", - "error.file.maxwidth": "De breedte van de afbeelding mag niet groter zijn dan {width} pixels", - "error.file.mime.differs": "Het geüploade bestand moet van hetzelfde mime-type zijn: \"{mime}\"", - "error.file.mime.forbidden": "Het type \"{mime}\" is niet toegestaan", - "error.file.mime.invalid": "Ongeldig media type: {mine}", - "error.file.mime.missing": "Het mediatype voor \"{filename}\" kan niet worden gedecteerd", - "error.file.minheight": "De hoogte van de afbeelding moet minimaal {height} pixels zijn", - "error.file.minsize": "Het bestand is te klein", - "error.file.minwidth": "De breedte van de afbeelding moet minimaal {width} pixels zijn", - "error.file.name.missing": "De bestandsnaam mag niet leeg zijn", - "error.file.notFound": "Het bestand kan niet worden gevonden", - "error.file.orientation": "De oriëntatie van de afbeelding moet \"{orientation}\" zijn", - "error.file.type.forbidden": "Je hebt geen rechten om {type} bestanden up te loaden", - "error.file.type.invalid": "Ongeldig bestands type: {type}", - "error.file.undefined": "Het bestand kan niet worden gevonden", - - "error.form.incomplete": "Verbeter alle fouten in het formulier", - "error.form.notSaved": "Het formulier kon niet worden opgeslagen", - - "error.language.code": "Vul een geldige code voor deze taal in", - "error.language.duplicate": "De taal bestaat al", - "error.language.name": "Vul een geldige naam voor deze taal in", - "error.language.notFound": "De taal kan niet worden gevonden", - - "error.layout.validation.block": "Er is een fout gevonden in blok {blockIndex} in ontwerp {layoutIndex}", - "error.layout.validation.settings": "Er is een fout gevonden in de instellingen van ontwerp {index} ", - - "error.license.format": "Vul een gelidge licentie-key in", - "error.license.email": "Gelieve een geldig emailadres in te voeren", - "error.license.verification": "De licentie kon niet worden geverifieerd. ", - - "error.offline": "Het Panel is momenteel offline", - - "error.page.changeSlug.permission": "Je kunt de URL van deze pagina niet wijzigen", - "error.page.changeStatus.incomplete": "Deze pagina bevat fouten en kan niet worden gepubliceerd", - "error.page.changeStatus.permission": "De status van deze pagina kan niet worden gewijzigd", - "error.page.changeStatus.toDraft.invalid": "De pagina \"{slug}\" kan niet worden aangepast naar 'concept'", - "error.page.changeTemplate.invalid": "De template van deze pagina \"{slug}\" kan niet worden gewijzigd", - "error.page.changeTemplate.permission": "Je hebt geen rechten om het template te wijzigen van \"{slug}\"", - "error.page.changeTitle.empty": "De titel mag niet leeg zijn", - "error.page.changeTitle.permission": "Je hebt geen rechten om de titel te wijzigen van \"{slug}\"", - "error.page.create.permission": "Je hebt geen rechten om \"{slug}\" aan te maken", - "error.page.delete": "De pagina \"{slug}\" kan niet worden verwijderd", - "error.page.delete.confirm": "Voer de paginatitel in om te bevestigen", - "error.page.delete.hasChildren": "Deze pagina heeft subpagina's en kan niet worden verwijderd", - "error.page.delete.permission": "Je hebt geen rechten om \"{slug}\" te verwijderen", - "error.page.draft.duplicate": "Er bestaat al een conceptpagina met de URL-appendix \"{slug}\"", - "error.page.duplicate": "Er bestaat al een pagina met de URL-appendix \"{slug}\"", - "error.page.duplicate.permission": "Je bent niet gemachtigd om \"{slug}\" te dupliceren", - "error.page.notFound": "De pagina \"{slug}\" kan niet worden gevonden", - "error.page.num.invalid": "Vul een geldig sorteer-cijfer in. Het cijfer mag niet negatief zijn", - "error.page.slug.invalid": "Vul een geldig URL-achtervoegsel in", - "error.page.slug.maxlength": "Slug lengte moet minder dan \"{length}\" tekens bevatten", - "error.page.sort.permission": "De pagina \"{slug}\" kan niet worden gesorteerd", - "error.page.status.invalid": "Zorg voor een geldige paginastatus", - "error.page.undefined": "De pagina kan niet worden gevonden", - "error.page.update.permission": "Je hebt geen rechten om \"{slug}\" te updaten", - - "error.section.files.max.plural": "Voeg niet meer dan {max} bestanden toe aan de zone \"{section}\"", - "error.section.files.max.singular": "Je kunt niet meer dan 1 bestand toevoegen aan de zone \"{section}\"", - "error.section.files.min.plural": "De \"{section}\" sectie moet minimaal {min} bestanden bevatten.", - "error.section.files.min.singular": "De \"{section}\" sectie moet minimaal 1 bestand bevatten.", - - "error.section.pages.max.plural": "Je kunt niet meer dan {max} pagina's toevoegen aan de zone \"{section}\"", - "error.section.pages.max.singular": "Je kunt niet meer dan 1 pagina toevoegen aan de zone \"{section}\"", - "error.section.pages.min.plural": "De \"{section}\" sectie moet minimaal {min} pagina's bevatten.", - "error.section.pages.min.singular": "De \"{section}\" sectie moet minimaal 1 pagina bevatten.", - - "error.section.notLoaded": "De zone \"{name}\" kan niet worden geladen", - "error.section.type.invalid": "Zone-type \"{type}\" is niet geldig", - - "error.site.changeTitle.empty": "De titel mag niet leeg zijn", - "error.site.changeTitle.permission": "Je hebt geen rechten om de titel van de site te wijzigen", - "error.site.update.permission": "Je hebt geen rechten om de site te updaten", - - "error.template.default.notFound": "Het standaard template bestaat niet", - - "error.unexpected": "Een onverwacht fout heeft plaats gevonden! Schakel debug-modus in voor meer informatie: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Je hebt geen rechten om het e-mailadres van gebruiker \"{name}\" te wijzigen", - "error.user.changeLanguage.permission": "Je hebt geen rechten om de taal voor gebruiker \"{name}\" te wijzigen", - "error.user.changeName.permission": "Je hebt geen rechten om de naam van gebruiker \"{name}\" te wijzigen", - "error.user.changePassword.permission": "Je hebt geen rechten om het wachtwoord van gebruiker \"{name}\" te wijzigen", - "error.user.changeRole.lastAdmin": "De rol van de laatste beheerder kan niet worden gewijzigd", - "error.user.changeRole.permission": "Je hebt geen rechten om de rol van gebruiker \"{name}\" te wijzigen", - "error.user.changeRole.toAdmin": "Je hebt geen rechten om de rol van iemand te wijzigen naar admin", - "error.user.create.permission": "Je hebt geen rechten om deze gebruiker aan te maken", - "error.user.delete": "De gebruiker \"{name}\" kan niet worden verwijderd", - "error.user.delete.lastAdmin": "Je kan de laatste admin niet verwijderen", - "error.user.delete.lastUser": "De laatste gebruiker kan niet worden verwijderd", - "error.user.delete.permission": "Je hebt geen rechten om gebruiker \"{name}\" te verwijderen", - "error.user.duplicate": "Er bestaat al een gebruiker met e-mailadres \"{email}\"", - "error.user.email.invalid": "Gelieve een geldig emailadres in te voeren", - "error.user.language.invalid": "Gelieve een geldige taal in te voeren", - "error.user.notFound": "De gebruiker \"{name}\" kan niet worden gevonden", - "error.user.password.invalid": "Gelieve een geldig wachtwoord in te voeren. Wachtwoorden moeten minstens 8 karakters lang zijn.", - "error.user.password.notSame": "De wachtwoorden komen niet overeen", - "error.user.password.undefined": "De gebruiker heeft geen wachtwoord", - "error.user.password.wrong": "Fout wachtwoord", - "error.user.role.invalid": "Gelieve een geldige rol in te voeren", - "error.user.undefined": "De gebruiker kan niet worden gevonden", - "error.user.update.permission": "Je hebt geen rechten om gebruiker \"{name}\" te updaten", - - "error.validation.accepted": "Gelieve te bevestigen", - "error.validation.alpha": "Vul alleen a-z karakters in", - "error.validation.alphanum": "Vul alleen a-z karakters of cijfers (0-9) in", - "error.validation.between": "Vul een waarde tussen \"{min}\" en \"{max}\"", - "error.validation.boolean": "Ga akkoord of weiger", - "error.validation.contains": "Vul een waarde in die \"{needle}\" bevat", - "error.validation.date": "Vul een geldige datum in", - "error.validation.date.after": "Vul een datum in na {date}", - "error.validation.date.before": "Vul een datum in voor {date}", - "error.validation.date.between": "Vul een datum in tussen {min} en {max}", - "error.validation.denied": "Weiger", - "error.validation.different": "De invoer mag niet \"{other}\" zijn", - "error.validation.email": "Gelieve een geldig emailadres in te voeren", - "error.validation.endswith": "De invoer moet eindigen met \"{end}\"", - "error.validation.filename": "Vul een geldige bestandsnaam in", - "error.validation.in": "Vul één van de volgende dingen in: ({in})", - "error.validation.integer": "Vul een geldig geheel getal in", - "error.validation.ip": "Vul een geldig IP-adres in", - "error.validation.less": "Vul een waarde in lager dan {max}", - "error.validation.match": "De invoer klopt niet met het verwachte patroon", - "error.validation.max": "Vul een waarde in die gelijk is aan of lager dan {max}", - "error.validation.maxlength": "Gebruik minder karakters (maximaal {max} karakters)", - "error.validation.maxwords": "Vul minder dan {max} woord(en) in", - "error.validation.min": "Vul een waarde in die gelijk is aan of groter dan {min}", - "error.validation.minlength": "Gebruik meer karakters (minimaal {min} karakters)", - "error.validation.minwords": "Vul minimaal {min} woord(en) in", - "error.validation.more": "Vul een grotere waarde in dan {min}", - "error.validation.notcontains": "Zorg dat de invoer niet \"{needle}\" bevat", - "error.validation.notin": "Vul de volgende dingen niet in: ({notIn})", - "error.validation.option": "Selecteer een geldige optie", - "error.validation.num": "Vul een geldig cijfer in", - "error.validation.required": "Vul iets in", - "error.validation.same": "Vul \"{other}\" in", - "error.validation.size": "De lengte van de invoer moet \"{size}\" zijn", - "error.validation.startswith": "De invoer moet beginnen met \"{start}\"", - "error.validation.time": "Vul een geldige tijd in", - "error.validation.time.after": "Voer een tijd in na {time}", - "error.validation.time.before": "Voer een tijd in voor {time}", - "error.validation.time.between": "Voer een tijd in tussen {min} en {max}", - "error.validation.url": "Vul een geldige URL in", - - "expand": "Open", - "expand.all": "Open alles", - - "field.required": "Dit veld is verplicht", - "field.blocks.changeType": "Wijzig type", - "field.blocks.code.name": "Code", - "field.blocks.code.language": "Taal", - "field.blocks.code.placeholder": "Jouw code ...", - "field.blocks.delete.confirm": "Wil je echt dit blok wilt verwijderen?", - "field.blocks.delete.confirm.all": "Wil je echt alle blokken verwijderen?", - "field.blocks.delete.confirm.selected": "Wil je de geselecteerde blokken echt verwijderen?", - "field.blocks.empty": "Nog geen blokken", - "field.blocks.fieldsets.label": "Selecteer een bloktype ...", - "field.blocks.fieldsets.paste": "Druk op {{ shortcut }} om blokken van je klembord te plakken/importeren", - "field.blocks.gallery.name": "Galerij", - "field.blocks.gallery.images.empty": "Nog geen afbeeldingen", - "field.blocks.gallery.images.label": "Afbeeldingen", - "field.blocks.heading.level": "Niveau", - "field.blocks.heading.name": "Koptekst", - "field.blocks.heading.text": "Tekst", - "field.blocks.heading.placeholder": "Koptekst ...", - "field.blocks.image.alt": "Alternatieve tekst", - "field.blocks.image.caption": "Beschrijving", - "field.blocks.image.crop": "Uitsnede", - "field.blocks.image.link": "Link", - "field.blocks.image.location": "Locatie", - "field.blocks.image.name": "Afbeelding", - "field.blocks.image.placeholder": "Selecteer een afbeelding", - "field.blocks.image.ratio": "Verhouding", - "field.blocks.image.url": "Afbeeldings-URL", - "field.blocks.line.name": "Lijn", - "field.blocks.list.name": "Lijst", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Tekst", - "field.blocks.markdown.placeholder": "Markdown ...", - "field.blocks.quote.name": "Citaat", - "field.blocks.quote.text.label": "Tekst", - "field.blocks.quote.text.placeholder": "Citaat ...", - "field.blocks.quote.citation.label": "Bron", - "field.blocks.quote.citation.placeholder": "door ...", - "field.blocks.text.name": "Tekst", - "field.blocks.text.placeholder": "Tekst ...", - "field.blocks.video.caption": "Beschrijving", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Voer een video link in", - "field.blocks.video.url.label": "Video link", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Nog geen bestanden geselecteerd", - - "field.layout.delete": "Verwijder indeling", - "field.layout.delete.confirm": "Weet je zeker dat je deze indeling wilt verwijderen?", - "field.layout.empty": "Er zijn nog geen rijen", - "field.layout.select": "Selecteer een indeling", - - "field.pages.empty": "Nog geen pagina's geselecteerd", - "field.structure.delete.confirm": "Wil je deze entry verwijderen?", - "field.structure.empty": "Nog geen items.", - "field.users.empty": "Nog geen gebruikers geselecteerd", - - "file.blueprint": "Dit bestand heeft nog geen blauwdruk. U kunt de instellingen definiëren in /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Wil je dit bestand
{filename} verwijderen?", - "file.sort": "Verander positie", - - "files": "Bestanden", - "files.empty": "Nog geen bestanden", - - "hide": "Verberg", - "hour": "Uur", - "import": "Importeer", - "info": "Info", - "insert": "Toevoegen", - "insert.after": "Voeg toe na", - "insert.before": "Voeg toe voor", - "install": "Installeren", - - "installation": "Installatie", - "installation.completed": "Het Panel is geïnstalleerd", - "installation.disabled": "Je kan geen Panel installatie uitvoeren op een openbare server. Voer het installatieprogramma uit op een lokale computer of schakel het in met de panel.install optie.", - "installation.issues.accounts": "De map /site/accounts heeft geen schrijfrechten", - "installation.issues.content": "De map /content bestaat niet of heeft geen schrijfrechten", - "installation.issues.curl": "De CURL-extensie is vereist", - "installation.issues.headline": "Het Panel kan niet worden geïnstalleerd", - "installation.issues.mbstring": "De MB String extensie is verplicht", - "installation.issues.media": "De map /mediabestaat niet of heeft geen schrijfrechten", - "installation.issues.php": "Gebruik PHP7+", - "installation.issues.server": "Kirby vereist Apache, Nginx of Caddy", - "installation.issues.sessions": "De map /site/sessions bestaat niet of heeft geen schrijfrechten", - - "language": "Taal", - "language.code": "Code", - "language.convert": "Maak standaard", - "language.convert.confirm": "

Weet je zeker dat je {name} wilt aanpassen naar de standaard taal? Dit kan niet ongedaan worden gemaakt

Als {name} nog niet vertaalde content heeft, is er geen content meer om op terug te vallen en zouden delen van je site leeg kunnen zijn.

", - "language.create": "Nieuwe taal toevoegen", - "language.delete.confirm": "Weet je zeker dat je de taal {name} inclusief alle vertalingen wilt verwijderen? Je kunt dit niet ongedaan maken!", - "language.deleted": "De taal is verwijderd", - "language.direction": "Leesrichting", - "language.direction.ltr": "Links naar rechts", - "language.direction.rtl": "Rechts naar links", - "language.locale": "PHP-locale regel", - "language.locale.warning": "Je gebruikt een aangepaste landinstelling. Wijzig het het taalbestand in /site/languages", - "language.name": "Naam", - "language.updated": "De taal is geüpdatet", - - "languages": "Talen", - "languages.default": "Standaard taal", - "languages.empty": "Er zijn nog geen talen", - "languages.secondary": "Andere talen", - "languages.secondary.empty": "Er zijn nog geen andere talen beschikbaar", - - "license": "Licentie", - "license.buy": "Koop een licentie", - "license.register": "Registreren", - "license.manage": "Manage your licenses", - "license.register.help": "Je hebt de licentie via e-mail gekregen nadat je de aankoop hebt gedaan. Kopieer en plak de licentie om te registreren. ", - "license.register.label": "Vul je licentie in", - "license.register.success": "Bedankt dat je Kirby ondersteunt", - "license.unregistered": "Dit is een niet geregistreerde demo van Kirby", - "license.unregistered.label": "Unregistered", - - "link": "Link", - "link.text": "Linktekst", - - "loading": "Laden", - - "lock.unsaved": "Niet opgeslagen wijzigingen", - "lock.unsaved.empty": "Er zijn geen niet opgeslagen wijzigingen meer", - "lock.isLocked": "Niet opgeslagen wijzigingen door {email}", - "lock.file.isLocked": "Dit bestand wordt momenteel bewerkt door {email} en kan niet worden gewijzigd.", - "lock.page.isLocked": "Deze pagina wordt momenteel bewerkt door {email} en kan niet worden gewijzigd.", - "lock.unlock": "Ontgrendelen", - "lock.isUnlocked": "Je niet opgeslagen wijzigingen zijn overschreven door een andere gebruiker. Je kunt je wijzigingen downloaden om ze handmatig samen te voegen.", - - "login": "Inloggen", - "login.code.label.login": "Log in code", - "login.code.label.password-reset": "Wachtwoord herstel code", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "Als uw e-mailadres geregistreerd is, werd de gevraagde code per e-mail verzonden.", - "login.email.login.body": "Hallo {user.nameOrEmail},\n\nJe hebt onlangs een inlogcode aangevraagd voor het Panel van {site}.\nDe volgende inlogcode is {timeout} minuten geldig:\n\n{code}\n\nAls je geen inlogcode hebt aangevraagd, mag je deze mail negeren of neem je contact op met uw beheerder.\nOm veiligheidsredenen verzoeken wij deze e-mail NIET door te sturen.", - "login.email.login.subject": "Jouw log in code", - "login.email.password-reset.body": "Hallo {user.nameOrEmail},\n\nJe hebt onlangs een paswoord herstel code aangevraagd voor het Panel van {site}.\nDe volgende paswoord herstel code is {timeout} minuten geldig:\n\n{code}\n\nAls je geen paswoord herstel code hebt aangevraagd, mag je deze mail negeren of neem je contact op met uw beheerder.\nOm veiligheidsredenen verzoeken wij deze e-mail NIET door te sturen.", - "login.email.password-reset.subject": "Jouw wachtwoord herstel code", - "login.remember": "Houd mij ingelogd", - "login.reset": "Wachtwoord herstellen", - "login.toggleText.code.email": "Log in via email", - "login.toggleText.code.email-password": "Log in met je wachtwoord", - "login.toggleText.password-reset.email": "Wachtwoord vergeten?", - "login.toggleText.password-reset.email-password": "← Terug naar log in", - - "logout": "Uitloggen", - - "menu": "Menu", - "meridiem": "AM/PM", - "mime": "Mime-type", - "minutes": "Minuten", - - "month": "Maand", - "months.april": "april", - "months.august": "augustus", - "months.december": "december", - "months.february": "februari", - "months.january": "januari", - "months.july": "juli", - "months.june": "juni", - "months.march": "maart", - "months.may": "mei", - "months.november": "november", - "months.october": "oktober", - "months.september": "september", - - "more": "Meer", - "name": "Naam", - "next": "Volgende", - "no": "nee", - "off": "uit", - "on": "aan", - "open": "Open", - "open.newWindow": "Openen in een nieuw scherm", - "options": "Opties", - "options.none": "Geen opties beschikbaar", - - "orientation": "Oriëntatie", - "orientation.landscape": "Liggend", - "orientation.portrait": "Staand", - "orientation.square": "Vierkant", - - "page.blueprint": "Deze pagina heeft nog geen blauwdruk. Je kan de instellingen definiëren in /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Verander URL", - "page.changeSlug.fromTitle": "Aanmaken op basis van titel", - "page.changeStatus": "Wijzig status", - "page.changeStatus.position": "Selecteer een positie", - "page.changeStatus.select": "Selecteer een nieuwe status", - "page.changeTemplate": "Verander template", - "page.delete.confirm": "Weet je zeker dat je pagina {title} wilt verwijderen?", - "page.delete.confirm.subpages": "Deze pagina heeft subpagina's.
Alle subpagina's zullen ook worden verwijderd.", - "page.delete.confirm.title": "Voeg een paginatitel in om te bevestigen", - "page.draft.create": "Maak concept", - "page.duplicate.appendix": "Kopiëren", - "page.duplicate.files": "Kopieer bestanden", - "page.duplicate.pages": "Kopieer pagina's", - "page.sort": "Verander positie", - "page.status": "Status", - "page.status.draft": "Concept", - "page.status.draft.description": "De pagina is in concept-modus en alleen zichtbaar voor ingelogde redacteuren of via een geheime link", - "page.status.listed": "Openbaar", - "page.status.listed.description": "Deze pagina is toegankelijk voor iedereen", - "page.status.unlisted": "Niet gepubliceerd", - "page.status.unlisted.description": "Deze pagina is alleen bereikbaar via URL", - - "pages": "Pagina’s", - "pages.empty": "Nog geen pagina's", - "pages.status.draft": "Concepten", - "pages.status.listed": "Gepubliceerd", - "pages.status.unlisted": "Niet gepubliceerd", - - "pagination.page": "Pagina", - - "password": "Wachtwoord", - "paste": "Plak", - "paste.after": "Plak achter", - "pixel": "Pixel", - "plugins": "Plugins", - "prev": "Vorige", - "preview": "Voorbeeld", - "remove": "Verwijder", - "rename": "Hernoem", - "replace": "Vervang", - "retry": "Probeer opnieuw", - "revert": "Annuleren", - "revert.confirm": "Weet je zeker dat je alle niet-opgeslagen veranderingen wilt verwijderen?", - - "role": "Rol", - "role.admin.description": "De admin heeft alle rechten", - "role.admin.title": "Admin", - "role.all": "Alle", - "role.empty": "Er zijn geen gebruikers met deze rol", - "role.description.placeholder": "Geen beschrijving", - "role.nobody.description": "Dit is een fallback-rol zonder rechten", - "role.nobody.title": "Niemand", - - "save": "Opslaan", - "search": "Zoeken", - "search.min": "Voer {min} tekens in om te zoeken", - "search.all": "Toon alles", - "search.results.none": "Geen resultaten", - - "section.required": "De sectie is verplicht", - - "security": "Security", - "select": "Selecteren", - "server": "Server", - "settings": "Opties", - "show": "Toon", - "site.blueprint": "Deze website heeft nog geen ontwerp. Je kan het ontwerp hier plaatsen/site/blueprints/site.yml", - "size": "Grootte", - "slug": "URL-toevoeging", - "sort": "Sorteren", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Titel", - "template": "Template", - "today": "Vandaag", - - "toolbar.button.code": "Code", - "toolbar.button.bold": "Dikgedrukte tekst", - "toolbar.button.email": "E-mailadres", - "toolbar.button.headings": "Kopteksten", - "toolbar.button.heading.1": "Koptekst 1", - "toolbar.button.heading.2": "Koptekst 2", - "toolbar.button.heading.3": "Koptekst 3", - "toolbar.button.heading.4": "Hoofding 4", - "toolbar.button.heading.5": "Hoofding 5", - "toolbar.button.heading.6": "Hoofding 6", - "toolbar.button.italic": "Cursieve tekst", - "toolbar.button.file": "Bestand", - "toolbar.button.file.select": "Selecteer een bestand", - "toolbar.button.file.upload": "Upload bestand", - "toolbar.button.link": "Link", - "toolbar.button.paragraph": "Paragraaf", - "toolbar.button.strike": "Doorstreept", - "toolbar.button.ol": "Genummerde lijst", - "toolbar.button.underline": "Onderlijn", - "toolbar.button.ul": "Opsomming", - - "translation.author": "Het team van Kirby", - "translation.direction": "ltr", - "translation.name": "Nederlands", - "translation.locale": "nl_NL", - - "upload": "Upload", - "upload.error.cantMove": "Het geüploadde bestand kon niet worden verplaatst", - "upload.error.cantWrite": "Fout bij het schrijven van het bestand naar de schijf", - "upload.error.default": "Het bestand kan niet worden geüpload", - "upload.error.extension": "Kan bestand niet uploaden vanwege de extensie", - "upload.error.formSize": "Het geüploadde bestand is groter dan de MAX_FILE_SIZE die is aangegeven in het formulier", - "upload.error.iniPostSize": "Het geüploadde bestand is groter dan de post_max_size in php.ini", - "upload.error.iniSize": "Het geüploadde bestand is groter dan de upload_max_filesize in php.ini", - "upload.error.noFile": "Er is geen bestand geüpload", - "upload.error.noFiles": "Er zijn geen bestanden geüpload", - "upload.error.partial": "Het geüploadde bestand is slechts gedeeltelijk geüpload", - "upload.error.tmpDir": "Er mist een tijdelijke map", - "upload.errors": "Foutmelding", - "upload.progress": "Uploaden...", - - "url": "Url", - "url.placeholder": "https://voorbeeld.nl", - - "user": "Gebruiker", - "user.blueprint": "Je kan aanvullende secties en formuliervelden voor deze gebruikersrol definiëren in /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Email veranderen", - "user.changeLanguage": "Taal veranderen", - "user.changeName": "Gebruiker hernoemen", - "user.changePassword": "Wachtwoord wijzigen", - "user.changePassword.new": "Nieuw wachtwoord", - "user.changePassword.new.confirm": "Bevestig het nieuwe wachtwoord...", - "user.changeRole": "Verander rol", - "user.changeRole.select": "Kies een nieuwe rol", - "user.create": "Voeg een nieuwe gebruiker toe", - "user.delete": "Verwijder deze gebruiker", - "user.delete.confirm": "Weet je zeker dat je
{email} wil verwijderen?", - - "users": "Gebruikers", - - "version": "Kirby-versie", - - "view.account": "Jouw account", - "view.installation": "Installatie", - "view.languages": "Talen", - "view.resetPassword": "Wachtwoord herstellen", - "view.site": "Site", - "view.system": "Systeem", - "view.users": "Gebruikers", - - "welcome": "Welkom", - "year": "Jaar", - "yes": "ja" + "account.changeName": "Wijzig je naam", + "account.delete": "Verwijder je account", + "account.delete.confirm": "Wil je echt je account verwijderen? Je wordt direct uitgelogd. Uw account kan niet worden hersteld.", + + "add": "Voeg toe", + "author": "Auteur", + "avatar": "Avatar", + "back": "Terug", + "cancel": "Annuleren", + "change": "Wijzigen", + "close": "Sluiten", + "confirm": "OK", + "collapse": "Sluit", + "collapse.all": "Sluit alles", + "copy": "Kopiëren", + "copy.all": "Kopieer alles", + "create": "Aanmaken", + + "date": "Datum", + "date.select": "Selecteer een datum", + + "day": "Dag", + "days.fri": "Vr", + "days.mon": "Ma", + "days.sat": "Za", + "days.sun": "Zo", + "days.thu": "Do", + "days.tue": "Di", + "days.wed": "Wo", + + "debugging": "Foutopsporing", + + "delete": "Verwijderen", + "delete.all": "Verwijder alles", + + "dialog.files.empty": "Geen bestanden om te selecteren", + "dialog.pages.empty": "Geen pagina's om te selecteren", + "dialog.users.empty": "Geen gebruikers om te selecteren", + + "dimensions": "Dimensies", + "disabled": "Uitgeschakeld", + "discard": "Annuleren", + "download": "Download", + "duplicate": "Dupliceren", + + "edit": "Wijzig", + + "email": "E-mailadres", + "email.placeholder": "mail@voorbeeld.nl", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Omgeving", + + "error.access.code": "Ongeldige code", + "error.access.login": "Ongeldige login", + "error.access.panel": "Je hebt geen toegang tot het Panel", + "error.access.view": "Je hebt geen toegangsrechten voor deze zone van het Panel", + + "error.avatar.create.fail": "De avatar kon niet worden geupload", + "error.avatar.delete.fail": "De avatar kan niet worden verwijderd", + "error.avatar.dimensions.invalid": "Houd de breedte en hoogte van de avatar onder 3000 pixels", + "error.avatar.mime.forbidden": "De avatar moet een JPEG of PNG bestand zijn", + + "error.blueprint.notFound": "De blueprint \"{name}\" kon niet geladen worden", + + "error.blocks.max.plural": "Je kunt niet meer dan {max} blokken toevoegen", + "error.blocks.max.singular": "Je kunt niet meer dan één blok toevoegen", + "error.blocks.min.plural": "Je moet ten minste {min} blok toevoegen", + "error.blocks.min.singular": "Je moet ten minste één blok toevoegen", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "De e-mailvoorinstelling \"{name}\" kan niet worden gevonden", + + "error.field.converter.invalid": "Ongeldige converter \"{converter}\"", + + "error.file.changeName.empty": "De naam mag niet leeg zijn", + "error.file.changeName.permission": "Je hebt geen rechten om de naam te wijzigen van \"{filename}\"", + "error.file.duplicate": "Er bestaat al een bestand met de naam \"{filename}\"", + "error.file.extension.forbidden": "Bestandsextensie \"{extension}\" is niet toegestaan", + "error.file.extension.invalid": "Ongeldige extensie: {extension}", + "error.file.extension.missing": "Je kunt geen bestanden uploaden zonder bestandsextensie", + "error.file.maxheight": "De hoogte van de afbeelding mag niet groter zijn dan {height} pixels", + "error.file.maxsize": "Het bestand is te groot", + "error.file.maxwidth": "De breedte van de afbeelding mag niet groter zijn dan {width} pixels", + "error.file.mime.differs": "Het geüploade bestand moet van hetzelfde mime-type zijn: \"{mime}\"", + "error.file.mime.forbidden": "Het type \"{mime}\" is niet toegestaan", + "error.file.mime.invalid": "Ongeldig media type: {mine}", + "error.file.mime.missing": "Het mediatype voor \"{filename}\" kan niet worden gedecteerd", + "error.file.minheight": "De hoogte van de afbeelding moet minimaal {height} pixels zijn", + "error.file.minsize": "Het bestand is te klein", + "error.file.minwidth": "De breedte van de afbeelding moet minimaal {width} pixels zijn", + "error.file.name.missing": "De bestandsnaam mag niet leeg zijn", + "error.file.notFound": "Het bestand kan niet worden gevonden", + "error.file.orientation": "De oriëntatie van de afbeelding moet \"{orientation}\" zijn", + "error.file.type.forbidden": "Je hebt geen rechten om {type} bestanden up te loaden", + "error.file.type.invalid": "Ongeldig bestands type: {type}", + "error.file.undefined": "Het bestand kan niet worden gevonden", + + "error.form.incomplete": "Verbeter alle fouten in het formulier", + "error.form.notSaved": "Het formulier kon niet worden opgeslagen", + + "error.language.code": "Vul een geldige code voor deze taal in", + "error.language.duplicate": "De taal bestaat al", + "error.language.name": "Vul een geldige naam voor deze taal in", + "error.language.notFound": "De taal kan niet worden gevonden", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "Er is een fout gevonden in de instellingen van ontwerp {index} ", + + "error.license.format": "Vul een gelidge licentie-key in", + "error.license.email": "Gelieve een geldig emailadres in te voeren", + "error.license.verification": "De licentie kon niet worden geverifieerd. ", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "Het Panel is momenteel offline", + + "error.page.changeSlug.permission": "Je kunt de URL van deze pagina niet wijzigen", + "error.page.changeStatus.incomplete": "Deze pagina bevat fouten en kan niet worden gepubliceerd", + "error.page.changeStatus.permission": "De status van deze pagina kan niet worden gewijzigd", + "error.page.changeStatus.toDraft.invalid": "De pagina \"{slug}\" kan niet worden aangepast naar 'concept'", + "error.page.changeTemplate.invalid": "De template van deze pagina \"{slug}\" kan niet worden gewijzigd", + "error.page.changeTemplate.permission": "Je hebt geen rechten om het template te wijzigen van \"{slug}\"", + "error.page.changeTitle.empty": "De titel mag niet leeg zijn", + "error.page.changeTitle.permission": "Je hebt geen rechten om de titel te wijzigen van \"{slug}\"", + "error.page.create.permission": "Je hebt geen rechten om \"{slug}\" aan te maken", + "error.page.delete": "De pagina \"{slug}\" kan niet worden verwijderd", + "error.page.delete.confirm": "Voer de paginatitel in om te bevestigen", + "error.page.delete.hasChildren": "Deze pagina heeft subpagina's en kan niet worden verwijderd", + "error.page.delete.permission": "Je hebt geen rechten om \"{slug}\" te verwijderen", + "error.page.draft.duplicate": "Er bestaat al een conceptpagina met de URL-appendix \"{slug}\"", + "error.page.duplicate": "Er bestaat al een pagina met de URL-appendix \"{slug}\"", + "error.page.duplicate.permission": "Je bent niet gemachtigd om \"{slug}\" te dupliceren", + "error.page.notFound": "De pagina \"{slug}\" kan niet worden gevonden", + "error.page.num.invalid": "Vul een geldig sorteer-cijfer in. Het cijfer mag niet negatief zijn", + "error.page.slug.invalid": "Vul een geldig URL-achtervoegsel in", + "error.page.slug.maxlength": "Slug lengte moet minder dan \"{length}\" tekens bevatten", + "error.page.sort.permission": "De pagina \"{slug}\" kan niet worden gesorteerd", + "error.page.status.invalid": "Zorg voor een geldige paginastatus", + "error.page.undefined": "De pagina kan niet worden gevonden", + "error.page.update.permission": "Je hebt geen rechten om \"{slug}\" te updaten", + + "error.section.files.max.plural": "Voeg niet meer dan {max} bestanden toe aan de zone \"{section}\"", + "error.section.files.max.singular": "Je kunt niet meer dan 1 bestand toevoegen aan de zone \"{section}\"", + "error.section.files.min.plural": "De \"{section}\" sectie moet minimaal {min} bestanden bevatten.", + "error.section.files.min.singular": "De \"{section}\" sectie moet minimaal 1 bestand bevatten.", + + "error.section.pages.max.plural": "Je kunt niet meer dan {max} pagina's toevoegen aan de zone \"{section}\"", + "error.section.pages.max.singular": "Je kunt niet meer dan 1 pagina toevoegen aan de zone \"{section}\"", + "error.section.pages.min.plural": "De \"{section}\" sectie moet minimaal {min} pagina's bevatten.", + "error.section.pages.min.singular": "De \"{section}\" sectie moet minimaal 1 pagina bevatten.", + + "error.section.notLoaded": "De zone \"{name}\" kan niet worden geladen", + "error.section.type.invalid": "Zone-type \"{type}\" is niet geldig", + + "error.site.changeTitle.empty": "De titel mag niet leeg zijn", + "error.site.changeTitle.permission": "Je hebt geen rechten om de titel van de site te wijzigen", + "error.site.update.permission": "Je hebt geen rechten om de site te updaten", + + "error.template.default.notFound": "Het standaard template bestaat niet", + + "error.unexpected": "Een onverwacht fout heeft plaats gevonden! Schakel debug-modus in voor meer informatie: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Je hebt geen rechten om het e-mailadres van gebruiker \"{name}\" te wijzigen", + "error.user.changeLanguage.permission": "Je hebt geen rechten om de taal voor gebruiker \"{name}\" te wijzigen", + "error.user.changeName.permission": "Je hebt geen rechten om de naam van gebruiker \"{name}\" te wijzigen", + "error.user.changePassword.permission": "Je hebt geen rechten om het wachtwoord van gebruiker \"{name}\" te wijzigen", + "error.user.changeRole.lastAdmin": "De rol van de laatste beheerder kan niet worden gewijzigd", + "error.user.changeRole.permission": "Je hebt geen rechten om de rol van gebruiker \"{name}\" te wijzigen", + "error.user.changeRole.toAdmin": "Je hebt geen rechten om de rol van iemand te wijzigen naar admin", + "error.user.create.permission": "Je hebt geen rechten om deze gebruiker aan te maken", + "error.user.delete": "De gebruiker \"{name}\" kan niet worden verwijderd", + "error.user.delete.lastAdmin": "Je kan de laatste admin niet verwijderen", + "error.user.delete.lastUser": "De laatste gebruiker kan niet worden verwijderd", + "error.user.delete.permission": "Je hebt geen rechten om gebruiker \"{name}\" te verwijderen", + "error.user.duplicate": "Er bestaat al een gebruiker met e-mailadres \"{email}\"", + "error.user.email.invalid": "Gelieve een geldig emailadres in te voeren", + "error.user.language.invalid": "Gelieve een geldige taal in te voeren", + "error.user.notFound": "De gebruiker \"{name}\" kan niet worden gevonden", + "error.user.password.invalid": "Gelieve een geldig wachtwoord in te voeren. Wachtwoorden moeten minstens 8 karakters lang zijn.", + "error.user.password.notSame": "De wachtwoorden komen niet overeen", + "error.user.password.undefined": "De gebruiker heeft geen wachtwoord", + "error.user.password.wrong": "Fout wachtwoord", + "error.user.role.invalid": "Gelieve een geldige rol in te voeren", + "error.user.undefined": "De gebruiker kan niet worden gevonden", + "error.user.update.permission": "Je hebt geen rechten om gebruiker \"{name}\" te updaten", + + "error.validation.accepted": "Gelieve te bevestigen", + "error.validation.alpha": "Vul alleen a-z karakters in", + "error.validation.alphanum": "Vul alleen a-z karakters of cijfers (0-9) in", + "error.validation.between": "Vul een waarde tussen \"{min}\" en \"{max}\"", + "error.validation.boolean": "Ga akkoord of weiger", + "error.validation.contains": "Vul een waarde in die \"{needle}\" bevat", + "error.validation.date": "Vul een geldige datum in", + "error.validation.date.after": "Vul een datum in na {date}", + "error.validation.date.before": "Vul een datum in voor {date}", + "error.validation.date.between": "Vul een datum in tussen {min} en {max}", + "error.validation.denied": "Weiger", + "error.validation.different": "De invoer mag niet \"{other}\" zijn", + "error.validation.email": "Gelieve een geldig emailadres in te voeren", + "error.validation.endswith": "De invoer moet eindigen met \"{end}\"", + "error.validation.filename": "Vul een geldige bestandsnaam in", + "error.validation.in": "Vul één van de volgende dingen in: ({in})", + "error.validation.integer": "Vul een geldig geheel getal in", + "error.validation.ip": "Vul een geldig IP-adres in", + "error.validation.less": "Vul een waarde in lager dan {max}", + "error.validation.match": "De invoer klopt niet met het verwachte patroon", + "error.validation.max": "Vul een waarde in die gelijk is aan of lager dan {max}", + "error.validation.maxlength": "Gebruik minder karakters (maximaal {max} karakters)", + "error.validation.maxwords": "Vul minder dan {max} woord(en) in", + "error.validation.min": "Vul een waarde in die gelijk is aan of groter dan {min}", + "error.validation.minlength": "Gebruik meer karakters (minimaal {min} karakters)", + "error.validation.minwords": "Vul minimaal {min} woord(en) in", + "error.validation.more": "Vul een grotere waarde in dan {min}", + "error.validation.notcontains": "Zorg dat de invoer niet \"{needle}\" bevat", + "error.validation.notin": "Vul de volgende dingen niet in: ({notIn})", + "error.validation.option": "Selecteer een geldige optie", + "error.validation.num": "Vul een geldig cijfer in", + "error.validation.required": "Vul iets in", + "error.validation.same": "Vul \"{other}\" in", + "error.validation.size": "De lengte van de invoer moet \"{size}\" zijn", + "error.validation.startswith": "De invoer moet beginnen met \"{start}\"", + "error.validation.time": "Vul een geldige tijd in", + "error.validation.time.after": "Voer een tijd in na {time}", + "error.validation.time.before": "Voer een tijd in voor {time}", + "error.validation.time.between": "Voer een tijd in tussen {min} en {max}", + "error.validation.url": "Vul een geldige URL in", + + "expand": "Open", + "expand.all": "Open alles", + + "field.required": "Dit veld is verplicht", + "field.blocks.changeType": "Wijzig type", + "field.blocks.code.name": "Code", + "field.blocks.code.language": "Taal", + "field.blocks.code.placeholder": "Jouw code ...", + "field.blocks.delete.confirm": "Wil je echt dit blok wilt verwijderen?", + "field.blocks.delete.confirm.all": "Wil je echt alle blokken verwijderen?", + "field.blocks.delete.confirm.selected": "Wil je de geselecteerde blokken echt verwijderen?", + "field.blocks.empty": "Nog geen blokken", + "field.blocks.fieldsets.label": "Selecteer een bloktype ...", + "field.blocks.fieldsets.paste": "Druk op {{ shortcut }} om blokken van je klembord te plakken/importeren", + "field.blocks.gallery.name": "Galerij", + "field.blocks.gallery.images.empty": "Nog geen afbeeldingen", + "field.blocks.gallery.images.label": "Afbeeldingen", + "field.blocks.heading.level": "Niveau", + "field.blocks.heading.name": "Koptekst", + "field.blocks.heading.text": "Tekst", + "field.blocks.heading.placeholder": "Koptekst ...", + "field.blocks.image.alt": "Alternatieve tekst", + "field.blocks.image.caption": "Beschrijving", + "field.blocks.image.crop": "Uitsnede", + "field.blocks.image.link": "Link", + "field.blocks.image.location": "Locatie", + "field.blocks.image.name": "Afbeelding", + "field.blocks.image.placeholder": "Selecteer een afbeelding", + "field.blocks.image.ratio": "Verhouding", + "field.blocks.image.url": "Afbeeldings-URL", + "field.blocks.line.name": "Lijn", + "field.blocks.list.name": "Lijst", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Tekst", + "field.blocks.markdown.placeholder": "Markdown ...", + "field.blocks.quote.name": "Citaat", + "field.blocks.quote.text.label": "Tekst", + "field.blocks.quote.text.placeholder": "Citaat ...", + "field.blocks.quote.citation.label": "Bron", + "field.blocks.quote.citation.placeholder": "door ...", + "field.blocks.text.name": "Tekst", + "field.blocks.text.placeholder": "Tekst ...", + "field.blocks.video.caption": "Beschrijving", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Voer een video link in", + "field.blocks.video.url.label": "Video link", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Nog geen bestanden geselecteerd", + + "field.layout.delete": "Verwijder indeling", + "field.layout.delete.confirm": "Weet je zeker dat je deze indeling wilt verwijderen?", + "field.layout.empty": "Er zijn nog geen rijen", + "field.layout.select": "Selecteer een indeling", + + "field.object.empty": "Nog geen informatie", + + "field.pages.empty": "Nog geen pagina's geselecteerd", + + "field.structure.delete.confirm": "Wil je deze entry verwijderen?", + "field.structure.empty": "Nog geen items.", + + "field.users.empty": "Nog geen gebruikers geselecteerd", + + "file.blueprint": "Dit bestand heeft nog geen blauwdruk. U kunt de instellingen definiëren in /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Wil je dit bestand
{filename} verwijderen?", + "file.sort": "Verander positie", + + "files": "Bestanden", + "files.empty": "Nog geen bestanden", + + "hide": "Verberg", + "hour": "Uur", + "import": "Importeer", + "info": "Info", + "insert": "Toevoegen", + "insert.after": "Voeg toe na", + "insert.before": "Voeg toe voor", + "install": "Installeren", + + "installation": "Installatie", + "installation.completed": "Het Panel is geïnstalleerd", + "installation.disabled": "Je kan geen Panel installatie uitvoeren op een openbare server. Voer het installatieprogramma uit op een lokale computer of schakel het in met de panel.install optie.", + "installation.issues.accounts": "De map /site/accounts heeft geen schrijfrechten", + "installation.issues.content": "De map /content bestaat niet of heeft geen schrijfrechten", + "installation.issues.curl": "De CURL-extensie is vereist", + "installation.issues.headline": "Het Panel kan niet worden geïnstalleerd", + "installation.issues.mbstring": "De MB String extensie is verplicht", + "installation.issues.media": "De map /mediabestaat niet of heeft geen schrijfrechten", + "installation.issues.php": "Gebruik PHP7+", + "installation.issues.server": "Kirby vereist Apache, Nginx of Caddy", + "installation.issues.sessions": "De map /site/sessions bestaat niet of heeft geen schrijfrechten", + + "language": "Taal", + "language.code": "Code", + "language.convert": "Maak standaard", + "language.convert.confirm": "

Weet je zeker dat je {name} wilt aanpassen naar de standaard taal? Dit kan niet ongedaan worden gemaakt

Als {name} nog niet vertaalde content heeft, is er geen content meer om op terug te vallen en zouden delen van je site leeg kunnen zijn.

", + "language.create": "Nieuwe taal toevoegen", + "language.delete.confirm": "Weet je zeker dat je de taal {name} inclusief alle vertalingen wilt verwijderen? Je kunt dit niet ongedaan maken!", + "language.deleted": "De taal is verwijderd", + "language.direction": "Leesrichting", + "language.direction.ltr": "Links naar rechts", + "language.direction.rtl": "Rechts naar links", + "language.locale": "PHP-locale regel", + "language.locale.warning": "Je gebruikt een aangepaste landinstelling. Wijzig het het taalbestand in /site/languages", + "language.name": "Naam", + "language.updated": "De taal is geüpdatet", + + "languages": "Talen", + "languages.default": "Standaard taal", + "languages.empty": "Er zijn nog geen talen", + "languages.secondary": "Andere talen", + "languages.secondary.empty": "Er zijn nog geen andere talen beschikbaar", + + "license": "Licentie", + "license.buy": "Koop een licentie", + "license.register": "Registreren", + "license.manage": "Beheer je licenties", + "license.register.help": "Je hebt de licentie via e-mail gekregen nadat je de aankoop hebt gedaan. Kopieer en plak de licentie om te registreren. ", + "license.register.label": "Vul je licentie in", + "license.register.success": "Bedankt dat je Kirby ondersteunt", + "license.unregistered": "Dit is een niet geregistreerde demo van Kirby", + "license.unregistered.label": "Unregistered", + + "link": "Link", + "link.text": "Linktekst", + + "loading": "Laden", + + "lock.unsaved": "Niet opgeslagen wijzigingen", + "lock.unsaved.empty": "Er zijn geen niet opgeslagen wijzigingen meer", + "lock.isLocked": "Niet opgeslagen wijzigingen door {email}", + "lock.file.isLocked": "Dit bestand wordt momenteel bewerkt door {email} en kan niet worden gewijzigd.", + "lock.page.isLocked": "Deze pagina wordt momenteel bewerkt door {email} en kan niet worden gewijzigd.", + "lock.unlock": "Ontgrendelen", + "lock.isUnlocked": "Je niet opgeslagen wijzigingen zijn overschreven door een andere gebruiker. Je kunt je wijzigingen downloaden om ze handmatig samen te voegen.", + + "login": "Inloggen", + "login.code.label.login": "Log in code", + "login.code.label.password-reset": "Wachtwoord herstel code", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "Als uw e-mailadres geregistreerd is, werd de gevraagde code per e-mail verzonden.", + "login.email.login.body": "Hallo {user.nameOrEmail},\n\nJe hebt onlangs een inlogcode aangevraagd voor het Panel van {site}.\nDe volgende inlogcode is {timeout} minuten geldig:\n\n{code}\n\nAls je geen inlogcode hebt aangevraagd, mag je deze mail negeren of neem je contact op met uw beheerder.\nOm veiligheidsredenen verzoeken wij deze e-mail NIET door te sturen.", + "login.email.login.subject": "Jouw log in code", + "login.email.password-reset.body": "Hallo {user.nameOrEmail},\n\nJe hebt onlangs een paswoord herstel code aangevraagd voor het Panel van {site}.\nDe volgende paswoord herstel code is {timeout} minuten geldig:\n\n{code}\n\nAls je geen paswoord herstel code hebt aangevraagd, mag je deze mail negeren of neem je contact op met uw beheerder.\nOm veiligheidsredenen verzoeken wij deze e-mail NIET door te sturen.", + "login.email.password-reset.subject": "Jouw wachtwoord herstel code", + "login.remember": "Houd mij ingelogd", + "login.reset": "Wachtwoord herstellen", + "login.toggleText.code.email": "Log in via email", + "login.toggleText.code.email-password": "Log in met je wachtwoord", + "login.toggleText.password-reset.email": "Wachtwoord vergeten?", + "login.toggleText.password-reset.email-password": "← Terug naar log in", + + "logout": "Uitloggen", + + "menu": "Menu", + "meridiem": "AM/PM", + "mime": "Mime-type", + "minutes": "Minuten", + + "month": "Maand", + "months.april": "april", + "months.august": "augustus", + "months.december": "december", + "months.february": "februari", + "months.january": "januari", + "months.july": "juli", + "months.june": "juni", + "months.march": "maart", + "months.may": "mei", + "months.november": "november", + "months.october": "oktober", + "months.september": "september", + + "more": "Meer", + "name": "Naam", + "next": "Volgende", + "no": "nee", + "off": "uit", + "on": "aan", + "open": "Open", + "open.newWindow": "Openen in een nieuw scherm", + "options": "Opties", + "options.none": "Geen opties beschikbaar", + + "orientation": "Oriëntatie", + "orientation.landscape": "Liggend", + "orientation.portrait": "Staand", + "orientation.square": "Vierkant", + + "page.blueprint": "Deze pagina heeft nog geen blauwdruk. Je kan de instellingen definiëren in /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Verander URL", + "page.changeSlug.fromTitle": "Aanmaken op basis van titel", + "page.changeStatus": "Wijzig status", + "page.changeStatus.position": "Selecteer een positie", + "page.changeStatus.select": "Selecteer een nieuwe status", + "page.changeTemplate": "Verander template", + "page.delete.confirm": "Weet je zeker dat je pagina {title} wilt verwijderen?", + "page.delete.confirm.subpages": "Deze pagina heeft subpagina's.
Alle subpagina's zullen ook worden verwijderd.", + "page.delete.confirm.title": "Voeg een paginatitel in om te bevestigen", + "page.draft.create": "Maak concept", + "page.duplicate.appendix": "Kopiëren", + "page.duplicate.files": "Kopieer bestanden", + "page.duplicate.pages": "Kopieer pagina's", + "page.sort": "Verander positie", + "page.status": "Status", + "page.status.draft": "Concept", + "page.status.draft.description": "De pagina is in concept-modus en alleen zichtbaar voor ingelogde redacteuren of via een geheime link", + "page.status.listed": "Openbaar", + "page.status.listed.description": "Deze pagina is toegankelijk voor iedereen", + "page.status.unlisted": "Niet gepubliceerd", + "page.status.unlisted.description": "Deze pagina is alleen bereikbaar via URL", + + "pages": "Pagina’s", + "pages.empty": "Nog geen pagina's", + "pages.status.draft": "Concepten", + "pages.status.listed": "Gepubliceerd", + "pages.status.unlisted": "Niet gepubliceerd", + + "pagination.page": "Pagina", + + "password": "Wachtwoord", + "paste": "Plak", + "paste.after": "Plak achter", + "pixel": "Pixel", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "Vorige", + "preview": "Voorbeeld", + "remove": "Verwijder", + "rename": "Hernoem", + "replace": "Vervang", + "retry": "Probeer opnieuw", + "revert": "Annuleren", + "revert.confirm": "Weet je zeker dat je alle niet-opgeslagen veranderingen wilt verwijderen?", + + "role": "Rol", + "role.admin.description": "De admin heeft alle rechten", + "role.admin.title": "Admin", + "role.all": "Alle", + "role.empty": "Er zijn geen gebruikers met deze rol", + "role.description.placeholder": "Geen beschrijving", + "role.nobody.description": "Dit is een fallback-rol zonder rechten", + "role.nobody.title": "Niemand", + + "save": "Opslaan", + "search": "Zoeken", + "search.min": "Voer {min} tekens in om te zoeken", + "search.all": "Toon alles", + "search.results.none": "Geen resultaten", + + "section.required": "De sectie is verplicht", + + "security": "Beveiliging", + "select": "Selecteren", + "server": "Server", + "settings": "Opties", + "show": "Toon", + "site.blueprint": "Deze website heeft nog geen ontwerp. Je kan het ontwerp hier plaatsen/site/blueprints/site.yml", + "size": "Grootte", + "slug": "URL-toevoeging", + "sort": "Sorteren", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "De .git map lijkt zichtbaar te zijn", + "system.issues.https": "We raden HTTPS aan voor al je sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "Geen gekende kwetsbaarheden", + "system.updateStatus.security-update": "Gratis veiligheids update { version } beschikbaar", + "system.updateStatus.security-upgrade": "Upgrade { version } met veiligheid aanpassingen beschikbaar", + "system.updateStatus.unreleased": "Niet vrijgegeven versie", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Gratis update { version } beschikbaar", + "system.updateStatus.upgrade": "Upgrade { version } beschikbaar", + + "title": "Titel", + "template": "Template", + "today": "Vandaag", + + "toolbar.button.code": "Code", + "toolbar.button.bold": "Dikgedrukte tekst", + "toolbar.button.email": "E-mailadres", + "toolbar.button.headings": "Kopteksten", + "toolbar.button.heading.1": "Koptekst 1", + "toolbar.button.heading.2": "Koptekst 2", + "toolbar.button.heading.3": "Koptekst 3", + "toolbar.button.heading.4": "Hoofding 4", + "toolbar.button.heading.5": "Hoofding 5", + "toolbar.button.heading.6": "Hoofding 6", + "toolbar.button.italic": "Cursieve tekst", + "toolbar.button.file": "Bestand", + "toolbar.button.file.select": "Selecteer een bestand", + "toolbar.button.file.upload": "Upload bestand", + "toolbar.button.link": "Link", + "toolbar.button.paragraph": "Paragraaf", + "toolbar.button.strike": "Doorstreept", + "toolbar.button.ol": "Genummerde lijst", + "toolbar.button.underline": "Onderlijn", + "toolbar.button.ul": "Opsomming", + + "translation.author": "Het team van Kirby", + "translation.direction": "ltr", + "translation.name": "Nederlands", + "translation.locale": "nl_NL", + + "upload": "Upload", + "upload.error.cantMove": "Het geüploadde bestand kon niet worden verplaatst", + "upload.error.cantWrite": "Fout bij het schrijven van het bestand naar de schijf", + "upload.error.default": "Het bestand kan niet worden geüpload", + "upload.error.extension": "Kan bestand niet uploaden vanwege de extensie", + "upload.error.formSize": "Het geüploadde bestand is groter dan de MAX_FILE_SIZE die is aangegeven in het formulier", + "upload.error.iniPostSize": "Het geüploadde bestand is groter dan de post_max_size in php.ini", + "upload.error.iniSize": "Het geüploadde bestand is groter dan de upload_max_filesize in php.ini", + "upload.error.noFile": "Er is geen bestand geüpload", + "upload.error.noFiles": "Er zijn geen bestanden geüpload", + "upload.error.partial": "Het geüploadde bestand is slechts gedeeltelijk geüpload", + "upload.error.tmpDir": "Er mist een tijdelijke map", + "upload.errors": "Foutmelding", + "upload.progress": "Uploaden...", + + "url": "Url", + "url.placeholder": "https://voorbeeld.nl", + + "user": "Gebruiker", + "user.blueprint": "Je kan aanvullende secties en formuliervelden voor deze gebruikersrol definiëren in /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Email veranderen", + "user.changeLanguage": "Taal veranderen", + "user.changeName": "Gebruiker hernoemen", + "user.changePassword": "Wachtwoord wijzigen", + "user.changePassword.new": "Nieuw wachtwoord", + "user.changePassword.new.confirm": "Bevestig het nieuwe wachtwoord...", + "user.changeRole": "Verander rol", + "user.changeRole.select": "Kies een nieuwe rol", + "user.create": "Voeg een nieuwe gebruiker toe", + "user.delete": "Verwijder deze gebruiker", + "user.delete.confirm": "Weet je zeker dat je
{email} wil verwijderen?", + + "users": "Gebruikers", + + "version": "Kirby-versie", + "version.current": "Huidige versie", + "version.latest": "Laatste versie", + "versionInformation": "Versie informatie", + + "view.account": "Jouw account", + "view.installation": "Installatie", + "view.languages": "Talen", + "view.resetPassword": "Wachtwoord herstellen", + "view.site": "Site", + "view.system": "Systeem", + "view.users": "Gebruikers", + + "welcome": "Welkom", + "year": "Jaar", + "yes": "ja" } diff --git a/kirby/i18n/translations/pl.json b/kirby/i18n/translations/pl.json index befaae9..de41cb3 100644 --- a/kirby/i18n/translations/pl.json +++ b/kirby/i18n/translations/pl.json @@ -1,573 +1,596 @@ { - "account.changeName": "Zmień swoje imię", - "account.delete": "Usuń swoje konto", - "account.delete.confirm": "Czy na pewno chcesz usunąć swoje konto? Zostaniesz natychmiast wylogowany. Twojego konta nie da się odzyskać.", - - "add": "Dodaj", - "author": "Autor", - "avatar": "Zdj\u0119cie profilowe", - "back": "Wróć", - "cancel": "Anuluj", - "change": "Zmie\u0144", - "close": "Zamknij", - "confirm": "Ok", - "collapse": "Zwiń", - "collapse.all": "Zwiń wszystkie", - "copy": "Kopiuj", - "copy.all": "Skopiuj wszystko", - "create": "Utwórz", - - "date": "Data", - "date.select": "Wybierz datę", - - "day": "Dzień", - "days.fri": "Pt", - "days.mon": "Pn", - "days.sat": "Sb", - "days.sun": "Nd", - "days.thu": "Czw", - "days.tue": "Wt", - "days.wed": "\u015ar", - - "debugging": "Debugowanie", - - "delete": "Usu\u0144", - "delete.all": "Usuń wszystkie", - - "dialog.files.empty": "Brak plików do wyboru", - "dialog.pages.empty": "Brak stron do wyboru", - "dialog.users.empty": "Brak użytkowników do wyboru", - - "dimensions": "Wymiary", - "disabled": "Wyłączone", - "discard": "Odrzu\u0107", - "download": "Pobierz", - "duplicate": "Zduplikuj", - - "edit": "Edytuj", - - "email": "Email", - "email.placeholder": "mail@example.com", - - "entries": "Wpisy", - "entry": "Wpis", - - "environment": "Środowisko", - - "error.access.code": "Nieprawidłowy kod", - "error.access.login": "Nieprawidłowy login", - "error.access.panel": "Nie masz uprawnień by dostać się do panelu", - "error.access.view": "Nie masz uprawnień, by dostać się do tej części panelu", - - "error.avatar.create.fail": "Nie udało się załadować zdjęcia profilowego", - "error.avatar.delete.fail": "Nie udało się usunąć zdjęcia profilowego", - "error.avatar.dimensions.invalid": "Proszę zachować szerokość i wysokość zdjęcia profilowego poniżej 3000 pikseli", - "error.avatar.mime.forbidden": "Zdjęcie profilowe musi być plikiem JPEG lub PNG", - - "error.blueprint.notFound": "Nie udało się załadować wzorca \"{name}\"", - - "error.blocks.max.plural": "Możesz dodać nie więcej niż {max} bloki/-ów", - "error.blocks.max.singular": "Możesz dodać tylko jeden blok", - "error.blocks.min.plural": "Musisz dodać co najmniej {min} bloki/-ów", - "error.blocks.min.singular": "Musisz dodać co najmniej jeden blok", - "error.blocks.validation": "W bloku {index} jest błąd", - - "error.email.preset.notFound": "Nie udało się załadować wzorca wiadomości e-mail \"{name}\"", - - "error.field.converter.invalid": "Nieprawidłowy konwerter \"{converter}\"", - - "error.file.changeName.empty": "Imię nie może być puste", - "error.file.changeName.permission": "Nie masz uprawnień, by zmienić nazwę \"{filename}\"", - "error.file.duplicate": "Istnieje już plik o nazwie \"{filename}\"", - "error.file.extension.forbidden": "Rozszerzenie \"{extension}\" jest niedozwolone", - "error.file.extension.invalid": "Nieprawidłowe rozszerzenie: {extension}", - "error.file.extension.missing": "Brak rozszerzenia pliku \"{filename}\"", - "error.file.maxheight": "Wysokość obrazka nie może być większa niż {height} pikseli", - "error.file.maxsize": "Plik jest za duży", - "error.file.maxwidth": "Szerokość obrazka nie może być większa niż {width} pikseli", - "error.file.mime.differs": "Przesłany plik musi być tego samego typu mime \"{mime}\"", - "error.file.mime.forbidden": "Typ multimediów \"{mime}\" jest niedozwolony", - "error.file.mime.invalid": "Nieprawidłowy typ MIME: {mime}", - "error.file.mime.missing": "Nie można wykryć typu multimediów dla \"{filename}\"", - "error.file.minheight": "Wysokość obrazka musi wynosić co najmniej {height} pikseli", - "error.file.minsize": "Plik jest za mały", - "error.file.minwidth": "Szerokość obrazka musi wynosić co najmniej {width} pikseli", - "error.file.name.missing": "Nazwa pliku nie może być pusta", - "error.file.notFound": "Nie można znaleźć pliku \"{filename}\"", - "error.file.orientation": "Orientacja obrazka musi być \"{orientation}\"", - "error.file.type.forbidden": "Nie możesz przesyłać plików {type}", - "error.file.type.invalid": "Nieprawidłowy typ pliku: {type}", - "error.file.undefined": "Nie można znaleźć pliku", - - "error.form.incomplete": "Popraw wszystkie błędy w formularzu…", - "error.form.notSaved": "Nie udało się zapisać formularza", - - "error.language.code": "Wprowadź poprawny kod języka.", - "error.language.duplicate": "Język już istnieje.", - "error.language.name": "Wprowadź poprawną nazwę języka.", - "error.language.notFound": "Język nie został odnaleziony", - - "error.layout.validation.block": "W bloku {blockIndex} w układzie {layoutIndex} jest błąd", - "error.layout.validation.settings": "W ustawieniach układu {index} jest błąd", - - "error.license.format": "Wprowadź poprawny klucz licencyjny", - "error.license.email": "Wprowadź poprawny adres email", - "error.license.verification": "Nie udało się zweryfikować licencji", - - "error.offline": "Panel jest obecnie offline", - - "error.page.changeSlug.permission": "Nie możesz zmienić końcówki adresu URL w \"{slug}\"", - "error.page.changeStatus.incomplete": "Strona zawiera błędy i nie można jej opublikować", - "error.page.changeStatus.permission": "Status tej strony nie może zostać zmieniony", - "error.page.changeStatus.toDraft.invalid": "Strony \"{slug}\" nie można przekonwertować na szkic", - "error.page.changeTemplate.invalid": "Nie można zmienić szablonu strony \"{slug}\"", - "error.page.changeTemplate.permission": "Nie masz uprawnień, by zmienić szablon dla \"{slug}\"", - "error.page.changeTitle.empty": "Tytuł nie może być pusty", - "error.page.changeTitle.permission": "Nie masz uprawnień, by zmienić tytuł dla \"{slug}\"", - "error.page.create.permission": "Nie masz uprawnień, by utworzyć \"{slug}\"", - "error.page.delete": "Strony \"{slug}\" nie można usunąć", - "error.page.delete.confirm": "Wprowadź tytuł strony, aby potwierdzić", - "error.page.delete.hasChildren": "Strona zawiera podstrony i nie można jej usunąć", - "error.page.delete.permission": "Nie masz uprawnień, by usunąć \"{slug}\"", - "error.page.draft.duplicate": "Istnieje już szkic z końcówką URL \"{slug}\"", - "error.page.duplicate": "Istnieje już strona z końcówką URL \"{slug}\"", - "error.page.duplicate.permission": "Nie masz uprawnień, by zduplikować \"{slug}\"", - "error.page.notFound": "Nie można znaleźć strony \"{slug}\"", - "error.page.num.invalid": "Wprowadź poprawny numer sortujący. Liczby nie mogą być ujemne.", - "error.page.slug.invalid": "Wprowadź poprawną końcówkę adresu URL", - "error.page.slug.maxlength": "Końcówka adresu musi być krótsza niż \"{length}\" znaków", - "error.page.sort.permission": "Nie można sortować strony \"{slug}\"", - "error.page.status.invalid": "Ustaw prawidłowy status strony", - "error.page.undefined": "Nie udało się znaleźć strony", - "error.page.update.permission": "Nie masz uprawnień, by zaktualizować \"{slug}\"", - - "error.section.files.max.plural": "Do sekcji \"{section}\" można dodać nie więcej niż {max} plików", - "error.section.files.max.singular": "Do sekcji \"{section}\" można dodać tylko jeden plik", - "error.section.files.min.plural": "W sekcji \"{section}\" musi być co najmniej {min} pliki/-ów", - "error.section.files.min.singular": "W sekcji \"{section}\" musi być co najmniej jeden plik", - - "error.section.pages.max.plural": "Do sekcji \"{section}\" można dodać nie więcej niż {max} stron", - "error.section.pages.max.singular": "Do sekcji \"{section}\" można dodać tylko jedną stronę", - "error.section.pages.min.plural": "W sekcji \"{section}\" musi być co najmniej {min} stron/-y", - "error.section.pages.min.singular": "W sekcji \"{section}\" musi być co najmniej jedna strona", - - "error.section.notLoaded": "Nie udało się załadować sekcji \"{name}\"", - "error.section.type.invalid": "Typ sekcji \"{type}\" jest nieprawidłowy", - - "error.site.changeTitle.empty": "Tytuł nie może być pusty", - "error.site.changeTitle.permission": "Nie masz uprawnień, by zmienić tytuł strony", - "error.site.update.permission": "Nie masz uprawnień, by zaktualizować stronę", - - "error.template.default.notFound": "Domyślny szablon nie istnieje", - - "error.unexpected": "Wystąpił nieoczekiwany błąd! Włącz tryb debugowania, aby uzyskać więcej informacji: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Nie masz uprawnień, by zmienić adres e-mail użytkownika \"{name}\"", - "error.user.changeLanguage.permission": "Nie masz uprawnień, by zmienić język użytkownika \"{name}\"", - "error.user.changeName.permission": "Nie masz uprawnień, by zmienić nazwę użytkownika \"{name}\"", - "error.user.changePassword.permission": "Nie masz uprawnień, by zmienić hasło użytkownika \"{name}\"", - "error.user.changeRole.lastAdmin": "Nie można zmienić roli ostatniego administratora", - "error.user.changeRole.permission": "Nie masz uprawnień, by zmienić rolę użytkownika \"{name}\"", - "error.user.changeRole.toAdmin": "Nie masz uprawnień, by awansować kogoś do roli daministratora", - "error.user.create.permission": "Nie masz uprawnień, by utworzyć tego użytkownika", - "error.user.delete": "Nie można usunąć użytkownika \"{name}\"", - "error.user.delete.lastAdmin": "Nie można usunąć ostatniego administratora", - "error.user.delete.lastUser": "Nie można usunąć ostatniego użytkownika", - "error.user.delete.permission": "Nie masz uprawnień, by usunąć użytkownika \"{name}\"", - "error.user.duplicate": "Istnieje już użytkownik z adresem email \"{email}\"", - "error.user.email.invalid": "Wprowadź poprawny adres email", - "error.user.language.invalid": "Proszę podać poprawny język", - "error.user.notFound": "Nie można znaleźć użytkownika \"{name}\"", - "error.user.password.invalid": "Wprowadź prawidłowe hasło. Hasła muszą mieć co najmniej 8 znaków.", - "error.user.password.notSame": "Hasła nie są takie same", - "error.user.password.undefined": "Użytkownik nie ma hasła", - "error.user.password.wrong": "Nieprawidłowe hasło", - "error.user.role.invalid": "Wprowadź poprawną rolę", - "error.user.undefined": "Nie można znaleźć użytkownika", - "error.user.update.permission": "Nie masz uprawnień, by zaktualizować użytkownika \"{name}\"", - - "error.validation.accepted": "Proszę potwierdzić", - "error.validation.alpha": "Wprowadź tylko znaki między a-z", - "error.validation.alphanum": "Wprowadź tylko znaki między a-z lub cyfry 0-9", - "error.validation.between": "Wprowadź wartość między \"{min}\" i \"{max}\"", - "error.validation.boolean": "Potwierdź lub odmów", - "error.validation.contains": "Wprowadź wartość, która zawiera \"{needle}\"", - "error.validation.date": "Wprowadź poprawną datę", - "error.validation.date.after": "Wprowadź datę późniejszą niż {date}", - "error.validation.date.before": "Wprowadź datę wcześniejszą niż {date}", - "error.validation.date.between": "Wprowadź datę między {min} a {max}", - "error.validation.denied": "Proszę odmówić", - "error.validation.different": "Wartością nie może być \"{other}\"", - "error.validation.email": "Wprowadź poprawny adres email", - "error.validation.endswith": "Wartość musi kończyć się na \"{end}\"", - "error.validation.filename": "Wprowadź poprawną nazwę pliku", - "error.validation.in": "Wprowadź jedno z następujących: ({in})", - "error.validation.integer": "Wprowadź poprawną liczbę całkowitą", - "error.validation.ip": "Wprowadź poprawny adres IP", - "error.validation.less": "Wprowadź wartość mniejszą niż {max}", - "error.validation.match": "Wartość nie jest zgodna z oczekiwanym wzorcem", - "error.validation.max": "Wprowadź wartość równą lub mniejszą niż {max}", - "error.validation.maxlength": "Wprowadź krótszą wartość. (maks. {max} znaków)", - "error.validation.maxwords": "Wprowadź nie więcej niż {max} słowa/słów", - "error.validation.min": "Wprowadź wartość równą lub większą niż {min}", - "error.validation.minlength": "Wprowadź dłuższą wartość. (min. {min} znaków)", - "error.validation.minwords": "Wprowadź co najmniej {min} słowa/słów", - "error.validation.more": "Wprowadź wartość większą niż {min}", - "error.validation.notcontains": "Wprowadź wartość, która nie zawiera \"{needle}\"", - "error.validation.notin": "Nie wprowadzaj żadnego z następujących ({notIn})", - "error.validation.option": "Wybierz poprawną opcję", - "error.validation.num": "Wprowadź poprawny numer", - "error.validation.required": "Wpisz coś", - "error.validation.same": "Wprowadź \"{other}\"", - "error.validation.size": "Rozmiar wartości musi wynosić \"{size}\"", - "error.validation.startswith": "Wartość musi zaczynać się od \"{start}\"", - "error.validation.time": "Wprowadź poprawny czas", - "error.validation.time.after": "Wprowadź czas późniejszy niż {time}", - "error.validation.time.before": "Wprowadź czas wcześniejszy niż {time}", - "error.validation.time.between": "Wprowadź czas między {min} a {max}", - "error.validation.url": "Wprowadź poprawny adres URL", - - "expand": "Rozwiń", - "expand.all": "Rozwiń wszystkie", - - "field.required": "Pole jest wymagane", - "field.blocks.changeType": "Zmień typ", - "field.blocks.code.name": "Kod", - "field.blocks.code.language": "Język", - "field.blocks.code.placeholder": "Twój kod …", - "field.blocks.delete.confirm": "Czy na pewno chcesz usunąć ten blok?", - "field.blocks.delete.confirm.all": "Czy na pewno chcesz usunąć wszystkie bloki?", - "field.blocks.delete.confirm.selected": "Czy na pewno chcesz usunąć wszystkie wybrane bloki?", - "field.blocks.empty": "Nie ma jeszcze żadnych bloków", - "field.blocks.fieldsets.label": "Wybierz typ bloku …", - "field.blocks.fieldsets.paste": "Wciśnij {{ shortcut }} by wkleić/zaimportować bloki ze schowka", - "field.blocks.gallery.name": "Galeria", - "field.blocks.gallery.images.empty": "Nie ma jeszcze żadnych obrazków", - "field.blocks.gallery.images.label": "Obrazki", - "field.blocks.heading.level": "Poziom", - "field.blocks.heading.name": "Nagłówek", - "field.blocks.heading.text": "Tekst", - "field.blocks.heading.placeholder": "Nagłówek …", - "field.blocks.image.alt": "Tekst alternatywny", - "field.blocks.image.caption": "Podpis", - "field.blocks.image.crop": "Przytnij", - "field.blocks.image.link": "Link", - "field.blocks.image.location": "Lokalizacja", - "field.blocks.image.name": "Obrazek", - "field.blocks.image.placeholder": "Wybierz obrazek", - "field.blocks.image.ratio": "Proporcje", - "field.blocks.image.url": "URL obrazka", - "field.blocks.line.name": "Linijka", - "field.blocks.list.name": "Lista", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Tekst", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Cytat", - "field.blocks.quote.text.label": "Tekst", - "field.blocks.quote.text.placeholder": "Cytat …", - "field.blocks.quote.citation.label": "Źródło", - "field.blocks.quote.citation.placeholder": "autorstwa …", - "field.blocks.text.name": "Tekst", - "field.blocks.text.placeholder": "Tekst …", - "field.blocks.video.caption": "Podpis", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Wprowadź URL video", - "field.blocks.video.url.label": "URL video", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Nie wybrano jeszcze żadnych plików", - - "field.layout.delete": "Usuń układ", - "field.layout.delete.confirm": "Czy na pewno chcesz usunąć ten układ?", - "field.layout.empty": "Nie ma jeszcze żadnych rzędów", - "field.layout.select": "Wybierz układ", - - "field.pages.empty": "Nie wybrano jeszcze żadnych stron", - "field.structure.delete.confirm": "Czy na pewno chcesz usunąć ten wiersz?", - "field.structure.empty": "Nie ma jeszcze \u017cadnych wpis\u00f3w.", - "field.users.empty": "Nie wybrano jeszcze żadnych użytkowników", - - "file.blueprint": "Ten plik nie ma jeszcze wzorca. Możesz go zdefiniować w /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Czy na pewno chcesz usunąć
{filename}?", - "file.sort": "Zmień pozycję", - - "files": "Pliki", - "files.empty": "Nie ma jeszcze żadnych plików", - - "hide": "Ukryj", - "hour": "Godzina", - "import": "Importuj", - "info": "Informacje", - "insert": "Wstaw", - "insert.after": "Wstaw po", - "insert.before": "Wstaw przed", - "install": "Zainstaluj", - - "installation": "Instalacja", - "installation.completed": "Panel został zainstalowany", - "installation.disabled": "Instalator panelu jest domyślnie wyłączony na serwerach publicznych. Uruchom instalator na komputerze lokalnym lub włącz go za pomocą opcji panel.install.", - "installation.issues.accounts": "Folder /site/accounts nie istnieje lub nie ma uprawnień do zapisu", - "installation.issues.content": "Folder /content nie istnieje lub nie ma uprawnień do zapisu", - "installation.issues.curl": "Wymagane jest rozszerzenie CURL", - "installation.issues.headline": "Nie można zainstalować panelu", - "installation.issues.mbstring": "Wymagane jest rozszerzenie MB String", - "installation.issues.media": "Folder /media nie istnieje lub nie ma uprawnień do zapisu", - "installation.issues.php": "Upewnij się, że używasz PHP 7+", - "installation.issues.server": "Kirby wymaga Apache, Nginx lub Caddy", - "installation.issues.sessions": "Folder /site/sessions nie istnieje lub nie ma uprawnień do zapisu", - - "language": "J\u0119zyk", - "language.code": "Kod", - "language.convert": "Ustaw jako domyślny", - "language.convert.confirm": "

Czy na pewno chcesz zmienić domyślny język na {name}? Nie można tego cofnąć.

Jeżeli brakuje tłumaczenia jakichś treści na {name}, nie będzie ich czym zastąpić i części witryny mogą być puste.

", - "language.create": "Dodaj nowy język", - "language.delete.confirm": "Czy na pewno chcesz usunąć język {name} i wszystkie tłumaczenia? Tego nie da się cofnąć!", - "language.deleted": "Język został usunięty", - "language.direction": "Kierunek czytania", - "language.direction.ltr": "Od lewej do prawej", - "language.direction.rtl": "Od prawej do lewej", - "language.locale": "PHP locale string", - "language.locale.warning": "Używasz niestandardowej konfiguracji ustawień regionalnych. Zmodyfikuj to w pliku języka w /site/langugaes", - "language.name": "Nazwa", - "language.updated": "Język został zaktualizowany", - - "languages": "Języki", - "languages.default": "Domyślny język", - "languages.empty": "Nie ma jeszcze żadnych języków", - "languages.secondary": "Dodatkowe języki", - "languages.secondary.empty": "Nie ma jeszcze dodatkowych języków", - - "license": "Licencja", - "license.buy": "Kup licencję", - "license.register": "Zarejestruj", - "license.manage": "Zarządzaj swoimi licencjami", - "license.register.help": "Po zakupieniu licencji otrzymałaś/-eś mailem klucz. Skopiuj go i wklej tutaj, aby dokonać rejestracji.", - "license.register.label": "Wprowadź swój kod licencji", - "license.register.success": "Dziękujemy za wspieranie Kirby", - "license.unregistered": "To jest niezarejestrowana wersja demonstracyjna Kirby", - "license.unregistered.label": "Niezarejestrowane", - - "link": "Link", - "link.text": "Tekst linku", - - "loading": "Ładuję", - - "lock.unsaved": "Niezapisane zmiany", - "lock.unsaved.empty": "Nie ma już żadnych niezapisanych zmian", - "lock.isLocked": "Niezapisane zmiany autorstwa {email}", - "lock.file.isLocked": "Plik jest aktualnie edytowany przez {email} i nie może zostać zmieniony.", - "lock.page.isLocked": "Strona jest aktualnie edytowana przez {email} i nie może zostać zmieniona.", - "lock.unlock": "Odblokuj", - "lock.isUnlocked": "Twoje niezapisane zmiany zostały nadpisane przez innego użytkownika. Możesz pobrać swoje zmiany, by scalić je ręcznie.", - - "login": "Zaloguj się", - "login.code.label.login": "Kod logowania się", - "login.code.label.password-reset": "Kod resetowania hasła", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "Jeśli Twój adres email jest zarejestrowany, żądany kod został wysłany na Twoją skrzynkę.", - "login.email.login.body": "Cześć {user.nameOrEmail},\n\nNiedawno poprosiłaś/-eś o kod do zalogowania się do panelu strony {site}.\nPoniższy kod do zalogowania się będzie ważny przez {timeout} minut:\n\n{code}\n\nJeżeli nie zażądałaś/-eś kodu do logowania się, zignoruj tę wiadomość e-mail lub skontaktuj się z administratorem, jeśli masz pytania.\nZe względów bezpieczeństwa NIE przesyłaj dalej tego e-maila.", - "login.email.login.subject": "Twój kod logowania się", - "login.email.password-reset.body": "Cześć {user.nameOrEmail},\n\nNiedawno poprosiłaś/-eś o kod resetowania hasła do panelu strony {site}.\nPoniższy kod resetowania hasła będzie ważny przez {timeout} minut:\n\n{code}\n\nJeżeli nie zażądałaś/-eś kodu resetowania hasła, zignoruj tę wiadomość e-mail lub skontaktuj się z administratorem, jeśli masz pytania. \nZe względów bezpieczeństwa NIE przesyłaj dalej tego e-maila. ", - "login.email.password-reset.subject": "Twój kod resetujący hasło", - "login.remember": "Nie wylogowuj mnie", - "login.reset": "Zresetuj hasło", - "login.toggleText.code.email": "Zaloguj się za pomocą adresu email", - "login.toggleText.code.email-password": "Zaloguj się za pomocą hasła", - "login.toggleText.password-reset.email": "Zapomniałeś/-aś hasła?", - "login.toggleText.password-reset.email-password": "← Powrót do logowania", - - "logout": "Wyloguj", - - "menu": "Menu", - "meridiem": "AM/PM", - "mime": "Typ multimediów", - "minutes": "Minuty", - - "month": "Miesiąc", - "months.april": "Kwiecie\u0144", - "months.august": "Sierpie\u0144", - "months.december": "Grudzie\u0144", - "months.february": "Luty", - "months.january": "Stycze\u0144", - "months.july": "Lipiec", - "months.june": "Czerwiec", - "months.march": "Marzec", - "months.may": "Maj", - "months.november": "Listopad", - "months.october": "Pa\u017adziernik", - "months.september": "Wrzesie\u0144", - - "more": "Więcej", - "name": "Nazwa", - "next": "Następne", - "no": "nie", - "off": "wyłączone", - "on": "włączone", - "open": "Otwórz", - "open.newWindow": "Otwórz w nowym oknie", - "options": "Opcje", - "options.none": "Brak opcji", - - "orientation": "Orientacja", - "orientation.landscape": "Pozioma", - "orientation.portrait": "Pionowa", - "orientation.square": "Kwadrat", - - "page.blueprint": "Ta strona nie ma jeszcze wzorca. Możesz go zdefiniować w /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Zmie\u0144 URL", - "page.changeSlug.fromTitle": "Utw\u00f3rz na podstawie tytu\u0142u", - "page.changeStatus": "Zmień status", - "page.changeStatus.position": "Wybierz pozycję", - "page.changeStatus.select": "Wybierz nowy status", - "page.changeTemplate": "Zmień szablon", - "page.delete.confirm": "Czy na pewno chcesz usunąć {title}?", - "page.delete.confirm.subpages": "Ta strona zawiera podstrony.
Wszystkie podstrony również zostaną usunięte.", - "page.delete.confirm.title": "Wprowadź tytuł strony, aby potwierdzić", - "page.draft.create": "Utwórz szkic", - "page.duplicate.appendix": "Kopiuj", - "page.duplicate.files": "Kopiuj pliki", - "page.duplicate.pages": "Kopiuj strony", - "page.sort": "Zmień pozycję", - "page.status": "Status", - "page.status.draft": "Szkic", - "page.status.draft.description": "Strona jest w trybie roboczym i widoczna tylko dla zalogowanych redaktorów lub pod sekretnym linkiem", - "page.status.listed": "Opublikowana", - "page.status.listed.description": "Strona jest opublikowana i widoczna dla każdego", - "page.status.unlisted": "Nie katalogowana", - "page.status.unlisted.description": "Strona jest dostępna tylko za pośrednictwem adresu URL", - - "pages": "Strony", - "pages.empty": "Nie ma jeszcze żadnych stron", - "pages.status.draft": "Szkice", - "pages.status.listed": "Opublikowane", - "pages.status.unlisted": "Nie katalogowana", - - "pagination.page": "Strona", - - "password": "Has\u0142o", - "paste": "Wklej", - "paste.after": "Wklej po", - "pixel": "Piksel", - "plugins": "Wtyczki", - "prev": "Poprzednie", - "preview": "Podgląd", - "remove": "Usuń", - "rename": "Zmień nazwę", - "replace": "Zamie\u0144", - "retry": "Pon\u00f3w pr\u00f3b\u0119", - "revert": "Odrzu\u0107", - "revert.confirm": "Czy na pewno chcesz usunąć wszystkie niezapisane zmiany?", - - "role": "Rola", - "role.admin.description": "Administrator posiada wszystkie uprawnienia", - "role.admin.title": "Administrator", - "role.all": "Wszystkie", - "role.empty": "Nie ma użytkowników z tą rolą", - "role.description.placeholder": "Brak opisu", - "role.nobody.description": "To jest rola zastępcza bez żadnych uprawnień", - "role.nobody.title": "Nikt", - - "save": "Zapisz", - "search": "Szukaj", - "search.min": "Aby wyszukać, wprowadź co najmniej {min} znaków", - "search.all": "Pokaż wzystkie", - "search.results.none": "Brak wyników", - - "section.required": "Sekcja jest wymagana", - - "security": "Bezpieczeństwo", - "select": "Wybierz", - "server": "Serwer", - "settings": "Ustawienia", - "show": "Pokaż", - "site.blueprint": "Ta strona nie ma jeszcze wzorca. Możesz go zdefiniować w /site/blueprints/site.yml", - "size": "Rozmiar", - "slug": "Końcówka URL", - "sort": "Sortuj", - - "stats.empty": "Brak raportów", - "system.issues.content": "Zdaje się, że folder „content” jest wystawiony na publiczny dostęp", - "system.issues.debug": "Debugowanie musi być wyłączone w środowisku produkcyjnym", - "system.issues.git": "Zdaje się, że folder „.git” jest wystawiony na publiczny dostęp", - "system.issues.https": "Zalecamy HTTPS dla wszystkich Twoich witryn", - "system.issues.kirby": "Zdaje się, że folder „kirby” jest wystawiony na publiczny dostęp", - "system.issues.site": "Zdaje się, że folder „site” jest wystawiony na publiczny dostęp", - - "title": "Tytuł", - "template": "Szablon", - "today": "Dzisiaj", - - "toolbar.button.code": "Kod", - "toolbar.button.bold": "Pogrubienie", - "toolbar.button.email": "Email", - "toolbar.button.headings": "Nagłówki", - "toolbar.button.heading.1": "Nagłówek 1", - "toolbar.button.heading.2": "Nagłówek 2", - "toolbar.button.heading.3": "Nagłówek 3", - "toolbar.button.heading.4": "Nagłówek 4", - "toolbar.button.heading.5": "Nagłówek 5", - "toolbar.button.heading.6": "Nagłówek 6", - "toolbar.button.italic": "Kursywa", - "toolbar.button.file": "Plik", - "toolbar.button.file.select": "Wybierz plik", - "toolbar.button.file.upload": "Prześlij plik", - "toolbar.button.link": "Link", - "toolbar.button.paragraph": "Akapit", - "toolbar.button.strike": "Przekreślenie", - "toolbar.button.ol": "Lista numerowana", - "toolbar.button.underline": "Podkreślenie", - "toolbar.button.ul": "Lista wypunktowana", - - "translation.author": "Zespół Kirby", - "translation.direction": "ltr", - "translation.name": "Polski", - "translation.locale": "pl_PL", - - "upload": "Prześlij", - "upload.error.cantMove": "Przesłany plik nie mógł być przeniesiony", - "upload.error.cantWrite": "Nie udało się zapisać pliku na dysku", - "upload.error.default": "Nie udało się przesłać pliku", - "upload.error.extension": "Przesyłanie pliku zostało zastopowane przez rozszerzenie", - "upload.error.formSize": "Przesłany plik przekracza dyrektywę MAX_FILE_SIZE określoną w formularzu", - "upload.error.iniPostSize": "Przesłany plik przekracza dyrektywę post_max_size określoną w php.ini", - "upload.error.iniSize": "Przesłany plik przekracza dyrektywę upload_max_filesize określoną w php.ini", - "upload.error.noFile": "Nie został przesłany żaden plik", - "upload.error.noFiles": "Nie zostały przesłane żadne pliki", - "upload.error.partial": "Została przesłana tylko część przesyłanego pliku", - "upload.error.tmpDir": "Brak tymczasowego folderu", - "upload.errors": "Błąd", - "upload.progress": "Przesyłanie…", - - "url": "Url", - "url.placeholder": "https://example.com", - - "user": "Użytkownik", - "user.blueprint": "Możesz zdefiniować dodatkowe sekcje i pola dla użytkownika o takiej roli w /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Zmień email", - "user.changeLanguage": "Zmień język", - "user.changeName": "Zmień nazwę tego użytkownika", - "user.changePassword": "Zmień hasło", - "user.changePassword.new": "Nowe hasło", - "user.changePassword.new.confirm": "Potwierdź nowe hasło…", - "user.changeRole": "Zmień rolę", - "user.changeRole.select": "Wybierz nową rolę", - "user.create": "Dodaj nowego użytkownika", - "user.delete": "Usuń tego użytkownika", - "user.delete.confirm": "Czy na pewno chcesz usunąć
{email}?", - - "users": "Użytkownicy", - - "version": "Wersja", - - "view.account": "Twoje konto", - "view.installation": "Instalacja", - "view.languages": "Języki", - "view.resetPassword": "Zresetuj hasło", - "view.site": "Strona", - "view.system": "System", - "view.users": "U\u017cytkownicy", - - "welcome": "Witaj", - "year": "Rok", - "yes": "tak" + "account.changeName": "Zmień swoje imię", + "account.delete": "Usuń swoje konto", + "account.delete.confirm": "Czy na pewno chcesz usunąć swoje konto? Zostaniesz natychmiast wylogowany. Twojego konta nie da się odzyskać.", + + "add": "Dodaj", + "author": "Autor", + "avatar": "Zdj\u0119cie profilowe", + "back": "Wróć", + "cancel": "Anuluj", + "change": "Zmie\u0144", + "close": "Zamknij", + "confirm": "Ok", + "collapse": "Zwiń", + "collapse.all": "Zwiń wszystkie", + "copy": "Kopiuj", + "copy.all": "Skopiuj wszystko", + "create": "Utwórz", + + "date": "Data", + "date.select": "Wybierz datę", + + "day": "Dzień", + "days.fri": "Pt", + "days.mon": "Pn", + "days.sat": "Sb", + "days.sun": "Nd", + "days.thu": "Czw", + "days.tue": "Wt", + "days.wed": "\u015ar", + + "debugging": "Debugowanie", + + "delete": "Usu\u0144", + "delete.all": "Usuń wszystkie", + + "dialog.files.empty": "Brak plików do wyboru", + "dialog.pages.empty": "Brak stron do wyboru", + "dialog.users.empty": "Brak użytkowników do wyboru", + + "dimensions": "Wymiary", + "disabled": "Wyłączone", + "discard": "Odrzu\u0107", + "download": "Pobierz", + "duplicate": "Zduplikuj", + + "edit": "Edytuj", + + "email": "Email", + "email.placeholder": "mail@example.com", + + "entries": "Wpisy", + "entry": "Wpis", + + "environment": "Środowisko", + + "error.access.code": "Nieprawidłowy kod", + "error.access.login": "Nieprawidłowy login", + "error.access.panel": "Nie masz uprawnień by dostać się do panelu", + "error.access.view": "Nie masz uprawnień, by dostać się do tej części panelu", + + "error.avatar.create.fail": "Nie udało się załadować zdjęcia profilowego", + "error.avatar.delete.fail": "Nie udało się usunąć zdjęcia profilowego", + "error.avatar.dimensions.invalid": "Proszę zachować szerokość i wysokość zdjęcia profilowego poniżej 3000 pikseli", + "error.avatar.mime.forbidden": "Zdjęcie profilowe musi być plikiem JPEG lub PNG", + + "error.blueprint.notFound": "Nie udało się załadować wzorca \"{name}\"", + + "error.blocks.max.plural": "Możesz dodać nie więcej niż {max} bloki/-ów", + "error.blocks.max.singular": "Możesz dodać tylko jeden blok", + "error.blocks.min.plural": "Musisz dodać co najmniej {min} bloki/-ów", + "error.blocks.min.singular": "Musisz dodać co najmniej jeden blok", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "Nie udało się załadować wzorca wiadomości e-mail \"{name}\"", + + "error.field.converter.invalid": "Nieprawidłowy konwerter \"{converter}\"", + + "error.file.changeName.empty": "Imię nie może być puste", + "error.file.changeName.permission": "Nie masz uprawnień, by zmienić nazwę \"{filename}\"", + "error.file.duplicate": "Istnieje już plik o nazwie \"{filename}\"", + "error.file.extension.forbidden": "Rozszerzenie \"{extension}\" jest niedozwolone", + "error.file.extension.invalid": "Nieprawidłowe rozszerzenie: {extension}", + "error.file.extension.missing": "Brak rozszerzenia pliku \"{filename}\"", + "error.file.maxheight": "Wysokość obrazka nie może być większa niż {height} pikseli", + "error.file.maxsize": "Plik jest za duży", + "error.file.maxwidth": "Szerokość obrazka nie może być większa niż {width} pikseli", + "error.file.mime.differs": "Przesłany plik musi być tego samego typu mime \"{mime}\"", + "error.file.mime.forbidden": "Typ multimediów \"{mime}\" jest niedozwolony", + "error.file.mime.invalid": "Nieprawidłowy typ MIME: {mime}", + "error.file.mime.missing": "Nie można wykryć typu multimediów dla \"{filename}\"", + "error.file.minheight": "Wysokość obrazka musi wynosić co najmniej {height} pikseli", + "error.file.minsize": "Plik jest za mały", + "error.file.minwidth": "Szerokość obrazka musi wynosić co najmniej {width} pikseli", + "error.file.name.missing": "Nazwa pliku nie może być pusta", + "error.file.notFound": "Nie można znaleźć pliku \"{filename}\"", + "error.file.orientation": "Orientacja obrazka musi być \"{orientation}\"", + "error.file.type.forbidden": "Nie możesz przesyłać plików {type}", + "error.file.type.invalid": "Nieprawidłowy typ pliku: {type}", + "error.file.undefined": "Nie można znaleźć pliku", + + "error.form.incomplete": "Popraw wszystkie błędy w formularzu…", + "error.form.notSaved": "Nie udało się zapisać formularza", + + "error.language.code": "Wprowadź poprawny kod języka.", + "error.language.duplicate": "Język już istnieje.", + "error.language.name": "Wprowadź poprawną nazwę języka.", + "error.language.notFound": "Język nie został odnaleziony", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "W ustawieniach układu {index} jest błąd", + + "error.license.format": "Wprowadź poprawny klucz licencyjny", + "error.license.email": "Wprowadź poprawny adres email", + "error.license.verification": "Nie udało się zweryfikować licencji", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "Panel jest obecnie offline", + + "error.page.changeSlug.permission": "Nie możesz zmienić końcówki adresu URL w \"{slug}\"", + "error.page.changeStatus.incomplete": "Strona zawiera błędy i nie można jej opublikować", + "error.page.changeStatus.permission": "Status tej strony nie może zostać zmieniony", + "error.page.changeStatus.toDraft.invalid": "Strony \"{slug}\" nie można przekonwertować na szkic", + "error.page.changeTemplate.invalid": "Nie można zmienić szablonu strony \"{slug}\"", + "error.page.changeTemplate.permission": "Nie masz uprawnień, by zmienić szablon dla \"{slug}\"", + "error.page.changeTitle.empty": "Tytuł nie może być pusty", + "error.page.changeTitle.permission": "Nie masz uprawnień, by zmienić tytuł dla \"{slug}\"", + "error.page.create.permission": "Nie masz uprawnień, by utworzyć \"{slug}\"", + "error.page.delete": "Strony \"{slug}\" nie można usunąć", + "error.page.delete.confirm": "Wprowadź tytuł strony, aby potwierdzić", + "error.page.delete.hasChildren": "Strona zawiera podstrony i nie można jej usunąć", + "error.page.delete.permission": "Nie masz uprawnień, by usunąć \"{slug}\"", + "error.page.draft.duplicate": "Istnieje już szkic z końcówką URL \"{slug}\"", + "error.page.duplicate": "Istnieje już strona z końcówką URL \"{slug}\"", + "error.page.duplicate.permission": "Nie masz uprawnień, by zduplikować \"{slug}\"", + "error.page.notFound": "Nie można znaleźć strony \"{slug}\"", + "error.page.num.invalid": "Wprowadź poprawny numer sortujący. Liczby nie mogą być ujemne.", + "error.page.slug.invalid": "Wprowadź poprawną końcówkę adresu URL", + "error.page.slug.maxlength": "Końcówka adresu musi być krótsza niż \"{length}\" znaków", + "error.page.sort.permission": "Nie można sortować strony \"{slug}\"", + "error.page.status.invalid": "Ustaw prawidłowy status strony", + "error.page.undefined": "Nie udało się znaleźć strony", + "error.page.update.permission": "Nie masz uprawnień, by zaktualizować \"{slug}\"", + + "error.section.files.max.plural": "Do sekcji \"{section}\" można dodać nie więcej niż {max} plików", + "error.section.files.max.singular": "Do sekcji \"{section}\" można dodać tylko jeden plik", + "error.section.files.min.plural": "W sekcji \"{section}\" musi być co najmniej {min} pliki/-ów", + "error.section.files.min.singular": "W sekcji \"{section}\" musi być co najmniej jeden plik", + + "error.section.pages.max.plural": "Do sekcji \"{section}\" można dodać nie więcej niż {max} stron", + "error.section.pages.max.singular": "Do sekcji \"{section}\" można dodać tylko jedną stronę", + "error.section.pages.min.plural": "W sekcji \"{section}\" musi być co najmniej {min} stron/-y", + "error.section.pages.min.singular": "W sekcji \"{section}\" musi być co najmniej jedna strona", + + "error.section.notLoaded": "Nie udało się załadować sekcji \"{name}\"", + "error.section.type.invalid": "Typ sekcji \"{type}\" jest nieprawidłowy", + + "error.site.changeTitle.empty": "Tytuł nie może być pusty", + "error.site.changeTitle.permission": "Nie masz uprawnień, by zmienić tytuł strony", + "error.site.update.permission": "Nie masz uprawnień, by zaktualizować stronę", + + "error.template.default.notFound": "Domyślny szablon nie istnieje", + + "error.unexpected": "Wystąpił nieoczekiwany błąd! Włącz tryb debugowania, aby uzyskać więcej informacji: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Nie masz uprawnień, by zmienić adres e-mail użytkownika \"{name}\"", + "error.user.changeLanguage.permission": "Nie masz uprawnień, by zmienić język użytkownika \"{name}\"", + "error.user.changeName.permission": "Nie masz uprawnień, by zmienić nazwę użytkownika \"{name}\"", + "error.user.changePassword.permission": "Nie masz uprawnień, by zmienić hasło użytkownika \"{name}\"", + "error.user.changeRole.lastAdmin": "Nie można zmienić roli ostatniego administratora", + "error.user.changeRole.permission": "Nie masz uprawnień, by zmienić rolę użytkownika \"{name}\"", + "error.user.changeRole.toAdmin": "Nie masz uprawnień, by awansować kogoś do roli daministratora", + "error.user.create.permission": "Nie masz uprawnień, by utworzyć tego użytkownika", + "error.user.delete": "Nie można usunąć użytkownika \"{name}\"", + "error.user.delete.lastAdmin": "Nie można usunąć ostatniego administratora", + "error.user.delete.lastUser": "Nie można usunąć ostatniego użytkownika", + "error.user.delete.permission": "Nie masz uprawnień, by usunąć użytkownika \"{name}\"", + "error.user.duplicate": "Istnieje już użytkownik z adresem email \"{email}\"", + "error.user.email.invalid": "Wprowadź poprawny adres email", + "error.user.language.invalid": "Proszę podać poprawny język", + "error.user.notFound": "Nie można znaleźć użytkownika \"{name}\"", + "error.user.password.invalid": "Wprowadź prawidłowe hasło. Hasła muszą mieć co najmniej 8 znaków.", + "error.user.password.notSame": "Hasła nie są takie same", + "error.user.password.undefined": "Użytkownik nie ma hasła", + "error.user.password.wrong": "Nieprawidłowe hasło", + "error.user.role.invalid": "Wprowadź poprawną rolę", + "error.user.undefined": "Nie można znaleźć użytkownika", + "error.user.update.permission": "Nie masz uprawnień, by zaktualizować użytkownika \"{name}\"", + + "error.validation.accepted": "Proszę potwierdzić", + "error.validation.alpha": "Wprowadź tylko znaki między a-z", + "error.validation.alphanum": "Wprowadź tylko znaki między a-z lub cyfry 0-9", + "error.validation.between": "Wprowadź wartość między \"{min}\" i \"{max}\"", + "error.validation.boolean": "Potwierdź lub odmów", + "error.validation.contains": "Wprowadź wartość, która zawiera \"{needle}\"", + "error.validation.date": "Wprowadź poprawną datę", + "error.validation.date.after": "Wprowadź datę późniejszą niż {date}", + "error.validation.date.before": "Wprowadź datę wcześniejszą niż {date}", + "error.validation.date.between": "Wprowadź datę między {min} a {max}", + "error.validation.denied": "Proszę odmówić", + "error.validation.different": "Wartością nie może być \"{other}\"", + "error.validation.email": "Wprowadź poprawny adres email", + "error.validation.endswith": "Wartość musi kończyć się na \"{end}\"", + "error.validation.filename": "Wprowadź poprawną nazwę pliku", + "error.validation.in": "Wprowadź jedno z następujących: ({in})", + "error.validation.integer": "Wprowadź poprawną liczbę całkowitą", + "error.validation.ip": "Wprowadź poprawny adres IP", + "error.validation.less": "Wprowadź wartość mniejszą niż {max}", + "error.validation.match": "Wartość nie jest zgodna z oczekiwanym wzorcem", + "error.validation.max": "Wprowadź wartość równą lub mniejszą niż {max}", + "error.validation.maxlength": "Wprowadź krótszą wartość. (maks. {max} znaków)", + "error.validation.maxwords": "Wprowadź nie więcej niż {max} słowa/słów", + "error.validation.min": "Wprowadź wartość równą lub większą niż {min}", + "error.validation.minlength": "Wprowadź dłuższą wartość. (min. {min} znaków)", + "error.validation.minwords": "Wprowadź co najmniej {min} słowa/słów", + "error.validation.more": "Wprowadź wartość większą niż {min}", + "error.validation.notcontains": "Wprowadź wartość, która nie zawiera \"{needle}\"", + "error.validation.notin": "Nie wprowadzaj żadnego z następujących ({notIn})", + "error.validation.option": "Wybierz poprawną opcję", + "error.validation.num": "Wprowadź poprawny numer", + "error.validation.required": "Wpisz coś", + "error.validation.same": "Wprowadź \"{other}\"", + "error.validation.size": "Rozmiar wartości musi wynosić \"{size}\"", + "error.validation.startswith": "Wartość musi zaczynać się od \"{start}\"", + "error.validation.time": "Wprowadź poprawny czas", + "error.validation.time.after": "Wprowadź czas późniejszy niż {time}", + "error.validation.time.before": "Wprowadź czas wcześniejszy niż {time}", + "error.validation.time.between": "Wprowadź czas między {min} a {max}", + "error.validation.url": "Wprowadź poprawny adres URL", + + "expand": "Rozwiń", + "expand.all": "Rozwiń wszystkie", + + "field.required": "Pole jest wymagane", + "field.blocks.changeType": "Zmień typ", + "field.blocks.code.name": "Kod", + "field.blocks.code.language": "Język", + "field.blocks.code.placeholder": "Twój kod …", + "field.blocks.delete.confirm": "Czy na pewno chcesz usunąć ten blok?", + "field.blocks.delete.confirm.all": "Czy na pewno chcesz usunąć wszystkie bloki?", + "field.blocks.delete.confirm.selected": "Czy na pewno chcesz usunąć wszystkie wybrane bloki?", + "field.blocks.empty": "Nie ma jeszcze żadnych bloków", + "field.blocks.fieldsets.label": "Wybierz typ bloku …", + "field.blocks.fieldsets.paste": "Wciśnij {{ shortcut }} by wkleić/zaimportować bloki ze schowka", + "field.blocks.gallery.name": "Galeria", + "field.blocks.gallery.images.empty": "Nie ma jeszcze żadnych obrazków", + "field.blocks.gallery.images.label": "Obrazki", + "field.blocks.heading.level": "Poziom", + "field.blocks.heading.name": "Nagłówek", + "field.blocks.heading.text": "Tekst", + "field.blocks.heading.placeholder": "Nagłówek …", + "field.blocks.image.alt": "Tekst alternatywny", + "field.blocks.image.caption": "Podpis", + "field.blocks.image.crop": "Przytnij", + "field.blocks.image.link": "Link", + "field.blocks.image.location": "Lokalizacja", + "field.blocks.image.name": "Obrazek", + "field.blocks.image.placeholder": "Wybierz obrazek", + "field.blocks.image.ratio": "Proporcje", + "field.blocks.image.url": "URL obrazka", + "field.blocks.line.name": "Linijka", + "field.blocks.list.name": "Lista", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Tekst", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Cytat", + "field.blocks.quote.text.label": "Tekst", + "field.blocks.quote.text.placeholder": "Cytat …", + "field.blocks.quote.citation.label": "Źródło", + "field.blocks.quote.citation.placeholder": "autorstwa …", + "field.blocks.text.name": "Tekst", + "field.blocks.text.placeholder": "Tekst …", + "field.blocks.video.caption": "Podpis", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Wprowadź URL video", + "field.blocks.video.url.label": "URL video", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Nie wybrano jeszcze żadnych plików", + + "field.layout.delete": "Usuń układ", + "field.layout.delete.confirm": "Czy na pewno chcesz usunąć ten układ?", + "field.layout.empty": "Nie ma jeszcze żadnych rzędów", + "field.layout.select": "Wybierz układ", + + "field.object.empty": "No information yet", + + "field.pages.empty": "Nie wybrano jeszcze żadnych stron", + + "field.structure.delete.confirm": "Czy na pewno chcesz usunąć ten wiersz?", + "field.structure.empty": "Nie ma jeszcze \u017cadnych wpis\u00f3w.", + + "field.users.empty": "Nie wybrano jeszcze żadnych użytkowników", + + "file.blueprint": "Ten plik nie ma jeszcze wzorca. Możesz go zdefiniować w /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Czy na pewno chcesz usunąć
{filename}?", + "file.sort": "Zmień pozycję", + + "files": "Pliki", + "files.empty": "Nie ma jeszcze żadnych plików", + + "hide": "Ukryj", + "hour": "Godzina", + "import": "Importuj", + "info": "Informacje", + "insert": "Wstaw", + "insert.after": "Wstaw po", + "insert.before": "Wstaw przed", + "install": "Zainstaluj", + + "installation": "Instalacja", + "installation.completed": "Panel został zainstalowany", + "installation.disabled": "Instalator panelu jest domyślnie wyłączony na serwerach publicznych. Uruchom instalator na komputerze lokalnym lub włącz go za pomocą opcji panel.install.", + "installation.issues.accounts": "Folder /site/accounts nie istnieje lub nie ma uprawnień do zapisu", + "installation.issues.content": "Folder /content nie istnieje lub nie ma uprawnień do zapisu", + "installation.issues.curl": "Wymagane jest rozszerzenie CURL", + "installation.issues.headline": "Nie można zainstalować panelu", + "installation.issues.mbstring": "Wymagane jest rozszerzenie MB String", + "installation.issues.media": "Folder /media nie istnieje lub nie ma uprawnień do zapisu", + "installation.issues.php": "Upewnij się, że używasz PHP 7+", + "installation.issues.server": "Kirby wymaga Apache, Nginx lub Caddy", + "installation.issues.sessions": "Folder /site/sessions nie istnieje lub nie ma uprawnień do zapisu", + + "language": "J\u0119zyk", + "language.code": "Kod", + "language.convert": "Ustaw jako domyślny", + "language.convert.confirm": "

Czy na pewno chcesz zmienić domyślny język na {name}? Nie można tego cofnąć.

Jeżeli brakuje tłumaczenia jakichś treści na {name}, nie będzie ich czym zastąpić i części witryny mogą być puste.

", + "language.create": "Dodaj nowy język", + "language.delete.confirm": "Czy na pewno chcesz usunąć język {name} i wszystkie tłumaczenia? Tego nie da się cofnąć!", + "language.deleted": "Język został usunięty", + "language.direction": "Kierunek czytania", + "language.direction.ltr": "Od lewej do prawej", + "language.direction.rtl": "Od prawej do lewej", + "language.locale": "PHP locale string", + "language.locale.warning": "Używasz niestandardowej konfiguracji ustawień regionalnych. Zmodyfikuj to w pliku języka w /site/langugaes", + "language.name": "Nazwa", + "language.updated": "Język został zaktualizowany", + + "languages": "Języki", + "languages.default": "Domyślny język", + "languages.empty": "Nie ma jeszcze żadnych języków", + "languages.secondary": "Dodatkowe języki", + "languages.secondary.empty": "Nie ma jeszcze dodatkowych języków", + + "license": "Licencja", + "license.buy": "Kup licencję", + "license.register": "Zarejestruj", + "license.manage": "Zarządzaj swoimi licencjami", + "license.register.help": "Po zakupieniu licencji otrzymałaś/-eś mailem klucz. Skopiuj go i wklej tutaj, aby dokonać rejestracji.", + "license.register.label": "Wprowadź swój kod licencji", + "license.register.success": "Dziękujemy za wspieranie Kirby", + "license.unregistered": "To jest niezarejestrowana wersja demonstracyjna Kirby", + "license.unregistered.label": "Niezarejestrowane", + + "link": "Link", + "link.text": "Tekst linku", + + "loading": "Ładuję", + + "lock.unsaved": "Niezapisane zmiany", + "lock.unsaved.empty": "Nie ma już żadnych niezapisanych zmian", + "lock.isLocked": "Niezapisane zmiany autorstwa {email}", + "lock.file.isLocked": "Plik jest aktualnie edytowany przez {email} i nie może zostać zmieniony.", + "lock.page.isLocked": "Strona jest aktualnie edytowana przez {email} i nie może zostać zmieniona.", + "lock.unlock": "Odblokuj", + "lock.isUnlocked": "Twoje niezapisane zmiany zostały nadpisane przez innego użytkownika. Możesz pobrać swoje zmiany, by scalić je ręcznie.", + + "login": "Zaloguj się", + "login.code.label.login": "Kod logowania się", + "login.code.label.password-reset": "Kod resetowania hasła", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "Jeśli Twój adres email jest zarejestrowany, żądany kod został wysłany na Twoją skrzynkę.", + "login.email.login.body": "Cześć {user.nameOrEmail},\n\nNiedawno poprosiłaś/-eś o kod do zalogowania się do panelu strony {site}.\nPoniższy kod do zalogowania się będzie ważny przez {timeout} minut:\n\n{code}\n\nJeżeli nie zażądałaś/-eś kodu do logowania się, zignoruj tę wiadomość e-mail lub skontaktuj się z administratorem, jeśli masz pytania.\nZe względów bezpieczeństwa NIE przesyłaj dalej tego e-maila.", + "login.email.login.subject": "Twój kod logowania się", + "login.email.password-reset.body": "Cześć {user.nameOrEmail},\n\nNiedawno poprosiłaś/-eś o kod resetowania hasła do panelu strony {site}.\nPoniższy kod resetowania hasła będzie ważny przez {timeout} minut:\n\n{code}\n\nJeżeli nie zażądałaś/-eś kodu resetowania hasła, zignoruj tę wiadomość e-mail lub skontaktuj się z administratorem, jeśli masz pytania. \nZe względów bezpieczeństwa NIE przesyłaj dalej tego e-maila. ", + "login.email.password-reset.subject": "Twój kod resetujący hasło", + "login.remember": "Nie wylogowuj mnie", + "login.reset": "Zresetuj hasło", + "login.toggleText.code.email": "Zaloguj się za pomocą adresu email", + "login.toggleText.code.email-password": "Zaloguj się za pomocą hasła", + "login.toggleText.password-reset.email": "Zapomniałeś/-aś hasła?", + "login.toggleText.password-reset.email-password": "← Powrót do logowania", + + "logout": "Wyloguj", + + "menu": "Menu", + "meridiem": "AM/PM", + "mime": "Typ multimediów", + "minutes": "Minuty", + + "month": "Miesiąc", + "months.april": "Kwiecie\u0144", + "months.august": "Sierpie\u0144", + "months.december": "Grudzie\u0144", + "months.february": "Luty", + "months.january": "Stycze\u0144", + "months.july": "Lipiec", + "months.june": "Czerwiec", + "months.march": "Marzec", + "months.may": "Maj", + "months.november": "Listopad", + "months.october": "Pa\u017adziernik", + "months.september": "Wrzesie\u0144", + + "more": "Więcej", + "name": "Nazwa", + "next": "Następne", + "no": "nie", + "off": "wyłączone", + "on": "włączone", + "open": "Otwórz", + "open.newWindow": "Otwórz w nowym oknie", + "options": "Opcje", + "options.none": "Brak opcji", + + "orientation": "Orientacja", + "orientation.landscape": "Pozioma", + "orientation.portrait": "Pionowa", + "orientation.square": "Kwadrat", + + "page.blueprint": "Ta strona nie ma jeszcze wzorca. Możesz go zdefiniować w /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Zmie\u0144 URL", + "page.changeSlug.fromTitle": "Utw\u00f3rz na podstawie tytu\u0142u", + "page.changeStatus": "Zmień status", + "page.changeStatus.position": "Wybierz pozycję", + "page.changeStatus.select": "Wybierz nowy status", + "page.changeTemplate": "Zmień szablon", + "page.delete.confirm": "Czy na pewno chcesz usunąć {title}?", + "page.delete.confirm.subpages": "Ta strona zawiera podstrony.
Wszystkie podstrony również zostaną usunięte.", + "page.delete.confirm.title": "Wprowadź tytuł strony, aby potwierdzić", + "page.draft.create": "Utwórz szkic", + "page.duplicate.appendix": "Kopiuj", + "page.duplicate.files": "Kopiuj pliki", + "page.duplicate.pages": "Kopiuj strony", + "page.sort": "Zmień pozycję", + "page.status": "Status", + "page.status.draft": "Szkic", + "page.status.draft.description": "Strona jest w trybie roboczym i widoczna tylko dla zalogowanych redaktorów lub pod sekretnym linkiem", + "page.status.listed": "Opublikowana", + "page.status.listed.description": "Strona jest opublikowana i widoczna dla każdego", + "page.status.unlisted": "Nie katalogowana", + "page.status.unlisted.description": "Strona jest dostępna tylko za pośrednictwem adresu URL", + + "pages": "Strony", + "pages.empty": "Nie ma jeszcze żadnych stron", + "pages.status.draft": "Szkice", + "pages.status.listed": "Opublikowane", + "pages.status.unlisted": "Nie katalogowana", + + "pagination.page": "Strona", + + "password": "Has\u0142o", + "paste": "Wklej", + "paste.after": "Wklej po", + "pixel": "Piksel", + "plugin": "Plugin", + "plugins": "Wtyczki", + "prev": "Poprzednie", + "preview": "Podgląd", + "remove": "Usuń", + "rename": "Zmień nazwę", + "replace": "Zamie\u0144", + "retry": "Pon\u00f3w pr\u00f3b\u0119", + "revert": "Odrzu\u0107", + "revert.confirm": "Czy na pewno chcesz usunąć wszystkie niezapisane zmiany?", + + "role": "Rola", + "role.admin.description": "Administrator posiada wszystkie uprawnienia", + "role.admin.title": "Administrator", + "role.all": "Wszystkie", + "role.empty": "Nie ma użytkowników z tą rolą", + "role.description.placeholder": "Brak opisu", + "role.nobody.description": "To jest rola zastępcza bez żadnych uprawnień", + "role.nobody.title": "Nikt", + + "save": "Zapisz", + "search": "Szukaj", + "search.min": "Aby wyszukać, wprowadź co najmniej {min} znaków", + "search.all": "Pokaż wzystkie", + "search.results.none": "Brak wyników", + + "section.required": "Sekcja jest wymagana", + + "security": "Bezpieczeństwo", + "select": "Wybierz", + "server": "Serwer", + "settings": "Ustawienia", + "show": "Pokaż", + "site.blueprint": "Ta strona nie ma jeszcze wzorca. Możesz go zdefiniować w /site/blueprints/site.yml", + "size": "Rozmiar", + "slug": "Końcówka URL", + "sort": "Sortuj", + + "stats.empty": "Brak raportów", + "system.issues.content": "Zdaje się, że folder „content” jest wystawiony na publiczny dostęp", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugowanie musi być wyłączone w środowisku produkcyjnym", + "system.issues.git": "Zdaje się, że folder „.git” jest wystawiony na publiczny dostęp", + "system.issues.https": "Zalecamy HTTPS dla wszystkich Twoich witryn", + "system.issues.kirby": "Zdaje się, że folder „kirby” jest wystawiony na publiczny dostęp", + "system.issues.site": "Zdaje się, że folder „site” jest wystawiony na publiczny dostęp", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Tytuł", + "template": "Szablon", + "today": "Dzisiaj", + + "toolbar.button.code": "Kod", + "toolbar.button.bold": "Pogrubienie", + "toolbar.button.email": "Email", + "toolbar.button.headings": "Nagłówki", + "toolbar.button.heading.1": "Nagłówek 1", + "toolbar.button.heading.2": "Nagłówek 2", + "toolbar.button.heading.3": "Nagłówek 3", + "toolbar.button.heading.4": "Nagłówek 4", + "toolbar.button.heading.5": "Nagłówek 5", + "toolbar.button.heading.6": "Nagłówek 6", + "toolbar.button.italic": "Kursywa", + "toolbar.button.file": "Plik", + "toolbar.button.file.select": "Wybierz plik", + "toolbar.button.file.upload": "Prześlij plik", + "toolbar.button.link": "Link", + "toolbar.button.paragraph": "Akapit", + "toolbar.button.strike": "Przekreślenie", + "toolbar.button.ol": "Lista numerowana", + "toolbar.button.underline": "Podkreślenie", + "toolbar.button.ul": "Lista wypunktowana", + + "translation.author": "Zespół Kirby", + "translation.direction": "ltr", + "translation.name": "Polski", + "translation.locale": "pl_PL", + + "upload": "Prześlij", + "upload.error.cantMove": "Przesłany plik nie mógł być przeniesiony", + "upload.error.cantWrite": "Nie udało się zapisać pliku na dysku", + "upload.error.default": "Nie udało się przesłać pliku", + "upload.error.extension": "Przesyłanie pliku zostało zastopowane przez rozszerzenie", + "upload.error.formSize": "Przesłany plik przekracza dyrektywę MAX_FILE_SIZE określoną w formularzu", + "upload.error.iniPostSize": "Przesłany plik przekracza dyrektywę post_max_size określoną w php.ini", + "upload.error.iniSize": "Przesłany plik przekracza dyrektywę upload_max_filesize określoną w php.ini", + "upload.error.noFile": "Nie został przesłany żaden plik", + "upload.error.noFiles": "Nie zostały przesłane żadne pliki", + "upload.error.partial": "Została przesłana tylko część przesyłanego pliku", + "upload.error.tmpDir": "Brak tymczasowego folderu", + "upload.errors": "Błąd", + "upload.progress": "Przesyłanie…", + + "url": "Url", + "url.placeholder": "https://example.com", + + "user": "Użytkownik", + "user.blueprint": "Możesz zdefiniować dodatkowe sekcje i pola dla użytkownika o takiej roli w /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Zmień email", + "user.changeLanguage": "Zmień język", + "user.changeName": "Zmień nazwę tego użytkownika", + "user.changePassword": "Zmień hasło", + "user.changePassword.new": "Nowe hasło", + "user.changePassword.new.confirm": "Potwierdź nowe hasło…", + "user.changeRole": "Zmień rolę", + "user.changeRole.select": "Wybierz nową rolę", + "user.create": "Dodaj nowego użytkownika", + "user.delete": "Usuń tego użytkownika", + "user.delete.confirm": "Czy na pewno chcesz usunąć
{email}?", + + "users": "Użytkownicy", + + "version": "Wersja", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "Twoje konto", + "view.installation": "Instalacja", + "view.languages": "Języki", + "view.resetPassword": "Zresetuj hasło", + "view.site": "Strona", + "view.system": "System", + "view.users": "U\u017cytkownicy", + + "welcome": "Witaj", + "year": "Rok", + "yes": "tak" } diff --git a/kirby/i18n/translations/pt_BR.json b/kirby/i18n/translations/pt_BR.json index 6181eca..4b42cdd 100644 --- a/kirby/i18n/translations/pt_BR.json +++ b/kirby/i18n/translations/pt_BR.json @@ -1,573 +1,596 @@ { - "account.changeName": "Mudar seu nome", - "account.delete": "Deletar sua conta", - "account.delete.confirm": "Deseja realmente deletar sua conta? Você sairá do site imediatamente. Sua conta não poderá ser recuperada. ", - - "add": "Adicionar", - "author": "Autor", - "avatar": "Foto do perfil", - "back": "Voltar", - "cancel": "Cancelar", - "change": "Alterar", - "close": "Fechar", - "confirm": "Salvar", - "collapse": "Colapsar", - "collapse.all": "Colapsar todos", - "copy": "Copiar", - "copy.all": "Copiar todos", - "create": "Criar", - - "date": "Data", - "date.select": "Selecione uma data", - - "day": "Dia", - "days.fri": "Sex", - "days.mon": "Seg", - "days.sat": "S\u00e1b", - "days.sun": "Dom", - "days.thu": "Qui", - "days.tue": "Ter", - "days.wed": "Qua", - - "debugging": "Depuração ", - - "delete": "Deletar", - "delete.all": "Deletar todos", - - "dialog.files.empty": "Nenhum arquivo para selecionar", - "dialog.pages.empty": "Nenhuma página para selecionar", - "dialog.users.empty": "Nenhum usuário para selecionar", - - "dimensions": "Dimensões", - "disabled": "Desativado", - "discard": "Descartar", - "download": "Baixar", - "duplicate": "Duplicar", - - "edit": "Editar", - - "email": "Email", - "email.placeholder": "mail@exemplo.com", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Ambiente", - - "error.access.code": "Código inválido", - "error.access.login": "Código de acesso inválido", - "error.access.panel": "Você não tem permissão para acessar o painel", - "error.access.view": "Você não tem permissão para acessar esta parte do painel", - - "error.avatar.create.fail": "A foto de perfil não pôde ser enviada", - "error.avatar.delete.fail": "A foto de perfil não pôde ser deletada", - "error.avatar.dimensions.invalid": "Por favor, use uma foto de perfil com largura e altura menores que 3000 pixels", - "error.avatar.mime.forbidden": "A foto de perfil deve ser um arquivo JPEG ou PNG", - - "error.blueprint.notFound": "A planta \"{name}\" não pôde ser carregada", - - "error.blocks.max.plural": "Você não deve adicionar mais do que {max} blocos", - "error.blocks.max.singular": "Você não deve adicionar mais do que um bloco", - "error.blocks.min.plural": "Você deve adicionar pelo menos {min} blocos", - "error.blocks.min.singular": "Você deve adicionar pelo menos um bloco", - "error.blocks.validation": "Há um erro no bloco {index}", - - "error.email.preset.notFound": "Pré-configuração de email \"{name}\" não foi encontrada", - - "error.field.converter.invalid": "Conversor \"{converter}\" inválido", - - "error.file.changeName.empty": "O nome não deve ficar em branco", - "error.file.changeName.permission": "Você não tem permissão para alterar o nome de \"{filename}\"", - "error.file.duplicate": "Um arquivo com o nome \"{filename}\" já existe", - "error.file.extension.forbidden": "Extensão \"{extension}\" não permitida", - "error.file.extension.invalid": "Extensão inválida: {extension}", - "error.file.extension.missing": "Extensão de \"{filename}\" em falta", - "error.file.maxheight": "A altura da imagem não pode exceder {height} pixels", - "error.file.maxsize": "O arquivo é grande demais", - "error.file.maxwidth": "A largura da imagem não pode exceder {width} pixels", - "error.file.mime.differs": "O arquivo enviado precisa ser do tipo \"{mime}\"", - "error.file.mime.forbidden": "Tipo de mídia \"{mime}\" não permitido", - "error.file.mime.invalid": "Tipo mime inválido: {mime}", - "error.file.mime.missing": "Tipo de mídia de \"{filename}\" não detectado", - "error.file.minheight": "A altura da imagem deve ser pelo menos {height} pixels", - "error.file.minsize": "O arquivo é pequeno demais", - "error.file.minwidth": "A largura da imagem deve ser pelo menos {width} pixels", - "error.file.name.missing": "O nome do arquivo não pode ficar em branco", - "error.file.notFound": "Arquivo \"{filename}\" não encontrado", - "error.file.orientation": "A orientação da imagem deve ser “{orientation}”", - "error.file.type.forbidden": "Você não tem permissão para enviar arquivos {type}", - "error.file.type.invalid": "Tipo inválido de arquivo: {type}", - "error.file.undefined": "Arquivo n\u00e3o encontrado", - - "error.form.incomplete": "Por favor, corrija os erros do formulário…", - "error.form.notSaved": "O formulário não pôde ser salvo", - - "error.language.code": "Por favor entre um código válido para o idioma", - "error.language.duplicate": "O idioma já existe", - "error.language.name": "Por favor entre um nome válido para o idioma", - "error.language.notFound": "O idioma não foi encontrado", - - "error.layout.validation.block": "Há um erro no bloco {blockIndex} no layout {layoutIndex}", - "error.layout.validation.settings": "Há um erro na configuração do layout {index}", - - "error.license.format": "Por favor entre uma chave de licensa válida ", - "error.license.email": "Digite um endereço de email válido", - "error.license.verification": "A licensa não pôde ser verificada", - - "error.offline": "O painel está offline no momento", - - "error.page.changeSlug.permission": "Você não tem permissão para alterar o anexo de URL de \"{slug}\"", - "error.page.changeStatus.incomplete": "A página possui erros e não pode ser salva", - "error.page.changeStatus.permission": "O estado desta página não pode ser alterado", - "error.page.changeStatus.toDraft.invalid": "A página \"{slug}\" não pode ser convertida para rascunho", - "error.page.changeTemplate.invalid": "O tema da página \"{slug}\" não pode ser alterado", - "error.page.changeTemplate.permission": "Você não tem permissão para alterar o tema de \"{slug}\"", - "error.page.changeTitle.empty": "O título não pode ficar em branco", - "error.page.changeTitle.permission": "Você não tem permissão para alterar o título de \"{slug}\"", - "error.page.create.permission": "Você não tem permissão para criar \"{slug}\"", - "error.page.delete": "A página \"{slug}\" não pode ser deletada", - "error.page.delete.confirm": "Por favor, digite o título da página para confirmar", - "error.page.delete.hasChildren": "A página possui subpáginas e não pode ser deletada", - "error.page.delete.permission": "Você não tem permissão para deletar \"{slug}\"", - "error.page.draft.duplicate": "Uma página rascunho com um anexo de URL \"{slug}\" já existe", - "error.page.duplicate": "Uma página com o anexo de URL \"{slug}\" já existe", - "error.page.duplicate.permission": "Você não tem permissão para duplicar “{slug}”", - "error.page.notFound": "Página \"{slug}\" não encontrada", - "error.page.num.invalid": "Digite um número de ordenação válido. Este número não pode ser negativo.", - "error.page.slug.invalid": "Por favor entre um anexo de URL válido ", - "error.page.slug.maxlength": "O slug deve ter menos de “{length}” caracteres", - "error.page.sort.permission": "A página \"{slug}\" não pode ser ordenada", - "error.page.status.invalid": "Por favor, defina um estado de página válido", - "error.page.undefined": "P\u00e1gina n\u00e3o encontrada", - "error.page.update.permission": "Você não tem permissão para atualizar \"{slug}\"", - - "error.section.files.max.plural": "Você não pode adicionar mais do que {max} arquivos à seção \"{section}\"", - "error.section.files.max.singular": "Você não pode adicionar mais do que um arquivo à seção \"{section}\"", - "error.section.files.min.plural": "A seção “{section}” precisa ter pelo menos {min} arquivos", - "error.section.files.min.singular": "A seção “{section}” precisa ter pelo menos um arquivo", - - "error.section.pages.max.plural": "Você não pode adicionar mais do que {max} páginas à seção \"{section}\"", - "error.section.pages.max.singular": "Você não pode adicionar mais do que uma página à seção \"{section}\"", - "error.section.pages.min.plural": "A seção “{section}” precisa ter pelo menos {min} páginas ", - "error.section.pages.min.singular": "A seção “{section}” precisa ter pelo menos uma página ", - - "error.section.notLoaded": "A seção \"{name}\" não pôde ser carregada", - "error.section.type.invalid": "O tipo da seção \"{type}\" não é válido", - - "error.site.changeTitle.empty": "O título não pode ficar em branco", - "error.site.changeTitle.permission": "Você não tem permissão para alterar o título do site", - "error.site.update.permission": "Você não tem permissão para atualizar o site", - - "error.template.default.notFound": "O tema padrão não existe", - - "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Você não tem permissão para alterar o email do usuário \"{name}\"", - "error.user.changeLanguage.permission": "Você não tem permissão para alterar o idioma do usuário \"{name}\"", - "error.user.changeName.permission": "Você não tem permissão para alterar o nome do usuário \"{name}\"", - "error.user.changePassword.permission": "Você não tem permissão para alterar a senha do usuário \"{name}\"", - "error.user.changeRole.lastAdmin": "O papel do último administrador não pode ser alterado", - "error.user.changeRole.permission": "Você não tem permissão para alterar o papel do usuário \"{name}\"", - "error.user.changeRole.toAdmin": "Você não tem permissão para promover usuários ao papel de administrador ", - "error.user.create.permission": "Você não tem permissão para criar este usuário", - "error.user.delete": "O usuário \"{name}\" não pode ser deletado", - "error.user.delete.lastAdmin": "O último administrador não pode ser deletado", - "error.user.delete.lastUser": "O último usuário não pode ser deletado", - "error.user.delete.permission": "Você não tem permissão para deletar o usuário \"{name}\"", - "error.user.duplicate": "Um usuário com o email \"{email}\" já existe", - "error.user.email.invalid": "Digite um endereço de email válido", - "error.user.language.invalid": "Digite um idioma válido", - "error.user.notFound": "Usuário \"{name}\" não encontrado", - "error.user.password.invalid": "Digite uma senha válida. Sua senha deve ter pelo menos 8 caracteres.", - "error.user.password.notSame": "As senhas não combinam", - "error.user.password.undefined": "O usuário não possui uma senha", - "error.user.password.wrong": "Senha errada", - "error.user.role.invalid": "Digite um papel válido", - "error.user.undefined": "Usuário não encontrado", - "error.user.update.permission": "Você não tem permissão para atualizar o usuário \"{name}\"", - - "error.validation.accepted": "Por favor, confirme", - "error.validation.alpha": "Por favor, use apenas caracteres entre a-z", - "error.validation.alphanum": "Por favor, use apenas caracteres entre a-z ou 0-9", - "error.validation.between": "Digite um valor entre \"{min}\" e \"{max}\"", - "error.validation.boolean": "Por favor, confirme ou rejeite", - "error.validation.contains": "Digite um valor que contenha \"{needle}\"", - "error.validation.date": "Escolha uma data válida", - "error.validation.date.after": "Por favor entre uma data depois de {date}", - "error.validation.date.before": "Por favor entre uma data antes de {date}", - "error.validation.date.between": "Por favor entre uma data entre {min} e {max}", - "error.validation.denied": "Por favor, cancele", - "error.validation.different": "O valor deve ser diferente de \"{other}\"", - "error.validation.email": "Digite um endereço de email válido", - "error.validation.endswith": "O valor deve terminar com \"{end}\"", - "error.validation.filename": "Digite um nome de arquivo válido", - "error.validation.in": "Digite um destes valores: ({in})", - "error.validation.integer": "Digite um número inteiro válido", - "error.validation.ip": "Digite um endereço de IP válido", - "error.validation.less": "Digite um valor menor que {max}", - "error.validation.match": "O valor não combina com o padrão esperado", - "error.validation.max": "Digite um valor igual ou menor que {max}", - "error.validation.maxlength": "Digite um valor curto. (no máximo {max} caracteres)", - "error.validation.maxwords": "Digite menos que {max} palavra(s)", - "error.validation.min": "Digite um valor igual ou maior que {min}", - "error.validation.minlength": "Digite um valor maior. (no mínimo {min} caracteres)", - "error.validation.minwords": "Digite ao menos {min} palavra(s)", - "error.validation.more": "Digite um valor maior que {min}", - "error.validation.notcontains": "Digite um valor que não contenha \"{needle}\"", - "error.validation.notin": "Não digite nenhum destes valores: ({notIn})", - "error.validation.option": "Escolha uma opção válida", - "error.validation.num": "Digite um número válido", - "error.validation.required": "Digite algo", - "error.validation.same": "Por favor, digite \"{other}\"", - "error.validation.size": "O tamanho do valor deve ser \"{size}\"", - "error.validation.startswith": "O valor deve começar com \"{start}\"", - "error.validation.time": "Digite um horário válido", - "error.validation.time.after": "Por favor entre um horário depois de {time}", - "error.validation.time.before": "Por favor entre um horário antes de {time}", - "error.validation.time.between": "Por favor entre um horário entre {min} e {max}", - "error.validation.url": "Digite uma URL válida", - - "expand": "Expandir", - "expand.all": "Expandir todos", - - "field.required": "Este campo é obrigatório ", - "field.blocks.changeType": "Mudar tipo", - "field.blocks.code.name": "Código", - "field.blocks.code.language": "Idioma", - "field.blocks.code.placeholder": "Seu código …", - "field.blocks.delete.confirm": "Deseja realmente deletar este bloco?", - "field.blocks.delete.confirm.all": "Deseja realmente deletar todos os blocos?", - "field.blocks.delete.confirm.selected": "Deseja realmente deletar os blocos selecionados?", - "field.blocks.empty": "Nenhum bloco", - "field.blocks.fieldsets.label": "Por favor selecione um tipo de bloco …", - "field.blocks.fieldsets.paste": "Digite {{ shortcut }} para colar/importar blocos da sua área de transferência ", - "field.blocks.gallery.name": "Galeria", - "field.blocks.gallery.images.empty": "Nenhuma imagem", - "field.blocks.gallery.images.label": "Imagens", - "field.blocks.heading.level": "Nível ", - "field.blocks.heading.name": "Título ", - "field.blocks.heading.text": "Texto", - "field.blocks.heading.placeholder": "Título …", - "field.blocks.image.alt": "Texto alternativo", - "field.blocks.image.caption": "Legenda", - "field.blocks.image.crop": "Cortar", - "field.blocks.image.link": "Link", - "field.blocks.image.location": "Localização ", - "field.blocks.image.name": "Imagem", - "field.blocks.image.placeholder": "Selecionar uma imagem", - "field.blocks.image.ratio": "Proporção ", - "field.blocks.image.url": "URL da imagem", - "field.blocks.line.name": "Linha", - "field.blocks.list.name": "Lista", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Texto", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Citação ", - "field.blocks.quote.text.label": "Texto", - "field.blocks.quote.text.placeholder": "Citação …", - "field.blocks.quote.citation.label": "Citação ", - "field.blocks.quote.citation.placeholder": "de …", - "field.blocks.text.name": "Texto", - "field.blocks.text.placeholder": "Texto …", - "field.blocks.video.caption": "Legenda", - "field.blocks.video.name": "Vídeo ", - "field.blocks.video.placeholder": "Entre uma URL de vídeo ", - "field.blocks.video.url.label": "URL-Vídeo", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Nenhum arquivo selecionado", - - "field.layout.delete": "Deletar layout", - "field.layout.delete.confirm": "Deseja realmente deletar este layout?", - "field.layout.empty": "Nenhuma linha", - "field.layout.select": "Selecionar um layout", - - "field.pages.empty": "Nenhuma página selecionada", - "field.structure.delete.confirm": "Deseja realmente deletar esta linha?", - "field.structure.empty": "Nenhum registro", - "field.users.empty": "Nenhum usuário selecionado", - - "file.blueprint": "Este arquivo não tem planta. Você pode definir sua planta em /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Deseja realmente deletar
{filename}?", - "file.sort": "Mudar posição", - - "files": "Arquivos", - "files.empty": "Nenhum arquivo", - - "hide": "Ocultar", - "hour": "Hora", - "import": "Importar", - "info": "Info", - "insert": "Inserir", - "insert.after": "Inserir após", - "insert.before": "Inserir antes", - "install": "Instalar", - - "installation": "Instalação", - "installation.completed": "Painel instalado com sucesso", - "installation.disabled": "O instalador do painel está desabilitado em servidores públicos por padrão. Por favor, execute o instalador em uma máquina local ou habilite a opção panel.install.", - "installation.issues.accounts": "A pasta /site/accounts não existe ou não possui permissão de escrita", - "installation.issues.content": "A pasta /content não existe ou não possui permissão de escrita", - "installation.issues.curl": "A extensão CURL é necessária", - "installation.issues.headline": "O painel não pôde ser instalado", - "installation.issues.mbstring": "A extensão MB String é necessária", - "installation.issues.media": "A pasta /media não existe ou não possui permissão de escrita", - "installation.issues.php": "Certifique-se que você está usando o PHP 7+", - "installation.issues.server": "Kirby necessita do Apache, Nginx ou Caddy", - "installation.issues.sessions": "A pasta /site/sessions não existe ou não possui permissão de escrita", - - "language": "Idioma", - "language.code": "Código", - "language.convert": "Tornar padrão", - "language.convert.confirm": "

Deseja realmente converter {name} para o idioma padrão? Esta ação não poderá ser revertida.

Se {name} tiver conteúdo não traduzido, partes do seu site poderão ficar sem conteúdo.

", - "language.create": "Adicionar novo idioma", - "language.delete.confirm": "Deseja realmente deletar o idioma {name} incluíndo todas as traduções. Esta ação não poderá ser revertida!", - "language.deleted": "Idioma deletado", - "language.direction": "Direção de leitura", - "language.direction.ltr": "Esquerda para direita", - "language.direction.rtl": "Direita para esquerda", - "language.locale": "String de localização do PHP", - "language.locale.warning": "Você está usando uma configuração de local customizada. Por favor modifique a configuração no arquivo do idioma em /site/languages", - "language.name": "Nome", - "language.updated": "Idioma atualizado", - - "languages": "Idiomas", - "languages.default": "Idioma padrão", - "languages.empty": "Nenhum idioma", - "languages.secondary": "Idiomas secundários", - "languages.secondary.empty": "Nenhum idioma secundário", - - "license": "Licen\u00e7a do Kirby ", - "license.buy": "Comprar licença", - "license.register": "Registrar", - "license.manage": "Manage your licenses", - "license.register.help": "Você recebeu o código da sua licença por email ao efetuar sua compra. Por favor, copie e cole o código para completar seu registro.", - "license.register.label": "Por favor, digite o código da sua licença", - "license.register.success": "Obrigado por apoiar o Kirby", - "license.unregistered": "Esta é uma cópia de demonstração não registrada do Kirby", - "license.unregistered.label": "Unregistered", - - "link": "Link", - "link.text": "Texto do link", - - "loading": "Carregando", - - "lock.unsaved": "Mudanças não salvas", - "lock.unsaved.empty": "Não há mais mudanças não salvas", - "lock.isLocked": "Mudanças não salvas por {email}", - "lock.file.isLocked": "Este arquivo está sendo editado no momento por {email}, e não pode ser mudado", - "lock.page.isLocked": "Esta página está sendo editada no momento por {email}, e não pode ser mudada", - "lock.unlock": "Destrancar", - "lock.isUnlocked": "Suas mudanças não salvas foram alteradas por outro usuário, e serão perdidas. Você pode baixar um arquivo com suas mudanças, para depois fundi-las manualmente. ", - - "login": "Entrar", - "login.code.label.login": "Código de acesso", - "login.code.label.password-reset": "Código de redefinição de senha", - "login.code.placeholder.email": "000 0000", - "login.code.text.email": "Se seu endereço de email está registrado, o código requisitado será mandado por email.", - "login.email.login.body": "Oi, {user.nameOrEmail},\n\nVocê recentemente pediu um código de acesso ao painel administrativo do site {site}.\nO seguinte código será válido por {timeout} minutos:\n\n{code}\n\nSe você não pediu este código de acesso, por favor ignore esta mensagem, ou contate seu Administrador de Sistemas se você tiver dúvidas.\nPor questões de segurança, por favor NÃO compartilhe esta mensagem.", - "login.email.login.subject": "Seu código de acesso", - "login.email.password-reset.body": "Oi, {user.nameOrEmail},\n\nVocê recentemente pediu um código de redefinição de senha, para o painel administrativo do site {site}.\nO seguinte código de redefinição de senha será válido por {timeout} minutos:\n\n{code}\n\nSe você não pediu este código, por favor ignore esta mensagem, ou contate seu Administrador de Sistemas se você tiver dúvidas.\nPor questões de segurança, por favor NÃO compartilhe esta mensagem.", - "login.email.password-reset.subject": "Seu código de redefinição de senha", - "login.remember": "Manter-me conectado", - "login.reset": "Redefinir senha", - "login.toggleText.code.email": "Entrar com email", - "login.toggleText.code.email-password": "Entrar com senha", - "login.toggleText.password-reset.email": "Esqueceu sua senha?", - "login.toggleText.password-reset.email-password": "← Voltar à entrada", - - "logout": "Sair", - - "menu": "Menu", - "meridiem": "AM/PM", - "mime": "Tipo de mídia", - "minutes": "Minutos", - - "month": "Mês", - "months.april": "Abril", - "months.august": "Agosto", - "months.december": "Dezembro", - "months.february": "Fevereiro", - "months.january": "Janeiro", - "months.july": "Julho", - "months.june": "Junho", - "months.march": "Mar\u00e7o", - "months.may": "Maio", - "months.november": "Novembro", - "months.october": "Outubro", - "months.september": "Setembro", - - "more": "Mais", - "name": "Nome", - "next": "Próximo", - "no": "não", - "off": "não", - "on": "sim", - "open": "Abrir", - "open.newWindow": "Abrir em nova janela", - "options": "Opções", - "options.none": "Nenhuma opção", - - "orientation": "Orientação", - "orientation.landscape": "Paisagem", - "orientation.portrait": "Retrato", - "orientation.square": "Quadrado", - - "page.blueprint": "Esta página não tem planta. Você pode definir sua planta em /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Alterar URL", - "page.changeSlug.fromTitle": "Criar a partir do t\u00edtulo", - "page.changeStatus": "Alterar estado", - "page.changeStatus.position": "Selecione uma posição", - "page.changeStatus.select": "Selecione um novo estado", - "page.changeTemplate": "Alterar tema", - "page.delete.confirm": "Deseja realmente deletar {title}?", - "page.delete.confirm.subpages": "Esta página possui subpáginas.
Todas as subpáginas serão excluídas também.", - "page.delete.confirm.title": "Digite o título da página para confirmar", - "page.draft.create": "Criar rascunho", - "page.duplicate.appendix": "Copiar", - "page.duplicate.files": "Copiar arquivos", - "page.duplicate.pages": "Copiar páginas", - "page.sort": "Mudar posição", - "page.status": "Estado", - "page.status.draft": "Rascunho", - "page.status.draft.description": "A página é um rascunho, e visível somente por editores logados, ou através de um link secreto.", - "page.status.listed": "Pública", - "page.status.listed.description": "A página pública é visível para todos", - "page.status.unlisted": "Não listadas", - "page.status.unlisted.description": "Esta página é acessível somente através da URL", - - "pages": "Páginas", - "pages.empty": "Nenhuma página", - "pages.status.draft": "Rascunhos", - "pages.status.listed": "Publicadas", - "pages.status.unlisted": "Não listadas", - - "pagination.page": "Página", - - "password": "Senha", - "paste": "Colar", - "paste.after": "Colar após", - "pixel": "Pixel", - "plugins": "Plugins", - "prev": "Anterior", - "preview": "Visualizar", - "remove": "Remover", - "rename": "Renomear", - "replace": "Substituir", - "retry": "Tentar novamente", - "revert": "Descartar", - "revert.confirm": "Deseja realmente deletar todas as mudanças não salvas?", - - "role": "Papel", - "role.admin.description": "O administrador tem todos os direitos", - "role.admin.title": "Administrador", - "role.all": "Todos", - "role.empty": "Não há usuários com este papel", - "role.description.placeholder": "Sem descrição", - "role.nobody.description": "Este é um papel atribuído por padrão, sem nenhuma permissão", - "role.nobody.title": "Ninguém", - - "save": "Salvar", - "search": "Buscar", - "search.min": "Digite {min} caracteres para fazer uma busca", - "search.all": "Mostrar todos", - "search.results.none": "Nenhum resultado", - - "section.required": "Esta seção é obrigatória", - - "security": "Security", - "select": "Selecionar", - "server": "Servidor", - "settings": "Configurações", - "show": "Mostrar", - "site.blueprint": "Este site não tem planta. Você pode definir sua planta em /site/blueprints/site.yml", - "size": "Tamanho", - "slug": "Anexo de URL", - "sort": "Ordenar", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Título", - "template": "Tema", - "today": "Hoje", - - "toolbar.button.code": "Código", - "toolbar.button.bold": "Negrito", - "toolbar.button.email": "Email", - "toolbar.button.headings": "Títulos", - "toolbar.button.heading.1": "Título 1", - "toolbar.button.heading.2": "Título 2", - "toolbar.button.heading.3": "Título 3", - "toolbar.button.heading.4": "Título 4", - "toolbar.button.heading.5": "Título 5", - "toolbar.button.heading.6": "Título 6", - "toolbar.button.italic": "Itálico", - "toolbar.button.file": "Arquivo", - "toolbar.button.file.select": "Selecionar arquivo", - "toolbar.button.file.upload": "Carregar arquivo", - "toolbar.button.link": "Link", - "toolbar.button.paragraph": "Parágrafo", - "toolbar.button.strike": "Riscado", - "toolbar.button.ol": "Lista ordenada", - "toolbar.button.underline": "Sublinhado", - "toolbar.button.ul": "Lista não-ordenada", - - "translation.author": "Time Kirby", - "translation.direction": "ltr", - "translation.name": "Português do Brasil", - "translation.locale": "pt_BR", - - "upload": "Enviar", - "upload.error.cantMove": "O arquivo carregado não pôde ser movido", - "upload.error.cantWrite": "Falha ao escrever o arquivo no disco", - "upload.error.default": "O arquivo não pode ser carregado", - "upload.error.extension": "O carregamento do arquivo foi interrompido por causa da extensão", - "upload.error.formSize": "O arquivo carregado excede a diretiva de MAX_FILE_SIZE especificada no formulário", - "upload.error.iniPostSize": "O arquivo carregado excede a diretiva post_max_size do php.ini", - "upload.error.iniSize": "O arquivo carregado excede a diretiva upload_max_size do php.ini", - "upload.error.noFile": "Nenhum arquivo foi carregado", - "upload.error.noFiles": "Nenhum arquivo foi carregado", - "upload.error.partial": "O arquivo foi só parcialmente carregado", - "upload.error.tmpDir": "Falta uma pasta temporária", - "upload.errors": "Erro", - "upload.progress": "Enviando…", - - "url": "Url", - "url.placeholder": "https://example.com", - - "user": "Usuário", - "user.blueprint": "Você pode definir seções e campos de formulário adicionais para este papel de usuário em /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Alterar email", - "user.changeLanguage": "Alterar idioma", - "user.changeName": "Renomear usuário", - "user.changePassword": "Alterar senha", - "user.changePassword.new": "Nova senha", - "user.changePassword.new.confirm": "Confirme a nova senha…", - "user.changeRole": "Alterar papel", - "user.changeRole.select": "Selecione um novo papel", - "user.create": "Adicionar novo usuário", - "user.delete": "Deletar este usuário", - "user.delete.confirm": "Deseja realmente deletar
{email}?", - - "users": "Usuários", - - "version": "Vers\u00e3o do Kirby", - - "view.account": "Sua conta", - "view.installation": "Instala\u00e7\u00e3o", - "view.languages": "Idiomas", - "view.resetPassword": "Redefinir senha", - "view.site": "Site", - "view.system": "Sistema", - "view.users": "Usu\u00e1rios", - - "welcome": "Bem-vindo", - "year": "Ano", - "yes": "sim" + "account.changeName": "Mudar seu nome", + "account.delete": "Deletar sua conta", + "account.delete.confirm": "Deseja realmente deletar sua conta? Você sairá do site imediatamente. Sua conta não poderá ser recuperada. ", + + "add": "Adicionar", + "author": "Autor", + "avatar": "Foto do perfil", + "back": "Voltar", + "cancel": "Cancelar", + "change": "Alterar", + "close": "Fechar", + "confirm": "Salvar", + "collapse": "Colapsar", + "collapse.all": "Colapsar todos", + "copy": "Copiar", + "copy.all": "Copiar todos", + "create": "Criar", + + "date": "Data", + "date.select": "Selecione uma data", + + "day": "Dia", + "days.fri": "Sex", + "days.mon": "Seg", + "days.sat": "S\u00e1b", + "days.sun": "Dom", + "days.thu": "Qui", + "days.tue": "Ter", + "days.wed": "Qua", + + "debugging": "Depuração ", + + "delete": "Deletar", + "delete.all": "Deletar todos", + + "dialog.files.empty": "Nenhum arquivo para selecionar", + "dialog.pages.empty": "Nenhuma página para selecionar", + "dialog.users.empty": "Nenhum usuário para selecionar", + + "dimensions": "Dimensões", + "disabled": "Desativado", + "discard": "Descartar", + "download": "Baixar", + "duplicate": "Duplicar", + + "edit": "Editar", + + "email": "Email", + "email.placeholder": "mail@exemplo.com", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Ambiente", + + "error.access.code": "Código inválido", + "error.access.login": "Código de acesso inválido", + "error.access.panel": "Você não tem permissão para acessar o painel", + "error.access.view": "Você não tem permissão para acessar esta parte do painel", + + "error.avatar.create.fail": "A foto de perfil não pôde ser enviada", + "error.avatar.delete.fail": "A foto de perfil não pôde ser deletada", + "error.avatar.dimensions.invalid": "Por favor, use uma foto de perfil com largura e altura menores que 3000 pixels", + "error.avatar.mime.forbidden": "A foto de perfil deve ser um arquivo JPEG ou PNG", + + "error.blueprint.notFound": "A planta \"{name}\" não pôde ser carregada", + + "error.blocks.max.plural": "Você não deve adicionar mais do que {max} blocos", + "error.blocks.max.singular": "Você não deve adicionar mais do que um bloco", + "error.blocks.min.plural": "Você deve adicionar pelo menos {min} blocos", + "error.blocks.min.singular": "Você deve adicionar pelo menos um bloco", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "Pré-configuração de email \"{name}\" não foi encontrada", + + "error.field.converter.invalid": "Conversor \"{converter}\" inválido", + + "error.file.changeName.empty": "O nome não deve ficar em branco", + "error.file.changeName.permission": "Você não tem permissão para alterar o nome de \"{filename}\"", + "error.file.duplicate": "Um arquivo com o nome \"{filename}\" já existe", + "error.file.extension.forbidden": "Extensão \"{extension}\" não permitida", + "error.file.extension.invalid": "Extensão inválida: {extension}", + "error.file.extension.missing": "Extensão de \"{filename}\" em falta", + "error.file.maxheight": "A altura da imagem não pode exceder {height} pixels", + "error.file.maxsize": "O arquivo é grande demais", + "error.file.maxwidth": "A largura da imagem não pode exceder {width} pixels", + "error.file.mime.differs": "O arquivo enviado precisa ser do tipo \"{mime}\"", + "error.file.mime.forbidden": "Tipo de mídia \"{mime}\" não permitido", + "error.file.mime.invalid": "Tipo mime inválido: {mime}", + "error.file.mime.missing": "Tipo de mídia de \"{filename}\" não detectado", + "error.file.minheight": "A altura da imagem deve ser pelo menos {height} pixels", + "error.file.minsize": "O arquivo é pequeno demais", + "error.file.minwidth": "A largura da imagem deve ser pelo menos {width} pixels", + "error.file.name.missing": "O nome do arquivo não pode ficar em branco", + "error.file.notFound": "Arquivo \"{filename}\" não encontrado", + "error.file.orientation": "A orientação da imagem deve ser “{orientation}”", + "error.file.type.forbidden": "Você não tem permissão para enviar arquivos {type}", + "error.file.type.invalid": "Tipo inválido de arquivo: {type}", + "error.file.undefined": "Arquivo n\u00e3o encontrado", + + "error.form.incomplete": "Por favor, corrija os erros do formulário…", + "error.form.notSaved": "O formulário não pôde ser salvo", + + "error.language.code": "Por favor entre um código válido para o idioma", + "error.language.duplicate": "O idioma já existe", + "error.language.name": "Por favor entre um nome válido para o idioma", + "error.language.notFound": "O idioma não foi encontrado", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "Há um erro na configuração do layout {index}", + + "error.license.format": "Por favor entre uma chave de licensa válida ", + "error.license.email": "Digite um endereço de email válido", + "error.license.verification": "A licensa não pôde ser verificada", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "O painel está offline no momento", + + "error.page.changeSlug.permission": "Você não tem permissão para alterar o anexo de URL de \"{slug}\"", + "error.page.changeStatus.incomplete": "A página possui erros e não pode ser salva", + "error.page.changeStatus.permission": "O estado desta página não pode ser alterado", + "error.page.changeStatus.toDraft.invalid": "A página \"{slug}\" não pode ser convertida para rascunho", + "error.page.changeTemplate.invalid": "O tema da página \"{slug}\" não pode ser alterado", + "error.page.changeTemplate.permission": "Você não tem permissão para alterar o tema de \"{slug}\"", + "error.page.changeTitle.empty": "O título não pode ficar em branco", + "error.page.changeTitle.permission": "Você não tem permissão para alterar o título de \"{slug}\"", + "error.page.create.permission": "Você não tem permissão para criar \"{slug}\"", + "error.page.delete": "A página \"{slug}\" não pode ser deletada", + "error.page.delete.confirm": "Por favor, digite o título da página para confirmar", + "error.page.delete.hasChildren": "A página possui subpáginas e não pode ser deletada", + "error.page.delete.permission": "Você não tem permissão para deletar \"{slug}\"", + "error.page.draft.duplicate": "Uma página rascunho com um anexo de URL \"{slug}\" já existe", + "error.page.duplicate": "Uma página com o anexo de URL \"{slug}\" já existe", + "error.page.duplicate.permission": "Você não tem permissão para duplicar “{slug}”", + "error.page.notFound": "Página \"{slug}\" não encontrada", + "error.page.num.invalid": "Digite um número de ordenação válido. Este número não pode ser negativo.", + "error.page.slug.invalid": "Por favor entre um anexo de URL válido ", + "error.page.slug.maxlength": "O slug deve ter menos de “{length}” caracteres", + "error.page.sort.permission": "A página \"{slug}\" não pode ser ordenada", + "error.page.status.invalid": "Por favor, defina um estado de página válido", + "error.page.undefined": "P\u00e1gina n\u00e3o encontrada", + "error.page.update.permission": "Você não tem permissão para atualizar \"{slug}\"", + + "error.section.files.max.plural": "Você não pode adicionar mais do que {max} arquivos à seção \"{section}\"", + "error.section.files.max.singular": "Você não pode adicionar mais do que um arquivo à seção \"{section}\"", + "error.section.files.min.plural": "A seção “{section}” precisa ter pelo menos {min} arquivos", + "error.section.files.min.singular": "A seção “{section}” precisa ter pelo menos um arquivo", + + "error.section.pages.max.plural": "Você não pode adicionar mais do que {max} páginas à seção \"{section}\"", + "error.section.pages.max.singular": "Você não pode adicionar mais do que uma página à seção \"{section}\"", + "error.section.pages.min.plural": "A seção “{section}” precisa ter pelo menos {min} páginas ", + "error.section.pages.min.singular": "A seção “{section}” precisa ter pelo menos uma página ", + + "error.section.notLoaded": "A seção \"{name}\" não pôde ser carregada", + "error.section.type.invalid": "O tipo da seção \"{type}\" não é válido", + + "error.site.changeTitle.empty": "O título não pode ficar em branco", + "error.site.changeTitle.permission": "Você não tem permissão para alterar o título do site", + "error.site.update.permission": "Você não tem permissão para atualizar o site", + + "error.template.default.notFound": "O tema padrão não existe", + + "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Você não tem permissão para alterar o email do usuário \"{name}\"", + "error.user.changeLanguage.permission": "Você não tem permissão para alterar o idioma do usuário \"{name}\"", + "error.user.changeName.permission": "Você não tem permissão para alterar o nome do usuário \"{name}\"", + "error.user.changePassword.permission": "Você não tem permissão para alterar a senha do usuário \"{name}\"", + "error.user.changeRole.lastAdmin": "O papel do último administrador não pode ser alterado", + "error.user.changeRole.permission": "Você não tem permissão para alterar o papel do usuário \"{name}\"", + "error.user.changeRole.toAdmin": "Você não tem permissão para promover usuários ao papel de administrador ", + "error.user.create.permission": "Você não tem permissão para criar este usuário", + "error.user.delete": "O usuário \"{name}\" não pode ser deletado", + "error.user.delete.lastAdmin": "O último administrador não pode ser deletado", + "error.user.delete.lastUser": "O último usuário não pode ser deletado", + "error.user.delete.permission": "Você não tem permissão para deletar o usuário \"{name}\"", + "error.user.duplicate": "Um usuário com o email \"{email}\" já existe", + "error.user.email.invalid": "Digite um endereço de email válido", + "error.user.language.invalid": "Digite um idioma válido", + "error.user.notFound": "Usuário \"{name}\" não encontrado", + "error.user.password.invalid": "Digite uma senha válida. Sua senha deve ter pelo menos 8 caracteres.", + "error.user.password.notSame": "As senhas não combinam", + "error.user.password.undefined": "O usuário não possui uma senha", + "error.user.password.wrong": "Senha errada", + "error.user.role.invalid": "Digite um papel válido", + "error.user.undefined": "Usuário não encontrado", + "error.user.update.permission": "Você não tem permissão para atualizar o usuário \"{name}\"", + + "error.validation.accepted": "Por favor, confirme", + "error.validation.alpha": "Por favor, use apenas caracteres entre a-z", + "error.validation.alphanum": "Por favor, use apenas caracteres entre a-z ou 0-9", + "error.validation.between": "Digite um valor entre \"{min}\" e \"{max}\"", + "error.validation.boolean": "Por favor, confirme ou rejeite", + "error.validation.contains": "Digite um valor que contenha \"{needle}\"", + "error.validation.date": "Escolha uma data válida", + "error.validation.date.after": "Por favor entre uma data depois de {date}", + "error.validation.date.before": "Por favor entre uma data antes de {date}", + "error.validation.date.between": "Por favor entre uma data entre {min} e {max}", + "error.validation.denied": "Por favor, cancele", + "error.validation.different": "O valor deve ser diferente de \"{other}\"", + "error.validation.email": "Digite um endereço de email válido", + "error.validation.endswith": "O valor deve terminar com \"{end}\"", + "error.validation.filename": "Digite um nome de arquivo válido", + "error.validation.in": "Digite um destes valores: ({in})", + "error.validation.integer": "Digite um número inteiro válido", + "error.validation.ip": "Digite um endereço de IP válido", + "error.validation.less": "Digite um valor menor que {max}", + "error.validation.match": "O valor não combina com o padrão esperado", + "error.validation.max": "Digite um valor igual ou menor que {max}", + "error.validation.maxlength": "Digite um valor curto. (no máximo {max} caracteres)", + "error.validation.maxwords": "Digite menos que {max} palavra(s)", + "error.validation.min": "Digite um valor igual ou maior que {min}", + "error.validation.minlength": "Digite um valor maior. (no mínimo {min} caracteres)", + "error.validation.minwords": "Digite ao menos {min} palavra(s)", + "error.validation.more": "Digite um valor maior que {min}", + "error.validation.notcontains": "Digite um valor que não contenha \"{needle}\"", + "error.validation.notin": "Não digite nenhum destes valores: ({notIn})", + "error.validation.option": "Escolha uma opção válida", + "error.validation.num": "Digite um número válido", + "error.validation.required": "Digite algo", + "error.validation.same": "Por favor, digite \"{other}\"", + "error.validation.size": "O tamanho do valor deve ser \"{size}\"", + "error.validation.startswith": "O valor deve começar com \"{start}\"", + "error.validation.time": "Digite um horário válido", + "error.validation.time.after": "Por favor entre um horário depois de {time}", + "error.validation.time.before": "Por favor entre um horário antes de {time}", + "error.validation.time.between": "Por favor entre um horário entre {min} e {max}", + "error.validation.url": "Digite uma URL válida", + + "expand": "Expandir", + "expand.all": "Expandir todos", + + "field.required": "Este campo é obrigatório ", + "field.blocks.changeType": "Mudar tipo", + "field.blocks.code.name": "Código", + "field.blocks.code.language": "Idioma", + "field.blocks.code.placeholder": "Seu código …", + "field.blocks.delete.confirm": "Deseja realmente deletar este bloco?", + "field.blocks.delete.confirm.all": "Deseja realmente deletar todos os blocos?", + "field.blocks.delete.confirm.selected": "Deseja realmente deletar os blocos selecionados?", + "field.blocks.empty": "Nenhum bloco", + "field.blocks.fieldsets.label": "Por favor selecione um tipo de bloco …", + "field.blocks.fieldsets.paste": "Digite {{ shortcut }} para colar/importar blocos da sua área de transferência ", + "field.blocks.gallery.name": "Galeria", + "field.blocks.gallery.images.empty": "Nenhuma imagem", + "field.blocks.gallery.images.label": "Imagens", + "field.blocks.heading.level": "Nível ", + "field.blocks.heading.name": "Título ", + "field.blocks.heading.text": "Texto", + "field.blocks.heading.placeholder": "Título …", + "field.blocks.image.alt": "Texto alternativo", + "field.blocks.image.caption": "Legenda", + "field.blocks.image.crop": "Cortar", + "field.blocks.image.link": "Link", + "field.blocks.image.location": "Localização ", + "field.blocks.image.name": "Imagem", + "field.blocks.image.placeholder": "Selecionar uma imagem", + "field.blocks.image.ratio": "Proporção ", + "field.blocks.image.url": "URL da imagem", + "field.blocks.line.name": "Linha", + "field.blocks.list.name": "Lista", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Texto", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Citação ", + "field.blocks.quote.text.label": "Texto", + "field.blocks.quote.text.placeholder": "Citação …", + "field.blocks.quote.citation.label": "Citação ", + "field.blocks.quote.citation.placeholder": "de …", + "field.blocks.text.name": "Texto", + "field.blocks.text.placeholder": "Texto …", + "field.blocks.video.caption": "Legenda", + "field.blocks.video.name": "Vídeo ", + "field.blocks.video.placeholder": "Entre uma URL de vídeo ", + "field.blocks.video.url.label": "URL-Vídeo", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Nenhum arquivo selecionado", + + "field.layout.delete": "Deletar layout", + "field.layout.delete.confirm": "Deseja realmente deletar este layout?", + "field.layout.empty": "Nenhuma linha", + "field.layout.select": "Selecionar um layout", + + "field.object.empty": "No information yet", + + "field.pages.empty": "Nenhuma página selecionada", + + "field.structure.delete.confirm": "Deseja realmente deletar esta linha?", + "field.structure.empty": "Nenhum registro", + + "field.users.empty": "Nenhum usuário selecionado", + + "file.blueprint": "Este arquivo não tem planta. Você pode definir sua planta em /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Deseja realmente deletar
{filename}?", + "file.sort": "Mudar posição", + + "files": "Arquivos", + "files.empty": "Nenhum arquivo", + + "hide": "Ocultar", + "hour": "Hora", + "import": "Importar", + "info": "Info", + "insert": "Inserir", + "insert.after": "Inserir após", + "insert.before": "Inserir antes", + "install": "Instalar", + + "installation": "Instalação", + "installation.completed": "Painel instalado com sucesso", + "installation.disabled": "O instalador do painel está desabilitado em servidores públicos por padrão. Por favor, execute o instalador em uma máquina local ou habilite a opção panel.install.", + "installation.issues.accounts": "A pasta /site/accounts não existe ou não possui permissão de escrita", + "installation.issues.content": "A pasta /content não existe ou não possui permissão de escrita", + "installation.issues.curl": "A extensão CURL é necessária", + "installation.issues.headline": "O painel não pôde ser instalado", + "installation.issues.mbstring": "A extensão MB String é necessária", + "installation.issues.media": "A pasta /media não existe ou não possui permissão de escrita", + "installation.issues.php": "Certifique-se que você está usando o PHP 7+", + "installation.issues.server": "Kirby necessita do Apache, Nginx ou Caddy", + "installation.issues.sessions": "A pasta /site/sessions não existe ou não possui permissão de escrita", + + "language": "Idioma", + "language.code": "Código", + "language.convert": "Tornar padrão", + "language.convert.confirm": "

Deseja realmente converter {name} para o idioma padrão? Esta ação não poderá ser revertida.

Se {name} tiver conteúdo não traduzido, partes do seu site poderão ficar sem conteúdo.

", + "language.create": "Adicionar novo idioma", + "language.delete.confirm": "Deseja realmente deletar o idioma {name} incluíndo todas as traduções. Esta ação não poderá ser revertida!", + "language.deleted": "Idioma deletado", + "language.direction": "Direção de leitura", + "language.direction.ltr": "Esquerda para direita", + "language.direction.rtl": "Direita para esquerda", + "language.locale": "String de localização do PHP", + "language.locale.warning": "Você está usando uma configuração de local customizada. Por favor modifique a configuração no arquivo do idioma em /site/languages", + "language.name": "Nome", + "language.updated": "Idioma atualizado", + + "languages": "Idiomas", + "languages.default": "Idioma padrão", + "languages.empty": "Nenhum idioma", + "languages.secondary": "Idiomas secundários", + "languages.secondary.empty": "Nenhum idioma secundário", + + "license": "Licen\u00e7a do Kirby ", + "license.buy": "Comprar licença", + "license.register": "Registrar", + "license.manage": "Manage your licenses", + "license.register.help": "Você recebeu o código da sua licença por email ao efetuar sua compra. Por favor, copie e cole o código para completar seu registro.", + "license.register.label": "Por favor, digite o código da sua licença", + "license.register.success": "Obrigado por apoiar o Kirby", + "license.unregistered": "Esta é uma cópia de demonstração não registrada do Kirby", + "license.unregistered.label": "Unregistered", + + "link": "Link", + "link.text": "Texto do link", + + "loading": "Carregando", + + "lock.unsaved": "Mudanças não salvas", + "lock.unsaved.empty": "Não há mais mudanças não salvas", + "lock.isLocked": "Mudanças não salvas por {email}", + "lock.file.isLocked": "Este arquivo está sendo editado no momento por {email}, e não pode ser mudado", + "lock.page.isLocked": "Esta página está sendo editada no momento por {email}, e não pode ser mudada", + "lock.unlock": "Destrancar", + "lock.isUnlocked": "Suas mudanças não salvas foram alteradas por outro usuário, e serão perdidas. Você pode baixar um arquivo com suas mudanças, para depois fundi-las manualmente. ", + + "login": "Entrar", + "login.code.label.login": "Código de acesso", + "login.code.label.password-reset": "Código de redefinição de senha", + "login.code.placeholder.email": "000 0000", + "login.code.text.email": "Se seu endereço de email está registrado, o código requisitado será mandado por email.", + "login.email.login.body": "Oi, {user.nameOrEmail},\n\nVocê recentemente pediu um código de acesso ao painel administrativo do site {site}.\nO seguinte código será válido por {timeout} minutos:\n\n{code}\n\nSe você não pediu este código de acesso, por favor ignore esta mensagem, ou contate seu Administrador de Sistemas se você tiver dúvidas.\nPor questões de segurança, por favor NÃO compartilhe esta mensagem.", + "login.email.login.subject": "Seu código de acesso", + "login.email.password-reset.body": "Oi, {user.nameOrEmail},\n\nVocê recentemente pediu um código de redefinição de senha, para o painel administrativo do site {site}.\nO seguinte código de redefinição de senha será válido por {timeout} minutos:\n\n{code}\n\nSe você não pediu este código, por favor ignore esta mensagem, ou contate seu Administrador de Sistemas se você tiver dúvidas.\nPor questões de segurança, por favor NÃO compartilhe esta mensagem.", + "login.email.password-reset.subject": "Seu código de redefinição de senha", + "login.remember": "Manter-me conectado", + "login.reset": "Redefinir senha", + "login.toggleText.code.email": "Entrar com email", + "login.toggleText.code.email-password": "Entrar com senha", + "login.toggleText.password-reset.email": "Esqueceu sua senha?", + "login.toggleText.password-reset.email-password": "← Voltar à entrada", + + "logout": "Sair", + + "menu": "Menu", + "meridiem": "AM/PM", + "mime": "Tipo de mídia", + "minutes": "Minutos", + + "month": "Mês", + "months.april": "Abril", + "months.august": "Agosto", + "months.december": "Dezembro", + "months.february": "Fevereiro", + "months.january": "Janeiro", + "months.july": "Julho", + "months.june": "Junho", + "months.march": "Mar\u00e7o", + "months.may": "Maio", + "months.november": "Novembro", + "months.october": "Outubro", + "months.september": "Setembro", + + "more": "Mais", + "name": "Nome", + "next": "Próximo", + "no": "não", + "off": "não", + "on": "sim", + "open": "Abrir", + "open.newWindow": "Abrir em nova janela", + "options": "Opções", + "options.none": "Nenhuma opção", + + "orientation": "Orientação", + "orientation.landscape": "Paisagem", + "orientation.portrait": "Retrato", + "orientation.square": "Quadrado", + + "page.blueprint": "Esta página não tem planta. Você pode definir sua planta em /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Alterar URL", + "page.changeSlug.fromTitle": "Criar a partir do t\u00edtulo", + "page.changeStatus": "Alterar estado", + "page.changeStatus.position": "Selecione uma posição", + "page.changeStatus.select": "Selecione um novo estado", + "page.changeTemplate": "Alterar tema", + "page.delete.confirm": "Deseja realmente deletar {title}?", + "page.delete.confirm.subpages": "Esta página possui subpáginas.
Todas as subpáginas serão excluídas também.", + "page.delete.confirm.title": "Digite o título da página para confirmar", + "page.draft.create": "Criar rascunho", + "page.duplicate.appendix": "Copiar", + "page.duplicate.files": "Copiar arquivos", + "page.duplicate.pages": "Copiar páginas", + "page.sort": "Mudar posição", + "page.status": "Estado", + "page.status.draft": "Rascunho", + "page.status.draft.description": "A página é um rascunho, e visível somente por editores logados, ou através de um link secreto.", + "page.status.listed": "Pública", + "page.status.listed.description": "A página pública é visível para todos", + "page.status.unlisted": "Não listadas", + "page.status.unlisted.description": "Esta página é acessível somente através da URL", + + "pages": "Páginas", + "pages.empty": "Nenhuma página", + "pages.status.draft": "Rascunhos", + "pages.status.listed": "Publicadas", + "pages.status.unlisted": "Não listadas", + + "pagination.page": "Página", + + "password": "Senha", + "paste": "Colar", + "paste.after": "Colar após", + "pixel": "Pixel", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "Anterior", + "preview": "Visualizar", + "remove": "Remover", + "rename": "Renomear", + "replace": "Substituir", + "retry": "Tentar novamente", + "revert": "Descartar", + "revert.confirm": "Deseja realmente deletar todas as mudanças não salvas?", + + "role": "Papel", + "role.admin.description": "O administrador tem todos os direitos", + "role.admin.title": "Administrador", + "role.all": "Todos", + "role.empty": "Não há usuários com este papel", + "role.description.placeholder": "Sem descrição", + "role.nobody.description": "Este é um papel atribuído por padrão, sem nenhuma permissão", + "role.nobody.title": "Ninguém", + + "save": "Salvar", + "search": "Buscar", + "search.min": "Digite {min} caracteres para fazer uma busca", + "search.all": "Mostrar todos", + "search.results.none": "Nenhum resultado", + + "section.required": "Esta seção é obrigatória", + + "security": "Security", + "select": "Selecionar", + "server": "Servidor", + "settings": "Configurações", + "show": "Mostrar", + "site.blueprint": "Este site não tem planta. Você pode definir sua planta em /site/blueprints/site.yml", + "size": "Tamanho", + "slug": "Anexo de URL", + "sort": "Ordenar", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Título", + "template": "Tema", + "today": "Hoje", + + "toolbar.button.code": "Código", + "toolbar.button.bold": "Negrito", + "toolbar.button.email": "Email", + "toolbar.button.headings": "Títulos", + "toolbar.button.heading.1": "Título 1", + "toolbar.button.heading.2": "Título 2", + "toolbar.button.heading.3": "Título 3", + "toolbar.button.heading.4": "Título 4", + "toolbar.button.heading.5": "Título 5", + "toolbar.button.heading.6": "Título 6", + "toolbar.button.italic": "Itálico", + "toolbar.button.file": "Arquivo", + "toolbar.button.file.select": "Selecionar arquivo", + "toolbar.button.file.upload": "Carregar arquivo", + "toolbar.button.link": "Link", + "toolbar.button.paragraph": "Parágrafo", + "toolbar.button.strike": "Riscado", + "toolbar.button.ol": "Lista ordenada", + "toolbar.button.underline": "Sublinhado", + "toolbar.button.ul": "Lista não-ordenada", + + "translation.author": "Time Kirby", + "translation.direction": "ltr", + "translation.name": "Português do Brasil", + "translation.locale": "pt_BR", + + "upload": "Enviar", + "upload.error.cantMove": "O arquivo carregado não pôde ser movido", + "upload.error.cantWrite": "Falha ao escrever o arquivo no disco", + "upload.error.default": "O arquivo não pode ser carregado", + "upload.error.extension": "O carregamento do arquivo foi interrompido por causa da extensão", + "upload.error.formSize": "O arquivo carregado excede a diretiva de MAX_FILE_SIZE especificada no formulário", + "upload.error.iniPostSize": "O arquivo carregado excede a diretiva post_max_size do php.ini", + "upload.error.iniSize": "O arquivo carregado excede a diretiva upload_max_size do php.ini", + "upload.error.noFile": "Nenhum arquivo foi carregado", + "upload.error.noFiles": "Nenhum arquivo foi carregado", + "upload.error.partial": "O arquivo foi só parcialmente carregado", + "upload.error.tmpDir": "Falta uma pasta temporária", + "upload.errors": "Erro", + "upload.progress": "Enviando…", + + "url": "Url", + "url.placeholder": "https://example.com", + + "user": "Usuário", + "user.blueprint": "Você pode definir seções e campos de formulário adicionais para este papel de usuário em /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Alterar email", + "user.changeLanguage": "Alterar idioma", + "user.changeName": "Renomear usuário", + "user.changePassword": "Alterar senha", + "user.changePassword.new": "Nova senha", + "user.changePassword.new.confirm": "Confirme a nova senha…", + "user.changeRole": "Alterar papel", + "user.changeRole.select": "Selecione um novo papel", + "user.create": "Adicionar novo usuário", + "user.delete": "Deletar este usuário", + "user.delete.confirm": "Deseja realmente deletar
{email}?", + + "users": "Usuários", + + "version": "Vers\u00e3o do Kirby", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "Sua conta", + "view.installation": "Instala\u00e7\u00e3o", + "view.languages": "Idiomas", + "view.resetPassword": "Redefinir senha", + "view.site": "Site", + "view.system": "Sistema", + "view.users": "Usu\u00e1rios", + + "welcome": "Bem-vindo", + "year": "Ano", + "yes": "sim" } diff --git a/kirby/i18n/translations/pt_PT.json b/kirby/i18n/translations/pt_PT.json index a2a20f1..ed82386 100644 --- a/kirby/i18n/translations/pt_PT.json +++ b/kirby/i18n/translations/pt_PT.json @@ -1,573 +1,596 @@ { - "account.changeName": "Mudar seu nome", - "account.delete": "Deletar sua conta", - "account.delete.confirm": "Deseja realmente deletar sua conta? Você sairá do site imediatamente. Sua conta não poderá ser recuperada. ", - - "add": "Adicionar", - "author": "Autor", - "avatar": "Foto do perfil", - "back": "Voltar", - "cancel": "Cancelar", - "change": "Alterar", - "close": "Fechar", - "confirm": "Salvar", - "collapse": "Colapsar", - "collapse.all": "Colapsar todos", - "copy": "Copiar", - "copy.all": "Copiar todos", - "create": "Criar", - - "date": "Data", - "date.select": "Selecione uma data", - - "day": "Dia", - "days.fri": "Sex", - "days.mon": "Seg", - "days.sat": "S\u00e1b", - "days.sun": "Dom", - "days.thu": "Qui", - "days.tue": "Ter", - "days.wed": "Qua", - - "debugging": "Depuração ", - - "delete": "Excluir", - "delete.all": "Deletar todos", - - "dialog.files.empty": "Sem arquivos para selecionar", - "dialog.pages.empty": "Sem páginas para selecionar", - "dialog.users.empty": "Sem utilizadores para selecionar", - - "dimensions": "Dimensões", - "disabled": "Inativo", - "discard": "Descartar", - "download": "Descarregar", - "duplicate": "Duplicar", - - "edit": "Editar", - - "email": "Email", - "email.placeholder": "mail@exemplo.pt", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Ambiente", - - "error.access.code": "Código inválido", - "error.access.login": "Login inválido", - "error.access.panel": "Não tem permissões para aceder ao painel", - "error.access.view": "Não tem permissões para aceder a esta área do Painel", - - "error.avatar.create.fail": "A foto de perfil não foi enviada", - "error.avatar.delete.fail": "A foto do perfil não foi excluída", - "error.avatar.dimensions.invalid": "Por favor, use uma foto de perfil com largura e altura menores que 3000 pixels", - "error.avatar.mime.forbidden": "A foto de perfil deve ser um arquivo JPEG ou PNG", - - "error.blueprint.notFound": "O blueprint \"{name}\" não pode ser carregado", - - "error.blocks.max.plural": "Você não deve adicionar mais do que {max} blocos", - "error.blocks.max.singular": "Você não deve adicionar mais do que um bloco", - "error.blocks.min.plural": "Você deve adicionar pelo menos {min} blocos", - "error.blocks.min.singular": "Você deve adicionar pelo menos um bloco", - "error.blocks.validation": "Há um erro no bloco {index}", - - "error.email.preset.notFound": "Preset de email \"{name}\" não encontrado", - - "error.field.converter.invalid": "Conversor \"{converter}\" inválido", - - "error.file.changeName.empty": "O nome não pode ficar em branco", - "error.file.changeName.permission": "Não tem permissões para alterar o nome de \"{filename}\"", - "error.file.duplicate": "Um arquivo com o nome \"{filename}\" já existe", - "error.file.extension.forbidden": "Extensão \"{extension}\" não permitida", - "error.file.extension.invalid": "Extensão inválida: {extension}", - "error.file.extension.missing": "Extensão de \"{filename}\" em falta", - "error.file.maxheight": "A altura da imagem não deve exceder {height} pixels", - "error.file.maxsize": "O arquivo é muito grande", - "error.file.maxwidth": "A largura da imagem não deve exceder {width} pixels", - "error.file.mime.differs": "O arquivo enviado precisa ser do tipo \"{mime}\"", - "error.file.mime.forbidden": "Tipo de mídia \"{mime}\" não permitido", - "error.file.mime.invalid": "Tipo de mídia inválido: {mime}", - "error.file.mime.missing": "Tipo de mídia de \"{filename}\" não detectado", - "error.file.minheight": "A altura da imagem deve ser pelo menos {height} pixels", - "error.file.minsize": "O ficheiro é muito pequeno", - "error.file.minwidth": "A largura da imagem deve ser pelo menos {width} pixels", - "error.file.name.missing": "O nome do arquivo não pode ficar em branco", - "error.file.notFound": "Arquivo \"{filename}\" não encontrado", - "error.file.orientation": "A orientação da imagem deve ser \"{orientation}\"", - "error.file.type.forbidden": "Não tem permissões para enviar arquivos {type}", - "error.file.type.invalid": "Tipo inválido de arquivo: {type}", - "error.file.undefined": "Arquivo n\u00e3o encontrado", - - "error.form.incomplete": "Por favor, corrija os erros do formulário…", - "error.form.notSaved": "O formulário não foi guardado", - - "error.language.code": "Insira um código de idioma válido", - "error.language.duplicate": "O idioma já existe", - "error.language.name": "Insira um nome válido para o idioma", - "error.language.notFound": "O idioma não foi encontrado", - - "error.layout.validation.block": "Há um erro no bloco {blockIndex} no layout {layoutIndex}", - "error.layout.validation.settings": "Há um erro na configuração do layout {index}", - - "error.license.format": "Insira uma chave de licença válida", - "error.license.email": "Digite um endereço de email válido", - "error.license.verification": "Não foi possível verificar a licença", - - "error.offline": "O painel está offline no momento", - - "error.page.changeSlug.permission": "Não tem permissões para alterar a URL de \"{slug}\"", - "error.page.changeStatus.incomplete": "A página possui erros e não pode ser guardada", - "error.page.changeStatus.permission": "O estado desta página não pode ser alterado", - "error.page.changeStatus.toDraft.invalid": "A página \"{slug}\" não pode ser convertida para rascunho", - "error.page.changeTemplate.invalid": "O tema da página \"{slug}\" não pode ser alterado", - "error.page.changeTemplate.permission": "Não tem permissões para alterar o tema de \"{slug}\"", - "error.page.changeTitle.empty": "O título não pode ficar em branco", - "error.page.changeTitle.permission": "Não tem permissões para alterar o título de \"{slug}\"", - "error.page.create.permission": "Não tem permissões para criar \"{slug}\"", - "error.page.delete": "A página \"{slug}\" não pode ser excluída", - "error.page.delete.confirm": "Por favor, digite o título da página para confirmar", - "error.page.delete.hasChildren": "A página possui subpáginas e não pode ser excluída", - "error.page.delete.permission": "Não tem permissões para excluir \"{slug}\"", - "error.page.draft.duplicate": "Um rascunho de página com a URL \"{slug}\" já existe", - "error.page.duplicate": "Uma página com a URL \"{slug}\" já existe", - "error.page.duplicate.permission": "Não tem permissão para duplicar \"{slug}\"", - "error.page.notFound": "Página\"{slug}\" não encontrada", - "error.page.num.invalid": "Digite um número de ordenação válido. Este número não pode ser negativo.", - "error.page.slug.invalid": "Por favor entre um anexo de URL válido ", - "error.page.slug.maxlength": "O slug não pode conter mais do que \"{length}\" caracteres", - "error.page.sort.permission": "A página \"{slug}\" não pode ser ordenada", - "error.page.status.invalid": "Por favor, defina um estado de página válido", - "error.page.undefined": "P\u00e1gina n\u00e3o encontrada", - "error.page.update.permission": "Não tem permissões para atualizar \"{slug}\"", - - "error.section.files.max.plural": "Não pode adicionar mais do que {max} arquivos à seção \"{section}\"", - "error.section.files.max.singular": "Não pode adicionar mais do que um arquivo à seção \"{section}\"", - "error.section.files.min.plural": "A secção \"{section}\" requer no mínimo {min} arquivos", - "error.section.files.min.singular": "A secção \"{section}\" requer no mínimo um arquivo", - - "error.section.pages.max.plural": "Não pode adicionar mais do que {max} página à seção \"{section}\"", - "error.section.pages.max.singular": "Não pode adicionar mais do que uma página à seção \"{section}\"", - "error.section.pages.min.plural": "A secção \"{section}\" requer no mínimo {min} páginas", - "error.section.pages.min.singular": "A secção \"{section}\" requer no mínimo uma página", - - "error.section.notLoaded": "A seção \"{name}\" não pôde ser carregada", - "error.section.type.invalid": "O tipo da seção \"{type}\" não é válido", - - "error.site.changeTitle.empty": "O título não pode ficar em branco", - "error.site.changeTitle.permission": "Não tem permissões para alterar o título do site", - "error.site.update.permission": "Não tem permissões para atualizar o site", - - "error.template.default.notFound": "O tema padrão não existe", - - "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Não tem permissões para alterar o email do utilizador \"{name}\"", - "error.user.changeLanguage.permission": "Não tem permissões para alterar o idioma do utilizador \"{name}\"", - "error.user.changeName.permission": "Não tem permissões para alterar o nome do utilizador \"{name}\"", - "error.user.changePassword.permission": "Não tem permissões para alterar a palavra-passe do utilizador \"{name}\"", - "error.user.changeRole.lastAdmin": "A função do último administrador não pode ser alterado", - "error.user.changeRole.permission": "Não tem permissões para alterar a função do utilizador \"{name}\"", - "error.user.changeRole.toAdmin": "Não tem permissões para promover utilizadores à função de administrador", - "error.user.create.permission": "Não tem permissões para criar este utilizador", - "error.user.delete": "O utilizador \"{name}\" não pode ser excluído", - "error.user.delete.lastAdmin": "O último administrador não pode ser excluído", - "error.user.delete.lastUser": "O último utilizador não pode ser excluído", - "error.user.delete.permission": "Não tem permissões para excluir o utilizador \"{name}\"", - "error.user.duplicate": "Um utilizador com o email \"{email}\" já existe", - "error.user.email.invalid": "Digite um endereço de email válido", - "error.user.language.invalid": "Digite um idioma válido", - "error.user.notFound": "Utilizador \"{name}\" não encontrado", - "error.user.password.invalid": "Digite uma palavra-passe válida. A sua palavra-passe deve ter pelo menos 8 caracteres.", - "error.user.password.notSame": "As palavras-passe não combinam", - "error.user.password.undefined": "O utilizador não possui uma palavra-passe", - "error.user.password.wrong": "Senha errada", - "error.user.role.invalid": "Digite uma função válida", - "error.user.undefined": "Usuário não encontrado", - "error.user.update.permission": "Não tem permissões para atualizar o utilizador \"{name}\"", - - "error.validation.accepted": "Por favor, confirme", - "error.validation.alpha": "Por favor, use apenas caracteres entre a-z", - "error.validation.alphanum": "Por favor, use apenas caracteres entre a-z ou 0-9", - "error.validation.between": "Digite um valor entre \"{min}\" e \"{max}\"", - "error.validation.boolean": "Por favor, confirme ou rejeite", - "error.validation.contains": "Digite um valor que contenha \"{needle}\"", - "error.validation.date": "Escolha uma data válida", - "error.validation.date.after": "Escolha uma data posterior a {date}", - "error.validation.date.before": "Escolha uma data anterior a {date}", - "error.validation.date.between": "Escolha uma data compreendida entre {min} e {max}", - "error.validation.denied": "Por favor, cancele", - "error.validation.different": "O valor deve ser diferente de \"{other}\"", - "error.validation.email": "Digite um endereço de email válido", - "error.validation.endswith": "O valor deve terminar com \"{end}\"", - "error.validation.filename": "Digite um nome de arquivo válido", - "error.validation.in": "Digite um destes valores: ({in})", - "error.validation.integer": "Digite um número inteiro válido", - "error.validation.ip": "Digite um endereço de IP válido", - "error.validation.less": "Digite um valor menor que {max}", - "error.validation.match": "O valor não combina com o padrão esperado", - "error.validation.max": "Digite um valor igual ou menor que {max}", - "error.validation.maxlength": "Digite um valor curto. (no máximo {max} caracteres)", - "error.validation.maxwords": "Digite menos que {max} palavra(s)", - "error.validation.min": "Digite um valor igual ou maior que {min}", - "error.validation.minlength": "Digite um valor maior. (no mínimo {min} caracteres)", - "error.validation.minwords": "Digite ao menos {min} palavra(s)", - "error.validation.more": "Digite um valor maior que {min}", - "error.validation.notcontains": "Digite um valor que não contenha \"{needle}\"", - "error.validation.notin": "Não digite nenhum destes valores: ({notIn})", - "error.validation.option": "Escolha uma opção válida", - "error.validation.num": "Digite um número válido", - "error.validation.required": "Digite algo", - "error.validation.same": "Por favor, digite \"{other}\"", - "error.validation.size": "O tamanho do valor deve ser \"{size}\"", - "error.validation.startswith": "O valor deve começar com \"{start}\"", - "error.validation.time": "Digite uma hora válida", - "error.validation.time.after": "Por favor entre um horário depois de {time}", - "error.validation.time.before": "Por favor entre um horário antes de {time}", - "error.validation.time.between": "Por favor entre um horário entre {min} e {max}", - "error.validation.url": "Digite uma URL válida", - - "expand": "Expandir", - "expand.all": "Expandir todos", - - "field.required": "Este campo é necessário", - "field.blocks.changeType": "Mudar tipo", - "field.blocks.code.name": "Código", - "field.blocks.code.language": "Idioma", - "field.blocks.code.placeholder": "Seu código …", - "field.blocks.delete.confirm": "Deseja realmente deletar este bloco?", - "field.blocks.delete.confirm.all": "Deseja realmente deletar todos os blocos?", - "field.blocks.delete.confirm.selected": "Deseja realmente deletar os blocos selecionados?", - "field.blocks.empty": "Nenhum bloco", - "field.blocks.fieldsets.label": "Por favor selecione um tipo de bloco …", - "field.blocks.fieldsets.paste": "Digite {{ shortcut }} para colar/importar blocos da sua área de transferência ", - "field.blocks.gallery.name": "Galeria", - "field.blocks.gallery.images.empty": "Nenhuma imagem", - "field.blocks.gallery.images.label": "Imagens", - "field.blocks.heading.level": "Nível ", - "field.blocks.heading.name": "Título ", - "field.blocks.heading.text": "Texto", - "field.blocks.heading.placeholder": "Título …", - "field.blocks.image.alt": "Texto alternativo", - "field.blocks.image.caption": "Legenda", - "field.blocks.image.crop": "Cortar", - "field.blocks.image.link": "Link", - "field.blocks.image.location": "Localização ", - "field.blocks.image.name": "Imagem", - "field.blocks.image.placeholder": "Selecionar uma imagem", - "field.blocks.image.ratio": "Proporção ", - "field.blocks.image.url": "URL da imagem", - "field.blocks.line.name": "Linha", - "field.blocks.list.name": "Lista", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Texto", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Citação ", - "field.blocks.quote.text.label": "Texto", - "field.blocks.quote.text.placeholder": "Citação …", - "field.blocks.quote.citation.label": "Citação ", - "field.blocks.quote.citation.placeholder": "de …", - "field.blocks.text.name": "Texto", - "field.blocks.text.placeholder": "Texto …", - "field.blocks.video.caption": "Legenda", - "field.blocks.video.name": "Vídeo ", - "field.blocks.video.placeholder": "Entre uma URL de vídeo ", - "field.blocks.video.url.label": "URL-Vídeo", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Nenhum arquivo selecionado", - - "field.layout.delete": "Deletar layout", - "field.layout.delete.confirm": "Deseja realmente deletar este layout?", - "field.layout.empty": "Nenhuma linha", - "field.layout.select": "Selecionar um layout", - - "field.pages.empty": "Nenhuma página selecionada", - "field.structure.delete.confirm": "Deseja realmente excluir este registro?", - "field.structure.empty": "Nenhum registro", - "field.users.empty": "Nenhum utilizador selecionado", - - "file.blueprint": "Este arquivo não tem planta. Você pode definir sua planta em /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Deseja realmente excluir
{filename}?", - "file.sort": "Mudar posição", - - "files": "Arquivos", - "files.empty": "Nenhum arquivo", - - "hide": "Ocultar", - "hour": "Hora", - "import": "Importar", - "info": "Info", - "insert": "Inserir", - "insert.after": "Inserir após", - "insert.before": "Inserir antes", - "install": "Instalar", - - "installation": "Instalação", - "installation.completed": "Painel instalado com sucesso", - "installation.disabled": "Por padrão, o instalador do painel está desabilitado em servidores públicos. Por favor, execute o instalador numa máquina local ou habilite a opção panel.install.", - "installation.issues.accounts": "A pasta /site/accounts não existe ou não possui permissão de escrita", - "installation.issues.content": "A pasta /content não existe ou não possui permissão de escrita", - "installation.issues.curl": "A extensão CURL é necessária", - "installation.issues.headline": "O painel não pôde ser instalado", - "installation.issues.mbstring": "A extensão MB String é necessária", - "installation.issues.media": "A pasta /media não existe ou não possui permissão de escrita", - "installation.issues.php": "Certifique-se que está a usar o PHP 7+", - "installation.issues.server": "O Kirby necessita do Apache, Nginx ou Caddy", - "installation.issues.sessions": "A pasta /site/sessions não existe ou não possui permissão de escrita", - - "language": "Idioma", - "language.code": "Código", - "language.convert": "Tornar padrão", - "language.convert.confirm": "

Deseja realmente converter {name} para o idioma padrão? Esta ação não poderá ser revertida.

Se {name} tiver conteúdo não traduzido, partes do seu site poderão ficar sem conteúdo.

", - "language.create": "Adicionar novo idioma", - "language.delete.confirm": "Deseja realmente excluir o idioma {name} incluíndo todas as traduções? Esta ação não poderá ser revertida!", - "language.deleted": "Idioma excluído", - "language.direction": "Direção de leitura", - "language.direction.ltr": "Esquerda para direita", - "language.direction.rtl": "Direita para esquerda", - "language.locale": "String de localização do PHP", - "language.locale.warning": "Está a usar configurações de localização personalizadas. Corrija as mesmas no ficheiro /site/languages", - "language.name": "Nome", - "language.updated": "Idioma atualizado", - - "languages": "Idiomas", - "languages.default": "Idioma padrão", - "languages.empty": "Nenhum idioma", - "languages.secondary": "Idiomas secundários", - "languages.secondary.empty": "Nenhum idioma secundário", - - "license": "Licen\u00e7a do Kirby ", - "license.buy": "Comprar uma licença", - "license.register": "Registrar", - "license.manage": "Manage your licenses", - "license.register.help": "Recebeu o código da sua licença por email após a compra. Por favor, copie e cole-o para completar o registro.", - "license.register.label": "Por favor, digite o código da sua licença", - "license.register.success": "Obrigado por apoiar o Kirby", - "license.unregistered": "Esta é uma demonstração não registrada do Kirby", - "license.unregistered.label": "Unregistered", - - "link": "Link", - "link.text": "Texto do link", - - "loading": "A carregar", - - "lock.unsaved": "Alterações por guardar", - "lock.unsaved.empty": "Não existem alterações por guardar", - "lock.isLocked": "Alterações por guardar de {email}", - "lock.file.isLocked": "O arquivo está a ser editado por {email} e não pode ser alterado.", - "lock.page.isLocked": "A página está a ser editada por {email} e não pode ser alterada.", - "lock.unlock": "Desbloquear", - "lock.isUnlocked": "As suas alterações foram sobrepostas por outro utilizador. Pode descarregar as suas alterações e combiná-las manualmente.", - - "login": "Entrar", - "login.code.label.login": "Código de acesso", - "login.code.label.password-reset": "Código de redefinição de senha", - "login.code.placeholder.email": "000 0000", - "login.code.text.email": "Se seu endereço de email está registrado, o código requisitado será mandado por email.", - "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.login.subject": "Seu código de acesso", - "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.password-reset.subject": "Seu código de redefinição de senha", - "login.remember": "Manter-me conectado", - "login.reset": "Redefinir senha", - "login.toggleText.code.email": "Entrar com email", - "login.toggleText.code.email-password": "Entrar com senha", - "login.toggleText.password-reset.email": "Esqueceu sua senha?", - "login.toggleText.password-reset.email-password": "← Voltar à entrada", - - "logout": "Sair", - - "menu": "Menu", - "meridiem": "AM/PM", - "mime": "Tipo de mídia", - "minutes": "Minutos", - - "month": "Mês", - "months.april": "Abril", - "months.august": "Agosto", - "months.december": "Dezembro", - "months.february": "Fevereiro", - "months.january": "Janeiro", - "months.july": "Julho", - "months.june": "Junho", - "months.march": "Mar\u00e7o", - "months.may": "Maio", - "months.november": "Novembro", - "months.october": "Outubro", - "months.september": "Setembro", - - "more": "Mais", - "name": "Nome", - "next": "Próximo", - "no": "não", - "off": "off", - "on": "on", - "open": "Abrir", - "open.newWindow": "Abrir em nova janela", - "options": "Opções", - "options.none": "Sem opções", - - "orientation": "Orientação", - "orientation.landscape": "Paisagem", - "orientation.portrait": "Retrato", - "orientation.square": "Quadrado", - - "page.blueprint": "Esta página não tem planta. Você pode definir sua planta em /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Alterar URL", - "page.changeSlug.fromTitle": "Criar a partir do t\u00edtulo", - "page.changeStatus": "Alterar estado", - "page.changeStatus.position": "Selecione uma posição", - "page.changeStatus.select": "Selecione um novo estado", - "page.changeTemplate": "Alterar tema", - "page.delete.confirm": "Deseja realmente excluir {title}?", - "page.delete.confirm.subpages": "Esta página possui subpáginas.
Todas as subpáginas serão excluídas também.", - "page.delete.confirm.title": "Digite o título da página para confirmar", - "page.draft.create": "Criar rascunho", - "page.duplicate.appendix": "Copiar", - "page.duplicate.files": "Copiar arquivos", - "page.duplicate.pages": "Copiar páginas", - "page.sort": "Mudar posição", - "page.status": "Estado", - "page.status.draft": "Rascunho", - "page.status.draft.description": "A página está em modo de rascunho e é visível somente para editores", - "page.status.listed": "Pública", - "page.status.listed.description": "A página é pública para todos", - "page.status.unlisted": "Não listadas", - "page.status.unlisted.description": "Esta página é acessível somente através da URL", - - "pages": "Páginas", - "pages.empty": "Nenhuma página", - "pages.status.draft": "Rascunhos", - "pages.status.listed": "Publicadas", - "pages.status.unlisted": "Não listadas", - - "pagination.page": "Página", - - "password": "Palavra-passe", - "paste": "Colar", - "paste.after": "Colar após", - "pixel": "Pixel", - "plugins": "Plugins", - "prev": "Anterior", - "preview": "Visualizar", - "remove": "Remover", - "rename": "Renomear", - "replace": "Substituir", - "retry": "Tentar novamente", - "revert": "Descartar", - "revert.confirm": "Tem a certeza que pretende eliminar todas as alterações por guardar?", - - "role": "Função", - "role.admin.description": "O administrador tem todas as permissões.", - "role.admin.title": "Administrador", - "role.all": "Todos", - "role.empty": "Não há utilizadores com esta função", - "role.description.placeholder": "Sem descrição", - "role.nobody.description": "Esta é uma função de salvaguarda sem permissões.", - "role.nobody.title": "Ninguém", - - "save": "Salvar", - "search": "Buscar", - "search.min": "Introduza {min} caracteres para pesquisar", - "search.all": "Mostrar todos", - "search.results.none": "Sem resultados", - - "section.required": "Esta seção é necessária", - - "security": "Security", - "select": "Selecionar", - "server": "Servidor", - "settings": "Configurações", - "show": "Mostrar", - "site.blueprint": "Este site não tem planta. Você pode definir sua planta em /site/blueprints/site.yml", - "size": "Tamanho", - "slug": "URL", - "sort": "Ordenar", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Título", - "template": "Tema", - "today": "Hoje", - - "toolbar.button.code": "Código", - "toolbar.button.bold": "Negrito", - "toolbar.button.email": "Email", - "toolbar.button.headings": "Títulos", - "toolbar.button.heading.1": "Título 1", - "toolbar.button.heading.2": "Título 2", - "toolbar.button.heading.3": "Título 3", - "toolbar.button.heading.4": "Título 4", - "toolbar.button.heading.5": "Título 5", - "toolbar.button.heading.6": "Título 6", - "toolbar.button.italic": "Itálico", - "toolbar.button.file": "Ficheiro", - "toolbar.button.file.select": "Selecione o arquivo", - "toolbar.button.file.upload": "Carregue o arquivo", - "toolbar.button.link": "Link", - "toolbar.button.paragraph": "Parágrafo", - "toolbar.button.strike": "Riscado", - "toolbar.button.ol": "Lista ordenada", - "toolbar.button.underline": "Sublinhado", - "toolbar.button.ul": "Lista não-ordenada", - - "translation.author": "Kirby Team", - "translation.direction": "ltr", - "translation.name": "Português (Europeu)", - "translation.locale": "pt_PT", - - "upload": "Enviar", - "upload.error.cantMove": "Não foi possível mover o arquivo carregado", - "upload.error.cantWrite": "Não foi possível guardar o arquivo no sistema de ficheiros.", - "upload.error.default": "Não foi possível carregar o arquivo", - "upload.error.extension": "A extensão do arquivo não permite o carregamento", - "upload.error.formSize": "O arquivo excede o tamanho MAX_FILE_SIZE", - "upload.error.iniPostSize": "O arquivo excede o tamanho post_max_size", - "upload.error.iniSize": "O arquivo carregado excede a definição upload_max_filesize do php.ini", - "upload.error.noFile": "Nenhum arquivo carregado", - "upload.error.noFiles": "Nenhuns arquivos carregados", - "upload.error.partial": "O arquivo foi parcialmente carregado", - "upload.error.tmpDir": "Pasta temporária em falta", - "upload.errors": "Erro", - "upload.progress": "A enviar…", - - "url": "Url", - "url.placeholder": "https://exemplo.pt", - - "user": "Utilizador", - "user.blueprint": "Você pode definir seções e campos de formulário adicionais para este papel de usuário em /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Alterar email", - "user.changeLanguage": "Alterar idioma", - "user.changeName": "Renomear este utilizador", - "user.changePassword": "Alterar palavra-passe", - "user.changePassword.new": "Nova palavra-passe", - "user.changePassword.new.confirm": "Confirme a nova palavra-passe…", - "user.changeRole": "Alterar Função", - "user.changeRole.select": "Selecione uma nova função", - "user.create": "Adicionar novo utilizador", - "user.delete": "Excluir este utilizador", - "user.delete.confirm": "Deseja realmente excluir
{email}?", - - "users": "Utilizadores", - - "version": "Vers\u00e3o do Kirby", - - "view.account": "A sua conta", - "view.installation": "Instala\u00e7\u00e3o", - "view.languages": "Idiomas", - "view.resetPassword": "Redefinir senha", - "view.site": "Site", - "view.system": "Sistema", - "view.users": "Utilizadores", - - "welcome": "Bem-vindo", - "year": "Ano", - "yes": "sim" + "account.changeName": "Mudar seu nome", + "account.delete": "Deletar sua conta", + "account.delete.confirm": "Deseja realmente deletar sua conta? Você sairá do site imediatamente. Sua conta não poderá ser recuperada. ", + + "add": "Adicionar", + "author": "Autor", + "avatar": "Foto do perfil", + "back": "Voltar", + "cancel": "Cancelar", + "change": "Alterar", + "close": "Fechar", + "confirm": "Salvar", + "collapse": "Colapsar", + "collapse.all": "Colapsar todos", + "copy": "Copiar", + "copy.all": "Copiar todos", + "create": "Criar", + + "date": "Data", + "date.select": "Selecione uma data", + + "day": "Dia", + "days.fri": "Sex", + "days.mon": "Seg", + "days.sat": "S\u00e1b", + "days.sun": "Dom", + "days.thu": "Qui", + "days.tue": "Ter", + "days.wed": "Qua", + + "debugging": "Depuração ", + + "delete": "Excluir", + "delete.all": "Deletar todos", + + "dialog.files.empty": "Sem arquivos para selecionar", + "dialog.pages.empty": "Sem páginas para selecionar", + "dialog.users.empty": "Sem utilizadores para selecionar", + + "dimensions": "Dimensões", + "disabled": "Inativo", + "discard": "Descartar", + "download": "Descarregar", + "duplicate": "Duplicar", + + "edit": "Editar", + + "email": "Email", + "email.placeholder": "mail@exemplo.pt", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Ambiente", + + "error.access.code": "Código inválido", + "error.access.login": "Login inválido", + "error.access.panel": "Não tem permissões para aceder ao painel", + "error.access.view": "Não tem permissões para aceder a esta área do Painel", + + "error.avatar.create.fail": "A foto de perfil não foi enviada", + "error.avatar.delete.fail": "A foto do perfil não foi excluída", + "error.avatar.dimensions.invalid": "Por favor, use uma foto de perfil com largura e altura menores que 3000 pixels", + "error.avatar.mime.forbidden": "A foto de perfil deve ser um arquivo JPEG ou PNG", + + "error.blueprint.notFound": "O blueprint \"{name}\" não pode ser carregado", + + "error.blocks.max.plural": "Você não deve adicionar mais do que {max} blocos", + "error.blocks.max.singular": "Você não deve adicionar mais do que um bloco", + "error.blocks.min.plural": "Você deve adicionar pelo menos {min} blocos", + "error.blocks.min.singular": "Você deve adicionar pelo menos um bloco", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "Preset de email \"{name}\" não encontrado", + + "error.field.converter.invalid": "Conversor \"{converter}\" inválido", + + "error.file.changeName.empty": "O nome não pode ficar em branco", + "error.file.changeName.permission": "Não tem permissões para alterar o nome de \"{filename}\"", + "error.file.duplicate": "Um arquivo com o nome \"{filename}\" já existe", + "error.file.extension.forbidden": "Extensão \"{extension}\" não permitida", + "error.file.extension.invalid": "Extensão inválida: {extension}", + "error.file.extension.missing": "Extensão de \"{filename}\" em falta", + "error.file.maxheight": "A altura da imagem não deve exceder {height} pixels", + "error.file.maxsize": "O arquivo é muito grande", + "error.file.maxwidth": "A largura da imagem não deve exceder {width} pixels", + "error.file.mime.differs": "O arquivo enviado precisa ser do tipo \"{mime}\"", + "error.file.mime.forbidden": "Tipo de mídia \"{mime}\" não permitido", + "error.file.mime.invalid": "Tipo de mídia inválido: {mime}", + "error.file.mime.missing": "Tipo de mídia de \"{filename}\" não detectado", + "error.file.minheight": "A altura da imagem deve ser pelo menos {height} pixels", + "error.file.minsize": "O ficheiro é muito pequeno", + "error.file.minwidth": "A largura da imagem deve ser pelo menos {width} pixels", + "error.file.name.missing": "O nome do arquivo não pode ficar em branco", + "error.file.notFound": "Arquivo \"{filename}\" não encontrado", + "error.file.orientation": "A orientação da imagem deve ser \"{orientation}\"", + "error.file.type.forbidden": "Não tem permissões para enviar arquivos {type}", + "error.file.type.invalid": "Tipo inválido de arquivo: {type}", + "error.file.undefined": "Arquivo n\u00e3o encontrado", + + "error.form.incomplete": "Por favor, corrija os erros do formulário…", + "error.form.notSaved": "O formulário não foi guardado", + + "error.language.code": "Insira um código de idioma válido", + "error.language.duplicate": "O idioma já existe", + "error.language.name": "Insira um nome válido para o idioma", + "error.language.notFound": "O idioma não foi encontrado", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "Há um erro na configuração do layout {index}", + + "error.license.format": "Insira uma chave de licença válida", + "error.license.email": "Digite um endereço de email válido", + "error.license.verification": "Não foi possível verificar a licença", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "O painel está offline no momento", + + "error.page.changeSlug.permission": "Não tem permissões para alterar a URL de \"{slug}\"", + "error.page.changeStatus.incomplete": "A página possui erros e não pode ser guardada", + "error.page.changeStatus.permission": "O estado desta página não pode ser alterado", + "error.page.changeStatus.toDraft.invalid": "A página \"{slug}\" não pode ser convertida para rascunho", + "error.page.changeTemplate.invalid": "O tema da página \"{slug}\" não pode ser alterado", + "error.page.changeTemplate.permission": "Não tem permissões para alterar o tema de \"{slug}\"", + "error.page.changeTitle.empty": "O título não pode ficar em branco", + "error.page.changeTitle.permission": "Não tem permissões para alterar o título de \"{slug}\"", + "error.page.create.permission": "Não tem permissões para criar \"{slug}\"", + "error.page.delete": "A página \"{slug}\" não pode ser excluída", + "error.page.delete.confirm": "Por favor, digite o título da página para confirmar", + "error.page.delete.hasChildren": "A página possui subpáginas e não pode ser excluída", + "error.page.delete.permission": "Não tem permissões para excluir \"{slug}\"", + "error.page.draft.duplicate": "Um rascunho de página com a URL \"{slug}\" já existe", + "error.page.duplicate": "Uma página com a URL \"{slug}\" já existe", + "error.page.duplicate.permission": "Não tem permissão para duplicar \"{slug}\"", + "error.page.notFound": "Página\"{slug}\" não encontrada", + "error.page.num.invalid": "Digite um número de ordenação válido. Este número não pode ser negativo.", + "error.page.slug.invalid": "Por favor entre um anexo de URL válido ", + "error.page.slug.maxlength": "O slug não pode conter mais do que \"{length}\" caracteres", + "error.page.sort.permission": "A página \"{slug}\" não pode ser ordenada", + "error.page.status.invalid": "Por favor, defina um estado de página válido", + "error.page.undefined": "P\u00e1gina n\u00e3o encontrada", + "error.page.update.permission": "Não tem permissões para atualizar \"{slug}\"", + + "error.section.files.max.plural": "Não pode adicionar mais do que {max} arquivos à seção \"{section}\"", + "error.section.files.max.singular": "Não pode adicionar mais do que um arquivo à seção \"{section}\"", + "error.section.files.min.plural": "A secção \"{section}\" requer no mínimo {min} arquivos", + "error.section.files.min.singular": "A secção \"{section}\" requer no mínimo um arquivo", + + "error.section.pages.max.plural": "Não pode adicionar mais do que {max} página à seção \"{section}\"", + "error.section.pages.max.singular": "Não pode adicionar mais do que uma página à seção \"{section}\"", + "error.section.pages.min.plural": "A secção \"{section}\" requer no mínimo {min} páginas", + "error.section.pages.min.singular": "A secção \"{section}\" requer no mínimo uma página", + + "error.section.notLoaded": "A seção \"{name}\" não pôde ser carregada", + "error.section.type.invalid": "O tipo da seção \"{type}\" não é válido", + + "error.site.changeTitle.empty": "O título não pode ficar em branco", + "error.site.changeTitle.permission": "Não tem permissões para alterar o título do site", + "error.site.update.permission": "Não tem permissões para atualizar o site", + + "error.template.default.notFound": "O tema padrão não existe", + + "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Não tem permissões para alterar o email do utilizador \"{name}\"", + "error.user.changeLanguage.permission": "Não tem permissões para alterar o idioma do utilizador \"{name}\"", + "error.user.changeName.permission": "Não tem permissões para alterar o nome do utilizador \"{name}\"", + "error.user.changePassword.permission": "Não tem permissões para alterar a palavra-passe do utilizador \"{name}\"", + "error.user.changeRole.lastAdmin": "A função do último administrador não pode ser alterado", + "error.user.changeRole.permission": "Não tem permissões para alterar a função do utilizador \"{name}\"", + "error.user.changeRole.toAdmin": "Não tem permissões para promover utilizadores à função de administrador", + "error.user.create.permission": "Não tem permissões para criar este utilizador", + "error.user.delete": "O utilizador \"{name}\" não pode ser excluído", + "error.user.delete.lastAdmin": "O último administrador não pode ser excluído", + "error.user.delete.lastUser": "O último utilizador não pode ser excluído", + "error.user.delete.permission": "Não tem permissões para excluir o utilizador \"{name}\"", + "error.user.duplicate": "Um utilizador com o email \"{email}\" já existe", + "error.user.email.invalid": "Digite um endereço de email válido", + "error.user.language.invalid": "Digite um idioma válido", + "error.user.notFound": "Utilizador \"{name}\" não encontrado", + "error.user.password.invalid": "Digite uma palavra-passe válida. A sua palavra-passe deve ter pelo menos 8 caracteres.", + "error.user.password.notSame": "As palavras-passe não combinam", + "error.user.password.undefined": "O utilizador não possui uma palavra-passe", + "error.user.password.wrong": "Senha errada", + "error.user.role.invalid": "Digite uma função válida", + "error.user.undefined": "Usuário não encontrado", + "error.user.update.permission": "Não tem permissões para atualizar o utilizador \"{name}\"", + + "error.validation.accepted": "Por favor, confirme", + "error.validation.alpha": "Por favor, use apenas caracteres entre a-z", + "error.validation.alphanum": "Por favor, use apenas caracteres entre a-z ou 0-9", + "error.validation.between": "Digite um valor entre \"{min}\" e \"{max}\"", + "error.validation.boolean": "Por favor, confirme ou rejeite", + "error.validation.contains": "Digite um valor que contenha \"{needle}\"", + "error.validation.date": "Escolha uma data válida", + "error.validation.date.after": "Escolha uma data posterior a {date}", + "error.validation.date.before": "Escolha uma data anterior a {date}", + "error.validation.date.between": "Escolha uma data compreendida entre {min} e {max}", + "error.validation.denied": "Por favor, cancele", + "error.validation.different": "O valor deve ser diferente de \"{other}\"", + "error.validation.email": "Digite um endereço de email válido", + "error.validation.endswith": "O valor deve terminar com \"{end}\"", + "error.validation.filename": "Digite um nome de arquivo válido", + "error.validation.in": "Digite um destes valores: ({in})", + "error.validation.integer": "Digite um número inteiro válido", + "error.validation.ip": "Digite um endereço de IP válido", + "error.validation.less": "Digite um valor menor que {max}", + "error.validation.match": "O valor não combina com o padrão esperado", + "error.validation.max": "Digite um valor igual ou menor que {max}", + "error.validation.maxlength": "Digite um valor curto. (no máximo {max} caracteres)", + "error.validation.maxwords": "Digite menos que {max} palavra(s)", + "error.validation.min": "Digite um valor igual ou maior que {min}", + "error.validation.minlength": "Digite um valor maior. (no mínimo {min} caracteres)", + "error.validation.minwords": "Digite ao menos {min} palavra(s)", + "error.validation.more": "Digite um valor maior que {min}", + "error.validation.notcontains": "Digite um valor que não contenha \"{needle}\"", + "error.validation.notin": "Não digite nenhum destes valores: ({notIn})", + "error.validation.option": "Escolha uma opção válida", + "error.validation.num": "Digite um número válido", + "error.validation.required": "Digite algo", + "error.validation.same": "Por favor, digite \"{other}\"", + "error.validation.size": "O tamanho do valor deve ser \"{size}\"", + "error.validation.startswith": "O valor deve começar com \"{start}\"", + "error.validation.time": "Digite uma hora válida", + "error.validation.time.after": "Por favor entre um horário depois de {time}", + "error.validation.time.before": "Por favor entre um horário antes de {time}", + "error.validation.time.between": "Por favor entre um horário entre {min} e {max}", + "error.validation.url": "Digite uma URL válida", + + "expand": "Expandir", + "expand.all": "Expandir todos", + + "field.required": "Este campo é necessário", + "field.blocks.changeType": "Mudar tipo", + "field.blocks.code.name": "Código", + "field.blocks.code.language": "Idioma", + "field.blocks.code.placeholder": "Seu código …", + "field.blocks.delete.confirm": "Deseja realmente deletar este bloco?", + "field.blocks.delete.confirm.all": "Deseja realmente deletar todos os blocos?", + "field.blocks.delete.confirm.selected": "Deseja realmente deletar os blocos selecionados?", + "field.blocks.empty": "Nenhum bloco", + "field.blocks.fieldsets.label": "Por favor selecione um tipo de bloco …", + "field.blocks.fieldsets.paste": "Digite {{ shortcut }} para colar/importar blocos da sua área de transferência ", + "field.blocks.gallery.name": "Galeria", + "field.blocks.gallery.images.empty": "Nenhuma imagem", + "field.blocks.gallery.images.label": "Imagens", + "field.blocks.heading.level": "Nível ", + "field.blocks.heading.name": "Título ", + "field.blocks.heading.text": "Texto", + "field.blocks.heading.placeholder": "Título …", + "field.blocks.image.alt": "Texto alternativo", + "field.blocks.image.caption": "Legenda", + "field.blocks.image.crop": "Cortar", + "field.blocks.image.link": "Link", + "field.blocks.image.location": "Localização ", + "field.blocks.image.name": "Imagem", + "field.blocks.image.placeholder": "Selecionar uma imagem", + "field.blocks.image.ratio": "Proporção ", + "field.blocks.image.url": "URL da imagem", + "field.blocks.line.name": "Linha", + "field.blocks.list.name": "Lista", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Texto", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Citação ", + "field.blocks.quote.text.label": "Texto", + "field.blocks.quote.text.placeholder": "Citação …", + "field.blocks.quote.citation.label": "Citação ", + "field.blocks.quote.citation.placeholder": "de …", + "field.blocks.text.name": "Texto", + "field.blocks.text.placeholder": "Texto …", + "field.blocks.video.caption": "Legenda", + "field.blocks.video.name": "Vídeo ", + "field.blocks.video.placeholder": "Entre uma URL de vídeo ", + "field.blocks.video.url.label": "URL-Vídeo", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Nenhum arquivo selecionado", + + "field.layout.delete": "Deletar layout", + "field.layout.delete.confirm": "Deseja realmente deletar este layout?", + "field.layout.empty": "Nenhuma linha", + "field.layout.select": "Selecionar um layout", + + "field.object.empty": "No information yet", + + "field.pages.empty": "Nenhuma página selecionada", + + "field.structure.delete.confirm": "Deseja realmente excluir este registro?", + "field.structure.empty": "Nenhum registro", + + "field.users.empty": "Nenhum utilizador selecionado", + + "file.blueprint": "Este arquivo não tem planta. Você pode definir sua planta em /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Deseja realmente excluir
{filename}?", + "file.sort": "Mudar posição", + + "files": "Arquivos", + "files.empty": "Nenhum arquivo", + + "hide": "Ocultar", + "hour": "Hora", + "import": "Importar", + "info": "Info", + "insert": "Inserir", + "insert.after": "Inserir após", + "insert.before": "Inserir antes", + "install": "Instalar", + + "installation": "Instalação", + "installation.completed": "Painel instalado com sucesso", + "installation.disabled": "Por padrão, o instalador do painel está desabilitado em servidores públicos. Por favor, execute o instalador numa máquina local ou habilite a opção panel.install.", + "installation.issues.accounts": "A pasta /site/accounts não existe ou não possui permissão de escrita", + "installation.issues.content": "A pasta /content não existe ou não possui permissão de escrita", + "installation.issues.curl": "A extensão CURL é necessária", + "installation.issues.headline": "O painel não pôde ser instalado", + "installation.issues.mbstring": "A extensão MB String é necessária", + "installation.issues.media": "A pasta /media não existe ou não possui permissão de escrita", + "installation.issues.php": "Certifique-se que está a usar o PHP 7+", + "installation.issues.server": "O Kirby necessita do Apache, Nginx ou Caddy", + "installation.issues.sessions": "A pasta /site/sessions não existe ou não possui permissão de escrita", + + "language": "Idioma", + "language.code": "Código", + "language.convert": "Tornar padrão", + "language.convert.confirm": "

Deseja realmente converter {name} para o idioma padrão? Esta ação não poderá ser revertida.

Se {name} tiver conteúdo não traduzido, partes do seu site poderão ficar sem conteúdo.

", + "language.create": "Adicionar novo idioma", + "language.delete.confirm": "Deseja realmente excluir o idioma {name} incluíndo todas as traduções? Esta ação não poderá ser revertida!", + "language.deleted": "Idioma excluído", + "language.direction": "Direção de leitura", + "language.direction.ltr": "Esquerda para direita", + "language.direction.rtl": "Direita para esquerda", + "language.locale": "String de localização do PHP", + "language.locale.warning": "Está a usar configurações de localização personalizadas. Corrija as mesmas no ficheiro /site/languages", + "language.name": "Nome", + "language.updated": "Idioma atualizado", + + "languages": "Idiomas", + "languages.default": "Idioma padrão", + "languages.empty": "Nenhum idioma", + "languages.secondary": "Idiomas secundários", + "languages.secondary.empty": "Nenhum idioma secundário", + + "license": "Licen\u00e7a do Kirby ", + "license.buy": "Comprar uma licença", + "license.register": "Registrar", + "license.manage": "Manage your licenses", + "license.register.help": "Recebeu o código da sua licença por email após a compra. Por favor, copie e cole-o para completar o registro.", + "license.register.label": "Por favor, digite o código da sua licença", + "license.register.success": "Obrigado por apoiar o Kirby", + "license.unregistered": "Esta é uma demonstração não registrada do Kirby", + "license.unregistered.label": "Unregistered", + + "link": "Link", + "link.text": "Texto do link", + + "loading": "A carregar", + + "lock.unsaved": "Alterações por guardar", + "lock.unsaved.empty": "Não existem alterações por guardar", + "lock.isLocked": "Alterações por guardar de {email}", + "lock.file.isLocked": "O arquivo está a ser editado por {email} e não pode ser alterado.", + "lock.page.isLocked": "A página está a ser editada por {email} e não pode ser alterada.", + "lock.unlock": "Desbloquear", + "lock.isUnlocked": "As suas alterações foram sobrepostas por outro utilizador. Pode descarregar as suas alterações e combiná-las manualmente.", + + "login": "Entrar", + "login.code.label.login": "Código de acesso", + "login.code.label.password-reset": "Código de redefinição de senha", + "login.code.placeholder.email": "000 0000", + "login.code.text.email": "Se seu endereço de email está registrado, o código requisitado será mandado por email.", + "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.login.subject": "Seu código de acesso", + "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.password-reset.subject": "Seu código de redefinição de senha", + "login.remember": "Manter-me conectado", + "login.reset": "Redefinir senha", + "login.toggleText.code.email": "Entrar com email", + "login.toggleText.code.email-password": "Entrar com senha", + "login.toggleText.password-reset.email": "Esqueceu sua senha?", + "login.toggleText.password-reset.email-password": "← Voltar à entrada", + + "logout": "Sair", + + "menu": "Menu", + "meridiem": "AM/PM", + "mime": "Tipo de mídia", + "minutes": "Minutos", + + "month": "Mês", + "months.april": "Abril", + "months.august": "Agosto", + "months.december": "Dezembro", + "months.february": "Fevereiro", + "months.january": "Janeiro", + "months.july": "Julho", + "months.june": "Junho", + "months.march": "Mar\u00e7o", + "months.may": "Maio", + "months.november": "Novembro", + "months.october": "Outubro", + "months.september": "Setembro", + + "more": "Mais", + "name": "Nome", + "next": "Próximo", + "no": "não", + "off": "off", + "on": "on", + "open": "Abrir", + "open.newWindow": "Abrir em nova janela", + "options": "Opções", + "options.none": "Sem opções", + + "orientation": "Orientação", + "orientation.landscape": "Paisagem", + "orientation.portrait": "Retrato", + "orientation.square": "Quadrado", + + "page.blueprint": "Esta página não tem planta. Você pode definir sua planta em /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Alterar URL", + "page.changeSlug.fromTitle": "Criar a partir do t\u00edtulo", + "page.changeStatus": "Alterar estado", + "page.changeStatus.position": "Selecione uma posição", + "page.changeStatus.select": "Selecione um novo estado", + "page.changeTemplate": "Alterar tema", + "page.delete.confirm": "Deseja realmente excluir {title}?", + "page.delete.confirm.subpages": "Esta página possui subpáginas.
Todas as subpáginas serão excluídas também.", + "page.delete.confirm.title": "Digite o título da página para confirmar", + "page.draft.create": "Criar rascunho", + "page.duplicate.appendix": "Copiar", + "page.duplicate.files": "Copiar arquivos", + "page.duplicate.pages": "Copiar páginas", + "page.sort": "Mudar posição", + "page.status": "Estado", + "page.status.draft": "Rascunho", + "page.status.draft.description": "A página está em modo de rascunho e é visível somente para editores", + "page.status.listed": "Pública", + "page.status.listed.description": "A página é pública para todos", + "page.status.unlisted": "Não listadas", + "page.status.unlisted.description": "Esta página é acessível somente através da URL", + + "pages": "Páginas", + "pages.empty": "Nenhuma página", + "pages.status.draft": "Rascunhos", + "pages.status.listed": "Publicadas", + "pages.status.unlisted": "Não listadas", + + "pagination.page": "Página", + + "password": "Palavra-passe", + "paste": "Colar", + "paste.after": "Colar após", + "pixel": "Pixel", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "Anterior", + "preview": "Visualizar", + "remove": "Remover", + "rename": "Renomear", + "replace": "Substituir", + "retry": "Tentar novamente", + "revert": "Descartar", + "revert.confirm": "Tem a certeza que pretende eliminar todas as alterações por guardar?", + + "role": "Função", + "role.admin.description": "O administrador tem todas as permissões.", + "role.admin.title": "Administrador", + "role.all": "Todos", + "role.empty": "Não há utilizadores com esta função", + "role.description.placeholder": "Sem descrição", + "role.nobody.description": "Esta é uma função de salvaguarda sem permissões.", + "role.nobody.title": "Ninguém", + + "save": "Salvar", + "search": "Buscar", + "search.min": "Introduza {min} caracteres para pesquisar", + "search.all": "Mostrar todos", + "search.results.none": "Sem resultados", + + "section.required": "Esta seção é necessária", + + "security": "Security", + "select": "Selecionar", + "server": "Servidor", + "settings": "Configurações", + "show": "Mostrar", + "site.blueprint": "Este site não tem planta. Você pode definir sua planta em /site/blueprints/site.yml", + "size": "Tamanho", + "slug": "URL", + "sort": "Ordenar", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Título", + "template": "Tema", + "today": "Hoje", + + "toolbar.button.code": "Código", + "toolbar.button.bold": "Negrito", + "toolbar.button.email": "Email", + "toolbar.button.headings": "Títulos", + "toolbar.button.heading.1": "Título 1", + "toolbar.button.heading.2": "Título 2", + "toolbar.button.heading.3": "Título 3", + "toolbar.button.heading.4": "Título 4", + "toolbar.button.heading.5": "Título 5", + "toolbar.button.heading.6": "Título 6", + "toolbar.button.italic": "Itálico", + "toolbar.button.file": "Ficheiro", + "toolbar.button.file.select": "Selecione o arquivo", + "toolbar.button.file.upload": "Carregue o arquivo", + "toolbar.button.link": "Link", + "toolbar.button.paragraph": "Parágrafo", + "toolbar.button.strike": "Riscado", + "toolbar.button.ol": "Lista ordenada", + "toolbar.button.underline": "Sublinhado", + "toolbar.button.ul": "Lista não-ordenada", + + "translation.author": "Kirby Team", + "translation.direction": "ltr", + "translation.name": "Português (Europeu)", + "translation.locale": "pt_PT", + + "upload": "Enviar", + "upload.error.cantMove": "Não foi possível mover o arquivo carregado", + "upload.error.cantWrite": "Não foi possível guardar o arquivo no sistema de ficheiros.", + "upload.error.default": "Não foi possível carregar o arquivo", + "upload.error.extension": "A extensão do arquivo não permite o carregamento", + "upload.error.formSize": "O arquivo excede o tamanho MAX_FILE_SIZE", + "upload.error.iniPostSize": "O arquivo excede o tamanho post_max_size", + "upload.error.iniSize": "O arquivo carregado excede a definição upload_max_filesize do php.ini", + "upload.error.noFile": "Nenhum arquivo carregado", + "upload.error.noFiles": "Nenhuns arquivos carregados", + "upload.error.partial": "O arquivo foi parcialmente carregado", + "upload.error.tmpDir": "Pasta temporária em falta", + "upload.errors": "Erro", + "upload.progress": "A enviar…", + + "url": "Url", + "url.placeholder": "https://exemplo.pt", + + "user": "Utilizador", + "user.blueprint": "Você pode definir seções e campos de formulário adicionais para este papel de usuário em /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Alterar email", + "user.changeLanguage": "Alterar idioma", + "user.changeName": "Renomear este utilizador", + "user.changePassword": "Alterar palavra-passe", + "user.changePassword.new": "Nova palavra-passe", + "user.changePassword.new.confirm": "Confirme a nova palavra-passe…", + "user.changeRole": "Alterar Função", + "user.changeRole.select": "Selecione uma nova função", + "user.create": "Adicionar novo utilizador", + "user.delete": "Excluir este utilizador", + "user.delete.confirm": "Deseja realmente excluir
{email}?", + + "users": "Utilizadores", + + "version": "Vers\u00e3o do Kirby", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "A sua conta", + "view.installation": "Instala\u00e7\u00e3o", + "view.languages": "Idiomas", + "view.resetPassword": "Redefinir senha", + "view.site": "Site", + "view.system": "Sistema", + "view.users": "Utilizadores", + + "welcome": "Bem-vindo", + "year": "Ano", + "yes": "sim" } diff --git a/kirby/i18n/translations/ru.json b/kirby/i18n/translations/ru.json index c38fb9d..11e1214 100644 --- a/kirby/i18n/translations/ru.json +++ b/kirby/i18n/translations/ru.json @@ -1,573 +1,596 @@ { - "account.changeName": "Изменить имя", - "account.delete": "Удалить аккаунт", - "account.delete.confirm": "Вы действительно хотите удалить свой аккаунт? Вы сразу покинете панель управления, а аккаунт нельзя будет восстановить.", - - "add": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c", - "author": "Автор", - "avatar": "\u0410\u0432\u0430\u0442\u0430\u0440 (\u0444\u043e\u0442\u043e)", - "back": "Назад", - "cancel": "\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c", - "change": "\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c", - "close": "\u0417\u0430\u043a\u0440\u044b\u0442\u044c", - "confirm": "Ок", - "collapse": "Свернуть", - "collapse.all": "Свернуть все", - "copy": "Скопировать", - "copy.all": "Копировать все", - "create": "Создать", - - "date": "Дата", - "date.select": "Выберите дату", - - "day": "День", - "days.fri": "\u041f\u0442", - "days.mon": "\u041f\u043d", - "days.sat": "\u0421\u0431", - "days.sun": "\u0412\u0441", - "days.thu": "\u0427\u0442", - "days.tue": "\u0412\u0442", - "days.wed": "\u0421\u0440", - - "debugging": "Отладка", - - "delete": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c", - "delete.all": "Удалить все", - - "dialog.files.empty": "Нет файлов для выбора", - "dialog.pages.empty": "Нет страниц для выбора", - "dialog.users.empty": "Нет пользователей для выбора", - - "dimensions": "Размеры", - "disabled": "Отключено", - "discard": "\u0421\u0431\u0440\u043e\u0441", - "download": "Скачать", - "duplicate": "Дублировать", - - "edit": "\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c", - - "email": "Email", - "email.placeholder": "mail@example.com", - - "entries": "Записи", - "entry": "Запись", - - "environment": "Среда", - - "error.access.code": "Неверный код", - "error.access.login": "Неправильный логин", - "error.access.panel": "У вас нет права доступа к панели", - "error.access.view": "У вас нет прав доступа к этой части панели", - - "error.avatar.create.fail": "Не удалось загрузить фотографию профиля", - "error.avatar.delete.fail": "\u0410\u0432\u0430\u0442\u0430\u0440 (\u0444\u043e\u0442\u043e) \u043a \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0443 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d", - "error.avatar.dimensions.invalid": "Пожалуйста, сделайте чтобы ширина или высота фотографии была меньше 3000 пикселей", - "error.avatar.mime.forbidden": "Фотография профиля должна быть JPEG или PNG", - - "error.blueprint.notFound": "Не удалось загрузить разметку \"{name}\"", - - "error.blocks.max.plural": "Вы не можете добавить больше {max} блоков", - "error.blocks.max.singular": "Вы не можете добавить больше одного блока", - "error.blocks.min.plural": "Вы должны добавить хотя бы {min} блоков", - "error.blocks.min.singular": "Вы должны добавить хотя бы один блок", - "error.blocks.validation": "Обнаружена ошибка в блоке {index}", - - "error.email.preset.notFound": "Шаблон эл. почты \"{name}\" не найден", - - "error.field.converter.invalid": "Неверный конвертер \"{converter}\"", - - "error.file.changeName.empty": "Название не может быть пустым", - "error.file.changeName.permission": "У вас нет права изменить название \"{filename}\"", - "error.file.duplicate": "Файл с названием \"{filename}\" уже есть", - "error.file.extension.forbidden": "Расширение файла \"{extension}\" неразрешено", - "error.file.extension.invalid": "Неверное разрешение: {extension}", - "error.file.extension.missing": "Файлу \"{filename}\" не хватает расширения", - "error.file.maxheight": "Высота изображения не должна превышать {height} px", - "error.file.maxsize": "Файл слишком большой", - "error.file.maxwidth": "Ширина изображения не должна превышать {width} px", - "error.file.mime.differs": "Загружаемый файл должен иметь такое же расширение (тип): \"{mime}\"", - "error.file.mime.forbidden": "Расширение (тип) \"{mime}\" не допускается", - "error.file.mime.invalid": "Неверное расширение (тип): {mime}", - "error.file.mime.missing": "Не удалось определить тип медиа для файла \"{filename}\"", - "error.file.minheight": "Высота файла должна быть хотя бы {height} px", - "error.file.minsize": "Файл слишком маленький", - "error.file.minwidth": "Ширина файла должна быть хотя бы {width} px", - "error.file.name.missing": "Название файла не может быть пустым", - "error.file.notFound": "\u0424\u0430\u0439\u043b \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d", - "error.file.orientation": "Ориентация изображения должна быть \"{orientation}\"", - "error.file.type.forbidden": "У вас нет права загружать файлы {type}", - "error.file.type.invalid": "Неверный тип файла: {type}", - "error.file.undefined": "\u0424\u0430\u0439\u043b \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d", - - "error.form.incomplete": "Пожалуйста, исправьте все ошибки в форме", - "error.form.notSaved": "Форма не может быть сохранена", - - "error.language.code": "Пожалуйста, впишите правильный код языка", - "error.language.duplicate": "Язык уже есть", - "error.language.name": "Пожалуйста, впишите правильное название языка", - "error.language.notFound": "Не получилось найти этот язык", - - "error.layout.validation.block": "Ошибка в блоке {blockIndex} в макете {layoutIndex}", - "error.layout.validation.settings": "Ошибка в настройках макета {index}", - - "error.license.format": "Пожалуйста, введите правильный лицензионный код", - "error.license.email": "Пожалуйста, введите правильный Email", - "error.license.verification": "Лицензия не подтверждена", - - "error.offline": "Панель управления не в сети", - - "error.page.changeSlug.permission": "\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c URL \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b", - "error.page.changeStatus.incomplete": "На странице есть ошибки и поэтому ее нельзя опубликовать", - "error.page.changeStatus.permission": "Невозможно изменить статус для этой страницы", - "error.page.changeStatus.toDraft.invalid": "Невозможно конвертировать в черновик страницу \"{slug}\"", - "error.page.changeTemplate.invalid": "Невозможно изменить шаблон страницы \"{slug}\"", - "error.page.changeTemplate.permission": "У вас нет права изменять шаблон для \"{slug}\"", - "error.page.changeTitle.empty": "Название не может быть пустым", - "error.page.changeTitle.permission": "у вас нет права изменять название \"{slug}\"", - "error.page.create.permission": "У вас нет права создать \"{slug}\"", - "error.page.delete": "Невозможно удалить страницу \"{slug}\"", - "error.page.delete.confirm": "Впишите название страницы чтобы подтвердить", - "error.page.delete.hasChildren": "У страницы есть внутренние страницы, поэтому ее невозможно удалить", - "error.page.delete.permission": "У вас нет права удалить \"{slug}\"", - "error.page.draft.duplicate": "Черновик страницы с аппендиксом URL \"{slug}\" уже есть", - "error.page.duplicate": "Страница с аппендиксом URL \"{slug}\" уже есть", - "error.page.duplicate.permission": "У вас нет права дублировать \"{slug}\"", - "error.page.notFound": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430", - "error.page.num.invalid": "Пожалуйста, впишите правильное число сортировки. Число не может быть отрицательным.", - "error.page.slug.invalid": "Пожалуйста, введите правильный URL", - "error.page.slug.maxlength": "Длина ссылки должна быть короче \"{length}\" символов", - "error.page.sort.permission": "Невозможно сортировать страницу \"{slug}\"", - "error.page.status.invalid": "Пожалуйста, установите верный статус страницы", - "error.page.undefined": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430", - "error.page.update.permission": "У вас нет права обновить \"{slug}\"", - - "error.section.files.max.plural": "Нельзя добавить больше чем {max} файлов в секции \"{section}\"", - "error.section.files.max.singular": "Можно добавить не больше 1 файла в секции \"{section}\"", - "error.section.files.min.plural": "Секция \"{section}\" требует хотя бы {min} файлов", - "error.section.files.min.singular": "Секция \"{section}\" требует хотя бы 1 файл", - - "error.section.pages.max.plural": "Можно добавить не больше {max} страниц в секции \"{section}\"", - "error.section.pages.max.singular": "Нельзя добавить больше чем 1 страницу в секции \"{section}\"", - "error.section.pages.min.plural": "Секция \"{section}\" требует хотя бы {min} страниц", - "error.section.pages.min.singular": "Секция \"{section}\" требует хотя бы одну страницу", - - "error.section.notLoaded": "Секция \"{name}\" не может быть загружена", - "error.section.type.invalid": "Тип секции {type} неверный", - - "error.site.changeTitle.empty": "Название не может быть пустым", - "error.site.changeTitle.permission": "У вас нет права изменять название сайта", - "error.site.update.permission": "У вас нет права обновить сайт", - - "error.template.default.notFound": "Нет шаблона по умолчанию", - - "error.unexpected": "Произошла непредвиденная ошибка! Включите режим отладки для получения дополнительной информации: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "У вас нет права изменять Email пользователя \"{name}\"", - "error.user.changeLanguage.permission": "У вас нет права изменять язык для пользователя \"{name}\"", - "error.user.changeName.permission": "У вас нет права изменять имя пользователя \"{name}\"", - "error.user.changePassword.permission": "У вас нет права изменять пароль для пользователя \"{name}\"", - "error.user.changeRole.lastAdmin": "Роль единственного администратора нельзя изменить", - "error.user.changeRole.permission": "У вас нет права изменять роль пользователя \"{name}\"", - "error.user.changeRole.toAdmin": "У вас нет прав предоставить роль администратора", - "error.user.create.permission": "У вас нет права создать этого пользователя", - "error.user.delete": "\u0410\u043a\u043a\u0430\u0443\u043d\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d", - "error.user.delete.lastAdmin": "\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430", - "error.user.delete.lastUser": "Нельзя удалить единственного пользователя", - "error.user.delete.permission": "У вас нет права удалить пользователя \"{name}\"", - "error.user.duplicate": "Пользователь с Email \"{email}\" уже есть", - "error.user.email.invalid": "Пожалуйста, введите правильный адрес эл. почты", - "error.user.language.invalid": "Введите правильный язык", - "error.user.notFound": "Пользователь \"{name}\" не найден", - "error.user.password.invalid": "Пожалуйста, введите правильный пароль. Он должен состоять минимум из 8 символов.", - "error.user.password.notSame": "\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u044c", - "error.user.password.undefined": "У пользователя нет пароля", - "error.user.password.wrong": "Неверный пароль", - "error.user.role.invalid": "Введите правильную роль", - "error.user.undefined": "Аккаунт не найден", - "error.user.update.permission": "У вас нет права обновить пользователя \"{name}\"", - - "error.validation.accepted": "Пожалуйста, подтвердите", - "error.validation.alpha": "Пожалуйста, введите только буквы a-z", - "error.validation.alphanum": "Пожалуйста, введите только буквы a-z или числа 0-9", - "error.validation.between": "Пожалуйста, введите значение от \"{min}\" до \"{max}\"", - "error.validation.boolean": "Пожалуйста, подтвердите или отмените", - "error.validation.contains": "Пожалуйста, впишите значение, которое содержит \"{needle}\"", - "error.validation.date": "Пожалуйста, укажите правильную дату", - "error.validation.date.after": "Пожалуйста, укажите дату после {date}", - "error.validation.date.before": "Пожалуйста, укажите дату до {date}", - "error.validation.date.between": "Пожалуйста, укажите дату между {min} и {max}", - "error.validation.denied": "Пожалуйста отмените", - "error.validation.different": "Значение не может быть \"{other}\"", - "error.validation.email": "Пожалуйста, введите правильный Email", - "error.validation.endswith": "Значение должно заканчиваться с \"{end}\"", - "error.validation.filename": "Пожалуйста, введите правильное название файла", - "error.validation.in": "Пожалуйста, введите одно из следующих: ({in})", - "error.validation.integer": "Пожалуйста, введите правильное целое число", - "error.validation.ip": "Пожалуйста, введите правильный IP адрес", - "error.validation.less": "Пожалуйста, введите значение меньше чем {max}", - "error.validation.match": "Значение не соответствует ожидаемому шаблону", - "error.validation.max": "Пожалуйста, введите значение равное или больше чем {max}", - "error.validation.maxlength": "Пожалуйста, введите значение короче (макс. {max} символов)", - "error.validation.maxwords": "Пожалуйста, введите не более {max} слов ", - "error.validation.min": "Пожалуйста, введите значение равное или больше чем {min}", - "error.validation.minlength": "Пожалуйста, введите значение длиннее (мин. {min} символов)", - "error.validation.minwords": "Пожалуйста, введите хотя бы {min} слов", - "error.validation.more": "Пожалуйста, введите значение больше, чем {min}", - "error.validation.notcontains": "Пожалуйста, введите значение, которое не содержит \"{needle}\"", - "error.validation.notin": "Пожалуйста, не вписывайте одно из: ({notIn})", - "error.validation.option": "Пожалуйста, выберите правильную опцию ", - "error.validation.num": "Пожалуйста, введите правильный номер", - "error.validation.required": "Пожалуйста, введите что-нибудь", - "error.validation.same": "Пожалуйста, введите \"{other}\"", - "error.validation.size": "Значение размера должно быть \"{size}\"", - "error.validation.startswith": "Значение должно начинаться с \"{start}\"", - "error.validation.time": "Пожалуйста, введите правильную дату", - "error.validation.time.after": "Пожалуйста, укажите время после {time}", - "error.validation.time.before": "Пожалуйста, укажите время до {time}", - "error.validation.time.between": "Пожалуйста, укажите время между {min} и {max}", - "error.validation.url": "Пожалуйста, введите правильный URL", - - "expand": "Развернуть", - "expand.all": "Развернуть все", - - "field.required": "Поле обязательно", - "field.blocks.changeType": "Изменить тип", - "field.blocks.code.name": "Код", - "field.blocks.code.language": "Язык", - "field.blocks.code.placeholder": "Ваш код …", - "field.blocks.delete.confirm": "Вы действительно хотите удалить этот блок?", - "field.blocks.delete.confirm.all": "Вы действительно хотите удалить все блоки?", - "field.blocks.delete.confirm.selected": "Вы действительно хотите удалить эти блоки?", - "field.blocks.empty": "Блоков нет", - "field.blocks.fieldsets.label": "Пожалуйста, выберите тип блока…", - "field.blocks.fieldsets.paste": "Нажмите {{ shortcut }} чтобы вставить/импортировать блоки из буфера памяти", - "field.blocks.gallery.name": "Галерея", - "field.blocks.gallery.images.empty": "Изображений нет", - "field.blocks.gallery.images.label": "Изображения", - "field.blocks.heading.level": "Уровень", - "field.blocks.heading.name": "Заголовок", - "field.blocks.heading.text": "Текст", - "field.blocks.heading.placeholder": "Заголовок …", - "field.blocks.image.alt": "Альтернативный текст", - "field.blocks.image.caption": "Подпись", - "field.blocks.image.crop": "Обрезать", - "field.blocks.image.link": "Ссылка", - "field.blocks.image.location": "Расположение", - "field.blocks.image.name": "Картинка", - "field.blocks.image.placeholder": "Выберите изображение", - "field.blocks.image.ratio": "Соотношение", - "field.blocks.image.url": "URL изображения", - "field.blocks.line.name": "Линия", - "field.blocks.list.name": "Список", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Текст", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Цитата", - "field.blocks.quote.text.label": "Текст", - "field.blocks.quote.text.placeholder": "Цитата …", - "field.blocks.quote.citation.label": "Цитирование", - "field.blocks.quote.citation.placeholder": "Автор …", - "field.blocks.text.name": "Текст", - "field.blocks.text.placeholder": "Текст …", - "field.blocks.video.caption": "Подпись", - "field.blocks.video.name": "Видео", - "field.blocks.video.placeholder": "Введите ссылку на видео", - "field.blocks.video.url.label": "Ссылка на видео", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Файлы не выбраны", - - "field.layout.delete": "Удалить разметку", - "field.layout.delete.confirm": "Вы действительно хотите удалить эту разметку?", - "field.layout.empty": "Строк нет", - "field.layout.select": "Выберите разметку", - - "field.pages.empty": "Страницы не выбраны", - "field.structure.delete.confirm": "Вы точно хотите удалить эту запись?", - "field.structure.empty": "Записей нет", - "field.users.empty": "Пользователей нет", - - "file.blueprint": "У файла пока нет разметки. Вы можете определить новые секции и поля разметки в /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Вы точно хотите удалить файл
{filename}?", - "file.sort": "Изменить позицию", - - "files": "Файлы", - "files.empty": "Еще нет файлов", - - "hide": "Скрыть", - "hour": "Час", - "import": "Импортировать", - "info": "Информация", - "insert": "\u0412\u0441\u0442\u0430\u0432\u0438\u0442\u044c", - "insert.after": "Вставить ниже", - "insert.before": "Вставить выше", - "install": "Установить", - - "installation": "Установка", - "installation.completed": "Панель установлена", - "installation.disabled": "Установка панели по умолчанию отключена на общедоступных серверах. Пожалуйста запустите установку на локальном сервере или включите такую возможность с помощью опции panel.install", - "installation.issues.accounts": "Каталог /site/accounts не существует или не имеет прав записи", - "installation.issues.content": "Каталог /content не существует или не имеет прав записи", - "installation.issues.curl": "Расширение CURL необходимо", - "installation.issues.headline": "Не удалось установить панель", - "installation.issues.mbstring": "Расширение MB String необходимо", - "installation.issues.media": "Каталог /media не существует или нет прав записи", - "installation.issues.php": "Убедитесь, что используется PHP 7+", - "installation.issues.server": "Kirby требует Apache, Nginx или Caddy ", - "installation.issues.sessions": "Каталог /site/sessions не существует или нет прав записи", - - "language": "\u042f\u0437\u044b\u043a", - "language.code": "Код", - "language.convert": "Установить по умолчанию", - "language.convert.confirm": "

Вы точно хотите конвертировать {name} в главный язык? Это нельзя будет отменить.

Если {name} имеет непереведенный контент, то больше не будет верного каскада и части вашего сайта могут быть пустыми.

", - "language.create": "Добавить новый язык", - "language.delete.confirm": "Вы точно хотите удалить {name} язык, включая все переводы? Это нельзя будет вернуть.", - "language.deleted": "Язык удален", - "language.direction": "Направление чтения", - "language.direction.ltr": "Слева направо", - "language.direction.rtl": "Справа налево", - "language.locale": "PHP locale string", - "language.locale.warning": "Вы используете кастомную локаль. Пожалуйста измените ее в файле языка в /site/languages", - "language.name": "Название", - "language.updated": "Язык обновлен", - - "languages": "Языки", - "languages.default": "Главный язык", - "languages.empty": "Языков нет", - "languages.secondary": "Дополнительные языки", - "languages.secondary.empty": "Дополнительных языков нет", - - "license": "Лицензия", - "license.buy": "Купить лицензию", - "license.register": "Зарегистрировать", - "license.manage": "Управление лицензиями", - "license.register.help": "После покупки вы получили по эл. почте код лицензии. Пожалуйста скопируйте и вставьте сюда чтобы зарегистрировать.", - "license.register.label": "Пожалуйста вставьте код лицензии", - "license.register.success": "Спасибо за поддержку Kirby", - "license.unregistered": "Это незарегистрированная версия Kirby", - "license.unregistered.label": "Не зарегистрировано", - - "link": "\u0421\u0441\u044b\u043b\u043a\u0430", - "link.text": "\u0422\u0435\u043a\u0441\u0442 \u0441\u0441\u044b\u043b\u043a\u0438", - - "loading": "Загрузка", - - "lock.unsaved": "Несохраненные изменения", - "lock.unsaved.empty": "Несохраненных изменений больше нет", - "lock.isLocked": "Несохраненные изменения пользователя {email}", - "lock.file.isLocked": "В данный момент этот файл редактирует {email}, поэтому его нельзя изменить.", - "lock.page.isLocked": "В данный момент эту страницу редактирует {email}, поэтому его нельзя изменить.", - "lock.unlock": "Разблокировать", - "lock.isUnlocked": "Ваши несохраненные изменения были перезаписаны другим пользователем. Вы можете загрузить ваши изменения и объединить их вручную.", - - "login": "Войти", - "login.code.label.login": "Код для входа", - "login.code.label.password-reset": "Код для сброса пароля", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "Если ваш Email уже зарегистрирован, запрашиваемый код был отправлен на него.", - "login.email.login.body": "Привет, {user.nameOrEmail}!\n\nНедавно вы запросили код для входа на «{site}».\nСледующий код входа будет действителен в течение {timeout} минут:\n\n{code}\n\nЕсли вы не запрашивали код для входа, проигнорируйте это письмо или обратитесь к администратору, если у вас есть вопросы.\nВ целях безопасности НЕ ПЕРЕСЫЛАЙТЕ это письмо.", - "login.email.login.subject": "Ваш код для входа", - "login.email.password-reset.body": "Привет, {user.nameOrEmail}!\n\nНедавно вы запросили сброс пароля для входа на «{site}».\nСледующий код входа будет действителен в течение {timeout} минут:\n\n{code}\n\nЕсли вы не запрашивали сброс пароля, проигнорируйте это письмо или обратитесь к администратору, если у вас есть вопросы.\nВ целях безопасности НЕ ПЕРЕСЫЛАЙТЕ это письмо.", - "login.email.password-reset.subject": "Ваш код для сброса пароля", - "login.remember": "Сохранять вход активным", - "login.reset": "Сбросить пароль", - "login.toggleText.code.email": "Вход с помощью Email", - "login.toggleText.code.email-password": "Вход с паролем", - "login.toggleText.password-reset.email": "Забыли ваш пароль?", - "login.toggleText.password-reset.email-password": "← Вернуться к форме входа", - - "logout": "Выйти", - - "menu": "Меню", - "meridiem": "До полудня / После полудня", - "mime": "Тип медиа", - "minutes": "Минуты", - - "month": "Месяц", - "months.april": "\u0410\u043f\u0440\u0435\u043b\u044c", - "months.august": "\u0410\u0432\u0433\u0443\u0441\u0442", - "months.december": "\u0414\u0435\u043a\u0430\u0431\u0440\u044c", - "months.february": "Февраль", - "months.january": "\u042f\u043d\u0432\u0430\u0440\u044c", - "months.july": "\u0418\u044e\u043b\u044c", - "months.june": "\u0418\u044e\u043d\u044c", - "months.march": "\u041c\u0430\u0440\u0442", - "months.may": "\u041c\u0430\u0439", - "months.november": "\u041d\u043e\u044f\u0431\u0440\u044c", - "months.october": "\u041e\u043a\u0442\u044f\u0431\u0440\u044c", - "months.september": "\u0421\u0435\u043d\u0442\u044f\u0431\u0440\u044c", - - "more": "Подробнее", - "name": "Название", - "next": "Дальше", - "no": "нет", - "off": "выключено", - "on": "включено", - "open": "Открыть", - "open.newWindow": "Открывать в новом окне", - "options": "Опции", - "options.none": "Параметров нет", - - "orientation": "Ориентация", - "orientation.landscape": "Горизонтальная", - "orientation.portrait": "Портретная", - "orientation.square": "Квадрат", - - "page.blueprint": "У страницы пока нет разметки. Вы можете определить новые секции и поля разметки в /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Изменить ссылку", - "page.changeSlug.fromTitle": "Создать из названия", - "page.changeStatus": "Изменить статус", - "page.changeStatus.position": "Пожалуйста, выберите позицию", - "page.changeStatus.select": "Выбрать новый статус", - "page.changeTemplate": "Изменить шаблон", - "page.delete.confirm": "Вы точно хотите удалить страницу {title}?", - "page.delete.confirm.subpages": "У этой страницы есть внутренние страницы.
Все внутренние страницы так же будут удалены.", - "page.delete.confirm.title": "Напишите название страницы, чтобы подтвердить", - "page.draft.create": "Создать черновик", - "page.duplicate.appendix": "(копия)", - "page.duplicate.files": "Копировать файлы", - "page.duplicate.pages": "Копировать страницы", - "page.sort": "Изменить позицию", - "page.status": "Статус", - "page.status.draft": "Черновик", - "page.status.draft.description": "Страница находится в черновом режиме и видна только зарегистрированным пользователям или по секретной ссылке", - "page.status.listed": "Опубликована", - "page.status.listed.description": "Страница доступна для всех посетителей", - "page.status.unlisted": "Скрыта", - "page.status.unlisted.description": "Страница доступна только по URL", - - "pages": "Страницы", - "pages.empty": "Страниц нет", - "pages.status.draft": "Черновики", - "pages.status.listed": "Опубликовано", - "pages.status.unlisted": "Скрытая", - - "pagination.page": "Страница", - - "password": "\u041f\u0430\u0440\u043e\u043b\u044c", - "paste": "Вставить", - "paste.after": "Вставить после", - "pixel": "Пиксель", - "plugins": "Плагины", - "prev": "Предыдущий", - "preview": "Предпросмотр", - "remove": "Удалить", - "rename": "Переназвать", - "replace": "\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c", - "retry": "\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c", - "revert": "\u0421\u0431\u0440\u043e\u0441", - "revert.confirm": "Вы действительно хотите удалить все несохраненные изменения?", - - "role": "\u0420\u043e\u043b\u044c", - "role.admin.description": "Администратор имеет все права", - "role.admin.title": "Администратор", - "role.all": "Все", - "role.empty": "Пользователей с такой ролью нет", - "role.description.placeholder": "Без описания", - "role.nobody.description": "Эта роль применяется если у пользователя нет никаких прав", - "role.nobody.title": "Никто", - - "save": "\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c", - "search": "Поиск", - "search.min": "Введите хотя бы {min} символов для поиска", - "search.all": "Показать все", - "search.results.none": "Нет результатов", - - "section.required": "Секция обязательна", - - "security": "Безопасность", - "select": "Выбрать", - "server": "Сервер", - "settings": "Настройка", - "show": "Показать", - "site.blueprint": "У сайта пока нет разметки. Вы можете определить новые секции и поля разметки в /site/blueprints/site.yml", - "size": "Размер", - "slug": "Понятная ссылка", - "sort": "Сортировать", - - "stats.empty": "Статистики нет", - "system.issues.content": "Похоже, к папке content есть несанкционированный доступ", - "system.issues.debug": "Включен режим отладки (debugging). Используйте его только при разработке.", - "system.issues.git": "Похоже, к папке .git есть несанкционированный доступ", - "system.issues.https": "Рекомендуется использовать HTTPS на всех сайтах", - "system.issues.kirby": "Похоже, к папке kirby есть несанкционированный доступ", - "system.issues.site": "Похоже, к папке site есть несанкционированный доступ", - - "title": "Название", - "template": "\u0428\u0430\u0431\u043b\u043e\u043d", - "today": "Сегодня", - - "toolbar.button.code": "Код", - "toolbar.button.bold": "\u0416\u0438\u0440\u043d\u044b\u0439 \u0448\u0440\u0438\u0444\u0442", - "toolbar.button.email": "Email", - "toolbar.button.headings": "Заголовки", - "toolbar.button.heading.1": "Заголовок 1", - "toolbar.button.heading.2": "Заголовок 2", - "toolbar.button.heading.3": "Заголовок 3", - "toolbar.button.heading.4": "Заголовок 4", - "toolbar.button.heading.5": "Заголовок 5", - "toolbar.button.heading.6": "Заголовок 6", - "toolbar.button.italic": "Курсив", - "toolbar.button.file": "Файл", - "toolbar.button.file.select": "Выбрать файл", - "toolbar.button.file.upload": "Закачать файл", - "toolbar.button.link": "\u0421\u0441\u044b\u043b\u043a\u0430", - "toolbar.button.paragraph": "Параграф", - "toolbar.button.strike": "Зачёркнутый", - "toolbar.button.ol": "Нумерованный список", - "toolbar.button.underline": "Подчёркнутый", - "toolbar.button.ul": "Маркированный список", - - "translation.author": "Команда Kirby", - "translation.direction": "ltr", - "translation.name": "Русский (Russian)", - "translation.locale": "ru_RU", - - "upload": "Закачать", - "upload.error.cantMove": "Не удается переместить загруженный файл", - "upload.error.cantWrite": "Не получилось записать файл на диск", - "upload.error.default": "Не удалось загрузить файл", - "upload.error.extension": "Загрузка файла не удалась из за расширения", - "upload.error.formSize": "Загруженный файл больше чем MAX_FILE_SIZE настройка в форме", - "upload.error.iniPostSize": "Загружаемый файл больше чем post_max_size настройка в php.ini", - "upload.error.iniSize": "Загруженный файл больше чем настройка upload_max_filesize в php.ini", - "upload.error.noFile": "Файл не был загружен", - "upload.error.noFiles": "Файлы не были загружены", - "upload.error.partial": "Файл загружен только частично", - "upload.error.tmpDir": "Не хватает временной папки", - "upload.errors": "Ошибка", - "upload.progress": "Закачивается...", - - "url": "URL", - "url.placeholder": "https://example.com", - - "user": "Пользователь", - "user.blueprint": "Вы можете определить новые секции и поля разметки для пользователя в /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Изменить Email", - "user.changeLanguage": "Изменить язык", - "user.changeName": "Переназвать этого пользователя", - "user.changePassword": "Изменить пароль", - "user.changePassword.new": "Новый пароль", - "user.changePassword.new.confirm": "Подтвердить новый пароль…", - "user.changeRole": "Изменить роль", - "user.changeRole.select": "Выбрать новую роль", - "user.create": "Добавить нового пользователя", - "user.delete": "Удалить этого пользователя", - "user.delete.confirm": "Вы действительно хотите аккаунт
{email}?", - - "users": "Пользователи", - - "version": "Версия", - - "view.account": "\u0412\u0430\u0448 \u0430\u043a\u043a\u0430\u0443\u043d\u0442", - "view.installation": "\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430", - "view.languages": "Языки", - "view.resetPassword": "Сбросить пароль", - "view.site": "Сайт", - "view.system": "Система", - "view.users": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438", - - "welcome": "Добро пожаловать", - "year": "Год", - "yes": "да" + "account.changeName": "Изменить имя", + "account.delete": "Удалить аккаунт", + "account.delete.confirm": "Вы действительно хотите удалить свой аккаунт? Вы сразу покинете панель управления, а аккаунт нельзя будет восстановить.", + + "add": "\u0414\u043e\u0431\u0430\u0432\u0438\u0442\u044c", + "author": "Автор", + "avatar": "\u0410\u0432\u0430\u0442\u0430\u0440 (\u0444\u043e\u0442\u043e)", + "back": "Назад", + "cancel": "\u041e\u0442\u043c\u0435\u043d\u0438\u0442\u044c", + "change": "\u0418\u0437\u043c\u0435\u043d\u0438\u0442\u044c", + "close": "\u0417\u0430\u043a\u0440\u044b\u0442\u044c", + "confirm": "Ок", + "collapse": "Свернуть", + "collapse.all": "Свернуть все", + "copy": "Скопировать", + "copy.all": "Копировать все", + "create": "Создать", + + "date": "Дата", + "date.select": "Выберите дату", + + "day": "День", + "days.fri": "\u041f\u0442", + "days.mon": "\u041f\u043d", + "days.sat": "\u0421\u0431", + "days.sun": "\u0412\u0441", + "days.thu": "\u0427\u0442", + "days.tue": "\u0412\u0442", + "days.wed": "\u0421\u0440", + + "debugging": "Отладка", + + "delete": "\u0423\u0434\u0430\u043b\u0438\u0442\u044c", + "delete.all": "Удалить все", + + "dialog.files.empty": "Нет файлов для выбора", + "dialog.pages.empty": "Нет страниц для выбора", + "dialog.users.empty": "Нет пользователей для выбора", + + "dimensions": "Размеры", + "disabled": "Отключено", + "discard": "\u0421\u0431\u0440\u043e\u0441", + "download": "Скачать", + "duplicate": "Дублировать", + + "edit": "\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c", + + "email": "Email", + "email.placeholder": "mail@example.com", + + "entries": "Записи", + "entry": "Запись", + + "environment": "Среда", + + "error.access.code": "Неверный код", + "error.access.login": "Неправильный логин", + "error.access.panel": "У вас нет права доступа к панели", + "error.access.view": "У вас нет прав доступа к этой части панели", + + "error.avatar.create.fail": "Не удалось загрузить фотографию профиля", + "error.avatar.delete.fail": "\u0410\u0432\u0430\u0442\u0430\u0440 (\u0444\u043e\u0442\u043e) \u043a \u0430\u043a\u043a\u0430\u0443\u043d\u0442\u0443 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d", + "error.avatar.dimensions.invalid": "Пожалуйста, сделайте чтобы ширина или высота фотографии была меньше 3000 пикселей", + "error.avatar.mime.forbidden": "Фотография профиля должна быть JPEG или PNG", + + "error.blueprint.notFound": "Не удалось загрузить разметку \"{name}\"", + + "error.blocks.max.plural": "Вы не можете добавить больше {max} блоков", + "error.blocks.max.singular": "Вы не можете добавить больше одного блока", + "error.blocks.min.plural": "Вы должны добавить хотя бы {min} блоков", + "error.blocks.min.singular": "Вы должны добавить хотя бы один блок", + "error.blocks.validation": "Ошибка в поле \"{field}\" в блоке {index} типа \"{fieldset}\"", + + "error.email.preset.notFound": "Шаблон эл. почты \"{name}\" не найден", + + "error.field.converter.invalid": "Неверный конвертер \"{converter}\"", + + "error.file.changeName.empty": "Название не может быть пустым", + "error.file.changeName.permission": "У вас нет права изменить название \"{filename}\"", + "error.file.duplicate": "Файл с названием \"{filename}\" уже есть", + "error.file.extension.forbidden": "Расширение файла \"{extension}\" неразрешено", + "error.file.extension.invalid": "Неверное разрешение: {extension}", + "error.file.extension.missing": "Файлу \"{filename}\" не хватает расширения", + "error.file.maxheight": "Высота изображения не должна превышать {height} px", + "error.file.maxsize": "Файл слишком большой", + "error.file.maxwidth": "Ширина изображения не должна превышать {width} px", + "error.file.mime.differs": "Загружаемый файл должен иметь такое же расширение (тип): \"{mime}\"", + "error.file.mime.forbidden": "Расширение (тип) \"{mime}\" не допускается", + "error.file.mime.invalid": "Неверное расширение (тип): {mime}", + "error.file.mime.missing": "Не удалось определить тип медиа для файла \"{filename}\"", + "error.file.minheight": "Высота файла должна быть хотя бы {height} px", + "error.file.minsize": "Файл слишком маленький", + "error.file.minwidth": "Ширина файла должна быть хотя бы {width} px", + "error.file.name.missing": "Название файла не может быть пустым", + "error.file.notFound": "\u0424\u0430\u0439\u043b \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d", + "error.file.orientation": "Ориентация изображения должна быть \"{orientation}\"", + "error.file.type.forbidden": "У вас нет права загружать файлы {type}", + "error.file.type.invalid": "Неверный тип файла: {type}", + "error.file.undefined": "\u0424\u0430\u0439\u043b \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d", + + "error.form.incomplete": "Пожалуйста, исправьте все ошибки в форме", + "error.form.notSaved": "Форма не может быть сохранена", + + "error.language.code": "Пожалуйста, впишите правильный код языка", + "error.language.duplicate": "Язык уже есть", + "error.language.name": "Пожалуйста, впишите правильное название языка", + "error.language.notFound": "Не получилось найти этот язык", + + "error.layout.validation.block": "Ошибка в поле \"{field}\" в блоке {blockIndex} типа \"{fieldset}\" внутри разметки {layoutIndex}", + "error.layout.validation.settings": "Ошибка в настройках макета {index}", + + "error.license.format": "Пожалуйста, введите правильный лицензионный код", + "error.license.email": "Пожалуйста, введите правильный Email", + "error.license.verification": "Лицензия не подтверждена", + + "error.object.validation": "Ошибка в поле \"{label}\":\n{message}", + + "error.offline": "Панель управления не в сети", + + "error.page.changeSlug.permission": "\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c URL \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b", + "error.page.changeStatus.incomplete": "На странице есть ошибки и поэтому ее нельзя опубликовать", + "error.page.changeStatus.permission": "Невозможно изменить статус для этой страницы", + "error.page.changeStatus.toDraft.invalid": "Невозможно конвертировать в черновик страницу \"{slug}\"", + "error.page.changeTemplate.invalid": "Невозможно изменить шаблон страницы \"{slug}\"", + "error.page.changeTemplate.permission": "У вас нет права изменять шаблон для \"{slug}\"", + "error.page.changeTitle.empty": "Название не может быть пустым", + "error.page.changeTitle.permission": "у вас нет права изменять название \"{slug}\"", + "error.page.create.permission": "У вас нет права создать \"{slug}\"", + "error.page.delete": "Невозможно удалить страницу \"{slug}\"", + "error.page.delete.confirm": "Впишите название страницы чтобы подтвердить", + "error.page.delete.hasChildren": "У страницы есть внутренние страницы, поэтому ее невозможно удалить", + "error.page.delete.permission": "У вас нет права удалить \"{slug}\"", + "error.page.draft.duplicate": "Черновик страницы с аппендиксом URL \"{slug}\" уже есть", + "error.page.duplicate": "Страница с аппендиксом URL \"{slug}\" уже есть", + "error.page.duplicate.permission": "У вас нет права дублировать \"{slug}\"", + "error.page.notFound": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430", + "error.page.num.invalid": "Пожалуйста, впишите правильное число сортировки. Число не может быть отрицательным.", + "error.page.slug.invalid": "Пожалуйста, введите правильный URL", + "error.page.slug.maxlength": "Длина ссылки должна быть короче \"{length}\" символов", + "error.page.sort.permission": "Невозможно сортировать страницу \"{slug}\"", + "error.page.status.invalid": "Пожалуйста, установите верный статус страницы", + "error.page.undefined": "\u0421\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u0430", + "error.page.update.permission": "У вас нет права обновить \"{slug}\"", + + "error.section.files.max.plural": "Нельзя добавить больше чем {max} файлов в секции \"{section}\"", + "error.section.files.max.singular": "Можно добавить не больше 1 файла в секции \"{section}\"", + "error.section.files.min.plural": "Секция \"{section}\" требует хотя бы {min} файлов", + "error.section.files.min.singular": "Секция \"{section}\" требует хотя бы 1 файл", + + "error.section.pages.max.plural": "Можно добавить не больше {max} страниц в секции \"{section}\"", + "error.section.pages.max.singular": "Нельзя добавить больше чем 1 страницу в секции \"{section}\"", + "error.section.pages.min.plural": "Секция \"{section}\" требует хотя бы {min} страниц", + "error.section.pages.min.singular": "Секция \"{section}\" требует хотя бы одну страницу", + + "error.section.notLoaded": "Секция \"{name}\" не может быть загружена", + "error.section.type.invalid": "Тип секции {type} неверный", + + "error.site.changeTitle.empty": "Название не может быть пустым", + "error.site.changeTitle.permission": "У вас нет права изменять название сайта", + "error.site.update.permission": "У вас нет права обновить сайт", + + "error.template.default.notFound": "Нет шаблона по умолчанию", + + "error.unexpected": "Произошла непредвиденная ошибка! Включите режим отладки для получения дополнительной информации: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "У вас нет права изменять Email пользователя \"{name}\"", + "error.user.changeLanguage.permission": "У вас нет права изменять язык для пользователя \"{name}\"", + "error.user.changeName.permission": "У вас нет права изменять имя пользователя \"{name}\"", + "error.user.changePassword.permission": "У вас нет права изменять пароль для пользователя \"{name}\"", + "error.user.changeRole.lastAdmin": "Роль единственного администратора нельзя изменить", + "error.user.changeRole.permission": "У вас нет права изменять роль пользователя \"{name}\"", + "error.user.changeRole.toAdmin": "У вас нет прав предоставить роль администратора", + "error.user.create.permission": "У вас нет права создать этого пользователя", + "error.user.delete": "\u0410\u043a\u043a\u0430\u0443\u043d\u0442 \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d", + "error.user.delete.lastAdmin": "\u0412\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u0430", + "error.user.delete.lastUser": "Нельзя удалить единственного пользователя", + "error.user.delete.permission": "У вас нет права удалить пользователя \"{name}\"", + "error.user.duplicate": "Пользователь с Email \"{email}\" уже есть", + "error.user.email.invalid": "Пожалуйста, введите правильный адрес эл. почты", + "error.user.language.invalid": "Введите правильный язык", + "error.user.notFound": "Пользователь \"{name}\" не найден", + "error.user.password.invalid": "Пожалуйста, введите правильный пароль. Он должен состоять минимум из 8 символов.", + "error.user.password.notSame": "\u041f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430, \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0434\u0438\u0442\u0435 \u043f\u0430\u0440\u043e\u043b\u044c", + "error.user.password.undefined": "У пользователя нет пароля", + "error.user.password.wrong": "Неверный пароль", + "error.user.role.invalid": "Введите правильную роль", + "error.user.undefined": "Аккаунт не найден", + "error.user.update.permission": "У вас нет права обновить пользователя \"{name}\"", + + "error.validation.accepted": "Пожалуйста, подтвердите", + "error.validation.alpha": "Пожалуйста, введите только буквы a-z", + "error.validation.alphanum": "Пожалуйста, введите только буквы a-z или числа 0-9", + "error.validation.between": "Пожалуйста, введите значение от \"{min}\" до \"{max}\"", + "error.validation.boolean": "Пожалуйста, подтвердите или отмените", + "error.validation.contains": "Пожалуйста, впишите значение, которое содержит \"{needle}\"", + "error.validation.date": "Пожалуйста, укажите правильную дату", + "error.validation.date.after": "Пожалуйста, укажите дату после {date}", + "error.validation.date.before": "Пожалуйста, укажите дату до {date}", + "error.validation.date.between": "Пожалуйста, укажите дату между {min} и {max}", + "error.validation.denied": "Пожалуйста отмените", + "error.validation.different": "Значение не может быть \"{other}\"", + "error.validation.email": "Пожалуйста, введите правильный Email", + "error.validation.endswith": "Значение должно заканчиваться с \"{end}\"", + "error.validation.filename": "Пожалуйста, введите правильное название файла", + "error.validation.in": "Пожалуйста, введите одно из следующих: ({in})", + "error.validation.integer": "Пожалуйста, введите правильное целое число", + "error.validation.ip": "Пожалуйста, введите правильный IP адрес", + "error.validation.less": "Пожалуйста, введите значение меньше чем {max}", + "error.validation.match": "Значение не соответствует ожидаемому шаблону", + "error.validation.max": "Пожалуйста, введите значение равное или больше чем {max}", + "error.validation.maxlength": "Пожалуйста, введите значение короче (макс. {max} символов)", + "error.validation.maxwords": "Пожалуйста, введите не более {max} слов ", + "error.validation.min": "Пожалуйста, введите значение равное или больше чем {min}", + "error.validation.minlength": "Пожалуйста, введите значение длиннее (мин. {min} символов)", + "error.validation.minwords": "Пожалуйста, введите хотя бы {min} слов", + "error.validation.more": "Пожалуйста, введите значение больше, чем {min}", + "error.validation.notcontains": "Пожалуйста, введите значение, которое не содержит \"{needle}\"", + "error.validation.notin": "Пожалуйста, не вписывайте одно из: ({notIn})", + "error.validation.option": "Пожалуйста, выберите правильную опцию ", + "error.validation.num": "Пожалуйста, введите правильный номер", + "error.validation.required": "Пожалуйста, введите что-нибудь", + "error.validation.same": "Пожалуйста, введите \"{other}\"", + "error.validation.size": "Значение размера должно быть \"{size}\"", + "error.validation.startswith": "Значение должно начинаться с \"{start}\"", + "error.validation.time": "Пожалуйста, введите правильную дату", + "error.validation.time.after": "Пожалуйста, укажите время после {time}", + "error.validation.time.before": "Пожалуйста, укажите время до {time}", + "error.validation.time.between": "Пожалуйста, укажите время между {min} и {max}", + "error.validation.url": "Пожалуйста, введите правильный URL", + + "expand": "Развернуть", + "expand.all": "Развернуть все", + + "field.required": "Поле обязательно", + "field.blocks.changeType": "Изменить тип", + "field.blocks.code.name": "Код", + "field.blocks.code.language": "Язык", + "field.blocks.code.placeholder": "Ваш код …", + "field.blocks.delete.confirm": "Вы действительно хотите удалить этот блок?", + "field.blocks.delete.confirm.all": "Вы действительно хотите удалить все блоки?", + "field.blocks.delete.confirm.selected": "Вы действительно хотите удалить эти блоки?", + "field.blocks.empty": "Блоков нет", + "field.blocks.fieldsets.label": "Пожалуйста, выберите тип блока…", + "field.blocks.fieldsets.paste": "Нажмите {{ shortcut }} чтобы вставить/импортировать блоки из буфера памяти", + "field.blocks.gallery.name": "Галерея", + "field.blocks.gallery.images.empty": "Изображений нет", + "field.blocks.gallery.images.label": "Изображения", + "field.blocks.heading.level": "Уровень", + "field.blocks.heading.name": "Заголовок", + "field.blocks.heading.text": "Текст", + "field.blocks.heading.placeholder": "Заголовок …", + "field.blocks.image.alt": "Альтернативный текст", + "field.blocks.image.caption": "Подпись", + "field.blocks.image.crop": "Обрезать", + "field.blocks.image.link": "Ссылка", + "field.blocks.image.location": "Расположение", + "field.blocks.image.name": "Картинка", + "field.blocks.image.placeholder": "Выберите изображение", + "field.blocks.image.ratio": "Соотношение", + "field.blocks.image.url": "URL изображения", + "field.blocks.line.name": "Линия", + "field.blocks.list.name": "Список", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Текст", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Цитата", + "field.blocks.quote.text.label": "Текст", + "field.blocks.quote.text.placeholder": "Цитата …", + "field.blocks.quote.citation.label": "Цитирование", + "field.blocks.quote.citation.placeholder": "Автор …", + "field.blocks.text.name": "Текст", + "field.blocks.text.placeholder": "Текст …", + "field.blocks.video.caption": "Подпись", + "field.blocks.video.name": "Видео", + "field.blocks.video.placeholder": "Введите ссылку на видео", + "field.blocks.video.url.label": "Ссылка на видео", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Файлы не выбраны", + + "field.layout.delete": "Удалить разметку", + "field.layout.delete.confirm": "Вы действительно хотите удалить эту разметку?", + "field.layout.empty": "Строк нет", + "field.layout.select": "Выберите разметку", + + "field.object.empty": "Пока нет информации", + + "field.pages.empty": "Страницы не выбраны", + + "field.structure.delete.confirm": "Вы точно хотите удалить эту запись?", + "field.structure.empty": "Записей нет", + + "field.users.empty": "Пользователей нет", + + "file.blueprint": "У файла пока нет разметки. Вы можете определить новые секции и поля разметки в /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Вы точно хотите удалить файл
{filename}?", + "file.sort": "Изменить позицию", + + "files": "Файлы", + "files.empty": "Еще нет файлов", + + "hide": "Скрыть", + "hour": "Час", + "import": "Импортировать", + "info": "Информация", + "insert": "\u0412\u0441\u0442\u0430\u0432\u0438\u0442\u044c", + "insert.after": "Вставить ниже", + "insert.before": "Вставить выше", + "install": "Установить", + + "installation": "Установка", + "installation.completed": "Панель установлена", + "installation.disabled": "Установка панели по умолчанию отключена на общедоступных серверах. Пожалуйста запустите установку на локальном сервере или включите такую возможность с помощью опции panel.install", + "installation.issues.accounts": "Каталог /site/accounts не существует или не имеет прав записи", + "installation.issues.content": "Каталог /content не существует или не имеет прав записи", + "installation.issues.curl": "Расширение CURL необходимо", + "installation.issues.headline": "Не удалось установить панель", + "installation.issues.mbstring": "Расширение MB String необходимо", + "installation.issues.media": "Каталог /media не существует или нет прав записи", + "installation.issues.php": "Убедитесь, что используется PHP 7+", + "installation.issues.server": "Kirby требует Apache, Nginx или Caddy ", + "installation.issues.sessions": "Каталог /site/sessions не существует или нет прав записи", + + "language": "\u042f\u0437\u044b\u043a", + "language.code": "Код", + "language.convert": "Установить по умолчанию", + "language.convert.confirm": "

Вы точно хотите конвертировать {name} в главный язык? Это нельзя будет отменить.

Если {name} имеет непереведенный контент, то больше не будет верного каскада и части вашего сайта могут быть пустыми.

", + "language.create": "Добавить новый язык", + "language.delete.confirm": "Вы точно хотите удалить {name} язык, включая все переводы? Это нельзя будет вернуть.", + "language.deleted": "Язык удален", + "language.direction": "Направление чтения", + "language.direction.ltr": "Слева направо", + "language.direction.rtl": "Справа налево", + "language.locale": "PHP locale string", + "language.locale.warning": "Вы используете кастомную локаль. Пожалуйста измените ее в файле языка в /site/languages", + "language.name": "Название", + "language.updated": "Язык обновлен", + + "languages": "Языки", + "languages.default": "Главный язык", + "languages.empty": "Языков нет", + "languages.secondary": "Дополнительные языки", + "languages.secondary.empty": "Дополнительных языков нет", + + "license": "Лицензия", + "license.buy": "Купить лицензию", + "license.register": "Зарегистрировать", + "license.manage": "Управление лицензиями", + "license.register.help": "После покупки вы получили по эл. почте код лицензии. Пожалуйста скопируйте и вставьте сюда чтобы зарегистрировать.", + "license.register.label": "Пожалуйста вставьте код лицензии", + "license.register.success": "Спасибо за поддержку Kirby", + "license.unregistered": "Это незарегистрированная версия Kirby", + "license.unregistered.label": "Не зарегистрировано", + + "link": "\u0421\u0441\u044b\u043b\u043a\u0430", + "link.text": "\u0422\u0435\u043a\u0441\u0442 \u0441\u0441\u044b\u043b\u043a\u0438", + + "loading": "Загрузка", + + "lock.unsaved": "Несохраненные изменения", + "lock.unsaved.empty": "Несохраненных изменений больше нет", + "lock.isLocked": "Несохраненные изменения пользователя {email}", + "lock.file.isLocked": "В данный момент этот файл редактирует {email}, поэтому его нельзя изменить.", + "lock.page.isLocked": "В данный момент эту страницу редактирует {email}, поэтому его нельзя изменить.", + "lock.unlock": "Разблокировать", + "lock.isUnlocked": "Ваши несохраненные изменения были перезаписаны другим пользователем. Вы можете загрузить ваши изменения и объединить их вручную.", + + "login": "Войти", + "login.code.label.login": "Код для входа", + "login.code.label.password-reset": "Код для сброса пароля", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "Если ваш Email уже зарегистрирован, запрашиваемый код был отправлен на него.", + "login.email.login.body": "Привет, {user.nameOrEmail}!\n\nНедавно вы запросили код для входа на «{site}».\nСледующий код входа будет действителен в течение {timeout} минут:\n\n{code}\n\nЕсли вы не запрашивали код для входа, проигнорируйте это письмо или обратитесь к администратору, если у вас есть вопросы.\nВ целях безопасности НЕ ПЕРЕСЫЛАЙТЕ это письмо.", + "login.email.login.subject": "Ваш код для входа", + "login.email.password-reset.body": "Привет, {user.nameOrEmail}!\n\nНедавно вы запросили сброс пароля для входа на «{site}».\nСледующий код входа будет действителен в течение {timeout} минут:\n\n{code}\n\nЕсли вы не запрашивали сброс пароля, проигнорируйте это письмо или обратитесь к администратору, если у вас есть вопросы.\nВ целях безопасности НЕ ПЕРЕСЫЛАЙТЕ это письмо.", + "login.email.password-reset.subject": "Ваш код для сброса пароля", + "login.remember": "Сохранять вход активным", + "login.reset": "Сбросить пароль", + "login.toggleText.code.email": "Вход с помощью Email", + "login.toggleText.code.email-password": "Вход с паролем", + "login.toggleText.password-reset.email": "Забыли ваш пароль?", + "login.toggleText.password-reset.email-password": "← Вернуться к форме входа", + + "logout": "Выйти", + + "menu": "Меню", + "meridiem": "До полудня / После полудня", + "mime": "Тип медиа", + "minutes": "Минуты", + + "month": "Месяц", + "months.april": "\u0410\u043f\u0440\u0435\u043b\u044c", + "months.august": "\u0410\u0432\u0433\u0443\u0441\u0442", + "months.december": "\u0414\u0435\u043a\u0430\u0431\u0440\u044c", + "months.february": "Февраль", + "months.january": "\u042f\u043d\u0432\u0430\u0440\u044c", + "months.july": "\u0418\u044e\u043b\u044c", + "months.june": "\u0418\u044e\u043d\u044c", + "months.march": "\u041c\u0430\u0440\u0442", + "months.may": "\u041c\u0430\u0439", + "months.november": "\u041d\u043e\u044f\u0431\u0440\u044c", + "months.october": "\u041e\u043a\u0442\u044f\u0431\u0440\u044c", + "months.september": "\u0421\u0435\u043d\u0442\u044f\u0431\u0440\u044c", + + "more": "Подробнее", + "name": "Название", + "next": "Дальше", + "no": "нет", + "off": "выключено", + "on": "включено", + "open": "Открыть", + "open.newWindow": "Открывать в новом окне", + "options": "Опции", + "options.none": "Параметров нет", + + "orientation": "Ориентация", + "orientation.landscape": "Горизонтальная", + "orientation.portrait": "Портретная", + "orientation.square": "Квадрат", + + "page.blueprint": "У страницы пока нет разметки. Вы можете определить новые секции и поля разметки в /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Изменить ссылку", + "page.changeSlug.fromTitle": "Создать из названия", + "page.changeStatus": "Изменить статус", + "page.changeStatus.position": "Пожалуйста, выберите позицию", + "page.changeStatus.select": "Выбрать новый статус", + "page.changeTemplate": "Изменить шаблон", + "page.delete.confirm": "Вы точно хотите удалить страницу {title}?", + "page.delete.confirm.subpages": "У этой страницы есть внутренние страницы.
Все внутренние страницы так же будут удалены.", + "page.delete.confirm.title": "Напишите название страницы, чтобы подтвердить", + "page.draft.create": "Создать черновик", + "page.duplicate.appendix": "(копия)", + "page.duplicate.files": "Копировать файлы", + "page.duplicate.pages": "Копировать страницы", + "page.sort": "Изменить позицию", + "page.status": "Статус", + "page.status.draft": "Черновик", + "page.status.draft.description": "Страница находится в черновом режиме и видна только зарегистрированным пользователям или по секретной ссылке", + "page.status.listed": "Опубликована", + "page.status.listed.description": "Страница доступна для всех посетителей", + "page.status.unlisted": "Скрыта", + "page.status.unlisted.description": "Страница доступна только по URL", + + "pages": "Страницы", + "pages.empty": "Страниц нет", + "pages.status.draft": "Черновики", + "pages.status.listed": "Опубликовано", + "pages.status.unlisted": "Скрытая", + + "pagination.page": "Страница", + + "password": "\u041f\u0430\u0440\u043e\u043b\u044c", + "paste": "Вставить", + "paste.after": "Вставить после", + "pixel": "Пиксель", + "plugin": "Расширение", + "plugins": "Плагины", + "prev": "Предыдущий", + "preview": "Предпросмотр", + "remove": "Удалить", + "rename": "Переназвать", + "replace": "\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c", + "retry": "\u041f\u043e\u0432\u0442\u043e\u0440\u0438\u0442\u044c", + "revert": "\u0421\u0431\u0440\u043e\u0441", + "revert.confirm": "Вы действительно хотите удалить все несохраненные изменения?", + + "role": "\u0420\u043e\u043b\u044c", + "role.admin.description": "Администратор имеет все права", + "role.admin.title": "Администратор", + "role.all": "Все", + "role.empty": "Пользователей с такой ролью нет", + "role.description.placeholder": "Без описания", + "role.nobody.description": "Эта роль применяется если у пользователя нет никаких прав", + "role.nobody.title": "Никто", + + "save": "\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c", + "search": "Поиск", + "search.min": "Введите хотя бы {min} символов для поиска", + "search.all": "Показать все", + "search.results.none": "Нет результатов", + + "section.required": "Секция обязательна", + + "security": "Безопасность", + "select": "Выбрать", + "server": "Сервер", + "settings": "Настройка", + "show": "Показать", + "site.blueprint": "У сайта пока нет разметки. Вы можете определить новые секции и поля разметки в /site/blueprints/site.yml", + "size": "Размер", + "slug": "Понятная ссылка", + "sort": "Сортировать", + + "stats.empty": "Статистики нет", + "system.issues.content": "Похоже, к папке content есть несанкционированный доступ", + "system.issues.eol.kirby": "Срок службы установленной вами версии Kirby истек, и она больше не будет получать обновления для системы безопасности", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Включен режим отладки (debugging). Используйте его только при разработке.", + "system.issues.git": "Похоже, к папке .git есть несанкционированный доступ", + "system.issues.https": "Рекомендуется использовать HTTPS на всех сайтах", + "system.issues.kirby": "Похоже, к папке kirby есть несанкционированный доступ", + "system.issues.site": "Похоже, к папке site есть несанкционированный доступ", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Не удалось проверить обновления", + "system.updateStatus.not-vulnerable": "Известных уязвимостей не выявлено", + "system.updateStatus.security-update": "Доступно бесплатное обновление для системы безопасности { version }", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Последняя версия", + "system.updateStatus.update": "Доступно бесплатное обновление { version }", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Название", + "template": "\u0428\u0430\u0431\u043b\u043e\u043d", + "today": "Сегодня", + + "toolbar.button.code": "Код", + "toolbar.button.bold": "\u0416\u0438\u0440\u043d\u044b\u0439 \u0448\u0440\u0438\u0444\u0442", + "toolbar.button.email": "Email", + "toolbar.button.headings": "Заголовки", + "toolbar.button.heading.1": "Заголовок 1", + "toolbar.button.heading.2": "Заголовок 2", + "toolbar.button.heading.3": "Заголовок 3", + "toolbar.button.heading.4": "Заголовок 4", + "toolbar.button.heading.5": "Заголовок 5", + "toolbar.button.heading.6": "Заголовок 6", + "toolbar.button.italic": "Курсив", + "toolbar.button.file": "Файл", + "toolbar.button.file.select": "Выбрать файл", + "toolbar.button.file.upload": "Закачать файл", + "toolbar.button.link": "\u0421\u0441\u044b\u043b\u043a\u0430", + "toolbar.button.paragraph": "Параграф", + "toolbar.button.strike": "Зачёркнутый", + "toolbar.button.ol": "Нумерованный список", + "toolbar.button.underline": "Подчёркнутый", + "toolbar.button.ul": "Маркированный список", + + "translation.author": "Команда Kirby", + "translation.direction": "ltr", + "translation.name": "Русский (Russian)", + "translation.locale": "ru_RU", + + "upload": "Закачать", + "upload.error.cantMove": "Не удается переместить загруженный файл", + "upload.error.cantWrite": "Не получилось записать файл на диск", + "upload.error.default": "Не удалось загрузить файл", + "upload.error.extension": "Загрузка файла не удалась из за расширения", + "upload.error.formSize": "Загруженный файл больше чем MAX_FILE_SIZE настройка в форме", + "upload.error.iniPostSize": "Загружаемый файл больше чем post_max_size настройка в php.ini", + "upload.error.iniSize": "Загруженный файл больше чем настройка upload_max_filesize в php.ini", + "upload.error.noFile": "Файл не был загружен", + "upload.error.noFiles": "Файлы не были загружены", + "upload.error.partial": "Файл загружен только частично", + "upload.error.tmpDir": "Не хватает временной папки", + "upload.errors": "Ошибка", + "upload.progress": "Закачивается...", + + "url": "URL", + "url.placeholder": "https://example.com", + + "user": "Пользователь", + "user.blueprint": "Вы можете определить новые секции и поля разметки для пользователя в /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Изменить Email", + "user.changeLanguage": "Изменить язык", + "user.changeName": "Переназвать этого пользователя", + "user.changePassword": "Изменить пароль", + "user.changePassword.new": "Новый пароль", + "user.changePassword.new.confirm": "Подтвердить новый пароль…", + "user.changeRole": "Изменить роль", + "user.changeRole.select": "Выбрать новую роль", + "user.create": "Добавить нового пользователя", + "user.delete": "Удалить этого пользователя", + "user.delete.confirm": "Вы действительно хотите аккаунт
{email}?", + + "users": "Пользователи", + + "version": "Версия", + "version.current": "Текущая версия", + "version.latest": "Последняя версия", + "versionInformation": "Version information", + + "view.account": "\u0412\u0430\u0448 \u0430\u043a\u043a\u0430\u0443\u043d\u0442", + "view.installation": "\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430", + "view.languages": "Языки", + "view.resetPassword": "Сбросить пароль", + "view.site": "Сайт", + "view.system": "Система", + "view.users": "\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438", + + "welcome": "Добро пожаловать", + "year": "Год", + "yes": "да" } diff --git a/kirby/i18n/translations/sk.json b/kirby/i18n/translations/sk.json index a7d53d2..b1e9455 100644 --- a/kirby/i18n/translations/sk.json +++ b/kirby/i18n/translations/sk.json @@ -1,573 +1,596 @@ { - "account.changeName": "Change your name", - "account.delete": "Delete your account", - "account.delete.confirm": "Do you really want to delete your account? You will be logged out immediately. Your account cannot be recovered.", - - "add": "Pridať", - "author": "Author", - "avatar": "Profilový obrázok", - "back": "Späť", - "cancel": "Zrušiť", - "change": "Zmeniť", - "close": "Zavrieť", - "confirm": "Ok", - "collapse": "Zabaliť", - "collapse.all": "Zabaliť všetky", - "copy": "Kopírovať", - "copy.all": "Copy all", - "create": "Vytvoriť", - - "date": "Dátum", - "date.select": "Zvoliť dátum", - - "day": "Deň", - "days.fri": "Pia", - "days.mon": "Pon", - "days.sat": "Sob", - "days.sun": "Ned", - "days.thu": "Štv", - "days.tue": "Uto", - "days.wed": "Str", - - "debugging": "Debugging", - - "delete": "Zmazať", - "delete.all": "Zmazať všetky", - - "dialog.files.empty": "No files to select", - "dialog.pages.empty": "No pages to select", - "dialog.users.empty": "No users to select", - - "dimensions": "Rozmery", - "disabled": "Disabled", - "discard": "Zahodiť", - "download": "Stiahnuť", - "duplicate": "Duplikovať", - - "edit": "Upraviť", - - "email": "E-mail", - "email.placeholder": "mail@example.com", - - "entries": "Entries", - "entry": "Entry", - - "environment": "Environment", - - "error.access.code": "Neplatný kód", - "error.access.login": "Neplatné prihlásenie", - "error.access.panel": "Nemáte povolenie na prístup do Panel-u", - "error.access.view": "You are not allowed to access this part of the panel", - - "error.avatar.create.fail": "Profilový obrázok sa nepodarilo nahrať", - "error.avatar.delete.fail": "Profilový obrázok sa nepodarilo zmazať", - "error.avatar.dimensions.invalid": "Prosím, dodržte, aby šírka a výška profilového obrázka bola menšia ako 3000 pixelov.", - "error.avatar.mime.forbidden": "Profilový obrázok musí byť súbor JPEG alebo PNG.", - - "error.blueprint.notFound": "Blueprint \"{name}\" sa nepodarilo načítať", - - "error.blocks.max.plural": "You must not add more than {max} blocks", - "error.blocks.max.singular": "You must not add more than one block", - "error.blocks.min.plural": "You must add at least {min} blocks", - "error.blocks.min.singular": "You must add at least one block", - "error.blocks.validation": "There's an error in block {index}", - - "error.email.preset.notFound": "E-mailovú predvoľbu \"{name}\" nie je možné nájsť", - - "error.field.converter.invalid": "Neplatný converter \"{converter}\"", - - "error.file.changeName.empty": "Meno nesmie byť prázdne", - "error.file.changeName.permission": "Nemáte povolenie na zmenu názvu pre \"{filename}\"", - "error.file.duplicate": "Súbor s názvom \"{filename}\" už existuje", - "error.file.extension.forbidden": "Prípona \"{extension}\" nie je povolená", - "error.file.extension.invalid": "Neplatná prípona: \"{extension}\"", - "error.file.extension.missing": "Prípona pre \"{filename}\" chýba", - "error.file.maxheight": "Výška obrázku nesmie prekročiť \"{height}\" pixelov", - "error.file.maxsize": "Súbor je príliš velký", - "error.file.maxwidth": "Šírka obrázku nesmie prekročiť \"{width}\" pixelov", - "error.file.mime.differs": "Mime typ nahratého súboru msa musí zhodovať s \"{mime}\"", - "error.file.mime.forbidden": "Typ média \"{mime}\" nie je povolený", - "error.file.mime.invalid": "Neplatný mime typ: \"{mime}\"", - "error.file.mime.missing": "Typ média pre \"{filename}\" sa nepodarilo zistiť", - "error.file.minheight": "Výška obrázku musí byť aspoň \"{height}\" pixelov", - "error.file.minsize": "Súbor je príliš malý", - "error.file.minwidth": "Šírka obrázku musí byť aspoň \"{width}\" pixelov", - "error.file.name.missing": "Názov súboru nemôže byť prázdny", - "error.file.notFound": "Súbor \"{filename}\" sa nepodarilo nájsť", - "error.file.orientation": "The orientation of the image must be \"{orientation}\"", - "error.file.type.forbidden": "Nemáte povolenie na nahrávanie súborov s typom {type}", - "error.file.type.invalid": "Neplatný typ súboru: \"{type}\"", - "error.file.undefined": "Súbor nie je možné nájsť", - - "error.form.incomplete": "Prosím, opravte všetky chyby v rámci formuláru...", - "error.form.notSaved": "Formulár sa nepodarilo uložiť", - - "error.language.code": "Please enter a valid code for the language", - "error.language.duplicate": "The language already exists", - "error.language.name": "Please enter a valid name for the language", - "error.language.notFound": "The language could not be found", - - "error.layout.validation.block": "There's an error in block {blockIndex} in layout {layoutIndex}", - "error.layout.validation.settings": "There's an error in layout {index} settings", - - "error.license.format": "Please enter a valid license key", - "error.license.email": "Prosím, zadajte platnú e-mailovú adresu", - "error.license.verification": "The license could not be verified", - - "error.offline": "The Panel is currently offline", - - "error.page.changeSlug.permission": "Nemáte povolenie na zmenu URL príponu pre \"{slug}\"", - "error.page.changeStatus.incomplete": "Stránka obsahuje chyby a nemôže byť zverejnená", - "error.page.changeStatus.permission": "Status tejto stránky nemôže byť zmenený", - "error.page.changeStatus.toDraft.invalid": "Stránka \"{slug}\" nemôže byť zmenená na koncept.", - "error.page.changeTemplate.invalid": "Šablónu pre stránku \"{slug}\" nie je možné zmeniť", - "error.page.changeTemplate.permission": "Nemáte povolenie na zmenu šablóny pre \"{slug}\"", - "error.page.changeTitle.empty": "Titulok nemôže byť prázdny", - "error.page.changeTitle.permission": "Nemáte povolenie na zmenu titulku pre \"{slug}\"", - "error.page.create.permission": "Nemáte povolenie na vytvorenie \"{slug}\"", - "error.page.delete": "Stránku \"{slug}\" nie je možné vymazať", - "error.page.delete.confirm": "Prosím, zadajte titulok stránky pre potvrdenie", - "error.page.delete.hasChildren": "Táto stránka obsahuje podstránky a nemôže byť zmazaná", - "error.page.delete.permission": "Nemáte povolenie na zmazanie stránky \"{slug}\"", - "error.page.draft.duplicate": "Koncept stránky s URL appendix-om \"{slug}\" už existuje", - "error.page.duplicate": "Stránka s URL appendix-om \"{slug}\" už existuje", - "error.page.duplicate.permission": "You are not allowed to duplicate \"{slug}\"", - "error.page.notFound": "Stránku \"{slug}\" nie je možné nájsť", - "error.page.num.invalid": "Prosím, zadajte platné číslo pre radenie. Čísla nemôžu byť záporné.", - "error.page.slug.invalid": "Please enter a valid URL appendix", - "error.page.slug.maxlength": "Slug length must be less than \"{length}\" characters", - "error.page.sort.permission": "Stránku \"{slug}\" nie je možné preradiť.", - "error.page.status.invalid": "Prosím, nastavte platnú status pre stránku", - "error.page.undefined": "Stránku nie je možné nájsť", - "error.page.update.permission": "Nemáte povolenie na aktualizáciu \"{slug}\"", - - "error.section.files.max.plural": "Nemôžete pridať viac ako {max} súbory/ov do sekcie \"{section}\"", - "error.section.files.max.singular": "Nemôžete pridať viac ako 1 súbor do sekcie \"{section}\"", - "error.section.files.min.plural": "The \"{section}\" section requires at least {min} files", - "error.section.files.min.singular": "The \"{section}\" section requires at least one file", - - "error.section.pages.max.plural": "Nemôžete pridať viac ako {max} stránky/ok do sekcie \"{section}\"", - "error.section.pages.max.singular": "Nemôžete pridať viac ako 1 stránku do sekcie \"{section}\"", - "error.section.pages.min.plural": "The \"{section}\" section requires at least {min} pages", - "error.section.pages.min.singular": "The \"{section}\" section requires at least one page", - - "error.section.notLoaded": "Sekciu \"{name}\" sa nepodarilo nahrať", - "error.section.type.invalid": "Typ sekcie \"{type}\" nie je platný", - - "error.site.changeTitle.empty": "Titulok nemôže byť prázdny", - "error.site.changeTitle.permission": "Nemáte povolenie na zmenu titulku pre portál", - "error.site.update.permission": "Nemáte povolenie na aktualizovanie portálu", - - "error.template.default.notFound": "Predvolená šablóna neexistuje", - - "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Nemáte povolenie na zmenu e-mailu pre užívateľa \"{name}\"", - "error.user.changeLanguage.permission": "Nemáte povolenie na zmenu jazyka pre užívateľa \"{name}\"", - "error.user.changeName.permission": "Nemáte povolenie na zmenu mena pre užívateľa \"{name}\"", - "error.user.changePassword.permission": "Nemáte povolenie na zmenu hesla pre užívateľa \"{name}\"", - "error.user.changeRole.lastAdmin": "Rolu pre posledného administrátora nie je možné zmeniť", - "error.user.changeRole.permission": "Nemáte povolenie na zmenu role pre užívateľa \"{name}\"", - "error.user.changeRole.toAdmin": "You are not allowed to promote someone to the admin role", - "error.user.create.permission": "Nemáte povolenie na vytvorenie tohto užívateľa", - "error.user.delete": "Užívateľa \"{name}\" nie je možné zmazať", - "error.user.delete.lastAdmin": "Posledného administrátora nie je možné zmazať", - "error.user.delete.lastUser": "Posledného užívateľa nie je možné zmazať", - "error.user.delete.permission": "Nemáte povolenie na zmazanie užívateľa \"{name}\"", - "error.user.duplicate": "Užívateľ s e-mailovou adresou \"{email}\" už existuje", - "error.user.email.invalid": "Prosím, zadajte platnú e-mailovú adresu", - "error.user.language.invalid": "Prosím, zadajte platný jazyk", - "error.user.notFound": "Užívateľa \"{name}\" nie je možné nájsť", - "error.user.password.invalid": "Prosím, zadajte platné heslo. Dĺžka hesla musí byť aspoň 8 znakov.", - "error.user.password.notSame": "Heslá nie sú rovnaké", - "error.user.password.undefined": "Užívateľ nemá heslo", - "error.user.password.wrong": "Wrong password", - "error.user.role.invalid": "Prosím, zadajte platnú rolu", - "error.user.undefined": "Užívateľa sa nepodarilo nájsť", - "error.user.update.permission": "Nemáte povolenie na aktualizáciu užívateľa \"{name}\"", - - "error.validation.accepted": "Prosím, potvrďte", - "error.validation.alpha": "Prosím, zadajte len znaky z hlások a-z", - "error.validation.alphanum": "Prosím, zadajte len znaky z hlások a-z a čísloviek 0-9", - "error.validation.between": "Prosím, zadajte hodnotu od \"{min}\" do \"{max}\"", - "error.validation.boolean": "Prosím, potvrďte alebo odmietnite", - "error.validation.contains": "Prosím, zadajte hodnotu, ktorá obsahuje \"{needle}\"", - "error.validation.date": "Prosím, zadajte platný dátum", - "error.validation.date.after": "Please enter a date after {date}", - "error.validation.date.before": "Please enter a date before {date}", - "error.validation.date.between": "Please enter a date between {min} and {max}", - "error.validation.denied": "Prosím, odmietnite", - "error.validation.different": "Hodnota nemôže byť \"{other}\"", - "error.validation.email": "Prosím, zadajte platnú e-mailovú adresu", - "error.validation.endswith": "Hodnota musí končiť na \"{end}\"", - "error.validation.filename": "Prosím, zadajte platný názov súboru", - "error.validation.in": "Prosím, zadajte jedno z nasledujúcich: ({in})", - "error.validation.integer": "Prosím, zadajte platné celé číslo", - "error.validation.ip": "Prosím, zadajte platnú e-mailovú adresu", - "error.validation.less": "Prosím, zadajte hodnotu menšiu ako {max}", - "error.validation.match": "Hodnota nezodpovedá očakávanému vzoru", - "error.validation.max": "Prosím, zadajte hodnotu rovnú alebo menšiu ako {max}", - "error.validation.maxlength": "Prosím, zadajte kratšiu hodnotu. (max. {max} charaktery/ov)", - "error.validation.maxwords": "Prosím, nezadávajte viac ako {max} slovo/á/ov", - "error.validation.min": "Prosím, zadajte hodnotu rovnú alebo väčšiu ako {min}", - "error.validation.minlength": "Prosím, zadajte dlhšiu hodnotu. (min. {min} charaktery/ov)", - "error.validation.minwords": "Prosím, zadajte aspoň {min} slovo/á/ov", - "error.validation.more": "Prosím zadajte hodnotu väčšiu ako {min}", - "error.validation.notcontains": "Prosím, zadajte hodnotu, ktorá neobsahuje \"{needle}\"", - "error.validation.notin": "Prosím, nezadávajte ani jedno z nasledujúcich: ({notIn})", - "error.validation.option": "Prosím, zadajte platnú voľbu", - "error.validation.num": "Prosím, zadajte platné číslo", - "error.validation.required": "Prosím, zadajte niečo", - "error.validation.same": "Prosím, zadajte \"{other}\"", - "error.validation.size": "Veľkosť hodnoty musí byť \"{size}\"", - "error.validation.startswith": "Hodnota musí začínať s \"{start}\"", - "error.validation.time": "Prosím, zadajte platný čas", - "error.validation.time.after": "Please enter a time after {time}", - "error.validation.time.before": "Please enter a time before {time}", - "error.validation.time.between": "Please enter a time between {min} and {max}", - "error.validation.url": "Prosím, zadajte platnú URL", - - "expand": "Rozbaliť", - "expand.all": "Rozbaliť všetky", - - "field.required": "The field is required", - "field.blocks.changeType": "Change type", - "field.blocks.code.name": "Kód", - "field.blocks.code.language": "Jazyk", - "field.blocks.code.placeholder": "Váš kód ...", - "field.blocks.delete.confirm": "Naozaj chcete zmazať tento blok?", - "field.blocks.delete.confirm.all": "Naozaj chcete zmazať všetky bloky?", - "field.blocks.delete.confirm.selected": "Naozaj chcete zmazať vybrané bloky?", - "field.blocks.empty": "No blocks yet", - "field.blocks.fieldsets.label": "Please select a block type …", - "field.blocks.fieldsets.paste": "Press {{ shortcut }} to paste/import blocks from your clipboard", - "field.blocks.gallery.name": "Galéria", - "field.blocks.gallery.images.empty": "No images yet", - "field.blocks.gallery.images.label": "Obrázky", - "field.blocks.heading.level": "Level", - "field.blocks.heading.name": "Nadpis", - "field.blocks.heading.text": "Text", - "field.blocks.heading.placeholder": "Nadpis ...", - "field.blocks.image.alt": "Alternative text", - "field.blocks.image.caption": "Popis", - "field.blocks.image.crop": "Orezanie", - "field.blocks.image.link": "Odkaz", - "field.blocks.image.location": "Poloha", - "field.blocks.image.name": "Obrázok", - "field.blocks.image.placeholder": "Select an image", - "field.blocks.image.ratio": "Ratio", - "field.blocks.image.url": "Image URL", - "field.blocks.line.name": "Line", - "field.blocks.list.name": "List", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Text", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Quote", - "field.blocks.quote.text.label": "Text", - "field.blocks.quote.text.placeholder": "Quote …", - "field.blocks.quote.citation.label": "Citation", - "field.blocks.quote.citation.placeholder": "by …", - "field.blocks.text.name": "Text", - "field.blocks.text.placeholder": "Text …", - "field.blocks.video.caption": "Popis", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Enter a video URL", - "field.blocks.video.url.label": "Video-URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Žiadne súbory zatiaľ neboli zvolené", - - "field.layout.delete": "Delete layout", - "field.layout.delete.confirm": "Do you really want to delete this layout?", - "field.layout.empty": "No rows yet", - "field.layout.select": "Select a layout", - - "field.pages.empty": "Žiadne stránky zatiaľ neboli zvolené", - "field.structure.delete.confirm": "Ste si istý, že chcete zmazať tento riadok?", - "field.structure.empty": "Zatiaľ žiadne údaje", - "field.users.empty": "Žiadni užívatelia zatiaľ neboli zvolení", - - "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Ste si istý, že chcete zmazať
{filename}?", - "file.sort": "Change position", - - "files": "Súbory", - "files.empty": "Zatiaľ žiadne súbory", - - "hide": "Hide", - "hour": "Hodina", - "import": "Import", - "info": "Info", - "insert": "Vložiť", - "insert.after": "Insert after", - "insert.before": "Insert before", - "install": "Inštalovať", - - "installation": "Inštalácia", - "installation.completed": "Panel bol nainštalovaný", - "installation.disabled": "Inštalácia Panelu na verejných serveroch je štandardne zablokovaná. Prosím, spustite inštaláciu na lokálnom serveri alebo aktivujte voľbu panel.install.", - "installation.issues.accounts": "Priečinok /site/accounts neexistuje alebo nie je nastavený ako zapisovateľný", - "installation.issues.content": "Priečinok /content neexistuje alebo nie je nastavený ako zapisovateľný", - "installation.issues.curl": "CURL rozšírenie je povinné", - "installation.issues.headline": "Panel nie je možné naištalovať", - "installation.issues.mbstring": "MB String rozšírenie je povinné", - "installation.issues.media": "Priečinok /media neexistuje alebo nie je nastavený ako zapisovateľný", - "installation.issues.php": "Uistite sa, že používate PHP 7+", - "installation.issues.server": "Kirby vyžaduje Apache, Nginx alebo Caddy", - "installation.issues.sessions": "Priečinok /site/sessions neexistuje alebo nie je nastavený ako zapisovateľný", - - "language": "Jazyk", - "language.code": "Kód", - "language.convert": "Nastaviť ako predvolené", - "language.convert.confirm": "

Ste si istý, že chcete nastaviť {name} ako predvolený jazyk? Túto akciu nie je možné zvrátiť.

Ak {name} obsahuje nepreložený obsah, tak pre tento obsah nebude fungovať platné volanie a niektoré časti vašich stránok zostanú prázdne.

", - "language.create": "Pridať nový jazyk", - "language.delete.confirm": "Ste si istý, že chcete zmazať jazyk {name} vrátane všetkých prekladov? Túto akciu nie je možné zvrátiť.", - "language.deleted": "Jazyk bol zmazaný", - "language.direction": "Smer čítania", - "language.direction.ltr": "Zľava doprava", - "language.direction.rtl": "Zprava doľava", - "language.locale": "PHP locale string", - "language.locale.warning": "You are using a custom locale set up. Please modify it in the language file in /site/languages", - "language.name": "Názov", - "language.updated": "Jazyk bol aktualizovaný", - - "languages": "Jazyky", - "languages.default": "Predvolený jazyk", - "languages.empty": "Zatiaľ žiadne jazyky", - "languages.secondary": "Sekundárne jazyky", - "languages.secondary.empty": "Zatiaľ žiadne sekundárne jazyky", - - "license": "Licencia", - "license.buy": "Zakúpiť licenciu", - "license.register": "Registrovať", - "license.manage": "Manage your licenses", - "license.register.help": "Licenčný kód vám bol doručený e-mailom po úspešnom nákupe. Prosím, skopírujte a prilepte ho na uskutočnenie registrácie.", - "license.register.label": "Prosím, zadajte váš licenčný kód", - "license.register.success": "Ďakujeme za vašu podporu Kirby", - "license.unregistered": "Toto je neregistrované demo Kirby", - "license.unregistered.label": "Unregistered", - - "link": "Odkaz", - "link.text": "Text odkazu", - - "loading": "Načítavanie", - - "lock.unsaved": "Unsaved changes", - "lock.unsaved.empty": "There are no more unsaved changes", - "lock.isLocked": "Unsaved changes by {email}", - "lock.file.isLocked": "The file is currently being edited by {email} and cannot be changed.", - "lock.page.isLocked": "The page is currently being edited by {email} and cannot be changed.", - "lock.unlock": "Unlock", - "lock.isUnlocked": "Your unsaved changes have been overwritten by another user. You can download your changes to merge them manually.", - - "login": "Prihlásenie", - "login.code.label.login": "Login code", - "login.code.label.password-reset": "Password reset code", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "If your email address is registered, the requested code was sent via email.", - "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.login.subject": "Your login code", - "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", - "login.email.password-reset.subject": "Your password reset code", - "login.remember": "Ponechať ma prihláseného", - "login.reset": "Reset password", - "login.toggleText.code.email": "Login via email", - "login.toggleText.code.email-password": "Login with password", - "login.toggleText.password-reset.email": "Forgot your password?", - "login.toggleText.password-reset.email-password": "← Back to login", - - "logout": "Odhlásenie", - - "menu": "Menu", - "meridiem": "AM/PM", - "mime": "Typ média", - "minutes": "Minúty", - - "month": "Mesiac", - "months.april": "Apríl", - "months.august": "August", - "months.december": "December", - "months.february": "Február", - "months.january": "Január", - "months.july": "Júl", - "months.june": "Jún", - "months.march": "Marec", - "months.may": "Máj", - "months.november": "November", - "months.october": "Október", - "months.september": "September", - - "more": "Viac", - "name": "Meno", - "next": "Ďalej", - "no": "no", - "off": "off", - "on": "on", - "open": "Otvoriť", - "open.newWindow": "Open in new window", - "options": "Nastavenia", - "options.none": "No options", - - "orientation": "Orientácia", - "orientation.landscape": "Širokouhlá", - "orientation.portrait": "Portrét", - "orientation.square": "Štvorec", - - "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Zmeniť URL", - "page.changeSlug.fromTitle": "Vytvoriť z titulku", - "page.changeStatus": "Zmeniť status", - "page.changeStatus.position": "Prosím, zmeňte pozíciu", - "page.changeStatus.select": "Zvoľte nový status", - "page.changeTemplate": "Zmeniť šablónu", - "page.delete.confirm": "Ste si istý, že chcete zmazať {title}?", - "page.delete.confirm.subpages": "Táto stránka obsahuje podstránky.
Všetky podstránky budú taktiež zmazané.", - "page.delete.confirm.title": "Pre potvrdenie zadajte titulok stránky", - "page.draft.create": "Vytvoriť koncept", - "page.duplicate.appendix": "Kopírovať", - "page.duplicate.files": "Copy files", - "page.duplicate.pages": "Copy pages", - "page.sort": "Change position", - "page.status": "Status", - "page.status.draft": "Koncept", - "page.status.draft.description": "The page is in draft mode and only visible for logged in editors or via secret link", - "page.status.listed": "Verejné", - "page.status.listed.description": "Stránka je prístupná pre všetkých", - "page.status.unlisted": "Skryté", - "page.status.unlisted.description": "Stránka je prístupná len prostredníctvom priamej URL", - - "pages": "Stránky", - "pages.empty": "Zatiaľ žiadne stránky", - "pages.status.draft": "Koncepty", - "pages.status.listed": "Zverejnené", - "pages.status.unlisted": "Skryté", - - "pagination.page": "Stránka", - - "password": "Heslo", - "paste": "Paste", - "paste.after": "Paste after", - "pixel": "Pixel", - "plugins": "Plugins", - "prev": "Predchádzajúci", - "preview": "Preview", - "remove": "Odstrániť", - "rename": "Premenovať", - "replace": "Nahradiť", - "retry": "Skúsiť ešte raz", - "revert": "Vrátiť späť", - "revert.confirm": "Do you really want to delete all unsaved changes?", - - "role": "Rola", - "role.admin.description": "The admin has all rights", - "role.admin.title": "Admin", - "role.all": "Všetko", - "role.empty": "S touto rolou neexistujú žiadni užívatelia", - "role.description.placeholder": "Žiadny popis", - "role.nobody.description": "This is a fallback role without any permissions", - "role.nobody.title": "Nobody", - - "save": "Uložiť", - "search": "Hľadať", - "search.min": "Enter {min} characters to search", - "search.all": "Show all", - "search.results.none": "No results", - - "section.required": "The section is required", - - "security": "Security", - "select": "Zvoliť", - "server": "Server", - "settings": "Nastavenia", - "show": "Show", - "site.blueprint": "The site has no blueprint yet. You can define the setup in /site/blueprints/site.yml", - "size": "Veľkosť", - "slug": "URL appendix", - "sort": "Zoradiť", - - "stats.empty": "No reports", - "system.issues.content": "The content folder seems to be exposed", - "system.issues.debug": "Debugging must be turned off in production", - "system.issues.git": "The .git folder seems to be exposed", - "system.issues.https": "We recommend HTTPS for all your sites", - "system.issues.kirby": "The kirby folder seems to be exposed", - "system.issues.site": "The site folder seems to be exposed", - - "title": "Titulok", - "template": "Šablóna", - "today": "Dnes", - - "toolbar.button.code": "Kód", - "toolbar.button.bold": "Tučný", - "toolbar.button.email": "E-mail", - "toolbar.button.headings": "Nadpisy", - "toolbar.button.heading.1": "Nadpis 1", - "toolbar.button.heading.2": "Nadpis 2", - "toolbar.button.heading.3": "Nadpis 3", - "toolbar.button.heading.4": "Heading 4", - "toolbar.button.heading.5": "Heading 5", - "toolbar.button.heading.6": "Heading 6", - "toolbar.button.italic": "Kurzíva", - "toolbar.button.file": "Súbor", - "toolbar.button.file.select": "Select a file", - "toolbar.button.file.upload": "Upload a file", - "toolbar.button.link": "Odkaz", - "toolbar.button.paragraph": "Paragraph", - "toolbar.button.strike": "Strike-through", - "toolbar.button.ol": "Číslovaný zoznam", - "toolbar.button.underline": "Underline", - "toolbar.button.ul": "Odrážkový zoznam", - - "translation.author": "Tím Kirby", - "translation.direction": "ltr", - "translation.name": "Slovensky", - "translation.locale": "sk_SK", - - "upload": "Nahrať", - "upload.error.cantMove": "The uploaded file could not be moved", - "upload.error.cantWrite": "Failed to write file to disk", - "upload.error.default": "The file could not be uploaded", - "upload.error.extension": "File upload stopped by extension", - "upload.error.formSize": "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the form", - "upload.error.iniPostSize": "The uploaded file exceeds the post_max_size directive in php.ini", - "upload.error.iniSize": "The uploaded file exceeds the upload_max_filesize directive in php.ini", - "upload.error.noFile": "No file was uploaded", - "upload.error.noFiles": "No files were uploaded", - "upload.error.partial": "The uploaded file was only partially uploaded", - "upload.error.tmpDir": "Missing a temporary folder", - "upload.errors": "Chyba", - "upload.progress": "Nahrávanie...", - - "url": "URL", - "url.placeholder": "https://example.com", - - "user": "Užívateľ", - "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Zmeniť e-mail", - "user.changeLanguage": "Zmeniť jazyk", - "user.changeName": "Premenovať tohto užívateľa", - "user.changePassword": "Zmeniť heslo", - "user.changePassword.new": "Nové heslo", - "user.changePassword.new.confirm": "Potvrdiť nové heslo...", - "user.changeRole": "Zmeniť rolu", - "user.changeRole.select": "Zvoliť novú rolu", - "user.create": "Pridať nového užívateľa", - "user.delete": "Zmazať tohto užívateľa", - "user.delete.confirm": "Ste si istý, že chcete zmazať
{email}?", - - "users": "Užívatelia", - - "version": "Verzia", - - "view.account": "Váš účet", - "view.installation": "Inštalácia", - "view.languages": "Jazyky", - "view.resetPassword": "Reset password", - "view.site": "Portál", - "view.system": "System", - "view.users": "Užívatelia", - - "welcome": "Vitajte", - "year": "Rok", - "yes": "yes" + "account.changeName": "Change your name", + "account.delete": "Delete your account", + "account.delete.confirm": "Do you really want to delete your account? You will be logged out immediately. Your account cannot be recovered.", + + "add": "Pridať", + "author": "Author", + "avatar": "Profilový obrázok", + "back": "Späť", + "cancel": "Zrušiť", + "change": "Zmeniť", + "close": "Zavrieť", + "confirm": "Ok", + "collapse": "Zabaliť", + "collapse.all": "Zabaliť všetky", + "copy": "Kopírovať", + "copy.all": "Copy all", + "create": "Vytvoriť", + + "date": "Dátum", + "date.select": "Zvoliť dátum", + + "day": "Deň", + "days.fri": "Pia", + "days.mon": "Pon", + "days.sat": "Sob", + "days.sun": "Ned", + "days.thu": "Štv", + "days.tue": "Uto", + "days.wed": "Str", + + "debugging": "Debugging", + + "delete": "Zmazať", + "delete.all": "Zmazať všetky", + + "dialog.files.empty": "No files to select", + "dialog.pages.empty": "No pages to select", + "dialog.users.empty": "No users to select", + + "dimensions": "Rozmery", + "disabled": "Disabled", + "discard": "Zahodiť", + "download": "Stiahnuť", + "duplicate": "Duplikovať", + + "edit": "Upraviť", + + "email": "E-mail", + "email.placeholder": "mail@example.com", + + "entries": "Entries", + "entry": "Entry", + + "environment": "Environment", + + "error.access.code": "Neplatný kód", + "error.access.login": "Neplatné prihlásenie", + "error.access.panel": "Nemáte povolenie na prístup do Panel-u", + "error.access.view": "You are not allowed to access this part of the panel", + + "error.avatar.create.fail": "Profilový obrázok sa nepodarilo nahrať", + "error.avatar.delete.fail": "Profilový obrázok sa nepodarilo zmazať", + "error.avatar.dimensions.invalid": "Prosím, dodržte, aby šírka a výška profilového obrázka bola menšia ako 3000 pixelov.", + "error.avatar.mime.forbidden": "Profilový obrázok musí byť súbor JPEG alebo PNG.", + + "error.blueprint.notFound": "Blueprint \"{name}\" sa nepodarilo načítať", + + "error.blocks.max.plural": "You must not add more than {max} blocks", + "error.blocks.max.singular": "You must not add more than one block", + "error.blocks.min.plural": "You must add at least {min} blocks", + "error.blocks.min.singular": "You must add at least one block", + "error.blocks.validation": "There's an error on the \"{field}\" field in block {index} using the \"{fieldset}\" block type", + + "error.email.preset.notFound": "E-mailovú predvoľbu \"{name}\" nie je možné nájsť", + + "error.field.converter.invalid": "Neplatný converter \"{converter}\"", + + "error.file.changeName.empty": "Meno nesmie byť prázdne", + "error.file.changeName.permission": "Nemáte povolenie na zmenu názvu pre \"{filename}\"", + "error.file.duplicate": "Súbor s názvom \"{filename}\" už existuje", + "error.file.extension.forbidden": "Prípona \"{extension}\" nie je povolená", + "error.file.extension.invalid": "Neplatná prípona: \"{extension}\"", + "error.file.extension.missing": "Prípona pre \"{filename}\" chýba", + "error.file.maxheight": "Výška obrázku nesmie prekročiť \"{height}\" pixelov", + "error.file.maxsize": "Súbor je príliš velký", + "error.file.maxwidth": "Šírka obrázku nesmie prekročiť \"{width}\" pixelov", + "error.file.mime.differs": "Mime typ nahratého súboru msa musí zhodovať s \"{mime}\"", + "error.file.mime.forbidden": "Typ média \"{mime}\" nie je povolený", + "error.file.mime.invalid": "Neplatný mime typ: \"{mime}\"", + "error.file.mime.missing": "Typ média pre \"{filename}\" sa nepodarilo zistiť", + "error.file.minheight": "Výška obrázku musí byť aspoň \"{height}\" pixelov", + "error.file.minsize": "Súbor je príliš malý", + "error.file.minwidth": "Šírka obrázku musí byť aspoň \"{width}\" pixelov", + "error.file.name.missing": "Názov súboru nemôže byť prázdny", + "error.file.notFound": "Súbor \"{filename}\" sa nepodarilo nájsť", + "error.file.orientation": "The orientation of the image must be \"{orientation}\"", + "error.file.type.forbidden": "Nemáte povolenie na nahrávanie súborov s typom {type}", + "error.file.type.invalid": "Neplatný typ súboru: \"{type}\"", + "error.file.undefined": "Súbor nie je možné nájsť", + + "error.form.incomplete": "Prosím, opravte všetky chyby v rámci formuláru...", + "error.form.notSaved": "Formulár sa nepodarilo uložiť", + + "error.language.code": "Please enter a valid code for the language", + "error.language.duplicate": "The language already exists", + "error.language.name": "Please enter a valid name for the language", + "error.language.notFound": "The language could not be found", + + "error.layout.validation.block": "There's an error on the \"{field}\" field in block {blockIndex} using the \"{fieldset}\" block type in layout {layoutIndex}", + "error.layout.validation.settings": "There's an error in layout {index} settings", + + "error.license.format": "Please enter a valid license key", + "error.license.email": "Prosím, zadajte platnú e-mailovú adresu", + "error.license.verification": "The license could not be verified", + + "error.object.validation": "There’s an error in the \"{label}\" field:\n{message}", + + "error.offline": "The Panel is currently offline", + + "error.page.changeSlug.permission": "Nemáte povolenie na zmenu URL príponu pre \"{slug}\"", + "error.page.changeStatus.incomplete": "Stránka obsahuje chyby a nemôže byť zverejnená", + "error.page.changeStatus.permission": "Status tejto stránky nemôže byť zmenený", + "error.page.changeStatus.toDraft.invalid": "Stránka \"{slug}\" nemôže byť zmenená na koncept.", + "error.page.changeTemplate.invalid": "Šablónu pre stránku \"{slug}\" nie je možné zmeniť", + "error.page.changeTemplate.permission": "Nemáte povolenie na zmenu šablóny pre \"{slug}\"", + "error.page.changeTitle.empty": "Titulok nemôže byť prázdny", + "error.page.changeTitle.permission": "Nemáte povolenie na zmenu titulku pre \"{slug}\"", + "error.page.create.permission": "Nemáte povolenie na vytvorenie \"{slug}\"", + "error.page.delete": "Stránku \"{slug}\" nie je možné vymazať", + "error.page.delete.confirm": "Prosím, zadajte titulok stránky pre potvrdenie", + "error.page.delete.hasChildren": "Táto stránka obsahuje podstránky a nemôže byť zmazaná", + "error.page.delete.permission": "Nemáte povolenie na zmazanie stránky \"{slug}\"", + "error.page.draft.duplicate": "Koncept stránky s URL appendix-om \"{slug}\" už existuje", + "error.page.duplicate": "Stránka s URL appendix-om \"{slug}\" už existuje", + "error.page.duplicate.permission": "You are not allowed to duplicate \"{slug}\"", + "error.page.notFound": "Stránku \"{slug}\" nie je možné nájsť", + "error.page.num.invalid": "Prosím, zadajte platné číslo pre radenie. Čísla nemôžu byť záporné.", + "error.page.slug.invalid": "Please enter a valid URL appendix", + "error.page.slug.maxlength": "Slug length must be less than \"{length}\" characters", + "error.page.sort.permission": "Stránku \"{slug}\" nie je možné preradiť.", + "error.page.status.invalid": "Prosím, nastavte platnú status pre stránku", + "error.page.undefined": "Stránku nie je možné nájsť", + "error.page.update.permission": "Nemáte povolenie na aktualizáciu \"{slug}\"", + + "error.section.files.max.plural": "Nemôžete pridať viac ako {max} súbory/ov do sekcie \"{section}\"", + "error.section.files.max.singular": "Nemôžete pridať viac ako 1 súbor do sekcie \"{section}\"", + "error.section.files.min.plural": "The \"{section}\" section requires at least {min} files", + "error.section.files.min.singular": "The \"{section}\" section requires at least one file", + + "error.section.pages.max.plural": "Nemôžete pridať viac ako {max} stránky/ok do sekcie \"{section}\"", + "error.section.pages.max.singular": "Nemôžete pridať viac ako 1 stránku do sekcie \"{section}\"", + "error.section.pages.min.plural": "The \"{section}\" section requires at least {min} pages", + "error.section.pages.min.singular": "The \"{section}\" section requires at least one page", + + "error.section.notLoaded": "Sekciu \"{name}\" sa nepodarilo nahrať", + "error.section.type.invalid": "Typ sekcie \"{type}\" nie je platný", + + "error.site.changeTitle.empty": "Titulok nemôže byť prázdny", + "error.site.changeTitle.permission": "Nemáte povolenie na zmenu titulku pre portál", + "error.site.update.permission": "Nemáte povolenie na aktualizovanie portálu", + + "error.template.default.notFound": "Predvolená šablóna neexistuje", + + "error.unexpected": "An unexpected error occurred! Enable debug mode for more info: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Nemáte povolenie na zmenu e-mailu pre užívateľa \"{name}\"", + "error.user.changeLanguage.permission": "Nemáte povolenie na zmenu jazyka pre užívateľa \"{name}\"", + "error.user.changeName.permission": "Nemáte povolenie na zmenu mena pre užívateľa \"{name}\"", + "error.user.changePassword.permission": "Nemáte povolenie na zmenu hesla pre užívateľa \"{name}\"", + "error.user.changeRole.lastAdmin": "Rolu pre posledného administrátora nie je možné zmeniť", + "error.user.changeRole.permission": "Nemáte povolenie na zmenu role pre užívateľa \"{name}\"", + "error.user.changeRole.toAdmin": "You are not allowed to promote someone to the admin role", + "error.user.create.permission": "Nemáte povolenie na vytvorenie tohto užívateľa", + "error.user.delete": "Užívateľa \"{name}\" nie je možné zmazať", + "error.user.delete.lastAdmin": "Posledného administrátora nie je možné zmazať", + "error.user.delete.lastUser": "Posledného užívateľa nie je možné zmazať", + "error.user.delete.permission": "Nemáte povolenie na zmazanie užívateľa \"{name}\"", + "error.user.duplicate": "Užívateľ s e-mailovou adresou \"{email}\" už existuje", + "error.user.email.invalid": "Prosím, zadajte platnú e-mailovú adresu", + "error.user.language.invalid": "Prosím, zadajte platný jazyk", + "error.user.notFound": "Užívateľa \"{name}\" nie je možné nájsť", + "error.user.password.invalid": "Prosím, zadajte platné heslo. Dĺžka hesla musí byť aspoň 8 znakov.", + "error.user.password.notSame": "Heslá nie sú rovnaké", + "error.user.password.undefined": "Užívateľ nemá heslo", + "error.user.password.wrong": "Wrong password", + "error.user.role.invalid": "Prosím, zadajte platnú rolu", + "error.user.undefined": "Užívateľa sa nepodarilo nájsť", + "error.user.update.permission": "Nemáte povolenie na aktualizáciu užívateľa \"{name}\"", + + "error.validation.accepted": "Prosím, potvrďte", + "error.validation.alpha": "Prosím, zadajte len znaky z hlások a-z", + "error.validation.alphanum": "Prosím, zadajte len znaky z hlások a-z a čísloviek 0-9", + "error.validation.between": "Prosím, zadajte hodnotu od \"{min}\" do \"{max}\"", + "error.validation.boolean": "Prosím, potvrďte alebo odmietnite", + "error.validation.contains": "Prosím, zadajte hodnotu, ktorá obsahuje \"{needle}\"", + "error.validation.date": "Prosím, zadajte platný dátum", + "error.validation.date.after": "Please enter a date after {date}", + "error.validation.date.before": "Please enter a date before {date}", + "error.validation.date.between": "Please enter a date between {min} and {max}", + "error.validation.denied": "Prosím, odmietnite", + "error.validation.different": "Hodnota nemôže byť \"{other}\"", + "error.validation.email": "Prosím, zadajte platnú e-mailovú adresu", + "error.validation.endswith": "Hodnota musí končiť na \"{end}\"", + "error.validation.filename": "Prosím, zadajte platný názov súboru", + "error.validation.in": "Prosím, zadajte jedno z nasledujúcich: ({in})", + "error.validation.integer": "Prosím, zadajte platné celé číslo", + "error.validation.ip": "Prosím, zadajte platnú e-mailovú adresu", + "error.validation.less": "Prosím, zadajte hodnotu menšiu ako {max}", + "error.validation.match": "Hodnota nezodpovedá očakávanému vzoru", + "error.validation.max": "Prosím, zadajte hodnotu rovnú alebo menšiu ako {max}", + "error.validation.maxlength": "Prosím, zadajte kratšiu hodnotu. (max. {max} charaktery/ov)", + "error.validation.maxwords": "Prosím, nezadávajte viac ako {max} slovo/á/ov", + "error.validation.min": "Prosím, zadajte hodnotu rovnú alebo väčšiu ako {min}", + "error.validation.minlength": "Prosím, zadajte dlhšiu hodnotu. (min. {min} charaktery/ov)", + "error.validation.minwords": "Prosím, zadajte aspoň {min} slovo/á/ov", + "error.validation.more": "Prosím zadajte hodnotu väčšiu ako {min}", + "error.validation.notcontains": "Prosím, zadajte hodnotu, ktorá neobsahuje \"{needle}\"", + "error.validation.notin": "Prosím, nezadávajte ani jedno z nasledujúcich: ({notIn})", + "error.validation.option": "Prosím, zadajte platnú voľbu", + "error.validation.num": "Prosím, zadajte platné číslo", + "error.validation.required": "Prosím, zadajte niečo", + "error.validation.same": "Prosím, zadajte \"{other}\"", + "error.validation.size": "Veľkosť hodnoty musí byť \"{size}\"", + "error.validation.startswith": "Hodnota musí začínať s \"{start}\"", + "error.validation.time": "Prosím, zadajte platný čas", + "error.validation.time.after": "Please enter a time after {time}", + "error.validation.time.before": "Please enter a time before {time}", + "error.validation.time.between": "Please enter a time between {min} and {max}", + "error.validation.url": "Prosím, zadajte platnú URL", + + "expand": "Rozbaliť", + "expand.all": "Rozbaliť všetky", + + "field.required": "The field is required", + "field.blocks.changeType": "Change type", + "field.blocks.code.name": "Kód", + "field.blocks.code.language": "Jazyk", + "field.blocks.code.placeholder": "Váš kód ...", + "field.blocks.delete.confirm": "Naozaj chcete zmazať tento blok?", + "field.blocks.delete.confirm.all": "Naozaj chcete zmazať všetky bloky?", + "field.blocks.delete.confirm.selected": "Naozaj chcete zmazať vybrané bloky?", + "field.blocks.empty": "No blocks yet", + "field.blocks.fieldsets.label": "Please select a block type …", + "field.blocks.fieldsets.paste": "Press {{ shortcut }} to paste/import blocks from your clipboard", + "field.blocks.gallery.name": "Galéria", + "field.blocks.gallery.images.empty": "No images yet", + "field.blocks.gallery.images.label": "Obrázky", + "field.blocks.heading.level": "Level", + "field.blocks.heading.name": "Nadpis", + "field.blocks.heading.text": "Text", + "field.blocks.heading.placeholder": "Nadpis ...", + "field.blocks.image.alt": "Alternative text", + "field.blocks.image.caption": "Popis", + "field.blocks.image.crop": "Orezanie", + "field.blocks.image.link": "Odkaz", + "field.blocks.image.location": "Poloha", + "field.blocks.image.name": "Obrázok", + "field.blocks.image.placeholder": "Select an image", + "field.blocks.image.ratio": "Ratio", + "field.blocks.image.url": "Image URL", + "field.blocks.line.name": "Line", + "field.blocks.list.name": "List", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Text", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Quote", + "field.blocks.quote.text.label": "Text", + "field.blocks.quote.text.placeholder": "Quote …", + "field.blocks.quote.citation.label": "Citation", + "field.blocks.quote.citation.placeholder": "by …", + "field.blocks.text.name": "Text", + "field.blocks.text.placeholder": "Text …", + "field.blocks.video.caption": "Popis", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Enter a video URL", + "field.blocks.video.url.label": "Video-URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Žiadne súbory zatiaľ neboli zvolené", + + "field.layout.delete": "Delete layout", + "field.layout.delete.confirm": "Do you really want to delete this layout?", + "field.layout.empty": "No rows yet", + "field.layout.select": "Select a layout", + + "field.object.empty": "No information yet", + + "field.pages.empty": "Žiadne stránky zatiaľ neboli zvolené", + + "field.structure.delete.confirm": "Ste si istý, že chcete zmazať tento riadok?", + "field.structure.empty": "Zatiaľ žiadne údaje", + + "field.users.empty": "Žiadni užívatelia zatiaľ neboli zvolení", + + "file.blueprint": "This file has no blueprint yet. You can define the setup in /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Ste si istý, že chcete zmazať
{filename}?", + "file.sort": "Change position", + + "files": "Súbory", + "files.empty": "Zatiaľ žiadne súbory", + + "hide": "Hide", + "hour": "Hodina", + "import": "Import", + "info": "Info", + "insert": "Vložiť", + "insert.after": "Insert after", + "insert.before": "Insert before", + "install": "Inštalovať", + + "installation": "Inštalácia", + "installation.completed": "Panel bol nainštalovaný", + "installation.disabled": "Inštalácia Panelu na verejných serveroch je štandardne zablokovaná. Prosím, spustite inštaláciu na lokálnom serveri alebo aktivujte voľbu panel.install.", + "installation.issues.accounts": "Priečinok /site/accounts neexistuje alebo nie je nastavený ako zapisovateľný", + "installation.issues.content": "Priečinok /content neexistuje alebo nie je nastavený ako zapisovateľný", + "installation.issues.curl": "CURL rozšírenie je povinné", + "installation.issues.headline": "Panel nie je možné naištalovať", + "installation.issues.mbstring": "MB String rozšírenie je povinné", + "installation.issues.media": "Priečinok /media neexistuje alebo nie je nastavený ako zapisovateľný", + "installation.issues.php": "Uistite sa, že používate PHP 7+", + "installation.issues.server": "Kirby vyžaduje Apache, Nginx alebo Caddy", + "installation.issues.sessions": "Priečinok /site/sessions neexistuje alebo nie je nastavený ako zapisovateľný", + + "language": "Jazyk", + "language.code": "Kód", + "language.convert": "Nastaviť ako predvolené", + "language.convert.confirm": "

Ste si istý, že chcete nastaviť {name} ako predvolený jazyk? Túto akciu nie je možné zvrátiť.

Ak {name} obsahuje nepreložený obsah, tak pre tento obsah nebude fungovať platné volanie a niektoré časti vašich stránok zostanú prázdne.

", + "language.create": "Pridať nový jazyk", + "language.delete.confirm": "Ste si istý, že chcete zmazať jazyk {name} vrátane všetkých prekladov? Túto akciu nie je možné zvrátiť.", + "language.deleted": "Jazyk bol zmazaný", + "language.direction": "Smer čítania", + "language.direction.ltr": "Zľava doprava", + "language.direction.rtl": "Zprava doľava", + "language.locale": "PHP locale string", + "language.locale.warning": "You are using a custom locale set up. Please modify it in the language file in /site/languages", + "language.name": "Názov", + "language.updated": "Jazyk bol aktualizovaný", + + "languages": "Jazyky", + "languages.default": "Predvolený jazyk", + "languages.empty": "Zatiaľ žiadne jazyky", + "languages.secondary": "Sekundárne jazyky", + "languages.secondary.empty": "Zatiaľ žiadne sekundárne jazyky", + + "license": "Licencia", + "license.buy": "Zakúpiť licenciu", + "license.register": "Registrovať", + "license.manage": "Manage your licenses", + "license.register.help": "Licenčný kód vám bol doručený e-mailom po úspešnom nákupe. Prosím, skopírujte a prilepte ho na uskutočnenie registrácie.", + "license.register.label": "Prosím, zadajte váš licenčný kód", + "license.register.success": "Ďakujeme za vašu podporu Kirby", + "license.unregistered": "Toto je neregistrované demo Kirby", + "license.unregistered.label": "Unregistered", + + "link": "Odkaz", + "link.text": "Text odkazu", + + "loading": "Načítavanie", + + "lock.unsaved": "Unsaved changes", + "lock.unsaved.empty": "There are no more unsaved changes", + "lock.isLocked": "Unsaved changes by {email}", + "lock.file.isLocked": "The file is currently being edited by {email} and cannot be changed.", + "lock.page.isLocked": "The page is currently being edited by {email} and cannot be changed.", + "lock.unlock": "Unlock", + "lock.isUnlocked": "Your unsaved changes have been overwritten by another user. You can download your changes to merge them manually.", + + "login": "Prihlásenie", + "login.code.label.login": "Login code", + "login.code.label.password-reset": "Password reset code", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "If your email address is registered, the requested code was sent via email.", + "login.email.login.body": "Hi {user.nameOrEmail},\n\nYou recently requested a login code for the Panel of {site}.\nThe following login code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a login code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.login.subject": "Your login code", + "login.email.password-reset.body": "Hi {user.nameOrEmail},\n\nYou recently requested a password reset code for the Panel of {site}.\nThe following password reset code will be valid for {timeout} minutes:\n\n{code}\n\nIf you did not request a password reset code, please ignore this email or contact your administrator if you have questions.\nFor security, please DO NOT forward this email.", + "login.email.password-reset.subject": "Your password reset code", + "login.remember": "Ponechať ma prihláseného", + "login.reset": "Reset password", + "login.toggleText.code.email": "Login via email", + "login.toggleText.code.email-password": "Login with password", + "login.toggleText.password-reset.email": "Forgot your password?", + "login.toggleText.password-reset.email-password": "← Back to login", + + "logout": "Odhlásenie", + + "menu": "Menu", + "meridiem": "AM/PM", + "mime": "Typ média", + "minutes": "Minúty", + + "month": "Mesiac", + "months.april": "Apríl", + "months.august": "August", + "months.december": "December", + "months.february": "Február", + "months.january": "Január", + "months.july": "Júl", + "months.june": "Jún", + "months.march": "Marec", + "months.may": "Máj", + "months.november": "November", + "months.october": "Október", + "months.september": "September", + + "more": "Viac", + "name": "Meno", + "next": "Ďalej", + "no": "no", + "off": "off", + "on": "on", + "open": "Otvoriť", + "open.newWindow": "Open in new window", + "options": "Nastavenia", + "options.none": "No options", + + "orientation": "Orientácia", + "orientation.landscape": "Širokouhlá", + "orientation.portrait": "Portrét", + "orientation.square": "Štvorec", + + "page.blueprint": "This page has no blueprint yet. You can define the setup in /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Zmeniť URL", + "page.changeSlug.fromTitle": "Vytvoriť z titulku", + "page.changeStatus": "Zmeniť status", + "page.changeStatus.position": "Prosím, zmeňte pozíciu", + "page.changeStatus.select": "Zvoľte nový status", + "page.changeTemplate": "Zmeniť šablónu", + "page.delete.confirm": "Ste si istý, že chcete zmazať {title}?", + "page.delete.confirm.subpages": "Táto stránka obsahuje podstránky.
Všetky podstránky budú taktiež zmazané.", + "page.delete.confirm.title": "Pre potvrdenie zadajte titulok stránky", + "page.draft.create": "Vytvoriť koncept", + "page.duplicate.appendix": "Kopírovať", + "page.duplicate.files": "Copy files", + "page.duplicate.pages": "Copy pages", + "page.sort": "Change position", + "page.status": "Status", + "page.status.draft": "Koncept", + "page.status.draft.description": "The page is in draft mode and only visible for logged in editors or via secret link", + "page.status.listed": "Verejné", + "page.status.listed.description": "Stránka je prístupná pre všetkých", + "page.status.unlisted": "Skryté", + "page.status.unlisted.description": "Stránka je prístupná len prostredníctvom priamej URL", + + "pages": "Stránky", + "pages.empty": "Zatiaľ žiadne stránky", + "pages.status.draft": "Koncepty", + "pages.status.listed": "Zverejnené", + "pages.status.unlisted": "Skryté", + + "pagination.page": "Stránka", + + "password": "Heslo", + "paste": "Paste", + "paste.after": "Paste after", + "pixel": "Pixel", + "plugin": "Plugin", + "plugins": "Plugins", + "prev": "Predchádzajúci", + "preview": "Preview", + "remove": "Odstrániť", + "rename": "Premenovať", + "replace": "Nahradiť", + "retry": "Skúsiť ešte raz", + "revert": "Vrátiť späť", + "revert.confirm": "Do you really want to delete all unsaved changes?", + + "role": "Rola", + "role.admin.description": "The admin has all rights", + "role.admin.title": "Admin", + "role.all": "Všetko", + "role.empty": "S touto rolou neexistujú žiadni užívatelia", + "role.description.placeholder": "Žiadny popis", + "role.nobody.description": "This is a fallback role without any permissions", + "role.nobody.title": "Nobody", + + "save": "Uložiť", + "search": "Hľadať", + "search.min": "Enter {min} characters to search", + "search.all": "Show all", + "search.results.none": "No results", + + "section.required": "The section is required", + + "security": "Security", + "select": "Zvoliť", + "server": "Server", + "settings": "Nastavenia", + "show": "Show", + "site.blueprint": "The site has no blueprint yet. You can define the setup in /site/blueprints/site.yml", + "size": "Veľkosť", + "slug": "URL appendix", + "sort": "Zoradiť", + + "stats.empty": "No reports", + "system.issues.content": "The content folder seems to be exposed", + "system.issues.eol.kirby": "Your installed Kirby version has reached end-of-life and will not receive further security updates", + "system.issues.eol.plugin": "Your installed version of the { plugin } plugin is has reached end-of-life and will not receive further security updates", + "system.issues.debug": "Debugging must be turned off in production", + "system.issues.git": "The .git folder seems to be exposed", + "system.issues.https": "We recommend HTTPS for all your sites", + "system.issues.kirby": "The kirby folder seems to be exposed", + "system.issues.site": "The site folder seems to be exposed", + "system.issues.vulnerability.kirby": "Your installation might be affected by the following vulnerability ({ severity } severity): { description }", + "system.issues.vulnerability.plugin": "Your installation might be affected by the following vulnerability in the { plugin } plugin ({ severity } severity): { description }", + "system.updateStatus": "Update status", + "system.updateStatus.error": "Could not check for updates", + "system.updateStatus.not-vulnerable": "No known vulnerabilities", + "system.updateStatus.security-update": "Free security update { version } available", + "system.updateStatus.security-upgrade": "Upgrade { version } with security fixes available", + "system.updateStatus.unreleased": "Unreleased version", + "system.updateStatus.up-to-date": "Up to date", + "system.updateStatus.update": "Free update { version } available", + "system.updateStatus.upgrade": "Upgrade { version } available", + + "title": "Titulok", + "template": "Šablóna", + "today": "Dnes", + + "toolbar.button.code": "Kód", + "toolbar.button.bold": "Tučný", + "toolbar.button.email": "E-mail", + "toolbar.button.headings": "Nadpisy", + "toolbar.button.heading.1": "Nadpis 1", + "toolbar.button.heading.2": "Nadpis 2", + "toolbar.button.heading.3": "Nadpis 3", + "toolbar.button.heading.4": "Heading 4", + "toolbar.button.heading.5": "Heading 5", + "toolbar.button.heading.6": "Heading 6", + "toolbar.button.italic": "Kurzíva", + "toolbar.button.file": "Súbor", + "toolbar.button.file.select": "Select a file", + "toolbar.button.file.upload": "Upload a file", + "toolbar.button.link": "Odkaz", + "toolbar.button.paragraph": "Paragraph", + "toolbar.button.strike": "Strike-through", + "toolbar.button.ol": "Číslovaný zoznam", + "toolbar.button.underline": "Underline", + "toolbar.button.ul": "Odrážkový zoznam", + + "translation.author": "Tím Kirby", + "translation.direction": "ltr", + "translation.name": "Slovensky", + "translation.locale": "sk_SK", + + "upload": "Nahrať", + "upload.error.cantMove": "The uploaded file could not be moved", + "upload.error.cantWrite": "Failed to write file to disk", + "upload.error.default": "The file could not be uploaded", + "upload.error.extension": "File upload stopped by extension", + "upload.error.formSize": "The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the form", + "upload.error.iniPostSize": "The uploaded file exceeds the post_max_size directive in php.ini", + "upload.error.iniSize": "The uploaded file exceeds the upload_max_filesize directive in php.ini", + "upload.error.noFile": "No file was uploaded", + "upload.error.noFiles": "No files were uploaded", + "upload.error.partial": "The uploaded file was only partially uploaded", + "upload.error.tmpDir": "Missing a temporary folder", + "upload.errors": "Chyba", + "upload.progress": "Nahrávanie...", + + "url": "URL", + "url.placeholder": "https://example.com", + + "user": "Užívateľ", + "user.blueprint": "You can define additional sections and form fields for this user role in /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Zmeniť e-mail", + "user.changeLanguage": "Zmeniť jazyk", + "user.changeName": "Premenovať tohto užívateľa", + "user.changePassword": "Zmeniť heslo", + "user.changePassword.new": "Nové heslo", + "user.changePassword.new.confirm": "Potvrdiť nové heslo...", + "user.changeRole": "Zmeniť rolu", + "user.changeRole.select": "Zvoliť novú rolu", + "user.create": "Pridať nového užívateľa", + "user.delete": "Zmazať tohto užívateľa", + "user.delete.confirm": "Ste si istý, že chcete zmazať
{email}?", + + "users": "Užívatelia", + + "version": "Verzia", + "version.current": "Current version", + "version.latest": "Latest version", + "versionInformation": "Version information", + + "view.account": "Váš účet", + "view.installation": "Inštalácia", + "view.languages": "Jazyky", + "view.resetPassword": "Reset password", + "view.site": "Portál", + "view.system": "System", + "view.users": "Užívatelia", + + "welcome": "Vitajte", + "year": "Rok", + "yes": "yes" } diff --git a/kirby/i18n/translations/sv_SE.json b/kirby/i18n/translations/sv_SE.json index a4565ef..9a4a928 100644 --- a/kirby/i18n/translations/sv_SE.json +++ b/kirby/i18n/translations/sv_SE.json @@ -1,573 +1,596 @@ { - "account.changeName": "Ändra ditt namn", - "account.delete": "Radera ditt konto", - "account.delete.confirm": "Vill du verkligen radera ditt konto? Du kommer att loggas ut omedelbart. Ditt konto kan inte återställas.", - - "add": "L\u00e4gg till", - "author": "Författare", - "avatar": "Profilbild", - "back": "Tillbaka", - "cancel": "Avbryt", - "change": "\u00c4ndra", - "close": "St\u00e4ng", - "confirm": "Spara", - "collapse": "Kollapsa", - "collapse.all": "Kollapsa alla", - "copy": "Kopiera", - "copy.all": "Kopiera alla", - "create": "Skapa", - - "date": "Datum", - "date.select": "Välj ett datum", - - "day": "Dag", - "days.fri": "Fre", - "days.mon": "M\u00e5n", - "days.sat": "L\u00f6r", - "days.sun": "S\u00f6n", - "days.thu": "Tor", - "days.tue": "Tis", - "days.wed": "Ons", - - "debugging": "Felsökning", - - "delete": "Radera", - "delete.all": "Radera allt", - - "dialog.files.empty": "Inga filer att välja", - "dialog.pages.empty": "Inga sidor att välja", - "dialog.users.empty": "Inga användare att välja", - - "dimensions": "Dimensioner", - "disabled": "Inaktiverad", - "discard": "Kassera", - "download": "Ladda ner", - "duplicate": "Duplicera", - - "edit": "Redigera", - - "email": "E-postadress", - "email.placeholder": "namn@exempel.se", - - "entries": "Poster", - "entry": "Post", - - "environment": "Miljö", - - "error.access.code": "Ogiltig kod", - "error.access.login": "Ogiltig inloggning", - "error.access.panel": "Du saknar behörighet att nå panelen", - "error.access.view": "Du saknar behörighet att nå denna del av panelen", - - "error.avatar.create.fail": "Profilbilden kunde inte laddas upp", - "error.avatar.delete.fail": "Profilbilden kunde inte raderas", - "error.avatar.dimensions.invalid": "Se till att profilbildens bredd och höjd är mindre än 3000 pixlar", - "error.avatar.mime.forbidden": "Profilbilden måste vara i formatet JPEG eller PNG", - - "error.blueprint.notFound": "Blueprint \"{name}\" kunde inte laddas", - - "error.blocks.max.plural": "Du får inte lägga till mer än {max} block", - "error.blocks.max.singular": "Du får inte lägga till mer än ett block", - "error.blocks.min.plural": "Du måste lägga till minst {min} block", - "error.blocks.min.singular": "Du måste lägga till minst ett block", - "error.blocks.validation": "Det finns ett fel i block {index}", - - "error.email.preset.notFound": "E-postförinställningen \"{name}\" kan inte hittas", - - "error.field.converter.invalid": "Ogiltig omvandlare \"{converter}\"", - - "error.file.changeName.empty": "Namnet får inte vara tomt", - "error.file.changeName.permission": "Du har inte behörighet att ändra namnet på \"{filename}\"", - "error.file.duplicate": "En fil med namnet \"{filename}\" existerar redan", - "error.file.extension.forbidden": "Filändelsen \"{extension}\" är inte tillåten", - "error.file.extension.invalid": "Ogiltig filändelse: {extension}", - "error.file.extension.missing": "Filen \"{filename}\" saknar filändelse", - "error.file.maxheight": "Bildens höjd får inte överstiga {height} pixlar", - "error.file.maxsize": "Filen är för stor", - "error.file.maxwidth": "Bildens bredd får inte överstiga {width} pixlar", - "error.file.mime.differs": "Den uppladdade filen måste vara av samma mime-typ \"{mime}\"", - "error.file.mime.forbidden": "Mediatypen \"{mime}\" är inte tillåten", - "error.file.mime.invalid": "Ogiltig mime-typ: {mime}", - "error.file.mime.missing": "Mediatypen för \"{filename}\" kan inte detekteras", - "error.file.minheight": "Bildens höjd måste vara minst {height} pixlar", - "error.file.minsize": "Filen är för liten", - "error.file.minwidth": "Bildens bredd måste vara minst {width} pixlar", - "error.file.name.missing": "Filnamnet får inte vara tomt", - "error.file.notFound": "Filen \"{filename}\" kan ej hittas", - "error.file.orientation": "Bildens orientering måste vara \"{orientation}\"", - "error.file.type.forbidden": "Du har inte behörighet att ladda upp filer av typen {type}", - "error.file.type.invalid": "Ogiltig filtyp: {type}", - "error.file.undefined": "Filen kan inte hittas", - - "error.form.incomplete": "Vänligen åtgärda alla formulärfel...", - "error.form.notSaved": "Formuläret kunde inte sparas", - - "error.language.code": "Ange en giltig kod för språket", - "error.language.duplicate": "Språket finns redan", - "error.language.name": "Ange ett giltigt namn för språket", - "error.language.notFound": "Språket hittades inte", - - "error.layout.validation.block": "Det finns ett fel i block {blockIndex} i layout {layoutIndex}", - "error.layout.validation.settings": "Det finns ett fel i inställningarna för layout {index}", - - "error.license.format": "Ange en giltig licensnyckel", - "error.license.email": "Ange en giltig e-postadress", - "error.license.verification": "Licensen kunde inte verifieras", - - "error.offline": "Panelen är för närvarande offline", - - "error.page.changeSlug.permission": "Du har inte behörighet att ändra URL-appendixen för \"{slug}\"", - "error.page.changeStatus.incomplete": "Sidan innehåller fel och kan inte publiceras", - "error.page.changeStatus.permission": "Statusen för denna sida kan inte ändras", - "error.page.changeStatus.toDraft.invalid": "Statusen för sidan \"{slug}\" kan inte ändras till utkast", - "error.page.changeTemplate.invalid": "Mallen för sidan \"{slug}\" kan inte ändras", - "error.page.changeTemplate.permission": "Du har inte behörighet att ändra mallen för \"{slug}\"", - "error.page.changeTitle.empty": "Titeln får inte vara tom", - "error.page.changeTitle.permission": "Du har inte behörighet att ändra titeln för \"{slug}\"", - "error.page.create.permission": "Du har inte behörighet att skapa \"{slug}\"", - "error.page.delete": "Sidan \"{slug}\" kan inte raderas", - "error.page.delete.confirm": "Fyll i sidans titel för att bekräfta", - "error.page.delete.hasChildren": "Sidan har undersidor och kan inte raderas", - "error.page.delete.permission": "Du har inte behörighet att radera \"{slug}\"", - "error.page.draft.duplicate": "Ett utkast med URL-appendixen \"{slug}\" existerar redan", - "error.page.duplicate": "En sida med URL-appendixen \"{slug}\" existerar redan", - "error.page.duplicate.permission": "Du har inte behörighet att duplicera \"{slug}\"", - "error.page.notFound": "Sidan \"{slug}\" kan inte hittas", - "error.page.num.invalid": "Ange ett giltigt nummer för sortering. Numret får inte vara negativt.", - "error.page.slug.invalid": "Ange en giltig URL-appendix", - "error.page.slug.maxlength": "Permalänkens längd måste vara kortare än \"{length}\" tecken", - "error.page.sort.permission": "Sidan \"{slug}\" kan inte sorteras", - "error.page.status.invalid": "Sätt en giltig status för sidan", - "error.page.undefined": "Sidan kan inte hittas", - "error.page.update.permission": "Du har inte behörighet att uppdatera \"{slug}\"", - - "error.section.files.max.plural": "Du får inte lägga till mer än {max} filer till sektionen \"{section}\"", - "error.section.files.max.singular": "Du får inte lägga till mer än en fil i sektionen \"{section}\"", - "error.section.files.min.plural": "Sektionen \"{section}\" kräver minst {min} filer", - "error.section.files.min.singular": "Sektionen \"{section}\" kräver minst en fil", - - "error.section.pages.max.plural": "Du får inte lägga till mer än {max} sidor till sektionen \"{section}\"", - "error.section.pages.max.singular": "Du får inte lägga till mer än en sida i sektionen \"{section}\"", - "error.section.pages.min.plural": "Sektionen \"{section}\" kräver minst {min} sidor", - "error.section.pages.min.singular": "Sektionen \"{section}\" kräver minst en sida", - - "error.section.notLoaded": "Sektionen \"{name}\" kunde inte laddas", - "error.section.type.invalid": "Sektionstypen \"{type}\" är inte giltig", - - "error.site.changeTitle.empty": "Titeln får inte vara tom", - "error.site.changeTitle.permission": "Du har inte behörighet att ändra titeln på webbplatsen", - "error.site.update.permission": "Du har inte behörighet att uppdatera webbplatsen", - - "error.template.default.notFound": "Standardmallen existerar inte", - - "error.unexpected": "Ett oväntat fel uppstod! Aktivera felsökningsläge för mer information: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "Du har inte behörighet att ändra e-postadressen för användaren \"{name}\"", - "error.user.changeLanguage.permission": "Du har inte behörighet att ändra språket för användaren \"{name}\"", - "error.user.changeName.permission": "Du har inte behörighet att ändra namnet för användaren \"{name}\"", - "error.user.changePassword.permission": "Du har inte behörighet att ändra lösenordet för användaren \"{name}\"", - "error.user.changeRole.lastAdmin": "Rollen för den återstående adminanvändaren kan inte ändras", - "error.user.changeRole.permission": "Du har inte behörighet att ändra rollen för användaren \"{name}\"", - "error.user.changeRole.toAdmin": "Du har inte behörighet att ge någon en administratörsroll", - "error.user.create.permission": "Du har inte behörighet att skapa denna användare", - "error.user.delete": "Användaren kan inte raderas", - "error.user.delete.lastAdmin": "Den återstående administratören kan inte raderas", - "error.user.delete.lastUser": "Den återstående användaren kan inte raderas", - "error.user.delete.permission": "Du har inte behörighet att radera användaren \"{name}\"", - "error.user.duplicate": "En användare med e-postadressen \"{email}\" finns redan", - "error.user.email.invalid": "Ange en giltig e-postadress", - "error.user.language.invalid": "Ange ett giltigt språk", - "error.user.notFound": "Användaren \"{name}\" kan ej hittas", - "error.user.password.invalid": "Ange ett giltigt lösenord. Lösenordet måste vara minst 8 tecken långt.", - "error.user.password.notSame": "Lösenorden matchar inte", - "error.user.password.undefined": "Användaren har inget lösenord", - "error.user.password.wrong": "Fel lösenord", - "error.user.role.invalid": "Ange en giltig roll", - "error.user.undefined": "Användaren kan inte hittas", - "error.user.update.permission": "Du har inte behörighet att uppdatera användaren \"{name}\"", - - "error.validation.accepted": "Vänligen bekräfta", - "error.validation.alpha": "Ange endast tecken mellan a-z", - "error.validation.alphanum": "Ange endast tecken mellan a-z eller siffror 0-9", - "error.validation.between": "Ange ett värde mellan \"{min}\" och \"{max}\"", - "error.validation.boolean": "Bekräfta eller neka", - "error.validation.contains": "Ange ett värde som innehåller \"{needle}\"", - "error.validation.date": "Ange ett giltigt datum", - "error.validation.date.after": "Ange ett datum efter {date}", - "error.validation.date.before": "Ange ett datum före {date}", - "error.validation.date.between": "Ange ett datum mellan {min} och {max}", - "error.validation.denied": "Vänligen neka", - "error.validation.different": "Värdet får inte vara \"{other}\"", - "error.validation.email": "Ange en giltig e-postadress", - "error.validation.endswith": "Värdet måste sluta med \"{end}\"", - "error.validation.filename": "Ange ett giltigt filnamn", - "error.validation.in": "Ange ett av följande: ({in})", - "error.validation.integer": "Ange en giltig heltalssiffra", - "error.validation.ip": "Ange en giltig IP-adress", - "error.validation.less": "Ange ett värde lägre än {max}", - "error.validation.match": "Värdet matchar inte det förväntade mönstret", - "error.validation.max": "Ange ett värde som är lika med eller lägre än {max}", - "error.validation.maxlength": "Ange ett kortare värde. (max {max} tecken)", - "error.validation.maxwords": "Ange inte mer än {max} ord", - "error.validation.min": "Ange ett värde som är lika med eller större än {min}", - "error.validation.minlength": "Ange ett längre värde. (minst {min} tecken)", - "error.validation.minwords": "Ange minst {min} ord", - "error.validation.more": "Ange ett större värde än {min}", - "error.validation.notcontains": "Ange ett värde som inte innehåller \"{needle}\"", - "error.validation.notin": "Ange inte något av följande: ({notIn})", - "error.validation.option": "Välj ett giltigt alternativ", - "error.validation.num": "Ange ett giltigt nummer", - "error.validation.required": "Ange någonting", - "error.validation.same": "Ange \"{other}\"", - "error.validation.size": "Storleken av värdet måste vara \"{size}\"", - "error.validation.startswith": "Värdet måste börja med \"{start}\"", - "error.validation.time": "Ange en giltig tid", - "error.validation.time.after": "Ange en tid efter {time}", - "error.validation.time.before": "Ange en tid före {time}", - "error.validation.time.between": "Ange en tid mellan {min} och {max}", - "error.validation.url": "Ange en giltig URL", - - "expand": "Expandera", - "expand.all": "Expandera alla", - - "field.required": "Fältet krävs", - "field.blocks.changeType": "Ändra typ", - "field.blocks.code.name": "Kod", - "field.blocks.code.language": "Språk", - "field.blocks.code.placeholder": "Din kod …", - "field.blocks.delete.confirm": "Vill du verkligen radera detta block?", - "field.blocks.delete.confirm.all": "Vill du verkligen radera alla block?", - "field.blocks.delete.confirm.selected": "Vill du verkligen radera de valda blocken?", - "field.blocks.empty": "Inga block än", - "field.blocks.fieldsets.label": "Välj en typ av block …", - "field.blocks.fieldsets.paste": "Tryck på {{ shortcut }} för att klistra in/importera block från ditt urklipp", - "field.blocks.gallery.name": "Galleri", - "field.blocks.gallery.images.empty": "Inga bilder än", - "field.blocks.gallery.images.label": "Bilder", - "field.blocks.heading.level": "Nivå", - "field.blocks.heading.name": "Rubrik", - "field.blocks.heading.text": "Text", - "field.blocks.heading.placeholder": "Rubrik …", - "field.blocks.image.alt": "Alternativ text", - "field.blocks.image.caption": "Rubrik", - "field.blocks.image.crop": "Beskär", - "field.blocks.image.link": "Länk", - "field.blocks.image.location": "Plats", - "field.blocks.image.name": "Bild", - "field.blocks.image.placeholder": "Välj en bild", - "field.blocks.image.ratio": "Bildförhållande", - "field.blocks.image.url": "Bild-URL", - "field.blocks.line.name": "Linje", - "field.blocks.list.name": "Punktlista", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Text", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Citat", - "field.blocks.quote.text.label": "Text", - "field.blocks.quote.text.placeholder": "Citat …", - "field.blocks.quote.citation.label": "Citat", - "field.blocks.quote.citation.placeholder": "av …", - "field.blocks.text.name": "Text", - "field.blocks.text.placeholder": "Text …", - "field.blocks.video.caption": "Rubrik", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Ange en URL till en video", - "field.blocks.video.url.label": "Video-URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Inga filer valda än", - - "field.layout.delete": "Radera layout", - "field.layout.delete.confirm": "Vill du verkligen radera denna layout?", - "field.layout.empty": "Inga rader än", - "field.layout.select": "Välj en layout", - - "field.pages.empty": "Inga sidor valda än", - "field.structure.delete.confirm": "Vill du verkligen radera denna rad?", - "field.structure.empty": "Inga poster än", - "field.users.empty": "Inga användare valda än", - - "file.blueprint": "Denna fil har ingen blueprint än. Du kan skapa en i /site/blueprints/files/{blueprint}.yml", - "file.delete.confirm": "Vill du verkligen radera
{filename}?", - "file.sort": "Ändra position", - - "files": "Filer", - "files.empty": "Inga filer än", - - "hide": "Göm", - "hour": "Timme", - "import": "Importera", - "info": "Info", - "insert": "Infoga", - "insert.after": "Infoga efter", - "insert.before": "Infoga före", - "install": "Installera", - - "installation": "Installation", - "installation.completed": "Panelen har installerats", - "installation.disabled": "Installeraren för panelen är som standard inaktiverad på offentliga servrar. Kör installeraren på en lokal maskin eller aktivera den med alternativet panel.install.", - "installation.issues.accounts": "Mappen /site/accounts finns inte eller är inte skrivbar", - "installation.issues.content": "Mappen /content finns inte eller är inte skrivbar", - "installation.issues.curl": "Tillägget CURL krävs", - "installation.issues.headline": "Panelen kan inte installeras", - "installation.issues.mbstring": "Tillägget MB String krävs", - "installation.issues.media": "Mappen /media finns inte eller är inte skrivbar", - "installation.issues.php": "Se till att du använder PHP 7+", - "installation.issues.server": "Kirby kräver Apache, Nginx eller Caddy", - "installation.issues.sessions": "Mappen /site/sessions finns inte eller är inte skrivbar", - - "language": "Spr\u00e5k", - "language.code": "Kod", - "language.convert": "Ange som standard", - "language.convert.confirm": "

Vill du verkligen göra {name} till standardspråket? Detta kan inte ångras.

Om {name} har oöversatt innehåll, kommer det inte längre finnas en alternativ översättning och delar av sajten kommer kanske att vara tom.

", - "language.create": "Lägg till ett nytt språk", - "language.delete.confirm": "Vill du verkligen radera språket {name} inklusive alla översättningar? Detta kan inte ångras!", - "language.deleted": "Språket har raderats", - "language.direction": "Läsriktning", - "language.direction.ltr": "Vänster till höger", - "language.direction.rtl": "Höger till vänster", - "language.locale": "PHP locale string", - "language.locale.warning": "Du använder en anpassad språkinställning. Ändra den i språkfilen i mappen /site/languages", - "language.name": "Namn", - "language.updated": "Språket har uppdaterats", - - "languages": "Språk", - "languages.default": "Standardspråk", - "languages.empty": "Det finns inga språk ännu", - "languages.secondary": "Sekundära språk", - "languages.secondary.empty": "Det finns inga sekundära språk ännu", - - "license": "Licens", - "license.buy": "Köp en licens", - "license.register": "Registrera", - "license.manage": "Hantera dina licenser", - "license.register.help": "Du fick din licenskod via e-post efter inköpet. Kopiera och klistra in den för att registrera licensen.", - "license.register.label": "Ange din licenskod", - "license.register.success": "Tack för att du stödjer Kirby", - "license.unregistered": "Detta är en oregistrerad demo av Kirby", - "license.unregistered.label": "Oregistrerad", - - "link": "L\u00e4nk", - "link.text": "L\u00e4nktext", - - "loading": "Laddar", - - "lock.unsaved": "Osparade ändringar", - "lock.unsaved.empty": "Det finns inga fler osparade ändringar", - "lock.isLocked": "Osparade ändringar av {email}", - "lock.file.isLocked": "Filen redigeras just nu av {email} och kan inte redigeras.", - "lock.page.isLocked": "Sidan redigeras just nu av {email} och kan inte redigeras.", - "lock.unlock": "Lås upp", - "lock.isUnlocked": "Dina osparade ändringar har skrivits över av en annan användare. Du kan ladda ner dina ändringar för att slå ihop dem manuellt.", - - "login": "Logga in", - "login.code.label.login": "Inloggningskod", - "login.code.label.password-reset": "Kod för återställning av lösenord", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "Om din e-postadress är registrerad skickades den begärda koden via e-post.", - "login.email.login.body": "Hej {user.nameOrEmail}.\n\nDu begärde nyligen en inloggningskod till panelen för {site}.\nFöljande kod är giltig i {timeout} minuter:\n\n{code}\n\nOm du inte har begärt någon inloggningskod, ignorera detta e-postmeddelande eller kontakta din administratör om du har frågor.\nAv säkerhetsskäl, vidarebefordra INTE detta e-postmeddelande.", - "login.email.login.subject": "Din inloggningskod", - "login.email.password-reset.body": "Hej {user.nameOrEmail}.\n\nDu begärde nyligen en kod för återställning av ditt lösenord till panelen för {site}.\nFöljande kod är giltig i {timeout} minuter:\n\n{code}\n\nOm du inte har begärt en återställning av ditt lösenord, ignorera detta e-postmeddelande eller kontakta din administratör om du har frågor.\nAv säkerhetsskäl, vidarebefordra INTE detta e-postmeddelande.", - "login.email.password-reset.subject": "Din kod för återställning av lösenord", - "login.remember": "Håll mig inloggad", - "login.reset": "Återställ lösenord", - "login.toggleText.code.email": "Logga in via e-post", - "login.toggleText.code.email-password": "Logga in med lösenord", - "login.toggleText.password-reset.email": "Glömt ditt lösenord?", - "login.toggleText.password-reset.email-password": "← Tillbaka till inloggning", - - "logout": "Logga ut", - - "menu": "Meny", - "meridiem": "a.m./p.m.", - "mime": "Mediatyp", - "minutes": "Minuter", - - "month": "Månad", - "months.april": "April", - "months.august": "Augusti", - "months.december": "December", - "months.february": "Februari", - "months.january": "Januari", - "months.july": "Juli", - "months.june": "Juni", - "months.march": "Mars", - "months.may": "Maj", - "months.november": "November", - "months.october": "Oktober", - "months.september": "September", - - "more": "Mer", - "name": "Namn", - "next": "Nästa", - "no": "nej", - "off": "av", - "on": "på", - "open": "Öppna", - "open.newWindow": "Öppna i nytt fönster", - "options": "Alternativ", - "options.none": "Inga alternativ", - - "orientation": "Orientering", - "orientation.landscape": "Liggande", - "orientation.portrait": "Stående", - "orientation.square": "Kvadrat", - - "page.blueprint": "Denna sida har ingen blueprint än. Du kan skapa en i /site/blueprints/pages/{blueprint}.yml", - "page.changeSlug": "Ändra URL", - "page.changeSlug.fromTitle": "Skapa utifr\u00e5n titel", - "page.changeStatus": "Ändra status", - "page.changeStatus.position": "Välj en ny position", - "page.changeStatus.select": "Välj en ny status", - "page.changeTemplate": "Ändra mall", - "page.delete.confirm": "Vill du verkligen radera {title}?", - "page.delete.confirm.subpages": "Denna sida har undersidor.
Alla undersidor kommer också att raderas.", - "page.delete.confirm.title": "Fyll i sidans titel för att bekräfta", - "page.draft.create": "Skapa utkast", - "page.duplicate.appendix": "Kopiera", - "page.duplicate.files": "Kopiera filer", - "page.duplicate.pages": "Kopiera sidor", - "page.sort": "Ändra position", - "page.status": "Status", - "page.status.draft": "Utkast", - "page.status.draft.description": "Sidan är ett utkast och endast synlig för inloggade redaktörer eller via en hemlig länk", - "page.status.listed": "Publik", - "page.status.listed.description": "Sidan är publik för vem som helst", - "page.status.unlisted": "Olistad", - "page.status.unlisted.description": "Sidan är endast åtkomlig via URL", - - "pages": "Sidor", - "pages.empty": "Inga sidor än", - "pages.status.draft": "Utkast", - "pages.status.listed": "Publicerade", - "pages.status.unlisted": "Olistade", - - "pagination.page": "Sida", - - "password": "L\u00f6senord", - "paste": "Klistra in", - "paste.after": "Klistra in efter", - "pixel": "Pixel", - "plugins": "Tillägg", - "prev": "Föregående", - "preview": "Förhandsgranska", - "remove": "Ta bort", - "rename": "Byt namn", - "replace": "Ersätt", - "retry": "F\u00f6rs\u00f6k igen", - "revert": "Återgå", - "revert.confirm": "Vill du verkligen radera alla osparade ändringar?", - - "role": "Roll", - "role.admin.description": "Administratören har alla behörigheter", - "role.admin.title": "Administratör", - "role.all": "Alla", - "role.empty": "Det finns inga användare med denna roll", - "role.description.placeholder": "Ingen beskrivning", - "role.nobody.description": "Detta är en roll utan några behörigheter", - "role.nobody.title": "Ingen", - - "save": "Spara", - "search": "Sök", - "search.min": "Ange {min} tecken för att söka", - "search.all": "Visa alla", - "search.results.none": "Inga träffar", - - "section.required": "Sektionen krävs", - - "security": "Säkerhet", - "select": "Välj", - "server": "Server", - "settings": "Inställningar", - "show": "Visa", - "site.blueprint": "Webbplatsen har ingen blueprint än. Du kan skapa en i /site/blueprints/site.yml", - "size": "Storlek", - "slug": "URL-appendix", - "sort": "Sortera", - - "stats.empty": "Inga rapporter", - "system.issues.content": "Mappen content verkar vara exponerad", - "system.issues.debug": "Felsökningsläget måste vara avstängt i produktion", - "system.issues.git": "Mappen .git verkar vara exponerad", - "system.issues.https": "Vi rekommenderar HTTPS för alla dina webbplatser", - "system.issues.kirby": "Mappen kirby verkar vara exponerad", - "system.issues.site": "Mappen site verkar vara exponerad", - - "title": "Titel", - "template": "Mall", - "today": "Idag", - - "toolbar.button.code": "Kod", - "toolbar.button.bold": "Fet", - "toolbar.button.email": "E-post", - "toolbar.button.headings": "Rubriker", - "toolbar.button.heading.1": "Rubrik 1", - "toolbar.button.heading.2": "Rubrik 2", - "toolbar.button.heading.3": "Rubrik 3", - "toolbar.button.heading.4": "Rubrik 4", - "toolbar.button.heading.5": "Rubrik 5", - "toolbar.button.heading.6": "Rubrik 6", - "toolbar.button.italic": "Kursiv", - "toolbar.button.file": "Fil", - "toolbar.button.file.select": "Välj en fil", - "toolbar.button.file.upload": "Ladda upp en fil", - "toolbar.button.link": "L\u00e4nk", - "toolbar.button.paragraph": "Stycke", - "toolbar.button.strike": "Genomstruken", - "toolbar.button.ol": "Sorterad lista", - "toolbar.button.underline": "Understruken", - "toolbar.button.ul": "Punktlista", - - "translation.author": "Kirby-teamet, Ola Christensson", - "translation.direction": "ltr", - "translation.name": "Svenska", - "translation.locale": "sv_SE", - - "upload": "Ladda upp", - "upload.error.cantMove": "Den överförda filen kunde inte flyttas", - "upload.error.cantWrite": "Det gick inte att skriva filen till hårddisken", - "upload.error.default": "Filen kunde inte laddas upp", - "upload.error.extension": "Filuppladdningen förhindrades på grund av filändelsen", - "upload.error.formSize": "Den överförda filen överskrider den maximala filstorlek som anges i formuläret (MAX_FILE_SIZE)", - "upload.error.iniPostSize": "Den överförda filen överskrider post_max_size-direktivet i php.ini", - "upload.error.iniSize": "Den överförda filen överskrider direktivet upload_max_filesize i php.ini", - "upload.error.noFile": "Ingen fil laddades upp", - "upload.error.noFiles": "Inga filer laddades upp", - "upload.error.partial": "Den överförda filen laddades bara delvis upp", - "upload.error.tmpDir": "Saknar en temporär mapp", - "upload.errors": "Fel", - "upload.progress": "Laddar upp...", - - "url": "URL", - "url.placeholder": "https://exempel.se", - - "user": "Användare", - "user.blueprint": "Du kan skapa ytterligare sektioner och fält för den här användarrollen i /site/blueprints/users/{blueprint}.yml", - "user.changeEmail": "Ändra e-postadress", - "user.changeLanguage": "Ändra språk", - "user.changeName": "Byt namn på denna användare", - "user.changePassword": "Ändra lösenord", - "user.changePassword.new": "Nytt lösenord", - "user.changePassword.new.confirm": "Bekräfta det nya lösenordet...", - "user.changeRole": "Ändra roll", - "user.changeRole.select": "Välj en ny roll", - "user.create": "Lägg till en ny användare", - "user.delete": "Radera denna användare", - "user.delete.confirm": "Vill du verkligen radera
{email}?", - - "users": "Användare", - - "version": "Version", - - "view.account": "Ditt konto", - "view.installation": "Installation", - "view.languages": "Språk", - "view.resetPassword": "Återställ lösenord", - "view.site": "Webbplats", - "view.system": "System", - "view.users": "Anv\u00e4ndare", - - "welcome": "Välkommen", - "year": "År", - "yes": "ja" + "account.changeName": "Ändra ditt namn", + "account.delete": "Radera ditt konto", + "account.delete.confirm": "Vill du verkligen radera ditt konto? Du kommer att loggas ut omedelbart. Ditt konto kan inte återställas.", + + "add": "L\u00e4gg till", + "author": "Författare", + "avatar": "Profilbild", + "back": "Tillbaka", + "cancel": "Avbryt", + "change": "\u00c4ndra", + "close": "St\u00e4ng", + "confirm": "Spara", + "collapse": "Kollapsa", + "collapse.all": "Kollapsa alla", + "copy": "Kopiera", + "copy.all": "Kopiera alla", + "create": "Skapa", + + "date": "Datum", + "date.select": "Välj ett datum", + + "day": "Dag", + "days.fri": "Fre", + "days.mon": "M\u00e5n", + "days.sat": "L\u00f6r", + "days.sun": "S\u00f6n", + "days.thu": "Tor", + "days.tue": "Tis", + "days.wed": "Ons", + + "debugging": "Felsökning", + + "delete": "Radera", + "delete.all": "Radera allt", + + "dialog.files.empty": "Inga filer att välja", + "dialog.pages.empty": "Inga sidor att välja", + "dialog.users.empty": "Inga användare att välja", + + "dimensions": "Dimensioner", + "disabled": "Inaktiverad", + "discard": "Kassera", + "download": "Ladda ner", + "duplicate": "Duplicera", + + "edit": "Redigera", + + "email": "E-postadress", + "email.placeholder": "namn@exempel.se", + + "entries": "Poster", + "entry": "Post", + + "environment": "Miljö", + + "error.access.code": "Ogiltig kod", + "error.access.login": "Ogiltig inloggning", + "error.access.panel": "Du saknar behörighet att nå panelen", + "error.access.view": "Du saknar behörighet att nå denna del av panelen", + + "error.avatar.create.fail": "Profilbilden kunde inte laddas upp", + "error.avatar.delete.fail": "Profilbilden kunde inte raderas", + "error.avatar.dimensions.invalid": "Se till att profilbildens bredd och höjd är mindre än 3000 pixlar", + "error.avatar.mime.forbidden": "Profilbilden måste vara i formatet JPEG eller PNG", + + "error.blueprint.notFound": "Blueprint \"{name}\" kunde inte laddas", + + "error.blocks.max.plural": "Du får inte lägga till mer än {max} block", + "error.blocks.max.singular": "Du får inte lägga till mer än ett block", + "error.blocks.min.plural": "Du måste lägga till minst {min} block", + "error.blocks.min.singular": "Du måste lägga till minst ett block", + "error.blocks.validation": "Det finns ett fel i fältet \"{field}\" i block {index} med blocktypen \"{fieldset}\"", + + "error.email.preset.notFound": "E-postförinställningen \"{name}\" kan inte hittas", + + "error.field.converter.invalid": "Ogiltig omvandlare \"{converter}\"", + + "error.file.changeName.empty": "Namnet får inte vara tomt", + "error.file.changeName.permission": "Du har inte behörighet att ändra namnet på \"{filename}\"", + "error.file.duplicate": "En fil med namnet \"{filename}\" existerar redan", + "error.file.extension.forbidden": "Filändelsen \"{extension}\" är inte tillåten", + "error.file.extension.invalid": "Ogiltig filändelse: {extension}", + "error.file.extension.missing": "Filen \"{filename}\" saknar filändelse", + "error.file.maxheight": "Bildens höjd får inte överstiga {height} pixlar", + "error.file.maxsize": "Filen är för stor", + "error.file.maxwidth": "Bildens bredd får inte överstiga {width} pixlar", + "error.file.mime.differs": "Den uppladdade filen måste vara av samma mime-typ \"{mime}\"", + "error.file.mime.forbidden": "Mediatypen \"{mime}\" är inte tillåten", + "error.file.mime.invalid": "Ogiltig mime-typ: {mime}", + "error.file.mime.missing": "Mediatypen för \"{filename}\" kan inte detekteras", + "error.file.minheight": "Bildens höjd måste vara minst {height} pixlar", + "error.file.minsize": "Filen är för liten", + "error.file.minwidth": "Bildens bredd måste vara minst {width} pixlar", + "error.file.name.missing": "Filnamnet får inte vara tomt", + "error.file.notFound": "Filen \"{filename}\" kan ej hittas", + "error.file.orientation": "Bildens orientering måste vara \"{orientation}\"", + "error.file.type.forbidden": "Du har inte behörighet att ladda upp filer av typen {type}", + "error.file.type.invalid": "Ogiltig filtyp: {type}", + "error.file.undefined": "Filen kan inte hittas", + + "error.form.incomplete": "Vänligen åtgärda alla formulärfel...", + "error.form.notSaved": "Formuläret kunde inte sparas", + + "error.language.code": "Ange en giltig kod för språket", + "error.language.duplicate": "Språket finns redan", + "error.language.name": "Ange ett giltigt namn för språket", + "error.language.notFound": "Språket hittades inte", + + "error.layout.validation.block": "Det finns ett fel i fältet \"{field}\" i blocket {blockIndex} med blocktypen \"{fieldset}\" i layouten {layoutIndex}", + "error.layout.validation.settings": "Det finns ett fel i inställningarna för layout {index}", + + "error.license.format": "Ange en giltig licensnyckel", + "error.license.email": "Ange en giltig e-postadress", + "error.license.verification": "Licensen kunde inte verifieras", + + "error.object.validation": "Det finns ett fel i fältet \"{label}\":\n{message}", + + "error.offline": "Panelen är för närvarande offline", + + "error.page.changeSlug.permission": "Du har inte behörighet att ändra URL-appendixen för \"{slug}\"", + "error.page.changeStatus.incomplete": "Sidan innehåller fel och kan inte publiceras", + "error.page.changeStatus.permission": "Statusen för denna sida kan inte ändras", + "error.page.changeStatus.toDraft.invalid": "Statusen för sidan \"{slug}\" kan inte ändras till utkast", + "error.page.changeTemplate.invalid": "Mallen för sidan \"{slug}\" kan inte ändras", + "error.page.changeTemplate.permission": "Du har inte behörighet att ändra mallen för \"{slug}\"", + "error.page.changeTitle.empty": "Titeln får inte vara tom", + "error.page.changeTitle.permission": "Du har inte behörighet att ändra titeln för \"{slug}\"", + "error.page.create.permission": "Du har inte behörighet att skapa \"{slug}\"", + "error.page.delete": "Sidan \"{slug}\" kan inte raderas", + "error.page.delete.confirm": "Fyll i sidans titel för att bekräfta", + "error.page.delete.hasChildren": "Sidan har undersidor och kan inte raderas", + "error.page.delete.permission": "Du har inte behörighet att radera \"{slug}\"", + "error.page.draft.duplicate": "Ett utkast med URL-appendixen \"{slug}\" existerar redan", + "error.page.duplicate": "En sida med URL-appendixen \"{slug}\" existerar redan", + "error.page.duplicate.permission": "Du har inte behörighet att duplicera \"{slug}\"", + "error.page.notFound": "Sidan \"{slug}\" kan inte hittas", + "error.page.num.invalid": "Ange ett giltigt nummer för sortering. Numret får inte vara negativt.", + "error.page.slug.invalid": "Ange en giltig URL-appendix", + "error.page.slug.maxlength": "Permalänkens längd måste vara kortare än \"{length}\" tecken", + "error.page.sort.permission": "Sidan \"{slug}\" kan inte sorteras", + "error.page.status.invalid": "Sätt en giltig status för sidan", + "error.page.undefined": "Sidan kan inte hittas", + "error.page.update.permission": "Du har inte behörighet att uppdatera \"{slug}\"", + + "error.section.files.max.plural": "Du får inte lägga till mer än {max} filer till sektionen \"{section}\"", + "error.section.files.max.singular": "Du får inte lägga till mer än en fil i sektionen \"{section}\"", + "error.section.files.min.plural": "Sektionen \"{section}\" kräver minst {min} filer", + "error.section.files.min.singular": "Sektionen \"{section}\" kräver minst en fil", + + "error.section.pages.max.plural": "Du får inte lägga till mer än {max} sidor till sektionen \"{section}\"", + "error.section.pages.max.singular": "Du får inte lägga till mer än en sida i sektionen \"{section}\"", + "error.section.pages.min.plural": "Sektionen \"{section}\" kräver minst {min} sidor", + "error.section.pages.min.singular": "Sektionen \"{section}\" kräver minst en sida", + + "error.section.notLoaded": "Sektionen \"{name}\" kunde inte laddas", + "error.section.type.invalid": "Sektionstypen \"{type}\" är inte giltig", + + "error.site.changeTitle.empty": "Titeln får inte vara tom", + "error.site.changeTitle.permission": "Du har inte behörighet att ändra titeln på webbplatsen", + "error.site.update.permission": "Du har inte behörighet att uppdatera webbplatsen", + + "error.template.default.notFound": "Standardmallen existerar inte", + + "error.unexpected": "Ett oväntat fel uppstod! Aktivera felsökningsläge för mer information: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "Du har inte behörighet att ändra e-postadressen för användaren \"{name}\"", + "error.user.changeLanguage.permission": "Du har inte behörighet att ändra språket för användaren \"{name}\"", + "error.user.changeName.permission": "Du har inte behörighet att ändra namnet för användaren \"{name}\"", + "error.user.changePassword.permission": "Du har inte behörighet att ändra lösenordet för användaren \"{name}\"", + "error.user.changeRole.lastAdmin": "Rollen för den återstående adminanvändaren kan inte ändras", + "error.user.changeRole.permission": "Du har inte behörighet att ändra rollen för användaren \"{name}\"", + "error.user.changeRole.toAdmin": "Du har inte behörighet att ge någon en administratörsroll", + "error.user.create.permission": "Du har inte behörighet att skapa denna användare", + "error.user.delete": "Användaren kan inte raderas", + "error.user.delete.lastAdmin": "Den återstående administratören kan inte raderas", + "error.user.delete.lastUser": "Den återstående användaren kan inte raderas", + "error.user.delete.permission": "Du har inte behörighet att radera användaren \"{name}\"", + "error.user.duplicate": "En användare med e-postadressen \"{email}\" finns redan", + "error.user.email.invalid": "Ange en giltig e-postadress", + "error.user.language.invalid": "Ange ett giltigt språk", + "error.user.notFound": "Användaren \"{name}\" kan ej hittas", + "error.user.password.invalid": "Ange ett giltigt lösenord. Lösenordet måste vara minst 8 tecken långt.", + "error.user.password.notSame": "Lösenorden matchar inte", + "error.user.password.undefined": "Användaren har inget lösenord", + "error.user.password.wrong": "Fel lösenord", + "error.user.role.invalid": "Ange en giltig roll", + "error.user.undefined": "Användaren kan inte hittas", + "error.user.update.permission": "Du har inte behörighet att uppdatera användaren \"{name}\"", + + "error.validation.accepted": "Vänligen bekräfta", + "error.validation.alpha": "Ange endast tecken mellan a-z", + "error.validation.alphanum": "Ange endast tecken mellan a-z eller siffror 0-9", + "error.validation.between": "Ange ett värde mellan \"{min}\" och \"{max}\"", + "error.validation.boolean": "Bekräfta eller neka", + "error.validation.contains": "Ange ett värde som innehåller \"{needle}\"", + "error.validation.date": "Ange ett giltigt datum", + "error.validation.date.after": "Ange ett datum efter {date}", + "error.validation.date.before": "Ange ett datum före {date}", + "error.validation.date.between": "Ange ett datum mellan {min} och {max}", + "error.validation.denied": "Vänligen neka", + "error.validation.different": "Värdet får inte vara \"{other}\"", + "error.validation.email": "Ange en giltig e-postadress", + "error.validation.endswith": "Värdet måste sluta med \"{end}\"", + "error.validation.filename": "Ange ett giltigt filnamn", + "error.validation.in": "Ange ett av följande: ({in})", + "error.validation.integer": "Ange en giltig heltalssiffra", + "error.validation.ip": "Ange en giltig IP-adress", + "error.validation.less": "Ange ett värde lägre än {max}", + "error.validation.match": "Värdet matchar inte det förväntade mönstret", + "error.validation.max": "Ange ett värde som är lika med eller lägre än {max}", + "error.validation.maxlength": "Ange ett kortare värde. (max {max} tecken)", + "error.validation.maxwords": "Ange inte mer än {max} ord", + "error.validation.min": "Ange ett värde som är lika med eller större än {min}", + "error.validation.minlength": "Ange ett längre värde. (minst {min} tecken)", + "error.validation.minwords": "Ange minst {min} ord", + "error.validation.more": "Ange ett större värde än {min}", + "error.validation.notcontains": "Ange ett värde som inte innehåller \"{needle}\"", + "error.validation.notin": "Ange inte något av följande: ({notIn})", + "error.validation.option": "Välj ett giltigt alternativ", + "error.validation.num": "Ange ett giltigt nummer", + "error.validation.required": "Ange någonting", + "error.validation.same": "Ange \"{other}\"", + "error.validation.size": "Storleken av värdet måste vara \"{size}\"", + "error.validation.startswith": "Värdet måste börja med \"{start}\"", + "error.validation.time": "Ange en giltig tid", + "error.validation.time.after": "Ange en tid efter {time}", + "error.validation.time.before": "Ange en tid före {time}", + "error.validation.time.between": "Ange en tid mellan {min} och {max}", + "error.validation.url": "Ange en giltig URL", + + "expand": "Expandera", + "expand.all": "Expandera alla", + + "field.required": "Fältet krävs", + "field.blocks.changeType": "Ändra typ", + "field.blocks.code.name": "Kod", + "field.blocks.code.language": "Språk", + "field.blocks.code.placeholder": "Din kod …", + "field.blocks.delete.confirm": "Vill du verkligen radera detta block?", + "field.blocks.delete.confirm.all": "Vill du verkligen radera alla block?", + "field.blocks.delete.confirm.selected": "Vill du verkligen radera de valda blocken?", + "field.blocks.empty": "Inga block än", + "field.blocks.fieldsets.label": "Välj en typ av block …", + "field.blocks.fieldsets.paste": "Tryck på {{ shortcut }} för att klistra in/importera block från ditt urklipp", + "field.blocks.gallery.name": "Galleri", + "field.blocks.gallery.images.empty": "Inga bilder än", + "field.blocks.gallery.images.label": "Bilder", + "field.blocks.heading.level": "Nivå", + "field.blocks.heading.name": "Rubrik", + "field.blocks.heading.text": "Text", + "field.blocks.heading.placeholder": "Rubrik …", + "field.blocks.image.alt": "Alternativ text", + "field.blocks.image.caption": "Rubrik", + "field.blocks.image.crop": "Beskär", + "field.blocks.image.link": "Länk", + "field.blocks.image.location": "Plats", + "field.blocks.image.name": "Bild", + "field.blocks.image.placeholder": "Välj en bild", + "field.blocks.image.ratio": "Bildförhållande", + "field.blocks.image.url": "Bild-URL", + "field.blocks.line.name": "Linje", + "field.blocks.list.name": "Punktlista", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Text", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Citat", + "field.blocks.quote.text.label": "Text", + "field.blocks.quote.text.placeholder": "Citat …", + "field.blocks.quote.citation.label": "Citat", + "field.blocks.quote.citation.placeholder": "av …", + "field.blocks.text.name": "Text", + "field.blocks.text.placeholder": "Text …", + "field.blocks.video.caption": "Rubrik", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Ange en URL till en video", + "field.blocks.video.url.label": "Video-URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Inga filer valda än", + + "field.layout.delete": "Radera layout", + "field.layout.delete.confirm": "Vill du verkligen radera denna layout?", + "field.layout.empty": "Inga rader än", + "field.layout.select": "Välj en layout", + + "field.object.empty": "Ingen information ännu", + + "field.pages.empty": "Inga sidor valda än", + + "field.structure.delete.confirm": "Vill du verkligen radera denna rad?", + "field.structure.empty": "Inga poster än", + + "field.users.empty": "Inga användare valda än", + + "file.blueprint": "Denna fil har ingen blueprint än. Du kan skapa en i /site/blueprints/files/{blueprint}.yml", + "file.delete.confirm": "Vill du verkligen radera
{filename}?", + "file.sort": "Ändra position", + + "files": "Filer", + "files.empty": "Inga filer än", + + "hide": "Göm", + "hour": "Timme", + "import": "Importera", + "info": "Info", + "insert": "Infoga", + "insert.after": "Infoga efter", + "insert.before": "Infoga före", + "install": "Installera", + + "installation": "Installation", + "installation.completed": "Panelen har installerats", + "installation.disabled": "Installeraren för panelen är som standard inaktiverad på offentliga servrar. Kör installeraren på en lokal maskin eller aktivera den med alternativet panel.install.", + "installation.issues.accounts": "Mappen /site/accounts finns inte eller är inte skrivbar", + "installation.issues.content": "Mappen /content finns inte eller är inte skrivbar", + "installation.issues.curl": "Tillägget CURL krävs", + "installation.issues.headline": "Panelen kan inte installeras", + "installation.issues.mbstring": "Tillägget MB String krävs", + "installation.issues.media": "Mappen /media finns inte eller är inte skrivbar", + "installation.issues.php": "Se till att du använder PHP 7+", + "installation.issues.server": "Kirby kräver Apache, Nginx eller Caddy", + "installation.issues.sessions": "Mappen /site/sessions finns inte eller är inte skrivbar", + + "language": "Spr\u00e5k", + "language.code": "Kod", + "language.convert": "Ange som standard", + "language.convert.confirm": "

Vill du verkligen göra {name} till standardspråket? Detta kan inte ångras.

Om {name} har oöversatt innehåll, kommer det inte längre finnas en alternativ översättning och delar av sajten kommer kanske att vara tom.

", + "language.create": "Lägg till ett nytt språk", + "language.delete.confirm": "Vill du verkligen radera språket {name} inklusive alla översättningar? Detta kan inte ångras!", + "language.deleted": "Språket har raderats", + "language.direction": "Läsriktning", + "language.direction.ltr": "Vänster till höger", + "language.direction.rtl": "Höger till vänster", + "language.locale": "PHP locale string", + "language.locale.warning": "Du använder en anpassad språkinställning. Ändra den i språkfilen i mappen /site/languages", + "language.name": "Namn", + "language.updated": "Språket har uppdaterats", + + "languages": "Språk", + "languages.default": "Standardspråk", + "languages.empty": "Det finns inga språk ännu", + "languages.secondary": "Sekundära språk", + "languages.secondary.empty": "Det finns inga sekundära språk ännu", + + "license": "Licens", + "license.buy": "Köp en licens", + "license.register": "Registrera", + "license.manage": "Hantera dina licenser", + "license.register.help": "Du fick din licenskod via e-post efter inköpet. Kopiera och klistra in den för att registrera licensen.", + "license.register.label": "Ange din licenskod", + "license.register.success": "Tack för att du stödjer Kirby", + "license.unregistered": "Detta är en oregistrerad demo av Kirby", + "license.unregistered.label": "Oregistrerad", + + "link": "L\u00e4nk", + "link.text": "L\u00e4nktext", + + "loading": "Laddar", + + "lock.unsaved": "Osparade ändringar", + "lock.unsaved.empty": "Det finns inga fler osparade ändringar", + "lock.isLocked": "Osparade ändringar av {email}", + "lock.file.isLocked": "Filen redigeras just nu av {email} och kan inte redigeras.", + "lock.page.isLocked": "Sidan redigeras just nu av {email} och kan inte redigeras.", + "lock.unlock": "Lås upp", + "lock.isUnlocked": "Dina osparade ändringar har skrivits över av en annan användare. Du kan ladda ner dina ändringar för att slå ihop dem manuellt.", + + "login": "Logga in", + "login.code.label.login": "Inloggningskod", + "login.code.label.password-reset": "Kod för återställning av lösenord", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "Om din e-postadress är registrerad skickades den begärda koden via e-post.", + "login.email.login.body": "Hej {user.nameOrEmail}.\n\nDu begärde nyligen en inloggningskod till panelen för {site}.\nFöljande kod är giltig i {timeout} minuter:\n\n{code}\n\nOm du inte har begärt någon inloggningskod, ignorera detta e-postmeddelande eller kontakta din administratör om du har frågor.\nAv säkerhetsskäl, vidarebefordra INTE detta e-postmeddelande.", + "login.email.login.subject": "Din inloggningskod", + "login.email.password-reset.body": "Hej {user.nameOrEmail}.\n\nDu begärde nyligen en kod för återställning av ditt lösenord till panelen för {site}.\nFöljande kod är giltig i {timeout} minuter:\n\n{code}\n\nOm du inte har begärt en återställning av ditt lösenord, ignorera detta e-postmeddelande eller kontakta din administratör om du har frågor.\nAv säkerhetsskäl, vidarebefordra INTE detta e-postmeddelande.", + "login.email.password-reset.subject": "Din kod för återställning av lösenord", + "login.remember": "Håll mig inloggad", + "login.reset": "Återställ lösenord", + "login.toggleText.code.email": "Logga in via e-post", + "login.toggleText.code.email-password": "Logga in med lösenord", + "login.toggleText.password-reset.email": "Glömt ditt lösenord?", + "login.toggleText.password-reset.email-password": "← Tillbaka till inloggning", + + "logout": "Logga ut", + + "menu": "Meny", + "meridiem": "a.m./p.m.", + "mime": "Mediatyp", + "minutes": "Minuter", + + "month": "Månad", + "months.april": "April", + "months.august": "Augusti", + "months.december": "December", + "months.february": "Februari", + "months.january": "Januari", + "months.july": "Juli", + "months.june": "Juni", + "months.march": "Mars", + "months.may": "Maj", + "months.november": "November", + "months.october": "Oktober", + "months.september": "September", + + "more": "Mer", + "name": "Namn", + "next": "Nästa", + "no": "nej", + "off": "av", + "on": "på", + "open": "Öppna", + "open.newWindow": "Öppna i nytt fönster", + "options": "Alternativ", + "options.none": "Inga alternativ", + + "orientation": "Orientering", + "orientation.landscape": "Liggande", + "orientation.portrait": "Stående", + "orientation.square": "Kvadrat", + + "page.blueprint": "Denna sida har ingen blueprint än. Du kan skapa en i /site/blueprints/pages/{blueprint}.yml", + "page.changeSlug": "Ändra URL", + "page.changeSlug.fromTitle": "Skapa utifr\u00e5n titel", + "page.changeStatus": "Ändra status", + "page.changeStatus.position": "Välj en ny position", + "page.changeStatus.select": "Välj en ny status", + "page.changeTemplate": "Ändra mall", + "page.delete.confirm": "Vill du verkligen radera {title}?", + "page.delete.confirm.subpages": "Denna sida har undersidor.
Alla undersidor kommer också att raderas.", + "page.delete.confirm.title": "Fyll i sidans titel för att bekräfta", + "page.draft.create": "Skapa utkast", + "page.duplicate.appendix": "Kopiera", + "page.duplicate.files": "Kopiera filer", + "page.duplicate.pages": "Kopiera sidor", + "page.sort": "Ändra position", + "page.status": "Status", + "page.status.draft": "Utkast", + "page.status.draft.description": "Sidan är ett utkast och endast synlig för inloggade redaktörer eller via en hemlig länk", + "page.status.listed": "Publik", + "page.status.listed.description": "Sidan är publik för vem som helst", + "page.status.unlisted": "Olistad", + "page.status.unlisted.description": "Sidan är endast åtkomlig via URL", + + "pages": "Sidor", + "pages.empty": "Inga sidor än", + "pages.status.draft": "Utkast", + "pages.status.listed": "Publicerade", + "pages.status.unlisted": "Olistade", + + "pagination.page": "Sida", + + "password": "L\u00f6senord", + "paste": "Klistra in", + "paste.after": "Klistra in efter", + "pixel": "Pixel", + "plugin": "Tillägg", + "plugins": "Tillägg", + "prev": "Föregående", + "preview": "Förhandsgranska", + "remove": "Ta bort", + "rename": "Byt namn", + "replace": "Ersätt", + "retry": "F\u00f6rs\u00f6k igen", + "revert": "Återgå", + "revert.confirm": "Vill du verkligen radera alla osparade ändringar?", + + "role": "Roll", + "role.admin.description": "Administratören har alla behörigheter", + "role.admin.title": "Administratör", + "role.all": "Alla", + "role.empty": "Det finns inga användare med denna roll", + "role.description.placeholder": "Ingen beskrivning", + "role.nobody.description": "Detta är en roll utan några behörigheter", + "role.nobody.title": "Ingen", + + "save": "Spara", + "search": "Sök", + "search.min": "Ange {min} tecken för att söka", + "search.all": "Visa alla", + "search.results.none": "Inga träffar", + + "section.required": "Sektionen krävs", + + "security": "Säkerhet", + "select": "Välj", + "server": "Server", + "settings": "Inställningar", + "show": "Visa", + "site.blueprint": "Webbplatsen har ingen blueprint än. Du kan skapa en i /site/blueprints/site.yml", + "size": "Storlek", + "slug": "URL-appendix", + "sort": "Sortera", + + "stats.empty": "Inga rapporter", + "system.issues.content": "Mappen content verkar vara exponerad", + "system.issues.eol.kirby": "Din installerade Kirby-version har nått slutet av sin livscykel och kommer inte att få fler säkerhetsuppdateringar", + "system.issues.eol.plugin": "Den installerade versionen av tillägget { plugin } har nått slutet på sin livscykel och kommer inte att få fler säkerhetsuppdateringar.", + "system.issues.debug": "Felsökningsläget måste vara avstängt i produktion", + "system.issues.git": "Mappen .git verkar vara exponerad", + "system.issues.https": "Vi rekommenderar HTTPS för alla dina webbplatser", + "system.issues.kirby": "Mappen kirby verkar vara exponerad", + "system.issues.site": "Mappen site verkar vara exponerad", + "system.issues.vulnerability.kirby": "Din installation kan vara påverkad av följande sårbarhet ({ severity } allvarlighetsgrad): { description }", + "system.issues.vulnerability.plugin": "Din installation kan vara påverkad av följande sårbarhet i tillägget { plugin } ({ severity } allvarlighetsgrad): { description }", + "system.updateStatus": "Uppdateringsstatus", + "system.updateStatus.error": "Det gick inte att söka efter uppdateringar", + "system.updateStatus.not-vulnerable": "Inga kända sårbarheter", + "system.updateStatus.security-update": "Gratis säkerhetsuppdatering { version } tillgänglig", + "system.updateStatus.security-upgrade": "Uppgradering { version } med säkerhetskorrigeringar är tillgänglig", + "system.updateStatus.unreleased": "Osläppt version", + "system.updateStatus.up-to-date": "Uppdaterad", + "system.updateStatus.update": "Gratis uppdatering { version } tillgänglig", + "system.updateStatus.upgrade": "Uppgradering { version } tillgänglig", + + "title": "Titel", + "template": "Mall", + "today": "Idag", + + "toolbar.button.code": "Kod", + "toolbar.button.bold": "Fet", + "toolbar.button.email": "E-post", + "toolbar.button.headings": "Rubriker", + "toolbar.button.heading.1": "Rubrik 1", + "toolbar.button.heading.2": "Rubrik 2", + "toolbar.button.heading.3": "Rubrik 3", + "toolbar.button.heading.4": "Rubrik 4", + "toolbar.button.heading.5": "Rubrik 5", + "toolbar.button.heading.6": "Rubrik 6", + "toolbar.button.italic": "Kursiv", + "toolbar.button.file": "Fil", + "toolbar.button.file.select": "Välj en fil", + "toolbar.button.file.upload": "Ladda upp en fil", + "toolbar.button.link": "L\u00e4nk", + "toolbar.button.paragraph": "Stycke", + "toolbar.button.strike": "Genomstruken", + "toolbar.button.ol": "Sorterad lista", + "toolbar.button.underline": "Understruken", + "toolbar.button.ul": "Punktlista", + + "translation.author": "Kirby-teamet, Ola Christensson", + "translation.direction": "ltr", + "translation.name": "Svenska", + "translation.locale": "sv_SE", + + "upload": "Ladda upp", + "upload.error.cantMove": "Den överförda filen kunde inte flyttas", + "upload.error.cantWrite": "Det gick inte att skriva filen till hårddisken", + "upload.error.default": "Filen kunde inte laddas upp", + "upload.error.extension": "Filuppladdningen förhindrades på grund av filändelsen", + "upload.error.formSize": "Den överförda filen överskrider den maximala filstorlek som anges i formuläret (MAX_FILE_SIZE)", + "upload.error.iniPostSize": "Den överförda filen överskrider post_max_size-direktivet i php.ini", + "upload.error.iniSize": "Den överförda filen överskrider direktivet upload_max_filesize i php.ini", + "upload.error.noFile": "Ingen fil laddades upp", + "upload.error.noFiles": "Inga filer laddades upp", + "upload.error.partial": "Den överförda filen laddades bara delvis upp", + "upload.error.tmpDir": "Saknar en temporär mapp", + "upload.errors": "Fel", + "upload.progress": "Laddar upp...", + + "url": "URL", + "url.placeholder": "https://exempel.se", + + "user": "Användare", + "user.blueprint": "Du kan skapa ytterligare sektioner och fält för den här användarrollen i /site/blueprints/users/{blueprint}.yml", + "user.changeEmail": "Ändra e-postadress", + "user.changeLanguage": "Ändra språk", + "user.changeName": "Byt namn på denna användare", + "user.changePassword": "Ändra lösenord", + "user.changePassword.new": "Nytt lösenord", + "user.changePassword.new.confirm": "Bekräfta det nya lösenordet...", + "user.changeRole": "Ändra roll", + "user.changeRole.select": "Välj en ny roll", + "user.create": "Lägg till en ny användare", + "user.delete": "Radera denna användare", + "user.delete.confirm": "Vill du verkligen radera
{email}?", + + "users": "Användare", + + "version": "Version", + "version.current": "Aktuell version", + "version.latest": "Senaste version", + "versionInformation": "Versionsinformation", + + "view.account": "Ditt konto", + "view.installation": "Installation", + "view.languages": "Språk", + "view.resetPassword": "Återställ lösenord", + "view.site": "Webbplats", + "view.system": "System", + "view.users": "Anv\u00e4ndare", + + "welcome": "Välkommen", + "year": "År", + "yes": "ja" } diff --git a/kirby/i18n/translations/tr.json b/kirby/i18n/translations/tr.json index 94e21dd..be7ac82 100644 --- a/kirby/i18n/translations/tr.json +++ b/kirby/i18n/translations/tr.json @@ -1,573 +1,596 @@ { - "account.changeName": "İsminizi değiştirin", - "account.delete": "Hesabınızı silin", - "account.delete.confirm": "Hesabınızı gerçekten silmek istiyor musunuz? Oturumunuz hemen sonlandırılacaktır. Hesabınız daha sonra geri alınamaz.", - - "add": "Ekle", - "author": "Yazar", - "avatar": "Profil resmi", - "back": "Geri", - "cancel": "\u0130ptal", - "change": "De\u011fi\u015ftir", - "close": "Kapat", - "confirm": "Tamam", - "collapse": "Daralt", - "collapse.all": "Tümünü daralt", - "copy": "Kopyala", - "copy.all": "Tümünü kopyala", - "create": "Oluştur", - - "date": "Tarih", - "date.select": "Bir tarih seçiniz", - - "day": "Gün", - "days.fri": "Cum", - "days.mon": "Pzt", - "days.sat": "Cmt", - "days.sun": "Paz", - "days.thu": "Per", - "days.tue": "Sal", - "days.wed": "\u00c7ar", - - "debugging": "Hata ayıklama", - - "delete": "Sil", - "delete.all": "Tümünü sil", - - "dialog.files.empty": "Seçilecek dosya yok", - "dialog.pages.empty": "Seçilecek sayfa yok", - "dialog.users.empty": "Seçilecek kullanıcı yok", - - "dimensions": "Boyutlar", - "disabled": "Devredışı", - "discard": "Vazge\u00e7", - "download": "İndir", - "duplicate": "Kopyala", - - "edit": "D\u00fczenle", - - "email": "E-Posta", - "email.placeholder": "eposta@ornek.com", - - "entries": "Girdiler", - "entry": "Girdi", - - "environment": "Ortam", - - "error.access.code": "Geçersiz kod", - "error.access.login": "Geçersiz giriş", - "error.access.panel": "Panel'e erişim izniniz yok", - "error.access.view": "Panel'in bu bölümüne erişim izniniz yok", - - "error.avatar.create.fail": "Profil resmi yüklenemedi", - "error.avatar.delete.fail": "Profil resmi silinemedi", - "error.avatar.dimensions.invalid": "Lütfen profil resminin genişliğini ve yüksekliğini 3000 pikselin altında tutun", - "error.avatar.mime.forbidden": "Profil resmi JPEG veya PNG dosyaları olmalıdır", - - "error.blueprint.notFound": "\"{name}\" adlı plan yüklenemedi", - - "error.blocks.max.plural": "{max} bloktan fazlasını eklememelisiniz", - "error.blocks.max.singular": "Birden fazla blok eklememelisiniz", - "error.blocks.min.plural": "En az {min} blok eklemelisiniz", - "error.blocks.min.singular": "En az bir blok eklemelisiniz", - "error.blocks.validation": "{index} bloğunda bir hata var", - - "error.email.preset.notFound": "\"{name}\" e-posta adresi bulunamadı", - - "error.field.converter.invalid": "Geçersiz dönüştürücü \"{converter}\"", - - "error.file.changeName.empty": "İsim boş olmamalıdır", - "error.file.changeName.permission": "\"{filename}\" adını değiştiremezsiniz", - "error.file.duplicate": "\"{filename}\" isimli bir dosya zaten var", - "error.file.extension.forbidden": "\"{extension}\" dosya uzantısına izin verilmiyor", - "error.file.extension.invalid": "Geçersiz uzantı: {extension}", - "error.file.extension.missing": "\"{filename}\" dosyasının uzantısı yok", - "error.file.maxheight": "Resmin yüksekliği {height} pikselden büyük olmamalıdır", - "error.file.maxsize": "Dosya çok büyük", - "error.file.maxwidth": "Resmin genişliği {width} pikselden büyük olmamalıdır", - "error.file.mime.differs": "Yüklenen dosya aynı dosya türü \"{mime}\" olmalıdır", - "error.file.mime.forbidden": "\"{mime}\" medya türüne izin verilmiyor", - "error.file.mime.invalid": "Geçersiz medya türü: {mime}", - "error.file.mime.missing": "\"{filename}\" için medya türü tespit edilemiyor", - "error.file.minheight": "Resmin yüksekliği en az {height} piksel olmalıdır", - "error.file.minsize": "Dosya çok küçük", - "error.file.minwidth": "Resmin genişliği en az {width} piksel olmalıdır", - "error.file.name.missing": "Dosya adı boş bırakılamaz", - "error.file.notFound": "\"{filename}\" dosyası bulunamadı", - "error.file.orientation": "Resmin oryantasyonu \"{orientation}\" olmalıdır", - "error.file.type.forbidden": "{type} dosya yükleme izni yok", - "error.file.type.invalid": "Geçersiz dosya türü: {type}", - "error.file.undefined": "Dosya bulunamad\u0131", - - "error.form.incomplete": "Lütfen tüm form hatalarını düzeltin...", - "error.form.notSaved": "Form kaydedilemedi", - - "error.language.code": "Lütfen dil için geçerli bir kod girin", - "error.language.duplicate": "Bu dil zaten var", - "error.language.name": "Lütfen dil için geçerli bir isim girin", - "error.language.notFound": "Dil bulunamadı", - - "error.layout.validation.block": "{layoutIndex}. düzenin {blockIndex}. bloğunda bir hata var", - "error.layout.validation.settings": "{index}. düzen ayarlarında bir hata var", - - "error.license.format": "Lütfen geçerli bir lisans anahtarı girin", - "error.license.email": "Lütfen geçerli bir e-posta adresi girin", - "error.license.verification": "Lisans doğrulanamadı", - - "error.offline": "Panel şu anda çevrimdışı", - - "error.page.changeSlug.permission": "\"{slug}\" uzantısına sahip bu sayfanın adresini değiştirilemez", - "error.page.changeStatus.incomplete": "Sayfada hatalar var ve yayınlanamadı", - "error.page.changeStatus.permission": "Bu sayfanın durumu değiştirilemez", - "error.page.changeStatus.toDraft.invalid": "\"{slug}\" sayfası bir taslak haline dönüştürülemiyor", - "error.page.changeTemplate.invalid": "\"{slug}\" sayfası için şablon değiştirilemiyor", - "error.page.changeTemplate.permission": "\"{slug}\" için şablonu değiştiremezsiniz", - "error.page.changeTitle.empty": "Başlık boş bırakılamaz", - "error.page.changeTitle.permission": "\"{slug}\" için başlığı değiştiremezsiniz", - "error.page.create.permission": "\"{slug}\" oluşturmanıza izin verilmiyor", - "error.page.delete": "\"{slug}\" sayfası silinemedi", - "error.page.delete.confirm": "Onaylamak için sayfa başlığını girin", - "error.page.delete.hasChildren": "Sayfada alt sayfalar var ve silinemiyor", - "error.page.delete.permission": "\"{slug}\" öğesini silmenize izin verilmiyor", - "error.page.draft.duplicate": "\"{slug}\" adres eki olan bir sayfa taslağı zaten mevcut", - "error.page.duplicate": "\"{slug}\" adres eki içeren bir sayfa zaten mevcut", - "error.page.duplicate.permission": "\"{slug}\" öğesini çoğaltmanıza izin verilmiyor", - "error.page.notFound": "\"{slug}\" uzantısındaki sayfa bulunamadı", - "error.page.num.invalid": "Lütfen geçerli bir sıralama numarası girin. Sayılar negatif olmamalıdır.", - "error.page.slug.invalid": "Lütfen geçerli bir URL eki girin", - "error.page.slug.maxlength": "Adres uzantısı \"{length}\" karakterden az olmalıdır", - "error.page.sort.permission": "\"{slug}\" sayfası sıralanamıyor", - "error.page.status.invalid": "Lütfen geçerli bir sayfa durumu ayarlayın", - "error.page.undefined": "Sayfa bulunamad\u0131", - "error.page.update.permission": "\"{slug}\" güncellemesine izin verilmiyor", - - "error.section.files.max.plural": "\"{section}\" bölümüne {max} dosyadan daha fazlasını eklememelisiniz", - "error.section.files.max.singular": "\"{section}\" bölümüne birden fazla dosya eklememelisiniz", - "error.section.files.min.plural": "\"{section}\" bölümü en az {min} dosya gerektiriyor", - "error.section.files.min.singular": "\"{section}\" bölümü en az bir dosya gerektiriyor", - - "error.section.pages.max.plural": "\"{section}\" bölümüne maksimum {max} sayfadan fazla ekleyemezsiniz", - "error.section.pages.max.singular": "\"{section}\" bölümüne birden fazla sayfa ekleyemezsiniz", - "error.section.pages.min.plural": "\"{section}\" bölümü en az {min} sayfa gerektiriyor", - "error.section.pages.min.singular": "\"{section}\" bölümü en az bir sayfa gerektiriyor", - - "error.section.notLoaded": "\"{name}\" bölümü yüklenemedi", - "error.section.type.invalid": "\"{type}\" tipi geçerli değil", - - "error.site.changeTitle.empty": "Başlık boş bırakılamaz", - "error.site.changeTitle.permission": "Sitenin başlığını değiştiremezsin", - "error.site.update.permission": "Siteyi güncellemenize izin verilmiyor", - - "error.template.default.notFound": "Varsayılan şablon yok", - - "error.unexpected": "Beklenmeyen bir hata oluştu! Daha fazla bilgi için hata ayıklama modunu etkinleştirin: https://getkirby.com/docs/reference/system/options/debug", - - "error.user.changeEmail.permission": "\"{name}\" kullanıcısı için e-postayı değiştiremezsiniz", - "error.user.changeLanguage.permission": "\"{name}\" kullanıcısının dilini değiştiremezsin", - "error.user.changeName.permission": "\"{name}\" kullanıcısının adını değiştiremezsiniz", - "error.user.changePassword.permission": "\"{name}\" kullanıcısının şifresini değiştiremezsiniz", - "error.user.changeRole.lastAdmin": "Son yöneticinin rolü değiştirilemez", - "error.user.changeRole.permission": "\"{name}\" kullanıcısının rolünü değiştiremezsin", - "error.user.changeRole.toAdmin": "Birini yönetici rolüne tanıtmanıza izin verilmiyor", - "error.user.create.permission": "Bu kullanıcıyı oluşturmanıza izin verilmiyor", - "error.user.delete": "\"{name}\" kullanıcısı silinemedi", - "error.user.delete.lastAdmin": "Son y\u00f6netici kullan\u0131c\u0131y\u0131 silemezsiniz", - "error.user.delete.lastUser": "Son kullanıcı silinemez", - "error.user.delete.permission": "\"{name}\" kullanıcısını silme yetkiniz yok", - "error.user.duplicate": "\"{email}\" e-posta adresine sahip bir kullanıcı zaten var", - "error.user.email.invalid": "Lütfen geçerli bir e-posta adresi girin", - "error.user.language.invalid": "Lütfen geçerli bir dil girin", - "error.user.notFound": "\"{name}\" kullanıcısı bulunamadı", - "error.user.password.invalid": "Lütfen geçerli bir şifre giriniz. Şifreler en az 8 karakter uzunluğunda olmalıdır.", - "error.user.password.notSame": "L\u00fctfen \u015fifreyi do\u011frulay\u0131n", - "error.user.password.undefined": "Bu kullanıcının şifresi yok", - "error.user.password.wrong": "Yanlış şifre", - "error.user.role.invalid": "Lütfen geçerli bir rol girin", - "error.user.undefined": "Kullanıcı bulunamadı", - "error.user.update.permission": "\"{name}\" kullanıcısını güncellemenize izin verilmiyor", - - "error.validation.accepted": "Lütfen onaylayın", - "error.validation.alpha": "Lütfen sadece a-z arasındaki karakterleri girin", - "error.validation.alphanum": "Lütfen sadece a-z veya 0-9 arasındaki rakamları girin", - "error.validation.between": "Lütfen \"{min}\" ile \"{max}\" arasında bir değer girin", - "error.validation.boolean": "Lütfen onaylayın veya reddedin", - "error.validation.contains": "Lütfen \"{needle}\" içeren bir değer girin", - "error.validation.date": "Lütfen geçerli bir tarih girin", - "error.validation.date.after": "Lütfen {date} tarihinden sonra bir tarih girin", - "error.validation.date.before": "Lütfen {date} tarihinden önce bir tarih girin", - "error.validation.date.between": "Lütfen {min} ve {max} arasında bir tarih girin", - "error.validation.denied": "Lütfen reddedin", - "error.validation.different": "Değer \"{other}\" olmamalıdır", - "error.validation.email": "Lütfen geçerli bir e-posta adresi girin", - "error.validation.endswith": "Değer \"{end}\" ile bitmelidir", - "error.validation.filename": "Lütfen geçerli bir dosya adı girin", - "error.validation.in": "Lütfen bunlardan birini girin: ({in})", - "error.validation.integer": "Lütfen geçerli bir tamsayı girin", - "error.validation.ip": "Lütfen geçerli bir ip adresi girin", - "error.validation.less": "Lütfen {max} 'dan daha düşük bir değer girin", - "error.validation.match": "Değer beklenen modelle eşleşmiyor", - "error.validation.max": "Lütfen {max} 'a eşit veya daha küçük bir değer girin", - "error.validation.maxlength": "Lütfen daha kısa bir değer girin. (maks. {max} karakter)", - "error.validation.maxwords": "Lütfen en fazla {max} kelime(ler) girin", - "error.validation.min": "Lütfen {min} ile eşit veya daha büyük bir değer girin", - "error.validation.minlength": "Lütfen daha uzun bir değer girin. (min. {min} karakter)", - "error.validation.minwords": "Lütfen en az {min} kelime(ler) girin", - "error.validation.more": "Lütfen {min} değerinden daha büyük bir değer girin", - "error.validation.notcontains": "Lütfen \"{needle}\" içermeyen bir değer girin", - "error.validation.notin": "Lütfen bunlardan herhangi birini girmeyin: ({notIn})", - "error.validation.option": "Lütfen geçerli bir seçenek girin", - "error.validation.num": "Lütfen geçerli bir sayı girin", - "error.validation.required": "Lütfen birşeyler girin", - "error.validation.same": "Lütfen \"{other}\" yazınız", - "error.validation.size": "Değerin boyutu \"{size}\" olmalıdır", - "error.validation.startswith": "Değer \"{start}\" ile başlamalıdır", - "error.validation.time": "Lütfen geçerli bir zaman girin", - "error.validation.time.after": "Lütfen {time} sonrası bir tarih girin", - "error.validation.time.before": "Lütfen {time} öncesi bir tarih girin", - "error.validation.time.between": "Lütfen {min} ile {max} arasında bir tarih girin", - "error.validation.url": "Lütfen geçerli bir adres girin", - - "expand": "Genişlet", - "expand.all": "Tümünü genişlet", - - "field.required": "Alan gereklidir", - "field.blocks.changeType": "Türü değiştir", - "field.blocks.code.name": "Kod", - "field.blocks.code.language": "Dil", - "field.blocks.code.placeholder": "Kodunuz …", - "field.blocks.delete.confirm": "Bu bloğu gerçekten silmek istiyor musunuz?", - "field.blocks.delete.confirm.all": "Tüm blokları gerçekten silmek istiyor musunuz?", - "field.blocks.delete.confirm.selected": "Seçilen blokları gerçekten silmek istiyor musunuz?", - "field.blocks.empty": "Henüz blok yok", - "field.blocks.fieldsets.label": "Lütfen bir blok türü seçiniz …", - "field.blocks.fieldsets.paste": "Panonuzdan blokları yapıştırmak veya içe aktarmak için {{ shortcut }}'e basın", - "field.blocks.gallery.name": "Galeri", - "field.blocks.gallery.images.empty": "Henüz görsel yok", - "field.blocks.gallery.images.label": "Görseller", - "field.blocks.heading.level": "Seviye", - "field.blocks.heading.name": "Başlık", - "field.blocks.heading.text": "Metin", - "field.blocks.heading.placeholder": "Başlık …", - "field.blocks.image.alt": "Alternatif metin", - "field.blocks.image.caption": "Altyazı", - "field.blocks.image.crop": "Kırp", - "field.blocks.image.link": "Bağlantı", - "field.blocks.image.location": "Lokasyon", - "field.blocks.image.name": "Görsel", - "field.blocks.image.placeholder": "Bir görsel seçin", - "field.blocks.image.ratio": "Oran", - "field.blocks.image.url": "Görsel URL", - "field.blocks.line.name": "Çizgi", - "field.blocks.list.name": "Liste", - "field.blocks.markdown.name": "Markdown", - "field.blocks.markdown.label": "Metin", - "field.blocks.markdown.placeholder": "Markdown …", - "field.blocks.quote.name": "Alıntı", - "field.blocks.quote.text.label": "Metin", - "field.blocks.quote.text.placeholder": "Alıntı …", - "field.blocks.quote.citation.label": "Alıntı", - "field.blocks.quote.citation.placeholder": "yazar …", - "field.blocks.text.name": "Metin", - "field.blocks.text.placeholder": "Metin …", - "field.blocks.video.caption": "Altyazı", - "field.blocks.video.name": "Video", - "field.blocks.video.placeholder": "Bir video URL'si girin", - "field.blocks.video.url.label": "Video-URL", - "field.blocks.video.url.placeholder": "https://youtube.com/?v=", - - "field.files.empty": "Henüz dosya seçilmedi", - - "field.layout.delete": "Düzeni sil", - "field.layout.delete.confirm": "Bu düzeni gerçekten silmek istiyor musunuz?", - "field.layout.empty": "Henüz satır yok", - "field.layout.select": "Bir düzen seçin", - - "field.pages.empty": "Henüz sayfa seçilmedi", - "field.structure.delete.confirm": "Bu girdiyi silmek istedi\u011finizden emin misiniz?", - "field.structure.empty": "Hen\u00fcz bir girdi yok", - "field.users.empty": "Henüz kullanıcı seçilmedi", - - "file.blueprint": "Bu dosyanın henüz bir planı yok. Kurulumu /site/blueprints/files/{blueprint}.yml dosyasında tanımlayabilirsiniz.", - "file.delete.confirm": "{filename} dosyasını silmek istediğinizden emin misiniz?", - "file.sort": "Pozisyon değiştir", - - "files": "Dosyalar", - "files.empty": "Henüz dosya yok", - - "hide": "Gizle", - "hour": "Saat", - "import": "İçe aktar", - "info": "Bilgi", - "insert": "Ekle", - "insert.after": "Sonrasına ekle", - "insert.before": "Öncesine ekle", - "install": "Kurulum", - - "installation": "Kurulum", - "installation.completed": "Panel kuruldu", - "installation.disabled": "Panel yükleyici, herkese açık sunucularda varsayılan olarak devre dışıdır. Lütfen yükleyiciyi yerel bir makinede çalıştırın veya panel.install seçeneğiyle etkinleştirin.", - "installation.issues.accounts": "/site/accounts klasörü yok yada yazılabilir değil", - "installation.issues.content": "/content klasörü yok yada yazılabilir değil", - "installation.issues.curl": "CURL eklentisi gerekli", - "installation.issues.headline": "Panel kurulamadı", - "installation.issues.mbstring": "MB String eklentisi gerekli", - "installation.issues.media": "/media klasörü yok yada yazılamaz", - "installation.issues.php": "PHP 7+ kullandığınızdan emin olun. ", - "installation.issues.server": "Kirby Apache, Nginx veya Caddy gerektirir", - "installation.issues.sessions": "/site/sessions klasörü mevcut değil veya yazılabilir değil", - - "language": "Dil", - "language.code": "Kod", - "language.convert": "Varsayılan yap", - "language.convert.confirm": "

{name}'i varsayılan dile dönüştürmek istiyor musunuz? Bu geri alınamaz.

{name} çevrilmemiş içeriğe sahipse, artık geçerli bir geri dönüş olmaz ve sitenizin bazı bölümleri boş olabilir.

", - "language.create": "Yeni bir dil ekle", - "language.delete.confirm": "Tüm çevirileri içeren {name} dilini gerçekten silmek istiyor musunuz? Bu geri alınamaz!", - "language.deleted": "Dil silindi", - "language.direction": "Okuma yönü", - "language.direction.ltr": "Soldan sağa", - "language.direction.rtl": "Sağdan sola", - "language.locale": "PHP yerel dizesi", - "language.locale.warning": "Özel bir yerel ayar kullanıyorsunuz. Lütfen /site/languages konumundaki dil dosyasından değiştirin.", - "language.name": "İsim", - "language.updated": "Dil güncellendi", - - "languages": "Diller", - "languages.default": "Varsayılan dil", - "languages.empty": "Henüz hiç dil yok", - "languages.secondary": "İkincil diller", - "languages.secondary.empty": "Henüz ikincil bir dil yok", - - "license": "Lisans", - "license.buy": "Bir lisans satın al", - "license.register": "Kayıt Ol", - "license.manage": "Lisanslarınızı yönetin", - "license.register.help": "Satın alma işleminden sonra e-posta yoluyla lisans kodunuzu aldınız. Lütfen kayıt olmak için kodu kopyalayıp yapıştırın.", - "license.register.label": "Lütfen lisans kodunu giriniz", - "license.register.success": "Kirby'yi desteklediğiniz için teşekkürler", - "license.unregistered": "Bu Kirby'nin kayıtsız bir demosu", - "license.unregistered.label": "Kayıtsız", - - "link": "Ba\u011flant\u0131", - "link.text": "Ba\u011flant\u0131 yaz\u0131s\u0131", - - "loading": "Yükleniyor", - - "lock.unsaved": "Kaydedilmemiş değişiklikler", - "lock.unsaved.empty": "Daha fazla kaydedilmemiş değişiklik yok", - "lock.isLocked": "{email} tarafından kaydedilmemiş değişiklikler", - "lock.file.isLocked": "Dosya şu anda {email} tarafından düzenlenmektedir ve değiştirilemez.", - "lock.page.isLocked": "Sayfa şu anda {email} tarafından düzenlenmektedir ve değiştirilemez.", - "lock.unlock": "Kilidi Aç", - "lock.isUnlocked": "Kaydedilmemiş değişikliklerin üzerine başka bir kullanıcı yazmış. Değişikliklerinizi el ile birleştirmek için değişikliklerinizi indirebilirsiniz.", - - "login": "Giriş", - "login.code.label.login": "Giriş kodu", - "login.code.label.password-reset": "Şifre sıfırlama kodu", - "login.code.placeholder.email": "000 000", - "login.code.text.email": "E-posta adresiniz kayıtlıysa, istenen kod e-posta yoluyla gönderilmiştir.", - "login.email.login.body": "Merhaba {user.nameOrEmail},\n\nKısa süre önce {site} Panel'i için bir giriş kodu istediniz.\nAşağıdaki giriş kodu {timeout} dakika boyunca geçerli olacaktır:\n\n{code}\n\nBir giriş kodu istemediyseniz, lütfen bu e-postayı dikkate almayın veya sorularınız varsa yöneticinize başvurun.\nGüvenliğiniz için lütfen bu e-postayı İLETMEYİN.", - "login.email.login.subject": "Giriş kodunuz", - "login.email.password-reset.body": "Merhaba {user.nameOrEmail},\n\nKısa süre önce {site} Panel'i için bir şifre sıfırlama kodu istediniz.\nAşağıdaki şifre sıfırlama kodu {timeout} dakika boyunca geçerli olacaktır:\n\n{code}\n\nŞifre sıfırlama kodu istemediyseniz, lütfen bu e-postayı dikkate almayın veya sorularınız varsa yöneticinizle iletişime geçin.\nGüvenliğiniz için lütfen bu e-postayı İLETMEYİN.", - "login.email.password-reset.subject": "Şifre sıfırlama kodunuz", - "login.remember": "Oturumumu açık tut", - "login.reset": "Şifreyi sıfırla", - "login.toggleText.code.email": "E-posta ile giriş yapın", - "login.toggleText.code.email-password": "Şifre ile giriş yapın", - "login.toggleText.password-reset.email": "Şifrenizi mi unuttunuz?", - "login.toggleText.password-reset.email-password": "← Girişe geri dön", - - "logout": "Güvenli Çıkış", - - "menu": "Menü", - "meridiem": "AM/PM", - "mime": "Medya Türü", - "minutes": "Dakika", - - "month": "Ay", - "months.april": "Nisan", - "months.august": "A\u011fustos", - "months.december": "Aral\u0131k", - "months.february": "Şubat", - "months.january": "Ocak", - "months.july": "Temmuz", - "months.june": "Haziran", - "months.march": "Mart", - "months.may": "May\u0131s", - "months.november": "Kas\u0131m", - "months.october": "Ekim", - "months.september": "Eyl\u00fcl", - - "more": "Daha Fazla", - "name": "İsim", - "next": "Sonraki", - "no": "hayır", - "off": "kapalı", - "on": "açık", - "open": "Önizleme", - "open.newWindow": "Yeni pencerede aç", - "options": "Seçenekler", - "options.none": "Seçenek yok", - - "orientation": "Oryantasyon", - "orientation.landscape": "Yatay", - "orientation.portrait": "Dikey", - "orientation.square": "Kare", - - "page.blueprint": "Bu dosyanın henüz bir planı yok. Kurulumu /site/blueprints/pages/{blueprint}.yml dosyasında tanımlayabilirsiniz.", - "page.changeSlug": "Web Adresini Değiştir", - "page.changeSlug.fromTitle": "Ba\u015fl\u0131ktan olu\u015ftur", - "page.changeStatus": "Durumu değiştir", - "page.changeStatus.position": "Lütfen bir pozisyon seçin", - "page.changeStatus.select": "Yeni bir durum seçin", - "page.changeTemplate": "Şablonu değiştir", - "page.delete.confirm": "{title} sayfasını silmek istediğinizden emin misiniz?", - "page.delete.confirm.subpages": "Bu sayfada alt sayfalar var.
Tüm alt sayfalar da silinecek.", - "page.delete.confirm.title": "Onaylamak için sayfa başlığını girin", - "page.draft.create": "Taslak oluştur", - "page.duplicate.appendix": "Kopya", - "page.duplicate.files": "Dosyaları kopyala", - "page.duplicate.pages": "Sayfaları kopyala", - "page.sort": "Pozisyon değiştir", - "page.status": "Durum", - "page.status.draft": "Taslak", - "page.status.draft.description": "Sayfa taslak halinde ve yalnızca oturum açmış editörler için veya gizli bağlantı üzerinden görülebilir", - "page.status.listed": "Herkese Açık", - "page.status.listed.description": "Bu sayfa herkese açık", - "page.status.unlisted": "Liste Dışı", - "page.status.unlisted.description": "Bu sayfa sadece bağlantı adresi ile erişilebilir", - - "pages": "Sayfalar", - "pages.empty": "Henüz sayfa yok", - "pages.status.draft": "Taslaklar", - "pages.status.listed": "Yayınlandı", - "pages.status.unlisted": "Liste Dışı", - - "pagination.page": "Sayfa", - - "password": "\u015eifre", - "paste": "Yapıştır", - "paste.after": "Sonrasına yapıştır", - "pixel": "Piksel", - "plugins": "Eklentiler", - "prev": "Önceki", - "preview": "Önizle", - "remove": "Kaldır", - "rename": "Yeniden Adlandır", - "replace": "De\u011fi\u015ftir", - "retry": "Tekrar Dene", - "revert": "Vazge\u00e7", - "revert.confirm": "Gerçekten kaydedilmemiş tüm değişiklikleri silmek istiyor musunuz?", - - "role": "Rol", - "role.admin.description": "Yönetici tüm haklara sahiptir", - "role.admin.title": "Yönetici", - "role.all": "Tümü", - "role.empty": "Bu role ait kullanıcı bulunamadı", - "role.description.placeholder": "Açıklama yok", - "role.nobody.description": "Bu hiçbir izni olmayan bir geri dönüş rolüdür.", - "role.nobody.title": "Hiçkimse", - - "save": "Kaydet", - "search": "Arama", - "search.min": "Aramak için {min} karakter girin", - "search.all": "Tümünü göster", - "search.results.none": "Sonuç yok", - - "section.required": "Bölüm gereklidir", - - "security": "Güvenlik", - "select": "Seç", - "server": "Sunucu", - "settings": "Ayarlar", - "show": "Göster", - "site.blueprint": "Sitenin henüz bir planı yok. Kurulumu /site/blueprints/site.yml'de tanımlayabilirsiniz.", - "size": "Boyut", - "slug": "Web Adres Uzantısı", - "sort": "Sırala", - - "stats.empty": "Rapor yok", - "system.issues.content": "İçerik klasörü açığa çıkmış görünüyor", - "system.issues.debug": "Canlı modda hata ayıklama kapatılmalıdır", - "system.issues.git": ".git klasörü açığa çıkmış görünüyor", - "system.issues.https": "Tüm siteleriniz için HTTPS'yi öneriyoruz", - "system.issues.kirby": "Kirby klasörü açığa çıkmış görünüyor", - "system.issues.site": "Site klasörü açığa çıkmış görünüyor", - - "title": "Başlık", - "template": "\u015eablon", - "today": "Bugün", - - "toolbar.button.code": "Kod", - "toolbar.button.bold": "Kalın Yazı", - "toolbar.button.email": "E-Posta", - "toolbar.button.headings": "Başlıklar", - "toolbar.button.heading.1": "Başlık 1", - "toolbar.button.heading.2": "Başlık 2", - "toolbar.button.heading.3": "Başlık 3", - "toolbar.button.heading.4": "Başlık 4", - "toolbar.button.heading.5": "Başlık 5", - "toolbar.button.heading.6": "Başlık 6", - "toolbar.button.italic": "Eğik Yazı", - "toolbar.button.file": "Dosya", - "toolbar.button.file.select": "Bir dosya seçin", - "toolbar.button.file.upload": "Bir dosya yükleyin", - "toolbar.button.link": "Ba\u011flant\u0131", - "toolbar.button.paragraph": "Paragraf", - "toolbar.button.strike": "Üstü çizili", - "toolbar.button.ol": "Sıralı liste", - "toolbar.button.underline": "Altı çizili", - "toolbar.button.ul": "Madde listesi", - - "translation.author": "Kirby Takımı", - "translation.direction": "ltr", - "translation.name": "T\u00fcrk\u00e7e", - "translation.locale": "tr_TR", - - "upload": "Yükle", - "upload.error.cantMove": "Yüklenen dosya taşınamadı", - "upload.error.cantWrite": "Dosya diske yazılamadı", - "upload.error.default": "Dosya yüklenemedi", - "upload.error.extension": "Dosya yükleme uzantısı tarafından durduruldu", - "upload.error.formSize": "Yüklenen dosya, formda belirtilen MAX_FILE_SIZE yönergesini aşıyor", - "upload.error.iniPostSize": "Yüklenen dosya php.ini içindeki post_max_size yönergesini aşıyor", - "upload.error.iniSize": "Yüklenen dosya php.ini içindeki upload_max_filesize yönergesini aşıyor", - "upload.error.noFile": "Dosya yüklenmedi", - "upload.error.noFiles": "Dosyalar yüklenmedi", - "upload.error.partial": "Yüklenen dosya sadece kısmen yüklendi", - "upload.error.tmpDir": "Geçici klasör eksik", - "upload.errors": "Hata", - "upload.progress": "Yükleniyor...", - - "url": "Url", - "url.placeholder": "https://ornek.com", - - "user": "Kullanıcı", - "user.blueprint": "Bu kullanıcı rolü için /site/blueprints/users/{blueprint}.yml içinde ek bölümler ve form alanları tanımlayabilirsiniz", - "user.changeEmail": "E-postayı değiştir", - "user.changeLanguage": "Dili değiştir", - "user.changeName": "Kullanıcıyı yeniden adlandır", - "user.changePassword": "Şifre değiştir", - "user.changePassword.new": "Yeni Şifre", - "user.changePassword.new.confirm": "Şifreyi onaylayın...", - "user.changeRole": "Rolü değiştir", - "user.changeRole.select": "Yeni bir rol seçin", - "user.create": "Yeni bir kullanıcı ekle", - "user.delete": "Bu kullanıcıyı sil", - "user.delete.confirm": "{email} kullanıcısını silmek istediğinizden emin misiniz?", - - "users": "Kullanıcılar", - - "version": "Versiyon", - - "view.account": "Hesap Bilgilerin", - "view.installation": "Kurulum", - "view.languages": "Diller", - "view.resetPassword": "Şifreyi sıfırla", - "view.site": "Site", - "view.system": "Sistem", - "view.users": "Kullan\u0131c\u0131lar", - - "welcome": "Hoşgeldiniz", - "year": "Yıl", - "yes": "evet" + "account.changeName": "İsminizi değiştirin", + "account.delete": "Hesabınızı silin", + "account.delete.confirm": "Hesabınızı gerçekten silmek istiyor musunuz? Oturumunuz hemen sonlandırılacaktır. Hesabınız daha sonra geri alınamaz.", + + "add": "Ekle", + "author": "Yazar", + "avatar": "Profil resmi", + "back": "Geri", + "cancel": "\u0130ptal", + "change": "De\u011fi\u015ftir", + "close": "Kapat", + "confirm": "Tamam", + "collapse": "Daralt", + "collapse.all": "Tümünü daralt", + "copy": "Kopyala", + "copy.all": "Tümünü kopyala", + "create": "Oluştur", + + "date": "Tarih", + "date.select": "Bir tarih seçiniz", + + "day": "Gün", + "days.fri": "Cum", + "days.mon": "Pzt", + "days.sat": "Cmt", + "days.sun": "Paz", + "days.thu": "Per", + "days.tue": "Sal", + "days.wed": "\u00c7ar", + + "debugging": "Hata ayıklama", + + "delete": "Sil", + "delete.all": "Tümünü sil", + + "dialog.files.empty": "Seçilecek dosya yok", + "dialog.pages.empty": "Seçilecek sayfa yok", + "dialog.users.empty": "Seçilecek kullanıcı yok", + + "dimensions": "Boyutlar", + "disabled": "Devredışı", + "discard": "Vazge\u00e7", + "download": "İndir", + "duplicate": "Kopyala", + + "edit": "D\u00fczenle", + + "email": "E-Posta", + "email.placeholder": "eposta@ornek.com", + + "entries": "Girdiler", + "entry": "Girdi", + + "environment": "Ortam", + + "error.access.code": "Geçersiz kod", + "error.access.login": "Geçersiz giriş", + "error.access.panel": "Panel'e erişim izniniz yok", + "error.access.view": "Panel'in bu bölümüne erişim izniniz yok", + + "error.avatar.create.fail": "Profil resmi yüklenemedi", + "error.avatar.delete.fail": "Profil resmi silinemedi", + "error.avatar.dimensions.invalid": "Lütfen profil resminin genişliğini ve yüksekliğini 3000 pikselin altında tutun", + "error.avatar.mime.forbidden": "Profil resmi JPEG veya PNG dosyaları olmalıdır", + + "error.blueprint.notFound": "\"{name}\" adlı plan yüklenemedi", + + "error.blocks.max.plural": "{max} bloktan fazlasını eklememelisiniz", + "error.blocks.max.singular": "Birden fazla blok eklememelisiniz", + "error.blocks.min.plural": "En az {min} blok eklemelisiniz", + "error.blocks.min.singular": "En az bir blok eklemelisiniz", + "error.blocks.validation": "\"{fieldset}\" blok türünü kullanan {index}. bloktaki \"{field}\" alanında bir hata var", + + "error.email.preset.notFound": "\"{name}\" e-posta adresi bulunamadı", + + "error.field.converter.invalid": "Geçersiz dönüştürücü \"{converter}\"", + + "error.file.changeName.empty": "İsim boş olmamalıdır", + "error.file.changeName.permission": "\"{filename}\" adını değiştiremezsiniz", + "error.file.duplicate": "\"{filename}\" isimli bir dosya zaten var", + "error.file.extension.forbidden": "\"{extension}\" dosya uzantısına izin verilmiyor", + "error.file.extension.invalid": "Geçersiz uzantı: {extension}", + "error.file.extension.missing": "\"{filename}\" dosyasının uzantısı yok", + "error.file.maxheight": "Resmin yüksekliği {height} pikselden büyük olmamalıdır", + "error.file.maxsize": "Dosya çok büyük", + "error.file.maxwidth": "Resmin genişliği {width} pikselden büyük olmamalıdır", + "error.file.mime.differs": "Yüklenen dosya aynı dosya türü \"{mime}\" olmalıdır", + "error.file.mime.forbidden": "\"{mime}\" medya türüne izin verilmiyor", + "error.file.mime.invalid": "Geçersiz medya türü: {mime}", + "error.file.mime.missing": "\"{filename}\" için medya türü tespit edilemiyor", + "error.file.minheight": "Resmin yüksekliği en az {height} piksel olmalıdır", + "error.file.minsize": "Dosya çok küçük", + "error.file.minwidth": "Resmin genişliği en az {width} piksel olmalıdır", + "error.file.name.missing": "Dosya adı boş bırakılamaz", + "error.file.notFound": "\"{filename}\" dosyası bulunamadı", + "error.file.orientation": "Resmin oryantasyonu \"{orientation}\" olmalıdır", + "error.file.type.forbidden": "{type} dosya yükleme izni yok", + "error.file.type.invalid": "Geçersiz dosya türü: {type}", + "error.file.undefined": "Dosya bulunamad\u0131", + + "error.form.incomplete": "Lütfen tüm form hatalarını düzeltin...", + "error.form.notSaved": "Form kaydedilemedi", + + "error.language.code": "Lütfen dil için geçerli bir kod girin", + "error.language.duplicate": "Bu dil zaten var", + "error.language.name": "Lütfen dil için geçerli bir isim girin", + "error.language.notFound": "Dil bulunamadı", + + "error.layout.validation.block": "{layoutIndex}. sıradaki düzende \"{fieldset}\" blok türünü kullanan {blockIndex}. bloktaki \"{field}\" alanında bir hata var", + "error.layout.validation.settings": "{index}. düzen ayarlarında bir hata var", + + "error.license.format": "Lütfen geçerli bir lisans anahtarı girin", + "error.license.email": "Lütfen geçerli bir e-posta adresi girin", + "error.license.verification": "Lisans doğrulanamadı", + + "error.object.validation": "\"{label}\" alanında bir hata var:\n{message}", + + "error.offline": "Panel şu anda çevrimdışı", + + "error.page.changeSlug.permission": "\"{slug}\" uzantısına sahip bu sayfanın adresini değiştirilemez", + "error.page.changeStatus.incomplete": "Sayfada hatalar var ve yayınlanamadı", + "error.page.changeStatus.permission": "Bu sayfanın durumu değiştirilemez", + "error.page.changeStatus.toDraft.invalid": "\"{slug}\" sayfası bir taslak haline dönüştürülemiyor", + "error.page.changeTemplate.invalid": "\"{slug}\" sayfası için şablon değiştirilemiyor", + "error.page.changeTemplate.permission": "\"{slug}\" için şablonu değiştiremezsiniz", + "error.page.changeTitle.empty": "Başlık boş bırakılamaz", + "error.page.changeTitle.permission": "\"{slug}\" için başlığı değiştiremezsiniz", + "error.page.create.permission": "\"{slug}\" oluşturmanıza izin verilmiyor", + "error.page.delete": "\"{slug}\" sayfası silinemedi", + "error.page.delete.confirm": "Onaylamak için sayfa başlığını girin", + "error.page.delete.hasChildren": "Sayfada alt sayfalar var ve silinemiyor", + "error.page.delete.permission": "\"{slug}\" öğesini silmenize izin verilmiyor", + "error.page.draft.duplicate": "\"{slug}\" adres eki olan bir sayfa taslağı zaten mevcut", + "error.page.duplicate": "\"{slug}\" adres eki içeren bir sayfa zaten mevcut", + "error.page.duplicate.permission": "\"{slug}\" öğesini çoğaltmanıza izin verilmiyor", + "error.page.notFound": "\"{slug}\" uzantısındaki sayfa bulunamadı", + "error.page.num.invalid": "Lütfen geçerli bir sıralama numarası girin. Sayılar negatif olmamalıdır.", + "error.page.slug.invalid": "Lütfen geçerli bir URL eki girin", + "error.page.slug.maxlength": "Adres uzantısı \"{length}\" karakterden az olmalıdır", + "error.page.sort.permission": "\"{slug}\" sayfası sıralanamıyor", + "error.page.status.invalid": "Lütfen geçerli bir sayfa durumu ayarlayın", + "error.page.undefined": "Sayfa bulunamad\u0131", + "error.page.update.permission": "\"{slug}\" güncellemesine izin verilmiyor", + + "error.section.files.max.plural": "\"{section}\" bölümüne {max} dosyadan daha fazlasını eklememelisiniz", + "error.section.files.max.singular": "\"{section}\" bölümüne birden fazla dosya eklememelisiniz", + "error.section.files.min.plural": "\"{section}\" bölümü en az {min} dosya gerektiriyor", + "error.section.files.min.singular": "\"{section}\" bölümü en az bir dosya gerektiriyor", + + "error.section.pages.max.plural": "\"{section}\" bölümüne maksimum {max} sayfadan fazla ekleyemezsiniz", + "error.section.pages.max.singular": "\"{section}\" bölümüne birden fazla sayfa ekleyemezsiniz", + "error.section.pages.min.plural": "\"{section}\" bölümü en az {min} sayfa gerektiriyor", + "error.section.pages.min.singular": "\"{section}\" bölümü en az bir sayfa gerektiriyor", + + "error.section.notLoaded": "\"{name}\" bölümü yüklenemedi", + "error.section.type.invalid": "\"{type}\" tipi geçerli değil", + + "error.site.changeTitle.empty": "Başlık boş bırakılamaz", + "error.site.changeTitle.permission": "Sitenin başlığını değiştiremezsin", + "error.site.update.permission": "Siteyi güncellemenize izin verilmiyor", + + "error.template.default.notFound": "Varsayılan şablon yok", + + "error.unexpected": "Beklenmeyen bir hata oluştu! Daha fazla bilgi için hata ayıklama modunu etkinleştirin: https://getkirby.com/docs/reference/system/options/debug", + + "error.user.changeEmail.permission": "\"{name}\" kullanıcısı için e-postayı değiştiremezsiniz", + "error.user.changeLanguage.permission": "\"{name}\" kullanıcısının dilini değiştiremezsin", + "error.user.changeName.permission": "\"{name}\" kullanıcısının adını değiştiremezsiniz", + "error.user.changePassword.permission": "\"{name}\" kullanıcısının şifresini değiştiremezsiniz", + "error.user.changeRole.lastAdmin": "Son yöneticinin rolü değiştirilemez", + "error.user.changeRole.permission": "\"{name}\" kullanıcısının rolünü değiştiremezsin", + "error.user.changeRole.toAdmin": "Birini yönetici rolüne tanıtmanıza izin verilmiyor", + "error.user.create.permission": "Bu kullanıcıyı oluşturmanıza izin verilmiyor", + "error.user.delete": "\"{name}\" kullanıcısı silinemedi", + "error.user.delete.lastAdmin": "Son y\u00f6netici kullan\u0131c\u0131y\u0131 silemezsiniz", + "error.user.delete.lastUser": "Son kullanıcı silinemez", + "error.user.delete.permission": "\"{name}\" kullanıcısını silme yetkiniz yok", + "error.user.duplicate": "\"{email}\" e-posta adresine sahip bir kullanıcı zaten var", + "error.user.email.invalid": "Lütfen geçerli bir e-posta adresi girin", + "error.user.language.invalid": "Lütfen geçerli bir dil girin", + "error.user.notFound": "\"{name}\" kullanıcısı bulunamadı", + "error.user.password.invalid": "Lütfen geçerli bir şifre giriniz. Şifreler en az 8 karakter uzunluğunda olmalıdır.", + "error.user.password.notSame": "L\u00fctfen \u015fifreyi do\u011frulay\u0131n", + "error.user.password.undefined": "Bu kullanıcının şifresi yok", + "error.user.password.wrong": "Yanlış şifre", + "error.user.role.invalid": "Lütfen geçerli bir rol girin", + "error.user.undefined": "Kullanıcı bulunamadı", + "error.user.update.permission": "\"{name}\" kullanıcısını güncellemenize izin verilmiyor", + + "error.validation.accepted": "Lütfen onaylayın", + "error.validation.alpha": "Lütfen sadece a-z arasındaki karakterleri girin", + "error.validation.alphanum": "Lütfen sadece a-z veya 0-9 arasındaki rakamları girin", + "error.validation.between": "Lütfen \"{min}\" ile \"{max}\" arasında bir değer girin", + "error.validation.boolean": "Lütfen onaylayın veya reddedin", + "error.validation.contains": "Lütfen \"{needle}\" içeren bir değer girin", + "error.validation.date": "Lütfen geçerli bir tarih girin", + "error.validation.date.after": "Lütfen {date} tarihinden sonra bir tarih girin", + "error.validation.date.before": "Lütfen {date} tarihinden önce bir tarih girin", + "error.validation.date.between": "Lütfen {min} ve {max} arasında bir tarih girin", + "error.validation.denied": "Lütfen reddedin", + "error.validation.different": "Değer \"{other}\" olmamalıdır", + "error.validation.email": "Lütfen geçerli bir e-posta adresi girin", + "error.validation.endswith": "Değer \"{end}\" ile bitmelidir", + "error.validation.filename": "Lütfen geçerli bir dosya adı girin", + "error.validation.in": "Lütfen bunlardan birini girin: ({in})", + "error.validation.integer": "Lütfen geçerli bir tamsayı girin", + "error.validation.ip": "Lütfen geçerli bir ip adresi girin", + "error.validation.less": "Lütfen {max} 'dan daha düşük bir değer girin", + "error.validation.match": "Değer beklenen modelle eşleşmiyor", + "error.validation.max": "Lütfen {max} 'a eşit veya daha küçük bir değer girin", + "error.validation.maxlength": "Lütfen daha kısa bir değer girin. (maks. {max} karakter)", + "error.validation.maxwords": "Lütfen en fazla {max} kelime(ler) girin", + "error.validation.min": "Lütfen {min} ile eşit veya daha büyük bir değer girin", + "error.validation.minlength": "Lütfen daha uzun bir değer girin. (min. {min} karakter)", + "error.validation.minwords": "Lütfen en az {min} kelime(ler) girin", + "error.validation.more": "Lütfen {min} değerinden daha büyük bir değer girin", + "error.validation.notcontains": "Lütfen \"{needle}\" içermeyen bir değer girin", + "error.validation.notin": "Lütfen bunlardan herhangi birini girmeyin: ({notIn})", + "error.validation.option": "Lütfen geçerli bir seçenek girin", + "error.validation.num": "Lütfen geçerli bir sayı girin", + "error.validation.required": "Lütfen birşeyler girin", + "error.validation.same": "Lütfen \"{other}\" yazınız", + "error.validation.size": "Değerin boyutu \"{size}\" olmalıdır", + "error.validation.startswith": "Değer \"{start}\" ile başlamalıdır", + "error.validation.time": "Lütfen geçerli bir zaman girin", + "error.validation.time.after": "Lütfen {time} sonrası bir tarih girin", + "error.validation.time.before": "Lütfen {time} öncesi bir tarih girin", + "error.validation.time.between": "Lütfen {min} ile {max} arasında bir tarih girin", + "error.validation.url": "Lütfen geçerli bir adres girin", + + "expand": "Genişlet", + "expand.all": "Tümünü genişlet", + + "field.required": "Alan gereklidir", + "field.blocks.changeType": "Türü değiştir", + "field.blocks.code.name": "Kod", + "field.blocks.code.language": "Dil", + "field.blocks.code.placeholder": "Kodunuz …", + "field.blocks.delete.confirm": "Bu bloğu gerçekten silmek istiyor musunuz?", + "field.blocks.delete.confirm.all": "Tüm blokları gerçekten silmek istiyor musunuz?", + "field.blocks.delete.confirm.selected": "Seçilen blokları gerçekten silmek istiyor musunuz?", + "field.blocks.empty": "Henüz blok yok", + "field.blocks.fieldsets.label": "Lütfen bir blok türü seçiniz …", + "field.blocks.fieldsets.paste": "Panonuzdan blokları yapıştırmak veya içe aktarmak için {{ shortcut }}'e basın", + "field.blocks.gallery.name": "Galeri", + "field.blocks.gallery.images.empty": "Henüz görsel yok", + "field.blocks.gallery.images.label": "Görseller", + "field.blocks.heading.level": "Seviye", + "field.blocks.heading.name": "Başlık", + "field.blocks.heading.text": "Metin", + "field.blocks.heading.placeholder": "Başlık …", + "field.blocks.image.alt": "Alternatif metin", + "field.blocks.image.caption": "Altyazı", + "field.blocks.image.crop": "Kırp", + "field.blocks.image.link": "Bağlantı", + "field.blocks.image.location": "Lokasyon", + "field.blocks.image.name": "Görsel", + "field.blocks.image.placeholder": "Bir görsel seçin", + "field.blocks.image.ratio": "Oran", + "field.blocks.image.url": "Görsel URL", + "field.blocks.line.name": "Çizgi", + "field.blocks.list.name": "Liste", + "field.blocks.markdown.name": "Markdown", + "field.blocks.markdown.label": "Metin", + "field.blocks.markdown.placeholder": "Markdown …", + "field.blocks.quote.name": "Alıntı", + "field.blocks.quote.text.label": "Metin", + "field.blocks.quote.text.placeholder": "Alıntı …", + "field.blocks.quote.citation.label": "Alıntı", + "field.blocks.quote.citation.placeholder": "yazar …", + "field.blocks.text.name": "Metin", + "field.blocks.text.placeholder": "Metin …", + "field.blocks.video.caption": "Altyazı", + "field.blocks.video.name": "Video", + "field.blocks.video.placeholder": "Bir video URL'si girin", + "field.blocks.video.url.label": "Video-URL", + "field.blocks.video.url.placeholder": "https://youtube.com/?v=", + + "field.files.empty": "Henüz dosya seçilmedi", + + "field.layout.delete": "Düzeni sil", + "field.layout.delete.confirm": "Bu düzeni gerçekten silmek istiyor musunuz?", + "field.layout.empty": "Henüz satır yok", + "field.layout.select": "Bir düzen seçin", + + "field.object.empty": "Henüz bilgi yok", + + "field.pages.empty": "Henüz sayfa seçilmedi", + + "field.structure.delete.confirm": "Bu girdiyi silmek istedi\u011finizden emin misiniz?", + "field.structure.empty": "Hen\u00fcz bir girdi yok", + + "field.users.empty": "Henüz kullanıcı seçilmedi", + + "file.blueprint": "Bu dosyanın henüz bir planı yok. Kurulumu /site/blueprints/files/{blueprint}.yml dosyasında tanımlayabilirsiniz.", + "file.delete.confirm": "{filename} dosyasını silmek istediğinizden emin misiniz?", + "file.sort": "Pozisyon değiştir", + + "files": "Dosyalar", + "files.empty": "Henüz dosya yok", + + "hide": "Gizle", + "hour": "Saat", + "import": "İçe aktar", + "info": "Bilgi", + "insert": "Ekle", + "insert.after": "Sonrasına ekle", + "insert.before": "Öncesine ekle", + "install": "Kurulum", + + "installation": "Kurulum", + "installation.completed": "Panel kuruldu", + "installation.disabled": "Panel yükleyici, herkese açık sunucularda varsayılan olarak devre dışıdır. Lütfen yükleyiciyi yerel bir makinede çalıştırın veya panel.install seçeneğiyle etkinleştirin.", + "installation.issues.accounts": "/site/accounts klasörü yok yada yazılabilir değil", + "installation.issues.content": "/content klasörü yok yada yazılabilir değil", + "installation.issues.curl": "CURL eklentisi gerekli", + "installation.issues.headline": "Panel kurulamadı", + "installation.issues.mbstring": "MB String eklentisi gerekli", + "installation.issues.media": "/media klasörü yok yada yazılamaz", + "installation.issues.php": "PHP 7+ kullandığınızdan emin olun. ", + "installation.issues.server": "Kirby Apache, Nginx veya Caddy gerektirir", + "installation.issues.sessions": "/site/sessions klasörü mevcut değil veya yazılabilir değil", + + "language": "Dil", + "language.code": "Kod", + "language.convert": "Varsayılan yap", + "language.convert.confirm": "

{name}'i varsayılan dile dönüştürmek istiyor musunuz? Bu geri alınamaz.

{name} çevrilmemiş içeriğe sahipse, artık geçerli bir geri dönüş olmaz ve sitenizin bazı bölümleri boş olabilir.

", + "language.create": "Yeni bir dil ekle", + "language.delete.confirm": "Tüm çevirileri içeren {name} dilini gerçekten silmek istiyor musunuz? Bu geri alınamaz!", + "language.deleted": "Dil silindi", + "language.direction": "Okuma yönü", + "language.direction.ltr": "Soldan sağa", + "language.direction.rtl": "Sağdan sola", + "language.locale": "PHP yerel dizesi", + "language.locale.warning": "Özel bir yerel ayar kullanıyorsunuz. Lütfen /site/languages konumundaki dil dosyasından değiştirin.", + "language.name": "İsim", + "language.updated": "Dil güncellendi", + + "languages": "Diller", + "languages.default": "Varsayılan dil", + "languages.empty": "Henüz hiç dil yok", + "languages.secondary": "İkincil diller", + "languages.secondary.empty": "Henüz ikincil bir dil yok", + + "license": "Lisans", + "license.buy": "Bir lisans satın al", + "license.register": "Kayıt Ol", + "license.manage": "Lisanslarınızı yönetin", + "license.register.help": "Satın alma işleminden sonra e-posta yoluyla lisans kodunuzu aldınız. Lütfen kayıt olmak için kodu kopyalayıp yapıştırın.", + "license.register.label": "Lütfen lisans kodunu giriniz", + "license.register.success": "Kirby'yi desteklediğiniz için teşekkürler", + "license.unregistered": "Bu Kirby'nin kayıtsız bir demosu", + "license.unregistered.label": "Kayıtsız", + + "link": "Ba\u011flant\u0131", + "link.text": "Ba\u011flant\u0131 yaz\u0131s\u0131", + + "loading": "Yükleniyor", + + "lock.unsaved": "Kaydedilmemiş değişiklikler", + "lock.unsaved.empty": "Daha fazla kaydedilmemiş değişiklik yok", + "lock.isLocked": "{email} tarafından kaydedilmemiş değişiklikler", + "lock.file.isLocked": "Dosya şu anda {email} tarafından düzenlenmektedir ve değiştirilemez.", + "lock.page.isLocked": "Sayfa şu anda {email} tarafından düzenlenmektedir ve değiştirilemez.", + "lock.unlock": "Kilidi Aç", + "lock.isUnlocked": "Kaydedilmemiş değişikliklerin üzerine başka bir kullanıcı yazmış. Değişikliklerinizi el ile birleştirmek için değişikliklerinizi indirebilirsiniz.", + + "login": "Giriş", + "login.code.label.login": "Giriş kodu", + "login.code.label.password-reset": "Şifre sıfırlama kodu", + "login.code.placeholder.email": "000 000", + "login.code.text.email": "E-posta adresiniz kayıtlıysa, istenen kod e-posta yoluyla gönderilmiştir.", + "login.email.login.body": "Merhaba {user.nameOrEmail},\n\nKısa süre önce {site} Panel'i için bir giriş kodu istediniz.\nAşağıdaki giriş kodu {timeout} dakika boyunca geçerli olacaktır:\n\n{code}\n\nBir giriş kodu istemediyseniz, lütfen bu e-postayı dikkate almayın veya sorularınız varsa yöneticinize başvurun.\nGüvenliğiniz için lütfen bu e-postayı İLETMEYİN.", + "login.email.login.subject": "Giriş kodunuz", + "login.email.password-reset.body": "Merhaba {user.nameOrEmail},\n\nKısa süre önce {site} Panel'i için bir şifre sıfırlama kodu istediniz.\nAşağıdaki şifre sıfırlama kodu {timeout} dakika boyunca geçerli olacaktır:\n\n{code}\n\nŞifre sıfırlama kodu istemediyseniz, lütfen bu e-postayı dikkate almayın veya sorularınız varsa yöneticinizle iletişime geçin.\nGüvenliğiniz için lütfen bu e-postayı İLETMEYİN.", + "login.email.password-reset.subject": "Şifre sıfırlama kodunuz", + "login.remember": "Oturumumu açık tut", + "login.reset": "Şifreyi sıfırla", + "login.toggleText.code.email": "E-posta ile giriş yapın", + "login.toggleText.code.email-password": "Şifre ile giriş yapın", + "login.toggleText.password-reset.email": "Şifrenizi mi unuttunuz?", + "login.toggleText.password-reset.email-password": "← Girişe geri dön", + + "logout": "Güvenli Çıkış", + + "menu": "Menü", + "meridiem": "AM/PM", + "mime": "Medya Türü", + "minutes": "Dakika", + + "month": "Ay", + "months.april": "Nisan", + "months.august": "A\u011fustos", + "months.december": "Aral\u0131k", + "months.february": "Şubat", + "months.january": "Ocak", + "months.july": "Temmuz", + "months.june": "Haziran", + "months.march": "Mart", + "months.may": "May\u0131s", + "months.november": "Kas\u0131m", + "months.october": "Ekim", + "months.september": "Eyl\u00fcl", + + "more": "Daha Fazla", + "name": "İsim", + "next": "Sonraki", + "no": "hayır", + "off": "kapalı", + "on": "açık", + "open": "Önizleme", + "open.newWindow": "Yeni pencerede aç", + "options": "Seçenekler", + "options.none": "Seçenek yok", + + "orientation": "Oryantasyon", + "orientation.landscape": "Yatay", + "orientation.portrait": "Dikey", + "orientation.square": "Kare", + + "page.blueprint": "Bu dosyanın henüz bir planı yok. Kurulumu /site/blueprints/pages/{blueprint}.yml dosyasında tanımlayabilirsiniz.", + "page.changeSlug": "Web Adresini Değiştir", + "page.changeSlug.fromTitle": "Ba\u015fl\u0131ktan olu\u015ftur", + "page.changeStatus": "Durumu değiştir", + "page.changeStatus.position": "Lütfen bir pozisyon seçin", + "page.changeStatus.select": "Yeni bir durum seçin", + "page.changeTemplate": "Şablonu değiştir", + "page.delete.confirm": "{title} sayfasını silmek istediğinizden emin misiniz?", + "page.delete.confirm.subpages": "Bu sayfada alt sayfalar var.
Tüm alt sayfalar da silinecek.", + "page.delete.confirm.title": "Onaylamak için sayfa başlığını girin", + "page.draft.create": "Taslak oluştur", + "page.duplicate.appendix": "Kopya", + "page.duplicate.files": "Dosyaları kopyala", + "page.duplicate.pages": "Sayfaları kopyala", + "page.sort": "Pozisyon değiştir", + "page.status": "Durum", + "page.status.draft": "Taslak", + "page.status.draft.description": "Sayfa taslak halinde ve yalnızca oturum açmış editörler için veya gizli bağlantı üzerinden görülebilir", + "page.status.listed": "Herkese Açık", + "page.status.listed.description": "Bu sayfa herkese açık", + "page.status.unlisted": "Liste Dışı", + "page.status.unlisted.description": "Bu sayfa sadece bağlantı adresi ile erişilebilir", + + "pages": "Sayfalar", + "pages.empty": "Henüz sayfa yok", + "pages.status.draft": "Taslaklar", + "pages.status.listed": "Yayınlandı", + "pages.status.unlisted": "Liste Dışı", + + "pagination.page": "Sayfa", + + "password": "\u015eifre", + "paste": "Yapıştır", + "paste.after": "Sonrasına yapıştır", + "pixel": "Piksel", + "plugin": "Eklenti", + "plugins": "Eklentiler", + "prev": "Önceki", + "preview": "Önizle", + "remove": "Kaldır", + "rename": "Yeniden Adlandır", + "replace": "De\u011fi\u015ftir", + "retry": "Tekrar Dene", + "revert": "Vazge\u00e7", + "revert.confirm": "Gerçekten kaydedilmemiş tüm değişiklikleri silmek istiyor musunuz?", + + "role": "Rol", + "role.admin.description": "Yönetici tüm haklara sahiptir", + "role.admin.title": "Yönetici", + "role.all": "Tümü", + "role.empty": "Bu role ait kullanıcı bulunamadı", + "role.description.placeholder": "Açıklama yok", + "role.nobody.description": "Bu hiçbir izni olmayan bir geri dönüş rolüdür.", + "role.nobody.title": "Hiçkimse", + + "save": "Kaydet", + "search": "Arama", + "search.min": "Aramak için {min} karakter girin", + "search.all": "Tümünü göster", + "search.results.none": "Sonuç yok", + + "section.required": "Bölüm gereklidir", + + "security": "Güvenlik", + "select": "Seç", + "server": "Sunucu", + "settings": "Ayarlar", + "show": "Göster", + "site.blueprint": "Sitenin henüz bir planı yok. Kurulumu /site/blueprints/site.yml'de tanımlayabilirsiniz.", + "size": "Boyut", + "slug": "Web Adres Uzantısı", + "sort": "Sırala", + + "stats.empty": "Rapor yok", + "system.issues.content": "İçerik klasörü açığa çıkmış görünüyor", + "system.issues.eol.kirby": "Yüklü Kirby sürümünüz kullanım ömrünün sonuna ulaştı ve daha fazla güvenlik güncellemesi almayacak", + "system.issues.eol.plugin": "{ plugin } eklentisinin yüklü sürümü kullanım ömrünün sonuna ulaştı ve daha fazla güvenlik güncellemesi almayacak", + "system.issues.debug": "Canlı modda hata ayıklama kapatılmalıdır", + "system.issues.git": ".git klasörü açığa çıkmış görünüyor", + "system.issues.https": "Tüm siteleriniz için HTTPS'yi öneriyoruz", + "system.issues.kirby": "Kirby klasörü açığa çıkmış görünüyor", + "system.issues.site": "Site klasörü açığa çıkmış görünüyor", + "system.issues.vulnerability.kirby": "Kurulumunuz aşağıdaki güvenlik açığından ({ severity } önem derecesi) etkilenebilir: { description }", + "system.issues.vulnerability.plugin": "Kurulumunuz, { plugin } eklentisindeki ({ severity } önem derecesi) aşağıdaki güvenlik açığından etkilenebilir: { description }", + "system.updateStatus": "Güncelleme durumu", + "system.updateStatus.error": "Güncellemeler kontrol edilemedi", + "system.updateStatus.not-vulnerable": "Bilinen güvenlik açığı yok", + "system.updateStatus.security-update": "Ücretsiz güvenlik güncellemesi { version } mevcut", + "system.updateStatus.security-upgrade": "Mevcut güvenlik düzeltmeleriyle { version } sürümüne yükseltin", + "system.updateStatus.unreleased": "Yayınlanmamış sürüm", + "system.updateStatus.up-to-date": "Güncel", + "system.updateStatus.update": "Ücretsiz güncelleme { version } mevcut", + "system.updateStatus.upgrade": "{ version } yükseltme mevcut", + + "title": "Başlık", + "template": "\u015eablon", + "today": "Bugün", + + "toolbar.button.code": "Kod", + "toolbar.button.bold": "Kalın Yazı", + "toolbar.button.email": "E-Posta", + "toolbar.button.headings": "Başlıklar", + "toolbar.button.heading.1": "Başlık 1", + "toolbar.button.heading.2": "Başlık 2", + "toolbar.button.heading.3": "Başlık 3", + "toolbar.button.heading.4": "Başlık 4", + "toolbar.button.heading.5": "Başlık 5", + "toolbar.button.heading.6": "Başlık 6", + "toolbar.button.italic": "Eğik Yazı", + "toolbar.button.file": "Dosya", + "toolbar.button.file.select": "Bir dosya seçin", + "toolbar.button.file.upload": "Bir dosya yükleyin", + "toolbar.button.link": "Ba\u011flant\u0131", + "toolbar.button.paragraph": "Paragraf", + "toolbar.button.strike": "Üstü çizili", + "toolbar.button.ol": "Sıralı liste", + "toolbar.button.underline": "Altı çizili", + "toolbar.button.ul": "Madde listesi", + + "translation.author": "Kirby Takımı", + "translation.direction": "ltr", + "translation.name": "T\u00fcrk\u00e7e", + "translation.locale": "tr_TR", + + "upload": "Yükle", + "upload.error.cantMove": "Yüklenen dosya taşınamadı", + "upload.error.cantWrite": "Dosya diske yazılamadı", + "upload.error.default": "Dosya yüklenemedi", + "upload.error.extension": "Dosya yükleme uzantısı tarafından durduruldu", + "upload.error.formSize": "Yüklenen dosya, formda belirtilen MAX_FILE_SIZE yönergesini aşıyor", + "upload.error.iniPostSize": "Yüklenen dosya php.ini içindeki post_max_size yönergesini aşıyor", + "upload.error.iniSize": "Yüklenen dosya php.ini içindeki upload_max_filesize yönergesini aşıyor", + "upload.error.noFile": "Dosya yüklenmedi", + "upload.error.noFiles": "Dosyalar yüklenmedi", + "upload.error.partial": "Yüklenen dosya sadece kısmen yüklendi", + "upload.error.tmpDir": "Geçici klasör eksik", + "upload.errors": "Hata", + "upload.progress": "Yükleniyor...", + + "url": "Url", + "url.placeholder": "https://ornek.com", + + "user": "Kullanıcı", + "user.blueprint": "Bu kullanıcı rolü için /site/blueprints/users/{blueprint}.yml içinde ek bölümler ve form alanları tanımlayabilirsiniz", + "user.changeEmail": "E-postayı değiştir", + "user.changeLanguage": "Dili değiştir", + "user.changeName": "Kullanıcıyı yeniden adlandır", + "user.changePassword": "Şifre değiştir", + "user.changePassword.new": "Yeni Şifre", + "user.changePassword.new.confirm": "Şifreyi onaylayın...", + "user.changeRole": "Rolü değiştir", + "user.changeRole.select": "Yeni bir rol seçin", + "user.create": "Yeni bir kullanıcı ekle", + "user.delete": "Bu kullanıcıyı sil", + "user.delete.confirm": "{email} kullanıcısını silmek istediğinizden emin misiniz?", + + "users": "Kullanıcılar", + + "version": "Versiyon", + "version.current": "Mevcut sürüm", + "version.latest": "En son sürüm", + "versionInformation": "Sürüm bilgisi", + + "view.account": "Hesap Bilgilerin", + "view.installation": "Kurulum", + "view.languages": "Diller", + "view.resetPassword": "Şifreyi sıfırla", + "view.site": "Site", + "view.system": "Sistem", + "view.users": "Kullan\u0131c\u0131lar", + + "welcome": "Hoşgeldiniz", + "year": "Yıl", + "yes": "evet" } diff --git a/kirby/panel/dist/css/style.css b/kirby/panel/dist/css/style.css index a82b55c..512ebe1 100644 --- a/kirby/panel/dist/css/style.css +++ b/kirby/panel/dist/css/style.css @@ -1 +1 @@ -:root{--color-backdrop:rgba(0, 0, 0, .6);--color-black:#000;--color-dark:#313740;--color-light:var(--color-gray-200);--color-white:#fff;--color-gray-100:#f7f7f7;--color-gray-200:#efefef;--color-gray-300:#ddd;--color-gray-400:#ccc;--color-gray-500:#999;--color-gray-600:#777;--color-gray-700:#555;--color-gray-800:#333;--color-gray-900:#111;--color-gray:var(--color-gray-600);--color-red-200:#edc1c1;--color-red-300:#e3a0a0;--color-red-400:#d16464;--color-red-600:#c82829;--color-red:var(--color-red-600);--color-orange-200:#f2d4bf;--color-orange-300:#ebbe9e;--color-orange-400:#de935f;--color-orange-600:#f4861f;--color-orange:var(--color-orange-600);--color-yellow-200:#f9e8c7;--color-yellow-300:#f7e2b8;--color-yellow-400:#f0c674;--color-yellow-600:#cca000;--color-yellow:var(--color-yellow-600);--color-green-200:#dce5c2;--color-green-300:#c6d49d;--color-green-400:#a7bd68;--color-green-600:#5d800d;--color-green:var(--color-green-600);--color-aqua-200:#d0e5e2;--color-aqua-300:#bbd9d5;--color-aqua-400:#8abeb7;--color-aqua-600:#398e93;--color-aqua:var(--color-aqua-600);--color-blue-200:#cbd7e5;--color-blue-300:#b1c2d8;--color-blue-400:#7e9abf;--color-blue-600:#4271ae;--color-blue:var(--color-blue-600);--color-purple-200:#e0d4e4;--color-purple-300:#d4c3d9;--color-purple-400:#b294bb;--color-purple-600:#9c48b9;--color-purple:var(--color-purple-600);--container:80rem;--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--font-mono:"SFMono-Regular", Consolas, Liberation Mono, Menlo, Courier, monospace;--font-normal:400;--font-bold:600;--leading-none:1;--leading-tight:1.25;--leading-snug:1.375;--leading-normal:1.5;--leading-relaxed:1.625;--leading-loose:2;--rounded-xs:1px;--rounded-sm:.125rem;--rounded:.25rem;--rounded-md:.375rem;--shadow:0 1px 3px 0 rgba(0, 0, 0, .1), 0 1px 2px 0 rgba(0, 0, 0, .06);--shadow-md:0 4px 6px -1px rgba(0, 0, 0, .1), 0 2px 4px -1px rgba(0, 0, 0, .06);--shadow-lg:0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -2px rgba(0, 0, 0, .05);--shadow-xl:0 20px 25px -5px rgba(0, 0, 0, .1), 0 10px 10px -5px rgba(0, 0, 0, .04);--shadow-outline:currentColor 0 0 0 2px;--shadow-inset:inset 0 2px 4px 0 rgba(0, 0, 0, .06);--spacing-0:0;--spacing-px:1px;--spacing-2px:2px;--spacing-1:.25rem;--spacing-2:.5rem;--spacing-3:.75rem;--spacing-4:1rem;--spacing-5:1.25rem;--spacing-6:1.5rem;--spacing-8:2rem;--spacing-10:2.5rem;--spacing-12:3rem;--spacing-16:4rem;--spacing-20:5rem;--spacing-24:6rem;--spacing-36:9rem;--text-xs:.75rem;--text-sm:.875rem;--text-base:1rem;--text-lg:1.125rem;--text-xl:1.25rem;--text-2xl:1.5rem;--text-3xl:1.75rem;--text-4xl:2.5rem;--text-5xl:3rem;--text-6xl:4rem;--color-background:var(--color-light);--color-border:var(--color-gray-400);--color-focus:var(--color-blue-600);--color-focus-light:var(--color-blue-400);--color-focus-outline:rgba(113, 143, 183, .25);--color-negative:var(--color-red-600);--color-negative-light:var(--color-red-400);--color-negative-outline:rgba(212, 110, 110, .25);--color-notice:var(--color-orange-600);--color-notice-light:var(--color-orange-400);--color-positive:var(--color-green-600);--color-positive-light:var(--color-green-400);--color-positive-outline:rgba(128, 149, 65, .25);--color-text:var(--color-gray-900);--color-text-light:var(--color-gray-600);--z-offline:1200;--z-fatal:1100;--z-loader:1000;--z-notification:900;--z-dialog:800;--z-navigation:700;--z-dropdown:600;--z-drawer:500;--z-dropzone:400;--z-toolbar:300;--z-content:200;--z-background:100;--bg-pattern:repeating-conic-gradient( rgba(0, 0, 0, 0) 0% 25%, rgba(0, 0, 0, .2) 0% 50% ) 50% / 20px 20px;--shadow-sticky:rgba(0, 0, 0, .05) 0 2px 5px;--shadow-dropdown:var(--shadow-lg);--shadow-item:var(--shadow);--field-input-padding:.5rem;--field-input-height:2.25rem;--field-input-line-height:1.25rem;--field-input-font-size:var(--text-base);--field-input-color-before:var(--color-gray-700);--field-input-color-after:var(--color-gray-700);--field-input-border:1px solid var(--color-border);--field-input-focus-border:1px solid var(--color-focus);--field-input-focus-outline:2px solid var(--color-focus-outline);--field-input-invalid-border:1px solid var(--color-negative-outline);--field-input-invalid-outline:0;--field-input-invalid-focus-border:1px solid var(--color-negative);--field-input-invalid-focus-outline:2px solid var(--color-negative-outline);--field-input-background:var(--color-white);--field-input-disabled-color:var(--color-gray-500);--field-input-disabled-background:var(--color-white);--field-input-disabled-border:1px solid var(--color-gray-300);--font-family-sans:var(--font-sans);--font-family-mono:var(--font-mono);--font-size-tiny:var(--text-xs);--font-size-small:var(--text-sm);--font-size-medium:var(--text-base);--font-size-large:var(--text-xl);--font-size-huge:var(--text-2xl);--font-size-monster:var(--text-3xl);--box-shadow-dropdown:var(--shadow-dropdown);--box-shadow-item:var(--shadow);--box-shadow-focus:var(--shadow-xl)}*,:after,:before{margin:0;padding:0;box-sizing:border-box}noscript{padding:1.5rem;display:flex;align-items:center;justify-content:center;height:100vh;text-align:center}html{font-family:var(--font-sans);background:var(--color-background)}body,html{color:var(--color-gray-900);height:100%;overflow:hidden}a{color:inherit;text-decoration:none}li{list-style:none}b,strong{font-weight:var(--font-bold)}@keyframes LoadingCursor{to{cursor:progress}}@keyframes Spin{to{transform:rotate(360deg)}}.k-dialog{position:relative;background:var(--color-background);width:100%;box-shadow:var(--shadow-lg);border-radius:var(--rounded-md);line-height:1;max-height:calc(100vh - 3rem);margin:1.5rem;display:flex;flex-direction:column}@media screen and (min-width:20rem){.k-dialog[data-size=small]{width:20rem}}@media screen and (min-width:22rem){.k-dialog[data-size=default]{width:22rem}}@media screen and (min-width:30rem){.k-dialog[data-size=medium]{width:30rem}}@media screen and (min-width:40rem){.k-dialog[data-size=large]{width:40rem}}[dir=ltr] .k-dialog-notification,[dir=rtl] .k-dialog-notification{border-top-right-radius:var(--rounded);border-top-left-radius:var(--rounded)}.k-dialog-notification{padding:.75rem 1.5rem;background:var(--color-gray-900);width:100%;margin-top:-1px;line-height:1.25rem;color:var(--color-white);display:flex;flex-shrink:0;align-items:center}.k-dialog-notification[data-theme]{background:var(--theme-light);color:var(--color-black)}.k-dialog-notification p{flex-grow:1;word-wrap:break-word;overflow:hidden}[dir=ltr] .k-dialog-notification .k-button{margin-left:1rem}[dir=rtl] .k-dialog-notification .k-button{margin-right:1rem}.k-dialog-notification .k-button{display:flex}.k-dialog-body{padding:1.5rem}.k-dialog-body .k-fieldset{padding-bottom:.5rem}.k-dialog-footer{padding:0;border-top:1px solid var(--color-gray-300);line-height:1;flex-shrink:0}.k-dialog-footer .k-button-group{display:flex;margin:0;justify-content:space-between}.k-dialog-footer .k-button-group .k-button{padding:.75rem 1rem;line-height:1.25rem}[dir=ltr] .k-dialog-footer .k-button-group .k-button:first-child{text-align:left}[dir=rtl] .k-dialog-footer .k-button-group .k-button:first-child{text-align:right}[dir=ltr] .k-dialog-footer .k-button-group .k-button:first-child{padding-left:1.5rem}[dir=rtl] .k-dialog-footer .k-button-group .k-button:first-child{padding-right:1.5rem}[dir=ltr] .k-dialog-footer .k-button-group .k-button:last-child{text-align:right}[dir=rtl] .k-dialog-footer .k-button-group .k-button:last-child{text-align:left}[dir=ltr] .k-dialog-footer .k-button-group .k-button:last-child{padding-right:1.5rem}[dir=rtl] .k-dialog-footer .k-button-group .k-button:last-child{padding-left:1.5rem}.k-dialog .k-pagination{margin-bottom:-1.5rem;display:flex;justify-content:center;align-items:center}.k-dialog-search{margin-bottom:.75rem}.k-dialog-search.k-input{background:rgba(0,0,0,.075);padding:0 1rem;height:36px;border-radius:var(--rounded)}.k-error-details{background:var(--color-white);display:block;overflow:auto;padding:1rem;font-size:var(--text-sm);line-height:1.25em;margin-top:.75rem}.k-error-details dt{color:var(--color-negative-light);margin-bottom:.25rem}.k-error-details dd{overflow:hidden;overflow-wrap:break-word;text-overflow:ellipsis}.k-error-details dd:not(:last-of-type){margin-bottom:1.5em}.k-error-details li:not(:last-child){border-bottom:1px solid var(--color-background);padding-bottom:.25rem;margin-bottom:.25rem}.k-files-dialog .k-list-item{cursor:pointer}[dir=ltr] .k-pages-dialog-navbar{padding-right:38px}[dir=rtl] .k-pages-dialog-navbar{padding-left:38px}.k-pages-dialog-navbar{display:flex;align-items:center;justify-content:center;margin-bottom:.5rem}.k-pages-dialog-navbar .k-button{width:38px}.k-pages-dialog-navbar .k-button[disabled]{opacity:0}.k-pages-dialog-navbar .k-headline{flex-grow:1;text-align:center}.k-pages-dialog .k-list-item{cursor:pointer}.k-pages-dialog .k-list-item .k-button[data-theme=disabled],.k-pages-dialog .k-list-item .k-button[disabled]{opacity:.25}.k-pages-dialog .k-list-item .k-button[data-theme=disabled]:hover{opacity:1}.k-users-dialog .k-list-item{cursor:pointer}.k-drawer{--drawer-header-height:2.5rem;--drawer-header-padding:1.5rem;position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--z-toolbar);display:flex;align-items:stretch;justify-content:flex-end;background:rgba(0,0,0,.2)}.k-drawer-box{position:relative;flex-basis:50rem;display:flex;flex-direction:column;background:var(--color-background);box-shadow:var(--shadow-xl)}[dir=ltr] .k-drawer-header{padding-left:var(--drawer-header-padding)}[dir=rtl] .k-drawer-header{padding-right:var(--drawer-header-padding)}.k-drawer-header{flex-shrink:0;height:var(--drawer-header-height);display:flex;align-items:center;line-height:1;justify-content:space-between;background:var(--color-white);font-size:var(--text-sm)}.k-drawer-title{padding:0 .75rem}[dir=ltr] .k-drawer-breadcrumb,[dir=ltr] .k-drawer-title{margin-left:-.75rem}[dir=rtl] .k-drawer-breadcrumb,[dir=rtl] .k-drawer-title{margin-right:-.75rem}.k-drawer-breadcrumb,.k-drawer-title{display:flex;flex-grow:1;align-items:center;min-width:0;font-size:var(--text-sm);font-weight:var(--font-normal)}[dir=ltr] .k-drawer-breadcrumb li:not(:last-child) .k-button:after{right:-.75rem}[dir=rtl] .k-drawer-breadcrumb li:not(:last-child) .k-button:after{left:-.75rem}.k-drawer-breadcrumb li:not(:last-child) .k-button:after{position:absolute;width:1.5rem;display:inline-flex;justify-content:center;align-items:center;content:"\203a";color:var(--color-gray-500);height:var(--drawer-header-height)}[dir=ltr] .k-drawer-breadcrumb .k-icon,[dir=ltr] .k-drawer-title .k-icon{margin-right:.5rem}[dir=rtl] .k-drawer-breadcrumb .k-icon,[dir=rtl] .k-drawer-title .k-icon{margin-left:.5rem}.k-drawer-breadcrumb .k-icon,.k-drawer-title .k-icon{width:1rem;color:var(--color-gray-500)}.k-drawer-breadcrumb .k-button{display:inline-flex;align-items:center;height:var(--drawer-header-height);padding-left:.75rem;padding-right:.75rem}.k-drawer-breadcrumb .k-button-text{opacity:1}[dir=ltr] .k-drawer-breadcrumb .k-button .k-button-icon~.k-button-text{padding-left:0}[dir=rtl] .k-drawer-breadcrumb .k-button .k-button-icon~.k-button-text{padding-right:0}[dir=ltr] .k-drawer-tabs{margin-right:.75rem}[dir=rtl] .k-drawer-tabs{margin-left:.75rem}.k-drawer-tabs{display:flex;align-items:center;line-height:1}.k-drawer-tab.k-button{height:var(--drawer-header-height);padding-left:.75rem;padding-right:.75rem;display:flex;align-items:center;font-size:var(--text-xs)}.k-drawer-tab.k-button[aria-current]:after{position:absolute;bottom:-1px;left:.75rem;right:.75rem;content:"";background:var(--color-black);height:2px}[dir=ltr] .k-drawer-options{padding-right:.75rem}[dir=rtl] .k-drawer-options{padding-left:.75rem}.k-drawer-option.k-button{width:var(--drawer-header-height);height:var(--drawer-header-height);color:var(--color-gray-500);line-height:1}.k-drawer-option.k-button:focus,.k-drawer-option.k-button:hover{color:var(--color-black)}.k-drawer-body{padding:1.5rem;flex-grow:1;background:var(--color-background)}.k-drawer[data-nested=true]{background:0 0}.k-drawer-body .k-table th,.k-drawer-body .k-textarea-input:focus-within .k-toolbar{top:-1.5rem}.k-calendar-input{--cell-padding:.25rem .5rem;padding:.5rem;color:var(--color-light);border-radius:var(--rounded-xs)}.k-calendar-table{table-layout:fixed;width:100%;min-width:15rem;padding-top:.5rem}.k-calendar-input>nav{display:flex;direction:ltr}.k-calendar-input>nav .k-button{padding:.5rem}.k-calendar-selects{flex-grow:1;display:flex;align-items:center;justify-content:center}[dir=ltr] .k-calendar-selects{direction:ltr}[dir=rtl] .k-calendar-selects{direction:rtl}.k-calendar-selects .k-select-input{padding:0 .5rem;font-weight:var(--font-normal);font-size:var(--text-sm)}.k-calendar-selects .k-select-input:focus-within{color:var(--color-focus-light)!important}.k-calendar-input th{padding:.5rem 0;color:var(--color-gray-500);font-size:var(--text-xs);font-weight:400;text-align:center}.k-calendar-day .k-button{width:2rem;height:2rem;margin-left:auto;margin-right:auto;color:var(--color-white);line-height:1.75rem;display:flex;justify-content:center;border-radius:50%;border:2px solid transparent}.k-calendar-day .k-button .k-button-text{opacity:1}.k-calendar-table .k-button:hover{color:var(--color-white)}.k-calendar-day:hover .k-button:not([data-disabled=true]){border-color:#ffffff40}.k-calendar-day[aria-current=date] .k-button{text-decoration:underline}.k-calendar-day[aria-selected=date] .k-button{border-color:currentColor;font-weight:600;color:var(--color-focus-light)}.k-calendar-today{text-align:center;padding-top:.5rem}.k-calendar-today .k-button{font-size:var(--text-xs);padding:1rem;text-decoration:underline}.k-calendar-today .k-button-text{opacity:1;vertical-align:baseline}.k-counter{font-size:var(--text-xs);color:var(--color-gray-900);font-weight:var(--font-bold)}.k-counter[data-invalid=true]{box-shadow:none;border:0;color:var(--color-negative)}[dir=ltr] .k-counter-rules{padding-left:.5rem}[dir=rtl] .k-counter-rules{padding-right:.5rem}.k-counter-rules{color:var(--color-gray-600);font-weight:var(--font-normal)}.k-form-submitter{display:none}.k-form-buttons[data-theme]{background:var(--theme-light)}.k-form-buttons .k-view{display:flex;justify-content:space-between;align-items:center}.k-form-button.k-button{font-weight:500;white-space:nowrap;line-height:1;height:2.5rem;display:flex;padding:0 1rem;align-items:center}[dir=ltr] .k-form-button:first-child{margin-left:-1rem}[dir=rtl] .k-form-button:first-child{margin-right:-1rem}[dir=ltr] .k-form-button:last-child{margin-right:-1rem}[dir=rtl] .k-form-button:last-child{margin-left:-1rem}[dir=ltr] .k-form-lock-info{margin-right:3rem}[dir=rtl] .k-form-lock-info{margin-left:3rem}.k-form-lock-info{display:flex;font-size:var(--text-sm);align-items:center;line-height:1.5em;padding:.625rem 0}[dir=ltr] .k-form-lock-info>.k-icon{margin-right:.5rem}[dir=rtl] .k-form-lock-info>.k-icon{margin-left:.5rem}.k-form-lock-buttons{display:flex;flex-shrink:0}.k-form-lock-loader{animation:Spin 4s linear infinite}.k-form-lock-loader .k-icon-loader{display:flex}.k-form-indicator-toggle{color:var(--color-notice-light)}.k-form-indicator-info{font-size:var(--text-sm);font-weight:var(--font-bold);padding:.75rem 1rem .25rem;line-height:1.25em;width:15rem}.k-field-label{font-weight:var(--font-bold);display:block;padding:0 0 .75rem;flex-grow:1;line-height:1.25rem}[dir=ltr] .k-field-label abbr{padding-left:.25rem}[dir=rtl] .k-field-label abbr{padding-right:.25rem}.k-field-label abbr{text-decoration:none;color:var(--color-gray-500)}.k-field-header{position:relative;display:flex;align-items:baseline}[dir=ltr] .k-field-options{right:0}[dir=rtl] .k-field-options{left:0}.k-field-options{position:absolute;top:calc(-.5rem - 1px)}.k-field-options.k-button-group .k-dropdown{height:auto}.k-field-options.k-button-group .k-field-options-button.k-button{padding:.75rem;display:flex}.k-field[data-disabled=true]{cursor:not-allowed}.k-field[data-disabled=true] *{pointer-events:none}.k-field[data-disabled=true] .k-text[data-theme=help] *{pointer-events:initial}.k-field:focus-within>.k-field-header>.k-field-counter{display:block}.k-field-help{padding-top:.5rem}.k-fieldset{border:0}.k-fieldset .k-grid{grid-row-gap:2.25rem}@media screen and (min-width:30em){.k-fieldset .k-grid{grid-column-gap:1.5rem}}.k-sections>.k-column[data-width="1/3"] .k-fieldset .k-grid,.k-sections>.k-column[data-width="1/4"] .k-fieldset .k-grid{grid-template-columns:repeat(1,1fr)}.k-sections>.k-column[data-width="1/3"] .k-fieldset .k-grid .k-column,.k-sections>.k-column[data-width="1/4"] .k-fieldset .k-grid .k-column{grid-column-start:initial}.k-input{display:flex;align-items:center;line-height:1;border:0;outline:0;background:0 0}.k-input-element{flex-grow:1}.k-input-icon{display:flex;justify-content:center;align-items:center;line-height:0}.k-input[data-disabled=true]{pointer-events:none}[data-disabled=true] .k-input-icon{color:var(--color-gray-600)}.k-input[data-theme=field]{line-height:1;border:var(--field-input-border);background:var(--field-input-background);border-radius:var(--rounded)}.k-input[data-theme=field]:focus-within{border:var(--field-input-focus-border);box-shadow:var(--color-focus-outline) 0 0 0 2px}.k-input[data-theme=field][data-disabled=true]{background:var(--color-background)}.k-input[data-theme=field] .k-input-icon{width:var(--field-input-height);align-self:stretch;display:flex;align-items:center;flex-shrink:0}.k-input[data-theme=field] .k-input-after,.k-input[data-theme=field] .k-input-before{align-self:stretch;display:flex;align-items:center;flex-shrink:0;padding:0 var(--field-input-padding)}[dir=ltr] .k-input[data-theme=field] .k-input-before{padding-right:0}[dir=ltr] .k-input[data-theme=field] .k-input-after,[dir=rtl] .k-input[data-theme=field] .k-input-before{padding-left:0}.k-input[data-theme=field] .k-input-before{color:var(--field-input-color-before)}[dir=rtl] .k-input[data-theme=field] .k-input-after{padding-right:0}.k-input[data-theme=field] .k-input-after{color:var(--field-input-color-after)}.k-input[data-theme=field] .k-input-icon>.k-dropdown{width:100%;height:100%}.k-input[data-theme=field] .k-input-icon-button{width:100%;height:100%;display:flex;align-items:center;justify-content:center;flex-shrink:0}.k-input[data-theme=field] .k-number-input,.k-input[data-theme=field] .k-select-input,.k-input[data-theme=field] .k-text-input{padding:var(--field-input-padding);line-height:var(--field-input-line-height)}.k-input[data-theme=field] .k-date-input .k-select-input,.k-input[data-theme=field] .k-time-input .k-select-input{padding-left:0;padding-right:0}[dir=ltr] .k-input[data-theme=field] .k-date-input .k-select-input:first-child,[dir=ltr] .k-input[data-theme=field] .k-time-input .k-select-input:first-child{padding-left:var(--field-input-padding)}[dir=rtl] .k-input[data-theme=field] .k-date-input .k-select-input:first-child,[dir=rtl] .k-input[data-theme=field] .k-time-input .k-select-input:first-child{padding-right:var(--field-input-padding)}.k-input[data-theme=field] .k-date-input .k-select-input:focus-within,.k-input[data-theme=field] .k-time-input .k-select-input:focus-within{color:var(--color-focus);font-weight:var(--font-bold)}[dir=ltr] .k-input[data-theme=field].k-time-input .k-time-input-meridiem{padding-left:var(--field-input-padding)}[dir=rtl] .k-input[data-theme=field].k-time-input .k-time-input-meridiem{padding-right:var(--field-input-padding)}.k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input li,.k-input[data-theme=field][data-type=checkboxes] .k-radio-input li,.k-input[data-theme=field][data-type=radio] .k-checkboxes-input li,.k-input[data-theme=field][data-type=radio] .k-radio-input li{min-width:0;overflow-wrap:break-word}[dir=ltr] .k-input[data-theme=field][data-type=checkboxes] .k-input-before{border-right:1px solid var(--color-background)}[dir=ltr] .k-input[data-theme=field][data-type=checkboxes] .k-input-element+.k-input-after,[dir=ltr] .k-input[data-theme=field][data-type=checkboxes] .k-input-element+.k-input-icon,[dir=rtl] .k-input[data-theme=field][data-type=checkboxes] .k-input-before{border-left:1px solid var(--color-background)}[dir=ltr] .k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input li,[dir=rtl] .k-input[data-theme=field][data-type=checkboxes] .k-input-element+.k-input-after,[dir=rtl] .k-input[data-theme=field][data-type=checkboxes] .k-input-element+.k-input-icon{border-right:1px solid var(--color-background)}.k-input[data-theme=field][data-type=checkboxes] .k-input-element{overflow:hidden}[dir=ltr] .k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input{margin-right:-1px}[dir=rtl] .k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input{margin-left:-1px}.k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input{display:grid;grid-template-columns:1fr;margin-bottom:-1px}@media screen and (min-width:65em){.k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input{grid-template-columns:repeat(var(--columns),1fr)}}[dir=rtl] .k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input li{border-left:1px solid var(--color-background)}.k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input li,.k-input[data-theme=field][data-type=radio] .k-radio-input li{border-bottom:1px solid var(--color-background)}.k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input label{display:block;line-height:var(--field-input-line-height);padding:var(--field-input-padding) var(--field-input-padding)}[dir=ltr] .k-input[data-theme=field][data-type=checkboxes] .k-checkbox-input-icon,[dir=ltr] .k-input[data-theme=field][data-type=radio] .k-radio-input label:before{left:var(--field-input-padding)}[dir=rtl] .k-input[data-theme=field][data-type=checkboxes] .k-checkbox-input-icon,[dir=rtl] .k-input[data-theme=field][data-type=radio] .k-radio-input label:before{right:var(--field-input-padding)}.k-input[data-theme=field][data-type=checkboxes] .k-checkbox-input-icon{top:calc((var(--field-input-height) - var(--field-input-font-size))/2);margin-top:0}[dir=ltr] .k-input[data-theme=field][data-type=radio] .k-input-before{border-right:1px solid var(--color-background)}[dir=ltr] .k-input[data-theme=field][data-type=radio] .k-input-element+.k-input-after,[dir=ltr] .k-input[data-theme=field][data-type=radio] .k-input-element+.k-input-icon,[dir=rtl] .k-input[data-theme=field][data-type=radio] .k-input-before{border-left:1px solid var(--color-background)}[dir=ltr] .k-input[data-theme=field][data-type=radio] .k-radio-input li,[dir=rtl] .k-input[data-theme=field][data-type=radio] .k-input-element+.k-input-after,[dir=rtl] .k-input[data-theme=field][data-type=radio] .k-input-element+.k-input-icon{border-right:1px solid var(--color-background)}.k-input[data-theme=field][data-type=radio] .k-input-element{overflow:hidden}[dir=ltr] .k-input[data-theme=field][data-type=radio] .k-radio-input{margin-right:-1px}[dir=rtl] .k-input[data-theme=field][data-type=radio] .k-radio-input{margin-left:-1px}.k-input[data-theme=field][data-type=radio] .k-radio-input{display:grid;grid-template-columns:1fr;margin-bottom:-1px}@media screen and (min-width:65em){.k-input[data-theme=field][data-type=radio] .k-radio-input{grid-template-columns:repeat(var(--columns),1fr)}}[dir=rtl] .k-input[data-theme=field][data-type=radio] .k-radio-input li{border-left:1px solid var(--color-background)}.k-input[data-theme=field][data-type=radio] .k-radio-input label{display:block;flex-grow:1;min-height:var(--field-input-height);line-height:var(--field-input-line-height);padding:calc((var(--field-input-height) - var(--field-input-line-height))/2) var(--field-input-padding)}.k-input[data-theme=field][data-type=radio] .k-radio-input label:before{top:calc((var(--field-input-height) - 1rem)/2);margin-top:-1px}.k-input[data-theme=field][data-type=radio] .k-radio-input .k-radio-input-info{display:block;font-size:var(--text-sm);color:var(--color-gray-600);line-height:var(--field-input-line-height);padding-top:calc(var(--field-input-line-height)/10)}.k-input[data-theme=field][data-type=radio] .k-radio-input .k-icon{width:var(--field-input-height);height:var(--field-input-height);display:flex;align-items:center;justify-content:center}.k-input[data-theme=field][data-type=range] .k-range-input{padding:var(--field-input-padding)}.k-input[data-theme=field][data-type=multiselect],.k-input[data-theme=field][data-type=select]{position:relative}[dir=ltr] .k-input[data-theme=field][data-type=select] .k-input-icon{right:0}[dir=rtl] .k-input[data-theme=field][data-type=select] .k-input-icon{left:0}.k-input[data-theme=field][data-type=select] .k-input-icon{position:absolute;top:0;bottom:0}.k-input[data-theme=field][data-type=tags] .k-tags-input{padding:.25rem .25rem 0}[dir=ltr] .k-input[data-theme=field][data-type=tags] .k-tag{margin-right:.25rem}[dir=rtl] .k-input[data-theme=field][data-type=tags] .k-tag{margin-left:.25rem}.k-input[data-theme=field][data-type=tags] .k-tag{margin-bottom:.25rem;height:auto;min-height:1.75rem;font-size:var(--text-sm)}.k-input[data-theme=field][data-type=tags] .k-tags-input input{font-size:var(--text-sm);padding:0 .25rem;height:1.75rem;line-height:1;margin-bottom:.25rem}.k-input[data-theme=field][data-type=tags] .k-tags-input .k-dropdown-content{top:calc(100% + .5rem + 2px)}.k-input[data-theme=field][data-type=tags] .k-tags-input .k-dropdown-content[data-dropup]{top:calc(100% + .5rem + 2px);bottom:initial;margin-bottom:initial}.k-input[data-theme=field][data-type=multiselect] .k-multiselect-input{padding:.25rem 2rem 0 .25rem;min-height:2.25rem}[dir=ltr] .k-input[data-theme=field][data-type=multiselect] .k-tag{margin-right:.25rem}[dir=rtl] .k-input[data-theme=field][data-type=multiselect] .k-tag{margin-left:.25rem}.k-input[data-theme=field][data-type=multiselect] .k-tag{margin-bottom:.25rem;height:1.75rem;font-size:var(--text-sm)}[dir=ltr] .k-input[data-theme=field][data-type=multiselect] .k-input-icon{right:0}[dir=rtl] .k-input[data-theme=field][data-type=multiselect] .k-input-icon{left:0}.k-input[data-theme=field][data-type=multiselect] .k-input-icon{position:absolute;top:0;bottom:0;pointer-events:none}.k-input[data-theme=field][data-type=textarea] .k-textarea-input-native{padding:.25rem var(--field-input-padding);line-height:1.5rem}[dir=ltr] .k-input[data-theme=field][data-type=toggle] .k-input-before{padding-right:calc(var(--field-input-padding)/2)}[dir=rtl] .k-input[data-theme=field][data-type=toggle] .k-input-before{padding-left:calc(var(--field-input-padding)/2)}[dir=ltr] .k-input[data-theme=field][data-type=toggle] .k-toggle-input{padding-left:var(--field-input-padding)}[dir=rtl] .k-input[data-theme=field][data-type=toggle] .k-toggle-input{padding-right:var(--field-input-padding)}.k-input[data-theme=field][data-type=toggle] .k-toggle-input-label{padding:0 var(--field-input-padding)0 .75rem;line-height:var(--field-input-height)}.k-login-code-form .k-user-info{height:38px;margin-bottom:2.25rem;padding:.5rem;background:var(--color-white);border-radius:var(--rounded-xs);box-shadow:var(--shadow)}.k-times{padding:var(--spacing-4) var(--spacing-6);display:grid;line-height:1;grid-template-columns:1fr 1fr;grid-gap:var(--spacing-6)}.k-times .k-icon{width:1rem;margin-bottom:var(--spacing-2)}.k-times-slot .k-button{padding:var(--spacing-1) var(--spacing-3) var(--spacing-1)0;font-variant-numeric:tabular-nums;white-space:nowrap}.k-times .k-times-slot hr{position:relative;opacity:1;margin:var(--spacing-2)0;border:0;height:1px;top:1px;background:var(--color-dark)}[dir=ltr] .k-upload input{left:-3000px}[dir=rtl] .k-upload input{right:-3000px}.k-upload input{position:absolute;top:0}.k-upload-dialog .k-headline{margin-bottom:.75rem}.k-upload-error-list,.k-upload-list{line-height:1.5em;font-size:var(--text-sm)}.k-upload-list-filename{color:var(--color-gray-600)}.k-upload-error-list li{padding:.75rem;background:var(--color-white);border-radius:var(--rounded-xs)}.k-upload-error-list li:not(:last-child){margin-bottom:2px}.k-upload-error-filename{color:var(--color-negative);font-weight:var(--font-bold)}.k-upload-error-message{color:var(--color-gray-600)}.k-writer-toolbar{position:absolute;display:flex;background:var(--color-black);height:30px;transform:translate(-50%) translateY(-.75rem);z-index:calc(var(--z-dropdown) + 1);box-shadow:var(--shadow);color:var(--color-white);border-radius:var(--rounded)}.k-writer-toolbar-button.k-button{display:flex;align-items:center;justify-content:center;height:30px;width:30px;font-size:var(--text-sm)!important;color:currentColor;line-height:1}.k-writer-toolbar-button.k-button:hover{background:rgba(255,255,255,.15)}.k-writer-toolbar-button.k-writer-toolbar-button-active{color:var(--color-blue-300)}.k-writer-toolbar-button.k-writer-toolbar-nodes{width:auto;padding:0 .75rem}[dir=ltr] .k-writer-toolbar .k-dropdown+.k-writer-toolbar-button{border-left:1px solid var(--color-gray-700)}[dir=rtl] .k-writer-toolbar .k-dropdown+.k-writer-toolbar-button{border-right:1px solid var(--color-gray-700)}[dir=ltr] .k-writer-toolbar-button.k-writer-toolbar-nodes:after{margin-left:.5rem}[dir=rtl] .k-writer-toolbar-button.k-writer-toolbar-nodes:after{margin-right:.5rem}.k-writer-toolbar-button.k-writer-toolbar-nodes:after{content:"";border-top:4px solid var(--color-white);border-left:4px solid transparent;border-right:4px solid transparent}.k-writer-toolbar .k-dropdown-content{color:var(--color-black);background:var(--color-white);margin-top:.5rem}.k-writer-toolbar .k-dropdown-content .k-dropdown-item[aria-current]{color:var(--color-focus);font-weight:500}.k-writer{position:relative;width:100%;grid-template-areas:"content";display:grid}.k-writer .ProseMirror{overflow-wrap:break-word;word-wrap:break-word;word-break:break-word;white-space:pre-wrap;font-variant-ligatures:none;line-height:inherit;grid-area:content}.k-writer .ProseMirror:focus{outline:0}.k-writer .ProseMirror *{caret-color:currentColor}.k-writer .ProseMirror a{color:var(--color-focus);text-decoration:underline}.k-writer .ProseMirror>:last-child{margin-bottom:0}.k-writer .ProseMirror h1,.k-writer .ProseMirror h2,.k-writer .ProseMirror h3,.k-writer .ProseMirror ol,.k-writer .ProseMirror p,.k-writer .ProseMirror ul{margin-bottom:.75rem}.k-writer .ProseMirror h1{font-size:var(--text-3xl);line-height:1.25em}.k-writer .ProseMirror h2{font-size:var(--text-2xl);line-height:1.25em}.k-writer .ProseMirror h3{font-size:var(--text-xl);line-height:1.25em}.k-writer .ProseMirror h1 strong,.k-writer .ProseMirror h2 strong,.k-writer .ProseMirror h3 strong{font-weight:700}.k-writer .ProseMirror strong{font-weight:600}.k-writer .ProseMirror code{position:relative;font-size:.925em;display:inline-block;line-height:1.325;padding:.05em .325em;background:var(--color-gray-300);border-radius:var(--rounded)}[dir=ltr] .k-writer .ProseMirror ol,[dir=ltr] .k-writer .ProseMirror ul{padding-left:1.75rem}[dir=rtl] .k-writer .ProseMirror ol,[dir=rtl] .k-writer .ProseMirror ul{padding-right:1.75rem}.k-writer .ProseMirror ul>li{list-style:disc}.k-writer .ProseMirror ul ul>li{list-style:circle}.k-writer .ProseMirror ul ul ul>li{list-style:square}.k-writer .ProseMirror ol>li{list-style:decimal}.k-writer .ProseMirror li>ol,.k-writer .ProseMirror li>p,.k-writer .ProseMirror li>ul{margin:0}.k-writer-code pre{-moz-tab-size:2;-o-tab-size:2;tab-size:2;font-size:var(--text-sm);line-height:2em;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;white-space:pre}.k-writer .ProseMirror code,.k-writer-code code{font-family:var(--font-mono)}.k-writer[data-placeholder][data-empty=true]:before{grid-area:content;content:attr(data-placeholder);line-height:inherit;color:var(--color-gray-500);pointer-events:none;white-space:pre-wrap;word-wrap:break-word}.k-login-alert{padding:.5rem .75rem;display:flex;justify-content:space-between;align-items:center;min-height:38px;margin-bottom:2rem;background:var(--color-negative);color:var(--color-white);font-size:var(--text-sm);border-radius:var(--rounded-xs);box-shadow:var(--shadow-lg);cursor:pointer}.k-structure-backdrop{position:absolute;top:0;right:0;bottom:0;left:0;z-index:2;height:100vh}.k-structure-form section{position:relative;z-index:3;border-radius:var(--rounded-xs);margin-bottom:1px;box-shadow:#1111110d 0 0 0 3px;border:1px solid var(--color-border);background:var(--color-background)}.k-structure-form-fields{padding:1.5rem 1.5rem 2rem}.k-structure-form-buttons{border-top:1px solid var(--color-border);display:flex;justify-content:space-between}.k-structure-form-buttons .k-pagination{display:none}@media screen and (min-width:65em){.k-structure-form-buttons .k-pagination{display:flex}}.k-structure-form-buttons .k-pagination>.k-button,.k-structure-form-buttons .k-pagination>span{padding:.875rem 1rem!important}.k-structure-form-cancel-button,.k-structure-form-submit-button{padding:.875rem 1.5rem;line-height:1rem;display:flex}[dir=ltr] .k-toolbar,[dir=rtl] .k-toolbar{border-top-right-radius:var(--rounded);border-top-left-radius:var(--rounded)}.k-toolbar{background:var(--color-white);border-bottom:1px solid var(--color-background);height:38px}.k-toolbar-wrapper{position:absolute;top:0;left:0;right:0;max-width:100%}.k-toolbar-buttons{display:flex}.k-toolbar-divider{width:1px;background:var(--color-background)}.k-toolbar-button{width:36px;height:36px}.k-toolbar-button:hover{background:rgba(239,239,239,.5)}.k-checkbox-input{position:relative;cursor:pointer}[dir=ltr] .k-checkbox-input-label{padding-left:1.75rem}[dir=rtl] .k-checkbox-input-label{padding-right:1.75rem}.k-checkbox-input-label{display:block}[dir=ltr] .k-checkbox-input-icon{left:0}[dir=rtl] .k-checkbox-input-icon{right:0}.k-checkbox-input-icon{position:absolute;width:1rem;height:1rem;border-radius:var(--rounded);border:2px solid var(--color-gray-500)}.k-checkbox-input-icon svg{position:absolute;width:12px;height:12px;display:none}.k-checkbox-input-icon path{stroke:var(--color-white)}.k-checkbox-input-native:checked+.k-checkbox-input-icon{border-color:var(--color-gray-900);background:var(--color-gray-900)}[data-disabled=true] .k-checkbox-input-native:checked+.k-checkbox-input-icon{border-color:var(--color-gray-600);background:var(--color-gray-600)}.k-checkbox-input-native:checked+.k-checkbox-input-icon svg{display:block}.k-checkbox-input-native:focus+.k-checkbox-input-icon{border-color:var(--color-blue-600)}.k-checkbox-input-native:focus:checked+.k-checkbox-input-icon{background:var(--color-focus)}.k-text-input{width:100%;border:0;background:0 0;font:inherit;color:inherit;font-variant-numeric:tabular-nums}.k-text-input::-moz-placeholder{color:var(--color-gray-500)}.k-text-input::placeholder{color:var(--color-gray-500)}.k-text-input:focus{outline:0}.k-text-input:invalid{box-shadow:none;outline:0}.k-list-input .ProseMirror{line-height:1.5em}.k-list-input .ProseMirror ol>li::marker{font-size:var(--text-sm);color:var(--color-gray-500)}.k-multiselect-input{display:flex;flex-wrap:wrap;position:relative;font-size:var(--text-sm);min-height:2.25rem;line-height:1}.k-multiselect-input .k-sortable-ghost{background:var(--color-focus)}.k-multiselect-input .k-tag{border-radius:var(--rounded-sm)}.k-multiselect-input .k-dropdown-content,.k-multiselect-input[data-layout=list] .k-tag{width:100%}.k-multiselect-search{margin-top:0!important;color:var(--color-white);background:var(--color-gray-900);border-bottom:1px dashed rgba(255,255,255,.2)}.k-multiselect-search>.k-button-text{flex:1;opacity:1!important}.k-multiselect-search input{width:100%;color:var(--color-white);background:0 0;border:0;outline:0;padding:.25rem 0;font:inherit}.k-multiselect-options{position:relative;max-height:275px;padding:.5rem 0}.k-multiselect-option{position:relative}.k-multiselect-option.selected{color:var(--color-positive-light)}.k-multiselect-option.disabled:not(.selected) .k-icon{opacity:0}.k-multiselect-option b{color:var(--color-focus-light);font-weight:700}[dir=ltr] .k-multiselect-value{margin-left:.25rem}[dir=rtl] .k-multiselect-value{margin-right:.25rem}.k-multiselect-value{color:var(--color-gray-500)}.k-multiselect-value:before{content:" ("}.k-multiselect-value:after{content:")"}[dir=ltr] .k-multiselect-input[data-layout=list] .k-tag{margin-right:0!important}[dir=rtl] .k-multiselect-input[data-layout=list] .k-tag{margin-left:0!important}.k-multiselect-more{width:100%;padding:.75rem;color:#fffc;text-align:center;border-top:1px dashed rgba(255,255,255,.2)}.k-multiselect-more:hover{color:var(--color-white)}.k-number-input{width:100%;border:0;background:0 0;font:inherit;color:inherit}.k-number-input::-moz-placeholder{color:var(--color-gray-500)}.k-number-input::placeholder{color:var(--color-gray-500)}.k-number-input:focus{outline:0}.k-number-input:invalid{box-shadow:none;outline:0}[dir=ltr] .k-radio-input li{padding-left:1.75rem}[dir=rtl] .k-radio-input li{padding-right:1.75rem}.k-radio-input li{position:relative;line-height:1.5rem}.k-radio-input input{position:absolute;width:0;height:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;opacity:0}.k-radio-input label{cursor:pointer;align-items:center}[dir=ltr] .k-radio-input label:before{left:0}[dir=rtl] .k-radio-input label:before{right:0}.k-radio-input label:before{position:absolute;top:.175em;content:"";width:1rem;height:1rem;border-radius:50%;border:2px solid var(--color-gray-500);box-shadow:var(--color-white) 0 0 0 2px inset}.k-radio-input input:checked+label:before{border-color:var(--color-gray-900);background:var(--color-gray-900)}[data-disabled=true] .k-radio-input input:checked+label:before{border-color:var(--color-gray-600);background:var(--color-gray-600)}.k-radio-input input:focus+label:before{border-color:var(--color-blue-600)}.k-radio-input input:focus:checked+label:before{background:var(--color-focus)}.k-radio-input-text{display:block}.k-range-input{--range-thumb-size:16px;--range-thumb-border:4px solid var(--color-gray-900);--range-thumb-border-disabled:4px solid var(--color-gray-600);--range-thumb-background:var(--color-background);--range-thumb-focus-border:4px solid var(--color-focus);--range-thumb-focus-background:var(--color-background);--range-track-height:4px;--range-track-background:var(--color-border);--range-track-color:var(--color-gray-900);--range-track-color-disabled:var(--color-gray-600);--range-track-focus-color:var(--color-focus);display:flex;align-items:center}.k-range-input-native{--min:0;--max:100;--value:0;--range:calc(var(--max) - var(--min));--ratio:calc((var(--value) - var(--min)) / var(--range));--position:calc( .5 * var(--range-thumb-size) + var(--ratio) * calc(100% - var(--range-thumb-size)) );-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;height:var(--range-thumb-size);background:0 0;font-size:var(--text-sm);line-height:1}.k-range-input-native::-webkit-slider-thumb{-webkit-appearance:none;appearance:none}.k-range-input-native::-webkit-slider-runnable-track{border:0;border-radius:var(--range-track-height);width:100%;height:var(--range-track-height);background:var(--range-track-background)}.k-range-input-native::-moz-range-track{border:0;border-radius:var(--range-track-height);width:100%;height:var(--range-track-height);background:var(--range-track-background)}.k-range-input-native::-ms-track{border:0;border-radius:var(--range-track-height);width:100%;height:var(--range-track-height);background:var(--range-track-background)}.k-range-input-native::-webkit-slider-runnable-track{background:linear-gradient(var(--range-track-color),var(--range-track-color))0/var(--position) 100%no-repeat var(--range-track-background)}.k-range-input-native::-moz-range-progress{height:var(--range-track-height);background:var(--range-track-color)}.k-range-input-native::-ms-fill-lower{height:var(--range-track-height);background:var(--range-track-color)}.k-range-input-native::-webkit-slider-thumb{margin-top:calc(.5*(var(--range-track-height) - var(--range-thumb-size)));box-sizing:border-box;width:var(--range-thumb-size);height:var(--range-thumb-size);background:var(--range-thumb-background);border:var(--range-thumb-border);border-radius:50%;cursor:pointer}.k-range-input-native::-moz-range-thumb{box-sizing:border-box;width:var(--range-thumb-size);height:var(--range-thumb-size);background:var(--range-thumb-background);border:var(--range-thumb-border);border-radius:50%;cursor:pointer}.k-range-input-native::-ms-thumb{box-sizing:border-box;width:var(--range-thumb-size);height:var(--range-thumb-size);background:var(--range-thumb-background);border:var(--range-thumb-border);border-radius:50%;cursor:pointer;margin-top:0}.k-range-input-native::-ms-tooltip{display:none}.k-range-input-native:focus{outline:0}.k-range-input-native:focus::-webkit-slider-runnable-track{border:0;border-radius:var(--range-track-height);width:100%;height:var(--range-track-height);background:var(--range-track-background);background:linear-gradient(var(--range-track-focus-color),var(--range-track-focus-color))0/var(--position) 100%no-repeat var(--range-track-background)}.k-range-input-native:focus::-moz-range-progress{height:var(--range-track-height);background:var(--range-track-focus-color)}.k-range-input-native:focus::-ms-fill-lower{height:var(--range-track-height);background:var(--range-track-focus-color)}.k-range-input-native:focus::-webkit-slider-thumb{background:var(--range-thumb-focus-background);border:var(--range-thumb-focus-border)}.k-range-input-native:focus::-moz-range-thumb{background:var(--range-thumb-focus-background);border:var(--range-thumb-focus-border)}.k-range-input-native:focus::-ms-thumb{background:var(--range-thumb-focus-background);border:var(--range-thumb-focus-border)}[dir=ltr] .k-range-input-tooltip{margin-left:1rem}[dir=rtl] .k-range-input-tooltip{margin-right:1rem}.k-range-input-tooltip{position:relative;max-width:20%;display:flex;align-items:center;color:var(--color-white);font-size:var(--text-xs);line-height:1;text-align:center;border-radius:var(--rounded-xs);background:var(--color-gray-900);padding:0 .25rem;white-space:nowrap}[dir=ltr] .k-range-input-tooltip:after{left:-5px}[dir=rtl] .k-range-input-tooltip:after{right:-5px}[dir=ltr] .k-range-input-tooltip:after{border-right:5px solid var(--color-gray-900)}[dir=rtl] .k-range-input-tooltip:after{border-left:5px solid var(--color-gray-900)}.k-range-input-tooltip:after{position:absolute;top:50%;width:0;height:0;transform:translateY(-50%);border-top:5px solid transparent;border-bottom:5px solid transparent;content:""}.k-range-input-tooltip>*{padding:4px}[data-disabled=true] .k-range-input-native::-webkit-slider-runnable-track{background:linear-gradient(var(--range-track-color-disabled),var(--range-track-color-disabled))0/var(--position) 100%no-repeat var(--range-track-background)}[data-disabled=true] .k-range-input-native::-moz-range-progress{height:var(--range-track-height);background:var(--range-track-color-disabled)}[data-disabled=true] .k-range-input-native::-ms-fill-lower{height:var(--range-track-height);background:var(--range-track-color-disabled)}[data-disabled=true] .k-range-input-native::-webkit-slider-thumb{border:var(--range-thumb-border-disabled)}[data-disabled=true] .k-range-input-native::-moz-range-thumb{border:var(--range-thumb-border-disabled)}[data-disabled=true] .k-range-input-native::-ms-thumb{border:var(--range-thumb-border-disabled)}[data-disabled=true] .k-range-input-tooltip{background:var(--color-gray-600)}[dir=ltr] [data-disabled=true] .k-range-input-tooltip:after{border-right:5px solid var(--color-gray-600)}[dir=rtl] [data-disabled=true] .k-range-input-tooltip:after{border-left:5px solid var(--color-gray-600)}.k-select-input{position:relative;display:block;cursor:pointer;overflow:hidden}.k-select-input-native{position:absolute;top:0;right:0;bottom:0;left:0;opacity:0;width:100%;font:inherit;z-index:1;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;font-weight:var(--font-normal)}.k-select-input-native[disabled]{cursor:default}.k-tags-input{display:flex;flex-wrap:wrap}.k-tags-input .k-tag{border-radius:var(--rounded-sm)}.k-tags-input .k-sortable-ghost{background:var(--color-focus)}.k-tags-input-element{flex-grow:1;flex-basis:0;min-width:0}.k-tags-input:focus-within .k-tags-input-element{flex-basis:4rem}.k-tags-input-element input{font:inherit;border:0;width:100%;background:0 0}.k-tags-input-element input:focus{outline:0}[dir=ltr] .k-tags-input[data-layout=list] .k-tag{margin-right:0!important}[dir=rtl] .k-tags-input[data-layout=list] .k-tag{margin-left:0!important}.k-tags-input[data-layout=list] .k-tag{width:100%}.k-textarea-input[data-size=small]{--size:7.5rem}.k-textarea-input[data-size=medium]{--size:15rem}.k-textarea-input[data-size=large]{--size:30rem}.k-textarea-input[data-size=huge]{--size:45rem}.k-textarea-input-wrapper{position:relative}.k-textarea-input-native{resize:none;border:0;width:100%;background:0 0;font:inherit;line-height:1.5em;color:inherit;min-height:var(--size)}.k-textarea-input-native::-moz-placeholder{color:var(--color-gray-500)}.k-textarea-input-native::placeholder{color:var(--color-gray-500)}.k-textarea-input-native:focus{outline:0}.k-textarea-input-native:invalid{box-shadow:none;outline:0}.k-textarea-input-native[data-font=monospace]{font-family:var(--font-mono)}.k-toolbar{margin-bottom:.25rem;color:#aaa}.k-textarea-input:focus-within .k-toolbar{position:sticky;top:0;left:0;right:0;z-index:1;box-shadow:#0000000d 0 2px 5px;border-bottom:1px solid rgba(0,0,0,.1);color:#000}.k-toggle-input{--toggle-background:var(--color-white);--toggle-color:var(--color-gray-500);--toggle-active-color:var(--color-gray-900);--toggle-focus-color:var(--color-focus);--toggle-height:16px;display:flex;align-items:center}.k-toggle-input-native{position:relative;height:var(--toggle-height);width:calc(var(--toggle-height)*2);border-radius:var(--toggle-height);border:2px solid var(--toggle-color);box-shadow:inset 0 0 0 2px var(--toggle-background),inset calc(var(--toggle-height)*-1) 0 0 2px var(--toggle-background);background-color:var(--toggle-color);outline:0;transition:all ease-in-out .1s;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;flex-shrink:0}.k-toggle-input-native:checked{border-color:var(--toggle-active-color);box-shadow:inset 0 0 0 2px var(--toggle-background),inset var(--toggle-height) 0 0 2px var(--toggle-background);background-color:var(--toggle-active-color)}.k-toggle-input-native[disabled]{border-color:var(--color-border);box-shadow:inset 0 0 0 2px var(--color-background),inset calc(var(--toggle-height)*-1) 0 0 2px var(--color-background);background-color:var(--color-border)}.k-toggle-input-native[disabled]:checked{box-shadow:inset 0 0 0 2px var(--color-background),inset var(--toggle-height) 0 0 2px var(--color-background)}.k-toggle-input-native:focus:checked{border:2px solid var(--color-focus);background-color:var(--toggle-focus-color)}.k-toggle-input-native::-ms-check{opacity:0}.k-toggle-input-label{cursor:pointer;flex-grow:1}.k-input[data-type=toggles]{display:inline-flex}.k-input[data-type=toggles].grow{display:flex}.k-toggles-input{display:grid;grid-template-columns:repeat(var(--options),minmax(0,1fr));gap:1px;border-radius:var(--rounded);line-height:1;background:var(--color-border);overflow:hidden}.k-toggles-input li{height:var(--field-input-height);background:var(--color-white)}.k-toggles-input label{align-items:center;background:var(--color-white);cursor:pointer;display:flex;font-size:var(--text-sm);justify-content:center;line-height:1.25;padding:0 var(--spacing-3);height:100%}[dir=ltr] .k-toggles-input .k-icon+.k-toggles-text{margin-left:var(--spacing-2)}[dir=rtl] .k-toggles-input .k-icon+.k-toggles-text{margin-right:var(--spacing-2)}.k-toggles-input input:focus:not(:checked)+label{background:var(--color-gray-200)}.k-toggles-input input:checked+label{background:var(--color-black);color:var(--color-white)}.k-blocks-field{position:relative}.k-date-field-body{display:flex;flex-wrap:wrap;line-height:1;border:var(--field-input-border);background:var(--color-gray-300);gap:1px;border-radius:var(--rounded);--multiplier:calc(25rem - 100%)}.k-date-field-body:focus-within{border:var(--field-input-focus-border);box-shadow:var(--color-focus-outline) 0 0 0 2px}.k-date-field[data-disabled] .k-date-field-body{background:0 0}.k-date-field-body>.k-input[data-theme=field]{border:0;box-shadow:none;border-radius:var(--rounded)}.k-date-field-body>.k-input[data-invalid=true],.k-date-field-body>.k-input[data-invalid=true]:focus-within{border:0!important;box-shadow:none!important}.k-date-field-body>*{flex-grow:1;flex-basis:calc(var(--multiplier)*999);max-width:100%}.k-date-field-body .k-input[data-type=date]{min-width:60%}.k-date-field-body .k-input[data-type=time]{min-width:30%}.k-files-field[data-disabled=true] *{pointer-events:all!important}body{counter-reset:headline-counter}.k-headline-field{position:relative;padding-top:1.5rem}.k-fieldset>.k-grid .k-column:first-child .k-headline-field{padding-top:0}[dir=ltr] .k-headline-field .k-headline[data-numbered]:before{padding-right:.25rem}[dir=rtl] .k-headline-field .k-headline[data-numbered]:before{padding-left:.25rem}.k-headline-field .k-headline[data-numbered]:before{counter-increment:headline-counter;content:counter(headline-counter,decimal-leading-zero);color:var(--color-focus);font-weight:400}.k-info-field .k-headline{padding-bottom:.75rem;line-height:1.25rem}.k-layout-column{position:relative;height:100%;display:flex;flex-direction:column;background:var(--color-white);min-height:6rem}.k-layout-column:focus{outline:0}.k-layout-column .k-blocks{background:0 0;box-shadow:none;padding:0;height:100%;background:var(--color-white);min-height:4rem}.k-layout-column .k-blocks[data-empty=true]{min-height:6rem}.k-layout-column .k-blocks-list{display:flex;flex-direction:column;height:100%}.k-layout-column .k-blocks .k-block-container:last-of-type{flex-grow:1}.k-layout-column .k-blocks-empty{position:absolute;top:0;right:0;bottom:0;left:0;justify-content:center;opacity:0;transition:opacity .3s;border:0}.k-layout-column .k-blocks-empty:hover{opacity:1}[dir=ltr] .k-layout-column .k-blocks-empty.k-empty .k-icon{border-right:0}[dir=rtl] .k-layout-column .k-blocks-empty.k-empty .k-icon{border-left:0}.k-layout-column .k-blocks-empty.k-empty .k-icon{width:1rem}[dir=ltr] .k-layout{padding-right:var(--layout-toolbar-width)}[dir=rtl] .k-layout{padding-left:var(--layout-toolbar-width)}.k-layout{--layout-border-color:var(--color-gray-300);--layout-toolbar-width:2rem;position:relative;background:#fff;box-shadow:var(--shadow)}[dir=ltr] [data-disabled=true] .k-layout{padding-right:0}[dir=rtl] [data-disabled=true] .k-layout{padding-left:0}.k-layout:not(:last-of-type){margin-bottom:1px}.k-layout:focus{outline:0}[dir=ltr] .k-layout-toolbar{right:0}[dir=rtl] .k-layout-toolbar{left:0}[dir=ltr] .k-layout-toolbar{border-left:1px solid var(--color-light)}[dir=rtl] .k-layout-toolbar{border-right:1px solid var(--color-light)}.k-layout-toolbar{position:absolute;top:0;bottom:0;width:var(--layout-toolbar-width);display:flex;flex-direction:column;font-size:var(--text-sm);background:var(--color-gray-100);color:var(--color-gray-500)}.k-layout-toolbar:hover{color:var(--color-black)}.k-layout-toolbar-button{width:var(--layout-toolbar-width);height:var(--layout-toolbar-width)}.k-layout-toolbar .k-sort-handle{margin-top:auto;color:currentColor}.k-layout-columns.k-grid{grid-gap:1px;background:var(--layout-border-color);background:var(--color-gray-300)}.k-layout:not(:first-child) .k-layout-columns.k-grid{border-top:0}.k-layouts .k-sortable-ghost{position:relative;box-shadow:#11111140 0 5px 10px;outline:2px solid var(--color-focus);cursor:grabbing;cursor:-webkit-grabbing;z-index:1}.k-layout-selector.k-dialog{background:#313740;color:var(--color-white)}.k-layout-selector .k-headline{line-height:1;margin-top:-.25rem;margin-bottom:1.5rem}.k-layout-selector ul{display:grid;grid-template-columns:repeat(3,1fr);grid-gap:1.5rem}.k-layout-selector-option .k-grid{height:5rem;grid-gap:2px;box-shadow:var(--shadow);cursor:pointer}.k-layout-selector-option:hover{outline:2px solid var(--color-green-300);outline-offset:2px}.k-layout-selector-option:last-child{margin-bottom:0}.k-layout-selector-option .k-column{display:flex;background:rgba(255,255,255,.2);justify-content:center;font-size:var(--text-xs);align-items:center}.k-layout-add-button{display:flex;align-items:center;width:100%;color:var(--color-gray-500);justify-content:center;padding:.75rem 0}.k-layout-add-button:hover{color:var(--color-black)}.k-line-field{position:relative;border:0;height:3rem;width:auto}.k-line-field:after{position:absolute;content:"";top:50%;margin-top:-1px;left:0;right:0;height:1px;background:var(--color-border)}.k-list-field .k-list-input{padding:.375rem .5rem .375rem .75rem}.k-pages-field[data-disabled=true] *{pointer-events:all!important}.k-structure-field:not([data-disabled=true]) td.k-table-column{cursor:pointer}.k-field-counter{display:none}.k-text-field:focus-within .k-field-counter{display:block}.k-users-field[data-disabled=true] *{pointer-events:all!important}.k-writer-field-input{line-height:1.5em;padding:.375rem .5rem}.k-aspect-ratio{position:relative;display:block;overflow:hidden;padding-bottom:100%}.k-aspect-ratio>*{position:absolute!important;top:0;right:0;bottom:0;left:0;height:100%;width:100%;-o-object-fit:contain;object-fit:contain}.k-aspect-ratio[data-cover=true]>*{-o-object-fit:cover;object-fit:cover}.k-bar{display:flex;align-items:center;justify-content:space-between;line-height:1}.k-bar-slot{flex-grow:1}.k-bar-slot[data-position=center]{text-align:center}[dir=ltr] .k-bar-slot[data-position=right]{text-align:right}[dir=rtl] .k-bar-slot[data-position=right]{text-align:left}.k-box{word-wrap:break-word;font-size:var(--text-sm)}.k-box:not([data-theme=none]){background:var(--color-white);border-radius:var(--rounded);line-height:1.25rem;padding:.5rem .75rem}.k-box[data-theme=code]{background:var(--color-gray-900);border:1px solid var(--color-black);color:var(--color-light);font-family:Input,Menlo,monospace;font-size:var(--text-sm);line-height:1.5}.k-box[data-theme=button]{padding:0}[dir=ltr] .k-box[data-theme=button] .k-button{text-align:left}[dir=rtl] .k-box[data-theme=button] .k-button{text-align:right}.k-box[data-theme=button] .k-button{padding:0 .75rem;height:2.25rem;width:100%;display:flex;align-items:center;line-height:2rem}[dir=ltr] .k-box[data-theme=info],[dir=ltr] .k-box[data-theme=negative],[dir=ltr] .k-box[data-theme=notice],[dir=ltr] .k-box[data-theme=positive]{border-left-color:var(--theme-light)}[dir=rtl] .k-box[data-theme=info],[dir=rtl] .k-box[data-theme=negative],[dir=rtl] .k-box[data-theme=notice],[dir=rtl] .k-box[data-theme=positive]{border-right-color:var(--theme-light)}.k-box[data-theme=info],.k-box[data-theme=negative],.k-box[data-theme=notice],.k-box[data-theme=positive]{border:0;background:var(--theme-bg)}[dir=ltr] .k-box[data-theme=empty]{border-left:0}[dir=rtl] .k-box[data-theme=empty]{border-right:0}.k-box[data-theme=empty]{text-align:center;padding:3rem 1.5rem;display:flex;justify-content:center;align-items:center;flex-direction:column;background:var(--color-background);border:1px dashed var(--color-border)}.k-box[data-theme=empty] .k-icon{margin-bottom:.5rem;color:var(--color-gray-500)}.k-box[data-theme=empty],.k-box[data-theme=empty] p{color:var(--color-gray-600)}.k-bubble{display:flex;padding:0 .5rem;white-space:nowrap;align-items:center;line-height:1.5;font-size:var(--text-xs);height:1.525rem;background:var(--color-light);color:var(--color-black);border-radius:var(--rounded);overflow:hidden}[dir=ltr] .k-bubble .k-item-figure{margin-left:-.5rem}[dir=rtl] .k-bubble .k-item-figure{margin-right:-.5rem}[dir=ltr] .k-bubble .k-item-figure{margin-right:var(--spacing-2)}[dir=rtl] .k-bubble .k-item-figure{margin-left:var(--spacing-2)}.k-bubble .k-item-figure{width:1.525rem;height:1.525rem}.k-bubbles{display:flex;gap:.25rem}.k-collection-help{padding:.5rem .75rem}.k-collection-footer{display:flex;justify-content:space-between;margin-left:-.75rem;margin-right:-.75rem}.k-collection-pagination{line-height:1.25rem;flex-shrink:0;min-height:2.75rem}.k-collection-pagination .k-pagination .k-button{padding:.5rem .75rem;line-height:1.125rem}.k-column{min-width:0;grid-column-start:span 12}.k-column[data-sticky=true]>div{position:sticky;top:4vh;z-index:2}@media screen and (min-width:65em){.k-column[data-width="1/1"],.k-column[data-width="12/12"],.k-column[data-width="2/2"],.k-column[data-width="3/3"],.k-column[data-width="4/4"],.k-column[data-width="6/6"]{grid-column-start:span 12}.k-column[data-width="11/12"]{grid-column-start:span 11}.k-column[data-width="10/12"],.k-column[data-width="5/6"]{grid-column-start:span 10}.k-column[data-width="3/4"],.k-column[data-width="9/12"]{grid-column-start:span 9}.k-column[data-width="2/3"],.k-column[data-width="4/6"],.k-column[data-width="8/12"]{grid-column-start:span 8}.k-column[data-width="7/12"]{grid-column-start:span 7}.k-column[data-width="1/2"],.k-column[data-width="2/4"],.k-column[data-width="3/6"],.k-column[data-width="6/12"]{grid-column-start:span 6}.k-column[data-width="5/12"]{grid-column-start:span 5}.k-column[data-width="1/3"],.k-column[data-width="2/6"],.k-column[data-width="4/12"]{grid-column-start:span 4}.k-column[data-width="1/4"],.k-column[data-width="3/12"]{grid-column-start:span 3}.k-column[data-width="1/6"],.k-column[data-width="2/12"]{grid-column-start:span 2}.k-column[data-width="1/12"]{grid-column-start:span 1}}.k-column[data-disabled=true]{cursor:not-allowed;opacity:.4}.k-column[data-disabled=true] *{pointer-events:none}.k-column[data-disabled=true] .k-text[data-theme=help] *{pointer-events:initial}.k-dropzone{position:relative}.k-dropzone:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;display:none;pointer-events:none;z-index:1}.k-dropzone[data-over=true]:after{display:block;outline:1px solid var(--color-focus);box-shadow:var(--color-focus-outline) 0 0 0 3px}.k-empty{display:flex;align-items:stretch;border-radius:var(--rounded);color:var(--color-gray-600);border:1px dashed var(--color-border)}button.k-empty{width:100%}button.k-empty:focus{outline:0}.k-empty p{font-size:var(--text-sm);color:var(--color-gray-600)}.k-empty>.k-icon{color:var(--color-gray-500)}.k-empty[data-layout=cardlets],.k-empty[data-layout=cards]{text-align:center;padding:1.5rem;justify-content:center;flex-direction:column}.k-empty[data-layout=cardlets] .k-icon,.k-empty[data-layout=cards] .k-icon{margin-bottom:1rem}.k-empty[data-layout=cardlets] .k-icon svg,.k-empty[data-layout=cards] .k-icon svg{width:2rem;height:2rem}.k-empty[data-layout=list],.k-empty[data-layout=table]{min-height:38px}[dir=ltr] .k-empty[data-layout=list]>.k-icon,[dir=ltr] .k-empty[data-layout=table]>.k-icon{border-right:1px solid rgba(0,0,0,.05)}[dir=rtl] .k-empty[data-layout=list]>.k-icon,[dir=rtl] .k-empty[data-layout=table]>.k-icon{border-left:1px solid rgba(0,0,0,.05)}.k-empty[data-layout=list]>.k-icon,.k-empty[data-layout=table]>.k-icon{width:36px;min-height:36px}.k-empty[data-layout=list]>p,.k-empty[data-layout=table]>p{line-height:1.25rem;padding:.5rem .75rem}.k-file-preview{background:var(--color-gray-800)}.k-file-preview-layout{display:grid;grid-template-columns:50%auto}.k-file-preview-layout>*{min-width:0}.k-file-preview-image{position:relative;display:flex;align-items:center;justify-content:center;background:var(--bg-pattern)}.k-file-preview-image-link{display:block;width:100%;padding:min(4vw,3rem);outline:0}.k-file-preview-image-link[data-tabbed=true]{box-shadow:none;outline:2px solid var(--color-focus);outline-offset:-2px}.k-file-preview-details{padding:1.5rem;flex-grow:1}.k-file-preview-details ul{line-height:1.5em;max-width:50rem;display:grid;grid-gap:1.5rem 3rem;grid-template-columns:repeat(auto-fill,minmax(100px,1fr))}.k-file-preview-details h3{font-size:var(--text-sm);font-weight:500;color:var(--color-gray-500)}.k-file-preview-details a,.k-file-preview-details p{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#ffffffbf;font-size:var(--text-sm)}@media screen and (min-width:30em){.k-file-preview-details ul{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}}@media screen and (max-width:65em){.k-file-preview-layout{padding:0!important}}@media screen and (min-width:65em){.k-file-preview-layout{grid-template-columns:33.333%auto;align-items:center}.k-file-preview-details{padding:3rem}}@media screen and (min-width:90em){.k-file-preview-layout{grid-template-columns:25%auto}}.k-grid{--columns:12;display:grid;grid-column-gap:0;grid-row-gap:0;grid-template-columns:1fr}@media screen and (min-width:30em){.k-grid[data-gutter=small]{grid-column-gap:1rem;grid-row-gap:1rem}.k-grid[data-gutter=huge],.k-grid[data-gutter=large],.k-grid[data-gutter=medium]{grid-column-gap:1.5rem;grid-row-gap:1.5rem}}@media screen and (min-width:65em){.k-grid{grid-template-columns:repeat(var(--columns),1fr)}.k-grid[data-gutter=large]{grid-column-gap:3rem}.k-grid[data-gutter=huge]{grid-column-gap:4.5rem}}@media screen and (min-width:90em){.k-grid[data-gutter=large]{grid-column-gap:4.5rem}.k-grid[data-gutter=huge]{grid-column-gap:6rem}}@media screen and (min-width:120em){.k-grid[data-gutter=large]{grid-column-gap:6rem}.k-grid[data-gutter=huge]{grid-column-gap:7.5rem}}.k-header{padding-top:4vh;margin-bottom:2rem;border-bottom:1px solid var(--color-border)}.k-header[data-tabs=true]{border-bottom:0}.k-header .k-headline{min-height:1.25em;margin-bottom:.5rem;word-wrap:break-word}.k-header .k-header-buttons{margin-top:-.5rem;height:3.25rem}.k-header .k-headline-editable{cursor:pointer}[dir=ltr] .k-header .k-headline-editable .k-icon{margin-left:.5rem}[dir=rtl] .k-header .k-headline-editable .k-icon{margin-right:.5rem}.k-header .k-headline-editable .k-icon{color:var(--color-gray-500);opacity:0;transition:opacity .3s;display:inline-block}.k-header .k-headline-editable:hover .k-icon{opacity:1}.k-panel-inside{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column}.k-panel-inside:focus{outline:0}.k-panel-header{z-index:var(--z-navigation);flex-shrink:0}.k-panel-view{flex-grow:1;padding-bottom:6rem}.k-item{position:relative;background:var(--color-white);border-radius:var(--rounded);box-shadow:var(--shadow);display:grid;grid-template-columns:auto;line-height:1}.k-item a:focus,.k-item:focus{outline:0}.k-item:focus-within{box-shadow:var(--shadow-outline)}.k-item-sort-handle.k-sort-handle{position:absolute;opacity:0;width:1.25rem;height:1.5rem;z-index:2;border-radius:1px}.k-item:hover .k-item-sort-handle{opacity:1}.k-item-figure{grid-area:figure}.k-item-content{grid-area:content;overflow:hidden}.k-item-info,.k-item-title{font-size:var(--text-sm);font-weight:400;text-overflow:ellipsis;white-space:nowrap;line-height:1.125rem;overflow:hidden}.k-item-info{grid-area:info;color:var(--color-gray-500)}.k-item-title-link.k-link[data-=true]{box-shadow:none}.k-item-title-link:after{position:absolute;content:"";top:0;right:0;bottom:0;left:0;z-index:1}.k-item-footer{grid-area:footer;display:flex;justify-content:space-between;align-items:center;min-width:0}[dir=ltr] .k-item-label{margin-right:.5rem}[dir=rtl] .k-item-label{margin-left:.5rem}.k-item-buttons{position:relative;display:flex;justify-content:flex-end;flex-shrink:0;flex-grow:1}.k-item-buttons>.k-button,.k-item-buttons>.k-dropdown{position:relative;width:38px;height:38px;display:flex!important;align-items:center;justify-content:center;line-height:1}.k-item-buttons>.k-button{z-index:1}.k-item-buttons>.k-options-dropdown>.k-options-dropdown-toggle{z-index:var(--z-toolbar)}.k-list-item{display:flex;align-items:center;height:38px}[dir=ltr] .k-list-item .k-item-sort-handle{left:-1.5rem}[dir=rtl] .k-list-item .k-item-sort-handle{right:-1.5rem}.k-list-item .k-item-sort-handle{width:1.5rem}[dir=ltr] .k-list-item .k-item-figure{border-top-left-radius:var(--rounded)}[dir=rtl] .k-list-item .k-item-figure{border-top-right-radius:var(--rounded)}[dir=ltr] .k-list-item .k-item-figure{border-bottom-left-radius:var(--rounded)}[dir=rtl] .k-list-item .k-item-figure{border-bottom-right-radius:var(--rounded)}.k-list-item .k-item-figure{width:38px}[dir=ltr] .k-list-item .k-item-content{margin-left:.75rem}[dir=rtl] .k-list-item .k-item-content{margin-right:.75rem}.k-list-item .k-item-content{display:flex;flex-grow:1;flex-shrink:2;justify-content:space-between;align-items:center}.k-list-item .k-item-info,.k-list-item .k-item-title{flex-grow:1;line-height:1.5rem}[dir=ltr] .k-list-item .k-item-title{margin-right:.5rem}[dir=rtl] .k-list-item .k-item-title{margin-left:.5rem}.k-list-item .k-item-title{flex-shrink:1}[dir=ltr] .k-list-item .k-item-info{text-align:right}[dir=rtl] .k-list-item .k-item-info{text-align:left}[dir=ltr] .k-list-item .k-item-info{margin-right:.5rem}[dir=rtl] .k-list-item .k-item-info{margin-left:.5rem}.k-list-item .k-item-info{flex-shrink:2;justify-self:end}.k-list-item .k-item-buttons,.k-list-item .k-item-footer{flex-shrink:0}.k-item:not(.k-list-item) .k-item-sort-handle{margin:var(--spacing-2);background:var(--color-background);box-shadow:var(--shadow-lg);border-radius:var(--rounded-sm)}[dir=ltr] .k-item:not(.k-list-item) .k-item-label{margin-left:-2px}[dir=rtl] .k-item:not(.k-list-item) .k-item-label{margin-right:-2px}.k-item:not(.k-list-item) .k-item-content{padding:.625rem .75rem}.k-cardlets-item{height:6rem;grid-template-rows:auto 38px;grid-template-areas:"content""footer"}.k-cardlets-item[data-has-figure=true]{grid-template-columns:6rem auto;grid-template-areas:"figure content""figure footer"}[dir=ltr] .k-cardlets-item .k-item-figure{border-top-left-radius:var(--rounded)}[dir=rtl] .k-cardlets-item .k-item-figure{border-top-right-radius:var(--rounded)}[dir=ltr] .k-cardlets-item .k-item-figure{border-bottom-left-radius:var(--rounded)}[dir=rtl] .k-cardlets-item .k-item-figure{border-bottom-right-radius:var(--rounded)}.k-cardlets-item .k-item-footer{padding-top:.5rem;padding-bottom:.5rem}.k-cards-item{grid-template-columns:auto;grid-template-rows:auto 1fr;grid-template-areas:"figure""content";--item-content-wrapper:0}[dir=ltr] .k-cards-item .k-item-figure,[dir=rtl] .k-cards-item .k-item-figure{border-top-right-radius:var(--rounded);border-top-left-radius:var(--rounded)}.k-cards-item .k-item-content{padding:.5rem .75rem!important;overflow:hidden}.k-cards-item .k-item-info,.k-cards-item .k-item-title{line-height:1.375rem;white-space:normal}.k-cards-item .k-item-info:after,.k-cards-item .k-item-title:after{display:inline-block;content:"\a0";width:var(--item-content-wrapper)}.k-cards-item[data-has-flag=true],.k-cards-item[data-has-options=true]{--item-content-wrapper:38px}.k-cards-item[data-has-flag=true][data-has-options=true]{--item-content-wrapper:76px}.k-cards-item[data-has-info=true] .k-item-title:after{display:none}[dir=ltr] .k-cards-item .k-item-footer{right:0}[dir=rtl] .k-cards-item .k-item-footer{left:0}.k-cards-item .k-item-footer{position:absolute;bottom:0;width:auto}.k-item-figure{overflow:hidden;flex-shrink:0}.k-cards-items{--min:13rem;--max:1fr;--gap:1.5rem;--column-gap:var(--gap);--row-gap:var(--gap);display:grid;grid-column-gap:var(--column-gap);grid-row-gap:var(--row-gap);grid-template-columns:repeat(auto-fill,minmax(var(--min),var(--max)))}@media screen and (min-width:30em){.k-cards-items[data-size=tiny]{--min:10rem}.k-cards-items[data-size=small]{--min:16rem}.k-cards-items[data-size=medium]{--min:24rem}.k-cards-items[data-size=huge],.k-cards-items[data-size=large],.k-column[data-width="1/4"] .k-cards-items,.k-column[data-width="1/5"] .k-cards-items,.k-column[data-width="1/6"] .k-cards-items{--min:1fr}}@media screen and (min-width:65em){.k-cards-items[data-size=large]{--min:32rem}}.k-cardlets-items{display:grid;grid-template-columns:repeat(auto-fill,minmax(16rem,1fr));grid-gap:.5rem}.k-list-items .k-list-item:not(:last-child){margin-bottom:2px}.k-overlay{position:fixed;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:var(--z-dialog);transform:translateZ(0)}.k-overlay[data-centered=true]{display:flex;align-items:center;justify-content:center}.k-overlay[data-dimmed=true]{background:var(--color-backdrop)}.k-overlay-loader{color:var(--color-white)}.k-panel[data-loading=true]{animation:LoadingCursor .5s}.k-panel[data-dragging=true],.k-panel[data-loading=true]:after{-webkit-user-select:none;-moz-user-select:none;user-select:none}.k-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));grid-gap:var(--spacing-2px)}.k-stat{display:flex;flex-direction:column;background:var(--color-white);box-shadow:var(--shadow);padding:var(--spacing-3) var(--spacing-6);line-height:var(--leading-normal);border-radius:var(--rounded)}.k-stat.k-link:hover,.k-stat[data-click=true]:hover{cursor:pointer;background:var(--color-gray-100)}.k-stat dd,.k-stat dt{display:block}.k-stat-value{font-size:var(--value);margin-bottom:var(--spacing-1);order:1}.k-stat-info,.k-stat-label{font-size:var(--text-xs)}.k-stat-label{order:2}.k-stat-info{order:3;color:var(--theme, var(--color-gray-500))}.k-stats[data-size=small]{--value:var(--text-base)}.k-stats[data-size=medium]{--value:var(--text-xl)}.k-stats[data-size=large]{--value:var(--text-2xl)}.k-stats[data-size=huge]{--value:var(--text-3xl)}.k-table{--table-row-height:38px;position:relative;table-layout:fixed;background:var(--color-white);font-size:var(--text-sm);border-spacing:0;box-shadow:var(--shadow);border-radius:var(--rounded);font-variant-numeric:tabular-nums}.k-table td,.k-table th{height:var(--table-row-height);overflow:hidden;text-overflow:ellipsis;line-height:1.25em}.k-table,.k-table td{width:100%}[dir=ltr] .k-table th:first-child{border-top-left-radius:var(--rounded)}[dir=rtl] .k-table th:first-child{border-top-right-radius:var(--rounded)}[dir=ltr] .k-table th:last-child{border-top-right-radius:var(--rounded)}[dir=rtl] .k-table th:last-child{border-top-left-radius:var(--rounded)}[dir=ltr] .k-table td:last-child,[dir=ltr] .k-table th:last-child{border-right:0}[dir=rtl] .k-table td:last-child,[dir=rtl] .k-table th:last-child{border-left:0}.k-table td:last-child,.k-table th:last-child{height:var(--table-row-height)}.k-table th,.k-table tr:not(:last-child) td{border-bottom:1px solid var(--color-background)}.k-table td:last-child{overflow:visible}[dir=ltr] .k-table td,[dir=ltr] .k-table th{border-right:1px solid var(--color-background)}[dir=rtl] .k-table td,[dir=rtl] .k-table th{border-left:1px solid var(--color-background)}.k-table tbody tr:hover td{background:rgba(239,239,239,.25)}.k-table-column[data-align]{text-align:var(--align)}.k-table-column[data-align=right]>.k-input{flex-direction:column;align-items:flex-end}.k-table th{position:sticky;top:0;left:0;right:0;width:100%;padding:0 .75rem;z-index:1;font-family:var(--font-mono);font-size:var(--text-xs);font-weight:400;color:var(--color-gray-600);background:var(--color-gray-100)}[dir=ltr] .k-table th{text-align:left}[dir=rtl] .k-table th{text-align:right}.k-table th:after{content:"";position:absolute;top:100%;left:0;right:0;height:.5rem;background:linear-gradient(to bottom,rgba(#000,.05),rgba(#000,0));z-index:2}.k-table .k-sort-handle,.k-table-index{display:grid;place-items:center;width:100%;height:var(--table-row-height)}.k-table .k-sort-handle,.k-table tr:hover .k-table-index-column[data-sortable=true] .k-table-index{display:none}.k-table tr:hover .k-sort-handle{display:grid!important}.k-table-row-ghost{background:var(--color-white);box-shadow:#11111140 0 5px 10px;outline:2px solid var(--color-focus);margin-bottom:2px;cursor:grabbing;cursor:-webkit-grabbing}.k-table-row-fallback{opacity:0!important}td.k-table-index-column,td.k-table-options-column,th.k-table-index-column,th.k-table-options-column{width:var(--table-row-height);text-align:center!important}.k-table-index{font-size:var(--text-xs);color:var(--color-gray-500);line-height:1.1em}.k-table-empty{color:var(--color-gray-600);font-size:var(--text-sm)}[data-disabled=true] .k-table{background:var(--color-background)}[dir=ltr] [data-disabled=true] .k-table td,[dir=ltr] [data-disabled=true] .k-table th{border-right:1px solid var(--color-border)}[dir=rtl] [data-disabled=true] .k-table td,[dir=rtl] [data-disabled=true] .k-table th{border-left:1px solid var(--color-border)}[data-disabled=true] .k-table td,[data-disabled=true] .k-table th{background:var(--color-background);border-bottom:1px solid var(--color-border)}[data-disabled=true] .k-table td:last-child{overflow:hidden;text-overflow:ellipsis}@media screen and (max-width:65em){.k-table td:not([data-mobile]),.k-table th:not([data-mobile]){display:none}}.k-tabs{position:relative;background:#e9e9e9;border:1px solid var(--color-border);border-radius:var(--rounded)}.k-tabs nav{display:flex;justify-content:center;margin-left:-1px;margin-right:-1px}[dir=ltr] .k-tab-button.k-button{border-left:1px solid transparent}[dir=rtl] .k-tab-button.k-button{border-right:1px solid transparent}[dir=ltr] .k-tab-button.k-button{border-right:1px solid var(--color-border)}[dir=rtl] .k-tab-button.k-button{border-left:1px solid var(--color-border)}.k-tab-button.k-button{position:relative;z-index:1;display:inline-flex;justify-content:center;align-items:center;padding:.625rem .75rem;font-size:var(--text-xs);text-transform:uppercase;text-align:center;font-weight:500;flex-grow:1;flex-shrink:1;flex-direction:column;max-width:15rem}@media screen and (min-width:30em){.k-tab-button.k-button{flex-direction:row}[dir=ltr] .k-tab-button.k-button .k-icon{margin-right:.5rem}[dir=rtl] .k-tab-button.k-button .k-icon{margin-left:.5rem}}[dir=ltr] .k-tab-button.k-button>.k-button-text{padding-left:0}[dir=rtl] .k-tab-button.k-button>.k-button-text{padding-right:0}.k-tab-button.k-button>.k-button-text{padding-top:.375rem;font-size:10px;overflow:hidden;max-width:10rem;text-overflow:ellipsis;opacity:1}@media screen and (min-width:30em){.k-tab-button.k-button>.k-button-text{font-size:var(--text-xs);padding-top:0}}[dir=ltr] .k-tab-button:last-child{border-right:1px solid transparent}[dir=rtl] .k-tab-button:last-child{border-left:1px solid transparent}[dir=ltr] .k-tab-button[aria-current]{border-right:1px solid var(--color-border)}[dir=rtl] .k-tab-button[aria-current]{border-left:1px solid var(--color-border)}.k-tab-button[aria-current]{position:relative;background:var(--color-background);pointer-events:none}[dir=ltr] .k-tab-button[aria-current]:first-child{border-left:1px solid var(--color-border)}[dir=rtl] .k-tab-button[aria-current]:first-child{border-right:1px solid var(--color-border)}.k-tab-button[aria-current]:after,.k-tab-button[aria-current]:before{position:absolute;content:""}.k-tab-button[aria-current]:before{left:-1px;right:-1px;top:-1px;height:2px;background:var(--color-black)}.k-tab-button[aria-current]:after{left:0;right:0;bottom:-1px;height:1px;background:var(--color-background)}[dir=ltr] .k-tabs-dropdown{right:0}[dir=rtl] .k-tabs-dropdown{left:0}.k-tabs-dropdown{top:100%}[dir=ltr] .k-tabs-badge{right:2px}[dir=rtl] .k-tabs-badge{left:2px}.k-tabs-badge{position:absolute;top:3px;font-variant-numeric:tabular-nums;line-height:1.5;padding:0 .25rem;border-radius:2px;font-size:10px;box-shadow:var(--shadow-md)}.k-tabs[data-theme=notice] .k-tabs-badge{background:var(--theme-light);color:var(--color-black)}.k-view{padding-left:1.5rem;padding-right:1.5rem;margin:0 auto;max-width:100rem}@media screen and (min-width:30em){.k-view{padding-left:3rem;padding-right:3rem}}@media screen and (min-width:90em){.k-view{padding-left:6rem;padding-right:6rem}}.k-view[data-align=center]{height:100vh;display:flex;align-items:center;justify-content:center;padding:0 3rem;overflow:auto}.k-view[data-align=center]>*{flex-basis:22.5rem}.k-fatal{position:fixed;top:0;right:0;bottom:0;left:0;background:var(--color-backdrop);display:flex;z-index:var(--z-fatal);align-items:center;justify-content:center;padding:1.5rem}.k-fatal-box{width:100%;height:100%;display:flex;flex-direction:column;color:var(--color-black);background:var(--color-red-400);box-shadow:var(--shadow-xl);border-radius:var(--rounded)}.k-fatal-box .k-headline{line-height:1;font-size:var(--text-sm);padding:.75rem}.k-fatal-box .k-button{padding:.75rem}.k-fatal-iframe{border:0;width:100%;flex-grow:1;background:var(--color-white)}.k-headline{--size:var(--text-base);font-size:var(--size);font-weight:var(--font-bold);line-height:1.5em}.k-headline[data-size=small]{--size:var(--text-sm)}.k-headline[data-size=large]{--size:var(--text-xl);font-weight:var(--font-normal)}@media screen and (min-width:65em){.k-headline[data-size=large]{--size:var(--text-2xl)}}.k-headline[data-size=huge]{--size:var(--text-2xl);line-height:1.15em}@media screen and (min-width:65em){.k-headline[data-size=huge]{--size:var(--text-3xl)}}.k-headline[data-theme]{color:var(--theme)}[dir=ltr] .k-headline abbr{padding-left:.25rem}[dir=rtl] .k-headline abbr{padding-right:.25rem}.k-headline abbr{color:var(--color-gray-500);text-decoration:none}.k-icon{--size:1rem;position:relative;line-height:0;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:var(--size)}.k-icon[data-size=medium]{--size:2rem}.k-icon[data-size=large]{--size:3rem}.k-icon svg{width:var(--size);height:var(--size);-moz-transform:scale(1)}.k-icon svg *{fill:currentColor}.k-icon[data-back=black]{color:var(--color-white)}.k-icon[data-back=white]{color:var(--color-gray-900)}.k-icon[data-back=pattern]{color:var(--color-white)}[data-disabled=true] .k-icon[data-back=pattern] svg{opacity:1}.k-icon-emoji{display:block;line-height:1;font-style:normal;font-size:var(--size)}@media only screen and (-webkit-min-device-pixel-ratio:2),not all,only screen and (min-resolution:192dpi),only screen and (min-resolution:2dppx){.k-icon-emoji{font-size:1.25em}}.k-icons{position:absolute;width:0;height:0}.k-image span{position:relative;display:block;line-height:0;padding-bottom:100%}.k-image img{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;-o-object-fit:contain;object-fit:contain}[dir=ltr] .k-image-error{left:50%}[dir=rtl] .k-image-error{right:50%}.k-image-error{position:absolute;top:50%;transform:translate(-50%,-50%);color:var(--color-white);font-size:.9em}.k-image-error svg *{fill:#ffffff4d}.k-image[data-cover=true] img{-o-object-fit:cover;object-fit:cover}.k-image[data-back=black] span{background:var(--color-gray-900)}.k-image[data-back=white] span{background:var(--color-white);color:var(--color-gray-900)}.k-image[data-back=white] .k-image-error{background:var(--color-gray-900);color:var(--color-white)}.k-image[data-back=pattern] span{background:var(--color-gray-800) var(--bg-pattern)}.k-loader{z-index:1}.k-loader-icon{animation:Spin .9s linear infinite}.k-offline-warning{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--z-offline);background:var(--color-backdrop);display:flex;align-items:center;justify-content:center;line-height:1}.k-offline-warning p{display:flex;align-items:center;gap:.5rem;background:var(--color-white);box-shadow:var(--shadow);padding:.75rem;border-radius:var(--rounded)}.k-offline-warning p .k-icon{color:var(--color-red-400)}.k-progress{-webkit-appearance:none;width:100%;height:.5rem;border-radius:5rem;background:var(--color-border);overflow:hidden;border:0}.k-progress::-webkit-progress-bar{border:0;background:var(--color-border);height:.5rem;border-radius:20px}.k-progress::-webkit-progress-value{border-radius:inherit;background:var(--color-focus);-webkit-transition:width .3s;transition:width .3s}.k-progress::-moz-progress-bar{border-radius:inherit;background:var(--color-focus);-moz-transition:width .3s;transition:width .3s}[dir=ltr] .k-registration,[dir=ltr] .k-registration p{margin-right:1rem}[dir=rtl] .k-registration,[dir=rtl] .k-registration p{margin-left:1rem}.k-registration{display:flex;align-items:center}.k-registration p{color:var(--color-negative-light);font-size:var(--text-sm);font-weight:600}@media screen and (max-width:90em){.k-registration p{display:none}}.k-registration .k-button{color:var(--color-white)}.k-sort-handle{cursor:move;cursor:grab;cursor:-webkit-grab;color:var(--color-gray-900);justify-content:center;align-items:center;line-height:0;width:2rem;height:2rem;display:flex;will-change:opacity,color;transition:opacity .3s;z-index:1}.k-sort-handle svg{width:1rem;height:1rem}.k-sort-handle:active{cursor:grabbing;cursor:-webkit-grabbing}.k-status-icon svg{width:14px;height:14px}.k-status-icon .k-icon{color:var(--theme-light)}.k-status-icon .k-button-text{color:var(--color-black)}.k-status-icon[data-disabled=true]{opacity:1!important}.k-status-icon[data-disabled=true] .k-icon{color:var(--color-gray-400);opacity:.5}.k-text{line-height:1.5em}[dir=ltr] .k-text ol,[dir=ltr] .k-text ul{margin-left:1rem}[dir=rtl] .k-text ol,[dir=rtl] .k-text ul{margin-right:1rem}.k-text li{list-style:inherit}.k-text p,.k-text>ol,.k-text>ul{margin-bottom:1.5em}.k-text a{text-decoration:underline}.k-text>:last-child{margin-bottom:0}.k-text[data-size=tiny]{font-size:var(--text-xs)}.k-text[data-size=small]{font-size:var(--text-sm)}.k-text[data-size=medium]{font-size:var(--text-base)}.k-text[data-size=large]{font-size:var(--text-xl)}.k-text[data-align]{text-align:var(--align)}.k-text[data-theme=help]{font-size:var(--text-sm);color:var(--color-gray-600);line-height:1.25rem}.k-dialog-body .k-text{word-wrap:break-word}.k-user-info{display:flex;align-items:center;line-height:1;font-size:var(--text-sm)}[dir=ltr] .k-user-info .k-image{margin-right:.75rem}[dir=rtl] .k-user-info .k-image{margin-left:.75rem}.k-user-info .k-image{width:1.5rem}[dir=ltr] .k-user-info .k-icon{margin-right:.75rem}[dir=rtl] .k-user-info .k-icon{margin-left:.75rem}.k-user-info .k-icon{width:1.5rem;height:1.5rem;background:var(--color-black);color:var(--color-white)}.k-breadcrumb{padding-left:.5rem;padding-right:.5rem}.k-breadcrumb-dropdown{height:2.5rem;width:2.5rem;display:flex;align-items:center;justify-content:center}.k-breadcrumb ol{display:none;align-items:center}@media screen and (min-width:30em){.k-breadcrumb ol{display:flex}.k-breadcrumb-dropdown{display:none}}.k-breadcrumb li,.k-breadcrumb-link{display:flex;align-items:center;min-width:0}.k-breadcrumb-link{font-size:var(--text-sm);align-self:stretch;padding-top:.625rem;padding-bottom:.625rem;line-height:1.25rem}.k-breadcrumb li{flex-shrink:3}.k-breadcrumb li:last-child{flex-shrink:1}.k-breadcrumb li:not(:last-child):after{content:"/";padding-left:.5rem;padding-right:.5rem;opacity:.5;flex-shrink:0}.k-breadcrumb li:not(:first-child):not(:last-child){max-width:15vw}[dir=ltr] .k-breadcrumb-icon{margin-right:.5rem}[dir=rtl] .k-breadcrumb-icon{margin-left:.5rem}.k-breadcrumb-icon.k-loader{opacity:.5}.k-breadcrumb-link-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}button{line-height:inherit;border:0;font-family:var(--font-sans);font-size:1rem;color:currentColor;background:0 0;cursor:pointer}button::-moz-focus-inner{padding:0;border:0}.k-button{display:inline-block;position:relative;font-size:var(--text-sm);transition:color .3s;outline:0}.k-button:focus,.k-button:hover{outline:0}.k-button *{vertical-align:middle}.k-button[data-responsive=true] .k-button-text{display:none}@media screen and (min-width:30em){.k-button[data-responsive=true] .k-button-text{display:inline}}.k-button[data-theme]{color:var(--theme)}.k-button-icon{display:inline-flex;align-items:center;line-height:0}[dir=ltr] .k-button-icon~.k-button-text{padding-left:.5rem}[dir=rtl] .k-button-icon~.k-button-text{padding-right:.5rem}.k-button-text{opacity:.75}.k-button:focus .k-button-text,.k-button:hover .k-button-text{opacity:1}.k-button-text b,.k-button-text span{vertical-align:baseline}.k-button[data-disabled=true]{opacity:.5;pointer-events:none;cursor:default}.k-card-options>.k-button[data-disabled=true]{display:inline-flex}.k-button-group{--padding-x:.75rem;--padding-y:1rem;--line-height:1rem;font-size:0;margin:0 calc(var(--padding-x)*-1)}.k-button-group>.k-dropdown{height:calc(var(--line-height) + (var(--padding-y)*2));display:inline-block}.k-button-group>.k-button,.k-button-group>.k-dropdown>.k-button{padding:var(--padding-y) var(--padding-x);line-height:var(--line-height)}.k-button-group .k-dropdown-content{top:calc(100% + 1px);margin:0 var(--padding-x)}.k-dropdown{position:relative}[dir=ltr] .k-dropdown-content{text-align:left}[dir=rtl] .k-dropdown-content{text-align:right}.k-dropdown-content{position:absolute;top:100%;background:var(--color-black);color:var(--color-white);z-index:var(--z-dropdown);box-shadow:var(--shadow-lg);border-radius:var(--rounded);margin-bottom:6rem}[dir=ltr] .k-dropdown-content[data-align=left]{left:0}[dir=ltr] .k-dropdown-content[data-align=right],[dir=rtl] .k-dropdown-content[data-align=left]{right:0}[dir=rtl] .k-dropdown-content[data-align=right]{left:0}.k-dropdown-content>.k-dropdown-item:first-child{margin-top:.5rem}.k-dropdown-content>.k-dropdown-item:last-child{margin-bottom:.5rem}.k-dropdown-content[data-dropup=true]{top:auto;bottom:100%;margin-bottom:.5rem}.k-dropdown-content hr{border-color:currentColor;opacity:.2;margin:.5rem 1rem}.k-dropdown-content[data-theme=light]{background:var(--color-white);color:var(--color-black)}.k-dropdown-item{white-space:nowrap;line-height:1;display:flex;width:100%;align-items:center;font-size:var(--text-sm);padding:6px 16px}.k-dropdown-item:focus{outline:0;box-shadow:var(--shadow-outline)}[dir=ltr] .k-dropdown-item .k-button-figure{padding-right:.5rem}[dir=rtl] .k-dropdown-item .k-button-figure{padding-left:.5rem}.k-dropdown-item .k-button-figure{text-align:center}.k-link{outline:0}.k-options-dropdown,.k-options-dropdown-toggle{display:flex;justify-content:center;align-items:center;height:38px}.k-options-dropdown-toggle{min-width:38px;padding:0 .75rem}.k-pagination{-webkit-user-select:none;-moz-user-select:none;user-select:none;direction:ltr}.k-pagination .k-button{padding:1rem}.k-pagination-details{white-space:nowrap}.k-pagination>span{font-size:var(--text-sm)}.k-pagination[data-align]{text-align:var(--align)}[dir=ltr] .k-dropdown-content.k-pagination-selector{left:50%}[dir=rtl] .k-dropdown-content.k-pagination-selector{right:50%}.k-dropdown-content.k-pagination-selector{position:absolute;top:100%;transform:translate(-50%);background:var(--color-black)}[dir=ltr] .k-dropdown-content.k-pagination-selector{direction:ltr}[dir=rtl] .k-dropdown-content.k-pagination-selector{direction:rtl}.k-pagination-settings{display:flex;align-items:center;justify-content:space-between}.k-pagination-settings .k-button{line-height:1}[dir=ltr] .k-pagination-settings label{border-right:1px solid rgba(255,255,255,.35)}[dir=rtl] .k-pagination-settings label{border-left:1px solid rgba(255,255,255,.35)}.k-pagination-settings label{display:flex;align-items:center;padding:.625rem 1rem;font-size:var(--text-xs)}[dir=ltr] .k-pagination-settings label span{margin-right:.5rem}[dir=rtl] .k-pagination-settings label span{margin-left:.5rem}.k-prev-next{direction:ltr}.k-search{max-width:30rem;margin:2.5rem auto;box-shadow:var(--shadow-lg);background:var(--color-light);border-radius:var(--rounded)}.k-search-input{display:flex}.k-search-types{flex-shrink:0;display:flex}[dir=ltr] .k-search-types>.k-button{padding-left:1rem}[dir=rtl] .k-search-types>.k-button{padding-right:1rem}.k-search-types>.k-button{font-size:var(--text-base);line-height:1;height:2.5rem}.k-search-types>.k-button .k-icon{height:2.5rem}.k-search-types>.k-button .k-button-text{opacity:1;font-weight:500}.k-search-input input{background:0 0;flex-grow:1;font:inherit;padding:.75rem;border:0;height:2.5rem}.k-search-close{width:3rem;line-height:1}.k-search-close .k-icon-loader{animation:Spin 2s linear infinite}.k-search input:focus{outline:0}.k-search-results{padding:.5rem 1rem 1rem}.k-search .k-item:not(:last-child){margin-bottom:.25rem}.k-search .k-item[data-selected=true]{outline:2px solid var(--color-focus)}.k-search .k-item-info,.k-search-empty{font-size:var(--text-xs)}.k-search-empty{text-align:center;color:var(--color-gray-600)}.k-tag{position:relative;font-size:var(--text-sm);line-height:1;cursor:pointer;background-color:var(--color-gray-900);color:var(--color-light);border-radius:var(--rounded);display:flex;align-items:center;justify-content:space-between;-webkit-user-select:none;-moz-user-select:none;user-select:none}.k-tag:focus{outline:0;background-color:var(--color-focus);color:#fff}.k-tag-text{padding:.3rem .75rem .375rem;line-height:var(--leading-tight)}[dir=ltr] .k-tag-toggle{padding-right:1px}[dir=rtl] .k-tag-toggle{padding-left:1px}[dir=ltr] .k-tag-toggle{border-left:1px solid rgba(255,255,255,.15)}[dir=rtl] .k-tag-toggle{border-right:1px solid rgba(255,255,255,.15)}.k-tag-toggle{color:#ffffffb3;width:1.75rem;height:100%}.k-tag-toggle:hover{background:rgba(255,255,255,.2);color:#fff}[data-disabled=true] .k-tag{background-color:var(--color-gray-600)}[data-disabled=true] .k-tag .k-tag-toggle{display:none}.k-topbar{--bg:var(--color-gray-900);position:relative;color:var(--color-white);flex-shrink:0;height:2.5rem;line-height:1;background:var(--bg)}.k-topbar-wrapper{position:relative;display:flex;align-items:center;margin-left:-.75rem;margin-right:-.75rem}[dir=ltr] .k-topbar-wrapper:after{left:100%}[dir=rtl] .k-topbar-wrapper:after{right:100%}.k-topbar-wrapper:after{position:absolute;content:"";height:2.5rem;background:var(--bg);width:3rem}.k-topbar-menu{flex-shrink:0}.k-topbar-menu ul{padding:.5rem 0}.k-topbar .k-button[data-theme]{color:var(--theme-light)}.k-topbar .k-button-text{opacity:1}.k-topbar-menu-button{display:flex;align-items:center}.k-topbar-menu .k-link[aria-current]{color:var(--color-focus);font-weight:500}.k-topbar-button{padding:.75rem;line-height:1;font-size:var(--text-sm)}.k-topbar-button .k-button-text{display:flex}[dir=ltr] .k-topbar-view-button{padding-right:0}[dir=rtl] .k-topbar-view-button{padding-left:0}.k-topbar-view-button{flex-shrink:0;display:flex;align-items:center}[dir=ltr] .k-topbar-view-button .k-icon{margin-right:.5rem}[dir=rtl] .k-topbar-view-button .k-icon{margin-left:.5rem}[dir=ltr] .k-topbar-signals{right:0}[dir=rtl] .k-topbar-signals{left:0}.k-topbar-signals{position:absolute;top:0;background:var(--bg);height:2.5rem;display:flex;align-items:center}.k-topbar-signals:before{position:absolute;content:"";top:-.5rem;bottom:0;width:.5rem;background:-webkit-linear-gradient(inline-start,rgba(17,17,17,0),#111)}.k-topbar-signals .k-button{line-height:1}.k-topbar-notification{font-weight:var(--font-bold);line-height:1;display:flex}@media screen and (max-width:30em){.k-topbar .k-button[data-theme=negative] .k-button-text{display:none}}.k-section,.k-sections{padding-bottom:3rem}.k-section-header{position:relative;display:flex;align-items:baseline;z-index:1}[dir=ltr] .k-section-header .k-headline{padding-right:var(--spacing-3)}[dir=rtl] .k-section-header .k-headline{padding-left:var(--spacing-3)}.k-section-header .k-headline{line-height:1.25rem;min-height:2rem;flex-grow:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}[dir=ltr] .k-section-header .k-button-group{right:0}[dir=rtl] .k-section-header .k-button-group{left:0}.k-section-header .k-button-group{position:absolute;top:calc(-.5rem - 1px)}.k-section-header .k-button-group>.k-button{padding:.75rem;display:inline-flex}.k-fields-issue-headline{margin-bottom:.5rem}.k-fields-section input[type=submit]{display:none}[data-locked=true] .k-fields-section{opacity:.2;pointer-events:none}.k-models-section[data-processing=true]{pointer-events:none}.k-models-section-search.k-input{margin-bottom:var(--spacing-3);background:var(--color-gray-300);padding:var(--spacing-2) var(--spacing-3);height:var(--field-input-height);border-radius:var(--rounded);font-size:var(--text-sm)}.k-info-section-headline{margin-bottom:.5rem}.k-user-profile{background:var(--color-white)}.k-user-profile>.k-view{padding-top:3rem;padding-bottom:3rem;display:flex;align-items:center;line-height:0}[dir=ltr] .k-user-profile .k-button-group{margin-left:.75rem}[dir=rtl] .k-user-profile .k-button-group{margin-right:.75rem}.k-user-profile .k-button-group{overflow:hidden}.k-user-profile .k-button-group .k-button{display:block;padding-top:.25rem;padding-bottom:.25rem;overflow:hidden;white-space:nowrap}.k-user-view-image .k-icon,.k-user-view-image .k-image{width:5rem;height:5rem;border-radius:var(--rounded);line-height:0;overflow:hidden}.k-user-view-image[data-disabled=true]{opacity:1}.k-user-view-image .k-image{display:block}.k-user-view-image .k-button-text{opacity:1}.k-user-name-placeholder{color:var(--color-gray-500);transition:color .3s}.k-header[data-editable=true] .k-user-name-placeholder:hover{color:var(--color-gray-900)}.k-error-view{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center}.k-error-view-content{line-height:1.5em;max-width:25rem;text-align:center}.k-error-view-icon{color:var(--color-negative);display:inline-block}.k-error-view-content p:not(:last-child){margin-bottom:.75rem}.k-installation-view .k-button{display:block;margin-top:1.5rem}.k-installation-view .k-headline{margin-bottom:.75rem}.k-installation-issues{line-height:1.5em;font-size:var(--text-sm)}[dir=ltr] .k-installation-issues li{padding-left:3.5rem}[dir=rtl] .k-installation-issues li{padding-right:3.5rem}.k-installation-issues li{position:relative;padding:1.5rem;background:var(--color-white)}[dir=ltr] .k-installation-issues .k-icon{left:1.5rem}[dir=rtl] .k-installation-issues .k-icon{right:1.5rem}.k-installation-issues .k-icon{position:absolute;top:calc(1.5rem + 2px)}.k-installation-issues .k-icon svg *{fill:var(--color-negative)}.k-installation-issues li:not(:last-child){margin-bottom:2px}.k-installation-issues li code{font:inherit;color:var(--color-negative)}[dir=ltr] .k-installation-view .k-button[type=submit]{margin-left:-1rem}[dir=rtl] .k-installation-view .k-button[type=submit]{margin-right:-1rem}.k-installation-view .k-button[type=submit]{padding:1rem}.k-languages-view .k-header{margin-bottom:1.5rem}.k-languages-view-section-header{margin-bottom:.5rem}.k-languages-view-section{margin-bottom:3rem}.k-login-fields{position:relative}[dir=ltr] .k-login-toggler{right:0}[dir=rtl] .k-login-toggler{left:0}.k-login-toggler{position:absolute;top:0;z-index:1;text-decoration:underline;font-size:.875rem}.k-login-form label abbr{visibility:hidden}.k-login-buttons{display:flex;align-items:center;justify-content:flex-end;padding:1.5rem 0}[dir=ltr] .k-login-button{margin-right:-1rem}[dir=rtl] .k-login-button{margin-left:-1rem}.k-login-button{padding:.5rem 1rem;font-weight:500;transition:opacity .3s}.k-login-button span{opacity:1}.k-login-button[disabled]{opacity:.25}.k-login-back-button,.k-login-checkbox{display:flex;align-items:center;flex-grow:1}[dir=ltr] .k-login-back-button{margin-left:-1rem}[dir=rtl] .k-login-back-button{margin-right:-1rem}.k-login-checkbox{padding:.5rem 0;font-size:var(--text-sm);cursor:pointer}.k-login-checkbox .k-checkbox-text{opacity:.75;transition:opacity .3s}.k-login-checkbox:focus span,.k-login-checkbox:hover span{opacity:1}.k-password-reset-view .k-user-info{height:38px;margin-bottom:2.25rem;padding:.5rem;background:var(--color-white);border-radius:var(--rounded-xs);box-shadow:var(--shadow)}.k-system-view .k-header{margin-bottom:1.5rem}.k-system-view-section-header{margin-bottom:.5rem;display:flex;justify-content:space-between}.k-system-view-section{margin-bottom:3rem}.k-system-info [data-theme] .k-stat-value{color:var(--theme)}.k-block-type-code-editor{position:relative;font-size:var(--text-sm);line-height:1.5em;background:#000;border-radius:var(--rounded);padding:.5rem .75rem 3rem;color:#fff;font-family:var(--font-mono)}.k-block-type-code-editor .k-editor{white-space:pre-wrap;line-height:1.75em}[dir=ltr] .k-block-type-code-editor-language{right:0}[dir=ltr] .k-block-type-code-editor-language .k-icon,[dir=rtl] .k-block-type-code-editor-language{left:0}.k-block-type-code-editor-language{font-size:var(--text-sm);position:absolute;bottom:0}[dir=rtl] .k-block-type-code-editor-language .k-icon{right:0}.k-block-type-code-editor-language .k-icon{position:absolute;top:0;height:1.5rem;display:flex;width:2rem;z-index:0}.k-block-type-code-editor-language .k-select-input{position:relative;padding:.325rem .75rem .5rem 2rem;z-index:1;font-size:var(--text-xs)}.k-block-type-default .k-block-title{line-height:1.5em}.k-block-type-gallery ul{display:grid;grid-gap:.75rem;grid-template-columns:repeat(auto-fit,minmax(6rem,1fr));line-height:0;align-items:center;justify-content:center;cursor:pointer}.k-block-type-gallery li:empty{padding-bottom:100%;background:var(--color-background)}.k-block-type-gallery li{display:flex;position:relative;align-items:center;justify-content:center}.k-block-type-gallery li img{flex-grow:1;max-width:100%}.k-block-type-heading-input{line-height:1.25em;font-weight:var(--font-bold)}.k-block-type-heading-input[data-level=h1]{font-size:var(--text-3xl);line-height:1.125em}.k-block-type-heading-input[data-level=h2]{font-size:var(--text-2xl)}.k-block-type-heading-input[data-level=h3]{font-size:var(--text-xl)}.k-block-type-heading-input[data-level=h4]{font-size:var(--text-lg)}.k-block-type-heading-input[data-level=h5]{line-height:1.5em;font-size:var(--text-base)}.k-block-type-heading-input[data-level=h6]{line-height:1.5em;font-size:var(--text-sm)}.k-block-type-heading-input .ProseMirror strong{font-weight:700}.k-block-type-image .k-block-figure-container{display:block;text-align:center;line-height:0}.k-block-type-image-auto{max-width:100%;max-height:30rem}.k-block-type-line hr{margin-top:.75rem;margin-bottom:.75rem;border:0;border-top:2px solid var(--color-gray-400)}.k-block-type-markdown-input{position:relative;font-size:var(--text-sm);line-height:1.5em;background:var(--color-background);border-radius:var(--rounded);padding:.5rem .5rem 0;font-family:var(--font-mono)}[dir=ltr] .k-block-type-quote-editor{padding-left:1rem}[dir=rtl] .k-block-type-quote-editor{padding-right:1rem}[dir=ltr] .k-block-type-quote-editor{border-left:2px solid var(--color-black)}[dir=rtl] .k-block-type-quote-editor{border-right:2px solid var(--color-black)}.k-block-type-quote-text{font-size:var(--text-xl);margin-bottom:.25rem;line-height:1.25em}.k-block-type-quote-citation{font-style:italic;font-size:var(--text-sm);color:var(--color-gray-600)}.k-block-type-table-preview{cursor:pointer;border:1px solid var(--color-gray-300);border-spacing:0;border-radius:var(--rounded-sm);overflow:hidden}[dir=ltr] .k-block-type-table-preview td,[dir=ltr] .k-block-type-table-preview th{text-align:left}[dir=rtl] .k-block-type-table-preview td,[dir=rtl] .k-block-type-table-preview th{text-align:right}.k-block-type-table-preview td,.k-block-type-table-preview th{line-height:1.5em;font-size:var(--text-sm)}.k-block-type-table-preview th{padding:.5rem .75rem}.k-block-type-table-preview td:not(.k-table-index-column){padding:0 .75rem}.k-block-type-table-preview td [class$=-field-preview],.k-block-type-table-preview td>*{padding:0}.k-block-type-text-input{font-size:var(--text-base);line-height:1.5em;height:100%}.k-block-container-type-text,.k-block-type-text,.k-block-type-text .k-writer .ProseMirror{height:100%}.k-block-container{position:relative;padding:.75rem;background:var(--color-white);border-radius:var(--rounded)}.k-block-container:not(:last-of-type){border-bottom:1px dashed rgba(0,0,0,.1)}.k-block-container:focus{outline:0}.k-block-container[data-batched=true],.k-block-container[data-selected=true]{z-index:2;border-bottom-color:transparent}.k-block-container[data-batched=true]:after{position:absolute;top:0;right:0;bottom:0;left:0;content:"";background:rgba(238,242,246,.375);mix-blend-mode:multiply;border:1px solid var(--color-focus)}.k-block-container[data-selected=true]{box-shadow:var(--color-focus) 0 0 0 1px,var(--color-focus-outline) 0 0 0 3px}[dir=ltr] .k-block-container .k-block-options{right:.75rem}[dir=rtl] .k-block-container .k-block-options{left:.75rem}.k-block-container .k-block-options{display:none;position:absolute;top:0;margin-top:calc(-1.75rem + 2px)}.k-block-container[data-last-in-batch=true]>.k-block-options,.k-block-container[data-selected=true]>.k-block-options{display:flex}.k-block-container[data-hidden=true] .k-block{opacity:.25}.k-drawer-options .k-button[data-disabled=true]{vertical-align:middle;display:inline-grid}[data-disabled=true] .k-block-container{background:var(--color-background)}.k-block-importer.k-dialog{background:#313740;color:var(--color-white)}.k-block-importer .k-dialog-body{padding:0}.k-block-importer label{display:block;padding:var(--spacing-6) var(--spacing-6)0;color:var(--color-gray-400)}.k-block-importer label kbd{background:rgba(0,0,0,.5);font-family:var(--font-mono);letter-spacing:.1em;padding:.25rem;border-radius:var(--rounded);margin:0 .25rem}.k-block-importer textarea{width:100%;height:20rem;background:0 0;font:inherit;color:var(--color-white);border:0;padding:var(--spacing-6);resize:none}.k-block-importer textarea:focus{outline:0}.k-blocks{background:var(--color-white);box-shadow:var(--shadow);border-radius:var(--rounded)}[data-disabled=true] .k-blocks{background:var(--color-background)}.k-blocks[data-multi-select-key=true] .k-block-container>*{pointer-events:none}.k-blocks[data-empty=true]{padding:0;background:0 0;box-shadow:none}.k-blocks .k-sortable-ghost{outline:2px solid var(--color-focus);box-shadow:#11111140 0 5px 10px;cursor:grabbing;cursor:-webkit-grabbing}.k-blocks-list>.k-blocks-empty{display:flex;align-items:center}.k-blocks-list>.k-blocks-empty:not(:only-child){display:none}.k-block-figure{cursor:pointer}.k-block-figure iframe{border:0;pointer-events:none;background:var(--color-black)}.k-block-figure figcaption{padding-top:.5rem;color:var(--color-gray-600);font-size:var(--text-sm);text-align:center}.k-block-figure-empty.k-button{display:flex;width:100%;height:6rem;border-radius:var(--rounded-sm);align-items:center;justify-content:center;color:var(--color-gray-600);background:var(--color-background)}.k-block-options{display:flex;align-items:center;background:var(--color-white);z-index:var(--z-dropdown);box-shadow:#0000001a -2px 0 5px,var(--shadow),var(--shadow-xl);color:var(--color-black);border-radius:var(--rounded)}[dir=ltr] .k-block-options-button{border-right:1px solid var(--color-background)}[dir=rtl] .k-block-options-button{border-left:1px solid var(--color-background)}.k-block-options-button{--block-options-button-size:30px;width:var(--block-options-button-size);height:var(--block-options-button-size);line-height:1;display:inline-flex;align-items:center;justify-content:center}[dir=ltr] .k-block-options-button:first-child{border-top-left-radius:var(--rounded)}[dir=rtl] .k-block-options-button:first-child{border-top-right-radius:var(--rounded)}[dir=ltr] .k-block-options-button:first-child{border-bottom-left-radius:var(--rounded)}[dir=rtl] .k-block-options-button:first-child{border-bottom-right-radius:var(--rounded)}[dir=ltr] .k-block-options-button:last-child{border-top-right-radius:var(--rounded)}[dir=rtl] .k-block-options-button:last-child{border-top-left-radius:var(--rounded)}[dir=ltr] .k-block-options-button:last-child{border-bottom-right-radius:var(--rounded)}[dir=rtl] .k-block-options-button:last-child{border-bottom-left-radius:var(--rounded)}[dir=ltr] .k-block-options-button:last-of-type{border-right:0}[dir=rtl] .k-block-options-button:last-of-type{border-left:0}.k-block-options-button[aria-current]{color:var(--color-focus)}.k-block-options-button:hover{background:var(--color-gray-100)}.k-block-options .k-dropdown-content{margin-top:.5rem}.k-block-selector.k-dialog{background:var(--color-dark);color:var(--color-white)}.k-block-selector .k-headline{margin-bottom:1rem}.k-block-selector details:not(:last-of-type){margin-bottom:1.5rem}.k-block-selector summary{font-size:var(--text-xs);cursor:pointer;color:var(--color-gray-400)}.k-block-selector details:only-of-type summary{pointer-events:none}.k-block-selector summary:focus{outline:0}.k-block-selector summary:focus-visible{color:var(--color-green-400)}.k-block-types{display:grid;grid-gap:2px;margin-top:.75rem;grid-template-columns:repeat(1,1fr)}[dir=ltr] .k-block-types .k-button{text-align:left}[dir=rtl] .k-block-types .k-button{text-align:right}.k-block-types .k-button{display:flex;align-items:flex-start;border-radius:var(--rounded);background:rgba(0,0,0,.5);width:100%;padding:0 .75rem 0 0;line-height:1.5em}.k-block-types .k-button:focus{outline:2px solid var(--color-green-300)}.k-block-types .k-button .k-button-text{padding:.5rem 0 .5rem .5rem}.k-block-types .k-button .k-icon{width:38px;height:38px}.k-clipboard-hint{padding-top:1.5rem;font-size:var(--text-xs);color:var(--color-gray-400)}.k-clipboard-hint kbd{background:rgba(0,0,0,.5);font-family:var(--font-mono);letter-spacing:.1em;padding:.25rem;border-radius:var(--rounded);margin:0 .25rem}[dir=ltr] .k-block-title{padding-right:.75rem}[dir=rtl] .k-block-title{padding-left:.75rem}.k-block-title{display:flex;align-items:center;min-width:0;font-size:var(--text-sm);line-height:1}[dir=ltr] .k-block-icon{margin-right:.5rem}[dir=rtl] .k-block-icon{margin-left:.5rem}.k-block-icon{width:1rem;color:var(--color-gray-500)}[dir=ltr] .k-block-name{margin-right:.5rem}[dir=rtl] .k-block-name{margin-left:.5rem}.k-block-label{color:var(--color-gray-600);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.k-bubbles-field-preview{padding:.325rem .75rem}.k-text-field-preview{padding:.325rem .75rem;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.k-url-field-preview{padding:.325rem .75rem}.k-url-field-preview a{color:var(--color-focus);text-decoration:underline;transition:color .3s;white-space:nowrap;max-width:100%}.k-url-field-preview a:hover{color:var(--color-black)}.k-flag-field-preview{height:var(--table-row-height);width:var(--table-row-height);display:flex;justify-content:center;align-items:center}.k-html-field-preview{padding:.325rem .75rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.5em}.k-html-field-preview p:not(:last-child){margin-bottom:1.5em}[dir=ltr] .k-html-field-preview ol,[dir=ltr] .k-html-field-preview ul{margin-left:1rem}[dir=rtl] .k-html-field-preview ol,[dir=rtl] .k-html-field-preview ul{margin-right:1rem}.k-html-field-preview ul>li{list-style:disc}.k-html-field-preview ol ul>li,.k-html-field-preview ul ul>li{list-style:circle}.k-html-field-preview ol>li{list-style:decimal}.k-html-field-preview ol>li::marker{color:var(--color-gray-500);font-size:var(--text-xs)}.k-toggle-field-preview label{padding:0 .25rem 0 .75rem;display:flex;height:38px;cursor:pointer;overflow:hidden;white-space:nowrap}[dir=ltr] .k-toggle-field-preview .k-toggle-input-label{padding-left:.5rem}[dir=ltr] [data-align=right] .k-toggle-field-preview .k-toggle-input-label,[dir=rtl] .k-toggle-field-preview .k-toggle-input-label{padding-right:.5rem}[dir=rtl] [data-align=right] .k-toggle-field-preview .k-toggle-input-label{padding-left:.5rem}[dir=ltr] .k-toggle-field-preview .k-toggle-input{padding-left:.75rem;padding-right:.25rem}.k-toggle-field-preview .k-toggle-input{padding-top:0;padding-bottom:0}[dir=ltr] [data-align=right] .k-toggle-field-preview .k-toggle-input,[dir=rtl] .k-toggle-field-preview .k-toggle-input{padding-left:.25rem;padding-right:.75rem}[dir=rtl] [data-align=right] .k-toggle-field-preview .k-toggle-input{padding-right:.25rem;padding-left:.75rem}[data-align=right] .k-toggle-field-preview .k-toggle-input{flex-direction:row-reverse}[data-align=left]{--align:start}[data-align=center]{--align:center}[data-align=right]{--align:end}[data-invalid=true]{border:1px solid var(--color-negative-outline);box-shadow:var(--color-negative-outline) 0 0 3px 2px}[data-invalid=true]:focus-within{border:var(--field-input-invalid-focus-border)!important;box-shadow:var(--color-negative-outline) 0 0 0 2px!important}[data-tabbed=true]{box-shadow:var(--shadow-outline);border-radius:var(--rounded)}[data-theme=positive],[data-theme=success]{--theme:var(--color-positive);--theme-light:var(--color-positive-light);--theme-bg:var(--color-green-300)}[data-theme=error],[data-theme=negative]{--theme:var(--color-negative);--theme-light:var(--color-negative-light);--theme-bg:var(--color-red-300)}[data-theme=notice]{--theme:var(--color-notice);--theme-light:var(--color-notice-light);--theme-bg:var(--color-orange-300)}[data-theme=info]{--theme:var(--color-focus);--theme-light:var(--color-focus-light);--theme-bg:var(--color-blue-200)}.scroll-x,.scroll-x-auto,.scroll-y,.scroll-y-auto{-webkit-overflow-scrolling:touch;transform:translateZ(0)}.scroll-x,.scroll-x-auto{overflow-x:scroll;overflow-y:hidden}.scroll-x-auto{overflow-x:auto}.scroll-y,.scroll-y-auto{overflow-x:hidden;overflow-y:scroll}.scroll-y-auto{overflow-y:auto}.input-hidden{position:absolute;-webkit-appearance:none;-moz-appearance:none;appearance:none;width:0;height:0;opacity:0}.k-offscreen,.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0} +.k-dialog{position:relative;background:var(--color-background);width:100%;box-shadow:var(--shadow-lg);border-radius:var(--rounded-md);line-height:1;max-height:calc(100vh - 3rem);margin:1.5rem;display:flex;flex-direction:column}@media screen and (min-width:20rem){.k-dialog[data-size=small]{width:20rem}}@media screen and (min-width:22rem){.k-dialog[data-size=default]{width:22rem}}@media screen and (min-width:30rem){.k-dialog[data-size=medium]{width:30rem}}@media screen and (min-width:40rem){.k-dialog[data-size=large]{width:40rem}}[dir=ltr] .k-dialog-notification,[dir=rtl] .k-dialog-notification{border-top-right-radius:var(--rounded);border-top-left-radius:var(--rounded)}.k-dialog-notification{padding:.75rem 1.5rem;background:var(--color-gray-900);width:100%;margin-top:-1px;line-height:1.25rem;color:var(--color-white);display:flex;flex-shrink:0;align-items:center}.k-dialog-notification[data-theme]{background:var(--theme-light);color:var(--color-black)}.k-dialog-notification p{flex-grow:1;word-wrap:break-word;overflow:hidden}[dir=ltr] .k-dialog-notification .k-button{margin-left:1rem}[dir=rtl] .k-dialog-notification .k-button{margin-right:1rem}.k-dialog-notification .k-button{display:flex}.k-dialog-body{padding:1.5rem}.k-dialog-body .k-fieldset{padding-bottom:.5rem}.k-dialog-footer{padding:0;border-top:1px solid var(--color-gray-300);line-height:1;flex-shrink:0}.k-dialog-footer .k-button-group{display:flex;margin:0;justify-content:space-between}.k-dialog-footer .k-button-group .k-button{padding:.75rem 1rem;line-height:1.25rem}[dir=ltr] .k-dialog-footer .k-button-group .k-button:first-child{text-align:left}[dir=rtl] .k-dialog-footer .k-button-group .k-button:first-child{text-align:right}[dir=ltr] .k-dialog-footer .k-button-group .k-button:first-child{padding-left:1.5rem}[dir=rtl] .k-dialog-footer .k-button-group .k-button:first-child{padding-right:1.5rem}[dir=ltr] .k-dialog-footer .k-button-group .k-button:last-child{text-align:right}[dir=rtl] .k-dialog-footer .k-button-group .k-button:last-child{text-align:left}[dir=ltr] .k-dialog-footer .k-button-group .k-button:last-child{padding-right:1.5rem}[dir=rtl] .k-dialog-footer .k-button-group .k-button:last-child{padding-left:1.5rem}.k-dialog .k-pagination{margin-bottom:-1.5rem;display:flex;justify-content:center;align-items:center}.k-dialog-search{margin-bottom:.75rem}.k-dialog-search.k-input{background:rgba(0,0,0,.075);padding:0 1rem;height:36px;border-radius:var(--rounded)}.k-error-details{background:var(--color-white);display:block;overflow:auto;padding:1rem;font-size:var(--text-sm);line-height:1.25em;margin-top:.75rem}.k-error-details dt{color:var(--color-negative-light);margin-bottom:.25rem}.k-error-details dd{overflow:hidden;overflow-wrap:break-word;text-overflow:ellipsis}.k-error-details dd:not(:last-of-type){margin-bottom:1.5em}.k-error-details li{white-space:pre-line}.k-error-details li:not(:last-child){border-bottom:1px solid var(--color-background);padding-bottom:.25rem;margin-bottom:.25rem}.k-files-dialog .k-list-item{cursor:pointer}[dir=ltr] .k-pages-dialog-navbar{padding-right:38px}[dir=rtl] .k-pages-dialog-navbar{padding-left:38px}.k-pages-dialog-navbar{display:flex;align-items:center;justify-content:center;margin-bottom:.5rem}.k-pages-dialog-navbar .k-button{width:38px}.k-pages-dialog-navbar .k-button[disabled]{opacity:0}.k-pages-dialog-navbar .k-headline{flex-grow:1;text-align:center}.k-pages-dialog .k-list-item{cursor:pointer}.k-pages-dialog .k-list-item .k-button[data-theme=disabled],.k-pages-dialog .k-list-item .k-button[disabled]{opacity:.25}.k-pages-dialog .k-list-item .k-button[data-theme=disabled]:hover{opacity:1}.k-users-dialog .k-list-item{cursor:pointer}.k-drawer{--drawer-header-height:2.5rem;--drawer-header-padding:1.5rem;position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--z-toolbar);display:flex;align-items:stretch;justify-content:flex-end;background:rgba(0,0,0,.2)}.k-drawer-box{position:relative;flex-basis:50rem;display:flex;flex-direction:column;background:var(--color-background);box-shadow:var(--shadow-xl)}[dir=ltr] .k-drawer-header{padding-left:var(--drawer-header-padding)}[dir=rtl] .k-drawer-header{padding-right:var(--drawer-header-padding)}.k-drawer-header{flex-shrink:0;height:var(--drawer-header-height);display:flex;align-items:center;line-height:1;justify-content:space-between;background:var(--color-white);font-size:var(--text-sm)}.k-drawer-title{padding:0 .75rem}[dir=ltr] .k-drawer-breadcrumb,[dir=ltr] .k-drawer-title{margin-left:-.75rem}[dir=rtl] .k-drawer-breadcrumb,[dir=rtl] .k-drawer-title{margin-right:-.75rem}.k-drawer-breadcrumb,.k-drawer-title{display:flex;flex-grow:1;align-items:center;min-width:0;font-size:var(--text-sm);font-weight:var(--font-normal)}[dir=ltr] .k-drawer-breadcrumb li:not(:last-child) .k-button:after{right:-.75rem}[dir=rtl] .k-drawer-breadcrumb li:not(:last-child) .k-button:after{left:-.75rem}.k-drawer-breadcrumb li:not(:last-child) .k-button:after{position:absolute;width:1.5rem;display:inline-flex;justify-content:center;align-items:center;content:"\203a";color:var(--color-gray-500);height:var(--drawer-header-height)}[dir=ltr] .k-drawer-breadcrumb .k-icon,[dir=ltr] .k-drawer-title .k-icon{margin-right:.5rem}[dir=rtl] .k-drawer-breadcrumb .k-icon,[dir=rtl] .k-drawer-title .k-icon{margin-left:.5rem}.k-drawer-breadcrumb .k-icon,.k-drawer-title .k-icon{width:1rem;color:var(--color-gray-500)}.k-drawer-breadcrumb .k-button{display:inline-flex;align-items:center;height:var(--drawer-header-height);padding-left:.75rem;padding-right:.75rem}.k-drawer-breadcrumb .k-button-text{opacity:1}[dir=ltr] .k-drawer-breadcrumb .k-button .k-button-icon~.k-button-text{padding-left:0}[dir=rtl] .k-drawer-breadcrumb .k-button .k-button-icon~.k-button-text{padding-right:0}[dir=ltr] .k-drawer-tabs{margin-right:.75rem}[dir=rtl] .k-drawer-tabs{margin-left:.75rem}.k-drawer-tabs{display:flex;align-items:center;line-height:1}.k-drawer-tab.k-button{height:var(--drawer-header-height);padding-left:.75rem;padding-right:.75rem;display:flex;align-items:center;font-size:var(--text-xs)}.k-drawer-tab.k-button[aria-current]:after{position:absolute;bottom:-1px;left:.75rem;right:.75rem;content:"";background:var(--color-black);height:2px}[dir=ltr] .k-drawer-options{padding-right:.75rem}[dir=rtl] .k-drawer-options{padding-left:.75rem}.k-drawer-option.k-button{width:var(--drawer-header-height);height:var(--drawer-header-height);color:var(--color-gray-500);line-height:1}.k-drawer-option.k-button:focus,.k-drawer-option.k-button:hover{color:var(--color-black)}.k-drawer-body{padding:1.5rem;flex-grow:1;background:var(--color-background)}.k-drawer[data-nested=true]{background:0 0}.k-drawer-body .k-table th,.k-drawer-body .k-textarea-input:focus-within .k-toolbar{top:-1.5rem}.k-calendar-input{--cell-padding:.25rem .5rem;padding:.5rem;color:var(--color-light);border-radius:var(--rounded-xs)}.k-calendar-table{table-layout:fixed;width:100%;min-width:15rem;padding-top:.5rem}.k-calendar-input>nav{display:flex;direction:ltr}.k-calendar-input>nav .k-button{padding:.5rem}.k-calendar-selects{flex-grow:1;display:flex;align-items:center;justify-content:center}[dir=ltr] .k-calendar-selects{direction:ltr}[dir=rtl] .k-calendar-selects{direction:rtl}.k-calendar-selects .k-select-input{padding:0 .5rem;font-weight:var(--font-normal);font-size:var(--text-sm)}.k-calendar-selects .k-select-input:focus-within{color:var(--color-focus-light)!important}.k-calendar-input th{padding:.5rem 0;color:var(--color-gray-500);font-size:var(--text-xs);font-weight:400;text-align:center}.k-calendar-day .k-button{width:2rem;height:2rem;margin-left:auto;margin-right:auto;color:var(--color-white);line-height:1.75rem;display:flex;justify-content:center;border-radius:50%;border:2px solid transparent}.k-calendar-day .k-button .k-button-text{opacity:1}.k-calendar-table .k-button:hover{color:var(--color-white)}.k-calendar-day:hover .k-button:not([data-disabled=true]){border-color:#ffffff40}.k-calendar-day[aria-current=date] .k-button{text-decoration:underline}.k-calendar-day[aria-selected=date] .k-button{border-color:currentColor;font-weight:600;color:var(--color-focus-light)}.k-calendar-today{text-align:center;padding-top:.5rem}.k-calendar-today .k-button{font-size:var(--text-xs);padding:1rem;text-decoration:underline}.k-calendar-today .k-button-text{opacity:1;vertical-align:baseline}.k-counter{font-size:var(--text-xs);color:var(--color-gray-900);font-weight:var(--font-bold)}.k-counter[data-invalid=true]{box-shadow:none;border:0;color:var(--color-negative)}[dir=ltr] .k-counter-rules{padding-left:.5rem}[dir=rtl] .k-counter-rules{padding-right:.5rem}.k-counter-rules{color:var(--color-gray-600);font-weight:var(--font-normal)}.k-form-submitter{display:none}.k-form-buttons[data-theme]{background:var(--theme-light)}.k-form-buttons .k-view{display:flex;justify-content:space-between;align-items:center}.k-form-button.k-button{font-weight:500;white-space:nowrap;line-height:1;height:2.5rem;display:flex;padding:0 1rem;align-items:center}[dir=ltr] .k-form-button:first-child{margin-left:-1rem}[dir=rtl] .k-form-button:first-child{margin-right:-1rem}[dir=ltr] .k-form-button:last-child{margin-right:-1rem}[dir=rtl] .k-form-button:last-child{margin-left:-1rem}[dir=ltr] .k-form-lock-info{margin-right:3rem}[dir=rtl] .k-form-lock-info{margin-left:3rem}.k-form-lock-info{display:flex;font-size:var(--text-sm);align-items:center;line-height:1.5em;padding:.625rem 0}[dir=ltr] .k-form-lock-info>.k-icon{margin-right:.5rem}[dir=rtl] .k-form-lock-info>.k-icon{margin-left:.5rem}.k-form-lock-buttons{display:flex;flex-shrink:0}.k-form-lock-loader{animation:Spin 4s linear infinite}.k-form-lock-loader .k-icon-loader{display:flex}.k-form-indicator-toggle{color:var(--color-notice-light)}.k-form-indicator-info{font-size:var(--text-sm);font-weight:var(--font-bold);padding:.75rem 1rem .25rem;line-height:1.25em;width:15rem}.k-field-label{font-weight:var(--font-bold);display:block;padding:0 0 .75rem;flex-grow:1;line-height:1.25rem}[dir=ltr] .k-field-label abbr{padding-left:.25rem}[dir=rtl] .k-field-label abbr{padding-right:.25rem}.k-field-label abbr{text-decoration:none;color:var(--color-gray-500)}.k-field-header{position:relative;display:flex;align-items:baseline}[dir=ltr] .k-field-options{right:0}[dir=rtl] .k-field-options{left:0}.k-field-options{position:absolute;top:calc(-.5rem - 1px)}.k-field-options.k-button-group .k-dropdown{height:auto}.k-field-options.k-button-group .k-field-options-button.k-button{padding:.75rem;display:flex}.k-field[data-disabled=true]{cursor:not-allowed}.k-field[data-disabled=true] *{pointer-events:none}.k-field[data-disabled=true] .k-text[data-theme=help] *{pointer-events:initial}.k-field:focus-within>.k-field-header>.k-field-counter{display:block}.k-field-help{padding-top:.5rem}.k-field-add-item-button{display:flex;align-items:center;width:100%;color:var(--color-gray-500);justify-content:center;padding:.75rem 0}.k-field-add-item-button:hover{color:var(--color-black)}.k-fieldset{border:0}.k-fieldset .k-grid{grid-row-gap:2.25rem}@media screen and (min-width:30em){.k-fieldset .k-grid{grid-column-gap:1.5rem}}.k-sections>.k-column[data-width="1/3"] .k-fieldset .k-grid,.k-sections>.k-column[data-width="1/4"] .k-fieldset .k-grid{grid-template-columns:repeat(1,1fr)}.k-sections>.k-column[data-width="1/3"] .k-fieldset .k-grid .k-column,.k-sections>.k-column[data-width="1/4"] .k-fieldset .k-grid .k-column{grid-column-start:initial}.k-input{display:flex;align-items:center;line-height:1;border:0;outline:0;background:0 0}.k-input-element{flex-grow:1}.k-input-icon{display:flex;justify-content:center;align-items:center;line-height:0}.k-input[data-disabled=true]{pointer-events:none}[data-disabled=true] .k-input-icon{color:var(--color-gray-600)}.k-input[data-theme=field]{line-height:1;border:var(--field-input-border);background:var(--field-input-background);border-radius:var(--rounded)}.k-input[data-theme=field]:focus-within{border:var(--field-input-focus-border);box-shadow:var(--color-focus-outline) 0 0 0 2px}.k-input[data-theme=field][data-disabled=true]{background:var(--color-background)}.k-input[data-theme=field] .k-input-icon{width:var(--field-input-height);align-self:stretch;display:flex;align-items:center;flex-shrink:0}.k-input[data-theme=field] .k-input-after,.k-input[data-theme=field] .k-input-before{align-self:stretch;display:flex;align-items:center;flex-shrink:0;padding:0 var(--field-input-padding)}[dir=ltr] .k-input[data-theme=field] .k-input-before{padding-right:0}[dir=ltr] .k-input[data-theme=field] .k-input-after,[dir=rtl] .k-input[data-theme=field] .k-input-before{padding-left:0}.k-input[data-theme=field] .k-input-before{color:var(--field-input-color-before)}[dir=rtl] .k-input[data-theme=field] .k-input-after{padding-right:0}.k-input[data-theme=field] .k-input-after{color:var(--field-input-color-after)}.k-input[data-theme=field] .k-input-icon>.k-dropdown{width:100%;height:100%}.k-input[data-theme=field] .k-input-icon-button{width:100%;height:100%;display:flex;align-items:center;justify-content:center;flex-shrink:0}.k-input[data-theme=field] .k-number-input,.k-input[data-theme=field] .k-select-input,.k-input[data-theme=field] .k-text-input{padding:var(--field-input-padding);line-height:var(--field-input-line-height);border-radius:var(--rounded)}.k-input[data-theme=field] .k-date-input .k-select-input,.k-input[data-theme=field] .k-time-input .k-select-input{padding-left:0;padding-right:0}[dir=ltr] .k-input[data-theme=field] .k-date-input .k-select-input:first-child,[dir=ltr] .k-input[data-theme=field] .k-time-input .k-select-input:first-child{padding-left:var(--field-input-padding)}[dir=rtl] .k-input[data-theme=field] .k-date-input .k-select-input:first-child,[dir=rtl] .k-input[data-theme=field] .k-time-input .k-select-input:first-child{padding-right:var(--field-input-padding)}.k-input[data-theme=field] .k-date-input .k-select-input:focus-within,.k-input[data-theme=field] .k-time-input .k-select-input:focus-within{color:var(--color-focus);font-weight:var(--font-bold)}[dir=ltr] .k-input[data-theme=field].k-time-input .k-time-input-meridiem{padding-left:var(--field-input-padding)}[dir=rtl] .k-input[data-theme=field].k-time-input .k-time-input-meridiem{padding-right:var(--field-input-padding)}.k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input li,.k-input[data-theme=field][data-type=checkboxes] .k-radio-input li,.k-input[data-theme=field][data-type=radio] .k-checkboxes-input li,.k-input[data-theme=field][data-type=radio] .k-radio-input li{min-width:0;overflow-wrap:break-word}[dir=ltr] .k-input[data-theme=field][data-type=checkboxes] .k-input-before{border-right:1px solid var(--color-background)}[dir=ltr] .k-input[data-theme=field][data-type=checkboxes] .k-input-element+.k-input-after,[dir=ltr] .k-input[data-theme=field][data-type=checkboxes] .k-input-element+.k-input-icon,[dir=rtl] .k-input[data-theme=field][data-type=checkboxes] .k-input-before{border-left:1px solid var(--color-background)}[dir=ltr] .k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input li,[dir=rtl] .k-input[data-theme=field][data-type=checkboxes] .k-input-element+.k-input-after,[dir=rtl] .k-input[data-theme=field][data-type=checkboxes] .k-input-element+.k-input-icon{border-right:1px solid var(--color-background)}.k-input[data-theme=field][data-type=checkboxes] .k-input-element{overflow:hidden}[dir=ltr] .k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input{margin-right:-1px}[dir=rtl] .k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input{margin-left:-1px}.k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input{display:grid;grid-template-columns:1fr;margin-bottom:-1px}@media screen and (min-width:65em){.k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input{grid-template-columns:repeat(var(--columns),1fr)}}[dir=rtl] .k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input li{border-left:1px solid var(--color-background)}.k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input li,.k-input[data-theme=field][data-type=radio] .k-radio-input li{border-bottom:1px solid var(--color-background)}.k-input[data-theme=field][data-type=checkboxes] .k-checkboxes-input label{display:block;line-height:var(--field-input-line-height);padding:var(--field-input-padding) var(--field-input-padding)}[dir=ltr] .k-input[data-theme=field][data-type=checkboxes] .k-checkbox-input-icon,[dir=ltr] .k-input[data-theme=field][data-type=radio] .k-radio-input label:before{left:var(--field-input-padding)}[dir=rtl] .k-input[data-theme=field][data-type=checkboxes] .k-checkbox-input-icon,[dir=rtl] .k-input[data-theme=field][data-type=radio] .k-radio-input label:before{right:var(--field-input-padding)}.k-input[data-theme=field][data-type=checkboxes] .k-checkbox-input-icon{top:calc((var(--field-input-height) - var(--field-input-font-size))/2);margin-top:0}[dir=ltr] .k-input[data-theme=field][data-type=radio] .k-input-before{border-right:1px solid var(--color-background)}[dir=ltr] .k-input[data-theme=field][data-type=radio] .k-input-element+.k-input-after,[dir=ltr] .k-input[data-theme=field][data-type=radio] .k-input-element+.k-input-icon,[dir=rtl] .k-input[data-theme=field][data-type=radio] .k-input-before{border-left:1px solid var(--color-background)}[dir=ltr] .k-input[data-theme=field][data-type=radio] .k-radio-input li,[dir=rtl] .k-input[data-theme=field][data-type=radio] .k-input-element+.k-input-after,[dir=rtl] .k-input[data-theme=field][data-type=radio] .k-input-element+.k-input-icon{border-right:1px solid var(--color-background)}.k-input[data-theme=field][data-type=radio] .k-input-element{overflow:hidden}[dir=ltr] .k-input[data-theme=field][data-type=radio] .k-radio-input{margin-right:-1px}[dir=rtl] .k-input[data-theme=field][data-type=radio] .k-radio-input{margin-left:-1px}.k-input[data-theme=field][data-type=radio] .k-radio-input{display:grid;grid-template-columns:1fr;margin-bottom:-1px}@media screen and (min-width:65em){.k-input[data-theme=field][data-type=radio] .k-radio-input{grid-template-columns:repeat(var(--columns),1fr)}}[dir=rtl] .k-input[data-theme=field][data-type=radio] .k-radio-input li{border-left:1px solid var(--color-background)}.k-input[data-theme=field][data-type=radio] .k-radio-input label{display:block;flex-grow:1;min-height:var(--field-input-height);line-height:var(--field-input-line-height);padding:calc((var(--field-input-height) - var(--field-input-line-height))/2) var(--field-input-padding)}.k-input[data-theme=field][data-type=radio] .k-radio-input label:before{top:calc((var(--field-input-height) - 1rem)/2);margin-top:-1px}.k-input[data-theme=field][data-type=radio] .k-radio-input .k-radio-input-info{display:block;font-size:var(--text-sm);color:var(--color-gray-600);line-height:var(--field-input-line-height);padding-top:calc(var(--field-input-line-height)/10)}.k-input[data-theme=field][data-type=radio] .k-radio-input .k-icon{width:var(--field-input-height);height:var(--field-input-height);display:flex;align-items:center;justify-content:center}.k-input[data-theme=field][data-type=range] .k-range-input{padding:var(--field-input-padding)}.k-input[data-theme=field][data-type=multiselect],.k-input[data-theme=field][data-type=select]{position:relative}[dir=ltr] .k-input[data-theme=field][data-type=select] .k-input-icon{right:0}[dir=rtl] .k-input[data-theme=field][data-type=select] .k-input-icon{left:0}.k-input[data-theme=field][data-type=select] .k-input-icon{position:absolute;top:0;bottom:0}.k-input[data-theme=field][data-type=tags] .k-tags-input{padding:.25rem .25rem 0}[dir=ltr] .k-input[data-theme=field][data-type=tags] .k-tag{margin-right:.25rem}[dir=rtl] .k-input[data-theme=field][data-type=tags] .k-tag{margin-left:.25rem}.k-input[data-theme=field][data-type=tags] .k-tag{margin-bottom:.25rem;height:auto;min-height:1.75rem;font-size:var(--text-sm)}.k-input[data-theme=field][data-type=tags] .k-tags-input input{font-size:var(--text-sm);padding:0 .25rem;height:1.75rem;line-height:1;margin-bottom:.25rem}.k-input[data-theme=field][data-type=tags] .k-tags-input .k-dropdown-content{top:calc(100% + .5rem + 2px)}.k-input[data-theme=field][data-type=tags] .k-tags-input .k-dropdown-content[data-dropup]{top:calc(100% + .5rem + 2px);bottom:initial;margin-bottom:initial}.k-input[data-theme=field][data-type=multiselect] .k-multiselect-input{padding:.25rem 2rem 0 .25rem;min-height:2.25rem}[dir=ltr] .k-input[data-theme=field][data-type=multiselect] .k-tag{margin-right:.25rem}[dir=rtl] .k-input[data-theme=field][data-type=multiselect] .k-tag{margin-left:.25rem}.k-input[data-theme=field][data-type=multiselect] .k-tag{margin-bottom:.25rem;height:1.75rem;font-size:var(--text-sm)}[dir=ltr] .k-input[data-theme=field][data-type=multiselect] .k-input-icon{right:0}[dir=rtl] .k-input[data-theme=field][data-type=multiselect] .k-input-icon{left:0}.k-input[data-theme=field][data-type=multiselect] .k-input-icon{position:absolute;top:0;bottom:0;pointer-events:none}.k-input[data-theme=field][data-type=textarea] .k-textarea-input-native{padding:.25rem var(--field-input-padding);line-height:1.5rem}[dir=ltr] .k-input[data-theme=field][data-type=toggle] .k-input-before{padding-right:calc(var(--field-input-padding)/2)}[dir=rtl] .k-input[data-theme=field][data-type=toggle] .k-input-before{padding-left:calc(var(--field-input-padding)/2)}[dir=ltr] .k-input[data-theme=field][data-type=toggle] .k-toggle-input{padding-left:var(--field-input-padding)}[dir=rtl] .k-input[data-theme=field][data-type=toggle] .k-toggle-input{padding-right:var(--field-input-padding)}.k-input[data-theme=field][data-type=toggle] .k-toggle-input-label{padding:0 var(--field-input-padding)0 .75rem;line-height:var(--field-input-height)}.k-login-code-form .k-user-info{height:38px;margin-bottom:2.25rem;padding:.5rem;background:var(--color-white);border-radius:var(--rounded-xs);box-shadow:var(--shadow)}.k-times{padding:var(--spacing-4) var(--spacing-6);display:grid;line-height:1;grid-template-columns:1fr 1fr;grid-gap:var(--spacing-6)}.k-times .k-icon{width:1rem;margin-bottom:var(--spacing-2)}.k-times-slot .k-button{padding:var(--spacing-1) var(--spacing-3) var(--spacing-1)0;font-variant-numeric:tabular-nums;white-space:nowrap}.k-times .k-times-slot hr{position:relative;opacity:1;margin:var(--spacing-2)0;border:0;height:1px;top:1px;background:var(--color-dark)}[dir=ltr] .k-upload input{left:-3000px}[dir=rtl] .k-upload input{right:-3000px}.k-upload input{position:absolute;top:0}.k-upload-dialog .k-headline{margin-bottom:.75rem}.k-upload-error-list,.k-upload-list{line-height:1.5em;font-size:var(--text-sm)}.k-upload-list-filename{color:var(--color-gray-600)}.k-upload-error-list li{padding:.75rem;background:var(--color-white);border-radius:var(--rounded-xs)}.k-upload-error-list li:not(:last-child){margin-bottom:2px}.k-upload-error-filename{color:var(--color-negative);font-weight:var(--font-bold)}.k-upload-error-message{color:var(--color-gray-600)}.k-writer-toolbar{position:absolute;display:flex;background:var(--color-black);height:30px;transform:translate(-50%) translateY(-.75rem);z-index:calc(var(--z-dropdown) + 1);box-shadow:var(--shadow);color:var(--color-white);border-radius:var(--rounded)}.k-writer-toolbar-button.k-button{display:flex;align-items:center;justify-content:center;height:30px;width:30px;font-size:var(--text-sm)!important;color:currentColor;line-height:1}.k-writer-toolbar-button.k-button:hover{background:rgba(255,255,255,.15)}.k-writer-toolbar-button.k-writer-toolbar-button-active{color:var(--color-blue-300)}.k-writer-toolbar-button.k-writer-toolbar-nodes{width:auto;padding:0 .75rem}[dir=ltr] .k-writer-toolbar .k-dropdown+.k-writer-toolbar-button{border-left:1px solid var(--color-gray-700)}[dir=rtl] .k-writer-toolbar .k-dropdown+.k-writer-toolbar-button{border-right:1px solid var(--color-gray-700)}[dir=ltr] .k-writer-toolbar-button.k-writer-toolbar-nodes:after{margin-left:.5rem}[dir=rtl] .k-writer-toolbar-button.k-writer-toolbar-nodes:after{margin-right:.5rem}.k-writer-toolbar-button.k-writer-toolbar-nodes:after{content:"";border-top:4px solid var(--color-white);border-left:4px solid transparent;border-right:4px solid transparent}.k-writer-toolbar .k-dropdown-content{color:var(--color-black);background:var(--color-white);margin-top:.5rem}.k-writer-toolbar .k-dropdown-content .k-dropdown-item[aria-current]{color:var(--color-focus);font-weight:500}.k-writer{position:relative;width:100%;grid-template-areas:"content";display:grid}.k-writer .ProseMirror{overflow-wrap:break-word;word-wrap:break-word;word-break:break-word;white-space:pre-wrap;font-variant-ligatures:none;line-height:inherit;grid-area:content}.k-writer .ProseMirror:focus{outline:0}.k-writer .ProseMirror *{caret-color:currentColor}.k-writer .ProseMirror a{color:var(--color-focus);text-decoration:underline}.k-writer .ProseMirror>:last-child{margin-bottom:0}.k-writer .ProseMirror h1,.k-writer .ProseMirror h2,.k-writer .ProseMirror h3,.k-writer .ProseMirror ol,.k-writer .ProseMirror p,.k-writer .ProseMirror ul{margin-bottom:.75rem}.k-writer .ProseMirror h1{font-size:var(--text-3xl);line-height:1.25em}.k-writer .ProseMirror h2{font-size:var(--text-2xl);line-height:1.25em}.k-writer .ProseMirror h3{font-size:var(--text-xl);line-height:1.25em}.k-writer .ProseMirror h1 strong,.k-writer .ProseMirror h2 strong,.k-writer .ProseMirror h3 strong{font-weight:700}.k-writer .ProseMirror strong{font-weight:600}.k-writer .ProseMirror code{position:relative;font-size:.925em;display:inline-block;line-height:1.325;padding:.05em .325em;background:var(--color-gray-300);border-radius:var(--rounded)}[dir=ltr] .k-writer .ProseMirror ol,[dir=ltr] .k-writer .ProseMirror ul{padding-left:1.75rem}[dir=rtl] .k-writer .ProseMirror ol,[dir=rtl] .k-writer .ProseMirror ul{padding-right:1.75rem}.k-writer .ProseMirror ul>li{list-style:disc}.k-writer .ProseMirror ul ul>li{list-style:circle}.k-writer .ProseMirror ul ul ul>li{list-style:square}.k-writer .ProseMirror ol>li{list-style:decimal}.k-writer .ProseMirror li>ol,.k-writer .ProseMirror li>p,.k-writer .ProseMirror li>ul{margin:0}.k-writer-code pre{-moz-tab-size:2;-o-tab-size:2;tab-size:2;font-size:var(--text-sm);line-height:2em;overflow-x:auto;overflow-y:hidden;-webkit-overflow-scrolling:touch;white-space:pre}.k-writer .ProseMirror code,.k-writer-code code{font-family:var(--font-mono)}.k-writer[data-placeholder][data-empty=true]:before{grid-area:content;content:attr(data-placeholder);line-height:inherit;color:var(--color-gray-500);pointer-events:none;white-space:pre-wrap;word-wrap:break-word}.k-login-alert{padding:.5rem .75rem;display:flex;justify-content:space-between;align-items:center;min-height:38px;margin-bottom:2rem;background:var(--color-negative);color:var(--color-white);font-size:var(--text-sm);border-radius:var(--rounded-xs);box-shadow:var(--shadow-lg);cursor:pointer}.k-structure-backdrop{position:absolute;top:0;right:0;bottom:0;left:0;z-index:2;height:100vh}.k-structure-form section{position:relative;z-index:3;border-radius:var(--rounded-xs);margin-bottom:1px;box-shadow:#1111110d 0 0 0 3px;border:1px solid var(--color-border);background:var(--color-background)}.k-structure-form-fields{padding:1.5rem 1.5rem 2rem}.k-structure-form-buttons{border-top:1px solid var(--color-border);display:flex;justify-content:space-between}.k-structure-form-buttons .k-pagination{display:none}@media screen and (min-width:65em){.k-structure-form-buttons .k-pagination{display:flex}}.k-structure-form-buttons .k-pagination>.k-button,.k-structure-form-buttons .k-pagination>span{padding:.875rem 1rem!important}.k-structure-form-cancel-button,.k-structure-form-submit-button{padding:.875rem 1.5rem;line-height:1rem;display:flex}[dir=ltr] .k-toolbar,[dir=rtl] .k-toolbar{border-top-right-radius:var(--rounded);border-top-left-radius:var(--rounded)}.k-toolbar{background:var(--color-white);border-bottom:1px solid var(--color-background);height:38px}.k-toolbar-wrapper{position:absolute;top:0;left:0;right:0;max-width:100%}.k-toolbar-buttons{display:flex}.k-toolbar-divider{width:1px;background:var(--color-background)}.k-toolbar-button{width:36px;height:36px}.k-toolbar-button:hover{background:rgba(239,239,239,.5)}.k-checkbox-input{position:relative;cursor:pointer}[dir=ltr] .k-checkbox-input-label{padding-left:1.75rem}[dir=rtl] .k-checkbox-input-label{padding-right:1.75rem}.k-checkbox-input-label{display:block}[dir=ltr] .k-checkbox-input-icon{left:0}[dir=rtl] .k-checkbox-input-icon{right:0}.k-checkbox-input-icon{position:absolute;width:1rem;height:1rem;border-radius:var(--rounded);border:2px solid var(--color-gray-500)}.k-checkbox-input-icon svg{position:absolute;width:12px;height:12px;display:none}.k-checkbox-input-icon path{stroke:var(--color-white)}.k-checkbox-input-native:checked+.k-checkbox-input-icon{border-color:var(--color-gray-900);background:var(--color-gray-900)}[data-disabled=true] .k-checkbox-input-native:checked+.k-checkbox-input-icon{border-color:var(--color-gray-600);background:var(--color-gray-600)}.k-checkbox-input-native:checked+.k-checkbox-input-icon svg{display:block}.k-checkbox-input-native:focus+.k-checkbox-input-icon{border-color:var(--color-blue-600)}.k-checkbox-input-native:focus:checked+.k-checkbox-input-icon{background:var(--color-focus)}.k-text-input{width:100%;border:0;background:0 0;font:inherit;color:inherit;font-variant-numeric:tabular-nums}.k-text-input::-moz-placeholder{color:var(--color-gray-500)}.k-text-input::placeholder{color:var(--color-gray-500)}.k-text-input:focus{outline:0}.k-text-input:invalid{box-shadow:none;outline:0}.k-list-input .ProseMirror{line-height:1.5em}.k-list-input .ProseMirror ol>li::marker{font-size:var(--text-sm);color:var(--color-gray-500)}.k-multiselect-input{display:flex;flex-wrap:wrap;position:relative;font-size:var(--text-sm);min-height:2.25rem;line-height:1}.k-multiselect-input .k-sortable-ghost{background:var(--color-focus)}.k-multiselect-input .k-tag{border-radius:var(--rounded-sm)}.k-multiselect-input .k-dropdown-content,.k-multiselect-input[data-layout=list] .k-tag{width:100%}.k-multiselect-search{margin-top:0!important;color:var(--color-white);background:var(--color-gray-900);border-bottom:1px dashed rgba(255,255,255,.2)}.k-multiselect-search>.k-button-text{flex:1;opacity:1!important}.k-multiselect-search input{width:100%;color:var(--color-white);background:0 0;border:0;outline:0;padding:.25rem 0;font:inherit}.k-multiselect-options{position:relative;max-height:275px;padding:.5rem 0}.k-multiselect-option{position:relative}.k-multiselect-option.selected{color:var(--color-positive-light)}.k-multiselect-option.disabled:not(.selected) .k-icon{opacity:0}.k-multiselect-option b{color:var(--color-focus-light);font-weight:700}[dir=ltr] .k-multiselect-input[data-layout=list] .k-tag{margin-right:0!important}[dir=rtl] .k-multiselect-input[data-layout=list] .k-tag{margin-left:0!important}.k-multiselect-more{width:100%;padding:.75rem;color:#fffc;text-align:center;border-top:1px dashed rgba(255,255,255,.2)}.k-multiselect-more:hover{color:var(--color-white)}.k-number-input{width:100%;border:0;background:0 0;font:inherit;color:inherit}.k-number-input::-moz-placeholder{color:var(--color-gray-500)}.k-number-input::placeholder{color:var(--color-gray-500)}.k-number-input:focus{outline:0}.k-number-input:invalid{box-shadow:none;outline:0}[dir=ltr] .k-radio-input li{padding-left:1.75rem}[dir=rtl] .k-radio-input li{padding-right:1.75rem}.k-radio-input li{position:relative;line-height:1.5rem}.k-radio-input input{position:absolute;width:0;height:0;-webkit-appearance:none;-moz-appearance:none;appearance:none;opacity:0}.k-radio-input label{cursor:pointer;align-items:center}[dir=ltr] .k-radio-input label:before{left:0}[dir=rtl] .k-radio-input label:before{right:0}.k-radio-input label:before{position:absolute;top:.175em;content:"";width:1rem;height:1rem;border-radius:50%;border:2px solid var(--color-gray-500);box-shadow:var(--color-white) 0 0 0 2px inset}.k-radio-input input:checked+label:before{border-color:var(--color-gray-900);background:var(--color-gray-900)}[data-disabled=true] .k-radio-input input:checked+label:before{border-color:var(--color-gray-600);background:var(--color-gray-600)}.k-radio-input input:focus+label:before{border-color:var(--color-blue-600)}.k-radio-input input:focus:checked+label:before{background:var(--color-focus)}.k-radio-input-text{display:block}.k-range-input{--range-thumb-size:16px;--range-thumb-border:4px solid var(--color-gray-900);--range-thumb-border-disabled:4px solid var(--color-gray-600);--range-thumb-background:var(--color-background);--range-thumb-focus-border:4px solid var(--color-focus);--range-thumb-focus-background:var(--color-background);--range-track-height:4px;--range-track-background:var(--color-border);--range-track-color:var(--color-gray-900);--range-track-color-disabled:var(--color-gray-600);--range-track-focus-color:var(--color-focus);display:flex;align-items:center}.k-range-input-native{--min:0;--max:100;--value:0;--range:calc(var(--max) - var(--min));--ratio:calc((var(--value) - var(--min)) / var(--range));--position:calc( .5 * var(--range-thumb-size) + var(--ratio) * calc(100% - var(--range-thumb-size)) );-webkit-appearance:none;-moz-appearance:none;appearance:none;width:100%;height:var(--range-thumb-size);background:0 0;font-size:var(--text-sm);line-height:1}.k-range-input-native::-webkit-slider-thumb{-webkit-appearance:none;appearance:none}.k-range-input-native::-webkit-slider-runnable-track{border:0;border-radius:var(--range-track-height);width:100%;height:var(--range-track-height);background:var(--range-track-background)}.k-range-input-native::-moz-range-track{border:0;border-radius:var(--range-track-height);width:100%;height:var(--range-track-height);background:var(--range-track-background)}.k-range-input-native::-ms-track{border:0;border-radius:var(--range-track-height);width:100%;height:var(--range-track-height);background:var(--range-track-background)}.k-range-input-native::-webkit-slider-runnable-track{background:linear-gradient(var(--range-track-color),var(--range-track-color))0/var(--position) 100%no-repeat var(--range-track-background)}.k-range-input-native::-moz-range-progress{height:var(--range-track-height);background:var(--range-track-color)}.k-range-input-native::-ms-fill-lower{height:var(--range-track-height);background:var(--range-track-color)}.k-range-input-native::-webkit-slider-thumb{margin-top:calc(.5*(var(--range-track-height) - var(--range-thumb-size)));box-sizing:border-box;width:var(--range-thumb-size);height:var(--range-thumb-size);background:var(--range-thumb-background);border:var(--range-thumb-border);border-radius:50%;cursor:pointer}.k-range-input-native::-moz-range-thumb{box-sizing:border-box;width:var(--range-thumb-size);height:var(--range-thumb-size);background:var(--range-thumb-background);border:var(--range-thumb-border);border-radius:50%;cursor:pointer}.k-range-input-native::-ms-thumb{box-sizing:border-box;width:var(--range-thumb-size);height:var(--range-thumb-size);background:var(--range-thumb-background);border:var(--range-thumb-border);border-radius:50%;cursor:pointer;margin-top:0}.k-range-input-native::-ms-tooltip{display:none}.k-range-input-native:focus{outline:0}.k-range-input-native:focus::-webkit-slider-runnable-track{border:0;border-radius:var(--range-track-height);width:100%;height:var(--range-track-height);background:var(--range-track-background);background:linear-gradient(var(--range-track-focus-color),var(--range-track-focus-color))0/var(--position) 100%no-repeat var(--range-track-background)}.k-range-input-native:focus::-moz-range-progress{height:var(--range-track-height);background:var(--range-track-focus-color)}.k-range-input-native:focus::-ms-fill-lower{height:var(--range-track-height);background:var(--range-track-focus-color)}.k-range-input-native:focus::-webkit-slider-thumb{background:var(--range-thumb-focus-background);border:var(--range-thumb-focus-border)}.k-range-input-native:focus::-moz-range-thumb{background:var(--range-thumb-focus-background);border:var(--range-thumb-focus-border)}.k-range-input-native:focus::-ms-thumb{background:var(--range-thumb-focus-background);border:var(--range-thumb-focus-border)}[dir=ltr] .k-range-input-tooltip{margin-left:1rem}[dir=rtl] .k-range-input-tooltip{margin-right:1rem}.k-range-input-tooltip{position:relative;max-width:20%;display:flex;align-items:center;color:var(--color-white);font-size:var(--text-xs);line-height:1;text-align:center;border-radius:var(--rounded-xs);background:var(--color-gray-900);padding:0 .25rem;white-space:nowrap}[dir=ltr] .k-range-input-tooltip:after{left:-5px}[dir=rtl] .k-range-input-tooltip:after{right:-5px}[dir=ltr] .k-range-input-tooltip:after{border-right:5px solid var(--color-gray-900)}[dir=rtl] .k-range-input-tooltip:after{border-left:5px solid var(--color-gray-900)}.k-range-input-tooltip:after{position:absolute;top:50%;width:0;height:0;transform:translateY(-50%);border-top:5px solid transparent;border-bottom:5px solid transparent;content:""}.k-range-input-tooltip>*{padding:4px}[data-disabled=true] .k-range-input-native::-webkit-slider-runnable-track{background:linear-gradient(var(--range-track-color-disabled),var(--range-track-color-disabled))0/var(--position) 100%no-repeat var(--range-track-background)}[data-disabled=true] .k-range-input-native::-moz-range-progress{height:var(--range-track-height);background:var(--range-track-color-disabled)}[data-disabled=true] .k-range-input-native::-ms-fill-lower{height:var(--range-track-height);background:var(--range-track-color-disabled)}[data-disabled=true] .k-range-input-native::-webkit-slider-thumb{border:var(--range-thumb-border-disabled)}[data-disabled=true] .k-range-input-native::-moz-range-thumb{border:var(--range-thumb-border-disabled)}[data-disabled=true] .k-range-input-native::-ms-thumb{border:var(--range-thumb-border-disabled)}[data-disabled=true] .k-range-input-tooltip{background:var(--color-gray-600)}[dir=ltr] [data-disabled=true] .k-range-input-tooltip:after{border-right:5px solid var(--color-gray-600)}[dir=rtl] [data-disabled=true] .k-range-input-tooltip:after{border-left:5px solid var(--color-gray-600)}.k-select-input{position:relative;display:block;cursor:pointer;overflow:hidden}.k-select-input-native{position:absolute;top:0;right:0;bottom:0;left:0;opacity:0;width:100%;font:inherit;z-index:1;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none;font-weight:var(--font-normal)}.k-select-input-native[disabled]{cursor:default}.k-tags-input{display:flex;flex-wrap:wrap}.k-tags-input .k-tag{border-radius:var(--rounded-sm)}.k-tags-input .k-sortable-ghost{background:var(--color-focus)}.k-tags-input-element{flex-grow:1;flex-basis:0;min-width:0}.k-tags-input:focus-within .k-tags-input-element{flex-basis:4rem}.k-tags-input-element input{font:inherit;border:0;width:100%;background:0 0}.k-tags-input-element input:focus{outline:0}[dir=ltr] .k-tags-input[data-layout=list] .k-tag{margin-right:0!important}[dir=rtl] .k-tags-input[data-layout=list] .k-tag{margin-left:0!important}.k-tags-input[data-layout=list] .k-tag{width:100%}.k-textarea-input[data-size=small]{--size:7.5rem}.k-textarea-input[data-size=medium]{--size:15rem}.k-textarea-input[data-size=large]{--size:30rem}.k-textarea-input[data-size=huge]{--size:45rem}.k-textarea-input-wrapper{position:relative}.k-textarea-input-native{resize:none;border:0;width:100%;background:0 0;font:inherit;line-height:1.5em;color:inherit;min-height:var(--size)}.k-textarea-input-native::-moz-placeholder{color:var(--color-gray-500)}.k-textarea-input-native::placeholder{color:var(--color-gray-500)}.k-textarea-input-native:focus{outline:0}.k-textarea-input-native:invalid{box-shadow:none;outline:0}.k-textarea-input-native[data-font=monospace]{font-family:var(--font-mono)}.k-toolbar{margin-bottom:.25rem;color:#aaa}.k-textarea-input:focus-within .k-toolbar{position:sticky;top:0;left:0;right:0;z-index:1;box-shadow:#0000000d 0 2px 5px;border-bottom:1px solid rgba(0,0,0,.1);color:#000}.k-toggle-input{--toggle-background:var(--color-white);--toggle-color:var(--color-gray-500);--toggle-active-color:var(--color-gray-900);--toggle-focus-color:var(--color-focus);--toggle-height:16px;display:flex;align-items:center}.k-toggle-input-native{position:relative;height:var(--toggle-height);width:calc(var(--toggle-height)*2);border-radius:var(--toggle-height);border:2px solid var(--toggle-color);box-shadow:inset 0 0 0 2px var(--toggle-background),inset calc(var(--toggle-height)*-1) 0 0 2px var(--toggle-background);background-color:var(--toggle-color);outline:0;transition:all ease-in-out .1s;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;flex-shrink:0}.k-toggle-input-native:checked{border-color:var(--toggle-active-color);box-shadow:inset 0 0 0 2px var(--toggle-background),inset var(--toggle-height) 0 0 2px var(--toggle-background);background-color:var(--toggle-active-color)}.k-toggle-input-native[disabled]{border-color:var(--color-border);box-shadow:inset 0 0 0 2px var(--color-background),inset calc(var(--toggle-height)*-1) 0 0 2px var(--color-background);background-color:var(--color-border)}.k-toggle-input-native[disabled]:checked{box-shadow:inset 0 0 0 2px var(--color-background),inset var(--toggle-height) 0 0 2px var(--color-background)}.k-toggle-input-native:focus:checked{border:2px solid var(--color-focus);background-color:var(--toggle-focus-color)}.k-toggle-input-native::-ms-check{opacity:0}.k-toggle-input-label{cursor:pointer;flex-grow:1}.k-input[data-type=toggles]{display:inline-flex}.k-input[data-type=toggles].grow{display:flex}.k-toggles-input{display:grid;grid-template-columns:repeat(var(--options),minmax(0,1fr));gap:1px;border-radius:var(--rounded);line-height:1;background:var(--color-border);overflow:hidden}.k-toggles-input li{height:var(--field-input-height);background:var(--color-white)}.k-toggles-input label{align-items:center;background:var(--color-white);cursor:pointer;display:flex;font-size:var(--text-sm);justify-content:center;line-height:1.25;padding:0 var(--spacing-3);height:100%}[dir=ltr] .k-toggles-input .k-icon+.k-toggles-text{margin-left:var(--spacing-2)}[dir=rtl] .k-toggles-input .k-icon+.k-toggles-text{margin-right:var(--spacing-2)}.k-toggles-input input:focus:not(:checked)+label{background:var(--color-gray-200)}.k-toggles-input input:checked+label{background:var(--color-black);color:var(--color-white)}.k-blocks-field{position:relative}.k-date-field-body{display:flex;flex-wrap:wrap;line-height:1;border:var(--field-input-border);background:var(--color-gray-300);gap:1px;border-radius:var(--rounded);--multiplier:calc(25rem - 100%)}.k-date-field-body:focus-within{border:var(--field-input-focus-border);box-shadow:var(--color-focus-outline) 0 0 0 2px}.k-date-field[data-disabled] .k-date-field-body{background:0 0}.k-date-field-body>.k-input[data-theme=field]{border:0;box-shadow:none;border-radius:var(--rounded)}.k-date-field-body>.k-input[data-invalid=true],.k-date-field-body>.k-input[data-invalid=true]:focus-within{border:0!important;box-shadow:none!important}.k-date-field-body>*{flex-grow:1;flex-basis:calc(var(--multiplier)*999);max-width:100%}.k-date-field-body .k-input[data-type=date]{min-width:60%}.k-date-field-body .k-input[data-type=time]{min-width:30%}.k-files-field[data-disabled=true] .k-item *{pointer-events:all!important}body{counter-reset:headline-counter}.k-headline-field{position:relative;padding-top:1.5rem}.k-fieldset>.k-grid .k-column:first-child .k-headline-field{padding-top:0}[dir=ltr] .k-headline-field .k-headline[data-numbered]:before{padding-right:.25rem}[dir=rtl] .k-headline-field .k-headline[data-numbered]:before{padding-left:.25rem}.k-headline-field .k-headline[data-numbered]:before{counter-increment:headline-counter;content:counter(headline-counter,decimal-leading-zero);color:var(--color-focus);font-weight:400}.k-info-field .k-headline{padding-bottom:.75rem;line-height:1.25rem}.k-layout-column{position:relative;height:100%;display:flex;flex-direction:column;background:var(--color-white);min-height:6rem}.k-layout-column:focus{outline:0}.k-layout-column .k-blocks{background:0 0;box-shadow:none;padding:0;height:100%;background:var(--color-white);min-height:4rem}.k-layout-column .k-blocks[data-empty=true]{min-height:6rem}.k-layout-column .k-blocks-list{display:flex;flex-direction:column;height:100%}.k-layout-column .k-blocks .k-block-container:last-of-type{flex-grow:1}.k-layout-column .k-blocks-empty{position:absolute;top:0;right:0;bottom:0;left:0;justify-content:center;opacity:0;transition:opacity .3s;border:0}.k-layout-column .k-blocks-empty:hover{opacity:1}[dir=ltr] .k-layout-column .k-blocks-empty.k-empty .k-icon{border-right:0}[dir=rtl] .k-layout-column .k-blocks-empty.k-empty .k-icon{border-left:0}.k-layout-column .k-blocks-empty.k-empty .k-icon{width:1rem}[dir=ltr] .k-layout{padding-right:var(--layout-toolbar-width)}[dir=rtl] .k-layout{padding-left:var(--layout-toolbar-width)}.k-layout{--layout-border-color:var(--color-gray-300);--layout-toolbar-width:2rem;position:relative;background:#fff;box-shadow:var(--shadow)}[dir=ltr] [data-disabled=true] .k-layout{padding-right:0}[dir=rtl] [data-disabled=true] .k-layout{padding-left:0}.k-layout:not(:last-of-type){margin-bottom:1px}.k-layout:focus{outline:0}[dir=ltr] .k-layout-toolbar{right:0}[dir=rtl] .k-layout-toolbar{left:0}[dir=ltr] .k-layout-toolbar{border-left:1px solid var(--color-light)}[dir=rtl] .k-layout-toolbar{border-right:1px solid var(--color-light)}.k-layout-toolbar{position:absolute;top:0;bottom:0;width:var(--layout-toolbar-width);display:flex;flex-direction:column;font-size:var(--text-sm);background:var(--color-gray-100);color:var(--color-gray-500)}.k-layout-toolbar:hover{color:var(--color-black)}.k-layout-toolbar-button{width:var(--layout-toolbar-width);height:var(--layout-toolbar-width)}.k-layout-toolbar .k-sort-handle{margin-top:auto;color:currentColor}.k-layout-columns.k-grid{grid-gap:1px;background:var(--layout-border-color);background:var(--color-gray-300)}.k-layout:not(:first-child) .k-layout-columns.k-grid{border-top:0}.k-layouts .k-sortable-ghost{position:relative;box-shadow:#11111140 0 5px 10px;outline:2px solid var(--color-focus);cursor:grabbing;cursor:-webkit-grabbing;z-index:1}.k-layout-selector.k-dialog{background:#313740;color:var(--color-white)}.k-layout-selector .k-headline{line-height:1;margin-top:-.25rem;margin-bottom:1.5rem}.k-layout-selector ul{display:grid;grid-template-columns:repeat(3,1fr);grid-gap:1.5rem}.k-layout-selector-option .k-grid{height:5rem;grid-gap:2px;box-shadow:var(--shadow);cursor:pointer}.k-layout-selector-option:hover{outline:2px solid var(--color-green-300);outline-offset:2px}.k-layout-selector-option:last-child{margin-bottom:0}.k-layout-selector-option .k-column{display:flex;background:rgba(255,255,255,.2);justify-content:center;font-size:var(--text-xs);align-items:center}.k-line-field{position:relative;border:0;height:3rem;width:auto}.k-line-field:after{position:absolute;content:"";top:50%;margin-top:-1px;left:0;right:0;height:1px;background:var(--color-border)}.k-list-field .k-list-input{padding:.375rem .5rem .375rem .75rem}.k-table.k-object-field-table{table-layout:auto}.k-table.k-object-field-table tbody td,.k-table.k-object-field-table tbody th,.k-table.k-object-field-table tbody th button{cursor:pointer;overflow:hidden;text-overflow:ellipsis}.k-table.k-object-field-table tbody td{max-width:0}.k-pages-field[data-disabled=true] .k-item *{pointer-events:all!important}.k-structure-field:not([data-disabled=true]) td.k-table-column{cursor:pointer}.k-field-counter{display:none}.k-text-field:focus-within .k-field-counter{display:block}.k-users-field[data-disabled=true] .k-item *{pointer-events:all!important}.k-writer-field-input{line-height:1.5em;padding:.375rem .5rem}.k-aspect-ratio{position:relative;display:block;overflow:hidden;padding-bottom:100%}.k-aspect-ratio>*{position:absolute!important;top:0;right:0;bottom:0;left:0;height:100%;width:100%;-o-object-fit:contain;object-fit:contain}.k-aspect-ratio[data-cover=true]>*{-o-object-fit:cover;object-fit:cover}.k-bar{display:flex;align-items:center;justify-content:space-between;line-height:1}.k-bar-slot{flex-grow:1}.k-bar-slot[data-position=center]{text-align:center}[dir=ltr] .k-bar-slot[data-position=right]{text-align:right}[dir=rtl] .k-bar-slot[data-position=right]{text-align:left}.k-box{word-wrap:break-word;font-size:var(--text-sm)}.k-box:not([data-theme=none]){background:var(--color-white);border-radius:var(--rounded);line-height:1.25rem;padding:.5rem .75rem}.k-box[data-theme=code]{background:var(--color-gray-900);border:1px solid var(--color-black);color:var(--color-light);font-family:Input,Menlo,monospace;font-size:var(--text-sm);line-height:1.5}.k-box[data-theme=button]{padding:0}[dir=ltr] .k-box[data-theme=button] .k-button{text-align:left}[dir=rtl] .k-box[data-theme=button] .k-button{text-align:right}.k-box[data-theme=button] .k-button{padding:0 .75rem;height:2.25rem;width:100%;display:flex;align-items:center;line-height:2rem}[dir=ltr] .k-box[data-theme=info],[dir=ltr] .k-box[data-theme=negative],[dir=ltr] .k-box[data-theme=notice],[dir=ltr] .k-box[data-theme=positive]{border-left-color:var(--theme-light)}[dir=rtl] .k-box[data-theme=info],[dir=rtl] .k-box[data-theme=negative],[dir=rtl] .k-box[data-theme=notice],[dir=rtl] .k-box[data-theme=positive]{border-right-color:var(--theme-light)}.k-box[data-theme=info],.k-box[data-theme=negative],.k-box[data-theme=notice],.k-box[data-theme=positive]{border:0;background:var(--theme-bg)}[dir=ltr] .k-box[data-theme=empty]{border-left:0}[dir=rtl] .k-box[data-theme=empty]{border-right:0}.k-box[data-theme=empty]{text-align:center;padding:3rem 1.5rem;display:flex;justify-content:center;align-items:center;flex-direction:column;background:var(--color-background);border:1px dashed var(--color-border)}.k-box[data-theme=empty] .k-icon{margin-bottom:.5rem;color:var(--color-gray-500)}.k-box[data-theme=empty],.k-box[data-theme=empty] p{color:var(--color-gray-600)}.k-bubble{display:flex;padding:0 .5rem;white-space:nowrap;align-items:center;line-height:1.5;font-size:var(--text-xs);height:1.525rem;background:var(--color-light);color:var(--color-black);border-radius:var(--rounded);overflow:hidden}[dir=ltr] .k-bubble .k-item-figure{margin-left:-.5rem}[dir=rtl] .k-bubble .k-item-figure{margin-right:-.5rem}[dir=ltr] .k-bubble .k-item-figure{margin-right:var(--spacing-2)}[dir=rtl] .k-bubble .k-item-figure{margin-left:var(--spacing-2)}.k-bubble .k-item-figure{width:1.525rem;height:1.525rem}.k-bubbles{display:flex;gap:.25rem}.k-collection-help{padding:.5rem .75rem}.k-collection-footer{display:flex;justify-content:space-between;margin-left:-.75rem;margin-right:-.75rem}.k-collection-pagination{line-height:1.25rem;flex-shrink:0;min-height:2.75rem}.k-collection-pagination .k-pagination .k-button{padding:.5rem .75rem;line-height:1.125rem}.k-column{min-width:0;grid-column-start:span 12}.k-column[data-sticky=true]>div{position:sticky;top:4vh;z-index:2}@media screen and (min-width:65em){.k-column[data-width="1/1"],.k-column[data-width="12/12"],.k-column[data-width="2/2"],.k-column[data-width="3/3"],.k-column[data-width="4/4"],.k-column[data-width="6/6"]{grid-column-start:span 12}.k-column[data-width="11/12"]{grid-column-start:span 11}.k-column[data-width="10/12"],.k-column[data-width="5/6"]{grid-column-start:span 10}.k-column[data-width="3/4"],.k-column[data-width="9/12"]{grid-column-start:span 9}.k-column[data-width="2/3"],.k-column[data-width="4/6"],.k-column[data-width="8/12"]{grid-column-start:span 8}.k-column[data-width="7/12"]{grid-column-start:span 7}.k-column[data-width="1/2"],.k-column[data-width="2/4"],.k-column[data-width="3/6"],.k-column[data-width="6/12"]{grid-column-start:span 6}.k-column[data-width="5/12"]{grid-column-start:span 5}.k-column[data-width="1/3"],.k-column[data-width="2/6"],.k-column[data-width="4/12"]{grid-column-start:span 4}.k-column[data-width="1/4"],.k-column[data-width="3/12"]{grid-column-start:span 3}.k-column[data-width="1/6"],.k-column[data-width="2/12"]{grid-column-start:span 2}.k-column[data-width="1/12"]{grid-column-start:span 1}}.k-column[data-disabled=true]{cursor:not-allowed;opacity:.4}.k-column[data-disabled=true] *{pointer-events:none}.k-column[data-disabled=true] .k-text[data-theme=help] *{pointer-events:initial}.k-dropzone{position:relative}.k-dropzone:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;display:none;pointer-events:none;z-index:1}.k-dropzone[data-over=true]:after{display:block;outline:1px solid var(--color-focus);box-shadow:var(--color-focus-outline) 0 0 0 3px}.k-empty{display:flex;align-items:stretch;border-radius:var(--rounded);color:var(--color-gray-600);border:1px dashed var(--color-border)}button.k-empty{width:100%}button.k-empty:focus{outline:0}.k-empty p{font-size:var(--text-sm);color:var(--color-gray-600)}.k-empty>.k-icon{color:var(--color-gray-500)}.k-empty[data-layout=cardlets],.k-empty[data-layout=cards]{text-align:center;padding:1.5rem;justify-content:center;flex-direction:column}.k-empty[data-layout=cardlets] .k-icon,.k-empty[data-layout=cards] .k-icon{margin-bottom:1rem}.k-empty[data-layout=cardlets] .k-icon svg,.k-empty[data-layout=cards] .k-icon svg{width:2rem;height:2rem}.k-empty[data-layout=list],.k-empty[data-layout=table]{min-height:38px}[dir=ltr] .k-empty[data-layout=list]>.k-icon,[dir=ltr] .k-empty[data-layout=table]>.k-icon{border-right:1px solid rgba(0,0,0,.05)}[dir=rtl] .k-empty[data-layout=list]>.k-icon,[dir=rtl] .k-empty[data-layout=table]>.k-icon{border-left:1px solid rgba(0,0,0,.05)}.k-empty[data-layout=list]>.k-icon,.k-empty[data-layout=table]>.k-icon{width:36px;min-height:36px}.k-empty[data-layout=list]>p,.k-empty[data-layout=table]>p{line-height:1.25rem;padding:.5rem .75rem}.k-file-preview{background:var(--color-gray-800)}.k-file-preview-layout{display:grid;grid-template-columns:50%auto}.k-file-preview-layout>*{min-width:0}.k-file-preview-image{position:relative;display:flex;align-items:center;justify-content:center;background:var(--bg-pattern)}.k-file-preview-image-link{display:block;width:100%;padding:min(4vw,3rem);outline:0}.k-file-preview-image-link[data-tabbed=true]{box-shadow:none;outline:2px solid var(--color-focus);outline-offset:-2px}.k-file-preview-details{padding:1.5rem;flex-grow:1}.k-file-preview-details ul{line-height:1.5em;max-width:50rem;display:grid;grid-gap:1.5rem 3rem;grid-template-columns:repeat(auto-fill,minmax(100px,1fr))}.k-file-preview-details h3{font-size:var(--text-sm);font-weight:500;color:var(--color-gray-500)}.k-file-preview-details a,.k-file-preview-details p{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;color:#ffffffbf;font-size:var(--text-sm)}@media screen and (min-width:30em){.k-file-preview-details ul{grid-template-columns:repeat(auto-fill,minmax(200px,1fr))}}@media screen and (max-width:65em){.k-file-preview-layout{padding:0!important}}@media screen and (min-width:65em){.k-file-preview-layout{grid-template-columns:33.333%auto;align-items:center}.k-file-preview-details{padding:3rem}}@media screen and (min-width:90em){.k-file-preview-layout{grid-template-columns:25%auto}}.k-grid{--columns:12;display:grid;grid-column-gap:0;grid-row-gap:0;grid-template-columns:1fr}@media screen and (min-width:30em){.k-grid[data-gutter=small]{grid-column-gap:1rem;grid-row-gap:1rem}.k-grid[data-gutter=huge],.k-grid[data-gutter=large],.k-grid[data-gutter=medium]{grid-column-gap:1.5rem;grid-row-gap:1.5rem}}@media screen and (min-width:65em){.k-grid{grid-template-columns:repeat(var(--columns),1fr)}.k-grid[data-gutter=large]{grid-column-gap:3rem}.k-grid[data-gutter=huge]{grid-column-gap:4.5rem}}@media screen and (min-width:90em){.k-grid[data-gutter=large]{grid-column-gap:4.5rem}.k-grid[data-gutter=huge]{grid-column-gap:6rem}}@media screen and (min-width:120em){.k-grid[data-gutter=large]{grid-column-gap:6rem}.k-grid[data-gutter=huge]{grid-column-gap:7.5rem}}.k-header{padding-top:4vh;margin-bottom:2rem;border-bottom:1px solid var(--color-border)}.k-header[data-tabs=true]{border-bottom:0}.k-header .k-headline{min-height:1.25em;margin-bottom:.5rem;word-wrap:break-word}.k-header .k-header-buttons{margin-top:-.5rem;height:3.25rem}.k-header .k-headline-editable{cursor:pointer}[dir=ltr] .k-header .k-headline-editable .k-icon{margin-left:.5rem}[dir=rtl] .k-header .k-headline-editable .k-icon{margin-right:.5rem}.k-header .k-headline-editable .k-icon{color:var(--color-gray-500);opacity:0;transition:opacity .3s;display:inline-block}.k-header .k-headline-editable:hover .k-icon{opacity:1}.k-panel-inside{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;flex-direction:column}.k-panel-inside:focus{outline:0}.k-panel-header{z-index:var(--z-navigation);flex-shrink:0}.k-panel-view{flex-grow:1;padding-bottom:6rem}.k-item{position:relative;background:var(--color-white);border-radius:var(--rounded);box-shadow:var(--shadow);display:grid;grid-template-columns:auto;line-height:1}.k-item a:focus,.k-item:focus{outline:0}.k-item.k-sortable-ghost,.k-item:focus-within{box-shadow:var(--shadow-outline)}.k-item-sort-handle.k-sort-handle{position:absolute;opacity:0;width:1.25rem;height:1.5rem;z-index:2;border-radius:1px}.k-item:hover .k-item-sort-handle{opacity:1}.k-item-figure{grid-area:figure}.k-item-content{grid-area:content;overflow:hidden}.k-item-info,.k-item-title{font-size:var(--text-sm);font-weight:400;text-overflow:ellipsis;white-space:nowrap;line-height:1.125rem;overflow:hidden}.k-item-info{grid-area:info;color:var(--color-gray-500)}.k-item-title-link.k-link[data-=true]{box-shadow:none}.k-item-title-link:after{position:absolute;content:"";top:0;right:0;bottom:0;left:0;z-index:1}.k-item-footer{grid-area:footer;display:flex;justify-content:space-between;align-items:center;min-width:0}[dir=ltr] .k-item-label{margin-right:.5rem}[dir=rtl] .k-item-label{margin-left:.5rem}.k-item-buttons{position:relative;display:flex;justify-content:flex-end;flex-shrink:0;flex-grow:1}.k-item-buttons>.k-button,.k-item-buttons>.k-dropdown{position:relative;width:38px;height:38px;display:flex!important;align-items:center;justify-content:center;line-height:1}.k-item-buttons>.k-button{z-index:1}.k-item-buttons>.k-options-dropdown>.k-options-dropdown-toggle{z-index:var(--z-toolbar)}.k-list-item{display:flex;align-items:center;height:38px}[dir=ltr] .k-list-item .k-item-sort-handle{left:-1.5rem}[dir=rtl] .k-list-item .k-item-sort-handle{right:-1.5rem}.k-list-item .k-item-sort-handle{width:1.5rem}[dir=ltr] .k-list-item .k-item-figure{border-top-left-radius:var(--rounded)}[dir=rtl] .k-list-item .k-item-figure{border-top-right-radius:var(--rounded)}[dir=ltr] .k-list-item .k-item-figure{border-bottom-left-radius:var(--rounded)}[dir=rtl] .k-list-item .k-item-figure{border-bottom-right-radius:var(--rounded)}.k-list-item .k-item-figure{width:38px}[dir=ltr] .k-list-item .k-item-content{margin-left:.75rem}[dir=rtl] .k-list-item .k-item-content{margin-right:.75rem}.k-list-item .k-item-content{display:flex;flex-grow:1;flex-shrink:2;justify-content:space-between;align-items:center}.k-list-item .k-item-info,.k-list-item .k-item-title{flex-grow:1;line-height:1.5rem}[dir=ltr] .k-list-item .k-item-title{margin-right:.5rem}[dir=rtl] .k-list-item .k-item-title{margin-left:.5rem}.k-list-item .k-item-title{flex-shrink:1}[dir=ltr] .k-list-item .k-item-info{text-align:right}[dir=rtl] .k-list-item .k-item-info{text-align:left}[dir=ltr] .k-list-item .k-item-info{margin-right:.5rem}[dir=rtl] .k-list-item .k-item-info{margin-left:.5rem}.k-list-item .k-item-info{flex-shrink:2;justify-self:end}.k-list-item .k-item-buttons,.k-list-item .k-item-footer{flex-shrink:0}.k-item:not(.k-list-item) .k-item-sort-handle{margin:var(--spacing-2);background:var(--color-background);box-shadow:var(--shadow-lg);border-radius:var(--rounded-sm)}[dir=ltr] .k-item:not(.k-list-item) .k-item-label{margin-left:-2px}[dir=rtl] .k-item:not(.k-list-item) .k-item-label{margin-right:-2px}.k-item:not(.k-list-item) .k-item-content{padding:.625rem .75rem}.k-cardlets-item{height:6rem;grid-template-rows:auto 38px;grid-template-areas:"content""footer"}.k-cardlets-item[data-has-figure=true]{grid-template-columns:6rem auto;grid-template-areas:"figure content""figure footer"}[dir=ltr] .k-cardlets-item .k-item-figure{border-top-left-radius:var(--rounded)}[dir=rtl] .k-cardlets-item .k-item-figure{border-top-right-radius:var(--rounded)}[dir=ltr] .k-cardlets-item .k-item-figure{border-bottom-left-radius:var(--rounded)}[dir=rtl] .k-cardlets-item .k-item-figure{border-bottom-right-radius:var(--rounded)}.k-cardlets-item .k-item-footer{padding-top:.5rem;padding-bottom:.5rem}.k-cards-item{grid-template-columns:auto;grid-template-rows:auto 1fr;grid-template-areas:"figure""content";--item-content-wrapper:0}[dir=ltr] .k-cards-item .k-item-figure,[dir=rtl] .k-cards-item .k-item-figure{border-top-right-radius:var(--rounded);border-top-left-radius:var(--rounded)}.k-cards-item .k-item-content{padding:.5rem .75rem!important;overflow:hidden}.k-cards-item .k-item-info,.k-cards-item .k-item-title{line-height:1.375rem;white-space:normal}.k-cards-item .k-item-info:after,.k-cards-item .k-item-title:after{display:inline-block;content:"\a0";width:var(--item-content-wrapper)}.k-cards-item[data-has-flag=true],.k-cards-item[data-has-options=true]{--item-content-wrapper:38px}.k-cards-item[data-has-flag=true][data-has-options=true]{--item-content-wrapper:76px}.k-cards-item[data-has-info=true] .k-item-title:after{display:none}[dir=ltr] .k-cards-item .k-item-footer{right:0}[dir=rtl] .k-cards-item .k-item-footer{left:0}.k-cards-item .k-item-footer{position:absolute;bottom:0;width:auto}.k-item-figure{overflow:hidden;flex-shrink:0}.k-cards-items{--min:13rem;--max:1fr;--gap:1.5rem;--column-gap:var(--gap);--row-gap:var(--gap);display:grid;grid-column-gap:var(--column-gap);grid-row-gap:var(--row-gap);grid-template-columns:repeat(auto-fill,minmax(var(--min),var(--max)))}@media screen and (min-width:30em){.k-cards-items[data-size=tiny]{--min:10rem}.k-cards-items[data-size=small]{--min:16rem}.k-cards-items[data-size=medium]{--min:24rem}.k-cards-items[data-size=huge],.k-cards-items[data-size=large],.k-column[data-width="1/4"] .k-cards-items,.k-column[data-width="1/5"] .k-cards-items,.k-column[data-width="1/6"] .k-cards-items{--min:1fr}}@media screen and (min-width:65em){.k-cards-items[data-size=large]{--min:32rem}}.k-cardlets-items{display:grid;grid-template-columns:repeat(auto-fill,minmax(16rem,1fr));grid-gap:.5rem}.k-list-items .k-list-item:not(:last-child){margin-bottom:2px}.k-overlay{position:fixed;top:0;right:0;bottom:0;left:0;width:100%;height:100%;z-index:var(--z-dialog);transform:translateZ(0)}.k-overlay[data-centered=true]{display:flex;align-items:center;justify-content:center}.k-overlay[data-dimmed=true]{background:var(--color-backdrop)}.k-overlay-loader{color:var(--color-white)}.k-panel[data-loading=true]{animation:LoadingCursor .5s}.k-panel[data-dragging=true],.k-panel[data-loading=true]:after{-webkit-user-select:none;-moz-user-select:none;user-select:none}.k-stats{display:grid;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));grid-auto-rows:1fr;grid-gap:var(--spacing-2px)}.k-stat{display:flex;flex-direction:column;background:var(--color-white);box-shadow:var(--shadow);padding:var(--spacing-3) var(--spacing-6);line-height:var(--leading-normal);border-radius:var(--rounded)}.k-stat.k-link:hover{cursor:pointer;background:var(--color-gray-100)}.k-stat dd,.k-stat dt{display:block}.k-stat-value{font-size:var(--value);margin-bottom:var(--spacing-1);order:1}.k-stat-info,.k-stat-label{font-size:var(--text-xs)}.k-stat-label{order:2}.k-stat-info{order:3;color:var(--theme, var(--color-gray-500))}.k-stats[data-size=small]{--value:var(--text-base)}.k-stats[data-size=medium]{--value:var(--text-xl)}.k-stats[data-size=large]{--value:var(--text-2xl)}.k-stats[data-size=huge]{--value:var(--text-3xl)}.k-table{--table-row-height:38px;position:relative;table-layout:fixed;background:var(--color-white);font-size:var(--text-sm);border-spacing:0;box-shadow:var(--shadow);border-radius:var(--rounded);font-variant-numeric:tabular-nums}.k-table[data-invalid]{border:0;box-shadow:var(--color-negative-outline) 0 0 0 1px,var(--color-negative-outline) 0 0 3px 2px}.k-table td,.k-table th{height:var(--table-row-height);overflow:hidden;text-overflow:ellipsis;line-height:1.25em}.k-table,.k-table td{width:100%}[dir=ltr] .k-table tbody tr:first-child th,[dir=ltr] .k-table thead th:first-child{border-top-left-radius:var(--rounded)}[dir=rtl] .k-table tbody tr:first-child th,[dir=rtl] .k-table thead th:first-child{border-top-right-radius:var(--rounded)}[dir=ltr] .k-table thead th:last-child{border-top-right-radius:var(--rounded)}[dir=rtl] .k-table thead th:last-child{border-top-left-radius:var(--rounded)}[dir=ltr] .k-table td:last-child,[dir=ltr] .k-table th:last-child{border-right:0}[dir=rtl] .k-table td:last-child,[dir=rtl] .k-table th:last-child{border-left:0}.k-table td:last-child,.k-table th:last-child{height:var(--table-row-height)}.k-table th,.k-table tr:not(:last-child) td{border-bottom:1px solid var(--color-background)}.k-table td:last-child{overflow:visible}[dir=ltr] .k-table td,[dir=ltr] .k-table th{border-right:1px solid var(--color-background)}[dir=rtl] .k-table td,[dir=rtl] .k-table th{border-left:1px solid var(--color-background)}[dir=ltr] .k-table td,[dir=ltr] .k-table th,[dir=ltr] .k-table th button{text-align:left}[dir=rtl] .k-table td,[dir=rtl] .k-table th,[dir=rtl] .k-table th button{text-align:right}.k-table th{padding:0 .75rem;font-family:var(--font-mono);font-size:var(--text-xs);font-weight:400;color:var(--color-gray-600);background:var(--color-gray-100);width:100%}.k-table th button{font:inherit;display:block;padding:0 .75rem;height:100%;width:100%;border-radius:var(--rounded)}.k-table th button:focus-visible{outline:2px solid var(--color-black);outline-offset:-2px}.k-table tbody tr:hover td{background:rgba(239,239,239,.25)}.k-table thead th{position:sticky;top:0;left:0;right:0;z-index:1}.k-table tbody th{width:auto;white-space:nowrap;padding:0;overflow:visible;border-radius:0}[dir=ltr] .k-table tbody tr:last-child th{border-bottom-left-radius:var(--rounded)}[dir=rtl] .k-table tbody tr:last-child th{border-bottom-right-radius:var(--rounded)}.k-table tbody tr:last-child th{border-bottom:0}.k-table-column[data-align]{text-align:var(--align)!important}.k-table-column[data-align=right]>.k-input{flex-direction:column;align-items:flex-end}.k-table .k-sort-handle,.k-table-index{display:grid;place-items:center;width:100%;height:var(--table-row-height)}.k-table .k-sort-handle,.k-table tr:hover .k-table-index-column[data-sortable=true] .k-table-index{display:none}.k-table tr:hover .k-sort-handle{display:grid!important}.k-table-row-ghost{background:var(--color-white);box-shadow:var(--shadow-outline);outline:2px solid var(--color-black);border-radius:var(--rounded);margin-bottom:2px;cursor:grabbing;cursor:-webkit-grabbing}.k-table-row-fallback{opacity:0!important}td.k-table-index-column,td.k-table-options-column,th.k-table-index-column,th.k-table-options-column{width:var(--table-row-height);text-align:center!important}.k-table-index{font-size:var(--text-xs);color:var(--color-gray-500);line-height:1.1em}.k-table-empty{color:var(--color-gray-600);font-size:var(--text-sm)}[data-disabled=true] .k-table{background:var(--color-gray-100)}[data-disabled=true] .k-table tbody td,[data-disabled=true] .k-table th{border-color:var(--color-gray-200)}[data-disabled=true] .k-table td:last-child{overflow:hidden;text-overflow:ellipsis}@media screen and (max-width:65em){.k-table td:not([data-mobile]),.k-table th:not([data-mobile]){display:none}}.k-table-update-status-cell{padding:0 .75rem;display:flex;align-items:center;height:100%}.k-table-update-status-cell-button,.k-table-update-status-cell-version{font-variant-numeric:tabular-nums}.k-table-update-status-cell-button{display:inline-flex;padding:.25rem 1.5rem .25rem .325rem;border-radius:var(--rounded);line-height:1;align-items:center;background:var(--color-gray-200)}.k-table-update-status-cell-button .k-button-text:after{position:absolute;top:50%;right:.5rem;margin-top:-2px;content:"";border-top:4px solid #000;border-left:4px solid transparent;border-right:4px solid transparent}.k-table-update-status-cell-button .k-icon{color:var(--theme)}.k-plugin-info{padding:1rem}.k-plugin-info div+div{margin-top:.5rem}.k-plugin-info dt{color:var(--color-gray-400);margin-right:.5rem}.k-plugin-info dd[data-theme]{color:var(--theme-light)}.k-plugin-info+.k-dropdown-item{padding-top:.75rem;border-top:1px solid var(--color-gray-700)}@media screen and (min-width:30em){.k-plugin-info{width:20rem}.k-plugin-info div{display:flex}}.k-tabs{position:relative;background:#e9e9e9;border:1px solid var(--color-border);border-radius:var(--rounded)}.k-tabs nav{display:flex;justify-content:center;margin-left:-1px;margin-right:-1px}[dir=ltr] .k-tab-button.k-button{border-left:1px solid transparent}[dir=rtl] .k-tab-button.k-button{border-right:1px solid transparent}[dir=ltr] .k-tab-button.k-button{border-right:1px solid var(--color-border)}[dir=rtl] .k-tab-button.k-button{border-left:1px solid var(--color-border)}.k-tab-button.k-button{position:relative;z-index:1;display:inline-flex;justify-content:center;align-items:center;padding:.625rem .75rem;font-size:var(--text-xs);text-transform:uppercase;text-align:center;font-weight:500;flex-grow:1;flex-shrink:1;flex-direction:column;max-width:15rem}@media screen and (min-width:30em){.k-tab-button.k-button{flex-direction:row}[dir=ltr] .k-tab-button.k-button .k-icon{margin-right:.5rem}[dir=rtl] .k-tab-button.k-button .k-icon{margin-left:.5rem}}[dir=ltr] .k-tab-button.k-button>.k-button-text{padding-left:0}[dir=rtl] .k-tab-button.k-button>.k-button-text{padding-right:0}.k-tab-button.k-button>.k-button-text{padding-top:.375rem;font-size:10px;overflow:hidden;max-width:10rem;text-overflow:ellipsis;opacity:1}@media screen and (min-width:30em){.k-tab-button.k-button>.k-button-text{font-size:var(--text-xs);padding-top:0}}[dir=ltr] .k-tab-button:last-child{border-right:1px solid transparent}[dir=rtl] .k-tab-button:last-child{border-left:1px solid transparent}[dir=ltr] .k-tab-button[aria-current]{border-right:1px solid var(--color-border)}[dir=rtl] .k-tab-button[aria-current]{border-left:1px solid var(--color-border)}.k-tab-button[aria-current]{position:relative;background:var(--color-background);pointer-events:none}[dir=ltr] .k-tab-button[aria-current]:first-child{border-left:1px solid var(--color-border)}[dir=rtl] .k-tab-button[aria-current]:first-child{border-right:1px solid var(--color-border)}.k-tab-button[aria-current]:after,.k-tab-button[aria-current]:before{position:absolute;content:""}.k-tab-button[aria-current]:before{left:-1px;right:-1px;top:-1px;height:2px;background:var(--color-black)}.k-tab-button[aria-current]:after{left:0;right:0;bottom:-1px;height:1px;background:var(--color-background)}[dir=ltr] .k-tabs-dropdown{right:0}[dir=rtl] .k-tabs-dropdown{left:0}.k-tabs-dropdown{top:100%}[dir=ltr] .k-tabs-badge{right:2px}[dir=rtl] .k-tabs-badge{left:2px}.k-tabs-badge{position:absolute;top:3px;font-variant-numeric:tabular-nums;line-height:1.5;padding:0 .25rem;border-radius:2px;font-size:10px;box-shadow:var(--shadow-md)}.k-tabs[data-theme=notice] .k-tabs-badge{background:var(--theme-light);color:var(--color-black)}.k-view{padding-left:1.5rem;padding-right:1.5rem;margin:0 auto;max-width:100rem}@media screen and (min-width:30em){.k-view{padding-left:3rem;padding-right:3rem}}@media screen and (min-width:90em){.k-view{padding-left:6rem;padding-right:6rem}}.k-view[data-align=center]{height:100vh;display:flex;align-items:center;justify-content:center;padding:0 3rem;overflow:auto}.k-view[data-align=center]>*{flex-basis:22.5rem}.k-fatal{position:fixed;top:0;right:0;bottom:0;left:0;background:var(--color-backdrop);display:flex;z-index:var(--z-fatal);align-items:center;justify-content:center;padding:1.5rem}.k-fatal-box{width:100%;height:100%;display:flex;flex-direction:column;color:var(--color-black);background:var(--color-red-400);box-shadow:var(--shadow-xl);border-radius:var(--rounded)}.k-fatal-box .k-headline{line-height:1;font-size:var(--text-sm);padding:.75rem}.k-fatal-box .k-button{padding:.75rem}.k-fatal-iframe{border:0;width:100%;flex-grow:1;background:var(--color-white)}.k-headline{--size:var(--text-base);font-size:var(--size);font-weight:var(--font-bold);line-height:1.5em}.k-headline[data-size=small]{--size:var(--text-sm)}.k-headline[data-size=large]{--size:var(--text-xl);font-weight:var(--font-normal)}@media screen and (min-width:65em){.k-headline[data-size=large]{--size:var(--text-2xl)}}.k-headline[data-size=huge]{--size:var(--text-2xl);line-height:1.15em}@media screen and (min-width:65em){.k-headline[data-size=huge]{--size:var(--text-3xl)}}.k-headline[data-theme]{color:var(--theme)}[dir=ltr] .k-headline abbr{padding-left:.25rem}[dir=rtl] .k-headline abbr{padding-right:.25rem}.k-headline abbr{color:var(--color-gray-500);text-decoration:none}.k-icon{--size:1rem;position:relative;line-height:0;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:var(--size)}.k-icon[data-size=medium]{--size:2rem}.k-icon[data-size=large]{--size:3rem}.k-icon svg{width:var(--size);height:var(--size);-moz-transform:scale(1)}.k-icon svg *{fill:currentColor}.k-icon[data-back=black]{color:var(--color-white)}.k-icon[data-back=white]{color:var(--color-gray-900)}.k-icon[data-back=pattern]{color:var(--color-white)}[data-disabled=true] .k-icon[data-back=pattern] svg{opacity:1}.k-icon-emoji{display:block;line-height:1;font-style:normal;font-size:var(--size)}@media not all,not all,not all,only screen and (min-resolution:192dpi),only screen and (min-resolution:2dppx){.k-icon-emoji{font-size:1.25em}}.k-icons{position:absolute;width:0;height:0}.k-image span{position:relative;display:block;line-height:0;padding-bottom:100%}.k-image img{position:absolute;top:0;right:0;bottom:0;left:0;width:100%;height:100%;-o-object-fit:contain;object-fit:contain}[dir=ltr] .k-image-error{left:50%}[dir=rtl] .k-image-error{right:50%}.k-image-error{position:absolute;top:50%;transform:translate(-50%,-50%);color:var(--color-white);font-size:.9em}.k-image-error svg *{fill:#ffffff4d}.k-image[data-cover=true] img{-o-object-fit:cover;object-fit:cover}.k-image[data-back=black] span{background:var(--color-gray-900)}.k-image[data-back=white] span{background:var(--color-white);color:var(--color-gray-900)}.k-image[data-back=white] .k-image-error{background:var(--color-gray-900);color:var(--color-white)}.k-image[data-back=pattern] span{background:var(--color-gray-800) var(--bg-pattern)}.k-loader{z-index:1}.k-loader-icon{animation:Spin .9s linear infinite}.k-offline-warning{position:fixed;top:0;right:0;bottom:0;left:0;z-index:var(--z-offline);background:var(--color-backdrop);display:flex;align-items:center;justify-content:center;line-height:1}.k-offline-warning p{display:flex;align-items:center;gap:.5rem;background:var(--color-white);box-shadow:var(--shadow);padding:.75rem;border-radius:var(--rounded)}.k-offline-warning p .k-icon{color:var(--color-red-400)}.k-progress{-webkit-appearance:none;width:100%;height:.5rem;border-radius:5rem;background:var(--color-border);overflow:hidden;border:0}.k-progress::-webkit-progress-bar{border:0;background:var(--color-border);height:.5rem;border-radius:20px}.k-progress::-webkit-progress-value{border-radius:inherit;background:var(--color-focus);-webkit-transition:width .3s;transition:width .3s}.k-progress::-moz-progress-bar{border-radius:inherit;background:var(--color-focus);-moz-transition:width .3s;transition:width .3s}[dir=ltr] .k-registration,[dir=ltr] .k-registration p{margin-right:1rem}[dir=rtl] .k-registration,[dir=rtl] .k-registration p{margin-left:1rem}.k-registration{display:flex;align-items:center}.k-registration p{color:var(--color-negative-light);font-size:var(--text-sm);font-weight:600}@media screen and (max-width:90em){.k-registration p{display:none}}.k-registration .k-button{color:var(--color-white)}.k-sort-handle{cursor:move;cursor:grab;cursor:-webkit-grab;color:var(--color-gray-900);justify-content:center;align-items:center;line-height:0;width:2rem;height:2rem;display:flex;will-change:opacity,color;transition:opacity .3s;z-index:1}.k-sort-handle svg{width:1rem;height:1rem}.k-sort-handle:active{cursor:grabbing;cursor:-webkit-grabbing}.k-status-icon svg{width:14px;height:14px}.k-status-icon .k-icon{color:var(--theme-light)}.k-status-icon .k-button-text{color:var(--color-black)}.k-status-icon[data-disabled=true]{opacity:1!important}.k-status-icon[data-disabled=true] .k-icon{color:var(--color-gray-400);opacity:.5}.k-text{line-height:1.5em}[dir=ltr] .k-text ol,[dir=ltr] .k-text ul{margin-left:1rem}[dir=rtl] .k-text ol,[dir=rtl] .k-text ul{margin-right:1rem}.k-text li{list-style:inherit}.k-text p,.k-text>ol,.k-text>ul{margin-bottom:1.5em}.k-text a{text-decoration:underline}.k-text>:last-child{margin-bottom:0}.k-text[data-size=tiny]{font-size:var(--text-xs)}.k-text[data-size=small]{font-size:var(--text-sm)}.k-text[data-size=medium]{font-size:var(--text-base)}.k-text[data-size=large]{font-size:var(--text-xl)}.k-text[data-align]{text-align:var(--align)}.k-text[data-theme=help]{font-size:var(--text-sm);color:var(--color-gray-600);line-height:1.25rem}.k-dialog-body .k-text{word-wrap:break-word}.k-user-info{display:flex;align-items:center;line-height:1;font-size:var(--text-sm)}[dir=ltr] .k-user-info .k-image{margin-right:.75rem}[dir=rtl] .k-user-info .k-image{margin-left:.75rem}.k-user-info .k-image{width:1.5rem}[dir=ltr] .k-user-info .k-icon{margin-right:.75rem}[dir=rtl] .k-user-info .k-icon{margin-left:.75rem}.k-user-info .k-icon{width:1.5rem;height:1.5rem;background:var(--color-black);color:var(--color-white)}.k-breadcrumb{padding-left:.5rem;padding-right:.5rem}.k-breadcrumb-dropdown{height:2.5rem;width:2.5rem;display:flex;align-items:center;justify-content:center}.k-breadcrumb ol{display:none;align-items:center}@media screen and (min-width:30em){.k-breadcrumb ol{display:flex}.k-breadcrumb-dropdown{display:none}}.k-breadcrumb li,.k-breadcrumb-link{display:flex;align-items:center;min-width:0}.k-breadcrumb-link{font-size:var(--text-sm);align-self:stretch;padding-top:.625rem;padding-bottom:.625rem;line-height:1.25rem}.k-breadcrumb li{flex-shrink:3}.k-breadcrumb li:last-child{flex-shrink:1}.k-breadcrumb li:not(:last-child):after{content:"/";padding-left:.5rem;padding-right:.5rem;opacity:.5;flex-shrink:0}.k-breadcrumb li:not(:first-child):not(:last-child){max-width:15vw}[dir=ltr] .k-breadcrumb-icon{margin-right:.5rem}[dir=rtl] .k-breadcrumb-icon{margin-left:.5rem}.k-breadcrumb-icon.k-loader{opacity:.5}.k-breadcrumb-link-text{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}button{line-height:inherit;border:0;font-family:var(--font-sans);font-size:1rem;color:currentColor;background:0 0;cursor:pointer}button::-moz-focus-inner{padding:0;border:0}.k-button{display:inline-block;position:relative;font-size:var(--text-sm);transition:color .3s;outline:0}.k-button:focus,.k-button:hover{outline:0}.k-button *{vertical-align:middle}.k-button[data-responsive=true] .k-button-text{display:none}@media screen and (min-width:30em){.k-button[data-responsive=true] .k-button-text{display:inline}}.k-button[data-theme]{color:var(--theme)}.k-button-icon{display:inline-flex;align-items:center;line-height:0}[dir=ltr] .k-button-icon~.k-button-text{padding-left:.5rem}[dir=rtl] .k-button-icon~.k-button-text{padding-right:.5rem}.k-button-text{opacity:.75}.k-button:focus .k-button-text,.k-button:hover .k-button-text{opacity:1}.k-button-text b,.k-button-text span{vertical-align:baseline}.k-button[data-disabled=true]{opacity:.5;pointer-events:none;cursor:default}.k-card-options>.k-button[data-disabled=true]{display:inline-flex}.k-button-group{--padding-x:.75rem;--padding-y:1rem;--line-height:1rem;font-size:0;margin:0 calc(var(--padding-x)*-1)}.k-button-group>.k-dropdown{height:calc(var(--line-height) + (var(--padding-y)*2));display:inline-block}.k-button-group>.k-button,.k-button-group>.k-dropdown>.k-button{padding:var(--padding-y) var(--padding-x);line-height:var(--line-height)}.k-button-group .k-dropdown-content{top:calc(100% + 1px);margin:0 var(--padding-x)}.k-dropdown{position:relative}[dir=ltr] .k-dropdown-content{text-align:left}[dir=rtl] .k-dropdown-content{text-align:right}.k-dropdown-content{position:absolute;top:100%;background:var(--color-black);color:var(--color-white);z-index:var(--z-dropdown);box-shadow:var(--shadow-lg);border-radius:var(--rounded);margin-bottom:6rem}[dir=ltr] .k-dropdown-content[data-align=left]{left:0}[dir=ltr] .k-dropdown-content[data-align=right],[dir=rtl] .k-dropdown-content[data-align=left]{right:0}[dir=rtl] .k-dropdown-content[data-align=right]{left:0}.k-dropdown-content>.k-dropdown-item:first-child{margin-top:.5rem}.k-dropdown-content>.k-dropdown-item:last-child{margin-bottom:.5rem}.k-dropdown-content[data-dropup=true]{top:auto;bottom:100%;margin-bottom:.5rem}.k-dropdown-content hr{border-color:currentColor;opacity:.2;margin:.5rem 1rem}.k-dropdown-content[data-theme=light]{background:var(--color-white);color:var(--color-black)}.k-dropdown-item{white-space:nowrap;line-height:1;display:flex;width:100%;align-items:center;font-size:var(--text-sm);padding:6px 16px}.k-dropdown-item:focus{outline:0;box-shadow:var(--shadow-outline)}[dir=ltr] .k-dropdown-item .k-button-figure{padding-right:.5rem}[dir=rtl] .k-dropdown-item .k-button-figure{padding-left:.5rem}.k-dropdown-item .k-button-figure{text-align:center}.k-link{outline:0}.k-options-dropdown,.k-options-dropdown-toggle{display:flex;justify-content:center;align-items:center;height:38px}.k-options-dropdown-toggle{min-width:38px;padding:0 .75rem}.k-pagination{-webkit-user-select:none;-moz-user-select:none;user-select:none;direction:ltr}.k-pagination .k-button{padding:1rem}.k-pagination-details{white-space:nowrap}.k-pagination>span{font-size:var(--text-sm)}.k-pagination[data-align]{text-align:var(--align)}[dir=ltr] .k-dropdown-content.k-pagination-selector{left:50%}[dir=rtl] .k-dropdown-content.k-pagination-selector{right:50%}.k-dropdown-content.k-pagination-selector{position:absolute;top:100%;transform:translate(-50%);background:var(--color-black)}[dir=ltr] .k-dropdown-content.k-pagination-selector{direction:ltr}[dir=rtl] .k-dropdown-content.k-pagination-selector{direction:rtl}.k-pagination-settings{display:flex;align-items:center;justify-content:space-between}.k-pagination-settings .k-button{line-height:1}[dir=ltr] .k-pagination-settings label{border-right:1px solid rgba(255,255,255,.35)}[dir=rtl] .k-pagination-settings label{border-left:1px solid rgba(255,255,255,.35)}.k-pagination-settings label{display:flex;align-items:center;padding:.625rem 1rem;font-size:var(--text-xs)}[dir=ltr] .k-pagination-settings label span{margin-right:.5rem}[dir=rtl] .k-pagination-settings label span{margin-left:.5rem}.k-prev-next{direction:ltr}.k-search{max-width:30rem;margin:2.5rem auto;box-shadow:var(--shadow-lg);background:var(--color-light);border-radius:var(--rounded)}.k-search-input{display:flex}.k-search-types{flex-shrink:0;display:flex}[dir=ltr] .k-search-types>.k-button{padding-left:1rem}[dir=rtl] .k-search-types>.k-button{padding-right:1rem}.k-search-types>.k-button{font-size:var(--text-base);line-height:1;height:2.5rem}.k-search-types>.k-button .k-icon{height:2.5rem}.k-search-types>.k-button .k-button-text{opacity:1;font-weight:500}.k-search-input input{background:0 0;flex-grow:1;font:inherit;padding:.75rem;border:0;height:2.5rem}.k-search-close{width:3rem;line-height:1}.k-search-close .k-icon-loader{animation:Spin 2s linear infinite}.k-search input:focus{outline:0}.k-search-results{padding:.5rem 1rem 1rem}.k-search .k-item:not(:last-child){margin-bottom:.25rem}.k-search .k-item[data-selected=true]{outline:2px solid var(--color-focus)}.k-search .k-item-info,.k-search-empty{font-size:var(--text-xs)}.k-search-empty{text-align:center;color:var(--color-gray-600)}.k-tag{position:relative;font-size:var(--text-sm);line-height:1;cursor:pointer;background-color:var(--color-gray-900);color:var(--color-light);border-radius:var(--rounded);display:flex;align-items:center;justify-content:space-between;-webkit-user-select:none;-moz-user-select:none;user-select:none}.k-tag:focus{outline:0;background-color:var(--color-focus);color:#fff}.k-tag-text{padding:.3rem .75rem .375rem;line-height:var(--leading-tight)}[dir=ltr] .k-tag-toggle{padding-right:1px}[dir=rtl] .k-tag-toggle{padding-left:1px}[dir=ltr] .k-tag-toggle{border-left:1px solid rgba(255,255,255,.15)}[dir=rtl] .k-tag-toggle{border-right:1px solid rgba(255,255,255,.15)}.k-tag-toggle{color:#ffffffb3;width:1.75rem;height:100%}.k-tag-toggle:hover{background:rgba(255,255,255,.2);color:#fff}[data-disabled=true] .k-tag{background-color:var(--color-gray-600)}[data-disabled=true] .k-tag .k-tag-toggle{display:none}.k-topbar{--bg:var(--color-gray-900);position:relative;color:var(--color-white);flex-shrink:0;height:2.5rem;line-height:1;background:var(--bg)}.k-topbar-wrapper{position:relative;display:flex;align-items:center;margin-left:-.75rem;margin-right:-.75rem}[dir=ltr] .k-topbar-wrapper:after{left:100%}[dir=rtl] .k-topbar-wrapper:after{right:100%}.k-topbar-wrapper:after{position:absolute;content:"";height:2.5rem;background:var(--bg);width:3rem}.k-topbar-menu{flex-shrink:0}.k-topbar-menu ul{padding:.5rem 0}.k-topbar .k-button[data-theme]{color:var(--theme-light)}.k-topbar .k-button-text{opacity:1}.k-topbar-menu-button{display:flex;align-items:center}.k-topbar-menu .k-link[aria-current]{color:var(--color-focus);font-weight:500}.k-topbar-button{padding:.75rem;line-height:1;font-size:var(--text-sm)}.k-topbar-button .k-button-text{display:flex}[dir=ltr] .k-topbar-view-button{padding-right:0}[dir=rtl] .k-topbar-view-button{padding-left:0}.k-topbar-view-button{flex-shrink:0;display:flex;align-items:center}[dir=ltr] .k-topbar-view-button .k-icon{margin-right:.5rem}[dir=rtl] .k-topbar-view-button .k-icon{margin-left:.5rem}[dir=ltr] .k-topbar-signals{right:0}[dir=rtl] .k-topbar-signals{left:0}.k-topbar-signals{position:absolute;top:0;background:var(--bg);height:2.5rem;display:flex;align-items:center}.k-topbar-signals:before{position:absolute;content:"";top:-.5rem;bottom:0;width:.5rem;background:-webkit-linear-gradient(inline-start,rgba(17,17,17,0),#111)}.k-topbar-signals .k-button{line-height:1}.k-topbar-notification{font-weight:var(--font-bold);line-height:1;display:flex}@media screen and (max-width:30em){.k-topbar .k-button[data-theme=negative] .k-button-text{display:none}}.k-section,.k-sections{padding-bottom:3rem}.k-section-header{position:relative;display:flex;align-items:baseline;z-index:1}[dir=ltr] .k-section-header .k-headline{padding-right:var(--spacing-3)}[dir=rtl] .k-section-header .k-headline{padding-left:var(--spacing-3)}.k-section-header .k-headline{line-height:1.25rem;min-height:2rem;flex-grow:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}[dir=ltr] .k-section-header .k-button-group{right:0}[dir=rtl] .k-section-header .k-button-group{left:0}.k-section-header .k-button-group{position:absolute;top:calc(-.5rem - 1px)}.k-section-header .k-button-group>.k-button{padding:.75rem;display:inline-flex}.k-fields-issue-headline{margin-bottom:.5rem}.k-fields-section input[type=submit]{display:none}[data-locked=true] .k-fields-section{opacity:.2;pointer-events:none}.k-models-section[data-processing=true]{pointer-events:none}.k-models-section-search.k-input{margin-bottom:var(--spacing-3);background:var(--color-gray-300);padding:var(--spacing-2) var(--spacing-3);height:var(--field-input-height);border-radius:var(--rounded);font-size:var(--text-sm)}.k-info-section-label{margin-bottom:.5rem}.k-user-profile{background:var(--color-white)}.k-user-profile>.k-view{padding-top:3rem;padding-bottom:3rem;display:flex;align-items:center;line-height:0}[dir=ltr] .k-user-profile .k-button-group{margin-left:.75rem}[dir=rtl] .k-user-profile .k-button-group{margin-right:.75rem}.k-user-profile .k-button-group{overflow:hidden}.k-user-profile .k-button-group .k-button{display:block;padding-top:.25rem;padding-bottom:.25rem;overflow:hidden;white-space:nowrap}.k-user-view-image .k-icon,.k-user-view-image .k-image{width:5rem;height:5rem;border-radius:var(--rounded);line-height:0;overflow:hidden}.k-user-view-image[data-disabled=true]{opacity:1}.k-user-view-image .k-image{display:block}.k-user-view-image .k-button-text{opacity:1}.k-user-name-placeholder{color:var(--color-gray-500);transition:color .3s}.k-header[data-editable=true] .k-user-name-placeholder:hover{color:var(--color-gray-900)}.k-error-view{position:absolute;top:0;right:0;bottom:0;left:0;display:flex;align-items:center;justify-content:center}.k-error-view-content{line-height:1.5em;max-width:25rem;text-align:center}.k-error-view-icon{color:var(--color-negative);display:inline-block}.k-error-view-content p:not(:last-child){margin-bottom:.75rem}.k-installation-view .k-button{display:block;margin-top:1.5rem}.k-installation-view .k-headline{margin-bottom:.75rem}.k-installation-issues{line-height:1.5em;font-size:var(--text-sm)}[dir=ltr] .k-installation-issues li{padding-left:3.5rem}[dir=rtl] .k-installation-issues li{padding-right:3.5rem}.k-installation-issues li{position:relative;padding:1.5rem;background:var(--color-white)}[dir=ltr] .k-installation-issues .k-icon{left:1.5rem}[dir=rtl] .k-installation-issues .k-icon{right:1.5rem}.k-installation-issues .k-icon{position:absolute;top:calc(1.5rem + 2px)}.k-installation-issues .k-icon svg *{fill:var(--color-negative)}.k-installation-issues li:not(:last-child){margin-bottom:2px}.k-installation-issues li code{font:inherit;color:var(--color-negative)}[dir=ltr] .k-installation-view .k-button[type=submit]{margin-left:-1rem}[dir=rtl] .k-installation-view .k-button[type=submit]{margin-right:-1rem}.k-installation-view .k-button[type=submit]{padding:1rem}.k-languages-view .k-header{margin-bottom:1.5rem}.k-languages-view-section-header{margin-bottom:.5rem}.k-languages-view-section{margin-bottom:3rem}.k-login-fields{position:relative}[dir=ltr] .k-login-toggler{right:0}[dir=rtl] .k-login-toggler{left:0}.k-login-toggler{position:absolute;top:0;z-index:1;text-decoration:underline;font-size:.875rem}.k-login-form label abbr{visibility:hidden}.k-login-buttons{display:flex;align-items:center;justify-content:flex-end;padding:1.5rem 0}[dir=ltr] .k-login-button{margin-right:-1rem}[dir=rtl] .k-login-button{margin-left:-1rem}.k-login-button{padding:.5rem 1rem;font-weight:500;transition:opacity .3s}.k-login-button span{opacity:1}.k-login-button[disabled]{opacity:.25}.k-login-back-button,.k-login-checkbox{display:flex;align-items:center;flex-grow:1}[dir=ltr] .k-login-back-button{margin-left:-1rem}[dir=rtl] .k-login-back-button{margin-right:-1rem}.k-login-checkbox{padding:.5rem 0;font-size:var(--text-sm);cursor:pointer}.k-login-checkbox .k-checkbox-text{opacity:.75;transition:opacity .3s}.k-login-checkbox:focus span,.k-login-checkbox:hover span{opacity:1}.k-password-reset-view .k-user-info{height:38px;margin-bottom:2.25rem;padding:.5rem;background:var(--color-white);border-radius:var(--rounded-xs);box-shadow:var(--shadow)}.k-system-view .k-header{margin-bottom:1.5rem}.k-system-view-section-header{margin-bottom:.5rem;display:flex;justify-content:space-between}.k-system-view-section{margin-bottom:3rem}.k-system-info .k-stat-label{color:var(--theme, var(--color-black))}.k-block-type-code-editor{position:relative;font-size:var(--text-sm);line-height:1.5em;background:#000;border-radius:var(--rounded);padding:.5rem .75rem 3rem;color:#fff;font-family:var(--font-mono)}.k-block-type-code-editor .k-editor{white-space:pre-wrap;line-height:1.75em}[dir=ltr] .k-block-type-code-editor-language{right:0}[dir=ltr] .k-block-type-code-editor-language .k-icon,[dir=rtl] .k-block-type-code-editor-language{left:0}.k-block-type-code-editor-language{font-size:var(--text-sm);position:absolute;bottom:0}[dir=rtl] .k-block-type-code-editor-language .k-icon{right:0}.k-block-type-code-editor-language .k-icon{position:absolute;top:0;height:1.5rem;display:flex;width:2rem;z-index:0}.k-block-type-code-editor-language .k-select-input{position:relative;padding:.325rem .75rem .5rem 2rem;z-index:1;font-size:var(--text-xs)}.k-block-type-default .k-block-title{line-height:1.5em}.k-block-type-gallery ul{display:grid;grid-gap:.75rem;grid-template-columns:repeat(auto-fit,minmax(6rem,1fr));line-height:0;align-items:center;justify-content:center;cursor:pointer}.k-block-type-gallery-placeholder{background:var(--color-background)}.k-block-type-gallery figcaption{padding-top:.5rem;color:var(--color-gray-600);font-size:var(--text-sm);text-align:center}.k-block-type-heading-input{line-height:1.25em;font-weight:var(--font-bold)}.k-block-type-heading-input[data-level=h1]{font-size:var(--text-3xl);line-height:1.125em}.k-block-type-heading-input[data-level=h2]{font-size:var(--text-2xl)}.k-block-type-heading-input[data-level=h3]{font-size:var(--text-xl)}.k-block-type-heading-input[data-level=h4]{font-size:var(--text-lg)}.k-block-type-heading-input[data-level=h5]{line-height:1.5em;font-size:var(--text-base)}.k-block-type-heading-input[data-level=h6]{line-height:1.5em;font-size:var(--text-sm)}.k-block-type-heading-input .ProseMirror strong{font-weight:700}.k-block-type-image .k-block-figure-container{display:block;text-align:center;line-height:0}.k-block-type-image-auto{max-width:100%;max-height:30rem}.k-block-type-line hr{margin-top:.75rem;margin-bottom:.75rem;border:0;border-top:2px solid var(--color-gray-400)}.k-block-type-markdown-input{position:relative;font-size:var(--text-sm);line-height:1.5em;background:var(--color-background);border-radius:var(--rounded);padding:.5rem .5rem 0;font-family:var(--font-mono)}[dir=ltr] .k-block-type-quote-editor{padding-left:1rem}[dir=rtl] .k-block-type-quote-editor{padding-right:1rem}[dir=ltr] .k-block-type-quote-editor{border-left:2px solid var(--color-black)}[dir=rtl] .k-block-type-quote-editor{border-right:2px solid var(--color-black)}.k-block-type-quote-text{font-size:var(--text-xl);margin-bottom:.25rem;line-height:1.25em}.k-block-type-quote-citation{font-style:italic;font-size:var(--text-sm);color:var(--color-gray-600)}.k-block-type-table-preview{cursor:pointer;border:1px solid var(--color-gray-300);border-spacing:0;border-radius:var(--rounded-sm);overflow:hidden}[dir=ltr] .k-block-type-table-preview td,[dir=ltr] .k-block-type-table-preview th{text-align:left}[dir=rtl] .k-block-type-table-preview td,[dir=rtl] .k-block-type-table-preview th{text-align:right}.k-block-type-table-preview td,.k-block-type-table-preview th{line-height:1.5em;font-size:var(--text-sm)}.k-block-type-table-preview th{padding:.5rem .75rem}.k-block-type-table-preview td:not(.k-table-index-column){padding:0 .75rem}.k-block-type-table-preview td [class$=-field-preview],.k-block-type-table-preview td>*{padding:0}.k-block-type-text-input{font-size:var(--text-base);line-height:1.5em;height:100%}.k-block-container-type-text,.k-block-type-text,.k-block-type-text .k-writer .ProseMirror{height:100%}.k-block-container{position:relative;padding:.75rem;background:var(--color-white);border-radius:var(--rounded)}.k-block-container:not(:last-of-type){border-bottom:1px dashed rgba(0,0,0,.1)}.k-block-container:focus{outline:0}.k-block-container[data-batched=true],.k-block-container[data-selected=true]{z-index:2;border-bottom-color:transparent}.k-block-container[data-batched=true]:after{position:absolute;top:0;right:0;bottom:0;left:0;content:"";background:rgba(238,242,246,.375);mix-blend-mode:multiply;border:1px solid var(--color-focus)}.k-block-container[data-selected=true]{box-shadow:var(--color-focus) 0 0 0 1px,var(--color-focus-outline) 0 0 0 3px}[dir=ltr] .k-block-container .k-block-options{right:.75rem}[dir=rtl] .k-block-container .k-block-options{left:.75rem}.k-block-container .k-block-options{display:none;position:absolute;top:0;margin-top:calc(-1.75rem + 2px)}.k-block-container[data-last-in-batch=true]>.k-block-options,.k-block-container[data-selected=true]>.k-block-options{display:flex}.k-block-container[data-hidden=true] .k-block{opacity:.25}.k-drawer-options .k-button[data-disabled=true]{vertical-align:middle;display:inline-grid}[data-disabled=true] .k-block-container{background:var(--color-background)}.k-block-importer.k-dialog{background:#313740;color:var(--color-white)}.k-block-importer .k-dialog-body{padding:0}.k-block-importer label{display:block;padding:var(--spacing-6) var(--spacing-6)0;color:var(--color-gray-400)}.k-block-importer label kbd{background:rgba(0,0,0,.5);font-family:var(--font-mono);letter-spacing:.1em;padding:.25rem;border-radius:var(--rounded);margin:0 .25rem}.k-block-importer textarea{width:100%;height:20rem;background:0 0;font:inherit;color:var(--color-white);border:0;padding:var(--spacing-6);resize:none}.k-block-importer textarea:focus{outline:0}.k-blocks{background:var(--color-white);box-shadow:var(--shadow);border-radius:var(--rounded)}[data-disabled=true] .k-blocks{background:var(--color-background)}.k-blocks[data-multi-select-key=true] .k-block-container>*{pointer-events:none}.k-blocks[data-empty=true]{padding:0;background:0 0;box-shadow:none}.k-blocks .k-sortable-ghost{outline:2px solid var(--color-focus);box-shadow:#11111140 0 5px 10px;cursor:grabbing;cursor:-webkit-grabbing}.k-blocks-list>.k-blocks-empty{display:flex;align-items:center}.k-blocks-list>.k-blocks-empty:not(:only-child){display:none}.k-block-figure{cursor:pointer}.k-block-figure iframe{border:0;pointer-events:none;background:var(--color-black)}.k-block-figure figcaption{padding-top:.5rem;color:var(--color-gray-600);font-size:var(--text-sm);text-align:center}.k-block-figure-empty.k-button{display:flex;width:100%;height:6rem;border-radius:var(--rounded-sm);align-items:center;justify-content:center;color:var(--color-gray-600);background:var(--color-background)}.k-block-options{display:flex;align-items:center;background:var(--color-white);z-index:var(--z-dropdown);box-shadow:#0000001a -2px 0 5px,var(--shadow),var(--shadow-xl);color:var(--color-black);border-radius:var(--rounded)}[dir=ltr] .k-block-options-button{border-right:1px solid var(--color-background)}[dir=rtl] .k-block-options-button{border-left:1px solid var(--color-background)}.k-block-options-button{--block-options-button-size:30px;width:var(--block-options-button-size);height:var(--block-options-button-size);line-height:1;display:inline-flex;align-items:center;justify-content:center}[dir=ltr] .k-block-options-button:first-child{border-top-left-radius:var(--rounded)}[dir=rtl] .k-block-options-button:first-child{border-top-right-radius:var(--rounded)}[dir=ltr] .k-block-options-button:first-child{border-bottom-left-radius:var(--rounded)}[dir=rtl] .k-block-options-button:first-child{border-bottom-right-radius:var(--rounded)}[dir=ltr] .k-block-options-button:last-child{border-top-right-radius:var(--rounded)}[dir=rtl] .k-block-options-button:last-child{border-top-left-radius:var(--rounded)}[dir=ltr] .k-block-options-button:last-child{border-bottom-right-radius:var(--rounded)}[dir=rtl] .k-block-options-button:last-child{border-bottom-left-radius:var(--rounded)}[dir=ltr] .k-block-options-button:last-of-type{border-right:0}[dir=rtl] .k-block-options-button:last-of-type{border-left:0}.k-block-options-button[aria-current]{color:var(--color-focus)}.k-block-options-button:hover{background:var(--color-gray-100)}.k-block-options .k-dropdown-content{margin-top:.5rem}.k-block-selector.k-dialog{background:var(--color-dark);color:var(--color-white)}.k-block-selector .k-headline{margin-bottom:1rem}.k-block-selector details:not(:last-of-type){margin-bottom:1.5rem}.k-block-selector summary{font-size:var(--text-xs);cursor:pointer;color:var(--color-gray-400)}.k-block-selector details:only-of-type summary{pointer-events:none}.k-block-selector summary:focus{outline:0}.k-block-selector summary:focus-visible{color:var(--color-green-400)}.k-block-types{display:grid;grid-gap:2px;margin-top:.75rem;grid-template-columns:repeat(1,1fr)}[dir=ltr] .k-block-types .k-button{text-align:left}[dir=rtl] .k-block-types .k-button{text-align:right}.k-block-types .k-button{display:flex;align-items:flex-start;border-radius:var(--rounded);background:rgba(0,0,0,.5);width:100%;padding:0 .75rem 0 0;line-height:1.5em}.k-block-types .k-button:focus{outline:2px solid var(--color-green-300)}.k-block-types .k-button .k-button-text{padding:.5rem 0 .5rem .5rem}.k-block-types .k-button .k-icon{width:38px;height:38px}.k-clipboard-hint{padding-top:1.5rem;font-size:var(--text-xs);color:var(--color-gray-400)}.k-clipboard-hint kbd{background:rgba(0,0,0,.5);font-family:var(--font-mono);letter-spacing:.1em;padding:.25rem;border-radius:var(--rounded);margin:0 .25rem}[dir=ltr] .k-block-title{padding-right:.75rem}[dir=rtl] .k-block-title{padding-left:.75rem}.k-block-title{display:flex;align-items:center;min-width:0;font-size:var(--text-sm);line-height:1}[dir=ltr] .k-block-icon{margin-right:.5rem}[dir=rtl] .k-block-icon{margin-left:.5rem}.k-block-icon{width:1rem;color:var(--color-gray-500)}[dir=ltr] .k-block-name{margin-right:.5rem}[dir=rtl] .k-block-name{margin-left:.5rem}.k-block-label{color:var(--color-gray-600);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.k-bubbles-field-preview{padding:.325rem .75rem}.k-text-field-preview{padding:.325rem .75rem;overflow-x:hidden;text-overflow:ellipsis;white-space:nowrap}.k-url-field-preview{padding:.325rem .75rem;overflow-x:hidden;text-overflow:ellipsis}.k-url-field-preview[data-link]{color:var(--color-focus)}.k-url-field-preview a{text-decoration:underline;transition:color .3s;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.k-url-field-preview a:hover{color:var(--color-black)}.k-flag-field-preview{height:var(--table-row-height);width:var(--table-row-height);display:flex;justify-content:center;align-items:center}.k-html-field-preview{padding:.325rem .75rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1.5em}.k-html-field-preview p:not(:last-child){margin-bottom:1.5em}[dir=ltr] .k-html-field-preview ol,[dir=ltr] .k-html-field-preview ul{margin-left:1rem}[dir=rtl] .k-html-field-preview ol,[dir=rtl] .k-html-field-preview ul{margin-right:1rem}.k-html-field-preview ul>li{list-style:disc}.k-html-field-preview ol ul>li,.k-html-field-preview ul ul>li{list-style:circle}.k-html-field-preview ol>li{list-style:decimal}.k-html-field-preview ol>li::marker{color:var(--color-gray-500);font-size:var(--text-xs)}.k-toggle-field-preview label{padding:0 .25rem 0 .75rem;display:flex;height:38px;cursor:pointer;overflow:hidden;white-space:nowrap}[dir=ltr] .k-toggle-field-preview .k-toggle-input-label{padding-left:.5rem}[dir=ltr] [data-align=right] .k-toggle-field-preview .k-toggle-input-label,[dir=rtl] .k-toggle-field-preview .k-toggle-input-label{padding-right:.5rem}[dir=rtl] [data-align=right] .k-toggle-field-preview .k-toggle-input-label{padding-left:.5rem}[dir=ltr] .k-toggle-field-preview .k-toggle-input{padding-left:.75rem;padding-right:.25rem}.k-toggle-field-preview .k-toggle-input{padding-top:0;padding-bottom:0}[dir=ltr] [data-align=right] .k-toggle-field-preview .k-toggle-input,[dir=rtl] .k-toggle-field-preview .k-toggle-input{padding-left:.25rem;padding-right:.75rem}[dir=rtl] [data-align=right] .k-toggle-field-preview .k-toggle-input{padding-right:.25rem;padding-left:.75rem}[data-align=right] .k-toggle-field-preview .k-toggle-input{flex-direction:row-reverse}:root{--color-backdrop:rgba(0, 0, 0, .6);--color-black:#000;--color-dark:#313740;--color-light:var(--color-gray-200);--color-white:#fff;--color-gray-100:#f7f7f7;--color-gray-200:#efefef;--color-gray-300:#ddd;--color-gray-400:#ccc;--color-gray-500:#999;--color-gray-600:#777;--color-gray-700:#555;--color-gray-800:#333;--color-gray-900:#111;--color-gray:var(--color-gray-600);--color-red-200:#edc1c1;--color-red-300:#e3a0a0;--color-red-400:#d16464;--color-red-600:#ce1f1f;--color-red:var(--color-red-600);--color-orange-200:#f2d4bf;--color-orange-300:#ebbe9e;--color-orange-400:#de935f;--color-orange-600:#f4861f;--color-orange:var(--color-orange-600);--color-yellow-200:#f9e8c7;--color-yellow-300:#f7e2b8;--color-yellow-400:#f0c674;--color-yellow-600:#cca000;--color-yellow:var(--color-yellow-600);--color-green-200:#dce5c2;--color-green-300:#c6d49d;--color-green-400:#a7bd68;--color-green-600:#678f00;--color-green:var(--color-green-600);--color-aqua-200:#d0e5e2;--color-aqua-300:#bbd9d5;--color-aqua-400:#8abeb7;--color-aqua-600:#398e93;--color-aqua:var(--color-aqua-600);--color-blue-200:#cbd7e5;--color-blue-300:#b1c2d8;--color-blue-400:#7e9abf;--color-blue-600:#4271ae;--color-blue:var(--color-blue-600);--color-purple-200:#e0d4e4;--color-purple-300:#d4c3d9;--color-purple-400:#b294bb;--color-purple-600:#9c48b9;--color-purple:var(--color-purple-600);--container:80rem;--font-sans:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";--font-mono:"SFMono-Regular", Consolas, Liberation Mono, Menlo, Courier, monospace;--font-normal:400;--font-bold:600;--leading-none:1;--leading-tight:1.25;--leading-snug:1.375;--leading-normal:1.5;--leading-relaxed:1.625;--leading-loose:2;--rounded-xs:1px;--rounded-sm:.125rem;--rounded:.25rem;--rounded-md:.375rem;--shadow:0 1px 3px 0 rgba(0, 0, 0, .1), 0 1px 2px 0 rgba(0, 0, 0, .06);--shadow-md:0 4px 6px -1px rgba(0, 0, 0, .1), 0 2px 4px -1px rgba(0, 0, 0, .06);--shadow-lg:0 10px 15px -3px rgba(0, 0, 0, .1), 0 4px 6px -2px rgba(0, 0, 0, .05);--shadow-xl:0 20px 25px -5px rgba(0, 0, 0, .1), 0 10px 10px -5px rgba(0, 0, 0, .04);--shadow-outline:currentColor 0 0 0 2px;--shadow-inset:inset 0 2px 4px 0 rgba(0, 0, 0, .06);--spacing-0:0;--spacing-px:1px;--spacing-2px:2px;--spacing-1:.25rem;--spacing-2:.5rem;--spacing-3:.75rem;--spacing-4:1rem;--spacing-5:1.25rem;--spacing-6:1.5rem;--spacing-8:2rem;--spacing-10:2.5rem;--spacing-12:3rem;--spacing-16:4rem;--spacing-20:5rem;--spacing-24:6rem;--spacing-36:9rem;--text-xs:.75rem;--text-sm:.875rem;--text-base:1rem;--text-lg:1.125rem;--text-xl:1.25rem;--text-2xl:1.5rem;--text-3xl:1.75rem;--text-4xl:2.5rem;--text-5xl:3rem;--text-6xl:4rem;--color-background:var(--color-light);--color-border:var(--color-gray-400);--color-focus:var(--color-blue-600);--color-focus-light:var(--color-blue-400);--color-focus-outline:rgba(113, 143, 183, .25);--color-negative:var(--color-red-600);--color-negative-light:var(--color-red-400);--color-negative-outline:rgba(212, 110, 110, .25);--color-notice:var(--color-orange-600);--color-notice-light:var(--color-orange-400);--color-positive:var(--color-green-600);--color-positive-light:var(--color-green-400);--color-positive-outline:rgba(128, 149, 65, .25);--color-text:var(--color-gray-900);--color-text-light:var(--color-gray-600);--z-offline:1200;--z-fatal:1100;--z-loader:1000;--z-notification:900;--z-dialog:800;--z-navigation:700;--z-dropdown:600;--z-drawer:500;--z-dropzone:400;--z-toolbar:300;--z-content:200;--z-background:100;--bg-pattern:repeating-conic-gradient( rgba(0, 0, 0, 0) 0% 25%, rgba(0, 0, 0, .2) 0% 50% ) 50% / 20px 20px;--shadow-sticky:rgba(0, 0, 0, .05) 0 2px 5px;--shadow-dropdown:var(--shadow-lg);--shadow-item:var(--shadow);--field-input-padding:.5rem;--field-input-height:2.25rem;--field-input-line-height:1.25rem;--field-input-font-size:var(--text-base);--field-input-color-before:var(--color-gray-700);--field-input-color-after:var(--color-gray-700);--field-input-border:1px solid var(--color-border);--field-input-focus-border:1px solid var(--color-focus);--field-input-focus-outline:2px solid var(--color-focus-outline);--field-input-invalid-border:1px solid var(--color-negative-outline);--field-input-invalid-outline:0;--field-input-invalid-focus-border:1px solid var(--color-negative);--field-input-invalid-focus-outline:2px solid var(--color-negative-outline);--field-input-background:var(--color-white);--field-input-disabled-color:var(--color-gray-500);--field-input-disabled-background:var(--color-white);--field-input-disabled-border:1px solid var(--color-gray-300);--font-family-sans:var(--font-sans);--font-family-mono:var(--font-mono);--font-size-tiny:var(--text-xs);--font-size-small:var(--text-sm);--font-size-medium:var(--text-base);--font-size-large:var(--text-xl);--font-size-huge:var(--text-2xl);--font-size-monster:var(--text-3xl);--box-shadow-dropdown:var(--shadow-dropdown);--box-shadow-item:var(--shadow);--box-shadow-focus:var(--shadow-xl)}*,:after,:before{margin:0;padding:0;box-sizing:border-box}noscript{padding:1.5rem;display:flex;align-items:center;justify-content:center;height:100vh;text-align:center}html{font-family:var(--font-sans);background:var(--color-background)}body,html{color:var(--color-gray-900);height:100%;overflow:hidden}a{color:inherit;text-decoration:none}li{list-style:none}b,strong{font-weight:var(--font-bold)}@keyframes LoadingCursor{to{cursor:progress}}@keyframes Spin{to{transform:rotate(360deg)}}[data-align=left]{--align:start}[data-align=center]{--align:center}[data-align=right]{--align:end}[data-invalid=true]{border:1px solid var(--color-negative-outline);box-shadow:var(--color-negative-outline) 0 0 3px 2px}[data-invalid=true]:focus-within{border:var(--field-input-invalid-focus-border)!important;box-shadow:var(--color-negative-outline) 0 0 0 2px!important}[data-tabbed=true]{box-shadow:var(--shadow-outline);border-radius:var(--rounded)}[data-theme=positive],[data-theme=success]{--theme:var(--color-positive);--theme-light:var(--color-positive-light);--theme-bg:var(--color-green-300)}[data-theme=error],[data-theme=negative]{--theme:var(--color-negative);--theme-light:var(--color-negative-light);--theme-bg:var(--color-red-300)}[data-theme=notice]{--theme:var(--color-notice);--theme-light:var(--color-notice-light);--theme-bg:var(--color-orange-300)}[data-theme=info]{--theme:var(--color-focus);--theme-light:var(--color-focus-light);--theme-bg:var(--color-blue-200)}.scroll-x,.scroll-x-auto,.scroll-y,.scroll-y-auto{-webkit-overflow-scrolling:touch;transform:translateZ(0)}.scroll-x,.scroll-x-auto{overflow-x:scroll;overflow-y:hidden}.scroll-x-auto{overflow-x:auto}.scroll-y,.scroll-y-auto{overflow-x:hidden;overflow-y:scroll}.scroll-y-auto{overflow-y:auto}.input-hidden{position:absolute;-webkit-appearance:none;-moz-appearance:none;appearance:none;width:0;height:0;opacity:0}.k-offscreen,.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0} diff --git a/kirby/panel/dist/img/icons.svg b/kirby/panel/dist/img/icons.svg index d0eba91..81446cd 100644 --- a/kirby/panel/dist/img/icons.svg +++ b/kirby/panel/dist/img/icons.svg @@ -409,6 +409,9 @@ + + + diff --git a/kirby/panel/dist/js/index.js b/kirby/panel/dist/js/index.js index 5600308..fb984ad 100644 --- a/kirby/panel/dist/js/index.js +++ b/kirby/panel/dist/js/index.js @@ -1 +1 @@ -import{V as t,a as e,m as s,d as n,c as i,b as o,I as r,P as l,S as a,F as u,N as c,s as d,l as p,w as h,e as m,f,t as g,g as k,h as b,i as y,j as v,k as $,n as _,D as x,o as w,E as S,p as C,q as O,r as A,T,u as I,v as M,x as E,y as L,z as j,A as D,B,C as P,G as N,H as q}from"./vendor.js";const F=t=>({changeName:async(e,s,n)=>t.patch(e+"/files/"+s+"/name",{name:n}),delete:async(e,s)=>t.delete(e+"/files/"+s),async get(e,s,n){let i=await t.get(e+"/files/"+s,n);return!0===Array.isArray(i.content)&&(i.content={}),i},link(t,e,s){return"/"+this.url(t,e,s)},update:async(e,s,n)=>t.patch(e+"/files/"+s,n),url(t,e,s){let n=t+"/files/"+e;return s&&(n+="/"+s),n}}),R=t=>({async blueprint(e){return t.get("pages/"+this.id(e)+"/blueprint")},async blueprints(e,s){return t.get("pages/"+this.id(e)+"/blueprints",{section:s})},async changeSlug(e,s){return t.patch("pages/"+this.id(e)+"/slug",{slug:s})},async changeStatus(e,s,n){return t.patch("pages/"+this.id(e)+"/status",{status:s,position:n})},async changeTemplate(e,s){return t.patch("pages/"+this.id(e)+"/template",{template:s})},async changeTitle(e,s){return t.patch("pages/"+this.id(e)+"/title",{title:s})},async children(e,s){return t.post("pages/"+this.id(e)+"/children/search",s)},async create(e,s){return null===e||"/"===e?t.post("site/children",s):t.post("pages/"+this.id(e)+"/children",s)},async delete(e,s){return t.delete("pages/"+this.id(e),s)},async duplicate(e,s,n){return t.post("pages/"+this.id(e)+"/duplicate",{slug:s,children:n.children||!1,files:n.files||!1})},async get(e,s){let n=await t.get("pages/"+this.id(e),s);return!0===Array.isArray(n.content)&&(n.content={}),n},id:t=>t.replace(/\//g,"+"),async files(e,s){return t.post("pages/"+this.id(e)+"/files/search",s)},link(t){return"/"+this.url(t)},async preview(t){return(await this.get(this.id(t),{select:"previewUrl"})).previewUrl},async search(e,s){return e?t.post("pages/"+this.id(e)+"/children/search?select=id,title,hasChildren",s):t.post("site/children/search?select=id,title,hasChildren",s)},async update(e,s){return t.patch("pages/"+this.id(e),s)},url(t,e){let s=null===t?"pages":"pages/"+String(t).replace(/\//g,"+");return e&&(s+="/"+e),s}});const z=t=>({running:0,async request(e,s,n=!1){s=Object.assign(s||{},{credentials:"same-origin",cache:"no-store",headers:{"x-requested-with":"xmlhttprequest","content-type":"application/json",...s.headers}}),t.methodOverwrite&&"GET"!==s.method&&"POST"!==s.method&&(s.headers["x-http-method-override"]=s.method,s.method="POST"),s=t.onPrepare(s);const i=e+"/"+JSON.stringify(s);t.onStart(i,n),this.running++;const o=await fetch([t.endpoint,e].join(t.endpoint.endsWith("/")||e.startsWith("/")?"":"/"),s);try{const e=await async function(t){const e=await t.text();let s;try{s=JSON.parse(e)}catch(n){return window.panel.$vue.$api.onParserError({html:e}),!1}return s}(o);if(o.status<200||o.status>299)throw e;if("error"===e.status)throw e;let s=e;return e.data&&"model"===e.type&&(s=e.data),this.running--,t.onComplete(i),t.onSuccess(e),s}catch(r){throw this.running--,t.onComplete(i),t.onError(r),r}},async get(t,e,s,n=!1){return e&&(t+="?"+Object.keys(e).filter((t=>void 0!==e[t]&&null!==e[t])).map((t=>t+"="+e[t])).join("&")),this.request(t,Object.assign(s||{},{method:"GET"}),n)},async post(t,e,s,n="POST",i=!1){return this.request(t,Object.assign(s||{},{method:n,body:JSON.stringify(e)}),i)},async patch(t,e,s,n=!1){return this.post(t,e,s,"PATCH",n)},async delete(t,e,s,n=!1){return this.post(t,e,s,"DELETE",n)}}),Y=t=>({blueprint:async e=>t.get("users/"+e+"/blueprint"),blueprints:async(e,s)=>t.get("users/"+e+"/blueprints",{section:s}),changeEmail:async(e,s)=>t.patch("users/"+e+"/email",{email:s}),changeLanguage:async(e,s)=>t.patch("users/"+e+"/language",{language:s}),changeName:async(e,s)=>t.patch("users/"+e+"/name",{name:s}),changePassword:async(e,s)=>t.patch("users/"+e+"/password",{password:s}),changeRole:async(e,s)=>t.patch("users/"+e+"/role",{role:s}),create:async e=>t.post("users",e),delete:async e=>t.delete("users/"+e),deleteAvatar:async e=>t.delete("users/"+e+"/avatar"),link(t,e){return"/"+this.url(t,e)},async list(e){return t.post(this.url(null,"search"),e)},get:async(e,s)=>t.get("users/"+e,s),async roles(e){return(await t.get(this.url(e,"roles"))).data.map((t=>({info:t.description||`(${window.panel.$t("role.description.placeholder")})`,text:t.title,value:t.name})))},search:async e=>t.post("users/search",e),update:async(e,s)=>t.patch("users/"+e,s),url(t,e){let s=t?"users/"+t:"users";return e&&(s+="/"+e),s}}),H={install(t,e){t.prototype.$api=t.$api=((t={})=>{const e={...{endpoint:"/api",methodOverwrite:!0,onPrepare:t=>t,onStart(){},onComplete(){},onSuccess(){},onParserError(){},onError(t){throw window.console.log(t.message),t}},...t.config||{}};let s={...e,...z(e),...t};return s.auth=(t=>({async login(e){const s={long:e.remember||!1,email:e.email,password:e.password};return t.post("auth/login",s)},logout:async()=>t.post("auth/logout"),user:async e=>t.get("auth",e),verifyCode:async e=>t.post("auth/code",{code:e})}))(s),s.files=F(s),s.languages=(t=>({create:async e=>t.post("languages",e),delete:async e=>t.delete("languages/"+e),get:async e=>t.get("languages/"+e),list:async()=>t.get("languages"),update:async(e,s)=>t.patch("languages/"+e,s)}))(s),s.pages=R(s),s.roles=(t=>({list:async e=>t.get("roles",e),get:async e=>t.get("roles/"+e)}))(s),s.system=(t=>({get:async(e={view:"panel"})=>t.get("system",e),install:async e=>(await t.post("system/install",e)).user,register:async e=>t.post("system/register",e)}))(s),s.site=(t=>({blueprint:async()=>t.get("site/blueprint"),blueprints:async()=>t.get("site/blueprints"),changeTitle:async e=>t.patch("site/title",{title:e}),children:async e=>t.post("site/children/search",e),get:async(e={view:"panel"})=>t.get("site",e),update:async e=>t.post("site",e)}))(s),s.translations=(t=>({list:async()=>t.get("translations"),get:async e=>t.get("translations/"+e)}))(s),s.users=Y(s),s})({config:{endpoint:window.panel.$urls.api,onComplete:s=>{t.$api.requests=t.$api.requests.filter((t=>t!==s)),0===t.$api.requests.length&&e.dispatch("isLoading",!1)},onError:e=>{window.panel.$config.debug&&window.console.error(e),403!==e.code||"Unauthenticated"!==e.message&&"access.panel"!==e.key||t.prototype.$go("/logout")},onParserError:({html:t,silent:s})=>{e.dispatch("fatal",{html:t,silent:s})},onPrepare:t=>(window.panel.$language&&(t.headers["x-language"]=window.panel.$language.code),t.headers["x-csrf"]=window.panel.$system.csrf,t),onStart:(s,n=!1)=>{!1===n&&e.dispatch("isLoading",!0),t.$api.requests.push(s)},onSuccess:()=>{clearInterval(t.$api.ping),t.$api.ping=setInterval(t.$api.auth.user,3e5)}},ping:null,requests:[]}),t.$api.ping=setInterval(t.$api.auth.user,3e5)}},U={name:"Fiber",data:()=>({component:null,state:window.fiber,key:null}),created(){this.$fiber.init(this.state,{base:document.querySelector("base").href,headers:()=>({"X-CSRF":this.state.$system.csrf}),onFatal({text:t,options:e}){this.$store.dispatch("fatal",{html:t,silent:e.silent})},onFinish:()=>{0===this.$api.requests.length&&this.$store.dispatch("isLoading",!1)},onPushState:t=>{window.history.pushState(t,"",t.$url)},onReplaceState:t=>{window.history.replaceState(t,"",t.$url)},onStart:({silent:t})=>{!0!==t&&this.$store.dispatch("isLoading",!0)},onSwap:async(t,e)=>{e={navigate:!0,replace:!1,...e},this.setGlobals(t),this.setTitle(t),this.setTranslation(t),this.component=t.$view.component,this.state=t,this.key=!0===e.replace?this.key:t.$view.timestamp,!0===e.navigate&&this.navigate()},query:()=>{var t;return{language:null==(t=this.state.$language)?void 0:t.code}}}),window.addEventListener("popstate",this.$reload)},methods:{navigate(){this.$store.dispatch("navigate")},setGlobals(e){["$config","$direction","$language","$languages","$license","$menu","$multilang","$permissions","$searches","$system","$translation","$urls","$user","$view"].forEach((s=>{void 0!==e[s]?t.prototype[s]=window.panel[s]=e[s]:t.prototype[s]=e[s]=window.panel[s]}))},setTitle(t){t.$view.title?document.title=t.$view.title+" | "+t.$system.title:document.title=t.$system.title},setTranslation(t){t.$translation&&(document.documentElement.lang=t.$translation.code)}},render(t){if(this.component)return t(this.component,{key:this.key,props:this.state.$view.props})}};function K(t){if(void 0!==t)return JSON.parse(JSON.stringify(t))}function G(t,e){for(const s of Object.keys(e))e[s]instanceof Object&&Object.assign(e[s],G(t[s]||{},e[s]));return Object.assign(t||{},e),t}const J={clone:K,isEmpty:function(t){return null==t||""===t||("object"==typeof t&&0===Object.keys(t).length&&t.constructor===Object||void 0!==t.length&&0===t.length)},merge:G},V=(t,e)=>{localStorage.setItem("kirby$content$"+t,JSON.stringify(e))},W={namespaced:!0,state:{current:null,models:{},status:{enabled:!0}},getters:{exists:t=>e=>Object.prototype.hasOwnProperty.call(t.models,e),hasChanges:(t,e)=>t=>{const s=e.model(t).changes;return Object.keys(s).length>0},isCurrent:t=>e=>t.current===e,id:t=>e=>(e=e||t.current,window.panel.$language?e+"?language="+window.panel.$language.code:e),model:(t,e)=>s=>(s=s||t.current,!0===e.exists(s)?t.models[s]:{api:null,originals:{},values:{},changes:{}}),originals:(t,e)=>t=>K(e.model(t).originals),values:(t,e)=>t=>({...e.originals(t),...e.changes(t)}),changes:(t,e)=>t=>K(e.model(t).changes)},mutations:{CLEAR(t){Object.keys(t.models).forEach((e=>{t.models[e].changes={}})),Object.keys(localStorage).forEach((t=>{t.startsWith("kirby$content$")&&localStorage.removeItem(t)}))},CREATE(e,[s,n]){if(!n)return!1;let i=e.models[s]?e.models[s].changes:n.changes;t.set(e.models,s,{api:n.api,originals:n.originals,changes:i||{}})},CURRENT(t,e){t.current=e},MOVE(e,[s,n]){const i=K(e.models[s]);t.delete(e.models,s),t.set(e.models,n,i);const o=localStorage.getItem("kirby$content$"+s);localStorage.removeItem("kirby$content$"+s),localStorage.setItem("kirby$content$"+n,o)},REMOVE(e,s){t.delete(e.models,s),localStorage.removeItem("kirby$content$"+s)},REVERT(e,s){e.models[s]&&(t.set(e.models[s],"changes",{}),localStorage.removeItem("kirby$content$"+s))},STATUS(e,s){t.set(e.status,"enabled",s)},UPDATE(e,[s,n,i]){if(!e.models[s])return!1;void 0===i&&(i=null),i=K(i);const o=JSON.stringify(i);JSON.stringify(e.models[s].originals[n])==o?t.delete(e.models[s].changes,n):t.set(e.models[s].changes,n,i),V(s,{api:e.models[s].api,originals:e.models[s].originals,changes:e.models[s].changes})}},actions:{init(t){Object.keys(localStorage).filter((t=>t.startsWith("kirby$content$"))).map((t=>t.split("kirby$content$")[1])).forEach((e=>{const s=localStorage.getItem("kirby$content$"+e);t.commit("CREATE",[e,JSON.parse(s)])})),Object.keys(localStorage).filter((t=>t.startsWith("kirby$form$"))).map((t=>t.split("kirby$form$")[1])).forEach((e=>{const s=localStorage.getItem("kirby$form$"+e);let n=null;try{n=JSON.parse(s)}catch(o){}if(!n||!n.api)return localStorage.removeItem("kirby$form$"+e),!1;const i={api:n.api,originals:n.originals,changes:n.values};t.commit("CREATE",[e,i]),V(e,i),localStorage.removeItem("kirby$form$"+e)}))},clear(t){t.commit("CLEAR")},create(t,e){const s=K(e.content);Array.isArray(e.ignore)&&e.ignore.forEach((t=>delete s[t])),e.id=t.getters.id(e.id);const n={api:e.api,originals:s,changes:{}};t.commit("CREATE",[e.id,n]),t.dispatch("current",e.id)},current(t,e){t.commit("CURRENT",e)},disable(t){t.commit("STATUS",!1)},enable(t){t.commit("STATUS",!0)},move(t,[e,s]){e=t.getters.id(e),s=t.getters.id(s),t.commit("MOVE",[e,s])},remove(t,e){t.commit("REMOVE",e),t.getters.isCurrent(e)&&t.commit("CURRENT",null)},revert(t,e){e=e||t.state.current,t.commit("REVERT",e)},async save(e,s){if(s=s||e.state.current,e.getters.isCurrent(s)&&!1===e.state.status.enabled)return!1;e.dispatch("disable");const n=e.getters.model(s),i={...n.originals,...n.changes};try{await t.$api.patch(n.api,i),e.commit("CREATE",[s,{...n,originals:i}]),e.dispatch("revert",s)}finally{e.dispatch("enable")}},update(t,[e,s,n]){n=n||t.state.current,t.commit("UPDATE",[n,e,s])}}},X={namespaced:!0,state:{open:[]},mutations:{CLOSE(t,e){t.open=e?t.open.filter((t=>t.id!==e)):[]},GOTO(t,e){t.open=t.open.slice(0,t.open.findIndex((t=>t.id===e))+1)},OPEN(t,e){t.open.push(e)}},actions:{close(t,e){t.commit("CLOSE",e)},goto(t,e){t.commit("GOTO",e)},open(t,e){t.commit("OPEN",e)}}},Z={timer:null,namespaced:!0,state:{type:null,message:null,details:null,timeout:null},mutations:{SET(t,e){t.type=e.type,t.message=e.message,t.details=e.details,t.timeout=e.timeout},UNSET(t){t.type=null,t.message=null,t.details=null,t.timeout=null}},actions:{close(t){clearTimeout(this.timer),t.commit("UNSET")},deprecated(t,e){console.warn("Deprecated: "+e)},error(t,e){let s=e;"string"==typeof e&&(s={message:e}),e instanceof Error&&(s={message:e.message},window.panel.$config.debug&&window.console.error(e)),t.dispatch("dialog",{component:"k-error-dialog",props:s},{root:!0}),t.dispatch("close")},open(t,e){t.dispatch("close"),t.commit("SET",e),e.timeout&&(this.timer=setTimeout((()=>{t.dispatch("close")}),e.timeout))},success(t,e){"string"==typeof e&&(e={message:e}),t.dispatch("open",{type:"success",timeout:4e3,...e})}}};t.use(e);const Q=new e.Store({strict:!1,state:{dialog:null,drag:null,fatal:!1,isLoading:!1},mutations:{SET_DIALOG(t,e){t.dialog=e},SET_DRAG(t,e){t.drag=e},SET_FATAL(t,e){t.fatal=e},SET_LOADING(t,e){t.isLoading=e}},actions:{dialog(t,e){t.commit("SET_DIALOG",e)},drag(t,e){t.commit("SET_DRAG",e)},fatal(t,e){!1!==e?(console.error("The JSON response could not be parsed"),window.panel.$config.debug&&console.info(e.html),e.silent||t.commit("SET_FATAL",e.html)):t.commit("SET_FATAL",!1)},isLoading(t,e){t.commit("SET_LOADING",!0===e)},navigate(t){t.dispatch("dialog",null),t.dispatch("drawers/close")}},modules:{content:W,drawers:X,notification:Z}}),tt={install(t){window.panel=window.panel||{},window.onunhandledrejection=t=>{t.preventDefault(),Q.dispatch("notification/error",t.reason)},window.panel.deprecated=t=>{Q.dispatch("notification/deprecated",t)},window.panel.error=t.config.errorHandler=t=>{Q.dispatch("notification/error",t)}}},et={install(t){const e=s(),n={$on:e.on,$off:e.off,$emit:e.emit,blur(t){n.$emit("blur",t)},click(t){n.$emit("click",t)},copy(t){n.$emit("copy",t)},dragenter(t){n.entered=t.target,n.prevent(t),n.$emit("dragenter",t)},dragleave(t){n.prevent(t),n.entered===t.target&&n.$emit("dragleave",t)},drop(t){n.prevent(t),n.$emit("drop",t)},entered:null,focus(t){n.$emit("focus",t)},keydown(e){let s=["keydown"];(e.metaKey||e.ctrlKey)&&s.push("cmd"),!0===e.altKey&&s.push("alt"),!0===e.shiftKey&&s.push("shift");let i=t.prototype.$helper.string.lcfirst(e.key);const o={escape:"esc",arrowUp:"up",arrowDown:"down",arrowLeft:"left",arrowRight:"right"};o[i]&&(i=o[i]),!1===["alt","control","shift","meta"].includes(i)&&s.push(i),n.$emit(s.join("."),e),n.$emit("keydown",e)},keyup(t){n.$emit("keyup",t)},online(t){n.$emit("online",t)},offline(t){n.$emit("offline",t)},paste(t){n.$emit("paste",t)},prevent(t){t.stopPropagation(),t.preventDefault()}};document.addEventListener("click",n.click,!1),document.addEventListener("copy",n.copy,!0),document.addEventListener("focus",n.focus,!0),document.addEventListener("paste",n.paste,!0),window.addEventListener("blur",n.blur,!1),window.addEventListener("dragenter",n.dragenter,!1),window.addEventListener("dragexit",n.prevent,!1),window.addEventListener("dragleave",n.dragleave,!1),window.addEventListener("drop",n.drop,!1),window.addEventListener("dragover",n.prevent,!1),window.addEventListener("keydown",n.keydown,!1),window.addEventListener("keyup",n.keyup,!1),window.addEventListener("offline",n.offline),window.addEventListener("online",n.online),t.prototype.$events=n}};class st{constructor(t={}){this.options={base:"/",headers:()=>({}),onFatal:()=>{},onFinish:()=>{},onPushState:()=>{},onReplaceState:()=>{},onStart:()=>{},onSwap:()=>{},query:()=>({}),...t},this.state={}}init(t={},e={}){this.options={...this.options,...e},this.setState(t)}arrayToString(t){return!1===Array.isArray(t)?String(t):t.join(",")}body(t){return"object"==typeof t?JSON.stringify(t):t}async fetch(t,e){return fetch(t,e)}async go(t,e){try{const s=await this.request(t,e);return!1!==s&&this.setState(s,e)}catch(s){if(!0!==(null==e?void 0:e.silent))throw s}}query(t={},e={}){let s=new URLSearchParams(e);return"object"!=typeof t&&(t={}),Object.entries(t).forEach((([t,e])=>{null!==e&&s.set(t,e)})),Object.entries(this.options.query()).forEach((([t,e])=>{var n,i;null!==(e=null!=(i=null!=(n=s.get(t))?n:e)?i:null)&&s.set(t,e)})),s}redirect(t){window.location.href=t}reload(t={}){return this.go(window.location.href,{...t,replace:!0})}async request(t="",e={}){var s;const n=!!(e={globals:!1,method:"GET",only:[],query:{},silent:!1,type:"$view",...e}).globals&&this.arrayToString(e.globals),i=this.arrayToString(e.only);this.options.onStart(e);try{const r=this.url(t,e.query);if(new URL(r).origin!==location.origin)return this.redirect(r),!1;const l=await this.fetch(r,{method:e.method,body:this.body(e.body),credentials:"same-origin",cache:"no-store",headers:{...this.options.headers(),"X-Fiber":!0,"X-Fiber-Globals":n,"X-Fiber-Only":i,"X-Fiber-Referrer":(null==(s=this.state.$view)?void 0:s.path)||null,...e.headers}});if(!1===l.headers.has("X-Fiber"))return this.redirect(l.url),!1;const a=await l.text();let u;try{u=JSON.parse(a)}catch(o){return this.options.onFatal({url:r,path:t,options:e,response:l,text:a}),!1}if(!u[e.type])throw Error(`The ${e.type} could not be loaded`);const c=u[e.type];if(c.error)throw Error(c.error);return"$view"===e.type?i.length?G(this.state,u):u:c}finally{this.options.onFinish(e)}}async setState(t,e={}){return"object"==typeof t&&(this.state=K(t),!0===e.replace||this.url(this.state.$url).href===window.location.href?this.options.onReplaceState(this.state,e):this.options.onPushState(this.state,e),this.options.onSwap(this.state,e),this.state)}url(t="",e={}){return(t="string"==typeof t&&null===t.match(/^https?:\/\//)?new URL(this.options.base+t.replace(/^\//,"")):new URL(t)).search=this.query(e,t.search),t}}const nt=async function(t){return{cancel:null,submit:null,props:{},...t}},it=async function(t,e={}){let s=null,n=null;"function"==typeof e?(s=e,e={}):(s=e.submit,n=e.cancel);let i=await this.$fiber.request("dialogs/"+t,{...e,type:"$dialog"});return"object"==typeof i&&(i.submit=s||null,i.cancel=n||null,i)};async function ot(t,e={}){let s=null;if(s="object"==typeof t?await nt.call(this,t):await it.call(this,t,e),!s)return!1;if(!s.component||!1===this.$helper.isComponent(s.component))throw Error("The dialog component does not exist");return s.props=s.props||{},this.$store.dispatch("dialog",s),s}function rt(t,e={}){return async s=>{const n=await this.$fiber.request("dropdowns/"+t,{...e,type:"$dropdown"});if(!n)return!1;if(!1===Array.isArray(n.options)||0===n.options.length)throw Error("The dropdown is empty");n.options.map((t=>(t.dialog&&(t.click=()=>{const e="string"==typeof t.dialog?t.dialog:t.dialog.url,s="object"==typeof t.dialog?t.dialog:{};return this.$dialog(e,s)}),t))),s(n.options)}}async function lt(t,e,s={}){return await this.$fiber.request("search/"+t,{query:{query:e},type:"$search",...s})}const at={install(t){const e=new st;t.prototype.$fiber=window.panel.$fiber=e,t.prototype.$dialog=window.panel.$dialog=ot,t.prototype.$dropdown=window.panel.$dropdown=rt,t.prototype.$go=window.panel.$go=e.go.bind(e),t.prototype.$reload=window.panel.$reload=e.reload.bind(e),t.prototype.$request=window.panel.$request=e.request.bind(e),t.prototype.$search=window.panel.$search=lt,t.prototype.$url=window.panel.$url=e.url.bind(e)}};const ut={read:function(t){if(!t)return null;if("string"==typeof t)return t;if(t instanceof ClipboardEvent){t.preventDefault();const e=t.clipboardData.getData("text/html")||t.clipboardData.getData("text/plain")||null;if(e)return e.replace(/\u00a0/g," ")}return null},write:function(t,e){if("string"!=typeof t&&(t=JSON.stringify(t,null,2)),e&&e instanceof ClipboardEvent)return e.preventDefault(),e.clipboardData.setData("text/plain",t),!0;const s=document.createElement("textarea");if(s.value=t,document.body.append(s),navigator.userAgent.match(/ipad|ipod|iphone/i)){s.contentEditable=!0,s.readOnly=!0;const t=document.createRange();t.selectNodeContents(s);const e=window.getSelection();e.removeAllRanges(),e.addRange(t),s.setSelectionRange(0,999999)}else s.select();return document.execCommand("copy"),s.remove(),!0}};function ct(t){if("string"==typeof t){if("pattern"===(t=t.toLowerCase()))return"var(--color-gray-800) var(--bg-pattern)";if(!1===t.startsWith("#")&&!1===t.startsWith("var(")){const e="--color-"+t;if(window.getComputedStyle(document.documentElement).getPropertyValue(e))return`var(${e})`}return t}}const dt=(t,e)=>{let s=null;return function(){clearTimeout(s),s=setTimeout((()=>t.apply(this,arguments)),e)}};function pt(t,e=!1){if(!t.match("youtu"))return!1;let s=null;try{s=new URL(t)}catch(d){return!1}const n=s.pathname.split("/").filter((t=>""!==t)),i=n[0],o=n[1],r="https://"+(!0===e?"www.youtube-nocookie.com":s.host)+"/embed",l=t=>!!t&&null!==t.match(/^[a-zA-Z0-9_-]+$/);let a=s.searchParams,u=null;switch(n.join("/")){case"embed/videoseries":case"playlist":l(a.get("list"))&&(u=r+"/videoseries");break;case"watch":l(a.get("v"))&&(u=r+"/"+a.get("v"),a.has("t")&&a.set("start",a.get("t")),a.delete("v"),a.delete("t"));break;default:s.host.includes("youtu.be")&&l(i)?(u="https://www.youtube.com/embed/"+i,a.has("t")&&a.set("start",a.get("t")),a.delete("t")):"embed"===i&&l(o)&&(u=r+"/"+o)}if(!u)return!1;const c=a.toString();return c.length&&(u+="?"+c),u}function ht(t,e=!1){let s=null;try{s=new URL(t)}catch(a){return!1}const n=s.pathname.split("/").filter((t=>""!==t));let i=s.searchParams,o=null;switch(!0===e&&i.append("dnt",1),s.host){case"vimeo.com":case"www.vimeo.com":o=n[0];break;case"player.vimeo.com":o=n[1]}if(!o||!o.match(/^[0-9]*$/))return!1;let r="https://player.vimeo.com/video/"+o;const l=i.toString();return l.length&&(r+="?"+l),r}const mt={youtube:pt,vimeo:ht,video:function(t,e=!1){return t.includes("youtu")?pt(t,e):!!t.includes("vimeo")&&ht(t,e)}},ft=e=>void 0!==t.options.components[e],gt=t=>!!t.dataTransfer&&(!!t.dataTransfer.types&&(!0===t.dataTransfer.types.includes("Files")&&!1===t.dataTransfer.types.includes("text/plain")));const kt={metaKey:function(){return window.navigator.userAgent.indexOf("Mac")>-1?"cmd":"ctrl"}},bt=(t="3/2",e="100%",s=!0)=>{const n=String(t).split("/");if(2!==n.length)return e;const i=Number(n[0]),o=Number(n[1]);let r=100;return 0!==i&&0!==o&&(r=s?r/i*o:r/o*i,r=parseFloat(String(r)).toFixed(2)),r+"%"},yt=t=>{var e=(t=t||{}).desc?-1:1,s=-e,n=/^0/,i=/\s+/g,o=/^\s+|\s+$/g,r=/[^\x00-\x80]/,l=/^0x[0-9a-f]+$/i,a=/(0x[\da-fA-F]+|(^[\+\-]?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?(?=\D|\s|$))|\d+)/g,u=/(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,c=t.insensitive?function(t){return function(t){if(t.toLocaleLowerCase)return t.toLocaleLowerCase();return t.toLowerCase()}(""+t).replace(o,"")}:function(t){return(""+t).replace(o,"")};function d(t){return t.replace(a,"\0$1\0").replace(/\0$/,"").replace(/^\0/,"").split("\0")}function p(t,e){return(!t.match(n)||1===e)&&parseFloat(t)||t.replace(i," ").replace(o,"")||0}return function(t,n){var i=c(t),o=c(n);if(!i&&!o)return 0;if(!i&&o)return s;if(i&&!o)return e;var a=d(i),h=d(o),m=parseInt(i.match(l),16)||1!==a.length&&Date.parse(i),f=parseInt(o.match(l),16)||m&&o.match(u)&&Date.parse(o)||null;if(f){if(mf)return e}for(var g=a.length,k=h.length,b=0,y=Math.max(g,k);b0)return e;if(_<0)return s;if(b===y-1)return 0}else{if(v<$)return s;if(v>$)return e}}return 0}};function vt(t){const e={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};return String(t).replace(/[&<>"'`=/]/g,(t=>e[t]))}function $t(t,e={}){const s=(t,e={})=>{var n;const i=vt(t.shift()),o=null!=(n=e[i])?n:null;return null===o?Object.prototype.hasOwnProperty.call(e,i)||"…":0===t.length?o:s(t,o)},n="[{]{1,2}[\\s]?",i="[\\s]?[}]{1,2}";return(t=t.replace(new RegExp(`${n}(.*?)${i}`,"gi"),((t,n)=>s(n.split("."),e)))).replace(new RegExp(`${n}.*${i}`,"gi"),"…")}function _t(t){const e=String(t);return e.charAt(0).toUpperCase()+e.slice(1)}RegExp.escape=function(t){return t.replace(new RegExp("[-/\\\\^$*+?.()[\\]{}]","gu"),"\\$&")};const xt={camelToKebab:function(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()},escapeHTML:vt,hasEmoji:function(t){if("string"!=typeof t)return!1;const e=t.match(/(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|[\ud83c\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|[\ud83c\ude32-\ude3a]|[\ud83c\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/i);return null!==e&&null!==e.length},lcfirst:function(t){const e=String(t);return e.charAt(0).toLowerCase()+e.slice(1)},pad:function(t,e=2){t=String(t);let s="";for(;s.length]+)>)/gi,"")},template:$t,ucfirst:_t,ucwords:function(t){return String(t).split(/ /g).map((t=>_t(t))).join(" ")},uuid:function(){let t,e,s="";for(t=0;t<32;t++)e=16*Math.random()|0,8!=t&&12!=t&&16!=t&&20!=t||(s+="-"),s+=(12==t?4:16==t?3&e|8:e).toString(16);return s}},wt=(t,e)=>{const s=Object.assign({url:"/",field:"file",method:"POST",attributes:{},complete:function(){},error:function(){},success:function(){},progress:function(){}},e),n=new FormData;n.append(s.field,t,t.name),s.attributes&&Object.keys(s.attributes).forEach((t=>{n.append(t,s.attributes[t])}));const i=new XMLHttpRequest,o=e=>{if(!e.lengthComputable||!s.progress)return;let n=Math.max(0,Math.min(100,e.loaded/e.total*100));s.progress(i,t,Math.ceil(n))};i.upload.addEventListener("loadstart",o),i.upload.addEventListener("progress",o),i.addEventListener("load",(e=>{let n=null;try{n=JSON.parse(e.target.response)}catch(o){n={status:"error",message:"The file could not be uploaded"}}"error"===n.status?s.error(i,t,n):(s.success(i,t,n),s.progress(i,t,100))})),i.addEventListener("error",(e=>{const n=JSON.parse(e.target.response);s.error(i,t,n),s.progress(i,t,100)})),i.open(s.method,s.url,!0),s.headers&&Object.keys(s.headers).forEach((t=>{const e=s.headers[t];i.setRequestHeader(t,e)})),i.send(n)},St={install(t){Array.prototype.sortBy=function(e){const s=t.prototype.$helper.sort(),n=e.split(" "),i=n[0],o=n[1]||"asc";return this.sort(((t,e)=>{const n=String(t[i]).toLowerCase(),r=String(e[i]).toLowerCase();return"desc"===o?s(r,n):s(n,r)}))},t.prototype.$helper={clipboard:ut,clone:J.clone,color:ct,embed:mt,isComponent:ft,isUploadEvent:gt,debounce:dt,keyboard:kt,object:J,pad:xt.pad,ratio:bt,slug:xt.slug,sort:yt,string:xt,upload:wt,uuid:xt.uuid},t.prototype.$esc=xt.escapeHTML}},Ct={install(t){t.$t=t.prototype.$t=window.panel.$t=(t,e,s=null)=>{if("string"!=typeof t)return;const n=window.panel.$translation.data[t]||s;return"string"!=typeof n?n:$t(n,e)},t.directive("direction",{inserted(t,e,s){!0!==s.context.disabled?t.dir=s.context.$direction:t.dir=null}})}};n.extend(i),n.extend(((t,e,s)=>{s.interpret=(t,e="date")=>{const n={date:{"YYYY-MM-DD":!0,"YYYY-MM-D":!0,"YYYY-MM-":!0,"YYYY-MM":!0,"YYYY-M-DD":!0,"YYYY-M-D":!0,"YYYY-M-":!0,"YYYY-M":!0,"YYYY-":!0,YYYYMMDD:!0,"MMM DD YYYY":!1,"MMM D YYYY":!1,"MMM DD YY":!1,"MMM D YY":!1,"MMM DD":!1,"MMM D":!1,"DD MMMM YYYY":!1,"DD MMMM YY":!1,"DD MMMM":!1,"D MMMM YYYY":!1,"D MMMM YY":!1,"D MMMM":!1,"DD MMM YYYY":!1,"D MMM YYYY":!1,"DD MMM YY":!1,"D MMM YY":!1,"DD MMM":!1,"D MMM":!1,"DD MM YYYY":!1,"DD M YYYY":!1,"D MM YYYY":!1,"D M YYYY":!1,"DD MM YY":!1,"D MM YY":!1,"DD M YY":!1,"D M YY":!1,YYYY:!0,MMMM:!0,MMM:!0,"DD MM":!1,"DD M":!1,"D MM":!1,"D M":!1,DD:!1,D:!1},time:{"HH:mm:ss a":!1,"HH:mm:ss":!1,"HH:mm a":!1,"HH:mm":!1,"HH a":!1,HH:!1}};if("string"==typeof t&&""!==t)for(const i in n[e]){const o=s(t,i,n[e][i]);if(!0===o.isValid())return o}return null}})),n.extend(((t,e,s)=>{const n=t=>"date"===t?"YYYY-MM-DD":"time"===t?"HH:mm:ss":"YYYY-MM-DD HH:mm:ss";e.prototype.toISO=function(t="datetime"){return this.format(n(t))},s.iso=function(t,e="datetime"){const i=s(t,n(e));return i&&i.isValid()?i:null}})),n.extend(((t,e)=>{e.prototype.merge=function(t,e="date"){let s=this.clone();if(!t||!t.isValid())return this;if("string"==typeof e){const t={date:["year","month","date"],time:["hour","minute","second"]};if(!1===Object.prototype.hasOwnProperty.call(t,e))throw new Error("Invalid merge unit alias");e=t[e]}for(const n of e)s=s.set(n,t.get(n));return s}})),n.extend(((t,e,s)=>{s.pattern=t=>new class{constructor(t,e){this.dayjs=t,this.pattern=e;const s={year:["YY","YYYY"],month:["M","MM","MMM","MMMM"],day:["D","DD"],hour:["h","hh","H","HH"],minute:["m","mm"],second:["s","ss"],meridiem:["a"]};this.parts=this.pattern.split(/\W/).map(((t,e)=>{const n=this.pattern.indexOf(t);return{index:e,unit:Object.keys(s)[Object.values(s).findIndex((e=>e.includes(t)))],start:n,end:n+(t.length-1)}}))}at(t,e=t){const s=this.parts.filter((s=>s.start<=t&&s.end>=e-1));return s[0]?s[0]:this.parts.filter((e=>e.start<=t)).pop()}format(t){return t&&t.isValid()?t.format(this.pattern):null}}(s,t)})),n.extend(((t,e)=>{e.prototype.round=function(t="date",e=1){const s=["second","minute","hour","date","month","year"];if("day"===t&&(t="date"),!1===s.includes(t))throw new Error("Invalid rounding unit");if(["date","month","year"].includes(t)&&1!==e||"hour"===t&&24%e!=0||["second","minute"].includes(t)&&60%e!=0)throw"Invalid rounding size for "+t;let n=this.clone();const i=s.indexOf(t),o=s.slice(0,i),r=o.pop();if(o.forEach((t=>n=n.startOf(t))),r){const e={month:12,date:n.daysInMonth(),hour:24,minute:60,second:60}[r];Math.round(n.get(r)/e)*e===e&&(n=n.add(1,"date"===t?"day":t)),n=n.startOf(t)}return n=n.set(t,Math.round(n.get(t)/e)*e),n}})),n.extend(((t,e,s)=>{e.prototype.validate=function(t,e,n="day"){if(!this.isValid())return!1;if(!t)return!0;t=s.iso(t);const i={min:"isAfter",max:"isBefore"}[e];return this.isSame(t,n)||this[i](t,n)}}));const Ot={install(t){t.prototype.$library={autosize:o,dayjs:n}}},At={props:{blueprint:String,lock:[Boolean,Object],help:String,name:String,parent:String,timestamp:Number},methods:{load(){return this.$api.get(this.parent+"/sections/"+this.name)}}},Tt={install(t){const e={...t.options.components},s={section:At};for(const[n,i]of Object.entries(window.panel.plugins.components))i.template||i.render||i.extends?("string"==typeof(null==i?void 0:i.extends)&&(e[i.extends]?i.extends=e[i.extends].extend({options:i,components:{...e,...i.components||{}}}):i.extends=null),i.template&&(i.render=null),i.mixins&&(i.mixins=i.mixins.map((t=>"string"==typeof t?s[t]:t))),e[n]&&window.console.warn(`Plugin is replacing "${n}"`),t.component(n,i),e[n]=t.options.components[n]):Q.dispatch("notification/error",`Neither template or render method provided nor extending a component when loading plugin component "${n}". The component has not been registered.`);for(const n of window.panel.plugins.use)t.use(n)}};function It(t,e,s,n,i,o,r,l){var a,u="function"==typeof t?t.options:t;if(e&&(u.render=e,u.staticRenderFns=s,u._compiled=!0),n&&(u.functional=!0),o&&(u._scopeId="data-v-"+o),r?(a=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),i&&i.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(r)},u._ssrRegister=a):i&&(a=l?function(){i.call(this,(u.functional?this.parent:this).$root.$options.shadowRoot)}:i),a)if(u.functional){u._injectStyles=a;var c=u.render;u.render=function(t,e){return a.call(e),c(t,e)}}else{var d=u.beforeCreate;u.beforeCreate=d?[].concat(d,a):[a]}return{exports:t,options:u}}const Mt=It({props:{autofocus:{type:Boolean,default:!0},cancelButton:{type:[String,Boolean],default:!0},icon:{type:String,default:"check"},size:{type:String,default:"default"},submitButton:{type:[String,Boolean],default:!0},theme:String,visible:Boolean},data:()=>({notification:null}),computed:{buttons(){let t=[];return this.cancelButton&&t.push({icon:"cancel",text:this.cancelButtonLabel,class:"k-dialog-button-cancel",click:this.cancel}),this.submitButtonConfig&&t.push({icon:this.icon,text:this.submitButtonLabel,theme:this.theme,class:"k-dialog-button-submit",click:this.submit}),t},cancelButtonLabel(){return!1!==this.cancelButton&&(!0===this.cancelButton||0===this.cancelButton.length?this.$t("cancel"):this.cancelButton)},submitButtonConfig(){return void 0!==this.$attrs.button?this.$attrs.button:void 0===this.submitButton||this.submitButton},submitButtonLabel(){return!0===this.submitButton||0===this.submitButton.length?this.$t("confirm"):this.submitButton}},created(){this.$events.$on("keydown.esc",this.close,!1)},destroyed(){this.$events.$off("keydown.esc",this.close,!1)},mounted(){this.visible&&this.$nextTick(this.open)},methods:{onOverlayClose(){this.notification=null,this.$emit("close"),this.$events.$off("keydown.esc",this.close),this.$store.dispatch("dialog",!1)},open(){this.$store.state.dialog||this.$store.dispatch("dialog",!0),this.notification=null,this.$refs.overlay.open(),this.$emit("open"),this.$events.$on("keydown.esc",this.close)},close(){this.$refs.overlay&&this.$refs.overlay.close()},cancel(){this.$emit("cancel"),this.close()},focus(){var t;if(null==(t=this.$refs.dialog)?void 0:t.querySelector){const t=this.$refs.dialog.querySelector(".k-dialog-button-cancel");"function"==typeof(null==t?void 0:t.focus)&&t.focus()}},error(t){this.notification={message:t,type:"error"}},submit(){this.$emit("submit")},success(t){this.notification={message:t,type:"success"}}}},(function(){var t=this,e=t._self._c;return e("k-overlay",{ref:"overlay",attrs:{autofocus:t.autofocus,centered:!0},on:{close:t.onOverlayClose,ready:function(e){return t.$emit("ready")}}},[e("div",{ref:"dialog",staticClass:"k-dialog",class:t.$vnode.data.staticClass,attrs:{"data-size":t.size},on:{mousedown:function(t){t.stopPropagation()}}},[t.notification?e("div",{staticClass:"k-dialog-notification",attrs:{"data-theme":t.notification.type}},[e("p",[t._v(t._s(t.notification.message))]),e("k-button",{attrs:{icon:"cancel"},on:{click:function(e){t.notification=null}}})],1):t._e(),e("div",{staticClass:"k-dialog-body scroll-y-auto"},[t._t("default")],2),t.$slots.footer||t.buttons.length?e("footer",{staticClass:"k-dialog-footer"},[t._t("footer",(function(){return[e("k-button-group",{attrs:{buttons:t.buttons}})]}))],2):t._e()])])}),[],!1,null,null,null,null).exports,Et={props:{autofocus:{type:Boolean,default:!0},cancelButton:{type:[String,Boolean],default:!0},icon:String,submitButton:{type:[String,Boolean],default:!0},size:String,theme:String,visible:Boolean},methods:{close(){this.$refs.dialog.close(),this.$emit("close")},error(t){this.$refs.dialog.error(t)},open(){this.$refs.dialog.open(),this.$emit("open")},success(t){this.$refs.dialog.close(),t.route&&this.$go(t.route),t.message&&this.$store.dispatch("notification/success",t.message),t.event&&("string"==typeof t.event&&(t.event=[t.event]),t.event.forEach((e=>{this.$events.$emit(e,t)}))),!1!==Object.prototype.hasOwnProperty.call(t,"emit")&&!1===t.emit||this.$emit("success")}}};const Lt=It({mixins:[Et],props:{details:[Object,Array],message:String,size:{type:String,default:"medium"}},computed:{detailsList(){return Array.isArray(this.details)?this.details:Object.values(this.details||{})}}},(function(){var t=this,e=t._self._c;return e("k-dialog",{ref:"dialog",staticClass:"k-error-dialog",attrs:{"cancel-button":!1,size:t.size,visible:!0},on:{cancel:function(e){return t.$emit("cancel")},close:function(e){return t.$emit("close")},submit:function(e){return t.$refs.dialog.close()}}},[e("k-text",[t._v(t._s(t.message))]),t.detailsList.length?e("dl",{staticClass:"k-error-details"},[t._l(t.detailsList,(function(s,n){return[e("dt",{key:"detail-label-"+n},[t._v(" "+t._s(s.label)+" ")]),e("dd",{key:"detail-message-"+n},["object"==typeof s.message?[e("ul",t._l(s.message,(function(s,n){return e("li",{key:n},[t._v(" "+t._s(s)+" ")])})),0)]:[t._v(" "+t._s(s.message)+" ")]],2)]}))],2):t._e()],1)}),[],!1,null,null,null,null).exports;const jt=It({props:{code:Number,component:String,path:String,props:Object,referrer:String},methods:{close(){this.$refs.dialog.close()},onCancel(){"function"==typeof this.$store.state.dialog.cancel&&this.$store.state.dialog.cancel({dialog:this})},async onSubmit(t){let e=null;try{if("function"==typeof this.$store.state.dialog.submit)e=await this.$store.state.dialog.submit({dialog:this,value:t});else{if(!this.path)throw"The dialog needs a submit action or a dialog route path to be submitted";e=await this.$request(this.path,{body:t,method:"POST",type:"$dialog",headers:{"X-Fiber-Referrer":this.referrer}})}if(!1===e)return!1;this.close(),this.$store.dispatch("notification/success",":)"),e.event&&("string"==typeof e.event&&(e.event=[e.event]),e.event.forEach((t=>{this.$events.$emit(t,e)}))),e.dispatch&&Object.keys(e.dispatch).forEach((t=>{const s=e.dispatch[t];this.$store.dispatch(t,!0===Array.isArray(s)?[...s]:s)})),e.redirect?this.$go(e.redirect):this.$reload(e.reload||{})}catch(s){this.$refs.dialog.error(s)}}}},(function(){var t=this;return(0,t._self._c)(t.component,t._b({ref:"dialog",tag:"component",attrs:{visible:!0},on:{cancel:t.onCancel,submit:t.onSubmit}},"component",t.props,!1))}),[],!1,null,null,null,null).exports,Dt={data:()=>({models:[],issue:null,selected:{},options:{endpoint:null,max:null,multiple:!0,parent:null,selected:[],search:!0},search:null,pagination:{limit:20,page:1,total:0}}),computed:{checkedIcon(){return!0===this.multiple?"check":"circle-filled"},collection(){return{empty:this.emptyProps,items:this.items,link:!1,layout:"list",pagination:{details:!0,dropdown:!1,align:"center",...this.pagination},sortable:!1}},items(){return this.models.map(this.item)},multiple(){return!0===this.options.multiple&&1!==this.options.max}},watch:{search(){this.updateSearch()}},created(){this.updateSearch=dt(this.updateSearch,200)},methods:{async fetch(){const t={page:this.pagination.page,search:this.search,...this.fetchData||{}};try{const e=await this.$api.get(this.options.endpoint,t);this.models=e.data,this.pagination=e.pagination,this.onFetched&&this.onFetched(e)}catch(e){this.models=[],this.issue=e.message}},async open(t,e){this.pagination.page=0,this.search=null;let s=!0;Array.isArray(t)?(this.models=t,s=!1):(this.models=[],e=t),this.options={...this.options,...e},this.selected={},this.options.selected.forEach((t=>{this.$set(this.selected,t,{id:t})})),s&&await this.fetch(),this.$refs.dialog.open()},paginate(t){this.pagination.page=t.page,this.pagination.limit=t.limit,this.fetch()},submit(){this.$emit("submit",Object.values(this.selected)),this.$refs.dialog.close()},isSelected(t){return void 0!==this.selected[t.id]},item:t=>t,toggle(t){!1!==this.options.multiple&&1!==this.options.max||(this.selected={}),!0!==this.isSelected(t)?this.options.max&&this.options.max<=Object.keys(this.selected).length||this.$set(this.selected,t.id,t):this.$delete(this.selected,t.id)},toggleBtn(t){const e=this.isSelected(t);return{icon:e?this.checkedIcon:"circle-outline",tooltip:e?this.$t("remove"):this.$t("select"),theme:e?"positive":null}},updateSearch(){this.pagination.page=0,this.fetch()}}};const Bt=It({mixins:[Dt],computed:{emptyProps(){return{icon:"image",text:this.$t("dialog.files.empty")}}}},(function(){var t=this,e=t._self._c;return e("k-dialog",{ref:"dialog",staticClass:"k-files-dialog",attrs:{size:"medium"},on:{cancel:function(e){return t.$emit("cancel")},submit:t.submit}},[t.issue?[e("k-box",{attrs:{text:t.issue,theme:"negative"}})]:[t.options.search?e("k-input",{staticClass:"k-dialog-search",attrs:{autofocus:!0,placeholder:t.$t("search")+" …",type:"text",icon:"search"},model:{value:t.search,callback:function(e){t.search=e},expression:"search"}}):t._e(),e("k-collection",t._b({on:{item:t.toggle,paginate:t.paginate},scopedSlots:t._u([{key:"options",fn:function({item:s}){return[e("k-button",t._b({on:{click:function(e){return t.toggle(s)}}},"k-button",t.toggleBtn(s),!1))]}}])},"k-collection",t.collection,!1))]],2)}),[],!1,null,null,null,null).exports;const Pt=It({mixins:[Et],props:{fields:{type:[Array,Object],default:()=>[]},novalidate:{type:Boolean,default:!0},size:{type:String,default:"medium"},submitButton:{type:[String,Boolean],default:()=>window.panel.$t("save")},text:{type:String},theme:{type:String,default:"positive"},value:{type:Object,default:()=>({})}},data(){return{model:this.value}},computed:{hasFields(){return Object.keys(this.fields).length>0}},watch:{value(t,e){t!==e&&(this.model=t)}}},(function(){var t=this,e=t._self._c;return e("k-dialog",t._b({ref:"dialog",on:{cancel:function(e){return t.$emit("cancel")},close:function(e){return t.$emit("close")},ready:function(e){return t.$emit("ready")},submit:function(e){return t.$refs.form.submit()}}},"k-dialog",t.$props,!1),[t.text?[e("k-text",{attrs:{html:t.text}})]:t._e(),t.hasFields?e("k-form",{ref:"form",attrs:{value:t.model,fields:t.fields,novalidate:t.novalidate},on:{input:function(e){return t.$emit("input",e)},submit:function(e){return t.$emit("submit",e)}}}):e("k-box",{attrs:{theme:"negative"}},[t._v(" This form dialog has no fields ")])],2)}),[],!1,null,null,null,null).exports;const Nt=It({extends:Pt,watch:{"model.name"(t){this.fields.code.disabled||this.onNameChanges(t)},"model.code"(t){this.fields.code.disabled||(this.model.code=this.$helper.slug(t,[this.$system.ascii]),this.onCodeChanges(this.model.code))}},methods:{onCodeChanges(t){if(!t)return this.model.locale=null;if(t.length>=2)if(-1!==t.indexOf("-")){let e=t.split("-"),s=[e[0],e[1].toUpperCase()];this.model.locale=s.join("_")}else{let e=this.$system.locales||[];(null==e?void 0:e[t])?this.model.locale=e[t]:this.model.locale=null}},onNameChanges(t){this.model.code=this.$helper.slug(t,[this.model.rules,this.$system.ascii]).substr(0,2)}}},null,null,!1,null,null,null,null).exports;const qt=It({mixins:[Dt],data(){const t=Dt.data();return{...t,model:{title:null,parent:null},options:{...t.options,parent:null}}},computed:{emptyProps(){return{icon:"page",text:this.$t("dialog.pages.empty")}},fetchData(){return{parent:this.options.parent}}},methods:{back(){this.options.parent=this.model.parent,this.pagination.page=1,this.fetch()},go(t){this.options.parent=t.id,this.pagination.page=1,this.fetch()},onFetched(t){this.model=t.model}}},(function(){var t=this,e=t._self._c;return e("k-dialog",{ref:"dialog",staticClass:"k-pages-dialog",attrs:{size:"medium"},on:{cancel:function(e){return t.$emit("cancel")},submit:t.submit}},[t.issue?[e("k-box",{attrs:{text:t.issue,theme:"negative"}})]:[t.model?e("header",{staticClass:"k-pages-dialog-navbar"},[e("k-button",{attrs:{disabled:!t.model.id,tooltip:t.$t("back"),icon:"angle-left"},on:{click:t.back}}),e("k-headline",[t._v(t._s(t.model.title))])],1):t._e(),t.options.search?e("k-input",{staticClass:"k-dialog-search",attrs:{autofocus:!0,placeholder:t.$t("search")+" …",type:"text",icon:"search"},model:{value:t.search,callback:function(e){t.search=e},expression:"search"}}):t._e(),e("k-collection",t._b({on:{item:t.toggle,paginate:t.paginate},scopedSlots:t._u([{key:"options",fn:function({item:s}){return[e("k-button",t._b({on:{click:function(e){return t.toggle(s)}}},"k-button",t.toggleBtn(s),!1)),t.model?e("k-button",{attrs:{disabled:!s.hasChildren,tooltip:t.$t("open"),icon:"angle-right"},on:{click:function(e){return e.stopPropagation(),t.go(s)}}}):t._e()]}}])},"k-collection",t.collection,!1))]],2)}),[],!1,null,null,null,null).exports;const Ft=It({mixins:[Et],props:{icon:{type:String,default:"trash"},submitButton:{type:[String,Boolean],default:()=>window.panel.$t("delete")},text:String,theme:{type:String,default:"negative"}}},(function(){var t=this;return(0,t._self._c)("k-text-dialog",t._g(t._b({ref:"dialog"},"k-text-dialog",t.$props,!1),t.$listeners),[t._t("default")],2)}),[],!1,null,null,null,null).exports;const Rt=It({mixins:[Et],props:{text:String}},(function(){var t=this,e=t._self._c;return e("k-dialog",t._g(t._b({ref:"dialog"},"k-dialog",t.$props,!1),t.$listeners),[t._t("default",(function(){return[t.text?e("k-text",{attrs:{html:t.text}}):e("k-box",{attrs:{theme:"negative"}},[t._v(" This dialog does not define any text ")])]}))],2)}),[],!1,null,null,null,null).exports;const zt=It({mixins:[Dt],computed:{emptyProps(){return{icon:"users",text:this.$t("dialog.users.empty")}}},methods:{item:t=>({...t,key:t.email,info:t.info!==t.text?t.info:null})}},(function(){var t=this,e=t._self._c;return e("k-dialog",{ref:"dialog",staticClass:"k-users-dialog",attrs:{size:"medium"},on:{cancel:function(e){return t.$emit("cancel")},submit:t.submit}},[t.issue?[e("k-box",{attrs:{text:t.issue,theme:"negative"}})]:[t.options.search?e("k-input",{staticClass:"k-dialog-search",attrs:{autofocus:!0,placeholder:t.$t("search")+" …",type:"text",icon:"search"},model:{value:t.search,callback:function(e){t.search=e},expression:"search"}}):t._e(),e("k-collection",t._b({on:{item:t.toggle,paginate:t.paginate},scopedSlots:t._u([{key:"options",fn:function({item:s}){return[e("k-button",t._b({on:{click:function(e){return t.toggle(s)}}},"k-button",t.toggleBtn(s),!1))]}}])},"k-collection",t.collection,!1))]],2)}),[],!1,null,null,null,null).exports;const Yt=It({inheritAttrs:!1,props:{id:String,icon:String,tab:String,tabs:Object,title:String},data:()=>({click:!1}),computed:{breadcrumb(){return this.$store.state.drawers.open},hasTabs(){return this.tabs&&Object.keys(this.tabs).length>1},index(){return this.breadcrumb.findIndex((t=>t.id===this._uid))},nested(){return this.index>0}},watch:{index(){-1===this.index&&this.close()}},destroyed(){this.$store.dispatch("drawers/close",this._uid)},methods:{close(){this.$refs.overlay.close()},goTo(t){if(t===this._uid)return!0;this.$store.dispatch("drawers/goto",t)},mouseup(){!0===this.click&&this.close(),this.click=!1},mousedown(t=!1){this.click=t,!0===this.click&&this.$store.dispatch("drawers/close")},onClose(){this.$store.dispatch("drawers/close",this._uid),this.$emit("close")},onOpen(){this.$store.dispatch("drawers/open",{id:this._uid,icon:this.icon,title:this.title}),this.$emit("open")},open(){this.$refs.overlay.open()}}},(function(){var t=this,e=t._self._c;return e("k-overlay",{ref:"overlay",attrs:{dimmed:!1},on:{close:t.onClose,open:t.onOpen}},[e("div",{staticClass:"k-drawer",attrs:{"data-id":t.id,"data-nested":t.nested},on:{mousedown:function(e){return e.stopPropagation(),t.mousedown(!0)},mouseup:t.mouseup}},[e("div",{staticClass:"k-drawer-box",on:{mousedown:function(e){return e.stopPropagation(),t.mousedown(!1)}}},[e("header",{staticClass:"k-drawer-header"},[1===t.breadcrumb.length?e("h2",{staticClass:"k-drawer-title"},[e("k-icon",{attrs:{type:t.icon}}),t._v(" "+t._s(t.title)+" ")],1):e("ul",{staticClass:"k-drawer-breadcrumb"},t._l(t.breadcrumb,(function(s){return e("li",{key:s.id},[e("k-button",{attrs:{icon:s.icon,text:s.title},on:{click:function(e){return t.goTo(s.id)}}})],1)})),0),t.hasTabs?e("nav",{staticClass:"k-drawer-tabs"},t._l(t.tabs,(function(s){return e("k-button",{key:s.name,staticClass:"k-drawer-tab",attrs:{current:t.tab==s.name,text:s.label},on:{click:function(e){return e.stopPropagation(),t.$emit("tab",s.name)}}})})),1):t._e(),e("nav",{staticClass:"k-drawer-options"},[t._t("options"),e("k-button",{staticClass:"k-drawer-option",attrs:{icon:"check"},on:{click:t.close}})],2)]),e("div",{staticClass:"k-drawer-body scroll-y-auto"},[t._t("default")],2)])])])}),[],!1,null,null,null,null).exports;const Ht=It({inheritAttrs:!1,props:{empty:{type:String,default:()=>"Missing field setup"},icon:String,id:String,tabs:Object,title:String,type:String,value:Object},data:()=>({tab:null}),computed:{fields(){const t=this.tab||null;return(this.tabs[t]||this.firstTab).fields||{}},firstTab(){return Object.values(this.tabs)[0]}},methods:{close(){this.$refs.drawer.close()},focus(t){var e;"function"==typeof(null==(e=this.$refs.form)?void 0:e.focus)&&this.$refs.form.focus(t)},open(t,e=!0){this.$refs.drawer.open(),this.tab=t||this.firstTab.name,!1!==e&&setTimeout((()=>{let t=Object.values(this.fields).filter((t=>!0===t.autofocus))[0]||null;this.focus(t)}),1)}}},(function(){var t=this,e=t._self._c;return e("k-drawer",{ref:"drawer",staticClass:"k-form-drawer",attrs:{id:t.id,icon:t.icon,tabs:t.tabs,tab:t.tab,title:t.title},on:{close:function(e){return t.$emit("close")},open:function(e){return t.$emit("open")},tab:function(e){t.tab=e}},scopedSlots:t._u([{key:"options",fn:function(){return[t._t("options")]},proxy:!0},{key:"default",fn:function(){return[0===Object.keys(t.fields).length?e("k-box",{attrs:{theme:"info"}},[t._v(" "+t._s(t.empty)+" ")]):e("k-form",{ref:"form",attrs:{autofocus:!0,fields:t.fields,value:t.$helper.clone(t.value)},on:{input:function(e){return t.$emit("input",e)}}})]},proxy:!0}],null,!0)})}),[],!1,null,null,null,null).exports;const Ut=It({props:{html:{type:Boolean,default:!1},limit:{type:Number,default:10},skip:{type:Array,default:()=>[]},options:Array,query:String},data:()=>({matches:[],selected:{text:null}}),methods:{close(){this.$refs.dropdown.close()},onSelect(t){this.$emit("select",t),this.$refs.dropdown.close()},search(t){if(t.length<1)return;const e=new RegExp(RegExp.escape(t),"ig");this.matches=this.options.filter((t=>!!t.text&&(-1===this.skip.indexOf(t.value)&&null!==t.text.match(e)))).slice(0,this.limit),this.$emit("search",t,this.matches),this.$refs.dropdown.open()}}},(function(){var t=this,e=t._self._c;return e("k-dropdown",{staticClass:"k-autocomplete"},[t._t("default"),e("k-dropdown-content",t._g({ref:"dropdown",attrs:{autofocus:!0}},t.$listeners),t._l(t.matches,(function(s,n){return e("k-dropdown-item",t._b({key:n,on:{mousedown:function(e){return t.onSelect(s)},keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"tab",9,e.key,"Tab")?null:(e.preventDefault(),t.onSelect(s))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:(e.preventDefault(),t.onSelect(s))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"left",37,e.key,["Left","ArrowLeft"])||"button"in e&&0!==e.button?null:(e.preventDefault(),t.close.apply(null,arguments))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"backspace",void 0,e.key,void 0)?null:(e.preventDefault(),t.close.apply(null,arguments))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"delete",[8,46],e.key,["Backspace","Delete","Del"])?null:(e.preventDefault(),t.close.apply(null,arguments))}]}},"k-dropdown-item",s,!1),[e("span",{domProps:{innerHTML:t._s(t.html?s.text:t.$esc(s.text))}})])})),1),t._v(" "+t._s(t.query)+" ")],2)}),[],!1,null,null,null,null).exports;const Kt=It({props:{disabled:Boolean,max:String,min:String,value:String},data(){return this.data(this.value)},computed:{numberOfDays(){return this.toDate().daysInMonth()},firstWeekday(){const t=this.toDate().day();return t>0?t:7},weekdays(){return["mon","tue","wed","thu","fri","sat","sun"].map((t=>this.$t("days."+t)))},weeks(){const t=this.firstWeekday-1;return Math.ceil((this.numberOfDays+t)/7)},monthnames(){return["january","february","march","april","may","june","july","august","september","october","november","december"].map((t=>this.$t("months."+t)))},months(){var t=[];return this.monthnames.forEach(((e,s)=>{const n=this.toDate(1,s);t.push({value:s,text:e,disabled:n.isBefore(this.current.min,"month")||n.isAfter(this.current.max,"month")})})),t},years(){var t,e,s,n;const i=null!=(e=null==(t=this.current.min)?void 0:t.get("year"))?e:this.current.year-20,o=null!=(n=null==(s=this.current.max)?void 0:s.get("year"))?n:this.current.year+20;return this.toOptions(i,o)}},watch:{value(t){const e=this.data(t);this.dt=e.dt,this.current=e.current}},methods:{data(t){const e=this.$library.dayjs.iso(t),s=this.$library.dayjs();return{dt:e,current:{month:(null!=e?e:s).month(),year:(null!=e?e:s).year(),min:this.$library.dayjs.iso(this.min),max:this.$library.dayjs.iso(this.max)}}},days(t){let e=[];const s=7*(t-1)+1,n=s+7;for(let i=s;ithis.numberOfDays;e.push(s?"":t)}return e},isDisabled(t){const e=this.toDate(t);return this.disabled||e.isBefore(this.current.min,"day")||e.isAfter(this.current.max,"day")},isSelected(t){return this.toDate(t).isSame(this.dt,"day")},isToday(t){const e=this.$library.dayjs();return this.toDate(t).isSame(e,"day")},onInput(){var t;this.$emit("input",(null==(t=this.dt)?void 0:t.toISO("date"))||null)},onNext(){const t=this.toDate().add(1,"month");this.show(t)},onPrev(){const t=this.toDate().subtract(1,"month");this.show(t)},select(t){const e="today"===t?this.$library.dayjs().merge(this.toDate(),"time"):this.toDate(t);this.dt=e,this.show(e),this.onInput()},show(t){this.current.year=t.year(),this.current.month=t.month()},toDate(t=1,e=this.current.month){return this.$library.dayjs(`${this.current.year}-${e+1}-${t}`)},toOptions(t,e){for(var s=[],n=t;n<=e;n++)s.push({value:n,text:this.$helper.pad(n)});return s}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-calendar-input"},[e("nav",[e("k-button",{attrs:{icon:"angle-left"},on:{click:t.onPrev}}),e("span",{staticClass:"k-calendar-selects"},[e("k-select-input",{attrs:{options:t.months,disabled:t.disabled,required:!0},model:{value:t.current.month,callback:function(e){t.$set(t.current,"month",t._n(e))},expression:"current.month"}}),e("k-select-input",{attrs:{options:t.years,disabled:t.disabled,required:!0},model:{value:t.current.year,callback:function(e){t.$set(t.current,"year",t._n(e))},expression:"current.year"}})],1),e("k-button",{attrs:{icon:"angle-right"},on:{click:t.onNext}})],1),e("table",{staticClass:"k-calendar-table"},[e("thead",[e("tr",t._l(t.weekdays,(function(s){return e("th",{key:"weekday_"+s},[t._v(" "+t._s(s)+" ")])})),0)]),e("tbody",t._l(t.weeks,(function(s){return e("tr",{key:"week_"+s},t._l(t.days(s),(function(s,n){return e("td",{key:"day_"+n,staticClass:"k-calendar-day",attrs:{"aria-current":!!t.isToday(s)&&"date","aria-selected":!!t.isSelected(s)&&"date"}},[s?e("k-button",{attrs:{disabled:t.isDisabled(s),text:s},on:{click:function(e){return t.select(s)}}}):t._e()],1)})),0)})),0),e("tfoot",[e("tr",[e("td",{staticClass:"k-calendar-today",attrs:{colspan:"7"}},[e("k-button",{attrs:{text:t.$t("today")},on:{click:function(e){return t.select("today")}}})],1)])])])])}),[],!1,null,null,null,null).exports;const Gt=It({props:{count:Number,min:Number,max:Number,required:{type:Boolean,default:!1}},computed:{valid(){return!1===this.required&&0===this.count||(!0!==this.required||0!==this.count)&&(!(this.min&&this.countthis.max))}}},(function(){var t=this,e=t._self._c;return e("span",{staticClass:"k-counter",attrs:{"data-invalid":!t.valid}},[e("span",[t._v(t._s(t.count))]),t.min&&t.max?e("span",{staticClass:"k-counter-rules"},[t._v("("+t._s(t.min)+"–"+t._s(t.max)+")")]):t.min?e("span",{staticClass:"k-counter-rules"},[t._v("≥ "+t._s(t.min))]):t.max?e("span",{staticClass:"k-counter-rules"},[t._v("≤ "+t._s(t.max))]):t._e()])}),[],!1,null,null,null,null).exports;const Jt=It({props:{disabled:Boolean,config:Object,fields:{type:[Array,Object],default:()=>({})},novalidate:{type:Boolean,default:!1},value:{type:Object,default:()=>({})}},data(){return{errors:{},listeners:{...this.$listeners,submit:this.onSubmit}}},methods:{focus(t){var e,s;null==(s=null==(e=this.$refs.fields)?void 0:e.focus)||s.call(e,t)},onSubmit(){this.$emit("submit",this.value)},submit(){this.$refs.submitter.click()}}},(function(){var t=this,e=t._self._c;return e("form",{ref:"form",staticClass:"k-form",attrs:{method:"POST",autocomplete:"off",novalidate:""},on:{submit:function(e){return e.preventDefault(),t.onSubmit.apply(null,arguments)}}},[t._t("header"),t._t("default",(function(){return[e("k-fieldset",t._g({ref:"fields",attrs:{disabled:t.disabled,fields:t.fields,novalidate:t.novalidate},model:{value:t.value,callback:function(e){t.value=e},expression:"value"}},t.listeners))]})),t._t("footer"),e("input",{ref:"submitter",staticClass:"k-form-submitter",attrs:{type:"submit"}})],2)}),[],!1,null,null,null,null).exports;const Vt=It({props:{lock:[Boolean,Object]},data:()=>({isRefreshing:null,isLocking:null}),computed:{hasChanges(){return this.$store.getters["content/hasChanges"]()},isDisabled(){return!1===this.$store.state.content.status.enabled},isLocked(){return"lock"===this.lockState},isUnlocked(){return"unlock"===this.lockState},mode(){return null!==this.lockState?this.lockState:!0===this.hasChanges?"changes":null},lockState(){return this.supportsLocking&&this.lock?this.lock.state:null},supportsLocking(){return!1!==this.lock},theme(){return"lock"===this.mode?"negative":"unlock"===this.mode?"info":"notice"}},watch:{hasChanges:{handler(t,e){!0===this.supportsLocking&&!1===this.isLocked&&!1===this.isUnlocked&&(!0===t?(this.onLock(),this.isLocking=setInterval(this.onLock,3e4)):e&&(clearInterval(this.isLocking),this.onLock(!1)))},immediate:!0},isLocked(t){!1===t&&this.$events.$emit("model.reload")}},created(){this.supportsLocking&&(this.isRefreshing=setInterval(this.check,1e4)),this.$events.$on("keydown.cmd.s",this.onSave)},destroyed(){clearInterval(this.isRefreshing),clearInterval(this.isLocking),this.$events.$off("keydown.cmd.s",this.onSave)},methods:{check(){this.$reload({navigate:!1,only:"$view.props.lock",silent:!0})},async onLock(t=!0){const e=[this.$view.path+"/lock",null,null,!0];if(!0===t)try{await this.$api.patch(...e)}catch(s){clearInterval(this.isLocking),this.$store.dispatch("content/revert")}else clearInterval(this.isLocking),await this.$api.delete(...e)},onDownload(){let t="";const e=this.$store.getters["content/changes"]();Object.keys(e).forEach((s=>{t+=s+": \n\n"+e[s],t+="\n\n----\n\n"}));let s=document.createElement("a");s.setAttribute("href","data:text/plain;charset=utf-8,"+encodeURIComponent(t)),s.setAttribute("download",this.$view.path+".txt"),s.style.display="none",document.body.appendChild(s),s.click(),document.body.removeChild(s)},async onResolve(){await this.onUnlock(!1),this.$store.dispatch("content/revert")},onRevert(){this.$refs.revert.open()},async onSave(t){if(!t)return!1;t.preventDefault&&t.preventDefault();try{await this.$store.dispatch("content/save"),this.$events.$emit("model.update"),this.$store.dispatch("notification/success",":)")}catch(e){if(403===e.code)return;e.details&&Object.keys(e.details).length>0?this.$store.dispatch("notification/error",{message:this.$t("error.form.incomplete"),details:e.details}):this.$store.dispatch("notification/error",{message:this.$t("error.form.notSaved"),details:[{label:"Exception: "+e.exception,message:e.message}]})}},async onUnlock(t=!0){const e=[this.$view.path+"/unlock",null,null,!0];!0===t?await this.$api.patch(...e):await this.$api.delete(...e),this.$reload({silent:!0})},revert(){this.$store.dispatch("content/revert"),this.$refs.revert.close()}}},(function(){var t=this,e=t._self._c;return e("nav",{staticClass:"k-form-buttons",attrs:{"data-theme":t.theme}},["unlock"===t.mode?e("k-view",[e("p",{staticClass:"k-form-lock-info"},[t._v(" "+t._s(t.$t("lock.isUnlocked"))+" ")]),e("span",{staticClass:"k-form-lock-buttons"},[e("k-button",{staticClass:"k-form-button",attrs:{text:t.$t("download"),icon:"download"},on:{click:t.onDownload}}),e("k-button",{staticClass:"k-form-button",attrs:{text:t.$t("confirm"),icon:"check"},on:{click:t.onResolve}})],1)]):"lock"===t.mode?e("k-view",[e("p",{staticClass:"k-form-lock-info"},[e("k-icon",{attrs:{type:"lock"}}),e("span",{domProps:{innerHTML:t._s(t.$t("lock.isLocked",{email:t.$esc(t.lock.data.email)}))}})],1),t.lock.data.unlockable?e("k-button",{staticClass:"k-form-button",attrs:{text:t.$t("lock.unlock"),icon:"unlock"},on:{click:function(e){return t.onUnlock()}}}):e("k-icon",{staticClass:"k-form-lock-loader",attrs:{type:"loader"}})],1):"changes"===t.mode?e("k-view",[e("k-button",{staticClass:"k-form-button",attrs:{disabled:t.isDisabled,text:t.$t("revert"),icon:"undo"},on:{click:t.onRevert}}),e("k-button",{staticClass:"k-form-button",attrs:{disabled:t.isDisabled,text:t.$t("save"),icon:"check"},on:{click:t.onSave}})],1):t._e(),e("k-dialog",{ref:"revert",attrs:{"submit-button":t.$t("revert"),icon:"undo",theme:"negative"},on:{submit:t.revert}},[e("k-text",{attrs:{html:t.$t("revert.confirm")}})],1)],1)}),[],!1,null,null,null,null).exports;const Wt=It({data:()=>({isOpen:!1,options:[]}),computed:{hasChanges(){return this.ids.length>0},ids(){return Object.keys(this.store).filter((t=>{var e;return Object.keys((null==(e=this.store[t])?void 0:e.changes)||{}).length>0}))},store(){return this.$store.state.content.models}},methods:{async toggle(){if(!1===this.$refs.list.isOpen)try{await this.$dropdown("changes",{method:"POST",body:{ids:this.ids}})((t=>{this.options=t}))}catch(t){return this.$store.dispatch("notification/success",this.$t("lock.unsaved.empty")),this.$store.dispatch("content/clear"),!1}this.$refs.list&&this.$refs.list.toggle()}}},(function(){var t=this,e=t._self._c;return t.hasChanges?e("k-dropdown",{staticClass:"k-form-indicator"},[e("k-button",{staticClass:"k-form-indicator-toggle k-topbar-button",attrs:{icon:"edit"},on:{click:t.toggle}}),e("k-dropdown-content",{ref:"list",attrs:{align:"right",theme:"light"}},[e("p",{staticClass:"k-form-indicator-info"},[t._v(t._s(t.$t("lock.unsaved"))+":")]),e("hr"),t._l(t.options,(function(s){return e("k-dropdown-item",t._b({key:s.id},"k-dropdown-item",s,!1),[t._v(" "+t._s(s.text)+" ")])}))],2)],1):t._e()}),[],!1,null,null,null,null).exports,Xt={props:{after:String}},Zt={props:{autofocus:Boolean}},Qt={props:{before:String}},te={props:{disabled:Boolean}},ee={props:{help:String}},se={props:{id:{type:[Number,String],default(){return this._uid}}}},ne={props:{invalid:Boolean}},ie={props:{label:String}},oe={props:{name:[Number,String]}},re={props:{required:Boolean}},le={mixins:[te,ee,ie,oe,re],props:{counter:[Boolean,Object],endpoints:Object,input:[String,Number],translate:Boolean,type:String}};const ae=It({mixins:[le],inheritAttrs:!1,computed:{labelText(){return this.label||" "}}},(function(){var t=this,e=t._self._c;return e("div",{class:"k-field k-field-name-"+t.name,attrs:{"data-disabled":t.disabled,"data-translate":t.translate},on:{focusin:function(e){return t.$emit("focus",e)},focusout:function(e){return t.$emit("blur",e)}}},[t._t("header",(function(){return[e("header",{staticClass:"k-field-header"},[t._t("label",(function(){return[e("label",{staticClass:"k-field-label",attrs:{for:t.input}},[t._v(" "+t._s(t.labelText)+" "),t.required?e("abbr",{attrs:{title:t.$t("field.required")}},[t._v("*")]):t._e()])]})),t._t("options"),t._t("counter",(function(){return[t.counter?e("k-counter",t._b({staticClass:"k-field-counter",attrs:{required:t.required}},"k-counter",t.counter,!1)):t._e()]}))],2)]})),t._t("default"),t._t("footer",(function(){return[t.help||t.$slots.help?e("footer",{staticClass:"k-field-footer"},[t._t("help",(function(){return[t.help?e("k-text",{staticClass:"k-field-help",attrs:{theme:"help",html:t.help}}):t._e()]}))],2):t._e()]}))],2)}),[],!1,null,null,null,null).exports;const ue=It({props:{config:Object,disabled:Boolean,fields:{type:[Array,Object],default:()=>[]},novalidate:{type:Boolean,default:!1},value:{type:Object,default:()=>({})}},data:()=>({errors:{}}),methods:{focus(t){if(t)return void(this.hasField(t)&&"function"==typeof this.$refs[t][0].focus&&this.$refs[t][0].focus());const e=Object.keys(this.$refs)[0];this.focus(e)},hasFieldType(t){return this.$helper.isComponent(`k-${t}-field`)},hasField(t){var e;return null==(e=this.$refs[t])?void 0:e[0]},meetsCondition(t){if(!t.when)return!0;let e=!0;return Object.keys(t.when).forEach((s=>{this.value[s.toLowerCase()]!==t.when[s]&&(e=!1)})),e},onInvalid(t,e,s,n){this.errors[n]=e,this.$emit("invalid",this.errors)},hasErrors(){return Object.keys(this.errors).length}}},(function(){var t=this,e=t._self._c;return e("fieldset",{staticClass:"k-fieldset"},[e("k-grid",[t._l(t.fields,(function(s,n){return["hidden"!==s.type&&t.meetsCondition(s)?e("k-column",{key:s.signature,attrs:{width:s.width}},[e("k-error-boundary",[t.hasFieldType(s.type)?e("k-"+s.type+"-field",t._b({ref:n,refInFor:!0,tag:"component",attrs:{"form-data":t.value,name:n,novalidate:t.novalidate,disabled:t.disabled||s.disabled},on:{input:function(e){return t.$emit("input",t.value,s,n)},focus:function(e){return t.$emit("focus",e,s,n)},invalid:(e,i)=>t.onInvalid(e,i,s,n),submit:function(e){return t.$emit("submit",e,s,n)}},model:{value:t.value[n],callback:function(e){t.$set(t.value,n,e)},expression:"value[fieldName]"}},"component",s,!1)):e("k-box",{attrs:{theme:"negative"}},[e("k-text",{attrs:{size:"small"}},[t._v(" The field type "),e("strong",[t._v('"'+t._s(n)+'"')]),t._v(" does not exist ")])],1)],1)],1):t._e()]}))],2)],1)}),[],!1,null,null,null,null).exports,ce={mixins:[Xt,Qt,te,ne],props:{autofocus:Boolean,type:String,icon:[String,Boolean],theme:String,novalidate:{type:Boolean,default:!1},value:{type:[String,Boolean,Number,Object,Array],default:null}}};const de=It({mixins:[ce],inheritAttrs:!1,data(){return{isInvalid:this.invalid,listeners:{...this.$listeners,invalid:(t,e)=>{this.isInvalid=t,this.$emit("invalid",t,e)}}}},computed:{inputProps(){return{...this.$props,...this.$attrs}}},methods:{blur(t){(null==t?void 0:t.relatedTarget)&&!1===this.$el.contains(t.relatedTarget)&&this.trigger(null,"blur")},focus(t){this.trigger(t,"focus")},select(t){this.trigger(t,"select")},trigger(t,e){var s,n,i;if("INPUT"===(null==(s=null==t?void 0:t.target)?void 0:s.tagName)&&"function"==typeof(null==(n=null==t?void 0:t.target)?void 0:n[e]))return void t.target[e]();if("function"==typeof(null==(i=this.$refs.input)?void 0:i[e]))return void this.$refs.input[e]();const o=this.$el.querySelector("input, select, textarea");"function"==typeof(null==o?void 0:o[e])&&o[e]()}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-input",attrs:{"data-disabled":t.disabled,"data-invalid":!t.novalidate&&t.isInvalid,"data-theme":t.theme,"data-type":t.type}},[t.$slots.before||t.before?e("span",{staticClass:"k-input-before",on:{click:t.focus}},[t._t("before",(function(){return[t._v(t._s(t.before))]}))],2):t._e(),e("span",{staticClass:"k-input-element",on:{click:function(e){return e.stopPropagation(),t.focus.apply(null,arguments)}}},[t._t("default",(function(){return[e("k-"+t.type+"-input",t._g(t._b({ref:"input",tag:"component",attrs:{value:t.value}},"component",t.inputProps,!1),t.listeners))]}))],2),t.$slots.after||t.after?e("span",{staticClass:"k-input-after",on:{click:t.focus}},[t._t("after",(function(){return[t._v(t._s(t.after))]}))],2):t._e(),t.$slots.icon||t.icon?e("span",{staticClass:"k-input-icon",on:{click:t.focus}},[t._t("icon",(function(){return[e("k-icon",{attrs:{type:t.icon}})]}))],2):t._e()])}),[],!1,null,null,null,null).exports;const pe=It({props:{methods:Array},data:()=>({currentForm:null,isLoading:!1,issue:"",user:{email:"",password:"",remember:!1}}),computed:{canToggle(){return null!==this.codeMode&&!0===this.methods.includes("password")&&(!0===this.methods.includes("password-reset")||!0===this.methods.includes("code"))},codeMode(){return!0===this.methods.includes("password-reset")?"password-reset":!0===this.methods.includes("code")?"code":null},fields(){let t={email:{autofocus:!0,label:this.$t("email"),type:"email",required:!0,link:!1}};return"email-password"===this.form&&(t.password={label:this.$t("password"),type:"password",minLength:8,required:!0,autocomplete:"current-password",counter:!1}),t},form(){return this.currentForm?this.currentForm:"password"===this.methods[0]?"email-password":"email"},isResetForm(){return"password-reset"===this.codeMode&&"email"===this.form},toggleText(){return this.$t("login.toggleText."+this.codeMode+"."+this.formOpposite(this.form))}},methods:{formOpposite:t=>"email-password"===t?"email":"email-password",async login(){this.issue=null,this.isLoading=!0;let t=Object.assign({},this.user);"email"===this.currentForm&&(t.password=null),!0===this.isResetForm&&(t.remember=!1);try{await this.$api.auth.login(t),this.$reload({globals:["$system","$translation"]})}catch(e){this.issue=e.message}finally{this.isLoading=!1}},toggleForm(){this.currentForm=this.formOpposite(this.form),this.$refs.fieldset.focus("email")}}},(function(){var t=this,e=t._self._c;return e("form",{staticClass:"k-login-form",on:{submit:function(e){return e.preventDefault(),t.login.apply(null,arguments)}}},[e("h1",{staticClass:"sr-only"},[t._v(" "+t._s(t.$t("login"))+" ")]),t.issue?e("k-login-alert",{on:{click:function(e){t.issue=null}}},[t._v(" "+t._s(t.issue)+" ")]):t._e(),e("div",{staticClass:"k-login-fields"},[!0===t.canToggle?e("button",{staticClass:"k-login-toggler",attrs:{type:"button"},on:{click:t.toggleForm}},[t._v(" "+t._s(t.toggleText)+" ")]):t._e(),e("k-fieldset",{ref:"fieldset",attrs:{novalidate:!0,fields:t.fields},model:{value:t.user,callback:function(e){t.user=e},expression:"user"}})],1),e("div",{staticClass:"k-login-buttons"},[!1===t.isResetForm?e("span",{staticClass:"k-login-checkbox"},[e("k-checkbox-input",{attrs:{value:t.user.remember,label:t.$t("login.remember")},on:{input:function(e){t.user.remember=e}}})],1):t._e(),e("k-button",{staticClass:"k-login-button",attrs:{icon:"check",type:"submit"}},[t._v(" "+t._s(t.$t("login"+(t.isResetForm?".reset":"")))+" "),t.isLoading?[t._v(" … ")]:t._e()],2)],1)],1)}),[],!1,null,null,null,null).exports;const he=It({props:{methods:Array,pending:Object},data:()=>({code:"",isLoadingBack:!1,isLoadingLogin:!1,issue:""}),computed:{mode(){return!0===this.methods.includes("password-reset")?"password-reset":"login"}},methods:{async back(){this.isLoadingBack=!0,this.$go("/logout")},async login(){this.issue=null,this.isLoadingLogin=!0;try{await this.$api.auth.verifyCode(this.code),this.$store.dispatch("notification/success",this.$t("welcome")),"password-reset"===this.mode?this.$go("reset-password"):this.$reload()}catch(t){this.issue=t.message}finally{this.isLoadingLogin=!1}}}},(function(){var t=this,e=t._self._c;return e("form",{staticClass:"k-login-form k-login-code-form",on:{submit:function(e){return e.preventDefault(),t.login.apply(null,arguments)}}},[e("h1",{staticClass:"sr-only"},[t._v(" "+t._s(t.$t("login"))+" ")]),t.issue?e("k-login-alert",{on:{click:function(e){t.issue=null}}},[t._v(" "+t._s(t.issue)+" ")]):t._e(),e("k-user-info",{attrs:{user:t.pending.email}}),e("k-text-field",{attrs:{autofocus:!0,counter:!1,help:t.$t("login.code.text."+t.pending.challenge),label:t.$t("login.code.label."+t.mode),novalidate:!0,placeholder:t.$t("login.code.placeholder."+t.pending.challenge),required:!0,autocomplete:"one-time-code",icon:"unlock",name:"code"},model:{value:t.code,callback:function(e){t.code=e},expression:"code"}}),e("div",{staticClass:"k-login-buttons"},[e("k-button",{staticClass:"k-login-button k-login-back-button",attrs:{icon:"angle-left"},on:{click:t.back}},[t._v(" "+t._s(t.$t("back"))+" "),t.isLoadingBack?[t._v(" … ")]:t._e()],2),e("k-button",{staticClass:"k-login-button",attrs:{icon:"check",type:"submit"}},[t._v(" "+t._s(t.$t("login"+("password-reset"===t.mode?".reset":"")))+" "),t.isLoadingLogin?[t._v(" … ")]:t._e()],2)],1)],1)}),[],!1,null,null,null,null).exports;const me=It({props:{display:{type:String,default:"HH:mm"},value:String},computed:{day(){return this.formatTimes([6,7,8,9,10,11,"-",12,13,14,15,16,17])},night(){return this.formatTimes([18,19,20,21,22,23,"-",0,1,2,3,4,5])}},methods:{formatTimes(t){return t.map((t=>{if("-"===t)return t;const e=this.$library.dayjs(t+":00","H:mm");return{display:e.format(this.display),select:e.toISO("time")}}))},select(t){this.$emit("input",t)}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-times"},[e("div",{staticClass:"k-times-slot"},[e("k-icon",{attrs:{type:"sun"}}),e("ul",t._l(t.day,(function(s){return e("li",{key:s.select},["-"===s?e("hr"):e("k-button",{on:{click:function(e){return t.select(s.select)}}},[t._v(t._s(s.display))])],1)})),0)],1),e("div",{staticClass:"k-times-slot"},[e("k-icon",{attrs:{type:"moon"}}),e("ul",t._l(t.night,(function(s){return e("li",{key:s.select},["-"===s?e("hr"):e("k-button",{on:{click:function(e){return t.select(s.select)}}},[t._v(t._s(s.display))])],1)})),0)],1)])}),[],!1,null,null,null,null).exports;const fe=It({props:{accept:{type:String,default:"*"},attributes:{type:Object},max:{type:Number},method:{type:String,default:"POST"},multiple:{type:Boolean,default:!0},url:{type:String}},data(){return{options:this.$props,completed:{},errors:[],files:[],total:0}},computed:{limit(){return!1===this.options.multiple?1:this.options.max}},methods:{open(t){this.params(t),setTimeout((()=>{this.$refs.input.click()}),1)},params(t){this.options=Object.assign({},this.$props,t)},select(t){this.upload(t.target.files)},drop(t,e){this.params(e),this.upload(t)},upload(t){this.$refs.dialog.open(),this.files=[...t],this.completed={},this.errors=[],this.hasErrors=!1,this.limit&&(this.files=this.files.slice(0,this.limit)),this.total=this.files.length,this.files.forEach((t=>{var e,s;this.$helper.upload(t,{url:this.options.url,attributes:this.options.attributes,method:this.options.method,headers:{"X-CSRF":window.panel.$system.csrf},progress:(t,e,s)=>{var n,i;null==(i=null==(n=this.$refs[e.name])?void 0:n[0])||i.set(s)},success:(t,e,s)=>{this.complete(e,s.data)},error:(t,e,s)=>{this.errors.push({file:e,message:s.message}),this.complete(e,s.data)}}),void 0!==(null==(s=null==(e=this.options)?void 0:e.attributes)?void 0:s.sort)&&this.options.attributes.sort++}))},complete(t,e){if(this.completed[t.name]=e,Object.keys(this.completed).length==this.total){if(this.$refs.input.value="",this.errors.length>0)return this.$forceUpdate(),void this.$emit("error",this.files);setTimeout((()=>{this.$refs.dialog.close(),this.$emit("success",this.files,Object.values(this.completed))}),250)}}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-upload"},[e("input",{ref:"input",attrs:{accept:t.options.accept,multiple:t.options.multiple,"aria-hidden":"true",type:"file",tabindex:"-1"},on:{change:t.select,click:function(t){t.stopPropagation()}}}),e("k-dialog",{ref:"dialog",staticClass:"k-upload-dialog",attrs:{"cancel-button":!1,"submit-button":!1,size:"medium"},scopedSlots:t._u([{key:"footer",fn:function(){return[t.errors.length>0?[e("k-button-group",{attrs:{buttons:[{icon:"check",text:t.$t("confirm"),click:()=>t.$refs.dialog.close()}]}})]:t._e()]},proxy:!0}])},[t.errors.length>0?[e("k-headline",[t._v(t._s(t.$t("upload.errors")))]),e("ul",{staticClass:"k-upload-error-list"},t._l(t.errors,(function(s,n){return e("li",{key:"error-"+n},[e("p",{staticClass:"k-upload-error-filename"},[t._v(" "+t._s(s.file.name)+" ")]),e("p",{staticClass:"k-upload-error-message"},[t._v(" "+t._s(s.message)+" ")])])})),0)]:[e("k-headline",[t._v(t._s(t.$t("upload.progress")))]),e("ul",{staticClass:"k-upload-list"},t._l(t.files,(function(s,n){return e("li",{key:"file-"+n},[e("k-progress",{ref:s.name,refInFor:!0}),e("p",{staticClass:"k-upload-list-filename"},[t._v(" "+t._s(s.name)+" ")]),e("p",[t._v(t._s(t.errors[s.name]))])],1)})),0)]],2)],1)}),[],!1,null,null,null,null).exports;const ge=t=>({$from:e})=>((t,e)=>{for(let s=t.depth;s>0;s--){const n=t.node(s);if(e(n))return{pos:s>0?t.before(s):0,start:t.start(s),depth:s,node:n}}})(e,t),ke=t=>e=>{if((t=>t instanceof c)(e)){const{node:s,$from:n}=e;if(((t,e)=>Array.isArray(t)&&t.indexOf(e.type)>-1||e.type===t)(t,s))return{node:s,pos:n.pos,depth:n.depth}}},be=(t,e,s={})=>{const n=ke(e)(t.selection)||ge((t=>t.type===e))(t.selection);return Object.keys(s).length&&n?n.node.hasMarkup(e,{...n.node.attrs,...s}):!!n};function ye(t=null,e=null){if(!t||!e)return!1;const s=t.parent.childAfter(t.parentOffset);if(!s.node)return!1;const n=s.node.marks.find((t=>t.type===e));if(!n)return!1;let i=t.index(),o=t.start()+s.offset,r=i+1,l=o+s.node.nodeSize;for(;i>0&&n.isInSet(t.parent.child(i-1).marks);)i-=1,o-=t.parent.child(i).nodeSize;for(;r{i=[...i,...t.marks]}));const o=i.find((t=>t.type.name===e.name));return o?o.attrs:{}},getNodeAttrs:function(t,e){const{from:s,to:n}=t.selection;let i=[];t.doc.nodesBetween(s,n,(t=>{i=[...i,t]}));const o=i.reverse().find((t=>t.type.name===e.name));return o?o.attrs:{}},markInputRule:function(t,e,s){return new r(t,((t,n,i,o)=>{const r=s instanceof Function?s(n):s,{tr:l}=t,a=n.length-1;let u=o,c=i;if(n[a]){const s=i+n[0].indexOf(n[a-1]),r=s+n[a-1].length-1,d=s+n[a-1].lastIndexOf(n[a]),p=d+n[a].length,h=function(t,e,s){let n=[];return s.doc.nodesBetween(t,e,((t,e)=>{n=[...n,...t.marks.map((s=>({start:e,end:e+t.nodeSize,mark:s})))]})),n}(i,o,t).filter((t=>{const{excluded:s}=t.mark.type;return s.find((t=>t.name===e.name))})).filter((t=>t.end>s));if(h.length)return!1;ps&&l.delete(s,d),c=s,u=c+n[a].length}return l.addMark(c,u,e.create(r)),l.removeStoredMark(e),l}))},markIsActive:function(t,e){const{from:s,$from:n,to:i,empty:o}=t.selection;return o?!!e.isInSet(t.storedMarks||n.marks()):!!t.doc.rangeHasMark(s,i,e)},markPasteRule:function(t,e,s){const n=(i,o)=>{const r=[];return i.forEach((i=>{var l;if(i.isText){const{text:n,marks:a}=i;let u,c=0;const d=!!a.filter((t=>"link"===t.type.name))[0];for(;!d&&null!==(u=t.exec(n));)if((null==(l=null==o?void 0:o.type)?void 0:l.allowsMarkType(e))&&u[1]){const t=u.index,n=t+u[0].length,o=t+u[0].indexOf(u[1]),l=o+u[1].length,a=s instanceof Function?s(u):s;t>0&&r.push(i.cut(c,t)),r.push(i.cut(o,l).mark(e.create(a).addToSet(i.marks))),c=n}cnew a(n(t.content),t.openStart,t.openEnd)}})},minMax:function(t=0,e=0,s=0){return Math.min(Math.max(parseInt(t,10),e),s)},nodeIsActive:be,nodeInputRule:function(t,e,s){return new r(t,((t,n,i,o)=>{const r=s instanceof Function?s(n):s,{tr:l}=t;return n[0]&&l.replaceWith(i-1,o,e.create(r)),l}))},pasteRule:function(t,e,s){const n=i=>{const o=[];return i.forEach((i=>{if(i.isText){const{text:n}=i;let r,l=0;do{if(r=t.exec(n),r){const t=r.index,n=t+r[0].length,a=s instanceof Function?s(r[0]):s;t>0&&o.push(i.cut(l,t)),o.push(i.cut(t,n).mark(e.create(a).addToSet(i.marks))),l=n}}while(r);lnew a(n(t.content),t.openStart,t.openEnd)}})},removeMark:function(t){return(e,s)=>{const{tr:n,selection:i}=e;let{from:o,to:r}=i;const{$from:l,empty:a}=i;if(a){const e=ye(l,t);o=e.from,r=e.to}return n.removeMark(o,r,t),s(n)}},toggleBlockType:function(t,e,s={}){return(n,i,o)=>be(n,t,s)?d(e)(n,i,o):d(t,s)(n,i,o)},toggleList:function(t,e){return(s,n,i)=>{const{schema:o,selection:r}=s,{$from:l,$to:a}=r,u=l.blockRange(a);if(!u)return!1;const c=ge((t=>ve(t,o)))(r);if(u.depth>=1&&c&&u.depth-c.depth<=1){if(c.node.type===t)return p(e)(s,n,i);if(ve(c.node,o)&&t.validContent(c.node.content)){const{tr:e}=s;return e.setNodeMarkup(c.pos,t),n&&n(e),!1}}return h(t)(s,n,i)}},updateMark:function(t,e){return(s,n)=>{const{tr:i,selection:o,doc:r}=s,{ranges:l,empty:a}=o;if(a){const{from:s,to:n}=ye(o.$from,t);r.rangeHasMark(s,n,t)&&i.removeMark(s,n,t),i.addMark(s,n,t.create(e))}else l.forEach((s=>{const{$to:n,$from:o}=s;r.rangeHasMark(o.pos,n.pos,t)&&i.removeMark(o.pos,n.pos,t),i.addMark(o.pos,n.pos,t.create(e))}));return n(i)}}};class _e{constructor(t=[],e){t.forEach((t=>{t.bindEditor(e),t.init()})),this.extensions=t}commands({schema:t,view:e}){return this.extensions.filter((t=>t.commands)).reduce(((s,n)=>{const{name:i,type:o}=n,r={},l=n.commands({schema:t,utils:$e,...["node","mark"].includes(o)?{type:t[`${o}s`][i]}:{}}),a=(t,s)=>{r[t]=t=>{if("function"!=typeof s||!e.editable)return!1;e.focus();const n=s(t);return"function"==typeof n?n(e.state,e.dispatch,e):n}};return"object"==typeof l?Object.entries(l).forEach((([t,e])=>{a(t,e)})):a(i,l),{...s,...r}}),{})}buttons(t="mark"){const e={};return this.extensions.filter((e=>e.type===t)).filter((t=>t.button)).forEach((t=>{Array.isArray(t.button)?t.button.forEach((t=>{e[t.id||t.name]=t})):e[t.name]=t.button})),e}getAllowedExtensions(t){return t instanceof Array||!t?t instanceof Array?this.extensions.filter((e=>!t.includes(e.name))):this.extensions:[]}getFromExtensions(t,e,s=this.extensions){return s.filter((t=>["extension"].includes(t.type))).filter((e=>e[t])).map((s=>s[t]({...e,utils:$e})))}getFromNodesAndMarks(t,e,s=this.extensions){return s.filter((t=>["node","mark"].includes(t.type))).filter((e=>e[t])).map((s=>s[t]({...e,type:e.schema[`${s.type}s`][s.name],utils:$e})))}inputRules({schema:t,excludedExtensions:e}){const s=this.getAllowedExtensions(e);return[...this.getFromExtensions("inputRules",{schema:t},s),...this.getFromNodesAndMarks("inputRules",{schema:t},s)].reduce(((t,e)=>[...t,...e]),[])}keymaps({schema:t}){return[...this.getFromExtensions("keys",{schema:t}),...this.getFromNodesAndMarks("keys",{schema:t})].map((t=>_(t)))}get marks(){return this.extensions.filter((t=>"mark"===t.type)).reduce(((t,{name:e,schema:s})=>({...t,[e]:s})),{})}get nodes(){return this.extensions.filter((t=>"node"===t.type)).reduce(((t,{name:e,schema:s})=>({...t,[e]:s})),{})}get options(){const{view:t}=this;return this.extensions.reduce(((e,s)=>({...e,[s.name]:new Proxy(s.options,{set(e,s,n){const i=e[s]!==n;return Object.assign(e,{[s]:n}),i&&t.updateState(t.state),!0}})})),{})}pasteRules({schema:t,excludedExtensions:e}){const s=this.getAllowedExtensions(e);return[...this.getFromExtensions("pasteRules",{schema:t},s),...this.getFromNodesAndMarks("pasteRules",{schema:t},s)].reduce(((t,e)=>[...t,...e]),[])}plugins({schema:t}){return[...this.getFromExtensions("plugins",{schema:t}),...this.getFromNodesAndMarks("plugins",{schema:t})].reduce(((t,e)=>[...t,...e]),[]).map((t=>t instanceof l?t:new l(t)))}}class xe{constructor(t={}){this.options={...this.defaults,...t}}init(){return null}bindEditor(t=null){this.editor=t}get name(){return null}get type(){return"extension"}get defaults(){return{}}plugins(){return[]}inputRules(){return[]}pasteRules(){return[]}keys(){return{}}}class we extends xe{constructor(t={}){super(t)}get type(){return"node"}get schema(){return null}commands(){return{}}}class Se extends we{get defaults(){return{inline:!1}}get name(){return"doc"}get schema(){return{content:this.options.inline?"inline*":"block+"}}}class Ce extends we{get button(){return{id:this.name,icon:"paragraph",label:window.panel.$t("toolbar.button.paragraph"),name:this.name}}commands({utils:t,type:e}){return{paragraph:()=>t.setBlockType(e)}}get schema(){return{content:"inline*",group:"block",draggable:!1,parseDOM:[{tag:"p"}],toDOM:()=>["p",0]}}get name(){return"paragraph"}}class Oe extends we{get name(){return"text"}get schema(){return{group:"inline"}}}class Ae extends class{emit(t,...e){this._callbacks=this._callbacks||{};const s=this._callbacks[t];return s&&s.forEach((t=>t.apply(this,e))),this}off(t,e){if(arguments.length){const s=this._callbacks?this._callbacks[t]:null;s&&(e?this._callbacks[t]=s.filter((t=>t!==e)):delete this._callbacks[t])}else this._callbacks={};return this}on(t,e){return this._callbacks=this._callbacks||{},this._callbacks[t]=this._callbacks[t]||[],this._callbacks[t].push(e),this}}{constructor(t={}){super(),this.defaults={autofocus:!1,content:"",disableInputRules:!1,disablePasteRules:!1,editable:!0,element:null,extensions:[],emptyDocument:{type:"doc",content:[]},events:{},inline:!1,parseOptions:{},topNode:"doc",useBuiltInExtensions:!0},this.init(t)}blur(){this.view.dom.blur()}get builtInExtensions(){return this.options.useBuiltInExtensions?[new Se({inline:this.options.inline}),new Oe,new Ce]:[]}buttons(t){return this.extensions.buttons(t)}clearContent(t=!1){this.setContent(this.options.emptyDocument,t)}command(t,...e){this.commands[t]&&this.commands[t](...e)}createCommands(){return this.extensions.commands({schema:this.schema,view:this.view})}createDocument(t,e=this.options.parseOptions){if(null===t)return this.schema.nodeFromJSON(this.options.emptyDocument);if("object"==typeof t)try{return this.schema.nodeFromJSON(t)}catch(s){return window.console.warn("Invalid content.","Passed value:",t,"Error:",s),this.schema.nodeFromJSON(this.options.emptyDocument)}if("string"==typeof t){const s=`
${t}
`,n=(new window.DOMParser).parseFromString(s,"text/html").body.firstElementChild;return x.fromSchema(this.schema).parse(n,e)}return!1}createEvents(){const t=this.options.events||{};return Object.entries(t).forEach((([t,e])=>{this.on(t,e)})),t}createExtensions(){return new _e([...this.builtInExtensions,...this.options.extensions],this)}createFocusEvents(){const t=(t,e,s=!0)=>{this.focused=s,this.emit(s?"focus":"blur",{event:e,state:t.state,view:t});const n=this.state.tr.setMeta("focused",s);this.view.dispatch(n)};return new l({props:{attributes:{tabindex:0},handleDOMEvents:{focus:(e,s)=>{t(e,s,!0)},blur:(e,s)=>{t(e,s,!1)}}}})}createInputRules(){return this.extensions.inputRules({schema:this.schema,excludedExtensions:this.options.disableInputRules})}createKeymaps(){return this.extensions.keymaps({schema:this.schema})}createMarks(){return this.extensions.marks}createNodes(){return this.extensions.nodes}createPasteRules(){return this.extensions.pasteRules({schema:this.schema,excludedExtensions:this.options.disablePasteRules})}createPlugins(){return this.extensions.plugins({schema:this.schema})}createSchema(){return new w({topNode:this.options.topNode,nodes:this.nodes,marks:this.marks})}createState(){return S.create({schema:this.schema,doc:this.createDocument(this.options.content),plugins:[...this.plugins,C({rules:this.inputRules}),...this.pasteRules,...this.keymaps,_({Backspace:I}),_(M),this.createFocusEvents()]})}createView(){return new O(this.element,{dispatchTransaction:this.dispatchTransaction.bind(this),editable:()=>this.options.editable,handlePaste:(t,e)=>{if("function"==typeof this.events.paste){const t=e.clipboardData.getData("text/html"),s=e.clipboardData.getData("text/plain");if(!0===this.events.paste(e,t,s))return!0}},handleDrop:(...t)=>{this.emit("drop",...t)},state:this.createState()})}destroy(){this.view&&this.view.destroy()}dispatchTransaction(t){const e=this.state,s=this.state.apply(t);this.view.updateState(s),this.selection={from:this.state.selection.from,to:this.state.selection.to},this.setActiveNodesAndMarks();const n={editor:this,getHTML:this.getHTML.bind(this),getJSON:this.getJSON.bind(this),state:this.state,transaction:t};this.emit("transaction",n),!t.docChanged&&t.getMeta("preventUpdate")||this.emit("update",n);const{from:i,to:o}=this.state.selection,r=!e||!e.selection.eq(s.selection);this.emit(s.selection.empty?"deselect":"select",{...n,from:i,hasChanged:r,to:o})}focus(t=null){if(this.view.focused&&null===t||!1===t)return;const{from:e,to:s}=this.selectionAtPosition(t);this.setSelection(e,s),setTimeout((()=>this.view.focus()),10)}getHTML(){const t=document.createElement("div"),e=A.fromSchema(this.schema).serializeFragment(this.state.doc.content);return t.appendChild(e),this.options.inline&&t.querySelector("p")?t.querySelector("p").innerHTML:t.innerHTML}getJSON(){return this.state.doc.toJSON()}getMarkAttrs(t=null){return this.activeMarkAttrs[t]}getSchemaJSON(){return JSON.parse(JSON.stringify({nodes:this.nodes,marks:this.marks}))}init(t={}){this.options={...this.defaults,...t},this.element=this.options.element,this.focused=!1,this.selection={from:0,to:0},this.events=this.createEvents(),this.extensions=this.createExtensions(),this.nodes=this.createNodes(),this.marks=this.createMarks(),this.schema=this.createSchema(),this.keymaps=this.createKeymaps(),this.inputRules=this.createInputRules(),this.pasteRules=this.createPasteRules(),this.plugins=this.createPlugins(),this.view=this.createView(),this.commands=this.createCommands(),this.setActiveNodesAndMarks(),!1!==this.options.autofocus&&this.focus(this.options.autofocus),this.emit("init",{view:this.view,state:this.state}),this.extensions.view=this.view,this.setContent(this.options.content,!0)}isEditable(){return this.options.editable}isEmpty(){if(this.state)return 0===this.state.doc.textContent.length}get isActive(){return Object.entries({...this.activeMarks,...this.activeNodes}).reduce(((t,[e,s])=>({...t,[e]:(t={})=>s(t)})),{})}removeMark(t){if(this.schema.marks[t])return $e.removeMark(this.schema.marks[t])(this.state,this.view.dispatch)}selectionAtPosition(t=null){if(this.selection&&null===t)return this.selection;if("start"===t||!0===t)return{from:0,to:0};if("end"===t){const{doc:t}=this.state;return{from:t.content.size,to:t.content.size}}return{from:t,to:t}}setActiveNodesAndMarks(){this.activeMarks=Object.values(this.schema.marks).filter((t=>$e.markIsActive(this.state,t))).map((t=>t.name)),this.activeMarkAttrs=Object.entries(this.schema.marks).reduce(((t,[e,s])=>({...t,[e]:$e.getMarkAttrs(this.state,s)})),{}),this.activeNodes=Object.values(this.schema.nodes).filter((t=>$e.nodeIsActive(this.state,t))).map((t=>t.name)),this.activeNodeAttrs=Object.entries(this.schema.nodes).reduce(((t,[e,s])=>({...t,[e]:$e.getNodeAttrs(this.state,s)})),{})}setContent(t={},e=!1,s){const{doc:n,tr:i}=this.state,o=this.createDocument(t,s),r=i.replaceWith(0,n.content.size,o).setMeta("preventUpdate",!e);this.view.dispatch(r)}setSelection(t=0,e=0){const{doc:s,tr:n}=this.state,i=$e.minMax(t,0,s.content.size),o=$e.minMax(e,0,s.content.size),r=T.create(s,i,o),l=n.setSelection(r);this.view.dispatch(l)}get state(){return this.view?this.view.state:null}toggleMark(t){if(this.schema.marks[t])return $e.toggleMark(this.schema.marks[t])(this.state,this.view.dispatch)}updateMark(t,e){if(this.schema.marks[t])return $e.updateMark(this.schema.marks[t],e)(this.state,this.view.dispatch)}}const Te=It({data:()=>({link:{href:null,title:null,target:!1}}),computed:{fields(){return{href:{label:this.$t("url"),type:"text",icon:"url"},title:{label:this.$t("title"),type:"text",icon:"title"},target:{label:this.$t("open.newWindow"),type:"toggle",text:[this.$t("no"),this.$t("yes")]}}}},methods:{open(t){this.link={title:null,target:!1,...t},this.link.target=Boolean(this.link.target),this.$refs.dialog.open()},submit(){this.$emit("submit",{...this.link,target:this.link.target?"_blank":null}),this.$refs.dialog.close()}}},(function(){var t=this;return(0,t._self._c)("k-form-dialog",{ref:"dialog",attrs:{fields:t.fields,"submit-button":t.$t("confirm"),size:"medium"},on:{close:function(e){return t.$emit("close")},submit:t.submit},model:{value:t.link,callback:function(e){t.link=e},expression:"link"}})}),[],!1,null,null,null,null).exports;const Ie=It({data:()=>({email:{email:null,title:null}}),computed:{fields(){return{href:{label:this.$t("email"),type:"email",icon:"email"},title:{label:this.$t("title"),type:"text",icon:"title"}}}},methods:{open(t){this.email={title:null,...t},this.$refs.dialog.open()},submit(){this.$emit("submit",this.email),this.$refs.dialog.close()}}},(function(){var t=this;return(0,t._self._c)("k-form-dialog",{ref:"dialog",attrs:{fields:t.fields,"submit-button":t.$t("confirm"),size:"medium"},on:{close:function(e){return t.$emit("close")},submit:t.submit},model:{value:t.email,callback:function(e){t.email=e},expression:"email"}})}),[],!1,null,null,null,null).exports;class Me extends xe{constructor(t={}){super(t)}command(){return()=>{}}remove(){this.editor.removeMark(this.name)}get schema(){return null}get type(){return"mark"}toggle(){return this.editor.toggleMark(this.name)}update(t){this.editor.updateMark(this.name,t)}}class Ee extends Me{get button(){return{icon:"code",label:window.panel.$t("toolbar.button.code")}}commands(){return()=>this.toggle()}inputRules({type:t,utils:e}){return[e.markInputRule(/(?:`)([^`]+)(?:`)$/,t)]}keys(){return{"Mod-`":()=>this.toggle()}}get name(){return"code"}pasteRules({type:t,utils:e}){return[e.markPasteRule(/(?:`)([^`]+)(?:`)/g,t)]}get schema(){return{excludes:"_",parseDOM:[{tag:"code"}],toDOM:()=>["code",0]}}}class Le extends Me{get button(){return{icon:"bold",label:window.panel.$t("toolbar.button.bold")}}commands(){return()=>this.toggle()}inputRules({type:t,utils:e}){return[e.markInputRule(/(?:\*\*|__)([^*_]+)(?:\*\*|__)$/,t)]}keys(){return{"Mod-b":()=>this.toggle()}}get name(){return"bold"}pasteRules({type:t,utils:e}){return[e.markPasteRule(/(?:\*\*|__)([^*_]+)(?:\*\*|__)/g,t)]}get schema(){return{parseDOM:[{tag:"strong"},{tag:"b",getAttrs:t=>"normal"!==t.style.fontWeight&&null},{style:"font-weight",getAttrs:t=>/^(bold(er)?|[5-9]\d{2,})$/.test(t)&&null}],toDOM:()=>["strong",0]}}}class je extends Me{get button(){return{icon:"italic",label:window.panel.$t("toolbar.button.italic")}}commands(){return()=>this.toggle()}inputRules({type:t,utils:e}){return[e.markInputRule(/(?:^|\s)((?:\*)((?:[^*]+))(?:\*))$/,t),e.markInputRule(/(?:^|\s)((?:_)((?:[^_]+))(?:_))$/,t)]}keys(){return{"Mod-i":()=>this.toggle()}}get name(){return"italic"}pasteRules({type:t,utils:e}){return[e.markPasteRule(/_([^_]+)_/g,t),e.markPasteRule(/\*([^*]+)\*/g,t)]}get schema(){return{parseDOM:[{tag:"i"},{tag:"em"},{style:"font-style=italic"}],toDOM:()=>["em",0]}}}class De extends Me{get button(){return{icon:"url",label:window.panel.$t("toolbar.button.link")}}commands(){return{link:()=>{this.editor.emit("link",this.editor)},insertLink:(t={})=>{if(t.href)return this.update(t)},removeLink:()=>this.remove(),toggleLink:(t={})=>{var e;(null==(e=t.href)?void 0:e.length)>0?this.editor.command("insertLink",t):this.editor.command("removeLink")}}}get defaults(){return{target:null}}get name(){return"link"}pasteRules({type:t,utils:e}){return[e.pasteRule(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b([-a-zA-Z0-9@:%_+.~#?&//=,]*)/gi,t,(t=>({href:t})))]}plugins(){return[{props:{handleClick:(t,e,s)=>{const n=this.editor.getMarkAttrs("link");n.href&&!0===s.altKey&&s.target instanceof HTMLAnchorElement&&(s.stopPropagation(),window.open(n.href,n.target))}}}]}get schema(){return{attrs:{href:{default:null},target:{default:null},title:{default:null}},inclusive:!1,parseDOM:[{tag:"a[href]:not([href^='mailto:'])",getAttrs:t=>({href:t.getAttribute("href"),target:t.getAttribute("target"),title:t.getAttribute("title")})}],toDOM:t=>["a",{...t.attrs,rel:"noopener noreferrer"},0]}}}class Be extends Me{get button(){return{icon:"email",label:"Email"}}commands(){return{email:()=>{this.editor.emit("email")},insertEmail:(t={})=>{if(t.href)return this.update(t)},removeEmail:()=>this.remove(),toggleEmail:(t={})=>{var e;(null==(e=t.href)?void 0:e.length)>0?this.editor.command("insertEmail",t):this.editor.command("removeEmail")}}}get defaults(){return{target:null}}get name(){return"email"}pasteRules({type:t,utils:e}){return[e.pasteRule(/^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/gi,t,(t=>({href:t})))]}plugins(){return[{props:{handleClick:(t,e,s)=>{const n=this.editor.getMarkAttrs("email");n.href&&!0===s.altKey&&s.target instanceof HTMLAnchorElement&&(s.stopPropagation(),window.open(n.href))}}}]}get schema(){return{attrs:{href:{default:null},title:{default:null}},inclusive:!1,parseDOM:[{tag:"a[href^='mailto:']",getAttrs:t=>({href:t.getAttribute("href").replace("mailto:",""),title:t.getAttribute("title")})}],toDOM:t=>["a",{...t.attrs,href:"mailto:"+t.attrs.href},0]}}}class Pe extends Me{get button(){return{icon:"strikethrough",label:window.panel.$t("toolbar.button.strike")}}commands(){return()=>this.toggle()}inputRules({type:t,utils:e}){return[e.markInputRule(/~([^~]+)~$/,t)]}keys(){return{"Mod-d":()=>this.toggle()}}get name(){return"strike"}pasteRules({type:t,utils:e}){return[e.markPasteRule(/~([^~]+)~/g,t)]}get schema(){return{parseDOM:[{tag:"s"},{tag:"del"},{tag:"strike"},{style:"text-decoration",getAttrs:t=>"line-through"===t}],toDOM:()=>["s",0]}}}class Ne extends Me{get button(){return{icon:"underline",label:window.panel.$t("toolbar.button.underline")}}commands(){return()=>this.toggle()}keys(){return{"Mod-u":()=>this.toggle()}}get name(){return"underline"}get schema(){return{parseDOM:[{tag:"u"},{style:"text-decoration",getAttrs:t=>"underline"===t}],toDOM:()=>["u",0]}}}class qe extends we{get button(){return{id:this.name,icon:"list-bullet",label:window.panel.$t("toolbar.button.ul"),name:this.name,when:["listItem","bulletList","orderedList"]}}commands({type:t,schema:e,utils:s}){return()=>s.toggleList(t,e.nodes.listItem)}inputRules({type:t,utils:e}){return[e.wrappingInputRule(/^\s*([-+*])\s$/,t)]}keys({type:t,schema:e,utils:s}){return{"Shift-Ctrl-8":s.toggleList(t,e.nodes.listItem)}}get name(){return"bulletList"}get schema(){return{content:"listItem+",group:"block",parseDOM:[{tag:"ul"}],toDOM:()=>["ul",0]}}}class Fe extends we{commands({utils:t,type:e}){return()=>this.createHardBreak(t,e)}createHardBreak(t,e){return t.chainCommands(t.exitCode,((t,s)=>(s(t.tr.replaceSelectionWith(e.create()).scrollIntoView()),!0)))}get defaults(){return{enter:!1,text:!1}}keys({utils:t,type:e}){const s=this.createHardBreak(t,e);let n={"Mod-Enter":s,"Shift-Enter":s};return this.options.enter&&(n.Enter=s),n}get name(){return"hardBreak"}get schema(){return{inline:!0,group:"inline",selectable:!1,parseDOM:[{tag:"br"}],toDOM:()=>["br"]}}}class Re extends we{get button(){return this.options.levels.map((t=>({id:`h${t}`,command:`h${t}`,icon:`h${t}`,label:window.panel.$t("toolbar.button.heading."+t),attrs:{level:t},name:this.name,when:["heading","paragraph"]})))}commands({type:t,schema:e,utils:s}){let n={toggleHeading:n=>s.toggleBlockType(t,e.nodes.paragraph,n)};return this.options.levels.forEach((i=>{n[`h${i}`]=()=>s.toggleBlockType(t,e.nodes.paragraph,{level:i})})),n}get defaults(){return{levels:[1,2,3,4,5,6]}}inputRules({type:t,utils:e}){return this.options.levels.map((s=>e.textblockTypeInputRule(new RegExp(`^(#{1,${s}})\\s$`),t,(()=>({level:s})))))}keys({type:t,utils:e}){return this.options.levels.reduce(((s,n)=>({...s,[`Shift-Ctrl-${n}`]:e.setBlockType(t,{level:n})})),{})}get name(){return"heading"}get schema(){return{attrs:{level:{default:1}},content:"inline*",group:"block",defining:!0,draggable:!1,parseDOM:this.options.levels.map((t=>({tag:`h${t}`,attrs:{level:t}}))),toDOM:t=>[`h${t.attrs.level}`,0]}}}class ze extends we{commands({type:t}){return()=>(e,s)=>s(e.tr.replaceSelectionWith(t.create()))}inputRules({type:t,utils:e}){return[e.nodeInputRule(/^(?:---|___\s|\*\*\*\s)$/,t)]}get name(){return"horizontalRule"}get schema(){return{group:"block",parseDOM:[{tag:"hr"}],toDOM:()=>["hr"]}}}class Ye extends we{keys({type:t,utils:e}){return{Enter:e.splitListItem(t),"Shift-Tab":e.liftListItem(t),Tab:e.sinkListItem(t)}}get name(){return"listItem"}get schema(){return{content:"paragraph block*",defining:!0,draggable:!1,parseDOM:[{tag:"li"}],toDOM:()=>["li",0]}}}class He extends we{get button(){return{id:this.name,icon:"list-numbers",label:window.panel.$t("toolbar.button.ol"),name:this.name,when:["listItem","bulletList","orderedList"]}}commands({type:t,schema:e,utils:s}){return()=>s.toggleList(t,e.nodes.listItem)}inputRules({type:t,utils:e}){return[e.wrappingInputRule(/^(\d+)\.\s$/,t,(t=>({order:+t[1]})),((t,e)=>e.childCount+e.attrs.order===+t[1]))]}keys({type:t,schema:e,utils:s}){return{"Shift-Ctrl-9":s.toggleList(t,e.nodes.listItem)}}get name(){return"orderedList"}get schema(){return{attrs:{order:{default:1}},content:"listItem+",group:"block",parseDOM:[{tag:"ol",getAttrs:t=>({order:t.hasAttribute("start")?+t.getAttribute("start"):1})}],toDOM:t=>1===t.attrs.order?["ol",0]:["ol",{start:t.attrs.order},0]}}}class Ue extends xe{commands(){return{undo:()=>E,redo:()=>L,undoDepth:()=>j,redoDepth:()=>D}}get defaults(){return{depth:"",newGroupDelay:""}}keys(){return{"Mod-z":E,"Mod-y":L,"Shift-Mod-z":L,"Mod-я":E,"Shift-Mod-я":L}}get name(){return"history"}plugins(){return[B({depth:this.options.depth,newGroupDelay:this.options.newGroupDelay})]}}class Ke extends xe{commands(){return{insertHtml:t=>(e,s)=>{let n=document.createElement("div");n.innerHTML=t.trim();const i=x.fromSchema(e.schema).parse(n);s(e.tr.replaceSelectionWith(i).scrollIntoView())}}}}class Ge extends xe{constructor(t={}){super(t)}close(){this.visible=!1,this.emit()}emit(){this.editor.emit("toolbar",{marks:this.marks,nodes:this.nodes,nodeAttrs:this.nodeAttrs,position:this.position,visible:this.visible})}init(){this.position={left:0,bottom:0},this.visible=!1,this.editor.on("blur",(()=>{this.close()})),this.editor.on("deselect",(()=>{this.close()})),this.editor.on("select",(({hasChanged:t})=>{!1!==t?this.open():this.emit()}))}get marks(){return this.editor.activeMarks}get nodes(){return this.editor.activeNodes}get nodeAttrs(){return this.editor.activeNodeAttrs}open(){this.visible=!0,this.reposition(),this.emit()}reposition(){const{from:t,to:e}=this.editor.selection,s=this.editor.view.coordsAtPos(t),n=this.editor.view.coordsAtPos(e,!0),i=this.editor.element.getBoundingClientRect();let o=(s.left+n.left)/2-i.left,r=Math.round(i.bottom-s.top);return this.position={bottom:r,left:o}}get type(){return"toolbar"}}const Je=It({props:{activeMarks:{type:Array,default:()=>[]},activeNodes:{type:Array,default:()=>[]},activeNodeAttrs:{type:[Array,Object],default:()=>[]},editor:{type:Object,required:!0},marks:{type:Array},isParagraphNodeHidden:{type:Boolean,default:!1}},computed:{activeButton(){return Object.values(this.nodeButtons).find((t=>this.isButtonActive(t)))||!1},hasVisibleButtons(){const t=Object.keys(this.nodeButtons);return t.length>1||1===t.length&&!1===t.includes("paragraph")},markButtons(){return this.buttons("mark")},nodeButtons(){let t=this.buttons("node");return!0===this.isParagraphNodeHidden&&t.paragraph&&delete t.paragraph,t}},methods:{buttons(t){const e=this.editor.buttons(t);let s=this.sorting;!1!==s&&!1!==Array.isArray(s)||(s=Object.keys(e));let n={};return s.forEach((t=>{e[t]&&(n[t]=e[t])})),n},command(t,...e){this.$emit("command",t,...e)},isButtonActive(t){if("paragraph"===t.name)return 1===this.activeNodes.length&&this.activeNodes.includes(t.name);let e=!0;if(t.attrs){const s=Object.values(this.activeNodeAttrs).find((e=>JSON.stringify(e)===JSON.stringify(t.attrs)));e=Boolean(s||!1)}return!0===e&&this.activeNodes.includes(t.name)},isButtonCurrent(t){return!!this.activeButton&&this.activeButton.id===t.id},isButtonDisabled(t){var e;if(null==(e=this.activeButton)?void 0:e.when){return!1===this.activeButton.when.includes(t.name)}return!1},needDividerAfterNode(t){let e=["paragraph"],s=Object.keys(this.nodeButtons);return(s.includes("bulletList")||s.includes("orderedList"))&&e.push("h6"),e.includes(t.id)}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-writer-toolbar"},[t.hasVisibleButtons?e("k-dropdown",{nativeOn:{mousedown:function(t){t.preventDefault()}}},[e("k-button",{class:{"k-writer-toolbar-button k-writer-toolbar-nodes":!0,"k-writer-toolbar-button-active":!!t.activeButton},attrs:{icon:t.activeButton.icon||"title"},on:{click:function(e){return t.$refs.nodes.toggle()}}}),e("k-dropdown-content",{ref:"nodes"},[t._l(t.nodeButtons,(function(s,n){return[e("k-dropdown-item",{key:n,attrs:{current:t.isButtonCurrent(s),disabled:t.isButtonDisabled(s),icon:s.icon},on:{click:function(e){return t.command(s.command||n)}}},[t._v(" "+t._s(s.label)+" ")]),t.needDividerAfterNode(s)?e("hr",{key:n+"-divider"}):t._e()]}))],2)],1):t._e(),t._l(t.markButtons,(function(s,n){return e("k-button",{key:n,class:{"k-writer-toolbar-button":!0,"k-writer-toolbar-button-active":t.activeMarks.includes(n)},attrs:{icon:s.icon,tooltip:s.label},on:{mousedown:function(e){return e.preventDefault(),t.command(s.command||n)}}})}))],2)}),[],!1,null,null,null,null).exports,Ve={props:{autofocus:Boolean,breaks:Boolean,code:Boolean,disabled:Boolean,emptyDocument:{type:Object,default:()=>({type:"doc",content:[]})},headings:[Array,Boolean],inline:{type:Boolean,default:!1},marks:{type:[Array,Boolean],default:!0},nodes:{type:[Array,Boolean],default:()=>["heading","bulletList","orderedList"]},paste:{type:Function,default:()=>()=>!1},placeholder:String,spellcheck:Boolean,extensions:Array,value:{type:String,default:""}}};const We=It({components:{"k-writer-email-dialog":Ie,"k-writer-link-dialog":Te,"k-writer-toolbar":Je},mixins:[Ve],data(){return{editor:null,json:{},html:this.value,isEmpty:!0,toolbar:!1}},computed:{isParagraphNodeHidden(){return!0===Array.isArray(this.nodes)&&3!==this.nodes.length&&!1===this.nodes.includes("paragraph")}},watch:{value(t,e){t!==e&&t!==this.html&&(this.html=t,this.editor.setContent(this.html))}},mounted(){this.editor=new Ae({autofocus:this.autofocus,content:this.value,editable:!this.disabled,element:this.$el,emptyDocument:this.emptyDocument,events:{link:t=>{this.$refs.linkDialog.open(t.getMarkAttrs("link"))},email:()=>{this.$refs.emailDialog.open(this.editor.getMarkAttrs("email"))},paste:this.paste,toolbar:t=>{this.toolbar=t,this.toolbar.visible&&this.$nextTick((()=>{this.onToolbarOpen()}))},update:t=>{if(!this.editor)return;const e=JSON.stringify(this.editor.getJSON());e!==JSON.stringify(this.json)&&(this.json=e,this.isEmpty=t.editor.isEmpty(),this.html=t.editor.getHTML(),this.isEmpty&&(0===t.editor.activeNodes.length||t.editor.activeNodes.includes("paragraph"))&&(this.html=""),this.$emit("input",this.html))}},extensions:[...this.createMarks(),...this.createNodes(),new Ue,new Ke,new Ge,...this.extensions||[]],inline:this.inline}),this.isEmpty=this.editor.isEmpty(),this.json=this.editor.getJSON()},beforeDestroy(){this.editor.destroy()},methods:{filterExtensions(t,e,s){!1===e?e=[]:!0!==e&&!1!==Array.isArray(e)||(e=Object.keys(t));let n=[];return e.forEach((e=>{t[e]&&n.push(t[e])})),"function"==typeof s&&(n=s(e,n)),n},command(t,...e){this.editor.command(t,...e)},createMarks(){return this.filterExtensions({bold:new Le,italic:new je,strike:new Pe,underline:new Ne,code:new Ee,link:new De,email:new Be},this.marks)},createNodes(){const t=new Fe({text:!0,enter:this.inline});return!0===this.inline?[t]:this.filterExtensions({bulletList:new qe,orderedList:new He,heading:new Re,horizontalRule:new ze,listItem:new Ye},this.nodes,((e,s)=>((e.includes("bulletList")||e.includes("orderedList"))&&s.push(new Ye),s.push(t),s)))},getHTML(){return this.editor.getHTML()},focus(){this.editor.focus()},onToolbarOpen(){if(this.$refs.toolbar){const t=this.$el.clientWidth,e=this.$refs.toolbar.$el.clientWidth;let s=this.toolbar.position.left;s-e/2<0&&(s=s+(e/2-s)-20),s+e/2>t&&(s=s-(s+e/2-t)+20),s!==this.toolbar.position.left&&(this.$refs.toolbar.$el.style.left=s+"px")}}}},(function(){var t=this,e=t._self._c;return e("div",{directives:[{name:"direction",rawName:"v-direction"}],ref:"editor",staticClass:"k-writer",attrs:{"data-empty":t.isEmpty,"data-placeholder":t.placeholder,spellcheck:t.spellcheck}},[t.editor?[t.toolbar.visible?e("k-writer-toolbar",{ref:"toolbar",style:{bottom:t.toolbar.position.bottom+"px","inset-inline-start":t.toolbar.position.left+"px"},attrs:{editor:t.editor,"active-marks":t.toolbar.marks,"active-nodes":t.toolbar.nodes,"active-node-attrs":t.toolbar.nodeAttrs,"is-paragraph-node-hidden":t.isParagraphNodeHidden},on:{command:function(e){return t.editor.command(e)}}}):t._e(),e("k-writer-link-dialog",{ref:"linkDialog",on:{close:function(e){return t.editor.focus()},submit:function(e){return t.editor.command("toggleLink",e)}}}),e("k-writer-email-dialog",{ref:"emailDialog",on:{close:function(e){return t.editor.focus()},submit:function(e){return t.editor.command("toggleEmail",e)}}})]:t._e()],2)}),[],!1,null,null,null,null).exports;const Xe=It({},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-login-alert",on:{click:function(e){return t.$emit("click")}}},[e("span",[t._t("default")],2),e("k-icon",{attrs:{type:"alert"}})],1)}),[],!1,null,null,null,null).exports;const Ze=It({props:{fields:Object,index:[Number,String],total:Number,value:Object},mounted(){this.$store.dispatch("content/disable"),this.$events.$on("keydown.cmd.s",this.onSubmit),this.$events.$on("keydown.esc",this.onDiscard)},destroyed(){this.$events.$off("keydown.cmd.s",this.onSubmit),this.$events.$off("keydown.esc",this.onDiscard),this.$store.dispatch("content/enable")},methods:{focus(t){this.$refs.form.focus(t)},onDiscard(){this.$emit("discard")},onInput(t){this.$emit("input",t)},onSubmit(){this.$emit("submit")}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-structure-form"},[e("div",{staticClass:"k-structure-backdrop",on:{click:t.onDiscard}}),e("section",[e("k-form",{ref:"form",staticClass:"k-structure-form-fields",attrs:{value:t.value,fields:t.fields},on:{input:t.onInput,submit:t.onSubmit}}),e("footer",{staticClass:"k-structure-form-buttons"},[e("k-button",{staticClass:"k-structure-form-cancel-button",attrs:{text:t.$t("cancel"),icon:"cancel"},on:{click:function(e){return t.$emit("close")}}}),"new"!==t.index?e("k-pagination",{attrs:{dropdown:!1,total:t.total,limit:1,page:t.index+1,details:!0},on:{paginate:function(e){return t.$emit("paginate",e)}}}):t._e(),e("k-button",{staticClass:"k-structure-form-submit-button",attrs:{text:t.$t("new"!==t.index?"confirm":"add"),icon:"check"},on:{click:t.onSubmit}})],1)],1)])}),[],!1,null,null,null,null).exports,Qe=function(t){this.command("insert",((e,s)=>{let n=[];return s.split("\n").forEach(((e,s)=>{let i="ol"===t?s+1+".":"-";n.push(i+" "+e)})),n.join("\n")}))};const ts=It({layout:["headlines","bold","italic","|","link","email","file","|","code","ul","ol"],props:{buttons:{type:[Boolean,Array],default:!0},uploads:[Boolean,Object,Array]},data(){let t={},e={},s=[],n=this.commands();return!1===this.buttons?t:(Array.isArray(this.buttons)&&(s=this.buttons),!0!==Array.isArray(this.buttons)&&(s=this.$options.layout),s.forEach(((s,i)=>{if("|"===s)t["divider-"+i]={divider:!0};else if(n[s]){let i=n[s];t[s]=i,i.shortcut&&(e[i.shortcut]=s)}})),{layout:t,shortcuts:e})},methods:{command(t,e){"function"==typeof t?t.apply(this):this.$emit("command",t,e)},close(){Object.keys(this.$refs).forEach((t=>{const e=this.$refs[t][0];"function"==typeof(null==e?void 0:e.close)&&e.close()}))},fileCommandSetup(){let t={label:this.$t("toolbar.button.file"),icon:"attachment"};return!1===this.uploads?t.command="selectFile":t.dropdown={select:{label:this.$t("toolbar.button.file.select"),icon:"check",command:"selectFile"},upload:{label:this.$t("toolbar.button.file.upload"),icon:"upload",command:"uploadFile"}},t},commands(){return{headlines:{label:this.$t("toolbar.button.headings"),icon:"title",dropdown:{h1:{label:this.$t("toolbar.button.heading.1"),icon:"title",command:"prepend",args:"#"},h2:{label:this.$t("toolbar.button.heading.2"),icon:"title",command:"prepend",args:"##"},h3:{label:this.$t("toolbar.button.heading.3"),icon:"title",command:"prepend",args:"###"}}},bold:{label:this.$t("toolbar.button.bold"),icon:"bold",command:"wrap",args:"**",shortcut:"b"},italic:{label:this.$t("toolbar.button.italic"),icon:"italic",command:"wrap",args:"*",shortcut:"i"},link:{label:this.$t("toolbar.button.link"),icon:"url",shortcut:"k",command:"dialog",args:"link"},email:{label:this.$t("toolbar.button.email"),icon:"email",shortcut:"e",command:"dialog",args:"email"},file:this.fileCommandSetup(),code:{label:this.$t("toolbar.button.code"),icon:"code",command:"wrap",args:"`"},ul:{label:this.$t("toolbar.button.ul"),icon:"list-bullet",command(){return Qe.apply(this,["ul"])}},ol:{label:this.$t("toolbar.button.ol"),icon:"list-numbers",command(){return Qe.apply(this,["ol"])}}}},shortcut(t,e){if(this.shortcuts[t]){const s=this.layout[this.shortcuts[t]];if(!s)return!1;e.preventDefault(),this.command(s.command,s.args)}}}},(function(){var t=this,e=t._self._c;return e("nav",{staticClass:"k-toolbar"},[e("div",{staticClass:"k-toolbar-wrapper"},[e("div",{staticClass:"k-toolbar-buttons"},[t._l(t.layout,(function(s,n){return[s.divider?[e("span",{key:n,staticClass:"k-toolbar-divider"})]:s.dropdown?[e("k-dropdown",{key:n},[e("k-button",{key:n,staticClass:"k-toolbar-button",attrs:{icon:s.icon,tooltip:s.label,tabindex:"-1"},on:{click:function(e){t.$refs[n+"-dropdown"][0].toggle()}}}),e("k-dropdown-content",{ref:n+"-dropdown",refInFor:!0},t._l(s.dropdown,(function(s,n){return e("k-dropdown-item",{key:n,attrs:{icon:s.icon},on:{click:function(e){return t.command(s.command,s.args)}}},[t._v(" "+t._s(s.label)+" ")])})),1)],1)]:[e("k-button",{key:n,staticClass:"k-toolbar-button",attrs:{icon:s.icon,tooltip:s.label,tabindex:"-1"},on:{click:function(e){return t.command(s.command,s.args)}}})]]}))],2)])])}),[],!1,null,null,null,null).exports;const es=It({data(){return{value:{email:null,text:null},fields:{email:{label:this.$t("email"),type:"email"},text:{label:this.$t("link.text"),type:"text"}}}},computed:{kirbytext(){return this.$config.kirbytext}},methods:{open(t,e){this.value.text=e,this.$refs.dialog.open()},cancel(){this.$emit("cancel")},createKirbytext(){var t;const e=this.value.email||"";return(null==(t=this.value.text)?void 0:t.length)>0?`(email: ${e} text: ${this.value.text})`:`(email: ${e})`},createMarkdown(){var t;const e=this.value.email||"";return(null==(t=this.value.text)?void 0:t.length)>0?`[${this.value.text}](mailto:${e})`:`<${e}>`},submit(){this.$emit("submit",this.kirbytext?this.createKirbytext():this.createMarkdown()),this.value={email:null,text:null},this.$refs.dialog.close()}}},(function(){var t=this,e=t._self._c;return e("k-dialog",{ref:"dialog",attrs:{"submit-button":t.$t("insert")},on:{close:t.cancel,submit:function(e){return t.$refs.form.submit()}}},[e("k-form",{ref:"form",attrs:{fields:t.fields},on:{submit:t.submit},model:{value:t.value,callback:function(e){t.value=e},expression:"value"}})],1)}),[],!1,null,null,null,null).exports;const ss=It({data(){return{value:{url:null,text:null},fields:{url:{label:this.$t("link"),type:"text",placeholder:this.$t("url.placeholder"),icon:"url"},text:{label:this.$t("link.text"),type:"text"}}}},computed:{kirbytext(){return this.$config.kirbytext}},methods:{open(t,e){this.value.text=e,this.$refs.dialog.open()},cancel(){this.$emit("cancel")},createKirbytext(){return this.value.text.length>0?`(link: ${this.value.url} text: ${this.value.text})`:`(link: ${this.value.url})`},createMarkdown(){return this.value.text.length>0?`[${this.value.text}](${this.value.url})`:`<${this.value.url}>`},submit(){this.$emit("submit",this.kirbytext?this.createKirbytext():this.createMarkdown()),this.value={url:null,text:null},this.$refs.dialog.close()}}},(function(){var t=this,e=t._self._c;return e("k-dialog",{ref:"dialog",attrs:{"submit-button":t.$t("insert")},on:{close:t.cancel,submit:function(e){return t.$refs.form.submit()}}},[e("k-form",{ref:"form",attrs:{fields:t.fields},on:{submit:t.submit},model:{value:t.value,callback:function(e){t.value=e},expression:"value"}})],1)}),[],!1,null,null,null,null).exports;const ns=It({mixins:[Zt,te,se,ie,re],inheritAttrs:!1,props:{value:Boolean},watch:{value(){this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus()},methods:{focus(){this.$refs.input.focus()},onChange(t){this.$emit("input",t)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},select(){this.focus()}},validations(){return{value:{required:!this.required||P.required}}}},(function(){var t=this,e=t._self._c;return e("label",{staticClass:"k-checkbox-input",on:{click:function(t){t.stopPropagation()}}},[e("input",{ref:"input",staticClass:"k-checkbox-input-native input-hidden",attrs:{id:t.id,disabled:t.disabled,type:"checkbox"},domProps:{checked:t.value},on:{change:function(e){return t.onChange(e.target.checked)}}}),e("span",{staticClass:"k-checkbox-input-icon",attrs:{"aria-hidden":"true"}},[e("svg",{attrs:{width:"12",height:"10",viewBox:"0 0 12 10",xmlns:"http://www.w3.org/2000/svg"}},[e("path",{attrs:{d:"M1 5l3.3 3L11 1","stroke-width":"2",fill:"none","fill-rule":"evenodd"}})])]),e("span",{staticClass:"k-checkbox-input-label",domProps:{innerHTML:t._s(t.label)}})])}),[],!1,null,null,null,null).exports,is={mixins:[Zt,te,se,re],props:{columns:Number,max:Number,min:Number,options:Array,value:{type:[Array,Object],default:()=>[]}}};const os=It({mixins:[is],inheritAttrs:!1,data(){return{selected:this.valueToArray(this.value)}},watch:{value(t){this.selected=this.valueToArray(t)},selected(){this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus()},methods:{focus(){this.$el.querySelector("input").focus()},onInput(t,e){if(!0===e)this.selected.push(t);else{const e=this.selected.indexOf(t);-1!==e&&this.selected.splice(e,1)}this.$emit("input",this.selected)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},select(){this.focus()},valueToArray:t=>!0===Array.isArray(t)?t:"string"==typeof t?String(t).split(","):"object"==typeof t?Object.values(t):void 0},validations(){return{selected:{required:!this.required||P.required,min:!this.min||P.minLength(this.min),max:!this.max||P.maxLength(this.max)}}}},(function(){var t=this,e=t._self._c;return e("ul",{staticClass:"k-checkboxes-input",style:"--columns:"+t.columns},t._l(t.options,(function(s,n){return e("li",{key:n},[e("k-checkbox-input",{attrs:{id:t.id+"-"+n,label:s.text,value:-1!==t.selected.indexOf(s.value)},on:{input:function(e){return t.onInput(s.value,e)}}})],1)})),0)}),[],!1,null,null,null,null).exports,rs={mixins:[Zt,te,se,re],props:{display:{type:String,default:"DD.MM.YYYY"},max:String,min:String,step:{type:Object,default:()=>({size:1,unit:"day"})},type:{type:String,default:"date"},value:String}};const ls=It({mixins:[rs],inheritAttrs:!1,data:()=>({dt:null,formatted:null}),computed:{inputType:()=>"date",pattern(){return this.$library.dayjs.pattern(this.display)},rounding(){return{...this.$options.props.step.default(),...this.step}}},watch:{value:{handler(t,e){if(t!==e){const e=this.toDatetime(t);this.commit(e)}},immediate:!0}},created(){this.$events.$on("keydown.cmd.s",this.onBlur)},destroyed(){this.$events.$off("keydown.cmd.s",this.onBlur)},methods:{alter(t){let e=this.parse()||this.round(this.$library.dayjs()),s=this.rounding.unit,n=this.rounding.size;const i=this.selection();null!==i&&("meridiem"===i.unit?(t="pm"===e.format("a")?"subtract":"add",s="hour",n=12):(s=i.unit,s!==this.rounding.unit&&(n=1))),e=e[t](n,s).round(this.rounding.unit,this.rounding.size),this.commit(e),this.emit(e),this.$nextTick((()=>this.select(i)))},commit(t){this.dt=t,this.formatted=this.pattern.format(t),this.$emit("invalid",this.$v.$invalid,this.$v)},emit(t){this.$emit("input",this.toISO(t))},focus(){this.$refs.input.focus()},onArrowDown(){this.alter("subtract")},onArrowUp(){this.alter("add")},onBlur(){const t=this.parse();this.commit(t),this.emit(t)},onEnter(){this.onBlur(),this.$nextTick((()=>this.$emit("submit")))},onInput(t){const e=this.parse(),s=this.pattern.format(e);if(!t||s==t)return this.commit(e),this.emit(e)},onTab(t){""!=this.$refs.input.value&&(this.onBlur(),this.$nextTick((()=>{const e=this.selection();if(this.$refs.input&&e.start===this.$refs.input.selectionStart&&e.end===this.$refs.input.selectionEnd-1)if(t.shiftKey){if(0===e.index)return;this.selectPrev(e.index)}else{if(e.index===this.pattern.parts.length-1)return;this.selectNext(e.index)}else t.shiftKey?this.selectLast():this.selectFirst();t.preventDefault()})))},parse(){let t=this.$refs.input.value;return t=this.$library.dayjs.interpret(t,this.inputType),this.round(t)},round(t){return(null==t?void 0:t.round(this.rounding.unit,this.rounding.size))||null},select(t){var e;t||(t=this.selection()),null==(e=this.$refs.input)||e.setSelectionRange(t.start,t.end+1)},selectFirst(){this.select(this.pattern.parts[0])},selectLast(){this.select(this.pattern.parts[this.pattern.parts.length-1])},selectNext(t){this.select(this.pattern.parts[t+1])},selectPrev(t){this.select(this.pattern.parts[t-1])},selection(){return this.pattern.at(this.$refs.input.selectionStart,this.$refs.input.selectionEnd)},toDatetime(t){return this.round(this.$library.dayjs.iso(t,this.inputType))},toISO(t){return(null==t?void 0:t.toISO(this.inputType))||null}},validations(){return{value:{min:!this.dt||!this.min||(()=>this.dt.validate(this.min,"min",this.rounding.unit)),max:!this.dt||!this.max||(()=>this.dt.validate(this.max,"max",this.rounding.unit)),required:!this.required||(()=>!!this.dt)}}}},(function(){var t=this;return(0,t._self._c)("input",{directives:[{name:"model",rawName:"v-model",value:t.formatted,expression:"formatted"},{name:"direction",rawName:"v-direction"}],ref:"input",class:`k-text-input k-${t.type}-input`,attrs:{id:t.id,autofocus:t.autofocus,disabled:t.disabled,placeholder:t.display,required:t.required,autocomplete:"off",spellcheck:"false",type:"text"},domProps:{value:t.formatted},on:{blur:t.onBlur,focus:function(e){return t.$emit("focus")},input:[function(e){e.target.composing||(t.formatted=e.target.value)},function(e){return t.onInput(e.target.value)}],keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"down",40,e.key,["Down","ArrowDown"])?null:(e.stopPropagation(),e.preventDefault(),t.onArrowDown.apply(null,arguments))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"up",38,e.key,["Up","ArrowUp"])?null:(e.stopPropagation(),e.preventDefault(),t.onArrowUp.apply(null,arguments))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:(e.stopPropagation(),e.preventDefault(),t.onEnter.apply(null,arguments))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"tab",9,e.key,"Tab")?null:t.onTab.apply(null,arguments)}]}})}),[],!1,null,null,null,null).exports,as={mixins:[Zt,te,se,oe,re],props:{autocomplete:{type:[Boolean,String],default:"off"},maxlength:Number,minlength:Number,pattern:String,placeholder:String,preselect:Boolean,spellcheck:{type:[Boolean,String],default:"off"},type:{type:String,default:"text"},value:String}};const us=It({mixins:[as],inheritAttrs:!1,data(){return{listeners:{...this.$listeners,input:t=>this.onInput(t.target.value)}}},watch:{value(){this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus(),this.$props.preselect&&this.select()},methods:{focus(){this.$refs.input.focus()},onInput(t){this.$emit("input",t)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},select(){this.$refs.input.select()}},validations(){return{value:{required:!this.required||P.required,minLength:!this.minlength||P.minLength(this.minlength),maxLength:!this.maxlength||P.maxLength(this.maxlength),email:"email"!==this.type||P.email,url:"url"!==this.type||P.url,pattern:!this.pattern||(t=>!this.required&&!t||!this.$refs.input.validity.patternMismatch)}}}},(function(){var t=this;return(0,t._self._c)("input",t._g(t._b({directives:[{name:"direction",rawName:"v-direction"}],ref:"input",staticClass:"k-text-input"},"input",{autocomplete:t.autocomplete,autofocus:t.autofocus,disabled:t.disabled,id:t.id,minlength:t.minlength,name:t.name,pattern:t.pattern,placeholder:t.placeholder,required:t.required,spellcheck:t.spellcheck,type:t.type,value:t.value},!1),t.listeners))}),[],!1,null,null,null,null).exports,cs={mixins:[as],props:{autocomplete:{type:String,default:"email"},placeholder:{type:String,default:()=>window.panel.$t("email.placeholder")},type:{type:String,default:"email"}}};const ds=It({extends:us,mixins:[cs]},null,null,!1,null,null,null,null).exports;class ps extends Se{get schema(){return{content:"bulletList|orderedList"}}}const hs=It({inheritAttrs:!1,props:{autofocus:Boolean,marks:{type:[Array,Boolean],default:!0},value:String},data(){return{list:this.value,html:this.value}},computed:{extensions:()=>[new ps({inline:!0})]},watch:{value(t){t!==this.html&&(this.list=t,this.html=t)}},methods:{focus(){this.$refs.input.focus()},onInput(t){let e=(new DOMParser).parseFromString(t,"text/html").querySelector("ul, ol");e&&0!==e.textContent.trim().length?(this.list=t,this.html=t.replace(/(

|<\/p>)/gi,""),this.$emit("input",this.html)):this.$emit("input",this.list="")}}},(function(){var t=this;return(0,t._self._c)("k-writer",t._b({ref:"input",staticClass:"k-list-input",attrs:{extensions:t.extensions,nodes:["bulletList","orderedList"],value:t.list},on:{input:t.onInput}},"k-writer",t.$props,!1))}),[],!1,null,null,null,null).exports,ms={mixins:[te,se,re],props:{max:Number,min:Number,layout:String,options:{type:Array,default:()=>[]},search:[Object,Boolean],separator:{type:String,default:","},sort:Boolean,value:{type:Array,required:!0,default:()=>[]}}};const fs=It({mixins:[ms],inheritAttrs:!1,data(){return{state:this.value,q:null,limit:!0,scrollTop:0}},computed:{draggable(){return this.state.length>1&&!this.sort},dragOptions(){return{disabled:!this.draggable,draggable:".k-tag",delay:1}},emptyLabel(){return this.q?this.$t("search.results.none"):this.$t("options.none")},filtered(){var t;return(null==(t=this.q)?void 0:t.length)>=(this.search.min||0)?this.options.filter((t=>this.isFiltered(t))).map((t=>({...t,display:this.toHighlightedString(t.text),info:this.toHighlightedString(t.value)}))):this.options.map((t=>({...t,display:t.text,info:t.value})))},more(){return!this.max||this.state.lengththis.options.findIndex((e=>e.value===t.value));return t.sort(((t,s)=>e(t)-e(s)))},visible(){return this.limit?this.filtered.slice(0,this.search.display||this.filtered.length):this.filtered}},watch:{value(t){this.state=t,this.onInvalid()}},mounted(){this.onInvalid(),this.$events.$on("click",this.close),this.$events.$on("keydown.cmd.s",this.close)},destroyed(){this.$events.$off("click",this.close),this.$events.$off("keydown.cmd.s",this.close)},methods:{add(t){!0===this.more&&(this.state.push(t),this.onInput())},blur(){this.close()},close(){!0===this.$refs.dropdown.isOpen&&(this.$refs.dropdown.close(),this.limit=!0)},escape(){this.q?this.q=null:this.close()},focus(){this.$refs.dropdown.open()},index(t){return this.state.findIndex((e=>e.value===t.value))},isFiltered(t){return String(t.text).match(this.regex)||String(t.value).match(this.regex)},isSelected(t){return-1!==this.index(t)},navigate(t){var e,s,n;"prev"===t&&(t="previous"),null==(n=null==(s=null==(e=document.activeElement)?void 0:e[t+"Sibling"])?void 0:s.focus)||n.call(s)},onClose(){!1===this.$refs.dropdown.isOpen&&(document.activeElement===this.$parent.$el&&(this.q=null),this.$parent.$el.focus())},onInput(){this.$emit("input",this.sorted)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},onOpen(){this.$nextTick((()=>{var t,e;null==(e=null==(t=this.$refs.search)?void 0:t.focus)||e.call(t),this.$refs.dropdown.$el.querySelector(".k-multiselect-options").scrollTop=this.scrollTop}))},remove(t){this.state.splice(this.index(t),1),this.onInput()},select(t){this.scrollTop=this.$refs.dropdown.$el.querySelector(".k-multiselect-options").scrollTop,t={text:t.text,value:t.value},this.isSelected(t)?this.remove(t):this.add(t)},toHighlightedString(t){return(t=this.$helper.string.stripHTML(t)).replace(this.regex,"$1")}},validations(){return{state:{required:!this.required||P.required,minLength:!this.min||P.minLength(this.min),maxLength:!this.max||P.maxLength(this.max)}}}},(function(){var t=this,e=t._self._c;return e("k-draggable",{staticClass:"k-multiselect-input",attrs:{list:t.state,options:t.dragOptions,"data-layout":t.layout,element:"k-dropdown"},on:{end:t.onInput},nativeOn:{click:function(e){return t.$refs.dropdown.toggle.apply(null,arguments)}},scopedSlots:t._u([{key:"footer",fn:function(){return[e("k-dropdown-content",{ref:"dropdown",on:{open:t.onOpen,close:t.onClose},nativeOn:{keydown:function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"esc",27,e.key,["Esc","Escape"])?null:(e.stopPropagation(),t.close.apply(null,arguments))}}},[t.search?e("k-dropdown-item",{staticClass:"k-multiselect-search",attrs:{icon:"search"}},[e("input",{directives:[{name:"model",rawName:"v-model",value:t.q,expression:"q"}],ref:"search",attrs:{placeholder:t.search.min?t.$t("search.min",{min:t.search.min}):t.$t("search")+" …"},domProps:{value:t.q},on:{keydown:function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"esc",27,e.key,["Esc","Escape"])?null:(e.stopPropagation(),t.escape.apply(null,arguments))},input:function(e){e.target.composing||(t.q=e.target.value)}}})]):t._e(),e("div",{staticClass:"k-multiselect-options scroll-y-auto"},[t._l(t.visible,(function(s){return e("k-dropdown-item",{key:s.value,class:{"k-multiselect-option":!0,selected:t.isSelected(s),disabled:!t.more},attrs:{icon:t.isSelected(s)?"check":"circle-outline"},on:{click:function(e){return e.preventDefault(),t.select(s)}},nativeOn:{keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:(e.preventDefault(),e.stopPropagation(),t.select(s))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"space",32,e.key,[" ","Spacebar"])?null:(e.preventDefault(),e.stopPropagation(),t.select(s))}]}},[e("span",{domProps:{innerHTML:t._s(s.display)}}),e("span",{staticClass:"k-multiselect-value",domProps:{innerHTML:t._s(s.info)}})])})),0===t.filtered.length?e("k-dropdown-item",{staticClass:"k-multiselect-option",attrs:{disabled:!0}},[t._v(" "+t._s(t.emptyLabel)+" ")]):t._e()],2),t.visible.lengththis.onInput(t.target.value),blur:this.onBlur}}},watch:{value(t){this.number=t},number:{immediate:!0,handler(){this.onInvalid()}}},mounted(){this.$props.autofocus&&this.focus(),this.$props.preselect&&this.select()},methods:{decimals(){const t=Number(this.step||0);return Math.floor(t)===t?0:-1!==t.toString().indexOf("e")?parseInt(t.toFixed(16).split(".")[1].split("").reverse().join("")).toString().length:t.toString().split(".")[1].length||0},format(t){if(isNaN(t)||""===t)return"";const e=this.decimals();return t=e?parseFloat(t).toFixed(e):Number.isInteger(this.step)?parseInt(t):parseFloat(t)},clean(){this.number=this.format(this.number)},emit(t){t=parseFloat(t),isNaN(t)&&(t=""),t!==this.value&&this.$emit("input",t)},focus(){this.$refs.input.focus()},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},onInput(t){this.number=t,this.emit(t)},onBlur(){this.clean(),this.emit(this.number)},select(){this.$refs.input.select()}},validations(){return{value:{required:!this.required||P.required,min:!this.min||P.minValue(this.min),max:!this.max||P.maxValue(this.max)}}}},(function(){var t=this;return(0,t._self._c)("input",t._g(t._b({ref:"input",staticClass:"k-number-input",attrs:{step:t.stepNumber,type:"number"},domProps:{value:t.number},on:{keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"s",void 0,e.key,void 0)?null:e.ctrlKey?t.clean.apply(null,arguments):null},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"s",void 0,e.key,void 0)?null:e.metaKey?t.clean.apply(null,arguments):null}]}},"input",{autofocus:t.autofocus,disabled:t.disabled,id:t.id,max:t.max,min:t.min,name:t.name,placeholder:t.placeholder,required:t.required},!1),t.listeners))}),[],!1,null,null,null,null).exports,bs={mixins:[as],props:{autocomplete:{type:String,default:"new-password"},type:{type:String,default:"password"}}};const ys=It({extends:us,mixins:[bs]},null,null,!1,null,null,null,null).exports,vs={mixins:[Zt,te,se,re],props:{columns:Number,options:Array,value:[String,Number,Boolean]}};const $s=It({mixins:[vs],inheritAttrs:!1,watch:{value(){this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus()},methods:{focus(){this.$el.querySelector("input").focus()},onInput(t){this.$emit("input",t)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},select(){this.focus()}},validations(){return{value:{required:!this.required||P.required}}}},(function(){var t=this,e=t._self._c;return e("ul",{staticClass:"k-radio-input",style:"--columns:"+t.columns},t._l(t.options,(function(s,n){return e("li",{key:n},[e("input",{staticClass:"k-radio-input-native",attrs:{id:t.id+"-"+n,name:t.id,type:"radio"},domProps:{value:s.value,checked:t.value===s.value},on:{change:function(e){return t.onInput(s.value)}}}),s.info?e("label",{attrs:{for:t.id+"-"+n}},[e("span",{staticClass:"k-radio-input-text",domProps:{innerHTML:t._s(s.text)}}),e("span",{staticClass:"k-radio-input-info",domProps:{innerHTML:t._s(s.info)}})]):e("label",{attrs:{for:t.id+"-"+n},domProps:{innerHTML:t._s(s.text)}}),s.icon?e("k-icon",{attrs:{type:s.icon}}):t._e()],1)})),0)}),[],!1,null,null,null,null).exports,_s={mixins:[Zt,te,se,oe,re],props:{default:[Number,String],max:{type:Number,default:100},min:{type:Number,default:0},step:{type:Number,default:1},tooltip:{type:[Boolean,Object],default:()=>({before:null,after:null})},value:[Number,String]}};const xs=It({mixins:[_s],inheritAttrs:!1,data(){return{listeners:{...this.$listeners,input:t=>this.onInput(t.target.value)}}},computed:{baseline(){return this.min<0?0:this.min},label(){return this.required||this.value||0===this.value?this.format(this.position):"–"},position(){return this.value||0===this.value?this.value:this.default||this.baseline}},watch:{position(){this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus()},methods:{focus(){this.$refs.input.focus()},format(t){const e=document.lang?document.lang.replace("_","-"):"en",s=this.step.toString().split("."),n=s.length>1?s[1].length:0;return new Intl.NumberFormat(e,{minimumFractionDigits:n}).format(t)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},onInput(t){this.$emit("input",t)}},validations(){return{position:{required:!this.required||P.required,min:!this.min||P.minValue(this.min),max:!this.max||P.maxValue(this.max)}}}},(function(){var t=this,e=t._self._c;return e("label",{staticClass:"k-range-input"},[e("input",t._g(t._b({ref:"input",staticClass:"k-range-input-native",style:`--min: ${t.min}; --max: ${t.max}; --value: ${t.position}`,attrs:{type:"range"},domProps:{value:t.position}},"input",{autofocus:t.autofocus,disabled:t.disabled,id:t.id,max:t.max,min:t.min,name:t.name,required:t.required,step:t.step},!1),t.listeners)),t.tooltip?e("span",{staticClass:"k-range-input-tooltip"},[t.tooltip.before?e("span",{staticClass:"k-range-input-tooltip-before"},[t._v(t._s(t.tooltip.before))]):t._e(),e("span",{staticClass:"k-range-input-tooltip-text"},[t._v(t._s(t.label))]),t.tooltip.after?e("span",{staticClass:"k-range-input-tooltip-after"},[t._v(t._s(t.tooltip.after))]):t._e()]):t._e()])}),[],!1,null,null,null,null).exports,ws={mixins:[Zt,te,se,oe,re],props:{ariaLabel:String,default:String,empty:{type:[Boolean,String],default:!0},placeholder:String,options:{type:Array,default:()=>[]},value:{type:[String,Number,Boolean],default:""}}};const Ss=It({mixins:[ws],inheritAttrs:!1,data(){return{selected:this.value,listeners:{...this.$listeners,click:t=>this.onClick(t),change:t=>this.onInput(t.target.value),input:()=>{}}}},computed:{emptyOption(){return this.placeholder||"—"},hasEmptyOption(){return!1!==this.empty&&!(this.required&&this.default)},label(){const t=this.text(this.selected);return""===this.selected||null===this.selected||null===t?this.emptyOption:t}},watch:{value(t){this.selected=t,this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus()},methods:{focus(){this.$refs.input.focus()},onClick(t){t.stopPropagation(),this.$emit("click",t)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},onInput(t){this.selected=t,this.$emit("input",this.selected)},select(){this.focus()},text(t){let e=null;return this.options.forEach((s=>{s.value==t&&(e=s.text)})),e}},validations(){return{selected:{required:!this.required||P.required}}}},(function(){var t=this,e=t._self._c;return e("span",{staticClass:"k-select-input",attrs:{"data-disabled":t.disabled,"data-empty":""===t.selected}},[e("select",t._g({ref:"input",staticClass:"k-select-input-native",attrs:{id:t.id,autofocus:t.autofocus,"aria-label":t.ariaLabel,disabled:t.disabled,name:t.name,required:t.required},domProps:{value:t.selected}},t.listeners),[t.hasEmptyOption?e("option",{attrs:{disabled:t.required,value:""}},[t._v(" "+t._s(t.emptyOption)+" ")]):t._e(),t._l(t.options,(function(s){return e("option",{key:s.value,attrs:{disabled:s.disabled},domProps:{value:s.value}},[t._v(" "+t._s(s.text)+" ")])}))],2),t._v(" "+t._s(t.label)+" ")])}),[],!1,null,null,null,null).exports,Cs={mixins:[as],props:{allow:{type:String,default:""},formData:{type:Object,default:()=>({})},sync:{type:String}}};const Os=It({extends:us,mixins:[Cs],data(){return{slug:this.sluggify(this.value),slugs:this.$language?this.$language.rules:this.$system.slugs,syncValue:null}},watch:{formData:{handler(t){return!this.disabled&&(!(!this.sync||void 0===t[this.sync])&&(t[this.sync]!=this.syncValue&&(this.syncValue=t[this.sync],void this.onInput(this.sluggify(this.syncValue)))))},deep:!0,immediate:!0},value(t){(t=this.sluggify(t))!==this.slug&&(this.slug=t,this.$emit("input",this.slug))}},methods:{sluggify(t){return this.$helper.slug(t,[this.slugs,this.$system.ascii],this.allow)},onInput(t){this.slug=this.sluggify(t),this.$emit("input",this.slug)}}},(function(){var t=this;return(0,t._self._c)("input",t._g(t._b({directives:[{name:"direction",rawName:"v-direction"}],ref:"input",staticClass:"k-text-input",attrs:{autocomplete:"off",spellcheck:"false",type:"text"},domProps:{value:t.slug}},"input",{autofocus:t.autofocus,disabled:t.disabled,id:t.id,minlength:t.minlength,name:t.name,pattern:t.pattern,placeholder:t.placeholder,required:t.required},!1),t.listeners))}),[],!1,null,null,null,null).exports,As={mixins:[Zt,te,se,oe,re],props:{accept:{type:String,default:"all"},icon:{type:[String,Boolean],default:"tag"},layout:String,max:Number,min:Number,options:{type:Array,default:()=>[]},separator:{type:String,default:","},value:{type:Array,default:()=>[]}}};const Ts=It({mixins:[As],inheritAttrs:!1,data(){return{tags:this.prepareTags(this.value),selected:null,newTag:null,tagOptions:this.options.map((t=>{var e;return(null==(e=this.icon)?void 0:e.length)>0&&(t.icon=this.icon),t}),this)}},computed:{dragOptions(){return{delay:1,disabled:!this.draggable,draggable:".k-tag"}},draggable(){return this.tags.length>1},skip(){return this.tags.map((t=>t.value))}},watch:{value(t){this.tags=this.prepareTags(t),this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus()},methods:{addString(t){if(t)if((t=t.trim()).includes(this.separator))t.split(this.separator).forEach((t=>{this.addString(t)}));else if(0!==t.length)if("options"===this.accept){const e=this.options.filter((e=>e.text===t))[0];if(!e)return;this.addTag(e)}else this.addTag({text:t,value:t})},addTag(t){this.addTagToIndex(t),this.$refs.autocomplete.close(),this.$refs.input.focus()},addTagToIndex(t){if("options"===this.accept){if(!this.options.filter((e=>e.value===t.value))[0])return}-1===this.index(t)&&(!this.max||this.tags.length=this.tags.length)return;break;case"first":e=0;break;case"last":e=this.tags.length-1;break;default:e=t}let n=this.tags[e];if(n){let t=this.$refs[n.value];if(null==t?void 0:t[0])return{ref:t[0],tag:n,index:e}}return!1},index(t){return this.tags.findIndex((e=>e.value===t.value))},onInput(){this.$emit("input",this.tags)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},leaveInput(t){0===t.target.selectionStart&&t.target.selectionStart===t.target.selectionEnd&&0!==this.tags.length&&(this.$refs.autocomplete.close(),this.navigate("last"),t.preventDefault())},navigate(t){var e=this.get(t);e?(e.ref.focus(),this.selectTag(e.tag)):"next"===t&&(this.$refs.input.focus(),this.selectTag(null))},prepareTags:t=>!1===Array.isArray(t)?[]:t.map((t=>"string"==typeof t?{text:t,value:t}:t)),remove(t){const e=this.get("prev"),s=this.get("next");this.tags.splice(this.index(t),1),this.onInput(),e?(this.selectTag(e.tag),e.ref.focus()):s?this.selectTag(s.tag):(this.selectTag(null),this.$refs.input.focus())},select(){this.focus()},selectTag(t){this.selected=t},tab(t){var e;(null==(e=this.newTag)?void 0:e.length)>0&&(t.preventDefault(),this.addString(this.newTag))},type(t){this.newTag=t,this.$refs.autocomplete.search(t)}},validations(){return{tags:{required:!this.required||P.required,minLength:!this.min||P.minLength(this.min),maxLength:!this.max||P.maxLength(this.max)}}}},(function(){var t=this,e=t._self._c;return e("k-draggable",{directives:[{name:"direction",rawName:"v-direction"}],ref:"box",staticClass:"k-tags-input",attrs:{list:t.tags,"data-layout":t.layout,options:t.dragOptions},on:{end:t.onInput},scopedSlots:t._u([{key:"footer",fn:function(){return[e("span",{staticClass:"k-tags-input-element"},[e("k-autocomplete",{ref:"autocomplete",attrs:{html:!0,options:t.options,skip:t.skip},on:{select:t.addTag,leave:function(e){return t.$refs.input.focus()}}},[e("input",{directives:[{name:"model",rawName:"v-model.trim",value:t.newTag,expression:"newTag",modifiers:{trim:!0}}],ref:"input",attrs:{id:t.id,autofocus:t.autofocus,disabled:t.disabled||t.max&&t.tags.length>=t.max,name:t.name,autocomplete:"off",type:"text"},domProps:{value:t.newTag},on:{input:[function(e){e.target.composing||(t.newTag=e.target.value.trim())},function(e){return t.type(e.target.value)}],blur:[t.blurInput,function(e){return t.$forceUpdate()}],keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"s",void 0,e.key,void 0)?null:e.metaKey?t.blurInput.apply(null,arguments):null},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"left",37,e.key,["Left","ArrowLeft"])||"button"in e&&0!==e.button||e.ctrlKey||e.shiftKey||e.altKey||e.metaKey?null:t.leaveInput.apply(null,arguments)},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")||e.ctrlKey||e.shiftKey||e.altKey||e.metaKey?null:t.enter.apply(null,arguments)},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"tab",9,e.key,"Tab")||e.ctrlKey||e.shiftKey||e.altKey||e.metaKey?null:t.tab.apply(null,arguments)},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"backspace",void 0,e.key,void 0)||e.ctrlKey||e.shiftKey||e.altKey||e.metaKey?null:t.leaveInput.apply(null,arguments)}]}})])],1)]},proxy:!0}])},t._l(t.tags,(function(s,n){return e("k-tag",{key:n,ref:s.value,refInFor:!0,attrs:{removable:!t.disabled,name:"tag"},on:{remove:function(e){return t.remove(s)}},nativeOn:{click:function(t){t.stopPropagation()},blur:function(e){return t.selectTag(null)},focus:function(e){return t.selectTag(s)},keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"left",37,e.key,["Left","ArrowLeft"])||"button"in e&&0!==e.button?null:t.navigate("prev")},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"right",39,e.key,["Right","ArrowRight"])||"button"in e&&2!==e.button?null:t.navigate("next")}],dblclick:function(e){return t.edit(s)}}},[t._v(" "+t._s(s.text)+" ")])})),1)}),[],!1,null,null,null,null).exports,Is={mixins:[as],props:{autocomplete:{type:String,default:"tel"},type:{type:String,default:"tel"}}};const Ms=It({extends:us,mixins:[Is]},null,null,!1,null,null,null,null).exports,Es={mixins:[Zt,te,se,oe,re],props:{buttons:{type:[Boolean,Array],default:!0},endpoints:Object,font:String,maxlength:Number,minlength:Number,placeholder:String,preselect:Boolean,size:String,spellcheck:{type:[Boolean,String],default:"off"},theme:String,uploads:[Boolean,Object,Array],value:String}};const Ls=It({mixins:[Es],inheritAttrs:!1,data:()=>({over:!1}),watch:{value(){this.onInvalid(),this.$nextTick((()=>{this.resize()}))}},mounted(){this.$nextTick((()=>{this.$library.autosize(this.$refs.input)})),this.onInvalid(),this.$props.autofocus&&this.focus(),this.$props.preselect&&this.select()},methods:{cancel(){this.$refs.input.focus()},dialog(t){if(!this.$refs[t+"Dialog"])throw"Invalid toolbar dialog";this.$refs[t+"Dialog"].open(this.$refs.input,this.selection())},focus(){this.$refs.input.focus()},insert(t){const e=this.$refs.input,s=e.value;setTimeout((()=>{if(e.focus(),document.execCommand("insertText",!1,t),e.value===s){const s=e.value.slice(0,e.selectionStart)+t+e.value.slice(e.selectionEnd);e.value=s,this.$emit("input",s)}})),this.resize()},insertFile(t){(null==t?void 0:t.length)>0&&this.insert(t.map((t=>t.dragText)).join("\n\n"))},insertUpload(t,e){this.insert(e.map((t=>t.dragText)).join("\n\n")),this.$events.$emit("model.update")},onClick(){this.$refs.toolbar&&this.$refs.toolbar.close()},onCommand(t,e){"function"==typeof this[t]?"function"==typeof e?this[t](e(this.$refs.input,this.selection())):this[t](e):window.console.warn(t+" is not a valid command")},onDrop(t){if(this.uploads&&this.$helper.isUploadEvent(t))return this.$refs.fileUpload.drop(t.dataTransfer.files,{url:this.$urls.api+"/"+this.endpoints.field+"/upload",multiple:!1});const e=this.$store.state.drag;"text"===(null==e?void 0:e.type)&&(this.focus(),this.insert(e.data))},onFocus(t){this.$emit("focus",t)},onInput(t){this.$emit("input",t.target.value)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},onOut(){this.$refs.input.blur(),this.over=!1},onOver(t){if(this.uploads&&this.$helper.isUploadEvent(t))return t.dataTransfer.dropEffect="copy",this.focus(),void(this.over=!0);const e=this.$store.state.drag;"text"===(null==e?void 0:e.type)&&(t.dataTransfer.dropEffect="copy",this.focus(),this.over=!0)},onShortcut(t){!1!==this.buttons&&"Meta"!==t.key&&"Control"!==t.key&&this.$refs.toolbar&&this.$refs.toolbar.shortcut(t.key,t)},onSubmit(t){return this.$emit("submit",t)},prepend(t){this.insert(t+" "+this.selection())},resize(){this.$library.autosize.update(this.$refs.input)},select(){this.$refs.select()},selectFile(){this.$refs.fileDialog.open({endpoint:this.endpoints.field+"/files",multiple:!1})},selection(){const t=this.$refs.input,e=t.selectionStart,s=t.selectionEnd;return t.value.substring(e,s)},uploadFile(){this.$refs.fileUpload.open({url:this.$urls.api+"/"+this.endpoints.field+"/upload",multiple:!1})},wrap(t){this.insert(t+this.selection()+t)}},validations(){return{value:{required:!this.required||P.required,minLength:!this.minlength||P.minLength(this.minlength),maxLength:!this.maxlength||P.maxLength(this.maxlength)}}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-textarea-input",attrs:{"data-over":t.over,"data-size":t.size,"data-theme":t.theme}},[e("div",{staticClass:"k-textarea-input-wrapper"},[t.buttons&&!t.disabled?e("k-toolbar",{ref:"toolbar",attrs:{buttons:t.buttons,disabled:t.disabled,uploads:t.uploads},on:{command:t.onCommand},nativeOn:{mousedown:function(t){t.preventDefault()}}}):t._e(),e("textarea",t._b({directives:[{name:"direction",rawName:"v-direction"}],ref:"input",staticClass:"k-textarea-input-native",attrs:{"data-font":t.font},on:{click:t.onClick,focus:t.onFocus,input:t.onInput,keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:e.metaKey?t.onSubmit.apply(null,arguments):null},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:e.ctrlKey?t.onSubmit.apply(null,arguments):null},function(e){return e.metaKey?t.onShortcut.apply(null,arguments):null},function(e){return e.ctrlKey?t.onShortcut.apply(null,arguments):null}],dragover:t.onOver,dragleave:t.onOut,drop:t.onDrop}},"textarea",{autofocus:t.autofocus,disabled:t.disabled,id:t.id,minlength:t.minlength,name:t.name,placeholder:t.placeholder,required:t.required,spellcheck:t.spellcheck,value:t.value},!1))],1),e("k-toolbar-email-dialog",{ref:"emailDialog",on:{cancel:t.cancel,submit:function(e){return t.insert(e)}}}),e("k-toolbar-link-dialog",{ref:"linkDialog",on:{cancel:t.cancel,submit:function(e){return t.insert(e)}}}),e("k-files-dialog",{ref:"fileDialog",on:{cancel:t.cancel,submit:function(e){return t.insertFile(e)}}}),t.uploads?e("k-upload",{ref:"fileUpload",on:{success:t.insertUpload}}):t._e()],1)}),[],!1,null,null,null,null).exports,js={props:{display:{type:String,default:"HH:mm"},max:String,min:String,step:{type:Object,default:()=>({size:5,unit:"minute"})},type:{type:String,default:"time"},value:String}};const Ds=It({mixins:[ls,js],computed:{inputType:()=>"time"}},null,null,!1,null,null,null,null).exports,Bs={props:{autofocus:Boolean,disabled:Boolean,id:[Number,String],text:{type:[Array,String]},required:Boolean,value:Boolean}};const Ps=It({mixins:[Bs],inheritAttrs:!1,computed:{label(){const t=this.text||[this.$t("off"),this.$t("on")];return Array.isArray(t)?this.value?t[1]:t[0]:t}},watch:{value(){this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus()},methods:{focus(){this.$refs.input.focus()},onEnter(t){"Enter"===t.key&&this.$refs.input.click()},onInput(t){this.$emit("input",t)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},select(){this.$refs.input.focus()}},validations(){return{value:{required:!this.required||P.required}}}},(function(){var t=this,e=t._self._c;return e("label",{staticClass:"k-toggle-input",attrs:{"data-disabled":t.disabled}},[e("input",{ref:"input",staticClass:"k-toggle-input-native",attrs:{id:t.id,disabled:t.disabled,type:"checkbox"},domProps:{checked:t.value},on:{change:function(e){return t.onInput(e.target.checked)}}}),e("span",{staticClass:"k-toggle-input-label",domProps:{innerHTML:t._s(t.label)}})])}),[],!1,null,null,null,null).exports,Ns={mixins:[Zt,te,se,re],props:{columns:Number,grow:Boolean,labels:Boolean,options:Array,reset:Boolean,value:[String,Number,Boolean]}};const qs=It({mixins:[Ns],inheritAttrs:!1,watch:{value(){this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus()},methods:{focus(){(this.$el.querySelector("input[checked]")||this.$el.querySelector("input")).focus()},onClick(t){t===this.value&&this.reset&&!this.required&&this.$emit("input","")},onInput(t){this.$emit("input",t)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},select(){this.focus()}},validations(){return{value:{required:!this.required||P.required}}}},(function(){var t=this,e=t._self._c;return e("ul",{staticClass:"k-toggles-input",style:"--options:"+(t.columns||t.options.length),attrs:{"data-invalid":t.$v.$invalid,"data-labels":t.labels}},t._l(t.options,(function(s,n){return e("li",{key:n},[e("input",{staticClass:"input-hidden",attrs:{id:t.id+"-"+n,name:t.id,type:"radio"},domProps:{value:s.value,checked:t.value===s.value},on:{click:function(e){return t.onClick(s.value)},change:function(e){return t.onInput(s.value)}}}),e("label",{attrs:{for:t.id+"-"+n,title:s.text}},[s.icon?e("k-icon",{attrs:{type:s.icon}}):t._e(),t.labels?e("span",{staticClass:"k-toggles-text"},[t._v(" "+t._s(s.text)+" ")]):t._e()],1)])})),0)}),[],!1,null,null,null,null).exports,Fs={mixins:[as],props:{autocomplete:{type:String,default:"url"},type:{type:String,default:"url"}}};const Rs=It({extends:us,mixins:[Fs]},null,null,!1,null,null,null,null).exports;t.component("k-checkbox-input",ns),t.component("k-checkboxes-input",os),t.component("k-date-input",ls),t.component("k-email-input",ds),t.component("k-list-input",hs),t.component("k-multiselect-input",fs),t.component("k-number-input",ks),t.component("k-password-input",ys),t.component("k-radio-input",$s),t.component("k-range-input",xs),t.component("k-select-input",Ss),t.component("k-slug-input",Os),t.component("k-tags-input",Ts),t.component("k-tel-input",Ms),t.component("k-text-input",us),t.component("k-textarea-input",Ls),t.component("k-time-input",Ds),t.component("k-toggle-input",Ps),t.component("k-toggles-input",qs),t.component("k-url-input",Rs);const zs=It({mixins:[le],inheritAttrs:!1,props:{autofocus:Boolean,empty:String,fieldsets:Object,fieldsetGroups:Object,group:String,max:{type:Number,default:null},value:{type:Array,default:()=>[]}},data:()=>({opened:[]}),computed:{hasFieldsets(){return Object.keys(this.fieldsets).length},isEmpty(){return 0===this.value.length},isFull(){return null!==this.max&&this.value.length>=this.max}},methods:{focus(){this.$refs.blocks.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-blocks-field",scopedSlots:t._u([{key:"options",fn:function(){return[t.hasFieldsets?e("k-dropdown",[e("k-button",{attrs:{icon:"dots"},on:{click:function(e){return t.$refs.options.toggle()}}}),e("k-dropdown-content",{ref:"options",attrs:{align:"right"}},[e("k-dropdown-item",{attrs:{disabled:t.isFull,icon:"add"},on:{click:function(e){return t.$refs.blocks.choose(t.value.length)}}},[t._v(" "+t._s(t.$t("add"))+" ")]),e("hr"),e("k-dropdown-item",{attrs:{disabled:t.isEmpty,icon:"template"},on:{click:function(e){return t.$refs.blocks.copyAll()}}},[t._v(" "+t._s(t.$t("copy.all"))+" ")]),e("k-dropdown-item",{attrs:{disabled:t.isFull,icon:"download"},on:{click:function(e){return t.$refs.blocks.pasteboard()}}},[t._v(" "+t._s(t.$t("paste"))+" ")]),e("hr"),e("k-dropdown-item",{attrs:{disabled:t.isEmpty,icon:"trash"},on:{click:function(e){return t.$refs.blocks.confirmToRemoveAll()}}},[t._v(" "+t._s(t.$t("delete.all"))+" ")])],1)],1):t._e()]},proxy:!0}])},"k-field",t.$props,!1),[e("k-blocks",t._g({ref:"blocks",attrs:{autofocus:t.autofocus,compact:!1,empty:t.empty,endpoints:t.endpoints,fieldsets:t.fieldsets,"fieldset-groups":t.fieldsetGroups,group:t.group,max:t.max,value:t.value},on:{close:function(e){t.opened=e},open:function(e){t.opened=e}}},t.$listeners))],1)}),[],!1,null,null,null,null).exports,Ys={props:{counter:{type:Boolean,default:!0}},computed:{counterOptions(){var t,e;if(null===this.value||this.disabled||!1===this.counter)return!1;let s=0;return this.value&&(s=Array.isArray(this.value)?this.value.length:String(this.value).length),{count:s,min:null!=(t=this.min)?t:this.minlength,max:null!=(e=this.max)?e:this.maxlength}}}};const Hs=It({mixins:[le,ce,is,Ys],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-checkboxes-field",attrs:{counter:t.counterOptions}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"checkboxes"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const Us=It({mixins:[le,ce,rs],inheritAttrs:!1,props:{calendar:{type:Boolean,default:!0},icon:{type:String,default:"calendar"},time:{type:[Boolean,Object],default:()=>({})},times:{type:Boolean,default:!0}},data(){return{isInvalid:!1,iso:this.toIso(this.value)}},computed:{isEmpty(){return this.time?null===this.iso.date&&this.iso.time:null===this.iso.date}},watch:{value(t,e){t!==e&&(this.iso=this.toIso(t))}},methods:{focus(){this.$refs.dateInput.focus()},now(){const t=this.$library.dayjs();return{date:t.toISO("date"),time:this.time?t.toISO("time"):"00:00:00"}},onInput(){if(this.isEmpty)return this.$emit("input","");const t=this.$library.dayjs.iso(this.iso.date+" "+this.iso.time);(t||null!==this.iso.date&&null!==this.iso.time)&&this.$emit("input",(null==t?void 0:t.toISO())||"")},onCalendarInput(t){var e;null==(e=this.$refs.calendar)||e.close(),this.onDateInput(t)},onDateInput(t){t&&!this.iso.time&&(this.iso.time=this.now().time),this.iso.date=t,this.onInput()},onDateInvalid(t){this.isInvalid=t},onTimeInput(t){t&&!this.iso.date&&(this.iso.date=this.now().date),this.iso.time=t,this.onInput()},onTimesInput(t){var e;null==(e=this.$refs.times)||e.close(),this.onTimeInput(t+":00")},toIso(t){const e=this.$library.dayjs.iso(t);return{date:(null==e?void 0:e.toISO("date"))||null,time:(null==e?void 0:e.toISO("time"))||null}}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-date-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("div",{ref:"body",staticClass:"k-date-field-body",attrs:{"data-invalid":!t.novalidate&&t.isInvalid,"data-theme":"field"}},[e("k-input",t._b({ref:"dateInput",attrs:{id:t._uid,autofocus:t.autofocus,disabled:t.disabled,display:t.display,max:t.max,min:t.min,required:t.required,value:t.value,theme:"field",type:"date"},on:{invalid:t.onDateInvalid,input:t.onDateInput,submit:function(e){return t.$emit("submit")}},scopedSlots:t._u([t.calendar?{key:"icon",fn:function(){return[e("k-dropdown",[e("k-button",{staticClass:"k-input-icon-button",attrs:{icon:t.icon,tooltip:t.$t("date.select")},on:{click:function(e){return t.$refs.calendar.toggle()}}}),e("k-dropdown-content",{ref:"calendar",attrs:{align:"right"}},[e("k-calendar",{attrs:{value:t.value,min:t.min,max:t.max},on:{input:t.onCalendarInput}})],1)],1)]},proxy:!0}:null],null,!0)},"k-input",t.$props,!1)),t.time?e("k-input",{ref:"timeInput",attrs:{disabled:t.disabled,display:t.time.display,required:t.required,step:t.time.step,value:t.iso.time,icon:t.time.icon,theme:"field",type:"time"},on:{input:t.onTimeInput,submit:function(e){return t.$emit("submit")}},scopedSlots:t._u([t.times?{key:"icon",fn:function(){return[e("k-dropdown",[e("k-button",{staticClass:"k-input-icon-button",attrs:{icon:t.time.icon||"clock",tooltip:t.$t("time.select")},on:{click:function(e){return t.$refs.times.toggle()}}}),e("k-dropdown-content",{ref:"times",attrs:{align:"right"}},[e("k-times",{attrs:{display:t.time.display,value:t.value},on:{input:t.onTimesInput}})],1)],1)]},proxy:!0}:null],null,!0)}):t._e()],1)])}),[],!1,null,null,null,null).exports;const Ks=It({mixins:[le,ce,cs],inheritAttrs:!1,props:{link:{type:Boolean,default:!0},icon:{type:String,default:"email"}},computed:{mailto(){var t;return(null==(t=this.value)?void 0:t.length)>0?"mailto:"+this.value:null}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-email-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"email"},scopedSlots:t._u([{key:"icon",fn:function(){return[t.link?e("k-button",{staticClass:"k-input-icon-button",attrs:{icon:t.icon,link:t.mailto,tooltip:t.$t("open"),tabindex:"-1",target:"_blank"}}):t._e()]},proxy:!0}])},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports,Gs={mixins:[le],inheritAttrs:!1,props:{empty:String,info:String,link:Boolean,layout:{type:String,default:"list"},max:Number,multiple:Boolean,parent:String,search:Boolean,size:String,text:String,value:{type:Array,default:()=>[]}},data(){return{selected:this.value}},computed:{btnIcon(){return!this.multiple&&this.selected.length>0?"refresh":"add"},btnLabel(){return!this.multiple&&this.selected.length>0?this.$t("change"):this.$t("add")},collection(){return{empty:this.emptyProps,items:this.selected,layout:this.layout,link:this.link,size:this.size,sortable:!this.disabled&&this.selected.length>1}},isInvalid(){return!(!this.required||0!==this.selected.length)||(!!(this.min&&this.selected.lengththis.max))},items(){return this.models.map(this.item)},more(){return!this.max||this.max>this.selected.length}},watch:{value(t){this.selected=t}},methods:{focus(){},item:t=>t,onInput(){this.$emit("input",this.selected)},open(){if(this.disabled)return!1;this.$refs.selector.open({endpoint:this.endpoints.field,max:this.max,multiple:this.multiple,search:this.search,selected:this.selected.map((t=>t.id))})},remove(t){this.selected.splice(t,1),this.onInput()},removeById(t){this.selected=this.selected.filter((e=>e.id!==t)),this.onInput()},select(t){0!==t.length?(this.selected=this.selected.filter((e=>t.filter((t=>t.id===e.id)).length>0)),t.forEach((t=>{0===this.selected.filter((e=>t.id===e.id)).length&&this.selected.push(t)})),this.onInput()):this.selected=[]}}};const Js=It({mixins:[Gs],props:{uploads:[Boolean,Object,Array]},computed:{emptyProps(){return{icon:"image",text:this.empty||this.$t("field.files.empty")}},moreUpload(){return!this.disabled&&this.more&&this.uploads},options(){return this.uploads?{icon:this.btnIcon,text:this.btnLabel,options:[{icon:"check",text:this.$t("select"),click:"open"},{icon:"upload",text:this.$t("upload"),click:"upload"}]}:{options:[{icon:"check",text:this.$t("select"),click:()=>this.open()}]}},uploadParams(){return{accept:this.uploads.accept,max:this.max,multiple:this.multiple,url:this.$urls.api+"/"+this.endpoints.field+"/upload"}}},created(){this.$events.$on("file.delete",this.removeById)},destroyed(){this.$events.$off("file.delete",this.removeById)},methods:{drop(t){return!1!==this.uploads&&this.$refs.fileUpload.drop(t,this.uploadParams)},prompt(){if(this.disabled)return!1;this.moreUpload?this.$refs.options.toggle():this.open()},onAction(t){if(this.moreUpload)switch(t){case"open":return this.open();case"upload":return this.$refs.fileUpload.open(this.uploadParams)}},isSelected(t){return this.selected.find((e=>e.id===t.id))},upload(t,e){!1===this.multiple&&(this.selected=[]),e.forEach((t=>{this.isSelected(t)||this.selected.push(t)})),this.onInput(),this.$events.$emit("model.update")}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-files-field",scopedSlots:t._u([t.more&&!t.disabled?{key:"options",fn:function(){return[e("k-button-group",{staticClass:"k-field-options"},[e("k-options-dropdown",t._b({ref:"options",on:{action:t.onAction}},"k-options-dropdown",t.options,!1))],1)]},proxy:!0}:null],null,!0)},"k-field",t.$props,!1),[e("k-dropzone",{attrs:{disabled:!t.moreUpload},on:{drop:t.drop}},[e("k-collection",t._b({on:{empty:t.prompt,sort:t.onInput,sortChange:function(e){return t.$emit("change",e)}},scopedSlots:t._u([{key:"options",fn:function({index:s}){return[t.disabled?t._e():e("k-button",{attrs:{tooltip:t.$t("remove"),icon:"remove"},on:{click:function(e){return t.remove(s)}}})]}}])},"k-collection",t.collection,!1))],1),e("k-files-dialog",{ref:"selector",on:{submit:t.select}}),e("k-upload",{ref:"fileUpload",on:{success:t.upload}})],1)}),[],!1,null,null,null,null).exports;const Vs=It({},(function(){return(0,this._self._c)("div",{staticClass:"k-field k-gap-field"})}),[],!1,null,null,null,null).exports;const Ws=It({mixins:[ee,ie],props:{numbered:Boolean}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-headline-field"},[e("k-headline",{attrs:{"data-numbered":t.numbered,size:"large"}},[t._v(" "+t._s(t.label)+" ")]),t.help?e("footer",{staticClass:"k-field-footer"},[t.help?e("k-text",{staticClass:"k-field-help",attrs:{theme:"help",html:t.help}}):t._e()],1):t._e()],1)}),[],!1,null,null,null,null).exports;const Xs=It({mixins:[ee,ie],props:{text:String,theme:{type:String,default:"info"}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-field k-info-field"},[e("k-headline",[t._v(t._s(t.label))]),e("k-box",{attrs:{theme:t.theme}},[e("k-text",{attrs:{html:t.text}})],1),t.help?e("footer",{staticClass:"k-field-footer"},[t.help?e("k-text",{staticClass:"k-field-help",attrs:{theme:"help",html:t.help}}):t._e()],1):t._e()],1)}),[],!1,null,null,null,null).exports;const Zs=It({components:{"k-block-layouts":It({components:{"k-layout":It({components:{"k-layout-column":It({props:{blocks:Array,endpoints:Object,fieldsetGroups:Object,fieldsets:Object,id:String,isSelected:Boolean,width:String}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-column k-layout-column",attrs:{id:t.id,"data-width":t.width,tabindex:"0"},on:{dblclick:function(e){return t.$refs.blocks.choose(t.blocks.length)}}},[e("k-blocks",{ref:"blocks",attrs:{endpoints:t.endpoints,"fieldset-groups":t.fieldsetGroups,fieldsets:t.fieldsets,value:t.blocks,group:"layout"},on:{input:function(e){return t.$emit("input",e)}},nativeOn:{dblclick:function(t){t.stopPropagation()}}})],1)}),[],!1,null,null,null,null).exports},props:{attrs:[Array,Object],columns:Array,disabled:Boolean,endpoints:Object,fieldsetGroups:Object,fieldsets:Object,id:String,isSelected:Boolean,settings:Object},computed:{tabs(){let t=this.settings.tabs;return Object.entries(t).forEach((([e,s])=>{Object.entries(s.fields).forEach((([s])=>{t[e].fields[s].endpoints={field:this.endpoints.field+"/fields/"+s,section:this.endpoints.section,model:this.endpoints.model}}))})),t}}},(function(){var t=this,e=t._self._c;return e("section",{staticClass:"k-layout",attrs:{"data-selected":t.isSelected,tabindex:"0"},on:{click:function(e){return t.$emit("select")}}},[e("k-grid",{staticClass:"k-layout-columns"},t._l(t.columns,(function(s,n){return e("k-layout-column",t._b({key:s.id,attrs:{endpoints:t.endpoints,"fieldset-groups":t.fieldsetGroups,fieldsets:t.fieldsets},on:{input:function(e){return t.$emit("updateColumn",{column:s,columnIndex:n,blocks:e})}}},"k-layout-column",s,!1))})),1),t.disabled?t._e():e("nav",{staticClass:"k-layout-toolbar"},[t.settings?e("k-button",{staticClass:"k-layout-toolbar-button",attrs:{tooltip:t.$t("settings"),icon:"settings"},on:{click:function(e){return t.$refs.drawer.open()}}}):t._e(),e("k-dropdown",[e("k-button",{staticClass:"k-layout-toolbar-button",attrs:{icon:"angle-down"},on:{click:function(e){return t.$refs.options.toggle()}}}),e("k-dropdown-content",{ref:"options",attrs:{align:"right"}},[e("k-dropdown-item",{attrs:{icon:"angle-up"},on:{click:function(e){return t.$emit("prepend")}}},[t._v(" "+t._s(t.$t("insert.before"))+" ")]),e("k-dropdown-item",{attrs:{icon:"angle-down"},on:{click:function(e){return t.$emit("append")}}},[t._v(" "+t._s(t.$t("insert.after"))+" ")]),e("hr"),t.settings?e("k-dropdown-item",{attrs:{icon:"settings"},on:{click:function(e){return t.$refs.drawer.open()}}},[t._v(" "+t._s(t.$t("settings"))+" ")]):t._e(),e("k-dropdown-item",{attrs:{icon:"copy"},on:{click:function(e){return t.$emit("duplicate")}}},[t._v(" "+t._s(t.$t("duplicate"))+" ")]),e("hr"),e("k-dropdown-item",{attrs:{icon:"trash"},on:{click:function(e){return t.$refs.confirmRemoveDialog.open()}}},[t._v(" "+t._s(t.$t("field.layout.delete"))+" ")])],1)],1),e("k-sort-handle")],1),t.settings?e("k-form-drawer",{ref:"drawer",staticClass:"k-layout-drawer",attrs:{tabs:t.tabs,title:t.$t("settings"),value:t.attrs,icon:"settings"},on:{input:function(e){return t.$emit("updateAttrs",e)}}}):t._e(),e("k-remove-dialog",{ref:"confirmRemoveDialog",attrs:{text:t.$t("field.layout.delete.confirm")},on:{submit:function(e){return t.$emit("remove")}}})],1)}),[],!1,null,null,null,null).exports},props:{disabled:Boolean,empty:String,endpoints:Object,fieldsetGroups:Object,fieldsets:Object,layouts:Array,max:Number,settings:Object,value:Array},data(){return{currentLayout:null,nextIndex:null,rows:this.value,selected:null}},computed:{draggableOptions(){return{id:this._uid,handle:!0,list:this.rows}}},watch:{value(){this.rows=this.value}},methods:{async addLayout(t){let e=await this.$api.post(this.endpoints.field+"/layout",{columns:t});this.rows.splice(this.nextIndex,0,e),this.layouts.length>1&&this.$refs.selector.close(),this.save()},duplicateLayout(t,e){let s={...this.$helper.clone(e),id:this.$helper.uuid()};s.columns=s.columns.map((t=>(t.id=this.$helper.uuid(),t.blocks=t.blocks.map((t=>(t.id=this.$helper.uuid(),t))),t))),this.rows.splice(t+1,0,s),this.save()},removeLayout(t){const e=this.rows.findIndex((e=>e.id===t.id));-1!==e&&this.$delete(this.rows,e),this.save()},save(){this.$emit("input",this.rows)},selectLayout(t){this.nextIndex=t,1!==this.layouts.length?this.$refs.selector.open():this.addLayout(this.layouts[0])},updateColumn(t){this.rows[t.layoutIndex].columns[t.columnIndex].blocks=t.blocks,this.save()},updateAttrs(t,e){this.rows[t].attrs=e,this.save()}}},(function(){var t=this,e=t._self._c;return e("div",[t.rows.length?[e("k-draggable",t._b({staticClass:"k-layouts",on:{sort:t.save}},"k-draggable",t.draggableOptions,!1),t._l(t.rows,(function(s,n){return e("k-layout",t._b({key:s.id,attrs:{disabled:t.disabled,endpoints:t.endpoints,"fieldset-groups":t.fieldsetGroups,fieldsets:t.fieldsets,"is-selected":t.selected===s.id,settings:t.settings},on:{append:function(e){return t.selectLayout(n+1)},duplicate:function(e){return t.duplicateLayout(n,s)},prepend:function(e){return t.selectLayout(n)},remove:function(e){return t.removeLayout(s)},select:function(e){t.selected=s.id},updateAttrs:function(e){return t.updateAttrs(n,e)},updateColumn:function(e){return t.updateColumn({layout:s,layoutIndex:n,...e})}}},"k-layout",s,!1))})),1),t.disabled?t._e():e("k-button",{staticClass:"k-layout-add-button",attrs:{icon:"add"},on:{click:function(e){return t.selectLayout(t.rows.length)}}})]:[e("k-empty",{staticClass:"k-layout-empty",attrs:{icon:"dashboard"},on:{click:function(e){return t.selectLayout(0)}}},[t._v(" "+t._s(t.empty||t.$t("field.layout.empty"))+" ")])],e("k-dialog",{ref:"selector",staticClass:"k-layout-selector",attrs:{"cancel-button":!1,"submit-button":!1,size:"medium"}},[e("k-headline",[t._v(t._s(t.$t("field.layout.select")))]),e("ul",t._l(t.layouts,(function(s,n){return e("li",{key:n,staticClass:"k-layout-selector-option"},[e("k-grid",{nativeOn:{click:function(e){return t.addLayout(s)}}},t._l(s,(function(t,s){return e("k-column",{key:s,attrs:{width:t}})})),1)],1)})),0)],1)],2)}),[],!1,null,null,null,null).exports},mixins:[le],inheritAttrs:!1,props:{empty:String,fieldsetGroups:Object,fieldsets:Object,layouts:{type:Array,default:()=>[["1/1"]]},settings:Object,value:{type:Array,default:()=>[]}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-layout-field"},"k-field",t.$props,!1),[e("k-block-layouts",t._b({on:{input:function(e){return t.$emit("input",e)}}},"k-block-layouts",t.$props,!1))],1)}),[],!1,null,null,null,null).exports;const Qs=It({},(function(){return(0,this._self._c)("hr",{staticClass:"k-line-field"})}),[],!1,null,null,null,null).exports;const tn=It({mixins:[le,ce],inheritAttrs:!1,props:{marks:[Array,Boolean],value:String},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-list-field",attrs:{input:t._uid,counter:!1}},"k-field",t.$props,!1),[e("k-input",t._b({ref:"input",attrs:{id:t._uid,marks:t.marks,value:t.value,type:"list",theme:"field"},on:{input:function(e){return t.$emit("input",e)}}},"k-input",t.$props,!1))],1)}),[],!1,null,null,null,null).exports;const en=It({mixins:[le,ce,ms,Ys],inheritAttrs:!1,props:{icon:{type:String,default:"angle-down"}},mounted(){this.$refs.input.$el.setAttribute("tabindex",0)},methods:{blur(t){this.$refs.input.blur(t)},focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-multiselect-field",attrs:{input:t._uid,counter:t.counterOptions},on:{blur:t.blur},nativeOn:{keydown:function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:(e.preventDefault(),t.focus.apply(null,arguments))}}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"multiselect"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const sn=It({mixins:[le,ce,gs],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-number-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"number"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const nn=It({mixins:[Gs],computed:{emptyProps(){return{icon:"page",text:this.empty||this.$t("field.pages.empty")}}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-pages-field",scopedSlots:t._u([{key:"options",fn:function(){return[e("k-button-group",{staticClass:"k-field-options"},[t.more&&!t.disabled?e("k-button",{staticClass:"k-field-options-button",attrs:{icon:t.btnIcon,text:t.btnLabel},on:{click:t.open}}):t._e()],1)]},proxy:!0}])},"k-field",t.$props,!1),[e("k-collection",t._b({on:{empty:t.open,sort:t.onInput,sortChange:function(e){return t.$emit("change",e)}},scopedSlots:t._u([{key:"options",fn:function({index:s}){return[t.disabled?t._e():e("k-button",{attrs:{tooltip:t.$t("remove"),icon:"remove"},on:{click:function(e){return t.remove(s)}}})]}}])},"k-collection",t.collection,!1)),e("k-pages-dialog",{ref:"selector",on:{submit:t.select}})],1)}),[],!1,null,null,null,null).exports;const on=It({mixins:[le,ce,bs,Ys],inheritAttrs:!1,props:{minlength:{type:Number,default:8},icon:{type:String,default:"key"}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-password-field",attrs:{input:t._uid,counter:t.counterOptions},scopedSlots:t._u([{key:"options",fn:function(){return[t._t("options")]},proxy:!0}],null,!0)},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"password"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const rn=It({mixins:[le,ce,vs],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-radio-field"},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"radio"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const ln=It({mixins:[ce,le,_s],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-range-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"range"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const an=It({mixins:[le,ce,ws],inheritAttrs:!1,props:{icon:{type:String,default:"angle-down"}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-select-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"select"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const un=It({mixins:[le,ce,Cs],inheritAttrs:!1,props:{icon:{type:String,default:"url"},path:{type:String},wizard:{type:[Boolean,Object],default:!1}},data(){return{slug:this.value}},computed:{preview(){return void 0!==this.help?this.help:void 0!==this.path?this.path+this.value:null}},watch:{value(){this.slug=this.value}},methods:{focus(){this.$refs.input.focus()},onWizard(){var t;this.formData[null==(t=this.wizard)?void 0:t.field]&&(this.slug=this.formData[this.wizard.field])}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-slug-field",attrs:{input:t._uid,help:t.preview},scopedSlots:t._u([t.wizard&&t.wizard.text?{key:"options",fn:function(){return[e("k-button",{attrs:{text:t.wizard.text,icon:"wand"},on:{click:t.onWizard}})]},proxy:!0}:null],null,!0)},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,value:t.slug,theme:"field",type:"slug"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const cn=It({mixins:[le],inheritAttrs:!1,props:{columns:Object,duplicate:{type:Boolean,default:!0},empty:String,fields:Object,limit:Number,max:Number,min:Number,prepend:{type:Boolean,default:!1},sortable:{type:Boolean,default:!0},sortBy:String,value:{type:Array,default:()=>[]}},data(){return{autofocus:null,items:this.toItems(this.value),currentIndex:null,currentModel:null,trash:null,page:1}},computed:{dragOptions(){return{disabled:!this.isSortable,fallbackClass:"k-sortable-row-fallback"}},form(){let t={};return Object.keys(this.fields).forEach((e=>{let s=this.fields[e];s.section=this.name,s.endpoints={field:this.endpoints.field+"+"+e,section:this.endpoints.section,model:this.endpoints.model},null===this.autofocus&&!0===s.autofocus&&(this.autofocus=e),t[e]=s})),t},index(){return this.limit?(this.page-1)*this.limit:1},more(){return!0!==this.disabled&&!(this.max&&this.items.length>=this.max)},isInvalid(){return!0!==this.disabled&&(!!(this.min&&this.items.lengththis.max))},isSortable(){return!this.sortBy&&(!this.limit&&(!0!==this.disabled&&(!(this.items.length<=1)&&!1!==this.sortable)))},pagination(){let t=0;return this.limit&&(t=(this.page-1)*this.limit),{page:this.page,offset:t,limit:this.limit,total:this.items.length,align:"center",details:!0}},options(){let t=[],e=this.duplicate&&this.more&&null===this.currentIndex;return e&&t.push({icon:"copy",text:this.$t("duplicate"),click:"duplicate"}),t.push({icon:"remove",text:e?this.$t("remove"):null,click:"remove"}),t},paginatedItems(){return this.limit?this.items.slice(this.pagination.offset,this.pagination.offset+this.limit):this.items}},watch:{value(t){t!=this.items&&(this.items=this.toItems(t))}},methods:{add(t){!0===this.prepend?this.items.unshift(t):this.items.push(t)},focus(){var t,e;null==(e=null==(t=this.$refs.add)?void 0:t.focus)||e.call(t)},jump(t,e){this.open(t+this.pagination.offset,e)},onAdd(){if(!0===this.disabled)return!1;if(null!==this.currentIndex)return this.onFormDiscard(),!1;let t={};for(const e in this.fields)t[e]=this.$helper.clone(this.fields[e].default);this.currentIndex="new",this.currentModel=t,this.onFormOpen()},onFormClose(){this.currentIndex=null,this.currentModel=null},onFormDiscard(){if("new"===this.currentIndex){if(0===Object.values(this.currentModel).filter((t=>!1===this.$helper.object.isEmpty(t))).length)return void this.onFormClose()}this.onFormSubmit()},onFormOpen(t=this.autofocus){this.$nextTick((()=>{var e;null==(e=this.$refs.form)||e.focus(t)}))},async onFormPaginate(t){await this.save(),this.open(t)},async onFormSubmit(){try{await this.save(),this.onFormClose()}catch(t){}},onInput(t=this.items){this.$emit("input",t)},onOption(t,e,s){switch(t){case"remove":this.onFormClose(),this.trash=s+this.pagination.offset,this.$refs.remove.open();break;case"duplicate":this.add(this.items[s+this.pagination.offset]),this.onInput()}},onRemove(){if(null===this.trash)return!1;this.items.splice(this.trash,1),this.trash=null,this.$refs.remove.close(),this.onInput(),0===this.paginatedItems.length&&this.page>1&&this.page--,this.items=this.sort(this.items)},open(t,e){this.currentIndex=t,this.currentModel=this.$helper.clone(this.items[t]),this.onFormOpen(e)},paginate({page:t}){this.page=t},sort(t){return this.sortBy?t.sortBy(this.sortBy):t},async save(){if(null!==this.currentIndex&&void 0!==this.currentIndex)try{return await this.validate(this.currentModel),"new"===this.currentIndex?this.add(this.currentModel):this.items[this.currentIndex]=this.currentModel,this.items=this.sort(this.items),this.onInput(),!0}catch(t){throw this.$store.dispatch("notification/error",{message:this.$t("error.form.incomplete"),details:t}),t}},toItems(t){return!1===Array.isArray(t)?[]:this.sort(t)},async validate(t){const e=await this.$api.post(this.endpoints.field+"/validate",t);if(e.length>0)throw e;return!0}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-structure-field",nativeOn:{click:function(t){t.stopPropagation()}},scopedSlots:t._u([{key:"options",fn:function(){return[t.more&&null===t.currentIndex?e("k-button",{ref:"add",attrs:{id:t._uid,text:t.$t("add"),icon:"add"},on:{click:t.onAdd}}):t._e()]},proxy:!0}])},"k-field",t.$props,!1),[null!==t.currentIndex?e("k-structure-form",{ref:"form",attrs:{fields:t.form,index:t.currentIndex,total:t.items.length},on:{close:t.onFormClose,discard:t.onFormDiscard,paginate:function(e){return t.onFormPaginate(e.offset)},submit:t.onFormSubmit},model:{value:t.currentModel,callback:function(e){t.currentModel=e},expression:"currentModel"}}):0===t.items.length?e("k-empty",{attrs:{"data-invalid":t.isInvalid,icon:"list-bullet"},on:{click:t.onAdd}},[t._v(" "+t._s(t.empty||t.$t("field.structure.empty"))+" ")]):[e("k-table",{attrs:{columns:t.columns,disabled:t.disabled,fields:t.fields,empty:t.$t("field.structure.empty"),index:t.index,options:t.options,rows:t.paginatedItems,sortable:t.isSortable,"data-invalid":t.isInvalid},on:{cell:function(e){return t.jump(e.rowIndex,e.columnIndex)},input:t.onInput,option:t.onOption}}),t.limit?e("k-pagination",t._b({on:{paginate:t.paginate}},"k-pagination",t.pagination,!1)):t._e(),t.disabled?t._e():e("k-dialog",{ref:"remove",attrs:{"submit-button":t.$t("delete"),theme:"negative"},on:{submit:t.onRemove}},[e("k-text",[t._v(t._s(t.$t("field.structure.delete.confirm")))])],1)]],2)}),[],!1,null,null,null,null).exports;const dn=It({mixins:[le,ce,As,Ys],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-tags-field",attrs:{input:t._uid,counter:t.counterOptions}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"tags"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const pn=It({mixins:[le,ce,Is],inheritAttrs:!1,props:{icon:{type:String,default:"phone"}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-tel-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"tel"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const hn=It({mixins:[le,ce,as,Ys],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()},select(){this.$refs.input.select()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-text-field",attrs:{input:t._uid,counter:t.counterOptions},scopedSlots:t._u([{key:"options",fn:function(){return[t._t("options")]},proxy:!0}],null,!0)},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const mn=It({mixins:[le,ce,Es,Ys],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-textarea-field",attrs:{input:t._uid,counter:t.counterOptions}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,type:"textarea",theme:"field"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const fn=It({mixins:[le,ce,js],inheritAttrs:!1,props:{icon:{type:String,default:"clock"},times:{type:Boolean,default:!0}},methods:{focus(){this.$refs.input.focus()},select(t){var e;this.$emit("input",t),null==(e=this.$refs.times)||e.close()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-time-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("k-input",t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"time"},on:{input:function(e){return t.$emit("input",e||"")}},scopedSlots:t._u([t.times?{key:"icon",fn:function(){return[e("k-dropdown",[e("k-button",{staticClass:"k-input-icon-button",attrs:{icon:t.icon||"clock",tooltip:t.$t("time.select")},on:{click:function(e){return t.$refs.times.toggle()}}}),e("k-dropdown-content",{ref:"times",attrs:{align:"right"}},[e("k-times",{attrs:{display:t.display,value:t.value},on:{input:t.select}})],1)],1)]},proxy:!0}:null],null,!0)},"k-input",t.$props,!1))],1)}),[],!1,null,null,null,null).exports;const gn=It({mixins:[le,ce,Bs],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-toggle-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"toggle"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const kn=It({mixins:[le,ce,Ns],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()},onInput(t){this.$emit("input",t)}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-toggles-field"},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",class:{grow:t.grow},attrs:{id:t._uid,theme:"field",type:"toggles"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const bn=It({mixins:[le,ce,Fs],inheritAttrs:!1,props:{link:{type:Boolean,default:!0},icon:{type:String,default:"url"}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-url-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"url"},scopedSlots:t._u([{key:"icon",fn:function(){return[t.link?e("k-button",{staticClass:"k-input-icon-button",attrs:{icon:t.icon,link:t.value,tooltip:t.$t("open"),tabindex:"-1",target:"_blank"}}):t._e()]},proxy:!0}])},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const yn=It({mixins:[Gs],computed:{emptyProps(){return{icon:"users",text:this.empty||this.$t("field.users.empty")}}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-users-field",scopedSlots:t._u([{key:"options",fn:function(){return[e("k-button-group",{staticClass:"k-field-options"},[t.more&&!t.disabled?e("k-button",{staticClass:"k-field-options-button",attrs:{icon:t.btnIcon,text:t.btnLabel},on:{click:t.open}}):t._e()],1)]},proxy:!0}])},"k-field",t.$props,!1),[e("k-collection",t._b({on:{empty:t.open,sort:t.onInput,sortChange:function(e){return t.$emit("change",e)}},scopedSlots:t._u([{key:"options",fn:function({index:s}){return[t.disabled?t._e():e("k-button",{attrs:{tooltip:t.$t("remove"),icon:"remove"},on:{click:function(e){return t.remove(s)}}})]}}])},"k-collection",t.collection,!1)),e("k-users-dialog",{ref:"selector",on:{submit:t.select}})],1)}),[],!1,null,null,null,null).exports;const vn=It({mixins:[le,ce,Ve],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-writer-field",attrs:{input:t._uid,counter:!1}},"k-field",t.$props,!1),[e("k-input",t._b({attrs:{after:t.after,before:t.before,icon:t.icon,theme:"field"}},"k-input",t.$props,!1),[e("k-writer",t._b({ref:"input",staticClass:"k-writer-field-input",attrs:{value:t.value},on:{input:function(e){return t.$emit("input",e)}}},"k-writer",t.$props,!1))],1)],1)}),[],!1,null,null,null,null).exports;t.component("k-blocks-field",zs),t.component("k-checkboxes-field",Hs),t.component("k-date-field",Us),t.component("k-email-field",Ks),t.component("k-files-field",Js),t.component("k-gap-field",Vs),t.component("k-headline-field",Ws),t.component("k-info-field",Xs),t.component("k-layout-field",Zs),t.component("k-line-field",Qs),t.component("k-list-field",tn),t.component("k-multiselect-field",en),t.component("k-number-field",sn),t.component("k-pages-field",nn),t.component("k-password-field",on),t.component("k-radio-field",rn),t.component("k-range-field",ln),t.component("k-select-field",an),t.component("k-slug-field",un),t.component("k-structure-field",cn),t.component("k-tags-field",dn),t.component("k-text-field",hn),t.component("k-textarea-field",mn),t.component("k-tel-field",pn),t.component("k-time-field",fn),t.component("k-toggle-field",gn),t.component("k-toggles-field",kn),t.component("k-url-field",bn),t.component("k-users-field",yn),t.component("k-writer-field",vn);const $n=It({props:{cover:Boolean,ratio:String},computed:{ratioPadding(){return this.$helper.ratio(this.ratio)}}},(function(){var t=this;return(0,t._self._c)("span",{staticClass:"k-aspect-ratio",style:{"padding-bottom":t.ratioPadding},attrs:{"data-cover":t.cover}},[t._t("default")],2)}),[],!1,null,null,null,null).exports;const _n=It({},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-bar"},[t.$slots.left?e("div",{staticClass:"k-bar-slot",attrs:{"data-position":"left"}},[t._t("left")],2):t._e(),t.$slots.center?e("div",{staticClass:"k-bar-slot",attrs:{"data-position":"center"}},[t._t("center")],2):t._e(),t.$slots.right?e("div",{staticClass:"k-bar-slot",attrs:{"data-position":"right"}},[t._t("right")],2):t._e()])}),[],!1,null,null,null,null).exports;const xn=It({props:{theme:{type:String,default:"none"},text:String,html:{type:Boolean,default:!1}}},(function(){var t=this,e=t._self._c;return e("div",t._g({staticClass:"k-box",attrs:{"data-theme":t.theme}},t.$listeners),[t._t("default",(function(){return[t.html?e("k-text",{attrs:{html:t.text}}):e("k-text",[t._v(" "+t._s(t.text)+" ")])]}))],2)}),[],!1,null,null,null,null).exports;const wn=It({inheritAttrs:!1,props:{back:String,color:String,element:{type:String,default:"li"},image:Object,link:String,text:String}},(function(){var t=this,e=t._self._c;return e(t.link?"k-link":"p",{tag:"component",staticClass:"k-bubble",style:{color:t.$helper.color(t.color),background:t.$helper.color(t.back)},attrs:{to:t.link},nativeOn:{click:function(t){t.stopPropagation()}}},[t.image?e("k-item-image",{attrs:{image:t.image,layout:"list"}}):t._e(),t._v(" "+t._s(t.text)+" ")],1)}),[],!1,null,null,null,null).exports;const Sn=It({inheritAttrs:!1,props:{bubbles:Array},computed:{items(){let t=this.bubbles;return"string"==typeof t&&(t=t.split(",")),t.map((t=>"string"==typeof t?{text:t}:t))}}},(function(){var t=this,e=t._self._c;return e("ul",{staticClass:"k-bubbles"},t._l(t.items,(function(s,n){return e("li",{key:n},[e("k-bubble",t._b({},"k-bubble",s,!1))],1)})),0)}),[],!1,null,null,null,null).exports;const Cn=It({props:{columns:{type:[Object,Array],default:()=>({})},empty:Object,help:String,items:{type:[Array,Object],default:()=>[]},layout:{type:String,default:"list"},link:{type:Boolean,default:!0},size:String,sortable:Boolean,pagination:{type:[Boolean,Object],default:()=>!1}},computed:{hasPagination(){return!1!==this.pagination&&(!0!==this.paginationOptions.hide&&!(this.pagination.total<=this.pagination.limit))},hasFooter(){return!(!this.hasPagination&&!this.help)},paginationOptions(){return{limit:10,details:!0,keys:!1,total:0,hide:!1,..."object"!=typeof this.pagination?{}:this.pagination}}},watch:{$props(){this.$forceUpdate()}},methods:{onEmpty(t){t.stopPropagation(),this.$emit("empty")},onOption(...t){this.$emit("action",...t),this.$emit("option",...t)}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-collection"},[t.items.length?e("k-items",{attrs:{columns:t.columns,items:t.items,layout:t.layout,link:t.link,size:t.size,sortable:t.sortable},on:{change:function(e){return t.$emit("change",e)},item:function(e){return t.$emit("item",e)},option:t.onOption,sort:function(e){return t.$emit("sort",e)}},scopedSlots:t._u([{key:"options",fn:function({item:e,itemIndex:s}){return[t._t("options",null,null,{item:e,index:s})]}}],null,!0)}):e("k-empty",t._g(t._b({attrs:{layout:t.layout}},"k-empty",t.empty,!1),t.$listeners.empty?{click:t.onEmpty}:{})),t.hasFooter?e("footer",{staticClass:"k-collection-footer"},[t.help?e("k-text",{staticClass:"k-collection-help",attrs:{theme:"help",html:t.help}}):t._e(),e("div",{staticClass:"k-collection-pagination"},[t.hasPagination?e("k-pagination",t._b({on:{paginate:function(e){return t.$emit("paginate",e)}}},"k-pagination",t.paginationOptions,!1)):t._e()],1)],1):t._e()],1)}),[],!1,null,null,null,null).exports;const On=It({props:{width:String,sticky:Boolean}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-column",attrs:{"data-width":t.width,"data-sticky":t.sticky}},[e("div",[t._t("default")],2)])}),[],!1,null,null,null,null).exports;const An=It({props:{disabled:{type:Boolean,default:!1}},data:()=>({files:[],dragging:!1,over:!1}),methods:{cancel(){this.reset()},reset(){this.dragging=!1,this.over=!1},onDrop(t){return!0===this.disabled||!1===this.$helper.isUploadEvent(t)?this.reset():(this.$events.$emit("dropzone.drop"),this.files=t.dataTransfer.files,this.$emit("drop",this.files),void this.reset())},onEnter(t){!1===this.disabled&&this.$helper.isUploadEvent(t)&&(this.dragging=!0)},onLeave(){this.reset()},onOver(t){!1===this.disabled&&this.$helper.isUploadEvent(t)&&(t.dataTransfer.dropEffect="copy",this.over=!0)}}},(function(){var t=this;return(0,t._self._c)("div",{staticClass:"k-dropzone",attrs:{"data-dragging":t.dragging,"data-over":t.over},on:{dragenter:t.onEnter,dragleave:t.onLeave,dragover:t.onOver,drop:t.onDrop}},[t._t("default")],2)}),[],!1,null,null,null,null).exports;const Tn=It({props:{text:String,icon:String,layout:{type:String,default:"list"}},computed:{element(){return void 0!==this.$listeners.click?"button":"div"}}},(function(){var t=this,e=t._self._c;return e(t.element,t._g({tag:"component",staticClass:"k-empty",attrs:{"data-layout":t.layout,type:"button"===t.element&&"button"}},t.$listeners),[t.icon?e("k-icon",{attrs:{type:t.icon}}):t._e(),e("p",[t._t("default",(function(){return[t._v(t._s(t.text))]}))],2)],1)}),[],!1,null,null,null,null).exports;const In=It({props:{details:Array,image:Object,url:String}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-file-preview"},[e("k-view",{staticClass:"k-file-preview-layout"},[e("div",{staticClass:"k-file-preview-image"},[e("k-link",{staticClass:"k-file-preview-image-link",attrs:{to:t.url,title:t.$t("open"),target:"_blank"}},[e("k-item-image",{attrs:{image:t.image,layout:"cards"}})],1)],1),e("div",{staticClass:"k-file-preview-details"},[e("ul",t._l(t.details,(function(s){return e("li",{key:s.title},[e("h3",[t._v(t._s(s.title))]),e("p",[s.link?e("k-link",{attrs:{to:s.link,tabindex:"-1",target:"_blank"}},[t._v(" /"+t._s(s.text)+" ")]):[t._v(" "+t._s(s.text)+" ")]],2)])})),0)])])],1)}),[],!1,null,null,null,null).exports;const Mn=It({props:{gutter:String}},(function(){var t=this;return(0,t._self._c)("div",{staticClass:"k-grid",attrs:{"data-gutter":t.gutter}},[t._t("default")],2)}),[],!1,null,null,null,null).exports;const En=It({props:{editable:Boolean,tab:String,tabs:{type:Array,default:()=>[]}},computed:{tabsWithBadges(){const t=Object.keys(this.$store.getters["content/changes"]());return this.tabs.map((e=>{let s=[];return Object.values(e.columns).forEach((t=>{Object.values(t.sections).forEach((t=>{"fields"===t.type&&Object.keys(t.fields).forEach((t=>{s.push(t)}))}))})),e.badge=s.filter((e=>t.includes(e.toLowerCase()))).length,e}))}}},(function(){var t=this,e=t._self._c;return e("header",{staticClass:"k-header",attrs:{"data-editable":t.editable,"data-tabs":t.tabsWithBadges.length>1}},[e("k-headline",{attrs:{tag:"h1",size:"huge"}},[t.editable&&t.$listeners.edit?e("span",{staticClass:"k-headline-editable",on:{click:function(e){return t.$emit("edit")}}},[t._t("default"),e("k-icon",{attrs:{type:"edit"}})],2):t._t("default")],2),t.$slots.left||t.$slots.right?e("k-bar",{staticClass:"k-header-buttons",scopedSlots:t._u([{key:"left",fn:function(){return[t._t("left")]},proxy:!0},{key:"right",fn:function(){return[t._t("right")]},proxy:!0}],null,!0)}):t._e(),e("k-tabs",{attrs:{tab:t.tab,tabs:t.tabsWithBadges,theme:"notice"}})],1)}),[],!1,null,null,null,null).exports;const Ln=It({inheritAttrs:!1},(function(){var t=this,e=t._self._c;return e("k-panel",{staticClass:"k-panel-inside",attrs:{tabindex:"0"}},[e("header",{staticClass:"k-panel-header"},[e("k-topbar",{attrs:{breadcrumb:t.$view.breadcrumb,license:t.$license,menu:t.$menu,view:t.$view}})],1),e("main",{staticClass:"k-panel-view scroll-y"},[t._t("default")],2),t._t("footer")],2)}),[],!1,null,null,null,null).exports;const jn=It({inheritAttrs:!1,props:{data:Object,flag:Object,image:[Object,Boolean],info:String,layout:{type:String,default:"list"},link:{type:[Boolean,String,Function]},options:{type:[Array,Function,String]},sortable:Boolean,target:String,text:String,width:String},computed:{hasFigure(){return!1!==this.image&&Object.keys(this.image).length>0},title(){return this.text||"-"}},methods:{onOption(t){this.$emit("action",t),this.$emit("option",t)}}},(function(){var t=this,e=t._self._c;return e("article",t._b({staticClass:"k-item",class:!!t.layout&&"k-"+t.layout+"-item",attrs:{"data-has-figure":t.hasFigure,"data-has-flag":Boolean(t.flag),"data-has-info":Boolean(t.info),"data-has-options":Boolean(t.options),tabindex:"-1"},on:{click:function(e){return t.$emit("click",e)},dragstart:function(e){return t.$emit("drag",e)}}},"article",t.data,!1),[t._t("image",(function(){return[t.hasFigure?e("k-item-image",{attrs:{image:t.image,layout:t.layout,width:t.width}}):t._e()]})),t.sortable?e("k-sort-handle",{staticClass:"k-item-sort-handle"}):t._e(),e("header",{staticClass:"k-item-content"},[t._t("default",(function(){return[e("h3",{staticClass:"k-item-title"},[!1!==t.link?e("k-link",{staticClass:"k-item-title-link",attrs:{target:t.target,to:t.link}},[e("span",{domProps:{innerHTML:t._s(t.title)}})]):e("span",{domProps:{innerHTML:t._s(t.title)}})],1),t.info?e("p",{staticClass:"k-item-info",domProps:{innerHTML:t._s(t.info)}}):t._e()]}))],2),t.flag||t.options||t.$slots.options?e("footer",{staticClass:"k-item-footer"},[e("nav",{staticClass:"k-item-buttons",on:{click:function(t){t.stopPropagation()}}},[t.flag?e("k-status-icon",t._b({},"k-status-icon",t.flag,!1)):t._e(),t._t("options",(function(){return[t.options?e("k-options-dropdown",{staticClass:"k-item-options-dropdown",attrs:{options:t.options},on:{option:t.onOption}}):t._e()]}))],2)]):t._e()],2)}),[],!1,null,null,null,null).exports;const Dn=It({inheritAttrs:!1,props:{image:[Object,Boolean],layout:{type:String,default:"list"},width:String},computed:{back(){return this.image.back||"black"},ratio(){return"cards"===this.layout&&this.image.ratio||"1/1"},size(){switch(this.layout){case"cards":return"large";case"cardlets":return"medium";default:return"regular"}},sizes(){switch(this.width){case"1/2":case"2/4":return"(min-width: 30em) and (max-width: 65em) 59em, (min-width: 65em) 44em, 27em";case"1/3":return"(min-width: 30em) and (max-width: 65em) 59em, (min-width: 65em) 29.333em, 27em";case"1/4":return"(min-width: 30em) and (max-width: 65em) 59em, (min-width: 65em) 22em, 27em";case"2/3":return"(min-width: 30em) and (max-width: 65em) 59em, (min-width: 65em) 27em, 27em";case"3/4":return"(min-width: 30em) and (max-width: 65em) 59em, (min-width: 65em) 66em, 27em";default:return"(min-width: 30em) and (max-width: 65em) 59em, (min-width: 65em) 88em, 27em"}}}},(function(){var t=this,e=t._self._c;return t.image?e("div",{staticClass:"k-item-figure",style:{background:t.$helper.color(t.back)}},[t.image.src?e("k-image",{staticClass:"k-item-image",attrs:{cover:t.image.cover,ratio:t.ratio,sizes:t.sizes,src:t.image.src,srcset:t.image.srcset}}):e("k-aspect-ratio",{attrs:{ratio:t.ratio}},[e("k-icon",{staticClass:"k-item-icon",attrs:{color:t.$helper.color(t.image.color),type:t.image.icon}})],1)],1):t._e()}),[],!1,null,null,null,null).exports;const Bn=It({inheritAttrs:!1,props:{columns:{type:[Object,Array],default:()=>({})},items:{type:Array,default:()=>[]},layout:{type:String,default:"list"},link:{type:Boolean,default:!0},image:{type:[Object,Boolean],default:()=>({})},sortable:Boolean,empty:{type:[String,Object]},size:{type:String,default:"default"}},computed:{dragOptions(){return{sort:this.sortable,disabled:!1===this.sortable,draggable:".k-draggable-item"}},table(){return{columns:this.columns,rows:this.items,sortable:this.sortable}}},methods:{onDragStart(t,e){this.$store.dispatch("drag",{type:"text",data:e})},onOption(t,e,s){this.$emit("option",t,e,s)},imageOptions(t){let e=this.image,s=t.image;return!1!==e&&!1!==s&&("object"!=typeof e&&(e={}),"object"!=typeof s&&(s={}),{...s,...e})}}},(function(){var t=this,e=t._self._c;return"table"===t.layout?e("k-table",t._b({on:{change:function(e){return t.$emit("change",e)},sort:function(e){return t.$emit("sort",e)},option:t.onOption}},"k-table",t.table,!1)):e("k-draggable",{staticClass:"k-items",class:"k-"+t.layout+"-items",attrs:{handle:!0,options:t.dragOptions,"data-layout":t.layout,"data-size":t.size,list:t.items},on:{change:function(e){return t.$emit("change",e)},end:function(e){return t.$emit("sort",t.items,e)}}},t._l(t.items,(function(s,n){return e("k-item",t._b({key:s.id||n,class:{"k-draggable-item":t.sortable&&s.sortable},attrs:{image:t.imageOptions(s),layout:t.layout,link:!!t.link&&s.link,sortable:t.sortable&&s.sortable,width:s.column},on:{click:function(e){return t.$emit("item",s,n)},drag:function(e){return t.onDragStart(e,s.dragText)},option:function(e){return t.onOption(e,s,n)}},nativeOn:{mouseover:function(e){return t.$emit("hover",e,s,n)}},scopedSlots:t._u([{key:"options",fn:function(){return[t._t("options",null,null,{item:s,itemIndex:n})]},proxy:!0}],null,!0)},"k-item",s,!1))})),1)}),[],!1,null,null,null,null).exports;const Pn=It({inheritAttrs:!0,props:{autofocus:{type:Boolean,default:!0},centered:{type:Boolean,default:!1},dimmed:{type:Boolean,default:!0},loading:{type:Boolean,default:!1}},data:()=>({isOpen:!1,scrollTop:0}),methods:{close(){!1!==this.isOpen&&(this.isOpen=!1,this.$emit("close"),this.restoreScrollPosition(),this.$events.$off("keydown.esc",this.close))},focus(){var t,e;let s=this.$refs.overlay.querySelector("\n [autofocus],\n [data-autofocus]\n ");return null===s&&(s=this.$refs.overlay.querySelector("\n input,\n textarea,\n select,\n button\n ")),"function"==typeof(null==s?void 0:s.focus)?s.focus():"function"==typeof(null==(e=null==(t=this.$slots.default[0])?void 0:t.context)?void 0:e.focus)?this.$slots.default[0].context.focus():void 0},open(){!0!==this.isOpen&&(this.storeScrollPosition(),this.isOpen=!0,this.$emit("open"),this.$events.$on("keydown.esc",this.close),setTimeout((()=>{!0===this.autofocus&&this.focus(),document.querySelector(".k-overlay > *").addEventListener("mousedown",(t=>t.stopPropagation())),this.$emit("ready")}),1))},restoreScrollPosition(){const t=document.querySelector(".k-panel-view");(null==t?void 0:t.scrollTop)&&(t.scrollTop=this.scrollTop)},storeScrollPosition(){const t=document.querySelector(".k-panel-view");(null==t?void 0:t.scrollTop)?this.scrollTop=t.scrollTop:this.scrollTop=0}}},(function(){var t=this,e=t._self._c;return t.isOpen?e("portal",[e("div",t._g({ref:"overlay",staticClass:"k-overlay",class:t.$vnode.data.staticClass,attrs:{"data-centered":t.loading||t.centered,"data-dimmed":t.dimmed,"data-loading":t.loading,dir:t.$translation.direction},on:{mousedown:t.close}},t.$listeners),[t.loading?e("k-loader",{staticClass:"k-overlay-loader"}):t._t("default",null,{close:t.close,isOpen:t.isOpen})],2)]):t._e()}),[],!1,null,null,null,null).exports;const Nn=It({computed:{defaultLanguage(){return!!this.$language&&this.$language.default},dialog(){return this.$helper.clone(this.$store.state.dialog)},dir(){return this.$translation.direction},language(){return this.$language?this.$language.code:null},role(){return this.$user?this.$user.role:null},user(){return this.$user?this.$user.id:null}},watch:{dir:{handler(){document.body.dir=this.dir},immediate:!0}},created(){this.$events.$on("drop",this.drop)},destroyed(){this.$events.$off("drop",this.drop)},methods:{drop(){this.$store.dispatch("drag",null)}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-panel",attrs:{"data-dragging":t.$store.state.drag,"data-loading":t.$store.state.isLoading,"data-language":t.language,"data-language-default":t.defaultLanguage,"data-role":t.role,"data-translation":t.$translation.code,"data-user":t.user,dir:t.dir}},[t._t("default"),t.$store.state.dialog&&t.$store.state.dialog.props?[e("k-fiber-dialog",t._b({},"k-fiber-dialog",t.dialog,!1))]:t._e(),!1!==t.$store.state.fatal?e("k-fatal",{attrs:{html:t.$store.state.fatal}}):t._e(),!1===t.$system.isLocal?e("k-offline-warning"):t._e(),e("k-icons")],2)}),[],!1,null,null,null,null).exports;const qn=It({props:{reports:Array,size:{type:String,default:"large"}}},(function(){var t=this,e=t._self._c;return e("dl",{staticClass:"k-stats",attrs:{"data-size":t.size}},t._l(t.reports,(function(s,n){return e(s.link?"k-link":"div",{key:n,tag:"component",staticClass:"k-stat",attrs:{"data-theme":s.theme,"data-click":!!s.click,to:s.link},on:{click:function(t){s.click&&s.click()}}},[e("dt",{staticClass:"k-stat-label"},[t._v(t._s(s.label))]),e("dd",{staticClass:"k-stat-value"},[t._v(t._s(s.value))]),e("dd",{staticClass:"k-stat-info"},[t._v(t._s(s.info))])])})),1)}),[],!1,null,null,null,null).exports;const Fn=It({inheritAttrs:!1,props:{columns:Object,disabled:Boolean,fields:{type:Object,default:()=>({})},empty:String,index:{type:[Number,Boolean],default:1},rows:Array,options:[Array,Function],sortable:Boolean},data(){return{values:this.rows}},computed:{columnsCount(){return Object.keys(this.columns).length},dragOptions(){return{disabled:!this.sortable,fallbackClass:"k-table-row-fallback",ghostClass:"k-table-row-ghost"}},hasIndexColumn(){return this.sortable||!1!==this.index},hasOptions(){return this.options||Object.values(this.values).filter((t=>t.options)).length>0}},watch:{rows(){this.values=this.rows}},methods:{isColumnEmpty(t){return 0===this.rows.filter((e=>!1===this.$helper.object.isEmpty(e[t]))).length},label(t,e){return t.label||this.$helper.string.ucfirst(e)},onChange(t){this.$emit("change",t)},onCell(t){this.$emit("cell",t)},onCellUpdate({columnIndex:t,rowIndex:e,value:s}){this.values[e][t]=s,this.$emit("input",this.values)},onHeader(t){this.$emit("header",t)},onOption(t,e,s){this.$emit("option",t,e,s)},onSort(){this.$emit("input",this.values),this.$emit("sort",this.values)},width(t){return"string"!=typeof t?"auto":!1===t.includes("/")?t:this.$helper.ratio(t,"auto",!1)}}},(function(){var t=this,e=t._self._c;return e("table",{staticClass:"k-table",attrs:{"data-disabled":t.disabled,"data-indexed":t.hasIndexColumn}},[e("thead",[e("tr",[t.hasIndexColumn?e("th",{staticClass:"k-table-index-column",attrs:{"data-mobile":""}},[t._v(" # ")]):t._e(),t._l(t.columns,(function(s,n){return e("th",{key:n+"-header",staticClass:"k-table-column",style:"width:"+t.width(s.width),attrs:{"data-mobile":s.mobile},on:{click:function(e){return t.onHeader({column:s,columnIndex:n})}}},[t._t("header",(function(){return[t._v(" "+t._s(t.label(s,n))+" ")]}),null,{column:s,columnIndex:n,label:t.label(s,n)})],2)})),t.hasOptions?e("th",{staticClass:"k-table-options-column",attrs:{"data-mobile":""}}):t._e()],2)]),e("k-draggable",{attrs:{list:t.values,options:t.dragOptions,handle:!0,element:"tbody"},on:{change:t.onChange,end:t.onSort}},[0===t.rows.length?e("tr",[e("td",{staticClass:"k-table-empty",attrs:{colspan:t.columnsCount}},[t._v(" "+t._s(t.empty)+" ")])]):t._l(t.values,(function(s,n){return e("tr",{key:n},[t.hasIndexColumn?e("td",{staticClass:"k-table-index-column",attrs:{"data-sortable":t.sortable&&!1!==s.sortable,"data-mobile":""}},[t._t("index",(function(){return[e("div",{staticClass:"k-table-index",domProps:{textContent:t._s(t.index+n)}})]}),null,{row:s,rowIndex:n}),t.sortable&&!1!==s.sortable?e("k-sort-handle",{staticClass:"k-table-sort-handle"}):t._e()],2):t._e(),t._l(t.columns,(function(i,o){return e("k-table-cell",{key:n+"-"+o,staticClass:"k-table-column",style:"width:"+t.width(i.width),attrs:{column:i,field:t.fields[o],row:s,mobile:i.mobile,value:s[o]},on:{input:function(e){return t.onCellUpdate({columnIndex:o,rowIndex:n,value:e})}},nativeOn:{click:function(e){return t.onCell({row:s,rowIndex:n,column:i,columnIndex:o})}}})})),t.hasOptions?e("td",{staticClass:"k-table-options-column",attrs:{"data-mobile":""}},[t._t("options",(function(){return[e("k-options-dropdown",{attrs:{options:s.options||t.options,text:(s.options||t.options).length>1},on:{option:function(e){return t.onOption(e,s,n)}}})]}),null,{row:s,rowIndex:n,options:t.options})],2):t._e()],2)}))],2)],1)}),[],!1,null,null,null,null).exports;const Rn=It({inheritAttrs:!1,props:{column:Object,field:Object,mobile:{type:Boolean,default:!1},row:Object,value:{default:""}},computed:{component(){return this.$helper.isComponent(`k-${this.type}-field-preview`)?`k-${this.type}-field-preview`:this.$helper.isComponent(`k-table-${this.type}-cell`)?`k-table-${this.type}-cell`:Array.isArray(this.value)?"k-array-field-preview":"k-text-field-preview"},type(){var t;return this.column.type||(null==(t=this.field)?void 0:t.type)}}},(function(){var t=this,e=t._self._c;return e("td",{attrs:{"data-align":t.column.align,"data-mobile":t.mobile}},[!1===t.$helper.object.isEmpty(t.value)?[e(t.component,{tag:"component",attrs:{column:t.column,field:t.field,row:t.row,value:t.value},on:{input:function(e){return t.$emit("input",e)}}})]:t._e()],2)}),[],!1,null,null,null,null).exports;const zn=It({props:{tab:String,tabs:Array,theme:String},data(){return{size:null,visibleTabs:this.tabs,invisibleTabs:[]}},computed:{current(){return(this.tabs.find((t=>t.name===this.tab))||this.tabs[0]||{}).name}},watch:{tabs:{handler(t){this.visibleTabs=t,this.invisibleTabs=[],this.resize(!0)},immediate:!0}},created(){window.addEventListener("resize",this.resize)},destroyed(){window.removeEventListener("resize",this.resize)},methods:{resize(t){if(this.tabs&&!(this.tabs.length<=1)){if(this.tabs.length<=3)return this.visibleTabs=this.tabs,void(this.invisibleTabs=[]);if(window.innerWidth>=700){if("large"===this.size&&!t)return;this.visibleTabs=this.tabs,this.invisibleTabs=[],this.size="large"}else{if("small"===this.size&&!t)return;this.visibleTabs=this.tabs.slice(0,2),this.invisibleTabs=this.tabs.slice(2),this.size="small"}}}}},(function(){var t=this,e=t._self._c;return t.tabs&&t.tabs.length>1?e("div",{staticClass:"k-tabs",attrs:{"data-theme":t.theme}},[e("nav",[t._l(t.visibleTabs,(function(s){return e("k-button",{key:s.name,staticClass:"k-tab-button",attrs:{link:s.link,current:t.current===s.name,icon:s.icon,tooltip:s.label}},[t._v(" "+t._s(s.label||s.text||s.name)+" "),s.badge?e("span",{staticClass:"k-tabs-badge"},[t._v(" "+t._s(s.badge)+" ")]):t._e()])})),t.invisibleTabs.length?e("k-button",{staticClass:"k-tab-button k-tabs-dropdown-button",attrs:{text:t.$t("more"),icon:"dots"},on:{click:function(e){return e.stopPropagation(),t.$refs.more.toggle()}}}):t._e()],2),t.invisibleTabs.length?e("k-dropdown-content",{ref:"more",staticClass:"k-tabs-dropdown",attrs:{align:"right"}},t._l(t.invisibleTabs,(function(s){return e("k-dropdown-item",{key:"more-"+s.name,attrs:{link:s.link,current:t.tab===s.name,icon:s.icon,tooltip:s.label}},[t._v(" "+t._s(s.label||s.text||s.name)+" ")])})),1):t._e()],1):t._e()}),[],!1,null,null,null,null).exports;const Yn=It({props:{align:String}},(function(){var t=this;return(0,t._self._c)("div",{staticClass:"k-view",attrs:{"data-align":t.align}},[t._t("default")],2)}),[],!1,null,null,null,null).exports,Hn={};const Un=It({components:{draggable:()=>{return t=()=>import("./vuedraggable.js"),(e=[])&&0!==e.length?Promise.all(e.map((t=>{if((t=function(t){return"/"+t}(t))in Hn)return;Hn[t]=!0;const e=t.endsWith(".css"),s=e?'[rel="stylesheet"]':"";if(document.querySelector(`link[href="${t}"]${s}`))return;const n=document.createElement("link");return n.rel=e?"stylesheet":"modulepreload",e||(n.as="script",n.crossOrigin=""),n.href=t,document.head.appendChild(n),e?new Promise(((e,s)=>{n.addEventListener("load",e),n.addEventListener("error",(()=>s(new Error(`Unable to preload CSS for ${t}`))))})):void 0}))).then((()=>t())):t();var t,e}},props:{data:Object,element:String,handle:[String,Boolean],list:[Array,Object],move:Function,options:Object},data(){return{listeners:{...this.$listeners,start:t=>{this.$store.dispatch("drag",{}),this.$listeners.start&&this.$listeners.start(t)},end:t=>{this.$store.dispatch("drag",null),this.$listeners.end&&this.$listeners.end(t)}}}},computed:{dragOptions(){let t=!1;return t=!0===this.handle?".k-sort-handle":this.handle,{fallbackClass:"k-sortable-fallback",fallbackOnBody:!0,forceFallback:!0,ghostClass:"k-sortable-ghost",handle:t,scroll:document.querySelector(".k-panel-view"),...this.options}}}},(function(){var t=this;return(0,t._self._c)("draggable",t._g(t._b({staticClass:"k-draggable",attrs:{"component-data":t.data,tag:t.element,list:t.list,move:t.move},scopedSlots:t._u([{key:"footer",fn:function(){return[t._t("footer")]},proxy:!0}],null,!0)},"draggable",t.dragOptions,!1),t.listeners),[t._t("default")],2)}),[],!1,null,null,null,null).exports;const Kn=It({data:()=>({error:null}),errorCaptured(t){return this.$config.debug&&window.console.warn(t),this.error=t,!1},render(t){return this.error?this.$slots.error?this.$slots.error[0]:this.$scopedSlots.error?this.$scopedSlots.error({error:this.error}):t("k-box",{attrs:{theme:"negative"}},this.error.message||this.error):this.$slots.default[0]}},null,null,!1,null,null,null,null).exports;const Gn=It({props:{html:String},mounted(){try{let t=this.$refs.iframe.contentWindow.document;t.open(),t.write(this.html),t.close()}catch(t){console.error(t)}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-fatal"},[e("div",{staticClass:"k-fatal-box"},[e("k-bar",{scopedSlots:t._u([{key:"left",fn:function(){return[e("k-headline",[t._v(" The JSON response could not be parsed ")])]},proxy:!0},{key:"right",fn:function(){return[e("k-button",{attrs:{icon:"cancel",text:"Close"},on:{click:function(e){return t.$store.dispatch("fatal",!1)}}})]},proxy:!0}])}),e("iframe",{ref:"iframe",staticClass:"k-fatal-iframe"})],1)])}),[],!1,null,null,null,null).exports;const Jn=It({props:{link:String,size:{type:String},tag:{type:String,default:"h2"},theme:{type:String}}},(function(){var t=this,e=t._self._c;return e(t.tag,t._g({tag:"component",staticClass:"k-headline",attrs:{"data-theme":t.theme,"data-size":t.size}},t.$listeners),[t.link?e("k-link",{attrs:{to:t.link}},[t._t("default")],2):t._t("default")],2)}),[],!1,null,null,null,null).exports;const Vn=It({props:{alt:String,color:String,back:String,size:String,type:String},computed:{isEmoji(){return this.$helper.string.hasEmoji(this.type)}}},(function(){var t=this,e=t._self._c;return e("span",{class:"k-icon k-icon-"+t.type,style:{background:t.$helper.color(t.back)},attrs:{"aria-label":t.alt,role:t.alt?"img":null,"aria-hidden":!t.alt,"data-back":t.back,"data-size":t.size}},[t.isEmoji?e("span",{staticClass:"k-icon-emoji"},[t._v(t._s(t.type))]):e("svg",{style:{color:t.$helper.color(t.color)},attrs:{viewBox:"0 0 16 16"}},[e("use",{attrs:{"xlink:href":"#icon-"+t.type}})])])}),[],!1,null,null,null,null).exports;const Wn=It({icons:window.panel.plugins.icons},(function(){var t=this,e=t._self._c;return e("svg",{staticClass:"k-icons",attrs:{"aria-hidden":"true",xmlns:"http://www.w3.org/2000/svg",overflow:"hidden"}},[e("defs",t._l(t.$options.icons,(function(s,n){return e("symbol",{key:n,attrs:{id:"icon-"+n,viewBox:"0 0 16 16"},domProps:{innerHTML:t._s(s)}})})),0)])}),[],!1,null,null,null,null).exports;const Xn=It({props:{alt:String,back:String,cover:Boolean,ratio:String,sizes:String,src:String,srcset:String},data:()=>({loaded:{type:Boolean,default:!1},error:{type:Boolean,default:!1}}),computed:{ratioPadding(){return this.$helper.ratio(this.ratio||"1/1")}},created(){let t=new Image;t.onload=()=>{this.loaded=!0,this.$emit("load")},t.onerror=()=>{this.error=!0,this.$emit("error")},t.src=this.src}},(function(){var t=this,e=t._self._c;return e("span",t._g({staticClass:"k-image",attrs:{"data-ratio":t.ratio,"data-back":t.back,"data-cover":t.cover}},t.$listeners),[e("span",{style:"padding-bottom:"+t.ratioPadding},[t.loaded?e("img",{key:t.src,attrs:{alt:t.alt||"",src:t.src,srcset:t.srcset,sizes:t.sizes},on:{dragstart:function(t){t.preventDefault()}}}):t._e(),t.loaded||t.error?t._e():e("k-loader",{attrs:{position:"center",theme:"light"}}),!t.loaded&&t.error?e("k-icon",{staticClass:"k-image-error",attrs:{type:"cancel"}}):t._e()],1)])}),[],!1,null,null,null,null).exports;const Zn=It({},(function(){var t=this._self._c;return t("span",{staticClass:"k-loader"},[t("k-icon",{staticClass:"k-loader-icon",attrs:{type:"loader"}})],1)}),[],!1,null,null,null,null).exports;const Qn=It({data:()=>({offline:!1}),created(){this.$events.$on("offline",this.isOffline),this.$events.$on("online",this.isOnline)},destroyed(){this.$events.$off("offline",this.isOffline),this.$events.$off("online",this.isOnline)},methods:{isOnline(){this.offline=!1},isOffline(){this.offline=!0}}},(function(){var t=this,e=t._self._c;return t.offline?e("div",{staticClass:"k-offline-warning"},[e("p",[e("k-icon",{attrs:{type:"bolt"}}),t._v(" "+t._s(t.$t("error.offline")))],1)]):t._e()}),[],!1,null,null,null,null).exports,ti=(t,e=!1)=>{if(t>=0&&t<=100)return!0;if(e)throw new Error("value has to be between 0 and 100");return!1};const ei=It({props:{value:{type:Number,default:0,validator:ti}},data(){return{state:this.value}},watch:{value(t){this.state=t}},methods:{set(t){ti(t,!0),this.state=t}}},(function(){var t=this;return(0,t._self._c)("progress",{staticClass:"k-progress",attrs:{max:"100"},domProps:{value:t.state}},[t._v(t._s(t.state)+"%")])}),[],!1,null,null,null,null).exports;const si=It({},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-registration"},[e("p",[t._v(t._s(t.$t("license.unregistered")))]),e("k-button",{staticClass:"k-topbar-button",attrs:{responsive:!0,tooltip:t.$t("license.unregistered"),icon:"key"},on:{click:function(e){return t.$dialog("registration")}}},[t._v(" "+t._s(t.$t("license.register"))+" ")]),e("k-button",{staticClass:"k-topbar-button",attrs:{responsive:!0,link:"https://getkirby.com/buy",target:"_blank",icon:"cart"}},[t._v(" "+t._s(t.$t("license.buy"))+" ")])],1)}),[],!1,null,null,null,null).exports;const ni=It({props:{icon:{type:String,default:"sort"}}},(function(){return(0,this._self._c)("k-icon",{staticClass:"k-sort-handle",attrs:{type:this.icon,"aria-hidden":"true"}})}),[],!1,null,null,null,null).exports;const ii=It({props:{click:{type:Function,default:()=>{}},disabled:Boolean,responsive:Boolean,status:String,text:String,tooltip:String},computed:{icon(){return"draft"===this.status?"circle-outline":"unlisted"===this.status?"circle-half":"circle"},theme(){return"draft"===this.status?"negative":"unlisted"===this.status?"info":"positive"},title(){let t=this.tooltip||this.text;return this.disabled&&(t+=` (${this.$t("disabled")})`),t}},methods:{onClick(){this.click(),this.$emit("click")}}},(function(){var t=this;return(0,t._self._c)("k-button",{class:"k-status-icon k-status-icon-"+t.status,attrs:{disabled:t.disabled,icon:t.icon,responsive:t.responsive,text:t.text,theme:t.theme,tooltip:t.title},on:{click:t.onClick}})}),[],!1,null,null,null,null).exports;const oi=It({props:{align:String,html:String,size:String,theme:String},computed:{attrs(){return{class:"k-text","data-align":this.align,"data-size":this.size,"data-theme":this.theme}}}},(function(){var t=this,e=t._self._c;return t.html?e("div",t._b({domProps:{innerHTML:t._s(t.html)}},"div",t.attrs,!1)):e("div",t._b({},"div",t.attrs,!1),[t._t("default")],2)}),[],!1,null,null,null,null).exports;const ri=It({props:{user:[Object,String]}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-user-info"},[t.user.avatar?e("k-image",{attrs:{cover:!0,src:t.user.avatar.url,ratio:"1/1"}}):e("k-icon",{attrs:{type:"user"}}),t._v(" "+t._s(t.user.name||t.user.email||t.user)+" ")],1)}),[],!1,null,null,null,null).exports;const li=It({props:{crumbs:{type:Array,default:()=>[]},label:{type:String,default:"Breadcrumb"},view:Object},computed:{dropdown(){return this.segments.map((t=>({...t,text:t.label,icon:"angle-right"})))},segments(){return[{link:this.view.link,label:this.view.breadcrumbLabel,icon:this.view.icon,loading:this.$store.state.isLoading},...this.crumbs]}},methods:{isLast(t){return this.crumbs.length-1===t}}},(function(){var t=this,e=t._self._c;return e("nav",{staticClass:"k-breadcrumb",attrs:{"aria-label":t.label}},[e("k-dropdown",{staticClass:"k-breadcrumb-dropdown"},[e("k-button",{attrs:{icon:"road-sign"},on:{click:function(e){return t.$refs.dropdown.toggle()}}}),e("k-dropdown-content",{ref:"dropdown",attrs:{options:t.dropdown,theme:"light"}})],1),e("ol",t._l(t.segments,(function(s,n){return e("li",{key:n},[e("k-link",{staticClass:"k-breadcrumb-link",attrs:{title:s.text||s.label,to:s.link,"aria-current":!!t.isLast(n)&&"page"}},[s.loading?e("k-loader",{staticClass:"k-breadcrumb-icon"}):s.icon?e("k-icon",{staticClass:"k-breadcrumb-icon",attrs:{type:s.icon}}):t._e(),e("span",{staticClass:"k-breadcrumb-link-text"},[t._v(" "+t._s(s.text||s.label)+" ")])],1)],1)})),0)],1)}),[],!1,null,null,null,null).exports;const ai=It({inheritAttrs:!1,props:{autofocus:Boolean,click:Function,current:[String,Boolean],disabled:Boolean,icon:String,id:[String,Number],link:String,responsive:Boolean,rel:String,role:String,target:String,tabindex:String,text:[String,Number],theme:String,tooltip:String,type:{type:String,default:"button"}},computed:{component(){return!0===this.disabled?"k-button-disabled":this.link?"k-button-link":"k-button-native"}},methods:{focus(){this.$refs.button.focus&&this.$refs.button.focus()},tab(){this.$refs.button.tab&&this.$refs.button.tab()},untab(){this.$refs.button.untab&&this.$refs.button.untab()}}},(function(){var t=this;return(0,t._self._c)(t.component,t._g(t._b({ref:"button",tag:"component"},"component",t.$props,!1),t.$listeners),[t.text?[t._v(" "+t._s(t.text)+" ")]:t._t("default")],2)}),[],!1,null,null,null,null).exports;const ui=It({inheritAttrs:!1,props:{icon:String,id:[String,Number],responsive:Boolean,theme:String,tooltip:String}},(function(){var t=this,e=t._self._c;return e("span",{staticClass:"k-button",attrs:{id:t.id,"data-disabled":!0,"data-responsive":t.responsive,"data-theme":t.theme,title:t.tooltip}},[t.icon?e("k-icon",{staticClass:"k-button-icon",attrs:{type:t.icon,alt:t.tooltip}}):t._e(),t.$slots.default?e("span",{staticClass:"k-button-text"},[t._t("default")],2):t._e()],1)}),[],!1,null,null,null,null).exports;const ci=It({props:{buttons:Array}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-button-group"},[t.$slots.default?t._t("default"):t._l(t.buttons,(function(s,n){return e("k-button",t._b({key:n},"k-button",s,!1))}))],2)}),[],!1,null,null,null,null).exports;const di=It({inheritAttrs:!1,props:{autofocus:Boolean,current:[String,Boolean],icon:String,id:[String,Number],link:String,rel:String,responsive:Boolean,role:String,target:String,tabindex:String,theme:String,tooltip:String},methods:{focus(){this.$el.focus()}}},(function(){var t=this,e=t._self._c;return e("k-link",t._g({staticClass:"k-button",attrs:{id:t.id,"aria-current":t.current,autofocus:t.autofocus,"data-theme":t.theme,"data-responsive":t.responsive,rel:t.rel,role:t.role,tabindex:t.tabindex,target:t.target,title:t.tooltip,to:t.link}},t.$listeners),[t.icon?e("k-icon",{staticClass:"k-button-icon",attrs:{type:t.icon,alt:t.tooltip}}):t._e(),t.$slots.default?e("span",{staticClass:"k-button-text"},[t._t("default")],2):t._e()],1)}),[],!1,null,null,null,null).exports,pi={mounted(){this.$el.addEventListener("keyup",this.onTab,!0),this.$el.addEventListener("blur",this.onUntab,!0)},destroyed(){this.$el.removeEventListener("keyup",this.onTab,!0),this.$el.removeEventListener("blur",this.onUntab,!0)},methods:{focus(){this.$el.focus&&this.$el.focus()},onTab(t){9===t.keyCode&&this.$el.setAttribute("data-tabbed",!0)},onUntab(){this.$el.removeAttribute("data-tabbed")},tab(){this.$el.focus(),this.$el.setAttribute("data-tabbed",!0)},untab(){this.$el.removeAttribute("data-tabbed")}}};const hi=It({mixins:[pi],inheritAttrs:!1,props:{autofocus:Boolean,click:{type:Function,default:()=>{}},current:[String,Boolean],icon:String,id:[String,Number],responsive:Boolean,role:String,tabindex:String,theme:String,tooltip:String,type:{type:String,default:"button"}}},(function(){var t=this,e=t._self._c;return e("button",t._g({staticClass:"k-button",attrs:{id:t.id,"aria-current":t.current,autofocus:t.autofocus,"data-theme":t.theme,"data-responsive":t.responsive,role:t.role,tabindex:t.tabindex,title:t.tooltip,type:t.type},on:{click:t.click}},t.$listeners),[t.icon?e("k-icon",{staticClass:"k-button-icon",attrs:{type:t.icon,alt:t.tooltip}}):t._e(),t.$slots.default?e("span",{staticClass:"k-button-text"},[t._t("default")],2):t._e()],1)}),[],!1,null,null,null,null).exports;const mi=It({},(function(){return(0,this._self._c)("span",{staticClass:"k-dropdown",on:{click:function(t){t.stopPropagation()}}},[this._t("default")],2)}),[],!1,null,null,null,null).exports;let fi=null;const gi=It({props:{align:{type:String,default:"left"},options:[Array,Function,String],theme:{type:String,default:"dark"}},data:()=>({current:-1,dropup:!1,isOpen:!1,items:[]}),methods:{async fetchOptions(t){if(!this.options)return t(this.items);"string"==typeof this.options?this.$dropdown(this.options)(t):"function"==typeof this.options?this.options(t):Array.isArray(this.options)&&t(this.options)},onOptionClick(t){"function"==typeof t.click?t.click.call(this):t.click&&this.$emit("action",t.click)},open(){this.reset(),fi&&fi!==this&&fi.close(),this.fetchOptions((t=>{this.$events.$on("keydown",this.navigate),this.$events.$on("click",this.close),this.items=t,this.isOpen=!0,fi=this,this.onOpen(),this.$emit("open")}))},reset(){this.current=-1,this.$events.$off("keydown",this.navigate),this.$events.$off("click",this.close)},close(){this.reset(),this.isOpen=fi=!1,this.$emit("close")},toggle(){this.isOpen?this.close():this.open()},focus(t=0){var e;(null==(e=this.$children[t])?void 0:e.focus)&&(this.current=t,this.$children[t].focus())},onOpen(){this.dropup=!1,this.$nextTick((()=>{if(this.$el){let t=window.innerHeight||document.body.clientHeight||document.documentElement.clientHeight,e=50,s=this.$el.getBoundingClientRect().top||0,n=this.$el.clientHeight;s+n>t-e&&n+2*ethis.$children.length-1){const t=this.$children.filter((t=>!1===t.disabled));this.current=this.$children.indexOf(t[t.length-1]);break}if(this.$children[this.current]&&!1===this.$children[this.current].disabled){this.focus(this.current);break}}break;case"Tab":for(;;){if(this.current++,this.current>this.$children.length-1){this.close(),this.$emit("leave",t.code);break}if(this.$children[this.current]&&!1===this.$children[this.current].disabled)break}}}}},(function(){var t=this,e=t._self._c;return t.isOpen?e("div",{staticClass:"k-dropdown-content",attrs:{"data-align":t.align,"data-dropup":t.dropup,"data-theme":t.theme}},[t._t("default",(function(){return[t._l(t.items,(function(s,n){return["-"===s?e("hr",{key:t._uid+"-item-"+n}):e("k-dropdown-item",t._b({key:t._uid+"-item-"+n,ref:t._uid+"-item-"+n,refInFor:!0,on:{click:function(e){return t.onOptionClick(s)}}},"k-dropdown-item",s,!1),[t._v(" "+t._s(s.text)+" ")])]}))]}))],2):t._e()}),[],!1,null,null,null,null).exports;const ki=It({inheritAttrs:!1,props:{disabled:Boolean,icon:String,image:[String,Object],link:String,target:String,theme:String,upload:String,current:[String,Boolean]},data(){return{listeners:{...this.$listeners,click:t=>{this.$parent.close(),this.$emit("click",t)}}}},methods:{focus(){this.$refs.button.focus()},tab(){this.$refs.button.tab()}}},(function(){var t=this;return(0,t._self._c)("k-button",t._g(t._b({ref:"button",staticClass:"k-dropdown-item"},"k-button",t.$props,!1),t.listeners),[t._t("default")],2)}),[],!1,null,null,null,null).exports;const bi=It({mixins:[pi],props:{disabled:Boolean,rel:String,tabindex:[String,Number],target:String,title:String,to:[String,Function]},data(){return{relAttr:"_blank"===this.target?"noreferrer noopener":this.rel,listeners:{...this.$listeners,click:this.onClick}}},computed:{href(){return"function"==typeof this.to?"":"/"!==this.to[0]||this.target?!0===this.to.includes("@")&&!1===this.to.includes("/")?"mailto:"+this.to:this.to:this.$url(this.to)}},methods:{isRoutable(t){if(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey)return!1;if(t.defaultPrevented)return!1;if(void 0!==t.button&&0!==t.button)return!1;if(this.target)return!1;if("string"==typeof this.href){if(this.href.includes("://")||this.href.startsWith("//"))return!1;if(this.href.includes("mailto:"))return!1}return!0},onClick(t){if(!0===this.disabled)return t.preventDefault(),!1;"function"==typeof this.to&&(t.preventDefault(),this.to()),this.isRoutable(t)&&(t.preventDefault(),this.$go(this.to)),this.$emit("click",t)}}},(function(){var t=this,e=t._self._c;return t.to&&!t.disabled?e("a",t._g({ref:"link",staticClass:"k-link",attrs:{href:t.href,rel:t.relAttr,tabindex:t.tabindex,target:t.target,title:t.title}},t.listeners),[t._t("default")],2):e("span",{staticClass:"k-link",attrs:{title:t.title,"data-disabled":""}},[t._t("default")],2)}),[],!1,null,null,null,null).exports;const yi=It({computed:{defaultLanguage(){return this.$languages.find((t=>!0===t.default))},language(){return this.$language},languages(){return this.$languages.filter((t=>!1===t.default))}},methods:{change(t){this.$emit("change",t),this.$go(window.location,{query:{language:t.code}})}}},(function(){var t=this,e=t._self._c;return t.languages.length?e("k-dropdown",{staticClass:"k-languages-dropdown"},[e("k-button",{attrs:{text:t.language.name,responsive:!0,icon:"globe"},on:{click:function(e){return t.$refs.languages.toggle()}}}),t.languages?e("k-dropdown-content",{ref:"languages"},[e("k-dropdown-item",{on:{click:function(e){return t.change(t.defaultLanguage)}}},[t._v(" "+t._s(t.defaultLanguage.name)+" ")]),e("hr"),t._l(t.languages,(function(s){return e("k-dropdown-item",{key:s.code,on:{click:function(e){return t.change(s)}}},[t._v(" "+t._s(s.name)+" ")])}))],2):t._e()],1):t._e()}),[],!1,null,null,null,null).exports;const vi=It({props:{align:{type:String,default:"right"},icon:{type:String,default:"dots"},options:{type:[Array,Function,String],default:()=>[]},text:{type:[Boolean,String],default:!0},theme:{type:String,default:"dark"}},computed:{hasSingleOption(){return Array.isArray(this.options)&&1===this.options.length}},methods:{onAction(t,e,s){"function"==typeof t?t.call(this):(this.$emit("action",t,e,s),this.$emit("option",t,e,s))},toggle(){this.$refs.options.toggle()}}},(function(){var t=this,e=t._self._c;return t.hasSingleOption?e("k-button",{staticClass:"k-options-dropdown-toggle",attrs:{icon:t.options[0].icon||t.icon,tooltip:t.options[0].tooltip||t.options[0].text},on:{click:function(e){return t.onAction(t.options[0].option||t.options[0].click,t.options[0],0)}}},[!0===t.text?[t._v(" "+t._s(t.options[0].text)+" ")]:!1!==t.text?[t._v(" "+t._s(t.text)+" ")]:t._e()],2):t.options.length?e("k-dropdown",{staticClass:"k-options-dropdown"},[e("k-button",{staticClass:"k-options-dropdown-toggle",attrs:{icon:t.icon,tooltip:t.$t("options")},on:{click:function(e){return t.$refs.options.toggle()}}},[t.text&&!0!==t.text?[t._v(" "+t._s(t.text)+" ")]:t._e()],2),e("k-dropdown-content",{ref:"options",staticClass:"k-options-dropdown-content",attrs:{align:t.align,options:t.options},on:{action:t.onAction}})],1):t._e()}),[],!1,null,null,null,null).exports;const $i=It({props:{align:{type:String,default:"left"},details:{type:Boolean,default:!1},dropdown:{type:Boolean,default:!0},keys:{type:Boolean,default:!1},limit:{type:Number,default:10},page:{type:Number,default:1},pageLabel:{type:String,default:()=>window.panel.$t("pagination.page")},total:{type:Number,default:0},prevLabel:{type:String,default:()=>window.panel.$t("prev")},nextLabel:{type:String,default:()=>window.panel.$t("next")},validate:{type:Function,default:()=>Promise.resolve()}},data(){return{currentPage:this.page}},computed:{show(){return this.pages>1},start(){return(this.currentPage-1)*this.limit+1},end(){let t=this.start-1+this.limit;return t>this.total?this.total:t},detailsText(){return 1===this.limit?this.start+" / ":this.start+"-"+this.end+" / "},pages(){return Math.ceil(this.total/this.limit)},hasPrev(){return this.start>1},hasNext(){return this.endthis.limit},offset(){return this.start-1}},watch:{page(t){this.currentPage=parseInt(t)}},created(){!0===this.keys&&window.addEventListener("keydown",this.navigate,!1)},destroyed(){window.removeEventListener("keydown",this.navigate,!1)},methods:{async goTo(t){try{await this.validate(t),t<1&&(t=1),t>this.pages&&(t=this.pages),this.currentPage=t,this.$refs.dropdown&&this.$refs.dropdown.close(),this.$emit("paginate",{page:this.currentPage,start:this.start,end:this.end,limit:this.limit,offset:this.offset})}catch(e){}},prev(){this.goTo(this.currentPage-1)},next(){this.goTo(this.currentPage+1)},navigate(t){switch(t.code){case"ArrowLeft":this.prev();break;case"ArrowRight":this.next()}}}},(function(){var t=this,e=t._self._c;return t.show?e("nav",{staticClass:"k-pagination",attrs:{"data-align":t.align}},[t.show?e("k-button",{attrs:{disabled:!t.hasPrev,tooltip:t.prevLabel,icon:"angle-left"},on:{click:t.prev}}):t._e(),t.details?[t.dropdown?[e("k-dropdown",[e("k-button",{staticClass:"k-pagination-details",attrs:{disabled:!t.hasPages},on:{click:function(e){return t.$refs.dropdown.toggle()}}},[t.total>1?[t._v(" "+t._s(t.detailsText)+" ")]:t._e(),t._v(" "+t._s(t.total)+" ")],2),e("k-dropdown-content",{ref:"dropdown",staticClass:"k-pagination-selector",on:{open:function(e){t.$nextTick((()=>t.$refs.page.focus()))}}},[e("div",{staticClass:"k-pagination-settings"},[e("label",{attrs:{for:"k-pagination-page"}},[e("span",[t._v(t._s(t.pageLabel)+":")]),e("select",{ref:"page",attrs:{id:"k-pagination-page"}},t._l(t.pages,(function(s){return e("option",{key:s,domProps:{selected:t.page===s,value:s}},[t._v(" "+t._s(s)+" ")])})),0)]),e("k-button",{attrs:{icon:"check"},on:{click:function(e){return t.goTo(t.$refs.page.value)}}})],1)])],1)]:[e("span",{staticClass:"k-pagination-details"},[t.total>1?[t._v(" "+t._s(t.detailsText)+" ")]:t._e(),t._v(" "+t._s(t.total)+" ")],2)]]:t._e(),t.show?e("k-button",{attrs:{disabled:!t.hasNext,tooltip:t.nextLabel,icon:"angle-right"},on:{click:t.next}}):t._e()],2):t._e()}),[],!1,null,null,null,null).exports;const _i=It({props:{prev:{type:[Boolean,Object],default:!1},next:{type:[Boolean,Object],default:!1}},computed:{buttons(){return[{...this.button(this.prev),icon:"angle-left"},{...this.button(this.next),icon:"angle-right"}]}},methods:{button:t=>t||{disabled:!0,link:"#"}}},(function(){return(0,this._self._c)("k-button-group",{staticClass:"k-prev-next",attrs:{buttons:this.buttons}})}),[],!1,null,null,null,null).exports;const xi=It({props:{types:{type:Object,default:()=>({})},type:String},data(){return{isLoading:!1,hasResults:!0,items:[],currentType:this.getType(this.type),q:null,selected:-1}},watch:{q(t,e){t!==e&&this.search(this.q)},currentType(t,e){t!==e&&this.search(this.q)},type(){this.currentType=this.getType(this.type)}},created(){this.search=dt(this.search,250),this.$events.$on("keydown.cmd.shift.f",this.open)},destroyed(){this.$events.$off("keydown.cmd.shift.f",this.open)},methods:{changeType(t){this.currentType=this.getType(t),this.$nextTick((()=>{this.$refs.input.focus()}))},close(){this.$refs.overlay.close(),this.hasResults=!0,this.items=[],this.q=null},getType(t){return this.types[t]||this.types[Object.keys(this.types)[0]]},navigate(t){this.$go(t.link),this.close()},onDown(){this.selected=0&&this.select(this.selected-1)},open(){this.$refs.overlay.open()},async search(t){this.isLoading=!0,this.$refs.types&&this.$refs.types.close();try{if(null===t||""===t)throw Error("Empty query");const e=await this.$search(this.currentType.id,t);if(!1===e)throw Error("JSON parsing failed");this.items=e.results}catch(e){this.items=[]}finally{this.select(-1),this.isLoading=!1,this.hasResults=this.items.length>0}},select(t){if(this.selected=t,this.$refs.items){const e=this.$refs.items.$el.querySelectorAll(".k-item");[...e].forEach((t=>delete t.dataset.selected)),t>=0&&(e[t].dataset.selected=!0)}}}},(function(){var t=this,e=t._self._c;return e("k-overlay",{ref:"overlay"},[e("div",{staticClass:"k-search",attrs:{role:"search"}},[e("div",{staticClass:"k-search-input"},[e("k-dropdown",{staticClass:"k-search-types"},[e("k-button",{attrs:{icon:t.currentType.icon,text:t.currentType.label},on:{click:function(e){return t.$refs.types.toggle()}}}),e("k-dropdown-content",{ref:"types"},t._l(t.types,(function(s,n){return e("k-dropdown-item",{key:n,attrs:{icon:s.icon},on:{click:function(e){return t.changeType(n)}}},[t._v(" "+t._s(s.label)+" ")])})),1)],1),e("input",{directives:[{name:"model",rawName:"v-model",value:t.q,expression:"q"}],ref:"input",attrs:{placeholder:t.$t("search")+" …","aria-label":t.$t("search"),autofocus:!0,type:"text"},domProps:{value:t.q},on:{input:[function(e){e.target.composing||(t.q=e.target.value)},function(e){t.hasResults=!0}],keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"down",40,e.key,["Down","ArrowDown"])?null:(e.preventDefault(),t.onDown.apply(null,arguments))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"up",38,e.key,["Up","ArrowUp"])?null:(e.preventDefault(),t.onUp.apply(null,arguments))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"tab",9,e.key,"Tab")?null:(e.preventDefault(),t.onTab.apply(null,arguments))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:t.onEnter.apply(null,arguments)},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"esc",27,e.key,["Esc","Escape"])?null:t.close.apply(null,arguments)}]}}),e("k-button",{staticClass:"k-search-close",attrs:{icon:t.isLoading?"loader":"cancel",tooltip:t.$t("close")},on:{click:t.close}})],1),!t.q||t.hasResults&&!t.items.length?t._e():e("div",{staticClass:"k-search-results"},[t.items.length?e("k-collection",{ref:"items",attrs:{items:t.items},on:{hover:t.onHover},nativeOn:{mouseout:function(e){return t.select(-1)}}}):t.hasResults?t._e():e("p",{staticClass:"k-search-empty"},[t._v(" "+t._s(t.$t("search.results.none"))+" ")])],1)])])}),[],!1,null,null,null,null).exports;const wi=It({props:{removable:Boolean},methods:{remove(){this.removable&&this.$emit("remove")},focus(){this.$refs.button.focus()}}},(function(){var t=this,e=t._self._c;return e("span",{ref:"button",staticClass:"k-tag",attrs:{tabindex:"0"},on:{keydown:function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"delete",[8,46],e.key,["Backspace","Delete","Del"])?null:(e.preventDefault(),t.remove.apply(null,arguments))}}},[e("span",{staticClass:"k-tag-text"},[t._t("default")],2),t.removable?e("k-icon",{staticClass:"k-tag-toggle",attrs:{type:"cancel-small"},nativeOn:{click:function(e){return t.remove.apply(null,arguments)}}}):t._e()],1)}),[],!1,null,null,null,null).exports;const Si=It({props:{breadcrumb:Array,license:Boolean,menu:Array,title:String,view:Object},computed:{notification(){return this.$store.state.notification.type&&"error"!==this.$store.state.notification.type?this.$store.state.notification:null}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-topbar"},[e("k-view",[e("div",{staticClass:"k-topbar-wrapper"},[e("k-dropdown",{staticClass:"k-topbar-menu"},[e("k-button",{staticClass:"k-topbar-button k-topbar-menu-button",attrs:{tooltip:t.$t("menu"),icon:"bars"},on:{click:function(e){return t.$refs.menu.toggle()}}},[e("k-icon",{attrs:{type:"angle-down"}})],1),e("k-dropdown-content",{ref:"menu",staticClass:"k-topbar-menu",attrs:{options:t.menu,theme:"light"}})],1),e("k-breadcrumb",{staticClass:"k-topbar-breadcrumb",attrs:{crumbs:t.breadcrumb,view:t.view}}),e("div",{staticClass:"k-topbar-signals"},[t.notification?e("k-button",{staticClass:"k-topbar-notification k-topbar-button",attrs:{text:t.notification.message,theme:"positive"},on:{click:function(e){return t.$store.dispatch("notification/close")}}}):t.license?t._e():e("k-registration"),e("k-form-indicator"),e("k-button",{staticClass:"k-topbar-button",attrs:{tooltip:t.$t("search"),icon:"search"},on:{click:function(e){return t.$refs.search.open()}}})],1)],1)]),e("k-search",{ref:"search",attrs:{type:t.$view.search||"pages",types:t.$searches}})],1)}),[],!1,null,null,null,null).exports;const Ci=It({props:{empty:String,blueprint:String,lock:[Boolean,Object],parent:String,tab:Object},computed:{content(){return this.$store.getters["content/values"]()}},methods:{exists(t){return this.$helper.isComponent(`k-${t}-section`)},meetsCondition(t){if(!t.when)return!0;let e=!0;return Object.keys(t.when).forEach((s=>{this.content[s.toLowerCase()]!==t.when[s]&&(e=!1)})),e}}},(function(){var t=this,e=t._self._c;return 0===t.tab.columns.length?e("k-box",{attrs:{html:!0,text:t.empty,theme:"info"}}):e("k-grid",{staticClass:"k-sections",attrs:{gutter:"large"}},t._l(t.tab.columns,(function(s,n){return e("k-column",{key:t.parent+"-column-"+n,attrs:{width:s.width,sticky:s.sticky}},[t._l(s.sections,(function(i,o){return[t.meetsCondition(i)?[t.exists(i.type)?e("k-"+i.type+"-section",t._b({key:t.parent+"-column-"+n+"-section-"+o+"-"+t.blueprint,tag:"component",class:"k-section k-section-name-"+i.name,attrs:{column:s.width,lock:t.lock,name:i.name,parent:t.parent,timestamp:t.$view.timestamp},on:{submit:function(e){return t.$emit("submit",e)}}},"component",i,!1)):[e("k-box",{key:t.parent+"-column-"+n+"-section-"+o,attrs:{text:t.$t("error.section.type.invalid",{type:i.type}),theme:"negative"}})]]:t._e()]}))],2)})),1)}),[],!1,null,null,null,null).exports;const Oi=It({mixins:[At],inheritAttrs:!1,data:()=>({fields:{},isLoading:!0,issue:null}),computed:{values(){return this.$store.getters["content/values"]()}},watch:{timestamp(){this.fetch()}},created(){this.input=dt(this.input,50),this.fetch()},methods:{input(t,e,s){this.$store.dispatch("content/update",[s,t[s]])},async fetch(){try{const t=await this.load();this.fields=t.fields,Object.keys(this.fields).forEach((t=>{this.fields[t].section=this.name,this.fields[t].endpoints={field:this.parent+"/fields/"+t,section:this.parent+"/sections/"+this.name,model:this.parent}}))}catch(t){this.issue=t}finally{this.isLoading=!1}},onSubmit(t){this.$events.$emit("keydown.cmd.s",t)}}},(function(){var t=this,e=t._self._c;return t.isLoading?t._e():e("section",{staticClass:"k-fields-section"},[t.issue?[e("k-headline",{staticClass:"k-fields-issue-headline"},[t._v(" Error ")]),e("k-box",{attrs:{text:t.issue.message,html:!1,theme:"negative"}})]:t._e(),e("k-form",{attrs:{fields:t.fields,validate:!0,value:t.values,disabled:t.lock&&"lock"===t.lock.state},on:{input:t.input,submit:t.onSubmit}})],2)}),[],!1,null,null,null,null).exports;const Ai=It({inheritAttrs:!1,props:{blueprint:String,column:String,parent:String,name:String,timestamp:Number},data:()=>({data:[],error:null,isLoading:!1,isProcessing:!1,options:{columns:{},empty:null,headline:null,help:null,layout:"list",link:null,max:null,min:null,size:null,sortable:null},pagination:{page:null},searchterm:null,searching:!1}),computed:{addIcon:()=>"add",buttons(){let t=[];return this.canSearch&&t.push({icon:"filter",text:this.$t("search"),click:this.onSearchToggle,responsive:!0}),this.canAdd&&t.push({icon:this.addIcon,text:this.$t("add"),click:this.onAdd}),t},canAdd:()=>!0,canDrop:()=>!1,canSearch(){return this.options.search},collection(){return{columns:this.options.columns,empty:this.emptyPropsWithSearch,layout:this.options.layout,help:this.options.help,items:this.items,pagination:this.pagination,sortable:!this.isProcessing&&this.options.sortable,size:this.options.size}},emptyProps(){return{icon:"page",text:this.$t("pages.empty")}},emptyPropsWithSearch(){return{...this.emptyProps,text:this.searching?this.$t("search.results.none"):this.options.empty||this.emptyProps.text}},items(){return this.data},isInvalid(){var t;return!((null==(t=this.searchterm)?void 0:t.length)>0)&&(!!(this.options.min&&this.data.lengththis.options.max))},paginationId(){return"kirby$pagination$"+this.parent+"/"+this.name},type:()=>"models"},watch:{searchterm:dt((function(){this.pagination.page=0,this.reload()}),200),timestamp(){this.reload()}},created(){this.load()},methods:{async load(t){t||(this.isLoading=!0),this.isProcessing=!0,null===this.pagination.page&&(this.pagination.page=localStorage.getItem(this.paginationId)||1);try{const t=await this.$api.get(this.parent+"/sections/"+this.name,{page:this.pagination.page,searchterm:this.searchterm});this.options=t.options,this.pagination=t.pagination,this.data=t.data}catch(e){this.error=e.message}finally{this.isProcessing=!1,this.isLoading=!1}},onAction(){},onAdd(){},onChange(){},onDrop(){},onSort(){},onPaginate(t){localStorage.setItem(this.paginationId,t.page),this.pagination=t,this.reload()},onSearchToggle(){this.searching=!this.searching,this.searchterm=null},onUpload(){},async reload(){await this.load(!0)},update(){this.reload(),this.$events.$emit("model.update")}}},(function(){var t=this,e=t._self._c;return!1===t.isLoading?e("section",{class:`k-models-section k-${t.type}-section`,attrs:{"data-processing":t.isProcessing}},[e("header",{staticClass:"k-section-header"},[e("k-headline",{attrs:{link:t.options.link}},[t._v(" "+t._s(t.options.headline||" ")+" "),t.options.min?e("abbr",{attrs:{title:t.$t("section.required")}},[t._v("*")]):t._e()]),e("k-button-group",{attrs:{buttons:t.buttons}})],1),t.error?e("k-box",{attrs:{theme:"negative"}},[e("k-text",{attrs:{size:"small"}},[e("strong",[t._v(" "+t._s(t.$t("error.section.notLoaded",{name:t.name}))+": ")]),t._v(" "+t._s(t.error)+" ")])],1):[e("k-dropzone",{attrs:{disabled:!t.canDrop},on:{drop:t.onDrop}},[t.searching&&t.options.search?e("k-input",{staticClass:"k-models-section-search",attrs:{autofocus:!0,placeholder:t.$t("search")+" …",type:"text"},on:{keydown:function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"esc",27,e.key,["Esc","Escape"])?null:t.onSearchToggle.apply(null,arguments)}},model:{value:t.searchterm,callback:function(e){t.searchterm=e},expression:"searchterm"}}):t._e(),e("k-collection",t._g(t._b({attrs:{"data-invalid":t.isInvalid},on:{action:t.onAction,change:t.onChange,sort:t.onSort,paginate:t.onPaginate}},"k-collection",t.collection,!1),t.canAdd?{empty:t.onAdd}:{}))],1),e("k-upload",{ref:"upload",on:{success:t.onUpload,error:t.reload}})]],2):t._e()}),[],!1,null,null,null,null).exports;const Ti=It({extends:Ai,computed:{addIcon:()=>"upload",canAdd(){return this.$permissions.files.create&&!1!==this.options.upload},canDrop(){return!1!==this.canAdd},emptyProps(){return{icon:"image",text:this.$t("files.empty")}},items(){return this.data.map((t=>(t.sortable=this.options.sortable,t.column=this.column,t.options=this.$dropdown(t.link,{query:{view:"list",update:this.options.sortable,delete:this.data.length>this.options.min}}),t.data={"data-id":t.id,"data-template":t.template},t)))},type:()=>"files",uploadProps(){return{...this.options.upload,url:this.$urls.api+"/"+this.options.upload.api}}},created(){this.load(),this.$events.$on("model.update",this.reload),this.$events.$on("file.sort",this.reload)},destroyed(){this.$events.$off("model.update",this.reload),this.$events.$off("file.sort",this.reload)},methods:{onAction(t,e){"replace"===t&&this.replace(e)},onAdd(){this.canAdd&&this.$refs.upload.open(this.uploadProps)},onDrop(t){this.canAdd&&this.$refs.upload.drop(t,this.uploadProps)},async onSort(t){if(!1===this.options.sortable)return!1;this.isProcessing=!0;try{await this.$api.patch(this.options.apiUrl+"/files/sort",{files:t.map((t=>t.id)),index:this.pagination.offset}),this.$store.dispatch("notification/success",":)"),this.$events.$emit("file.sort")}catch(e){this.reload(),this.$store.dispatch("notification/error",e.message)}finally{this.isProcessing=!1}},onUpload(){this.$events.$emit("file.create"),this.$events.$emit("model.update"),this.$store.dispatch("notification/success",":)")},replace(t){this.$refs.upload.open({url:this.$urls.api+"/"+t.link,accept:"."+t.extension+","+t.mime,multiple:!1})}}},null,null,!1,null,null,null,null).exports;const Ii=It({mixins:[At],data:()=>({headline:null,text:null,theme:null}),async created(){const t=await this.load();this.headline=t.headline,this.text=t.text,this.theme=t.theme||"info"}},(function(){var t=this,e=t._self._c;return e("section",{staticClass:"k-info-section"},[e("k-headline",{staticClass:"k-info-section-headline"},[t._v(" "+t._s(t.headline)+" ")]),e("k-box",{attrs:{theme:t.theme}},[e("k-text",{attrs:{html:t.text}})],1)],1)}),[],!1,null,null,null,null).exports;const Mi=It({extends:Ai,computed:{canAdd(){return this.options.add&&this.$permissions.pages.create},items(){return this.data.map((t=>{const e=!1!==t.permissions.changeStatus;return t.flag={status:t.status,tooltip:this.$t("page.status"),disabled:!e,click:()=>this.$dialog(t.link+"/changeStatus")},t.sortable=t.permissions.sort&&this.options.sortable,t.deletable=this.data.length>this.options.min,t.column=this.column,t.options=this.$dropdown(t.link,{query:{view:"list",delete:t.deletable,sort:t.sortable}}),t.data={"data-id":t.id,"data-status":t.status,"data-template":t.template},t}))}},created(){this.load(),this.$events.$on("page.changeStatus",this.reload),this.$events.$on("page.sort",this.reload)},destroyed(){this.$events.$off("page.changeStatus",this.reload),this.$events.$off("page.sort",this.reload)},methods:{onAdd(){this.canAdd&&this.$dialog("pages/create",{query:{parent:this.options.link||this.parent,view:this.parent,section:this.name}})},async onChange(t){let e=null;if(t.added&&(e="added"),t.moved&&(e="moved"),e){this.isProcessing=!0;const n=t[e].element,i=t[e].newIndex+1+this.pagination.offset;try{await this.$api.pages.changeStatus(n.id,"listed",i),this.$store.dispatch("notification/success",":)"),this.$events.$emit("page.sort",n)}catch(s){this.$store.dispatch("notification/error",{message:s.message,details:s.details}),await this.reload()}finally{this.isProcessing=!1}}}}},null,null,!1,null,null,null,null).exports;const Ei=It({mixins:[At],data:()=>({isLoading:!0,headline:null,reports:null,size:null}),async created(){const t=await this.load();this.isLoading=!1,this.headline=t.headline,this.reports=t.reports,this.size=t.size},methods:{}},(function(){var t=this,e=t._self._c;return!1===t.isLoading?e("section",{staticClass:"k-stats-section"},[e("header",{staticClass:"k-section-header"},[e("k-headline",[t._v(" "+t._s(t.headline)+" ")])],1),t.reports.length>0?e("k-stats",{attrs:{reports:t.reports,size:t.size}}):e("k-empty",{attrs:{icon:"chart"}},[t._v(" "+t._s(t.empty||t.$t("stats.empty")))])],1):t._e()}),[],!1,null,null,null,null).exports;t.component("k-sections",Ci),t.component("k-fields-section",Oi),t.component("k-files-section",Ti),t.component("k-info-section",Ii),t.component("k-pages-section",Mi),t.component("k-stats-section",Ei);const Li=It({props:{blueprint:String,next:Object,prev:Object,permissions:{type:Object,default:()=>({})},lock:{type:[Boolean,Object]},model:{type:Object,default:()=>({})},tab:{type:Object,default:()=>({columns:[]})},tabs:{type:Array,default:()=>[]}},computed:{id(){return this.model.link},isLocked(){var t;return"lock"===(null==(t=this.lock)?void 0:t.state)},protectedFields:()=>[]},watch:{"model.id":{handler(){this.content()},immediate:!0}},created(){this.$events.$on("model.reload",this.reload),this.$events.$on("keydown.left",this.toPrev),this.$events.$on("keydown.right",this.toNext)},destroyed(){this.$events.$off("model.reload",this.reload),this.$events.$off("keydown.left",this.toPrev),this.$events.$off("keydown.right",this.toNext)},methods:{content(){this.$store.dispatch("content/create",{id:this.id,api:this.id,content:this.model.content,ignore:this.protectedFields})},async reload(){await this.$reload(),this.content()},toPrev(t){this.prev&&"body"===t.target.localName&&this.$go(this.prev.link)},toNext(t){this.next&&"body"===t.target.localName&&this.$go(this.next.link)}}},null,null,!1,null,null,null,null).exports;const ji=It({extends:Li,computed:{avatarOptions(){return[{icon:"upload",text:this.$t("change"),click:()=>this.$refs.upload.open()},{icon:"trash",text:this.$t("delete"),click:this.deleteAvatar}]},buttons(){return[{icon:"email",text:`${this.$t("email")}: ${this.model.email}`,disabled:!this.permissions.changeEmail||this.isLocked,click:()=>this.$dialog(this.id+"/changeEmail")},{icon:"bolt",text:`${this.$t("role")}: ${this.model.role}`,disabled:!this.permissions.changeRole||this.isLocked,click:()=>this.$dialog(this.id+"/changeRole")},{icon:"globe",text:`${this.$t("language")}: ${this.model.language}`,disabled:!this.permissions.changeLanguage||this.isLocked,click:()=>this.$dialog(this.id+"/changeLanguage")}]},uploadApi(){return this.$urls.api+"/"+this.id+"/avatar"}},methods:{async deleteAvatar(){await this.$api.users.deleteAvatar(this.model.id),this.avatar=null,this.$store.dispatch("notification/success",":)"),this.$reload()},onAvatar(){this.model.avatar?this.$refs.picture.toggle():this.$refs.upload.open()},uploadedAvatar(){this.$store.dispatch("notification/success",":)"),this.$reload()}}},(function(){var t=this,e=t._self._c;return e("k-inside",{scopedSlots:t._u([{key:"footer",fn:function(){return[e("k-form-buttons",{attrs:{lock:t.lock}})]},proxy:!0}])},[e("div",{staticClass:"k-user-view",attrs:{"data-locked":t.isLocked,"data-id":t.model.id,"data-template":t.blueprint}},[e("div",{staticClass:"k-user-profile"},[e("k-view",[e("k-dropdown",[e("k-button",{staticClass:"k-user-view-image",attrs:{tooltip:t.$t("avatar"),disabled:t.isLocked},on:{click:t.onAvatar}},[t.model.avatar?e("k-image",{attrs:{cover:!0,src:t.model.avatar,ratio:"1/1"}}):e("k-icon",{attrs:{back:"gray-900",color:"gray-200",type:"user"}})],1),t.model.avatar?e("k-dropdown-content",{ref:"picture",attrs:{options:t.avatarOptions}}):t._e()],1),e("k-button-group",{attrs:{buttons:t.buttons}})],1)],1),e("k-view",[e("k-header",{attrs:{editable:t.permissions.changeName&&!t.isLocked,tab:t.tab.name,tabs:t.tabs},on:{edit:function(e){return t.$dialog(t.id+"/changeName")}},scopedSlots:t._u([{key:"left",fn:function(){return[e("k-button-group",[e("k-dropdown",{staticClass:"k-user-view-options"},[e("k-button",{attrs:{disabled:t.isLocked,text:t.$t("settings"),icon:"cog"},on:{click:function(e){return t.$refs.settings.toggle()}}}),e("k-dropdown-content",{ref:"settings",attrs:{options:t.$dropdown(t.id)}})],1),e("k-languages-dropdown")],1)]},proxy:!0},{key:"right",fn:function(){return[t.model.account?t._e():e("k-prev-next",{attrs:{prev:t.prev,next:t.next}})]},proxy:!0}])},[t.model.name&&0!==t.model.name.length?[t._v(" "+t._s(t.model.name)+" ")]:e("span",{staticClass:"k-user-name-placeholder"},[t._v(" "+t._s(t.$t("name"))+" … ")])],2),e("k-sections",{attrs:{blueprint:t.blueprint,empty:t.$t("user.blueprint",{blueprint:t.$esc(t.blueprint)}),lock:t.lock,parent:t.id,tab:t.tab}}),e("k-upload",{ref:"upload",attrs:{url:t.uploadApi,multiple:!1,accept:"image/*"},on:{success:t.uploadedAvatar}})],1)],1)])}),[],!1,null,null,null,null).exports;const Di=It({extends:ji,prevnext:!1},null,null,!1,null,null,null,null).exports;const Bi=It({props:{error:String,layout:String}},(function(){var t=this,e=t._self._c;return e(`k-${t.layout}`,{tag:"component"},[e("k-view",{staticClass:"k-error-view"},[e("div",{staticClass:"k-error-view-content"},[e("k-text",[e("p",[e("k-icon",{staticClass:"k-error-view-icon",attrs:{type:"alert"}})],1),t._t("default",(function(){return[e("p",[t._v(" "+t._s(t.error)+" ")])]}))],2)],1)])],1)}),[],!1,null,null,null,null).exports;const Pi=It({extends:Li,props:{preview:Object},methods:{action(t){if("replace"===t)this.$refs.upload.open({url:this.$urls.api+"/"+this.id,accept:"."+this.model.extension+","+this.model.mime,multiple:!1})},onUpload(){this.$store.dispatch("notification/success",":)"),this.$reload()}}},(function(){var t=this,e=t._self._c;return e("k-inside",{scopedSlots:t._u([{key:"footer",fn:function(){return[e("k-form-buttons",{attrs:{lock:t.lock}})]},proxy:!0}])},[e("div",{staticClass:"k-file-view",attrs:{"data-locked":t.isLocked,"data-id":t.model.id,"data-template":t.blueprint}},[e("k-file-preview",t._b({},"k-file-preview",t.preview,!1)),e("k-view",{staticClass:"k-file-content"},[e("k-header",{attrs:{editable:t.permissions.changeName&&!t.isLocked,tab:t.tab.name,tabs:t.tabs},on:{edit:function(e){return t.$dialog(t.id+"/changeName")}},scopedSlots:t._u([{key:"left",fn:function(){return[e("k-button-group",[e("k-button",{staticClass:"k-file-view-options",attrs:{link:t.preview.url,responsive:!0,text:t.$t("open"),icon:"open",target:"_blank"}}),e("k-dropdown",{staticClass:"k-file-view-options"},[e("k-button",{attrs:{disabled:t.isLocked,responsive:!0,text:t.$t("settings"),icon:"cog"},on:{click:function(e){return t.$refs.settings.toggle()}}}),e("k-dropdown-content",{ref:"settings",attrs:{options:t.$dropdown(t.id)},on:{action:t.action}})],1),e("k-languages-dropdown")],1)]},proxy:!0},{key:"right",fn:function(){return[e("k-prev-next",{attrs:{prev:t.prev,next:t.next}})]},proxy:!0}])},[t._v(" "+t._s(t.model.filename)+" ")]),e("k-sections",{attrs:{blueprint:t.blueprint,empty:t.$t("file.blueprint",{blueprint:t.$esc(t.blueprint)}),lock:t.lock,parent:t.id,tab:t.tab}}),e("k-upload",{ref:"upload",on:{success:t.onUpload}})],1)],1)])}),[],!1,null,null,null,null).exports;const Ni=It({props:{isInstallable:Boolean,isInstalled:Boolean,isOk:Boolean,requirements:Object,translations:Array},data(){return{user:{name:"",email:"",language:this.$translation.code,password:"",role:"admin"}}},computed:{fields(){return{email:{label:this.$t("email"),type:"email",link:!1,autofocus:!0,required:!0},password:{label:this.$t("password"),type:"password",placeholder:this.$t("password")+" …",required:!0},language:{label:this.$t("language"),type:"select",options:this.translations,icon:"globe",empty:!1,required:!0}}},isReady(){return this.isOk&&this.isInstallable},isComplete(){return this.isOk&&this.isInstalled}},methods:{async install(){try{await this.$api.system.install(this.user),await this.$reload({globals:["$system","$translation"]}),this.$store.dispatch("notification/success",this.$t("welcome")+"!")}catch(t){this.$store.dispatch("notification/error",t)}}}},(function(){var t=this,e=t._self._c;return e("k-panel",[e("k-view",{staticClass:"k-installation-view",attrs:{align:"center"}},[t.isComplete?e("k-text",[e("k-headline",[t._v(t._s(t.$t("installation.completed")))]),e("k-link",{attrs:{to:"/login"}},[t._v(" "+t._s(t.$t("login"))+" ")])],1):t.isReady?e("form",{on:{submit:function(e){return e.preventDefault(),t.install.apply(null,arguments)}}},[e("h1",{staticClass:"sr-only"},[t._v(" "+t._s(t.$t("installation"))+" ")]),e("k-fieldset",{attrs:{fields:t.fields,novalidate:!0},model:{value:t.user,callback:function(e){t.user=e},expression:"user"}}),e("k-button",{attrs:{text:t.$t("install"),type:"submit",icon:"check"}})],1):e("div",[e("k-headline",[t._v(" "+t._s(t.$t("installation.issues.headline"))+" ")]),e("ul",{staticClass:"k-installation-issues"},[!1===t.isInstallable?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.disabled"))}})],1):t._e(),!1===t.requirements.php?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.issues.php"))}})],1):t._e(),!1===t.requirements.server?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.issues.server"))}})],1):t._e(),!1===t.requirements.mbstring?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.issues.mbstring"))}})],1):t._e(),!1===t.requirements.curl?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.issues.curl"))}})],1):t._e(),!1===t.requirements.accounts?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.issues.accounts"))}})],1):t._e(),!1===t.requirements.content?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.issues.content"))}})],1):t._e(),!1===t.requirements.media?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.issues.media"))}})],1):t._e(),!1===t.requirements.sessions?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.issues.sessions"))}})],1):t._e()]),e("k-button",{attrs:{text:t.$t("retry"),icon:"refresh"},on:{click:t.$reload}})],1)],1)],1)}),[],!1,null,null,null,null).exports;const qi=It({props:{languages:{type:Array,default:()=>[]}},computed:{languagesCollection(){return this.languages.map((t=>({...t,image:{back:"black",color:"gray",icon:"globe"},link:()=>{this.$dialog(`languages/${t.id}/update`)},options:[{icon:"edit",text:this.$t("edit"),click(){this.$dialog(`languages/${t.id}/update`)}},{icon:"trash",text:this.$t("delete"),disabled:t.default&&1!==this.languages.length,click(){this.$dialog(`languages/${t.id}/delete`)}}]})))},primaryLanguage(){return this.languagesCollection.filter((t=>t.default))},secondaryLanguages(){return this.languagesCollection.filter((t=>!1===t.default))}}},(function(){var t=this,e=t._self._c;return e("k-inside",[e("k-view",{staticClass:"k-languages-view"},[e("k-header",[t._v(" "+t._s(t.$t("view.languages"))+" "),e("k-button-group",{attrs:{slot:"left"},slot:"left"},[e("k-button",{attrs:{text:t.$t("language.create"),icon:"add"},on:{click:function(e){return t.$dialog("languages/create")}}})],1)],1),e("section",{staticClass:"k-languages"},[t.languages.length>0?[e("section",{staticClass:"k-languages-view-section"},[e("header",{staticClass:"k-languages-view-section-header"},[e("k-headline",[t._v(t._s(t.$t("languages.default")))])],1),e("k-collection",{attrs:{items:t.primaryLanguage}})],1),e("section",{staticClass:"k-languages-view-section"},[e("header",{staticClass:"k-languages-view-section-header"},[e("k-headline",[t._v(t._s(t.$t("languages.secondary")))])],1),t.secondaryLanguages.length?e("k-collection",{attrs:{items:t.secondaryLanguages}}):e("k-empty",{attrs:{icon:"globe"},on:{click:function(e){return t.$dialog("languages/create")}}},[t._v(" "+t._s(t.$t("languages.secondary.empty"))+" ")])],1)]:0===t.languages.length?[e("k-empty",{attrs:{icon:"globe"},on:{click:function(e){return t.$dialog("languages/create")}}},[t._v(" "+t._s(t.$t("languages.empty"))+" ")])]:t._e()],2)],1)],1)}),[],!1,null,null,null,null).exports;const Fi=It({components:{"k-login-plugin":window.panel.plugins.login||pe},props:{methods:Array,pending:Object},computed:{form(){return this.pending.email?"code":this.$user?null:"login"}},created(){this.$store.dispatch("content/clear")}},(function(){var t=this,e=t._self._c;return e("k-panel",["login"===t.form?e("k-view",{staticClass:"k-login-view",attrs:{align:"center"}},[e("k-login-plugin",{attrs:{methods:t.methods}})],1):"code"===t.form?e("k-view",{staticClass:"k-login-code-view",attrs:{align:"center"}},[e("k-login-code",t._b({},"k-login-code",t.$props,!1))],1):t._e()],1)}),[],!1,null,null,null,null).exports;const Ri=It({extends:Li,props:{status:Object},computed:{protectedFields:()=>["title"]}},(function(){var t=this,e=t._self._c;return e("k-inside",{scopedSlots:t._u([{key:"footer",fn:function(){return[e("k-form-buttons",{attrs:{lock:t.lock}})]},proxy:!0}])},[e("k-view",{staticClass:"k-page-view",attrs:{"data-locked":t.isLocked,"data-id":t.model.id,"data-template":t.blueprint}},[e("k-header",{attrs:{editable:t.permissions.changeTitle&&!t.isLocked,tab:t.tab.name,tabs:t.tabs},on:{edit:function(e){return t.$dialog(t.id+"/changeTitle")}},scopedSlots:t._u([{key:"left",fn:function(){return[e("k-button-group",[t.permissions.preview&&t.model.previewUrl?e("k-button",{staticClass:"k-page-view-preview",attrs:{link:t.model.previewUrl,responsive:!0,text:t.$t("open"),icon:"open",target:"_blank"}}):t._e(),t.status?e("k-status-icon",{attrs:{status:t.model.status,disabled:!t.permissions.changeStatus||t.isLocked,responsive:!0,text:t.status.label},on:{click:function(e){return t.$dialog(t.id+"/changeStatus")}}}):t._e(),e("k-dropdown",{staticClass:"k-page-view-options"},[e("k-button",{attrs:{disabled:!0===t.isLocked,responsive:!0,text:t.$t("settings"),icon:"cog"},on:{click:function(e){return t.$refs.settings.toggle()}}}),e("k-dropdown-content",{ref:"settings",attrs:{options:t.$dropdown(t.id)}})],1),e("k-languages-dropdown")],1)]},proxy:!0},{key:"right",fn:function(){return[t.model.id?e("k-prev-next",{attrs:{prev:t.prev,next:t.next}}):t._e()]},proxy:!0}])},[t._v(" "+t._s(t.model.title)+" ")]),e("k-sections",{attrs:{blueprint:t.blueprint,empty:t.$t("page.blueprint",{blueprint:t.$esc(t.blueprint)}),lock:t.lock,parent:t.id,tab:t.tab}})],1)],1)}),[],!1,null,null,null,null).exports;const zi=It({props:{id:String},computed:{view(){return"k-"+this.id+"-plugin-view"}}},(function(){var t=this._self._c;return t("k-inside",[t(this.view,{tag:"component"})],1)}),[],!1,null,null,null,null).exports;const Yi=It({data:()=>({isLoading:!1,issue:"",values:{password:null,passwordConfirmation:null}}),computed:{fields(){return{password:{autofocus:!0,label:this.$t("user.changePassword.new"),icon:"key",type:"password"},passwordConfirmation:{label:this.$t("user.changePassword.new.confirm"),icon:"key",type:"password"}}}},mounted(){this.$store.dispatch("title",this.$t("view.resetPassword"))},methods:{async submit(){if(!this.values.password||this.values.password.length<8)return this.issue=this.$t("error.user.password.invalid"),!1;if(this.values.password!==this.values.passwordConfirmation)return this.issue=this.$t("error.user.password.notSame"),!1;this.isLoading=!0;try{await this.$api.users.changePassword(this.$user.id,this.values.password),this.$store.dispatch("notification/success",":)"),this.$go("/")}catch(t){this.issue=t.message}finally{this.isLoading=!1}}}},(function(){var t=this,e=t._self._c;return e("k-inside",[e("k-view",{staticClass:"k-password-reset-view",attrs:{align:"center"}},[e("k-form",{attrs:{fields:t.fields,"submit-button":t.$t("change")},on:{submit:t.submit},scopedSlots:t._u([{key:"header",fn:function(){return[e("h1",{staticClass:"sr-only"},[t._v(" "+t._s(t.$t("view.resetPassword"))+" ")]),t.issue?e("k-login-alert",{on:{click:function(e){t.issue=null}}},[t._v(" "+t._s(t.issue)+" ")]):t._e(),e("k-user-info",{attrs:{user:t.$user}})]},proxy:!0},{key:"footer",fn:function(){return[e("div",{staticClass:"k-login-buttons"},[e("k-button",{staticClass:"k-login-button",attrs:{icon:"check",type:"submit"}},[t._v(" "+t._s(t.$t("change"))+" "),t.isLoading?[t._v(" … ")]:t._e()],2)],1)]},proxy:!0}]),model:{value:t.values,callback:function(e){t.values=e},expression:"values"}})],1)],1)}),[],!1,null,null,null,null).exports;const Hi=It({extends:Li,computed:{protectedFields:()=>["title"]}},(function(){var t=this,e=t._self._c;return e("k-inside",{scopedSlots:t._u([{key:"footer",fn:function(){return[e("k-form-buttons",{attrs:{lock:t.lock}})]},proxy:!0}])},[e("k-view",{staticClass:"k-site-view",attrs:{"data-locked":t.isLocked,"data-id":"/","data-template":"site"}},[e("k-header",{attrs:{editable:t.permissions.changeTitle&&!t.isLocked,tabs:t.tabs,tab:t.tab.name},on:{edit:function(e){return t.$dialog("site/changeTitle")}},scopedSlots:t._u([{key:"left",fn:function(){return[e("k-button-group",[e("k-button",{staticClass:"k-site-view-preview",attrs:{link:t.model.previewUrl,responsive:!0,text:t.$t("open"),icon:"open",target:"_blank"}}),e("k-languages-dropdown")],1)]},proxy:!0}])},[t._v(" "+t._s(t.model.title)+" ")]),e("k-sections",{attrs:{blueprint:t.blueprint,empty:t.$t("site.blueprint"),lock:t.lock,tab:t.tab,parent:"site"},on:{submit:function(e){return t.$emit("submit",e)}}})],1)],1)}),[],!1,null,null,null,null).exports;const Ui=It({props:{debug:Boolean,license:String,php:String,plugins:Array,server:String,https:Boolean,urls:Object,version:String},data:()=>({security:[]}),computed:{environment(){return[{label:this.$t("license"),value:this.license?"Kirby 3":this.$t("license.unregistered.label"),theme:this.license?null:"negative",click:this.license?()=>this.$dialog("license"):()=>this.$dialog("registration")},{label:this.$t("version"),value:this.version,link:"https://github.com/getkirby/kirby/releases/tag/"+this.version},{label:"PHP",value:this.php},{label:this.$t("server"),value:this.server||"?"}]}},async created(){console.info("Running system health checks for the Panel system view; failed requests in the following console output are expected behavior.");let t=(Promise.allSettled||Promise.all).bind(Promise);await t([this.check("content"),this.check("debug"),this.check("git"),this.check("https"),this.check("kirby"),this.check("site")]),console.info("System health checks ended.")},methods:{async check(t){switch(t){case"debug":!0===this.debug&&this.securityIssue(t);break;case"https":!0!==this.https&&this.securityIssue(t);break;default:{const e=this.urls[t];if(!e)return!1;!0===await this.isAccessible(e)&&this.securityIssue(t)}}},securityIssue(t){this.security.push({image:{back:"var(--color-red-200)",icon:"alert",color:"var(--color-red)"},id:t,text:this.$t("system.issues."+t),link:"https://getkirby.com/security/"+t})},isAccessible:async t=>(await fetch(t,{cache:"no-store"})).status<400,retry(){this.$go(window.location.href)}}},(function(){var t=this,e=t._self._c;return e("k-inside",[e("k-view",{staticClass:"k-system-view"},[e("k-header",[t._v(" "+t._s(t.$t("view.system"))+" ")]),e("section",{staticClass:"k-system-view-section"},[e("header",{staticClass:"k-system-view-section-header"},[e("k-headline",[t._v(t._s(t.$t("environment")))])],1),e("k-stats",{staticClass:"k-system-info",attrs:{reports:t.environment,size:"medium"}})],1),t.security.length?e("section",{staticClass:"k-system-view-section"},[e("header",{staticClass:"k-system-view-section-header"},[e("k-headline",[t._v(t._s(t.$t("security")))]),e("k-button",{attrs:{tooltip:t.$t("retry"),icon:"refresh"},on:{click:t.retry}})],1),e("k-items",{attrs:{items:t.security}})],1):t._e(),t.plugins.length?e("section",{staticClass:"k-system-view-section"},[e("header",{staticClass:"k-system-view-section-header"},[e("k-headline",{attrs:{link:"https://getkirby.com/plugins"}},[t._v(" "+t._s(t.$t("plugins"))+" ")])],1),e("k-table",{attrs:{index:!1,columns:{name:{label:t.$t("name"),type:"url",mobile:!0},author:{label:t.$t("author")},license:{label:t.$t("license")},version:{label:t.$t("version"),width:"8rem",mobile:!0}},rows:t.plugins}})],1):t._e()],1)],1)}),[],!1,null,null,null,null).exports;const Ki=It({props:{role:Object,roles:Array,search:String,title:String,users:Object},computed:{items(){return this.users.data.map((t=>(t.options=this.$dropdown(t.link),t)))}},methods:{paginate(t){this.$reload({query:{page:t.page}})}}},(function(){var t=this,e=t._self._c;return e("k-inside",[e("k-view",{staticClass:"k-users-view"},[e("k-header",{scopedSlots:t._u([{key:"left",fn:function(){return[e("k-button-group",{attrs:{buttons:[{disabled:!1===t.$permissions.users.create,text:t.$t("user.create"),icon:"add",click:()=>t.$dialog("users/create")}]}})]},proxy:!0},{key:"right",fn:function(){return[e("k-button-group",[e("k-dropdown",[e("k-button",{attrs:{responsive:!0,text:`${t.$t("role")}: ${t.role?t.role.title:t.$t("role.all")}`,icon:"funnel"},on:{click:function(e){return t.$refs.roles.toggle()}}}),e("k-dropdown-content",{ref:"roles",attrs:{align:"right"}},[e("k-dropdown-item",{attrs:{icon:"bolt",link:"/users"}},[t._v(" "+t._s(t.$t("role.all"))+" ")]),e("hr"),t._l(t.roles,(function(s){return e("k-dropdown-item",{key:s.id,attrs:{link:"/users/?role="+s.id,icon:"bolt"}},[t._v(" "+t._s(s.title)+" ")])}))],2)],1)],1)]},proxy:!0}])},[t._v(" "+t._s(t.$t("view.users"))+" ")]),t.users.data.length>0?[e("k-collection",{attrs:{items:t.items,pagination:t.users.pagination},on:{paginate:t.paginate}})]:0===t.users.pagination.total?[e("k-empty",{attrs:{icon:"users"}},[t._v(" "+t._s(t.$t("role.empty"))+" ")])]:t._e()],2)],1)}),[],!1,null,null,null,null).exports;const Gi=It({computed:{placeholder(){return this.field("code",{}).placeholder},languages(){return this.field("language",{options:[]}).options}},methods:{focus(){this.$refs.code.focus()}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-block-type-code-editor"},[e("k-input",{ref:"code",attrs:{buttons:!1,placeholder:t.placeholder,spellcheck:!1,value:t.content.code,type:"textarea"},on:{input:function(e){return t.update({code:e})}}}),t.languages.length?e("div",{staticClass:"k-block-type-code-editor-language"},[e("k-icon",{attrs:{type:"code"}}),e("k-input",{ref:"language",attrs:{empty:!1,options:t.languages,value:t.content.language,type:"select"},on:{input:function(e){return t.update({language:e})}}})],1):t._e()],1)}),[],!1,null,null,null,null).exports,Ji=Object.freeze(Object.defineProperty({__proto__:null,default:Gi},Symbol.toStringTag,{value:"Module"}));const Vi=It({},(function(){var t=this;return(0,t._self._c)("k-block-title",{attrs:{content:t.content,fieldset:t.fieldset},on:{dblclick:function(e){return t.$emit("open")}}})}),[],!1,null,null,null,null).exports,Wi=Object.freeze(Object.defineProperty({__proto__:null,default:Vi},Symbol.toStringTag,{value:"Module"}));const Xi=It({},(function(){var t=this,e=t._self._c;return e("ul",{on:{dblclick:t.open}},[0===t.content.images.length?[e("li"),e("li"),e("li"),e("li"),e("li")]:t._l(t.content.images,(function(t){return e("li",{key:t.id},[e("img",{attrs:{src:t.url,srcset:t.image.srcset,alt:t.alt}})])}))],2)}),[],!1,null,null,null,null).exports,Zi=Object.freeze(Object.defineProperty({__proto__:null,default:Xi},Symbol.toStringTag,{value:"Module"}));const Qi=It({computed:{textField(){return this.field("text",{marks:!0})}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-block-type-heading-input",attrs:{"data-level":t.content.level}},[e("k-writer",{ref:"input",attrs:{inline:!0,marks:t.textField.marks,placeholder:t.textField.placeholder,value:t.content.text},on:{input:function(e){return t.update({text:e})}}})],1)}),[],!1,null,null,null,null).exports,to=Object.freeze(Object.defineProperty({__proto__:null,default:Qi},Symbol.toStringTag,{value:"Module"}));const eo=It({computed:{captionMarks(){return this.field("caption",{marks:!0}).marks},crop(){return this.content.crop||!1},src(){var t;return"web"===this.content.location?this.content.src:!!(null==(t=this.content.image[0])?void 0:t.url)&&this.content.image[0].url},ratio(){return this.content.ratio||!1}}},(function(){var t=this,e=t._self._c;return e("k-block-figure",{attrs:{caption:t.content.caption,"caption-marks":t.captionMarks,"empty-text":t.$t("field.blocks.image.placeholder")+" …","is-empty":!t.src,"empty-icon":"image"},on:{open:t.open,update:t.update}},[t.src?[t.ratio?e("k-aspect-ratio",{attrs:{ratio:t.ratio,cover:t.crop}},[e("img",{attrs:{alt:t.content.alt,src:t.src}})]):e("img",{staticClass:"k-block-type-image-auto",attrs:{alt:t.content.alt,src:t.src}})]:t._e()],2)}),[],!1,null,null,null,null).exports,so=Object.freeze(Object.defineProperty({__proto__:null,default:eo},Symbol.toStringTag,{value:"Module"}));const no=It({},(function(){return this._self._c,this._m(0)}),[function(){var t=this._self._c;return t("div",[t("hr")])}],!1,null,null,null,null).exports,io=Object.freeze(Object.defineProperty({__proto__:null,default:no},Symbol.toStringTag,{value:"Module"}));const oo=It({computed:{marks(){return this.field("text",{}).marks}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this;return(0,t._self._c)("k-input",{ref:"input",staticClass:"k-block-type-list-input",attrs:{marks:t.marks,value:t.content.text,type:"list"},on:{input:function(e){return t.update({text:e})}}})}),[],!1,null,null,null,null).exports,ro=Object.freeze(Object.defineProperty({__proto__:null,default:oo},Symbol.toStringTag,{value:"Module"}));const lo=It({computed:{placeholder(){return this.field("text",{}).placeholder}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this;return(0,t._self._c)("k-input",{ref:"input",staticClass:"k-block-type-markdown-input",attrs:{buttons:!1,placeholder:t.placeholder,spellcheck:!1,value:t.content.text,type:"textarea"},on:{input:function(e){return t.update({text:e})}}})}),[],!1,null,null,null,null).exports,ao=Object.freeze(Object.defineProperty({__proto__:null,default:lo},Symbol.toStringTag,{value:"Module"}));const uo=It({computed:{citationField(){return this.field("citation",{})},textField(){return this.field("text",{})}},methods:{focus(){this.$refs.text.focus()}}},(function(){var t,e,s=this,n=s._self._c;return n("div",{staticClass:"k-block-type-quote-editor"},[n("k-writer",{ref:"text",staticClass:"k-block-type-quote-text",attrs:{inline:null!=(t=s.textField.inline)&&t,marks:s.textField.marks,placeholder:s.textField.placeholder,value:s.content.text},on:{input:function(t){return s.update({text:t})}}}),n("k-writer",{ref:"citation",staticClass:"k-block-type-quote-citation",attrs:{inline:null==(e=s.citationField.inline)||e,marks:s.citationField.marks,placeholder:s.citationField.placeholder,value:s.content.citation},on:{input:function(t){return s.update({citation:t})}}})],1)}),[],!1,null,null,null,null).exports,co=Object.freeze(Object.defineProperty({__proto__:null,default:uo},Symbol.toStringTag,{value:"Module"}));const po=It({inheritAttrs:!1,computed:{columns(){return this.table.columns||this.fields},fields(){return this.table.fields||{}},rows(){return this.content.rows||[]},table(){let t=null;for(const e of Object.values(this.fieldset.tabs))e.fields.rows&&(t=e.fields.rows);return t||{}}}},(function(){var t=this;return(0,t._self._c)("k-table",{staticClass:"k-block-type-table-preview",attrs:{columns:t.columns,empty:t.$t("field.structure.empty"),rows:t.rows},nativeOn:{dblclick:function(e){return t.open.apply(null,arguments)}}})}),[],!1,null,null,null,null).exports,ho=Object.freeze(Object.defineProperty({__proto__:null,default:po},Symbol.toStringTag,{value:"Module"}));const mo=It({computed:{component(){const t="k-"+this.textField.type+"-input";return this.$helper.isComponent(t)?t:"k-writer"},textField(){return this.field("text",{})}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this;return(0,t._self._c)(t.component,t._b({ref:"input",tag:"component",staticClass:"k-block-type-text-input",attrs:{value:t.content.text},on:{input:function(e){return t.update({text:e})}}},"component",t.textField,!1))}),[],!1,null,null,null,null).exports,fo=Object.freeze(Object.defineProperty({__proto__:null,default:mo},Symbol.toStringTag,{value:"Module"}));const go=It({computed:{captionMarks(){return this.field("caption",{marks:!0}).marks},video(){return this.$helper.embed.video(this.content.url,!0)}}},(function(){var t=this,e=t._self._c;return e("k-block-figure",{attrs:{caption:t.content.caption,"caption-marks":t.captionMarks,"empty-text":t.$t("field.blocks.video.placeholder")+" …","is-empty":!t.video,"empty-icon":"video"},on:{open:t.open,update:t.update}},[e("k-aspect-ratio",{attrs:{ratio:"16/9"}},[t.video?e("iframe",{attrs:{src:t.video,referrerpolicy:"strict-origin-when-cross-origin"}}):t._e()])],1)}),[],!1,null,null,null,null).exports,ko=Object.freeze(Object.defineProperty({__proto__:null,default:go},Symbol.toStringTag,{value:"Module"}));const bo=It({inheritAttrs:!1,props:{attrs:[Array,Object],content:[Array,Object],endpoints:Object,fieldset:Object,id:String,isBatched:Boolean,isFull:Boolean,isHidden:Boolean,isLastInBatch:Boolean,isSelected:Boolean,name:String,next:Object,prev:Object,type:String},data:()=>({skipFocus:!1}),computed:{className(){let t=["k-block-type-"+this.type];return this.fieldset.preview!==this.type&&t.push("k-block-type-"+this.fieldset.preview),!1===this.wysiwyg&&t.push("k-block-type-default"),t},customComponent(){return this.wysiwyg?this.wysiwygComponent:"k-block-type-default"},isEditable(){return!1!==this.fieldset.editable},listeners(){return{...this.$listeners,confirmToRemove:this.confirmToRemove,open:this.open}},tabs(){let t=this.fieldset.tabs;return Object.entries(t).forEach((([e,s])=>{Object.entries(s.fields).forEach((([s])=>{t[e].fields[s].section=this.name,t[e].fields[s].endpoints={field:this.endpoints.field+"/fieldsets/"+this.type+"/fields/"+s,section:this.endpoints.section,model:this.endpoints.model}}))})),t},wysiwyg(){return!1!==this.wysiwygComponent},wysiwygComponent(){if(!1===this.fieldset.preview)return!1;let t;return this.fieldset.preview&&(t="k-block-type-"+this.fieldset.preview,this.$helper.isComponent(t))?t:(t="k-block-type-"+this.type,!!this.$helper.isComponent(t)&&t)}},methods:{close(){this.$refs.drawer.close()},confirmToRemove(){this.$refs.removeDialog.open()},focus(){!0!==this.skipFocus&&("function"==typeof this.$refs.editor.focus?this.$refs.editor.focus():this.$refs.container.focus())},onFocusIn(t){var e,s;(null==(s=null==(e=this.$refs.options)?void 0:e.$el)?void 0:s.contains(t.target))||this.$emit("focus",t)},goTo(t){t&&(this.skipFocus=!0,this.close(),this.$nextTick((()=>{t.$refs.container.focus(),t.open(),this.skipFocus=!1})))},open(){var t;null==(t=this.$refs.drawer)||t.open()},remove(){this.$refs.removeDialog.close(),this.$emit("remove",this.id)}}},(function(){var t=this,e=t._self._c;return e("div",{ref:"container",staticClass:"k-block-container",class:"k-block-container-type-"+t.type,attrs:{"data-batched":t.isBatched,"data-disabled":t.fieldset.disabled,"data-hidden":t.isHidden,"data-id":t.id,"data-last-in-batch":t.isLastInBatch,"data-selected":t.isSelected,"data-translate":t.fieldset.translate,tabindex:"0"},on:{keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"down",40,e.key,["Down","ArrowDown"])?null:e.ctrlKey&&e.shiftKey?(e.preventDefault(),t.$emit("sortDown")):null},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"up",38,e.key,["Up","ArrowUp"])?null:e.ctrlKey&&e.shiftKey?(e.preventDefault(),t.$emit("sortUp")):null}],focus:function(e){return t.$emit("focus")},focusin:t.onFocusIn}},[e("div",{staticClass:"k-block",class:t.className},[e(t.customComponent,t._g(t._b({ref:"editor",tag:"component"},"component",t.$props,!1),t.listeners))],1),e("k-block-options",t._g({ref:"options",attrs:{"is-batched":t.isBatched,"is-editable":t.isEditable,"is-full":t.isFull,"is-hidden":t.isHidden}},t.listeners)),t.isEditable&&!t.isBatched?e("k-form-drawer",{ref:"drawer",staticClass:"k-block-drawer",attrs:{id:t.id,icon:t.fieldset.icon||"box",tabs:t.tabs,title:t.fieldset.name,value:t.content},on:{close:function(e){return t.focus()},input:function(e){return t.$emit("update",e)}},scopedSlots:t._u([{key:"options",fn:function(){return[t.isHidden?e("k-button",{staticClass:"k-drawer-option",attrs:{icon:"hidden"},on:{click:function(e){return t.$emit("show")}}}):t._e(),e("k-button",{staticClass:"k-drawer-option",attrs:{disabled:!t.prev,icon:"angle-left"},on:{click:function(e){return e.preventDefault(),e.stopPropagation(),t.goTo(t.prev)}}}),e("k-button",{staticClass:"k-drawer-option",attrs:{disabled:!t.next,icon:"angle-right"},on:{click:function(e){return e.preventDefault(),e.stopPropagation(),t.goTo(t.next)}}}),e("k-button",{staticClass:"k-drawer-option",attrs:{icon:"trash"},on:{click:function(e){return e.preventDefault(),e.stopPropagation(),t.confirmToRemove.apply(null,arguments)}}})]},proxy:!0}],null,!1,2211169536)}):t._e(),e("k-remove-dialog",{ref:"removeDialog",attrs:{text:t.$t("field.blocks.delete.confirm")},on:{submit:t.remove}})],1)}),[],!1,null,null,null,null).exports;const yo=It({components:{"k-block-pasteboard":It({inheritAttrs:!1,computed:{shortcut(){return this.$helper.keyboard.metaKey()+"+v"}},methods:{close(){this.$refs.dialog.close()},open(){this.$refs.dialog.open()},onPaste(t){this.$emit("paste",t),this.close()}}},(function(){var t=this,e=t._self._c;return e("k-dialog",{ref:"dialog",staticClass:"k-block-importer",attrs:{"cancel-button":!1,"submit-button":!1,size:"large"}},[e("label",{attrs:{for:"pasteboard"},domProps:{innerHTML:t._s(t.$t("field.blocks.fieldsets.paste",{shortcut:t.shortcut}))}}),e("textarea",{attrs:{id:"pasteboard"},on:{paste:function(e){return e.preventDefault(),t.onPaste.apply(null,arguments)}}})])}),[],!1,null,null,null,null).exports},inheritAttrs:!1,props:{autofocus:Boolean,empty:String,endpoints:Object,fieldsets:Object,fieldsetGroups:Object,group:String,max:{type:Number,default:null},value:{type:Array,default:()=>[]}},data(){return{isMultiSelectKey:!1,batch:[],blocks:this.value,current:null,isFocussed:!1}},computed:{draggableOptions(){return{id:this._uid,handle:".k-sort-handle",list:this.blocks,move:this.move,delay:10,data:{fieldsets:this.fieldsets,isFull:this.isFull},options:{group:this.group}}},hasFieldsets(){return Object.keys(this.fieldsets).length},isEditing(){return this.$store.state.dialog||this.$store.state.drawers.open.length>0},isEmpty(){return 0===this.blocks.length},isFull(){return null!==this.max&&this.blocks.length>=this.max},selected(){return this.current},selectedOrBatched(){return this.batch.length>0?this.batch:this.selected?[this.selected]:[]}},watch:{value(){this.blocks=this.value}},created(){this.$events.$on("blur",this.onBlur),this.$events.$on("copy",this.copy),this.$events.$on("focus",this.onOutsideFocus),this.$events.$on("keydown",this.onKey),this.$events.$on("keyup",this.onKey),this.$events.$on("paste",this.onPaste)},destroyed(){this.$events.$off("blur",this.onBlur),this.$events.$off("copy",this.copy),this.$events.$off("focus",this.onOutsideFocus),this.$events.$off("keydown",this.onKey),this.$events.$off("keyup",this.onKey),this.$events.$off("paste",this.onPaste)},mounted(){!0===this.$props.autofocus&&this.focus()},methods:{append(t,e){if("string"!=typeof t){if(Array.isArray(t)){let s=this.$helper.clone(t).map((t=>(t.id=this.$helper.uuid(),t)));const n=Object.keys(this.fieldsets);if(s=s.filter((t=>n.includes(t.type))),this.max){const t=this.max-this.blocks.length;s=s.slice(0,t)}this.blocks.splice(e,0,...s),this.save()}}else this.add(t,e)},async add(t="text",e){const s=await this.$api.get(this.endpoints.field+"/fieldsets/"+t);this.blocks.splice(e,0,s),this.save(),this.$nextTick((()=>{this.focusOrOpen(s)}))},addToBatch(t){null!==this.selected&&!1===this.batch.includes(this.selected)&&(this.batch.push(this.selected),this.current=null),!1===this.batch.includes(t.id)&&this.batch.push(t.id)},choose(t){if(1===Object.keys(this.fieldsets).length){const e=Object.values(this.fieldsets)[0].type;this.add(e,t)}else this.$refs.selector.open(t)},chooseToConvert(t){this.$refs.selector.open(t,{disabled:[t.type],headline:this.$t("field.blocks.changeType"),event:"convert"})},click(t){this.$emit("click",t)},confirmToRemoveAll(){this.$refs.removeAll.open()},confirmToRemoveSelected(){this.$refs.removeSelected.open()},copy(t){if(!0===this.isEditing)return!1;if(0===this.blocks.length)return!1;if(0===this.selectedOrBatched.length)return!1;if(!0===this.isInputEvent(t))return!1;let e=[];if(this.blocks.forEach((t=>{this.selectedOrBatched.includes(t.id)&&e.push(t)})),0===e.length)return!1;this.$helper.clipboard.write(e,t),t instanceof ClipboardEvent==!1&&(this.batch=this.selectedOrBatched),this.$store.dispatch("notification/success",`${e.length} copied!`)},copyAll(){this.selectAll(),this.copy(),this.deselectAll()},async convert(t,e){var s;const n=this.findIndex(e.id);if(-1===n)return!1;const i=t=>{var e;let s={};for(const n of Object.values(null!=(e=null==t?void 0:t.tabs)?e:{}))s={...s,...n.fields};return s},o=this.blocks[n],r=await this.$api.get(this.endpoints.field+"/fieldsets/"+t),l=this.fieldsets[o.type],a=this.fieldsets[t];if(!a)return!1;let u=r.content;const c=i(a),d=i(l);for(const[p,h]of Object.entries(c)){const t=d[p];(null==t?void 0:t.type)===h.type&&(null==(s=null==o?void 0:o.content)?void 0:s[p])&&(u[p]=o.content[p])}this.blocks[n]={...r,id:o.id,content:u},this.save()},deselectAll(){this.batch=[],this.current=null},async duplicate(t,e){const s={...this.$helper.clone(t),id:this.$helper.uuid()};this.blocks.splice(e+1,0,s),this.save()},fieldset(t){return this.fieldsets[t.type]||{icon:"box",name:t.type,tabs:{content:{fields:{}}},type:t.type}},find(t){return this.blocks.find((e=>e.id===t))},findIndex(t){return this.blocks.findIndex((e=>e.id===t))},focus(t){(null==t?void 0:t.id)&&this.$refs["block-"+t.id]?this.$refs["block-"+t.id][0].focus():this.blocks[0]&&this.focus(this.blocks[0])},focusOrOpen(t){this.fieldsets[t.type].wysiwyg?this.focus(t):this.open(t)},hide(t){this.$set(t,"isHidden",!0),this.save()},isBatched(t){return this.batch.includes(t.id)},isInputEvent(){const t=document.querySelector(":focus");return t&&t.matches("input, textarea, [contenteditable], .k-writer")},isLastInBatch(t){const[e]=this.batch.slice(-1);return e&&t.id===e},isOnlyInstance:()=>1===document.querySelectorAll(".k-blocks").length,isSelected(t){return this.selected&&this.selected===t.id},move(t){if(t.from!==t.to){const e=t.draggedContext.element,s=t.relatedContext.component.componentData||t.relatedContext.component.$parent.componentData;if(!1===Object.keys(s.fieldsets).includes(e.type))return!1;if(!0===s.isFull)return!1}return!0},onBlur(){0===this.batch.length&&(this.isMultiSelectKey=!1)},onKey(t){this.isMultiSelectKey=t.metaKey||t.ctrlKey||t.altKey},onOutsideFocus(t){if("function"==typeof t.target.closest&&t.target.closest(".k-dialog"))return;const e=document.querySelector(".k-overlay:last-of-type");if(!1===this.$el.contains(t.target)&&(!e||!1===e.contains(t.target)))return this.select(null);if(e){const e=this.$el.closest(".k-layout-column");if(!1===(null==e?void 0:e.contains(t.target)))return this.select(null)}},onPaste(t){var e;return!0!==this.isInputEvent(t)&&(!0===this.isEditing?!0===(null==(e=this.$refs.selector)?void 0:e.isOpen())&&this.paste(t):(0!==this.selectedOrBatched.length||!0===this.isOnlyInstance())&&this.paste(t))},open(t){this.$refs["block-"+t.id]&&this.$refs["block-"+t.id][0].open()},async paste(t){const e=this.$helper.clipboard.read(t),s=await this.$api.post(this.endpoints.field+"/paste",{html:e});let n=this.selectedOrBatched[this.selectedOrBatched.length-1],i=this.findIndex(n);-1===i&&(i=this.blocks.length),this.append(s,i+1)},pasteboard(){this.$refs.pasteboard.open()},prevNext(t){if(this.blocks[t]){let e=this.blocks[t];if(this.$refs["block-"+e.id])return this.$refs["block-"+e.id][0]}},remove(t){var e;const s=this.findIndex(t.id);-1!==s&&((null==(e=this.selected)?void 0:e.id)===t.id&&this.select(null),this.$delete(this.blocks,s),this.save())},removeAll(){this.batch=[],this.blocks=[],this.save(),this.$refs.removeAll.close()},removeSelected(){this.batch.forEach((t=>{const e=this.findIndex(t);-1!==e&&this.$delete(this.blocks,e)})),this.deselectAll(),this.save(),this.$refs.removeSelected.close()},save(){this.$emit("input",this.blocks)},select(t,e=null){if(e&&this.isMultiSelectKey&&this.onKey(e),t&&this.isMultiSelectKey)return this.addToBatch(t),void(this.current=null);this.batch=[],this.current=t?t.id:null},selectAll(){this.batch=Object.values(this.blocks).map((t=>t.id))},show(t){this.$set(t,"isHidden",!1),this.save()},sort(t,e,s){if(s<0)return;let n=this.$helper.clone(this.blocks);n.splice(e,1),n.splice(s,0,t),this.blocks=n,this.save(),this.$nextTick((()=>{this.focus(t)}))},update(t,e){const s=this.findIndex(t.id);-1!==s&&Object.entries(e).forEach((([t,e])=>{this.$set(this.blocks[s].content,t,e)})),this.save()}}},(function(){var t=this,e=t._self._c;return e("div",{ref:"wrapper",staticClass:"k-blocks",attrs:{"data-empty":0===t.blocks.length,"data-multi-select-key":t.isMultiSelectKey},on:{focusin:function(e){t.focussed=!0},focusout:function(e){t.focussed=!1}}},[t.hasFieldsets?[e("k-draggable",t._b({staticClass:"k-blocks-list",on:{sort:t.save},scopedSlots:t._u([{key:"footer",fn:function(){return[e("k-empty",{staticClass:"k-blocks-empty",attrs:{icon:"box"},on:{click:function(e){return t.choose(t.blocks.length)}}},[t._v(" "+t._s(t.empty||t.$t("field.blocks.empty"))+" ")])]},proxy:!0}],null,!1,2413899928)},"k-draggable",t.draggableOptions,!1),t._l(t.blocks,(function(s,n){return e("k-block",t._b({key:s.id,ref:"block-"+s.id,refInFor:!0,attrs:{endpoints:t.endpoints,fieldset:t.fieldset(s),"is-batched":t.isBatched(s),"is-last-in-batch":t.isLastInBatch(s),"is-full":t.isFull,"is-hidden":!0===s.isHidden,"is-selected":t.isSelected(s),next:t.prevNext(n+1),prev:t.prevNext(n-1)},on:{append:function(e){return t.append(e,n+1)},blur:function(e){return t.select(null)},choose:function(e){return t.choose(e)},chooseToAppend:function(e){return t.choose(n+1)},chooseToConvert:function(e){return t.chooseToConvert(s)},chooseToPrepend:function(e){return t.choose(n)},copy:function(e){return t.copy()},confirmToRemoveSelected:t.confirmToRemoveSelected,duplicate:function(e){return t.duplicate(s,n)},focus:function(e){return t.select(s)},hide:function(e){return t.hide(s)},paste:function(e){return t.pasteboard()},prepend:function(e){return t.add(e,n)},remove:function(e){return t.remove(s)},sortDown:function(e){return t.sort(s,n,n+1)},sortUp:function(e){return t.sort(s,n,n-1)},show:function(e){return t.show(s)},update:function(e){return t.update(s,e)}},nativeOn:{click:function(e){return e.stopPropagation(),t.select(s,e)}}},"k-block",s,!1))})),1),e("k-block-selector",{ref:"selector",attrs:{fieldsets:t.fieldsets,"fieldset-groups":t.fieldsetGroups},on:{add:t.add,convert:t.convert,paste:function(e){return t.paste(e)}}}),e("k-remove-dialog",{ref:"removeAll",attrs:{text:t.$t("field.blocks.delete.confirm.all")},on:{submit:t.removeAll}}),e("k-remove-dialog",{ref:"removeSelected",attrs:{text:t.$t("field.blocks.delete.confirm.selected")},on:{submit:t.removeSelected}}),e("k-block-pasteboard",{ref:"pasteboard",on:{paste:function(e){return t.paste(e)}}})]:[e("k-box",{attrs:{theme:"info"}},[t._v(" No fieldsets yet ")])]],2)}),[],!1,null,null,null,null).exports;const vo=It({inheritAttrs:!1,props:{caption:String,captionMarks:[Boolean,Array],cover:{type:Boolean,default:!0},isEmpty:Boolean,emptyIcon:String,emptyText:String,ratio:String},computed:{ratioPadding(){return this.$helper.ratio(this.ratio||"16/9")}}},(function(){var t=this,e=t._self._c;return e("figure",{staticClass:"k-block-figure"},[t.isEmpty?e("k-button",{staticClass:"k-block-figure-empty",attrs:{icon:t.emptyIcon,text:t.emptyText},on:{click:function(e){return t.$emit("open")}}}):e("span",{staticClass:"k-block-figure-container",on:{dblclick:function(e){return t.$emit("open")}}},[t._t("default")],2),t.caption?e("figcaption",[e("k-writer",{attrs:{inline:!0,marks:t.captionMarks,value:t.caption},on:{input:function(e){return t.$emit("update",{caption:e})}}})],1):t._e()],1)}),[],!1,null,null,null,null).exports;const $o=It({props:{isBatched:Boolean,isEditable:Boolean,isFull:Boolean,isHidden:Boolean},methods:{open(){this.$refs.options.open()}}},(function(){var t=this,e=t._self._c;return e("k-dropdown",{staticClass:"k-block-options"},[t.isBatched?[e("k-button",{staticClass:"k-block-options-button",attrs:{tooltip:t.$t("copy"),icon:"template"},on:{click:function(e){return e.preventDefault(),t.$emit("copy")}}}),e("k-button",{staticClass:"k-block-options-button",attrs:{tooltip:t.$t("remove"),icon:"trash"},on:{click:function(e){return e.preventDefault(),t.$emit("confirmToRemoveSelected")}}})]:[t.isEditable?e("k-button",{staticClass:"k-block-options-button",attrs:{tooltip:t.$t("edit"),icon:"edit"},on:{click:function(e){return t.$emit("open")}}}):t._e(),e("k-button",{staticClass:"k-block-options-button",attrs:{disabled:t.isFull,tooltip:t.$t("insert.after"),icon:"add"},on:{click:function(e){return t.$emit("chooseToAppend")}}}),e("k-button",{staticClass:"k-block-options-button",attrs:{tooltip:t.$t("delete"),icon:"trash"},on:{click:function(e){return t.$emit("confirmToRemove")}}}),e("k-button",{staticClass:"k-block-options-button",attrs:{tooltip:t.$t("more"),icon:"dots"},on:{click:function(e){return t.$refs.options.toggle()}}}),e("k-button",{staticClass:"k-block-options-button k-sort-handle",attrs:{tooltip:t.$t("sort"),icon:"sort"},on:{keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"up",38,e.key,["Up","ArrowUp"])?null:(e.preventDefault(),t.$emit("sortUp"))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"down",40,e.key,["Down","ArrowDown"])?null:(e.preventDefault(),t.$emit("sortDown"))}]}}),e("k-dropdown-content",{ref:"options",attrs:{align:"right"}},[e("k-dropdown-item",{attrs:{disabled:t.isFull,icon:"angle-up"},on:{click:function(e){return t.$emit("chooseToPrepend")}}},[t._v(" "+t._s(t.$t("insert.before"))+" ")]),e("k-dropdown-item",{attrs:{disabled:t.isFull,icon:"angle-down"},on:{click:function(e){return t.$emit("chooseToAppend")}}},[t._v(" "+t._s(t.$t("insert.after"))+" ")]),e("hr"),t.isEditable?e("k-dropdown-item",{attrs:{icon:"edit"},on:{click:function(e){return t.$emit("open")}}},[t._v(" "+t._s(t.$t("edit"))+" ")]):t._e(),e("k-dropdown-item",{attrs:{icon:"refresh"},on:{click:function(e){return t.$emit("chooseToConvert")}}},[t._v(" "+t._s(t.$t("field.blocks.changeType"))+" ")]),e("hr"),e("k-dropdown-item",{attrs:{icon:"template"},on:{click:function(e){return t.$emit("copy")}}},[t._v(" "+t._s(t.$t("copy"))+" ")]),e("k-dropdown-item",{attrs:{icon:"download"},on:{click:function(e){return t.$emit("paste")}}},[t._v(" "+t._s(t.$t("paste.after"))+" ")]),e("hr"),e("k-dropdown-item",{attrs:{icon:t.isHidden?"preview":"hidden"},on:{click:function(e){return t.$emit(t.isHidden?"show":"hide")}}},[t._v(" "+t._s(!0===t.isHidden?t.$t("show"):t.$t("hide"))+" ")]),e("k-dropdown-item",{attrs:{disabled:t.isFull,icon:"copy"},on:{click:function(e){return t.$emit("duplicate")}}},[t._v(" "+t._s(t.$t("duplicate"))+" ")]),e("hr"),e("k-dropdown-item",{attrs:{icon:"trash"},on:{click:function(e){return t.$emit("confirmToRemove")}}},[t._v(" "+t._s(t.$t("delete"))+" ")])],1)]],2)}),[],!1,null,null,null,null).exports;const _o=It({inheritAttrs:!1,props:{endpoint:String,fieldsets:Object,fieldsetGroups:Object},data(){return{dialogIsOpen:!1,disabled:[],headline:null,payload:null,event:"add",groups:this.createGroups()}},computed:{shortcut(){return this.$helper.keyboard.metaKey()+"+v"}},methods:{add(t){this.$emit(this.event,t,this.payload),this.$refs.dialog.close()},close(){this.$refs.dialog.close()},createGroups(){let t={},e=0;const s=this.fieldsetGroups||{blocks:{label:this.$t("field.blocks.fieldsets.label"),sets:Object.keys(this.fieldsets)}};return Object.keys(s).forEach((n=>{let i=s[n];i.open=!1!==i.open,i.fieldsets=i.sets.filter((t=>this.fieldsets[t])).map((t=>(e++,{...this.fieldsets[t],index:e}))),0!==i.fieldsets.length&&(t[n]=i)})),t},isOpen(){return this.dialogIsOpen},navigate(t){var e,s;null==(s=null==(e=this.$refs["fieldset-"+t])?void 0:e[0])||s.focus()},onClose(){this.dialogIsOpen=!1,this.$events.$off("paste",this.close)},onOpen(){this.dialogIsOpen=!0,this.$events.$on("paste",this.close)},open(t,e={}){const s={event:"add",disabled:[],headline:null,...e};this.event=s.event,this.disabled=s.disabled,this.headline=s.headline,this.payload=t,this.$refs.dialog.open()}}},(function(){var t=this,e=t._self._c;return e("k-dialog",{ref:"dialog",staticClass:"k-block-selector",attrs:{"cancel-button":!1,"submit-button":!1,size:"medium"},on:{open:t.onOpen,close:t.onClose}},[t.headline?e("k-headline",[t._v(" "+t._s(t.headline)+" ")]):t._e(),t._l(t.groups,(function(s,n){return e("details",{key:n,attrs:{open:s.open}},[e("summary",[t._v(t._s(s.label))]),e("div",{staticClass:"k-block-types"},t._l(s.fieldsets,(function(s){return e("k-button",{key:s.name,ref:"fieldset-"+s.index,refInFor:!0,attrs:{disabled:t.disabled.includes(s.type),icon:s.icon||"box",text:s.name},on:{keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"up",38,e.key,["Up","ArrowUp"])?null:t.navigate(s.index-1)},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"down",40,e.key,["Down","ArrowDown"])?null:t.navigate(s.index+1)}],click:function(e){return t.add(s.type)}}})})),1)])})),e("p",{staticClass:"k-clipboard-hint",domProps:{innerHTML:t._s(t.$t("field.blocks.fieldsets.paste",{shortcut:t.shortcut}))}})],2)}),[],!1,null,null,null,null).exports;const xo=It({inheritAttrs:!1,props:{fieldset:Object,content:Object},computed:{icon(){return this.fieldset.icon||"box"},label(){if(!this.fieldset.label||0===this.fieldset.label.length)return!1;if(this.fieldset.label===this.fieldset.name)return!1;const t=this.$helper.string.template(this.fieldset.label,this.content);return"…"!==t&&t},name(){return this.fieldset.name}}},(function(){var t=this,e=t._self._c;return e("div",t._g({staticClass:"k-block-title"},t.$listeners),[e("k-icon",{staticClass:"k-block-icon",attrs:{type:t.icon}}),e("span",{staticClass:"k-block-name"},[t._v(" "+t._s(t.name)+" ")]),t.label?e("span",{staticClass:"k-block-label"},[t._v(" "+t._s(t.label)+" ")]):t._e()],1)}),[],!1,null,null,null,null).exports;const wo=It({inheritAttrs:!1,props:{content:[Object,Array],fieldset:Object},methods:{field(t,e=null){let s=null;return Object.values(this.fieldset.tabs).forEach((e=>{e.fields[t]&&(s=e.fields[t])})),s||e},open(){this.$emit("open")},update(t){this.$emit("update",{...this.content,...t})}}},null,null,!1,null,null,null,null).exports;t.component("k-block",bo),t.component("k-blocks",yo),t.component("k-block-figure",vo),t.component("k-block-options",$o),t.component("k-block-selector",_o),t.component("k-block-title",xo),t.component("k-block-type",wo);const So=Object.assign({"./Types/Code.vue":Ji,"./Types/Default.vue":Wi,"./Types/Gallery.vue":Zi,"./Types/Heading.vue":to,"./Types/Image.vue":so,"./Types/Line.vue":io,"./Types/List.vue":ro,"./Types/Markdown.vue":ao,"./Types/Quote.vue":co,"./Types/Table.vue":ho,"./Types/Text.vue":fo,"./Types/Video.vue":ko});Object.keys(So).map((e=>{const s=e.match(/\/([a-zA-Z]*)\.vue/)[1].toLowerCase();let n=So[e].default;n.extends=wo,t.component("k-block-type-"+s,n)}));const Co={inheritAttrs:!1,props:{column:{type:Object,default:()=>({})},field:Object,value:{}}};const Oo=It({mixins:[Co],inheritAttrs:!1,props:{value:[Array,String]},computed:{bubbles(){var t,e;let s=this.value;const n=(null==(t=this.column)?void 0:t.options)||(null==(e=this.field)?void 0:e.options)||[];return"string"==typeof s&&(s=s.split(",")),s.map((t=>{"string"==typeof t&&(t={value:t,text:t});for(const e of n)e.value===t.value&&(t.text=e.text);return{back:"light",color:"black",...t}}))}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-bubbles-field-preview",class:t.$options.class},[e("k-bubbles",{attrs:{bubbles:t.bubbles}})],1)}),[],!1,null,null,null,null).exports;const Ao=It({extends:Oo,inheritAttrs:!1,class:"k-array-field-preview",computed:{bubbles(){return[{text:1===this.value.length?`1 ${this.$t("entry")}`:`${this.value.length} ${this.$t("entries")}`}]}}},null,null,!1,null,null,null,null).exports;const To=It({mixins:[Co],inheritAttrs:!1,computed:{text(){return this.value}}},(function(){var t=this;return(0,t._self._c)("p",{staticClass:"k-text-field-preview",class:t.$options.class},[t._v(" "+t._s(t.column.before)+" "),t._t("default",(function(){return[t._v(t._s(t.text))]})),t._v(" "+t._s(t.column.after)+" ")],2)}),[],!1,null,null,null,null).exports;const Io=It({extends:To,inheritAttrs:!1,props:{value:String},class:"k-date-field-preview",computed:{text(){var t,e,s,n,i,o;if("string"!=typeof this.value)return"";const r=this.$library.dayjs(this.value);if(!r)return"";let l=(null==(t=this.column)?void 0:t.display)||(null==(e=this.field)?void 0:e.display)||"YYYY-MM-DD",a=(null==(n=null==(s=this.column)?void 0:s.time)?void 0:n.display)||(null==(o=null==(i=this.field)?void 0:i.time)?void 0:o.display);return a&&(l+=" "+a),r.format(l)}}},null,null,!1,null,null,null,null).exports;const Mo=It({mixins:[Co],props:{value:[String,Object]},computed:{link(){return"object"==typeof this.value?this.value.href:this.value},text(){return"object"==typeof this.value?this.value.text:this.link}}},(function(){var t=this,e=t._self._c;return e("p",{staticClass:"k-url-field-preview",class:t.$options.class},[t._v(" "+t._s(t.column.before)+" "),e("k-link",{attrs:{to:t.link},nativeOn:{click:function(t){t.stopPropagation()}}},[t._v(" "+t._s(t.text)+" ")]),t._v(" "+t._s(t.column.after)+" ")],1)}),[],!1,null,null,null,null).exports;const Eo=It({extends:Mo,class:"k-email-field-preview"},null,null,!1,null,null,null,null).exports;const Lo=It({extends:Oo,inheritAttrs:!1,class:"k-files-field-preview",computed:{bubbles(){return this.value.map((t=>({text:t.filename,link:t.link,image:t.image})))}}},null,null,!1,null,null,null,null).exports;const jo=It({mixins:[Co],inheritAttrs:!1,props:{value:Object}},(function(){var t=this;return(0,t._self._c)("k-status-icon",t._b({staticClass:"k-flag-field-preview"},"k-status-icon",t.value,!1))}),[],!1,null,null,null,null).exports;const Do=It({mixins:[Co],inheritAttrs:!1,props:{value:String},computed:{html(){return this.value}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-html-field-preview",class:t.$options.class},[t._v(" "+t._s(t.column.before)+" "),e("div",{domProps:{innerHTML:t._s(t.html)}}),t._v(" "+t._s(t.column.after)+" ")])}),[],!1,null,null,null,null).exports;const Bo=It({mixins:[Co],inheritAttrs:!1,props:{value:[Object]}},(function(){return(0,this._self._c)("k-item-image",{staticClass:"k-image-field-preview",attrs:{image:this.value,layout:"list"}})}),[],!1,null,null,null,null).exports;const Po=It({extends:Oo,inheritAttrs:!1,class:"k-pages-field-preview"},null,null,!1,null,null,null,null).exports;const No=It({extends:To,inheritAttrs:!1,props:{value:String},class:"k-time-field-preview",computed:{text(){const t=this.$library.dayjs.iso(this.value,"time");return(null==t?void 0:t.format(this.field.display))||""}}},null,null,!1,null,null,null,null).exports;const qo=It({props:{field:Object,value:Boolean,column:Object},computed:{text(){return!1!==this.column.text?this.field.text:null}}},(function(){var t=this;return(0,t._self._c)("k-input",{staticClass:"k-toggle-field-preview",attrs:{text:t.text,value:t.value,type:"toggle"},on:{input:function(e){return t.$emit("input",e)}}})}),[],!1,null,null,null,null).exports;const Fo=It({extends:Oo,inheritAttrs:!1,class:"k-users-field-preview",computed:{bubble(){return this.value.map((t=>({text:t.username,link:t.link,image:t.image})))}}},null,null,!1,null,null,null,null).exports;t.component("k-array-field-preview",Ao),t.component("k-bubbles-field-preview",Oo),t.component("k-date-field-preview",Io),t.component("k-email-field-preview",Eo),t.component("k-files-field-preview",Lo),t.component("k-flag-field-preview",jo),t.component("k-html-field-preview",Do),t.component("k-image-field-preview",Bo),t.component("k-pages-field-preview",Po),t.component("k-text-field-preview",To),t.component("k-toggle-field-preview",qo),t.component("k-time-field-preview",No),t.component("k-url-field-preview",Mo),t.component("k-users-field-preview",Fo),t.component("k-list-field-preview",Do),t.component("k-writer-field-preview",Do),t.component("k-checkboxes-field-preview",Oo),t.component("k-multiselect-field-preview",Oo),t.component("k-radio-field-preview",Oo),t.component("k-select-field-preview",Oo),t.component("k-tags-field-preview",Oo),t.component("k-toggles-field-preview",Oo),t.component("k-dialog",Mt),t.component("k-error-dialog",Lt),t.component("k-fiber-dialog",jt),t.component("k-files-dialog",Bt),t.component("k-form-dialog",Pt),t.component("k-language-dialog",Nt),t.component("k-pages-dialog",qt),t.component("k-remove-dialog",Ft),t.component("k-text-dialog",Rt),t.component("k-users-dialog",zt),t.component("k-drawer",Yt),t.component("k-form-drawer",Ht),t.component("k-calendar",Kt),t.component("k-counter",Gt),t.component("k-autocomplete",Ut),t.component("k-form",Jt),t.component("k-form-buttons",Vt),t.component("k-form-indicator",Wt),t.component("k-field",ae),t.component("k-fieldset",ue),t.component("k-input",de),t.component("k-login",pe),t.component("k-login-code",he),t.component("k-times",me),t.component("k-upload",fe),t.component("k-writer",We),t.component("k-login-alert",Xe),t.component("k-structure-form",Ze),t.component("k-toolbar",ts),t.component("k-toolbar-email-dialog",es),t.component("k-toolbar-link-dialog",ss),t.component("k-aspect-ratio",$n),t.component("k-bar",_n),t.component("k-box",xn),t.component("k-bubble",wn),t.component("k-bubbles",Sn),t.component("k-collection",Cn),t.component("k-column",On),t.component("k-dropzone",An),t.component("k-empty",Tn),t.component("k-file-preview",In),t.component("k-grid",Mn),t.component("k-header",En),t.component("k-inside",Ln),t.component("k-item",jn),t.component("k-item-image",Dn),t.component("k-items",Bn),t.component("k-overlay",Pn),t.component("k-panel",Nn),t.component("k-stats",qn),t.component("k-table",Fn),t.component("k-table-cell",Rn),t.component("k-tabs",zn),t.component("k-view",Yn),t.component("k-draggable",Un),t.component("k-error-boundary",Kn),t.component("k-fatal",Gn),t.component("k-headline",Jn),t.component("k-icon",Vn),t.component("k-icons",Wn),t.component("k-image",Xn),t.component("k-loader",Zn),t.component("k-offline-warning",Qn),t.component("k-progress",ei),t.component("k-registration",si),t.component("k-status-icon",ii),t.component("k-sort-handle",ni),t.component("k-text",oi),t.component("k-user-info",ri),t.component("k-breadcrumb",li),t.component("k-button",ai),t.component("k-button-disabled",ui),t.component("k-button-group",ci),t.component("k-button-link",di),t.component("k-button-native",hi),t.component("k-dropdown",mi),t.component("k-dropdown-content",gi),t.component("k-dropdown-item",ki),t.component("k-languages-dropdown",yi),t.component("k-link",bi),t.component("k-options-dropdown",vi),t.component("k-pagination",$i),t.component("k-prev-next",_i),t.component("k-search",xi),t.component("k-tag",wi),t.component("k-topbar",Si),t.component("k-account-view",Di),t.component("k-error-view",Bi),t.component("k-file-view",Pi),t.component("k-installation-view",Ni),t.component("k-languages-view",qi),t.component("k-login-view",Fi),t.component("k-page-view",Ri),t.component("k-plugin-view",zi),t.component("k-reset-password-view",Yi),t.component("k-site-view",Hi),t.component("k-system-view",Ui),t.component("k-users-view",Ki),t.component("k-user-view",ji);t.config.productionTip=!1,t.config.devtools=!0,t.use(tt),t.use(St),t.use(Ot),t.use(Tt),t.use(et),t.use(Ct),t.use(at),t.use(H,Q),t.use(N),t.use(q),new t({store:Q,created(){window.panel.$vue=window.panel.app=this,window.panel.plugins.created.forEach((t=>t(this))),this.$store.dispatch("content/init")},render:t=>t(U)}).$mount("#app"); +import{V as t,s as e,I as s,P as n,S as i,F as o,N as r,a as l,l as a,w as u,c,e as d,t as p,b as h,d as m,f,g,h as k,k as b,D as v,i as y,E as $,j as _,m as x,n as w,T as S,u as C,o as O,p as A,r as T,q as I,v as j,x as E,y as M,z as L,A as B,B as D,C as P,G as N,H as F,J as q,K as R,L as z}from"./vendor.js";const Y=t=>({changeName:async(e,s,n)=>t.patch(e+"/files/"+s+"/name",{name:n}),delete:async(e,s)=>t.delete(e+"/files/"+s),async get(e,s,n){let i=await t.get(e+"/files/"+s,n);return!0===Array.isArray(i.content)&&(i.content={}),i},link(t,e,s){return"/"+this.url(t,e,s)},update:async(e,s,n)=>t.patch(e+"/files/"+s,n),url(t,e,s){let n=t+"/files/"+e;return s&&(n+="/"+s),n}}),H=t=>({async blueprint(e){return t.get("pages/"+this.id(e)+"/blueprint")},async blueprints(e,s){return t.get("pages/"+this.id(e)+"/blueprints",{section:s})},async changeSlug(e,s){return t.patch("pages/"+this.id(e)+"/slug",{slug:s})},async changeStatus(e,s,n){return t.patch("pages/"+this.id(e)+"/status",{status:s,position:n})},async changeTemplate(e,s){return t.patch("pages/"+this.id(e)+"/template",{template:s})},async changeTitle(e,s){return t.patch("pages/"+this.id(e)+"/title",{title:s})},async children(e,s){return t.post("pages/"+this.id(e)+"/children/search",s)},async create(e,s){return null===e||"/"===e?t.post("site/children",s):t.post("pages/"+this.id(e)+"/children",s)},async delete(e,s){return t.delete("pages/"+this.id(e),s)},async duplicate(e,s,n){return t.post("pages/"+this.id(e)+"/duplicate",{slug:s,children:n.children||!1,files:n.files||!1})},async get(e,s){let n=await t.get("pages/"+this.id(e),s);return!0===Array.isArray(n.content)&&(n.content={}),n},id:t=>t.replace(/\//g,"+"),async files(e,s){return t.post("pages/"+this.id(e)+"/files/search",s)},link(t){return"/"+this.url(t)},async preview(t){return(await this.get(this.id(t),{select:"previewUrl"})).previewUrl},async search(e,s){return e?t.post("pages/"+this.id(e)+"/children/search?select=id,title,hasChildren",s):t.post("site/children/search?select=id,title,hasChildren",s)},async update(e,s){return t.patch("pages/"+this.id(e),s)},url(t,e){let s=null===t?"pages":"pages/"+String(t).replace(/\//g,"+");return e&&(s+="/"+e),s}});const U=t=>({running:0,async request(e,s,n=!1){s=Object.assign(s||{},{credentials:"same-origin",cache:"no-store",headers:{"x-requested-with":"xmlhttprequest","content-type":"application/json",...s.headers}}),t.methodOverwrite&&"GET"!==s.method&&"POST"!==s.method&&(s.headers["x-http-method-override"]=s.method,s.method="POST"),s=t.onPrepare(s);const i=e+"/"+JSON.stringify(s);t.onStart(i,n),this.running++;const o=await fetch([t.endpoint,e].join(t.endpoint.endsWith("/")||e.startsWith("/")?"":"/"),s);try{const e=await async function(t){const e=await t.text();let s;try{s=JSON.parse(e)}catch(n){return window.panel.$vue.$api.onParserError({html:e}),!1}return s}(o);if(o.status<200||o.status>299)throw e;if("error"===e.status)throw e;let s=e;return e.data&&"model"===e.type&&(s=e.data),this.running--,t.onComplete(i),t.onSuccess(e),s}catch(r){if(this.running--,t.onComplete(i),!1!==t.onError(r))throw r}},async get(t,e,s,n=!1){return e&&(t+="?"+Object.keys(e).filter((t=>void 0!==e[t]&&null!==e[t])).map((t=>t+"="+e[t])).join("&")),this.request(t,Object.assign(s||{},{method:"GET"}),n)},async post(t,e,s,n="POST",i=!1){return this.request(t,Object.assign(s||{},{method:n,body:JSON.stringify(e)}),i)},async patch(t,e,s,n=!1){return this.post(t,e,s,"PATCH",n)},async delete(t,e,s,n=!1){return this.post(t,e,s,"DELETE",n)}}),K=t=>({blueprint:async e=>t.get("users/"+e+"/blueprint"),blueprints:async(e,s)=>t.get("users/"+e+"/blueprints",{section:s}),changeEmail:async(e,s)=>t.patch("users/"+e+"/email",{email:s}),changeLanguage:async(e,s)=>t.patch("users/"+e+"/language",{language:s}),changeName:async(e,s)=>t.patch("users/"+e+"/name",{name:s}),changePassword:async(e,s)=>t.patch("users/"+e+"/password",{password:s}),changeRole:async(e,s)=>t.patch("users/"+e+"/role",{role:s}),create:async e=>t.post("users",e),delete:async e=>t.delete("users/"+e),deleteAvatar:async e=>t.delete("users/"+e+"/avatar"),link(t,e){return"/"+this.url(t,e)},async list(e){return t.post(this.url(null,"search"),e)},get:async(e,s)=>t.get("users/"+e,s),async roles(e){return(await t.get(this.url(e,"roles"))).data.map((t=>({info:t.description||`(${window.panel.$t("role.description.placeholder")})`,text:t.title,value:t.name})))},search:async e=>t.post("users/search",e),update:async(e,s)=>t.patch("users/"+e,s),url(t,e){let s=t?"users/"+t:"users";return e&&(s+="/"+e),s}}),V={install(t,e){t.prototype.$api=t.$api=((t={})=>{const e={...{endpoint:"/api",methodOverwrite:!0,onPrepare:t=>t,onStart(){},onComplete(){},onSuccess(){},onParserError(){},onError(t){throw window.console.log(t.message),t}},...t.config||{}};let s={...e,...U(e),...t};return s.auth=(t=>({async login(e){const s={long:e.remember||!1,email:e.email,password:e.password};return t.post("auth/login",s)},logout:async()=>t.post("auth/logout"),ping:async()=>t.post("auth/ping"),user:async e=>t.get("auth",e),verifyCode:async e=>t.post("auth/code",{code:e})}))(s),s.files=Y(s),s.languages=(t=>({create:async e=>t.post("languages",e),delete:async e=>t.delete("languages/"+e),get:async e=>t.get("languages/"+e),list:async()=>t.get("languages"),update:async(e,s)=>t.patch("languages/"+e,s)}))(s),s.pages=H(s),s.roles=(t=>({list:async e=>t.get("roles",e),get:async e=>t.get("roles/"+e)}))(s),s.system=(t=>({get:async(e={view:"panel"})=>t.get("system",e),install:async e=>(await t.post("system/install",e)).user,register:async e=>t.post("system/register",e)}))(s),s.site=(t=>({blueprint:async()=>t.get("site/blueprint"),blueprints:async()=>t.get("site/blueprints"),changeTitle:async e=>t.patch("site/title",{title:e}),children:async e=>t.post("site/children/search",e),get:async(e={view:"panel"})=>t.get("site",e),update:async e=>t.post("site",e)}))(s),s.translations=(t=>({list:async()=>t.get("translations"),get:async e=>t.get("translations/"+e)}))(s),s.users=K(s),s})({config:{endpoint:window.panel.$urls.api,onComplete:s=>{t.$api.requests=t.$api.requests.filter((t=>t!==s)),0===t.$api.requests.length&&e.dispatch("isLoading",!1)},onError:e=>{if(window.panel.$config.debug&&window.console.error(e),403===e.code&&("Unauthenticated"===e.message||"access.panel"===e.key))return t.prototype.$go("/logout"),!1},onParserError:({html:t,silent:s})=>{e.dispatch("fatal",{html:t,silent:s})},onPrepare:t=>(window.panel.$language&&(t.headers["x-language"]=window.panel.$language.code),t.headers["x-csrf"]=window.panel.$system.csrf,t),onStart:(s,n=!1)=>{!1===n&&e.dispatch("isLoading",!0),t.$api.requests.push(s)},onSuccess:()=>{clearInterval(t.$api.ping),t.$api.ping=setInterval(t.$api.auth.ping,3e5)}},ping:null,requests:[]}),t.$api.ping=setInterval(t.$api.auth.ping,3e5)}},J={name:"Fiber",data:()=>({component:null,state:window.fiber,key:null}),created(){this.$fiber.init(this.state,{base:document.querySelector("base").href,headers:()=>({"X-CSRF":this.state.$system.csrf}),onFatal({text:t,options:e}){this.$store.dispatch("fatal",{html:t,silent:e.silent})},onFinish:()=>{0===this.$api.requests.length&&this.$store.dispatch("isLoading",!1)},onPushState:t=>{window.history.pushState(t,"",t.$url)},onReplaceState:t=>{window.history.replaceState(t,"",t.$url)},onStart:({silent:t})=>{!0!==t&&this.$store.dispatch("isLoading",!0)},onSwap:async(t,e)=>{e={navigate:!0,replace:!1,...e},this.setGlobals(t),this.setTitle(t),this.setTranslation(t),this.component=t.$view.component,this.state=t,this.key=!0===e.replace?this.key:t.$view.timestamp,!0===e.navigate&&this.navigate()},query:()=>{var t;return{language:null==(t=this.state.$language)?void 0:t.code}}}),window.addEventListener("popstate",this.$reload)},methods:{navigate(){this.$store.dispatch("navigate")},setGlobals(e){["$config","$direction","$language","$languages","$license","$menu","$multilang","$permissions","$searches","$system","$translation","$urls","$user","$view"].forEach((s=>{void 0!==e[s]?t.prototype[s]=window.panel[s]=e[s]:t.prototype[s]=e[s]=window.panel[s]}))},setTitle(t){t.$view.title?document.title=t.$view.title+" | "+t.$system.title:document.title=t.$system.title},setTranslation(t){t.$translation&&(document.documentElement.lang=t.$translation.code)}},render(t){if(this.component)return t(this.component,{key:this.key,props:this.state.$view.props})}};function G(t,e,s,n,i,o,r,l){var a,u="function"==typeof t?t.options:t;if(e&&(u.render=e,u.staticRenderFns=s,u._compiled=!0),n&&(u.functional=!0),o&&(u._scopeId="data-v-"+o),r?(a=function(t){(t=t||this.$vnode&&this.$vnode.ssrContext||this.parent&&this.parent.$vnode&&this.parent.$vnode.ssrContext)||"undefined"==typeof __VUE_SSR_CONTEXT__||(t=__VUE_SSR_CONTEXT__),i&&i.call(this,t),t&&t._registeredComponents&&t._registeredComponents.add(r)},u._ssrRegister=a):i&&(a=l?function(){i.call(this,(u.functional?this.parent:this).$root.$options.shadowRoot)}:i),a)if(u.functional){u._injectStyles=a;var c=u.render;u.render=function(t,e){return a.call(e),c(t,e)}}else{var d=u.beforeCreate;u.beforeCreate=d?[].concat(d,a):[a]}return{exports:t,options:u}}const W=G({props:{autofocus:{type:Boolean,default:!0},cancelButton:{type:[String,Boolean],default:!0},disabled:Boolean,icon:{type:String,default:"check"},size:{type:String,default:"default"},submitButton:{type:[String,Boolean],default:!0},theme:String,visible:Boolean},data:()=>({notification:null}),computed:{buttons(){let t=[];return this.cancelButton&&t.push({icon:"cancel",text:this.cancelButtonLabel,class:"k-dialog-button-cancel",click:this.cancel}),this.submitButtonConfig&&t.push({icon:this.icon,text:this.submitButtonLabel,theme:this.theme,class:"k-dialog-button-submit",click:this.submit,disabled:this.disabled}),t},cancelButtonLabel(){return!1!==this.cancelButton&&(!0===this.cancelButton||0===this.cancelButton.length?this.$t("cancel"):this.cancelButton)},submitButtonConfig(){return void 0!==this.$attrs.button?this.$attrs.button:void 0===this.submitButton||this.submitButton},submitButtonLabel(){return!0===this.submitButton||0===this.submitButton.length?this.$t("confirm"):this.submitButton}},created(){this.$events.$on("keydown.esc",this.close,!1)},destroyed(){this.$events.$off("keydown.esc",this.close,!1)},mounted(){this.visible&&this.$nextTick(this.open)},methods:{onOverlayClose(){this.notification=null,this.$emit("close"),this.$events.$off("keydown.esc",this.close),this.$store.dispatch("dialog",!1)},open(){this.$store.state.dialog||this.$store.dispatch("dialog",!0),this.notification=null,this.$refs.overlay.open(),this.$emit("open"),this.$events.$on("keydown.esc",this.close)},close(){this.$refs.overlay&&this.$refs.overlay.close()},cancel(){this.$emit("cancel"),this.close()},focus(){var t;if(null==(t=this.$refs.dialog)?void 0:t.querySelector){const t=this.$refs.dialog.querySelector(".k-dialog-button-cancel");"function"==typeof(null==t?void 0:t.focus)&&t.focus()}},error(t){this.notification={message:t,type:"error"}},submit(){this.$emit("submit")},success(t){this.notification={message:t,type:"success"}}}},(function(){var t=this,e=t._self._c;return e("k-overlay",{ref:"overlay",attrs:{autofocus:t.autofocus,centered:!0},on:{close:t.onOverlayClose,ready:function(e){return t.$emit("ready")}}},[e("div",{ref:"dialog",staticClass:"k-dialog",class:t.$vnode.data.staticClass,attrs:{"data-size":t.size},on:{mousedown:function(t){t.stopPropagation()}}},[t.notification?e("div",{staticClass:"k-dialog-notification",attrs:{"data-theme":t.notification.type}},[e("p",[t._v(t._s(t.notification.message))]),e("k-button",{attrs:{icon:"cancel"},on:{click:function(e){t.notification=null}}})],1):t._e(),e("div",{staticClass:"k-dialog-body scroll-y-auto"},[t._t("default")],2),t.$slots.footer||t.buttons.length?e("footer",{staticClass:"k-dialog-footer"},[t._t("footer",(function(){return[e("k-button-group",{attrs:{buttons:t.buttons}})]}))],2):t._e()])])}),[],!1,null,null,null,null).exports,X={props:{autofocus:{type:Boolean,default:!0},cancelButton:{type:[String,Boolean],default:!0},icon:String,submitButton:{type:[String,Boolean],default:!0},size:String,theme:String,visible:Boolean},methods:{close(){this.$refs.dialog.close(),this.$emit("close")},error(t){this.$refs.dialog.error(t)},open(){this.$refs.dialog.open(),this.$emit("open")},success(t){this.$refs.dialog.close(),t.route&&this.$go(t.route),t.message&&this.$store.dispatch("notification/success",t.message),t.event&&("string"==typeof t.event&&(t.event=[t.event]),t.event.forEach((e=>{this.$events.$emit(e,t)}))),!1!==Object.prototype.hasOwnProperty.call(t,"emit")&&!1===t.emit||this.$emit("success")}}};const Z=G({mixins:[X],props:{details:[Object,Array],message:String,size:{type:String,default:"medium"}},computed:{detailsList(){return Array.isArray(this.details)?this.details:Object.values(this.details||{})}}},(function(){var t=this,e=t._self._c;return e("k-dialog",{ref:"dialog",staticClass:"k-error-dialog",attrs:{"cancel-button":!1,size:t.size,visible:!0},on:{cancel:function(e){return t.$emit("cancel")},close:function(e){return t.$emit("close")},submit:function(e){return t.$refs.dialog.close()}}},[e("k-text",[t._v(t._s(t.message))]),t.detailsList.length?e("dl",{staticClass:"k-error-details"},[t._l(t.detailsList,(function(s,n){return[e("dt",{key:"detail-label-"+n},[t._v(" "+t._s(s.label)+" ")]),e("dd",{key:"detail-message-"+n},["object"==typeof s.message?[e("ul",t._l(s.message,(function(s,n){return e("li",{key:n},[t._v(" "+t._s(s)+" ")])})),0)]:[t._v(" "+t._s(s.message)+" ")]],2)]}))],2):t._e()],1)}),[],!1,null,null,null,null).exports;const Q=G({props:{code:Number,component:String,path:String,props:Object,referrer:String},data:()=>({isProcessing:!1}),methods:{close(){this.$refs.dialog.close()},onCancel(){"function"==typeof this.$store.state.dialog.cancel&&this.$store.state.dialog.cancel({dialog:this})},async onSubmit(t){if(!0===this.isProcessing)return!1;let e=null;this.isProcessing=!0;try{if("function"==typeof this.$store.state.dialog.submit)e=await this.$store.state.dialog.submit({dialog:this,value:t});else{if(!this.path)throw"The dialog needs a submit action or a dialog route path to be submitted";e=await this.$request(this.path,{body:t,method:"POST",type:"$dialog",headers:{"X-Fiber-Referrer":this.referrer}})}if(!1===e)return!1;this.$refs.dialog.success(e),e.dispatch&&Object.keys(e.dispatch).forEach((t=>{const s=e.dispatch[t];this.$store.dispatch(t,!0===Array.isArray(s)?[...s]:s)})),e.redirect?this.$go(e.redirect):this.$reload(e.reload||{})}catch(s){this.$refs.dialog.error(s)}finally{this.isProcessing=!1}}}},(function(){var t=this;return(0,t._self._c)(t.component,t._b({ref:"dialog",tag:"component",attrs:{disabled:t.isProcessing,visible:!0},on:{cancel:t.onCancel,submit:t.onSubmit}},"component",t.props,!1))}),[],!1,null,null,null,null).exports,tt=(t,e)=>{let s=null;return function(){clearTimeout(s),s=setTimeout((()=>t.apply(this,arguments)),e)}},et={data:()=>({models:[],issue:null,selected:{},options:{endpoint:null,max:null,multiple:!0,parent:null,selected:[],search:!0},search:null,pagination:{limit:20,page:1,total:0}}),computed:{checkedIcon(){return!0===this.multiple?"check":"circle-filled"},collection(){return{empty:this.emptyProps,items:this.items,link:!1,layout:"list",pagination:{details:!0,dropdown:!1,align:"center",...this.pagination},sortable:!1}},items(){return this.models.map(this.item)},multiple(){return!0===this.options.multiple&&1!==this.options.max}},watch:{search(){this.updateSearch()}},created(){this.updateSearch=tt(this.updateSearch,200)},methods:{async fetch(){const t={page:this.pagination.page,search:this.search,...this.fetchData||{}};try{const e=await this.$api.get(this.options.endpoint,t);this.models=e.data,this.pagination=e.pagination,this.onFetched&&this.onFetched(e)}catch(e){this.models=[],this.issue=e.message}},async open(t,s){this.pagination.page=0,this.search=null;let n=!0;Array.isArray(t)?(this.models=t,n=!1):(this.models=[],s=t),this.options={...this.options,...s},this.selected={},this.options.selected.forEach((t=>{e(this.selected,t,{id:t})})),n&&await this.fetch(),this.$refs.dialog.open()},paginate(t){this.pagination.page=t.page,this.pagination.limit=t.limit,this.fetch()},submit(){this.$emit("submit",Object.values(this.selected)),this.$refs.dialog.close()},isSelected(t){return void 0!==this.selected[t.id]},item:t=>t,toggle(t){!1!==this.options.multiple&&1!==this.options.max||(this.selected={}),!0!==this.isSelected(t)?this.options.max&&this.options.max<=Object.keys(this.selected).length||e(this.selected,t.id,t):this.$delete(this.selected,t.id)},toggleBtn(t){const e=this.isSelected(t);return{icon:e?this.checkedIcon:"circle-outline",tooltip:e?this.$t("remove"):this.$t("select"),theme:e?"positive":null}},updateSearch(){this.pagination.page=0,this.fetch()}}};const st=G({mixins:[et],computed:{emptyProps(){return{icon:"image",text:this.$t("dialog.files.empty")}}}},(function(){var t=this,e=t._self._c;return e("k-dialog",{ref:"dialog",staticClass:"k-files-dialog",attrs:{size:"medium"},on:{cancel:function(e){return t.$emit("cancel")},submit:t.submit}},[t.issue?[e("k-box",{attrs:{text:t.issue,theme:"negative"}})]:[t.options.search?e("k-input",{staticClass:"k-dialog-search",attrs:{autofocus:!0,placeholder:t.$t("search")+" …",value:t.search,type:"text",icon:"search"},on:{input:function(e){t.search=e}}}):t._e(),e("k-collection",t._b({on:{item:t.toggle,paginate:t.paginate},scopedSlots:t._u([{key:"options",fn:function({item:s}){return[e("k-button",t._b({on:{click:function(e){return t.toggle(s)}}},"k-button",t.toggleBtn(s),!1))]}}])},"k-collection",t.collection,!1))]],2)}),[],!1,null,null,null,null).exports;const nt=G({mixins:[X],props:{disabled:Boolean,fields:{type:[Array,Object],default:()=>[]},novalidate:{type:Boolean,default:!0},size:{type:String,default:"medium"},submitButton:{type:[String,Boolean],default:()=>window.panel.$t("save")},text:{type:String},theme:{type:String,default:"positive"},value:{type:Object,default:()=>({})}},data(){return{model:this.value}},computed:{hasFields(){return Object.keys(this.fields).length>0}},watch:{value(t){this.model=t}},methods:{onInput(t){this.model=t,this.$emit("input",t)},onSubmit(t){this.$emit("submit",t)}}},(function(){var t=this,e=t._self._c;return e("k-dialog",t._b({ref:"dialog",on:{cancel:function(e){return t.$emit("cancel")},close:function(e){return t.$emit("close")},ready:function(e){return t.$emit("ready")},submit:function(e){return t.$refs.form.submit()}}},"k-dialog",t.$props,!1),[t.text?[e("k-text",{attrs:{html:t.text}})]:t._e(),t.hasFields?e("k-form",{ref:"form",attrs:{value:t.model,fields:t.fields,novalidate:t.novalidate},on:{input:t.onInput,submit:t.onSubmit}}):e("k-box",{attrs:{theme:"negative"}},[t._v(" This form dialog has no fields ")])],2)}),[],!1,null,null,null,null).exports;const it=G({extends:nt,watch:{"model.name"(t){this.fields.code.disabled||this.onNameChanges(t)},"model.code"(t){this.fields.code.disabled||(this.model.code=this.$helper.slug(t,[this.$system.ascii]),this.onCodeChanges(this.model.code))}},methods:{onCodeChanges(t){if(!t)return this.model.locale=null;if(t.length>=2)if(-1!==t.indexOf("-")){let e=t.split("-"),s=[e[0],e[1].toUpperCase()];this.model.locale=s.join("_")}else{let e=this.$system.locales||[];(null==e?void 0:e[t])?this.model.locale=e[t]:this.model.locale=null}},onNameChanges(t){this.model.code=this.$helper.slug(t,[this.model.rules,this.$system.ascii]).substr(0,2)}}},null,null,!1,null,null,null,null).exports;const ot=G({mixins:[et],data(){const t=et.data();return{...t,model:{title:null,parent:null},options:{...t.options,parent:null}}},computed:{emptyProps(){return{icon:"page",text:this.$t("dialog.pages.empty")}},fetchData(){return{parent:this.options.parent}}},methods:{back(){this.options.parent=this.model.parent,this.pagination.page=1,this.fetch()},go(t){this.options.parent=t.id,this.pagination.page=1,this.fetch()},onFetched(t){this.model=t.model}}},(function(){var t=this,e=t._self._c;return e("k-dialog",{ref:"dialog",staticClass:"k-pages-dialog",attrs:{size:"medium"},on:{cancel:function(e){return t.$emit("cancel")},submit:t.submit}},[t.issue?[e("k-box",{attrs:{text:t.issue,theme:"negative"}})]:[t.model?e("header",{staticClass:"k-pages-dialog-navbar"},[e("k-button",{attrs:{disabled:!t.model.id,tooltip:t.$t("back"),icon:"angle-left"},on:{click:t.back}}),e("k-headline",[t._v(t._s(t.model.title))])],1):t._e(),t.options.search?e("k-input",{staticClass:"k-dialog-search",attrs:{autofocus:!0,placeholder:t.$t("search")+" …",value:t.search,type:"text",icon:"search"},on:{input:function(e){t.search=e}}}):t._e(),e("k-collection",t._b({on:{item:t.toggle,paginate:t.paginate},scopedSlots:t._u([{key:"options",fn:function({item:s}){return[e("k-button",t._b({on:{click:function(e){return t.toggle(s)}}},"k-button",t.toggleBtn(s),!1)),t.model?e("k-button",{attrs:{disabled:!s.hasChildren,tooltip:t.$t("open"),icon:"angle-right"},on:{click:function(e){return e.stopPropagation(),t.go(s)}}}):t._e()]}}])},"k-collection",t.collection,!1))]],2)}),[],!1,null,null,null,null).exports;const rt=G({mixins:[X],props:{disabled:Boolean,icon:{type:String,default:"trash"},submitButton:{type:[String,Boolean],default:()=>window.panel.$t("delete")},text:String,theme:{type:String,default:"negative"}}},(function(){var t=this;return(0,t._self._c)("k-text-dialog",t._g(t._b({ref:"dialog"},"k-text-dialog",t.$props,!1),t.$listeners),[t._t("default")],2)}),[],!1,null,null,null,null).exports;const lt=G({mixins:[X],props:{disabled:Boolean,text:String}},(function(){var t=this,e=t._self._c;return e("k-dialog",t._g(t._b({ref:"dialog"},"k-dialog",t.$props,!1),t.$listeners),[t._t("default",(function(){return[t.text?e("k-text",{attrs:{html:t.text}}):e("k-box",{attrs:{theme:"negative"}},[t._v(" This dialog does not define any text ")])]}))],2)}),[],!1,null,null,null,null).exports;const at=G({mixins:[et],computed:{emptyProps(){return{icon:"users",text:this.$t("dialog.users.empty")}}},methods:{item:t=>({...t,key:t.email,info:t.info!==t.text?t.info:null})}},(function(){var t=this,e=t._self._c;return e("k-dialog",{ref:"dialog",staticClass:"k-users-dialog",attrs:{size:"medium"},on:{cancel:function(e){return t.$emit("cancel")},submit:t.submit}},[t.issue?[e("k-box",{attrs:{text:t.issue,theme:"negative"}})]:[t.options.search?e("k-input",{staticClass:"k-dialog-search",attrs:{autofocus:!0,placeholder:t.$t("search")+" …",value:t.search,type:"text",icon:"search"},on:{input:function(e){t.search=e}}}):t._e(),e("k-collection",t._b({on:{item:t.toggle,paginate:t.paginate},scopedSlots:t._u([{key:"options",fn:function({item:s}){return[e("k-button",t._b({on:{click:function(e){return t.toggle(s)}}},"k-button",t.toggleBtn(s),!1))]}}])},"k-collection",t.collection,!1))]],2)}),[],!1,null,null,null,null).exports,ut={install(t){t.component("k-dialog",W),t.component("k-error-dialog",Z),t.component("k-fiber-dialog",Q),t.component("k-files-dialog",st),t.component("k-form-dialog",nt),t.component("k-language-dialog",it),t.component("k-pages-dialog",ot),t.component("k-remove-dialog",rt),t.component("k-text-dialog",lt),t.component("k-users-dialog",at)}};const ct=G({inheritAttrs:!1,props:{id:String,icon:String,tab:String,tabs:Object,title:String},data:()=>({click:!1}),computed:{breadcrumb(){return this.$store.state.drawers.open},hasTabs(){return this.tabs&&Object.keys(this.tabs).length>1},index(){return this.breadcrumb.findIndex((t=>t.id===this._uid))},nested(){return this.index>0}},watch:{index(){-1===this.index&&this.close()}},destroyed(){this.$store.dispatch("drawers/close",this._uid)},methods:{close(){this.$refs.overlay.close()},goTo(t){if(t===this._uid)return!0;this.$store.dispatch("drawers/goto",t)},mouseup(){!0===this.click&&this.close(),this.click=!1},mousedown(t=!1){this.click=t,!0===this.click&&this.$store.dispatch("drawers/close")},onClose(){this.$store.dispatch("drawers/close",this._uid),this.$emit("close")},onOpen(){this.$store.dispatch("drawers/open",{id:this._uid,icon:this.icon,title:this.title}),this.$emit("open")},open(){this.$refs.overlay.open()}}},(function(){var t=this,e=t._self._c;return e("k-overlay",{ref:"overlay",attrs:{dimmed:!1},on:{close:t.onClose,open:t.onOpen}},[e("div",{staticClass:"k-drawer",attrs:{"data-id":t.id,"data-nested":t.nested},on:{mousedown:function(e){return e.stopPropagation(),t.mousedown(!0)},mouseup:t.mouseup}},[e("div",{staticClass:"k-drawer-box",on:{mousedown:function(e){return e.stopPropagation(),t.mousedown(!1)}}},[e("header",{staticClass:"k-drawer-header"},[1===t.breadcrumb.length?e("h2",{staticClass:"k-drawer-title"},[e("k-icon",{attrs:{type:t.icon}}),t._v(" "+t._s(t.title)+" ")],1):e("ul",{staticClass:"k-drawer-breadcrumb"},t._l(t.breadcrumb,(function(s){return e("li",{key:s.id},[e("k-button",{attrs:{icon:s.icon,text:s.title},on:{click:function(e){return t.goTo(s.id)}}})],1)})),0),t.hasTabs?e("nav",{staticClass:"k-drawer-tabs"},t._l(t.tabs,(function(s){return e("k-button",{key:s.name,staticClass:"k-drawer-tab",attrs:{current:t.tab==s.name,text:s.label},on:{click:function(e){return e.stopPropagation(),t.$emit("tab",s.name)}}})})),1):t._e(),e("nav",{staticClass:"k-drawer-options"},[t._t("options"),e("k-button",{staticClass:"k-drawer-option",attrs:{icon:"check"},on:{click:t.close}})],2)]),e("div",{staticClass:"k-drawer-body scroll-y-auto"},[t._t("default")],2)])])])}),[],!1,null,null,null,null).exports;const dt=G({inheritAttrs:!1,props:{empty:{type:String,default:()=>"Missing field setup"},icon:String,id:String,tabs:Object,title:String,type:String,value:Object},data:()=>({tab:null}),computed:{fields(){const t=this.tab||null;return(this.tabs[t]||this.firstTab).fields||{}},firstTab(){return Object.values(this.tabs)[0]}},methods:{close(){this.$refs.drawer.close()},focus(t){var e;"function"==typeof(null==(e=this.$refs.form)?void 0:e.focus)&&this.$refs.form.focus(t)},open(t,e=!0){var s;this.$refs.drawer.open(),this.tab=t||this.firstTab.name,!0===e&&(e=null==(s=Object.values(this.fields).find((t=>!0===t.autofocus)))?void 0:s.name),setTimeout((()=>{this.focus(e)}),10)}}},(function(){var t=this,e=t._self._c;return e("k-drawer",{ref:"drawer",staticClass:"k-form-drawer",attrs:{id:t.id,icon:t.icon,tabs:t.tabs,tab:t.tab,title:t.title},on:{close:function(e){return t.$emit("close")},open:function(e){return t.$emit("open")},tab:function(e){t.tab=e}},scopedSlots:t._u([{key:"options",fn:function(){return[t._t("options")]},proxy:!0},{key:"default",fn:function(){return[0===Object.keys(t.fields).length?e("k-box",{attrs:{theme:"info"}},[t._v(" "+t._s(t.empty)+" ")]):e("k-form",{ref:"form",attrs:{autofocus:!0,fields:t.fields,value:t.$helper.clone(t.value)},on:{input:function(e){return t.$emit("input",e)},invalid:function(e){return t.$emit("invalid",e)}}})]},proxy:!0}],null,!0)})}),[],!1,null,null,null,null).exports,pt={install(t){t.component("k-drawer",ct),t.component("k-form-drawer",dt)}};const ht=G({props:{html:{type:Boolean,default:!1},limit:{type:Number,default:10},skip:{type:Array,default:()=>[]},options:Array,query:String},data:()=>({matches:[],selected:{text:null}}),methods:{close(){this.$refs.dropdown.close()},onSelect(t){this.$emit("select",t),this.$refs.dropdown.close()},search(t){if(t.length<1)return;const e=new RegExp(RegExp.escape(t),"ig");this.matches=this.options.filter((t=>!!t.text&&(-1===this.skip.indexOf(t.value)&&null!==t.text.match(e)))).slice(0,this.limit),this.$emit("search",t,this.matches),this.$refs.dropdown.open()}}},(function(){var t=this,e=t._self._c;return e("k-dropdown",{staticClass:"k-autocomplete"},[t._t("default"),e("k-dropdown-content",t._g({ref:"dropdown",attrs:{autofocus:!0}},t.$listeners),t._l(t.matches,(function(s,n){return e("k-dropdown-item",t._b({key:n,on:{mousedown:function(e){return t.onSelect(s)},keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"tab",9,e.key,"Tab")?null:(e.preventDefault(),t.onSelect(s))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:(e.preventDefault(),t.onSelect(s))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"left",37,e.key,["Left","ArrowLeft"])||"button"in e&&0!==e.button?null:(e.preventDefault(),t.close.apply(null,arguments))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"backspace",void 0,e.key,void 0)?null:(e.preventDefault(),t.close.apply(null,arguments))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"delete",[8,46],e.key,["Backspace","Delete","Del"])?null:(e.preventDefault(),t.close.apply(null,arguments))}]}},"k-dropdown-item",s,!1),[e("span",{domProps:{innerHTML:t._s(t.html?s.text:t.$esc(s.text))}})])})),1),t._v(" "+t._s(t.query)+" ")],2)}),[],!1,null,null,null,null).exports;const mt=G({props:{disabled:Boolean,max:String,min:String,value:String},data(){return this.data(this.value)},computed:{numberOfDays(){return this.toDate().daysInMonth()},firstWeekday(){const t=this.toDate().day();return t>0?t:7},weekdays(){return["mon","tue","wed","thu","fri","sat","sun"].map((t=>this.$t("days."+t)))},weeks(){const t=this.firstWeekday-1;return Math.ceil((this.numberOfDays+t)/7)},monthnames(){return["january","february","march","april","may","june","july","august","september","october","november","december"].map((t=>this.$t("months."+t)))},months(){var t=[];return this.monthnames.forEach(((e,s)=>{const n=this.toDate(1,s);t.push({value:s,text:e,disabled:n.isBefore(this.current.min,"month")||n.isAfter(this.current.max,"month")})})),t},years(){var t,e,s,n;const i=null!=(e=null==(t=this.current.min)?void 0:t.get("year"))?e:this.current.year-20,o=null!=(n=null==(s=this.current.max)?void 0:s.get("year"))?n:this.current.year+20;return this.toOptions(i,o)}},watch:{value(t){const e=this.data(t);this.dt=e.dt,this.current=e.current}},methods:{data(t){const e=this.$library.dayjs.iso(t),s=this.$library.dayjs();return{dt:e,current:{month:(null!=e?e:s).month(),year:(null!=e?e:s).year(),min:this.$library.dayjs.iso(this.min),max:this.$library.dayjs.iso(this.max)}}},days(t){let e=[];const s=7*(t-1)+1,n=s+7;for(let i=s;ithis.numberOfDays;e.push(s?"":t)}return e},isDisabled(t){const e=this.toDate(t);return this.disabled||e.isBefore(this.current.min,"day")||e.isAfter(this.current.max,"day")},isSelected(t){return this.toDate(t).isSame(this.dt,"day")},isToday(t){const e=this.$library.dayjs();return this.toDate(t).isSame(e,"day")},onInput(){var t;this.$emit("input",(null==(t=this.dt)?void 0:t.toISO("date"))||null)},onNext(){const t=this.toDate().add(1,"month");this.show(t)},onPrev(){const t=this.toDate().subtract(1,"month");this.show(t)},select(t){const e="today"===t?this.$library.dayjs().merge(this.toDate(),"time"):this.toDate(t);this.dt=e,this.show(e),this.onInput()},show(t){this.current.year=t.year(),this.current.month=t.month()},toDate(t=1,e=this.current.month){return this.$library.dayjs(`${this.current.year}-${e+1}-${t}`)},toOptions(t,e){for(var s=[],n=t;n<=e;n++)s.push({value:n,text:this.$helper.pad(n)});return s}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-calendar-input"},[e("nav",[e("k-button",{attrs:{icon:"angle-left"},on:{click:t.onPrev}}),e("span",{staticClass:"k-calendar-selects"},[e("k-select-input",{attrs:{options:t.months,disabled:t.disabled,required:!0,value:t.current.month},on:{input:function(e){t.current.month=e}}}),e("k-select-input",{attrs:{options:t.years,disabled:t.disabled,required:!0,value:t.current.year},on:{input:function(e){t.current.year=e}}})],1),e("k-button",{attrs:{icon:"angle-right"},on:{click:t.onNext}})],1),e("table",{staticClass:"k-calendar-table"},[e("thead",[e("tr",t._l(t.weekdays,(function(s){return e("th",{key:"weekday_"+s},[t._v(" "+t._s(s)+" ")])})),0)]),e("tbody",t._l(t.weeks,(function(s){return e("tr",{key:"week_"+s},t._l(t.days(s),(function(s,n){return e("td",{key:"day_"+n,staticClass:"k-calendar-day",attrs:{"aria-current":!!t.isToday(s)&&"date","aria-selected":!!t.isSelected(s)&&"date"}},[s?e("k-button",{attrs:{disabled:t.isDisabled(s),text:s},on:{click:function(e){return t.select(s)}}}):t._e()],1)})),0)})),0),e("tfoot",[e("tr",[e("td",{staticClass:"k-calendar-today",attrs:{colspan:"7"}},[e("k-button",{attrs:{text:t.$t("today")},on:{click:function(e){return t.select("today")}}})],1)])])])])}),[],!1,null,null,null,null).exports;const ft=G({props:{count:Number,min:Number,max:Number,required:{type:Boolean,default:!1}},computed:{valid(){return!1===this.required&&0===this.count||(!0!==this.required||0!==this.count)&&(!(this.min&&this.countthis.max))}}},(function(){var t=this,e=t._self._c;return e("span",{staticClass:"k-counter",attrs:{"data-invalid":!t.valid}},[e("span",[t._v(t._s(t.count))]),t.min&&t.max?e("span",{staticClass:"k-counter-rules"},[t._v("("+t._s(t.min)+"–"+t._s(t.max)+")")]):t.min?e("span",{staticClass:"k-counter-rules"},[t._v("≥ "+t._s(t.min))]):t.max?e("span",{staticClass:"k-counter-rules"},[t._v("≤ "+t._s(t.max))]):t._e()])}),[],!1,null,null,null,null).exports;const gt=G({props:{disabled:Boolean,config:Object,fields:{type:[Array,Object],default:()=>({})},novalidate:{type:Boolean,default:!1},value:{type:Object,default:()=>({})}},data(){return{errors:{},listeners:{...this.$listeners,input:this.onInput,submit:this.onSubmit}}},methods:{focus(t){var e,s;null==(s=null==(e=this.$refs.fields)?void 0:e.focus)||s.call(e,t)},onInput(t,e,s){this.$emit("input",t,e,s)},onSubmit(){this.$emit("submit",this.value)},submit(){this.$refs.submitter.click()}}},(function(){var t=this,e=t._self._c;return e("form",{ref:"form",staticClass:"k-form",attrs:{method:"POST",autocomplete:"off",novalidate:""},on:{submit:function(e){return e.preventDefault(),t.onSubmit.apply(null,arguments)}}},[t._t("header"),t._t("default",(function(){return[e("k-fieldset",t._g({ref:"fields",attrs:{disabled:t.disabled,fields:t.fields,novalidate:t.novalidate,value:t.value}},t.listeners))]})),t._t("footer"),e("input",{ref:"submitter",staticClass:"k-form-submitter",attrs:{type:"submit"}})],2)}),[],!1,null,null,null,null).exports;const kt=G({props:{lock:[Boolean,Object]},data:()=>({isRefreshing:null,isLocking:null}),computed:{api(){return[this.$view.path+"/lock",null,null,!0]},hasChanges(){return this.$store.getters["content/hasChanges"]()},isDisabled(){return!1===this.$store.state.content.status.enabled},isLocked(){return"lock"===this.lockState},isUnlocked(){return"unlock"===this.lockState},mode(){return null!==this.lockState?this.lockState:!0===this.hasChanges?"changes":null},lockState(){return this.supportsLocking&&this.lock?this.lock.state:null},supportsLocking(){return!1!==this.lock},theme(){return"lock"===this.mode?"negative":"unlock"===this.mode?"info":"notice"}},watch:{hasChanges:{handler(t,e){!0===this.supportsLocking&&!1===this.isLocked&&!1===this.isUnlocked&&(!0===t?(this.onLock(),this.isLocking=setInterval(this.onLock,3e4)):e&&(clearInterval(this.isLocking),this.onLock(!1)))},immediate:!0},isLocked(t){!1===t&&this.$events.$emit("model.reload")}},created(){this.supportsLocking&&(this.isRefreshing=setInterval(this.check,1e4)),this.$events.$on("keydown.cmd.s",this.onSave)},destroyed(){clearInterval(this.isRefreshing),clearInterval(this.isLocking),this.$events.$off("keydown.cmd.s",this.onSave)},methods:{async check(){const{lock:t}=await this.$api.get(...this.api);e(this.$view.props,"lock",t)},async onLock(t=!0){if(!0===t)try{await this.$api.patch(...this.api)}catch(e){clearInterval(this.isLocking),this.$store.dispatch("content/revert")}else clearInterval(this.isLocking),await this.$api.delete(...this.api)},onDownload(){let t="";const e=this.$store.getters["content/changes"]();Object.keys(e).forEach((s=>{t+=s+": \n\n"+e[s],t+="\n\n----\n\n"}));let s=document.createElement("a");s.setAttribute("href","data:text/plain;charset=utf-8,"+encodeURIComponent(t)),s.setAttribute("download",this.$view.path+".txt"),s.style.display="none",document.body.appendChild(s),s.click(),document.body.removeChild(s)},async onResolve(){await this.onUnlock(!1),this.$store.dispatch("content/revert")},onRevert(){this.$refs.revert.open()},async onSave(t){if(!t)return!1;t.preventDefault&&t.preventDefault();try{await this.$store.dispatch("content/save"),this.$events.$emit("model.update"),this.$store.dispatch("notification/success",":)")}catch(e){if(403===e.code)return;e.details&&Object.keys(e.details).length>0?this.$store.dispatch("notification/error",{message:this.$t("error.form.incomplete"),details:e.details}):this.$store.dispatch("notification/error",{message:this.$t("error.form.notSaved"),details:[{label:"Exception: "+e.exception,message:e.message}]})}},async onUnlock(t=!0){const e=[this.$view.path+"/unlock",null,null,!0];!0===t?await this.$api.patch(...e):await this.$api.delete(...e),this.$reload({silent:!0})},revert(){this.$store.dispatch("content/revert"),this.$refs.revert.close()}}},(function(){var t=this,e=t._self._c;return e("nav",{staticClass:"k-form-buttons",attrs:{"data-theme":t.theme}},["unlock"===t.mode?e("k-view",[e("p",{staticClass:"k-form-lock-info"},[t._v(" "+t._s(t.$t("lock.isUnlocked"))+" ")]),e("span",{staticClass:"k-form-lock-buttons"},[e("k-button",{staticClass:"k-form-button",attrs:{text:t.$t("download"),icon:"download"},on:{click:t.onDownload}}),e("k-button",{staticClass:"k-form-button",attrs:{text:t.$t("confirm"),icon:"check"},on:{click:t.onResolve}})],1)]):"lock"===t.mode?e("k-view",[e("p",{staticClass:"k-form-lock-info"},[e("k-icon",{attrs:{type:"lock"}}),e("span",{domProps:{innerHTML:t._s(t.$t("lock.isLocked",{email:t.$esc(t.lock.data.email)}))}})],1),t.lock.data.unlockable?e("k-button",{staticClass:"k-form-button",attrs:{text:t.$t("lock.unlock"),icon:"unlock"},on:{click:function(e){return t.onUnlock()}}}):e("k-icon",{staticClass:"k-form-lock-loader",attrs:{type:"loader"}})],1):"changes"===t.mode?e("k-view",[e("k-button",{staticClass:"k-form-button",attrs:{disabled:t.isDisabled,text:t.$t("revert"),icon:"undo"},on:{click:t.onRevert}}),e("k-button",{staticClass:"k-form-button",attrs:{disabled:t.isDisabled,text:t.$t("save"),icon:"check"},on:{click:t.onSave}})],1):t._e(),e("k-dialog",{ref:"revert",attrs:{"submit-button":t.$t("revert"),icon:"undo",theme:"negative"},on:{submit:t.revert}},[e("k-text",{attrs:{html:t.$t("revert.confirm")}})],1)],1)}),[],!1,null,null,null,null).exports;const bt=G({data:()=>({isOpen:!1,options:[]}),computed:{hasChanges(){return this.ids.length>0},ids(){return Object.keys(this.store).filter((t=>{var e;return Object.keys((null==(e=this.store[t])?void 0:e.changes)||{}).length>0}))},store(){return this.$store.state.content.models}},methods:{async toggle(){if(!1===this.$refs.list.isOpen)try{await this.$dropdown("changes",{method:"POST",body:{ids:this.ids}})((t=>{this.options=t}))}catch(t){return this.$store.dispatch("notification/success",this.$t("lock.unsaved.empty")),this.$store.dispatch("content/clear"),!1}this.$refs.list&&this.$refs.list.toggle()}}},(function(){var t=this,e=t._self._c;return t.hasChanges?e("k-dropdown",{staticClass:"k-form-indicator"},[e("k-button",{staticClass:"k-form-indicator-toggle k-topbar-button",attrs:{icon:"edit"},on:{click:t.toggle}}),e("k-dropdown-content",{ref:"list",attrs:{align:"right",theme:"light"}},[e("p",{staticClass:"k-form-indicator-info"},[t._v(t._s(t.$t("lock.unsaved"))+":")]),e("hr"),t._l(t.options,(function(s){return e("k-dropdown-item",t._b({key:s.id},"k-dropdown-item",s,!1),[t._v(" "+t._s(s.text)+" ")])}))],2)],1):t._e()}),[],!1,null,null,null,null).exports,vt={props:{after:String}},yt={props:{autofocus:Boolean}},$t={props:{before:String}},_t={props:{disabled:Boolean}},xt={props:{help:String}},wt={props:{id:{type:[Number,String],default(){return this._uid}}}},St={props:{invalid:Boolean}},Ct={props:{label:String}},Ot={props:{name:[Number,String]}},At={props:{required:Boolean}},Tt={mixins:[_t,xt,Ct,Ot,At],props:{counter:[Boolean,Object],endpoints:Object,input:[String,Number],translate:Boolean,type:String}};const It=G({mixins:[Tt],inheritAttrs:!1,computed:{labelText(){return this.label||" "}}},(function(){var t=this,e=t._self._c;return e("div",{class:"k-field k-field-name-"+t.name,attrs:{"data-disabled":t.disabled,"data-translate":t.translate},on:{focusin:function(e){return t.$emit("focus",e)},focusout:function(e){return t.$emit("blur",e)}}},[t._t("header",(function(){return[e("header",{staticClass:"k-field-header"},[t._t("label",(function(){return[e("label",{staticClass:"k-field-label",attrs:{for:t.input}},[t._v(" "+t._s(t.labelText)+" "),t.required?e("abbr",{attrs:{title:t.$t("field.required")}},[t._v("*")]):t._e()])]})),t._t("options"),t._t("counter",(function(){return[t.counter?e("k-counter",t._b({staticClass:"k-field-counter",attrs:{required:t.required}},"k-counter",t.counter,!1)):t._e()]}))],2)]})),t._t("default"),t._t("footer",(function(){return[t.help||t.$slots.help?e("footer",{staticClass:"k-field-footer"},[t._t("help",(function(){return[t.help?e("k-text",{staticClass:"k-field-help",attrs:{theme:"help",html:t.help}}):t._e()]}))],2):t._e()]}))],2)}),[],!1,null,null,null,null).exports;const jt=G({props:{config:Object,disabled:Boolean,fields:{type:[Array,Object],default:()=>[]},novalidate:{type:Boolean,default:!1},value:{type:Object,default:()=>({})}},data:()=>({errors:{}}),methods:{focus(t){if(t)return void(this.hasField(t)&&"function"==typeof this.$refs[t][0].focus&&this.$refs[t][0].focus());const e=Object.keys(this.$refs)[0];this.focus(e)},hasFieldType(t){return this.$helper.isComponent(`k-${t}-field`)},hasField(t){var e;return null==(e=this.$refs[t])?void 0:e[0]},onInvalid(t,e,s,n){this.errors[n]=e,this.$emit("invalid",this.errors)},onInput(t,e,s){const n={...this.value,[s]:t};this.$emit("input",n,e,s)},hasErrors(){return Object.keys(this.errors).length}}},(function(){var t=this,e=t._self._c;return e("fieldset",{staticClass:"k-fieldset"},[e("k-grid",[t._l(t.fields,(function(s,n){return[t.$helper.field.isVisible(s,t.value)?e("k-column",{key:s.signature,attrs:{width:s.width}},[e("k-error-boundary",[t.hasFieldType(s.type)?e("k-"+s.type+"-field",t._b({ref:n,refInFor:!0,tag:"component",attrs:{disabled:t.disabled||s.disabled,"form-data":t.value,name:n,novalidate:t.novalidate,value:t.value[n]},on:{input:function(e){return t.onInput(e,s,n)},focus:function(e){return t.$emit("focus",e,s,n)},invalid:(e,i)=>t.onInvalid(e,i,s,n),submit:function(e){return t.$emit("submit",e,s,n)}}},"component",s,!1)):e("k-box",{attrs:{theme:"negative"}},[e("k-text",{attrs:{size:"small"}},[t._v(" The field type "),e("strong",[t._v('"'+t._s(n)+'"')]),t._v(" does not exist ")])],1)],1)],1):t._e()]}))],2)],1)}),[],!1,null,null,null,null).exports,Et={mixins:[vt,$t,_t,St],props:{autofocus:Boolean,type:String,icon:[String,Boolean],theme:String,novalidate:{type:Boolean,default:!1},value:{type:[String,Boolean,Number,Object,Array],default:null}}};const Mt=G({mixins:[Et],inheritAttrs:!1,data(){return{isInvalid:this.invalid,listeners:{...this.$listeners,invalid:(t,e)=>{this.isInvalid=t,this.$emit("invalid",t,e)}}}},computed:{inputProps(){return{...this.$props,...this.$attrs}}},methods:{blur(t){(null==t?void 0:t.relatedTarget)&&!1===this.$el.contains(t.relatedTarget)&&this.trigger(null,"blur")},focus(t){this.trigger(t,"focus")},select(t){this.trigger(t,"select")},trigger(t,e){var s,n,i;if("INPUT"===(null==(s=null==t?void 0:t.target)?void 0:s.tagName)&&"function"==typeof(null==(n=null==t?void 0:t.target)?void 0:n[e]))return void t.target[e]();if("function"==typeof(null==(i=this.$refs.input)?void 0:i[e]))return void this.$refs.input[e]();const o=this.$el.querySelector("input, select, textarea");"function"==typeof(null==o?void 0:o[e])&&o[e]()}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-input",attrs:{"data-disabled":t.disabled,"data-invalid":!t.novalidate&&t.isInvalid,"data-theme":t.theme,"data-type":t.type}},[t.$slots.before||t.before?e("span",{staticClass:"k-input-before",on:{click:t.focus}},[t._t("before",(function(){return[t._v(t._s(t.before))]}))],2):t._e(),e("span",{staticClass:"k-input-element",on:{click:function(e){return e.stopPropagation(),t.focus.apply(null,arguments)}}},[t._t("default",(function(){return[e("k-"+t.type+"-input",t._g(t._b({ref:"input",tag:"component",attrs:{value:t.value}},"component",t.inputProps,!1),t.listeners))]}))],2),t.$slots.after||t.after?e("span",{staticClass:"k-input-after",on:{click:t.focus}},[t._t("after",(function(){return[t._v(t._s(t.after))]}))],2):t._e(),t.$slots.icon||t.icon?e("span",{staticClass:"k-input-icon",on:{click:t.focus}},[t._t("icon",(function(){return[e("k-icon",{attrs:{type:t.icon}})]}))],2):t._e()])}),[],!1,null,null,null,null).exports;const Lt=G({props:{methods:Array},data:()=>({currentForm:null,isLoading:!1,user:{email:"",password:"",remember:!1}}),computed:{canToggle(){return null!==this.codeMode&&!0===this.methods.includes("password")&&(!0===this.methods.includes("password-reset")||!0===this.methods.includes("code"))},codeMode(){return!0===this.methods.includes("password-reset")?"password-reset":!0===this.methods.includes("code")?"code":null},fields(){let t={email:{autofocus:!0,label:this.$t("email"),type:"email",required:!0,link:!1}};return"email-password"===this.form&&(t.password={label:this.$t("password"),type:"password",minLength:8,required:!0,autocomplete:"current-password",counter:!1}),t},form(){return this.currentForm?this.currentForm:"password"===this.methods[0]?"email-password":"email"},isResetForm(){return"password-reset"===this.codeMode&&"email"===this.form},toggleText(){return this.$t("login.toggleText."+this.codeMode+"."+this.formOpposite(this.form))}},methods:{formOpposite:t=>"email-password"===t?"email":"email-password",async login(){this.$emit("error",null),this.isLoading=!0;let t=Object.assign({},this.user);"email"===this.currentForm&&(t.password=null),!0===this.isResetForm&&(t.remember=!1);try{await this.$api.auth.login(t),this.$reload({globals:["$system","$translation"]})}catch(e){this.$emit("error",e)}finally{this.isLoading=!1}},toggleForm(){this.currentForm=this.formOpposite(this.form),this.$refs.fieldset.focus("email")}}},(function(){var t=this,e=t._self._c;return e("form",{staticClass:"k-login-form",on:{submit:function(e){return e.preventDefault(),t.login.apply(null,arguments)}}},[e("div",{staticClass:"k-login-fields"},[!0===t.canToggle?e("button",{staticClass:"k-login-toggler",attrs:{type:"button"},on:{click:t.toggleForm}},[t._v(" "+t._s(t.toggleText)+" ")]):t._e(),e("k-fieldset",{ref:"fieldset",attrs:{novalidate:!0,fields:t.fields,value:t.user},on:{input:function(e){t.user=e}}})],1),e("div",{staticClass:"k-login-buttons"},[!1===t.isResetForm?e("span",{staticClass:"k-login-checkbox"},[e("k-checkbox-input",{attrs:{value:t.user.remember,label:t.$t("login.remember")},on:{input:function(e){t.user.remember=e}}})],1):t._e(),e("k-button",{staticClass:"k-login-button",attrs:{icon:"check",type:"submit"}},[t._v(" "+t._s(t.$t("login"+(t.isResetForm?".reset":"")))+" "),t.isLoading?[t._v(" … ")]:t._e()],2)],1)])}),[],!1,null,null,null,null).exports;const Bt=G({props:{methods:Array,pending:Object},data:()=>({code:"",isLoadingBack:!1,isLoadingLogin:!1}),computed:{mode(){return!0===this.methods.includes("password-reset")?"password-reset":"login"}},methods:{async back(){this.isLoadingBack=!0,this.$go("/logout")},async login(){this.$emit("error",null),this.isLoadingLogin=!0;try{await this.$api.auth.verifyCode(this.code),this.$store.dispatch("notification/success",this.$t("welcome")),"password-reset"===this.mode?this.$go("reset-password"):this.$reload()}catch(t){this.$emit("error",t)}finally{this.isLoadingLogin=!1}}}},(function(){var t=this,e=t._self._c;return e("form",{staticClass:"k-login-form k-login-code-form",on:{submit:function(e){return e.preventDefault(),t.login.apply(null,arguments)}}},[e("k-user-info",{attrs:{user:t.pending.email}}),e("k-text-field",{attrs:{autofocus:!0,counter:!1,help:t.$t("login.code.text."+t.pending.challenge),label:t.$t("login.code.label."+t.mode),novalidate:!0,placeholder:t.$t("login.code.placeholder."+t.pending.challenge),required:!0,value:t.code,autocomplete:"one-time-code",icon:"unlock",name:"code"},on:{input:function(e){t.code=e}}}),e("div",{staticClass:"k-login-buttons"},[e("k-button",{staticClass:"k-login-button k-login-back-button",attrs:{icon:"angle-left"},on:{click:t.back}},[t._v(" "+t._s(t.$t("back"))+" "),t.isLoadingBack?[t._v(" … ")]:t._e()],2),e("k-button",{staticClass:"k-login-button",attrs:{icon:"check",type:"submit"}},[t._v(" "+t._s(t.$t("login"+("password-reset"===t.mode?".reset":"")))+" "),t.isLoadingLogin?[t._v(" … ")]:t._e()],2)],1)],1)}),[],!1,null,null,null,null).exports;const Dt=G({props:{display:{type:String,default:"HH:mm"},value:String},computed:{day(){return this.formatTimes([6,7,8,9,10,11,"-",12,13,14,15,16,17])},night(){return this.formatTimes([18,19,20,21,22,23,"-",0,1,2,3,4,5])}},methods:{formatTimes(t){return t.map((t=>{if("-"===t)return t;const e=this.$library.dayjs(t+":00","H:mm");return{display:e.format(this.display),select:e.toISO("time")}}))},select(t){this.$emit("input",t)}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-times"},[e("div",{staticClass:"k-times-slot"},[e("k-icon",{attrs:{type:"sun"}}),e("ul",t._l(t.day,(function(s){return e("li",{key:s.select},["-"===s?e("hr"):e("k-button",{on:{click:function(e){return t.select(s.select)}}},[t._v(t._s(s.display))])],1)})),0)],1),e("div",{staticClass:"k-times-slot"},[e("k-icon",{attrs:{type:"moon"}}),e("ul",t._l(t.night,(function(s){return e("li",{key:s.select},["-"===s?e("hr"):e("k-button",{on:{click:function(e){return t.select(s.select)}}},[t._v(t._s(s.display))])],1)})),0)],1)])}),[],!1,null,null,null,null).exports;const Pt=G({props:{accept:{type:String,default:"*"},attributes:{type:Object},max:{type:Number},method:{type:String,default:"POST"},multiple:{type:Boolean,default:!0},url:{type:String}},data(){return{options:this.$props,completed:{},errors:[],files:[],total:0}},computed:{limit(){return!1===this.options.multiple?1:this.options.max}},methods:{open(t){this.params(t),setTimeout((()=>{this.$refs.input.click()}),1)},params(t){this.options=Object.assign({},this.$props,t)},select(t){this.upload(t.target.files)},drop(t,e){this.params(e),this.upload(t)},upload(t){this.$refs.dialog.open(),this.files=[...t],this.completed={},this.errors=[],this.hasErrors=!1,this.limit&&(this.files=this.files.slice(0,this.limit)),this.total=this.files.length,this.files.forEach((t=>{var e,s;this.$helper.upload(t,{url:this.options.url,attributes:this.options.attributes,method:this.options.method,headers:{"X-CSRF":window.panel.$system.csrf},progress:(t,e,s)=>{var n,i;null==(i=null==(n=this.$refs[e.name])?void 0:n[0])||i.set(s)},success:(t,e,s)=>{this.complete(e,s.data)},error:(t,e,s)=>{this.errors.push({file:e,message:s.message}),this.complete(e,s.data)}}),void 0!==(null==(s=null==(e=this.options)?void 0:e.attributes)?void 0:s.sort)&&this.options.attributes.sort++}))},complete(t,e){if(this.completed[t.name]=e,Object.keys(this.completed).length==this.total){if(this.$refs.input.value="",this.errors.length>0)return this.$forceUpdate(),void this.$emit("error",this.files);setTimeout((()=>{this.$refs.dialog.close(),this.$emit("success",this.files,Object.values(this.completed))}),250)}}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-upload"},[e("input",{ref:"input",attrs:{accept:t.options.accept,multiple:t.options.multiple,"aria-hidden":"true",type:"file",tabindex:"-1"},on:{change:t.select,click:function(t){t.stopPropagation()}}}),e("k-dialog",{ref:"dialog",staticClass:"k-upload-dialog",attrs:{"cancel-button":!1,"submit-button":!1,size:"medium"},scopedSlots:t._u([{key:"footer",fn:function(){return[t.errors.length>0?[e("k-button-group",{attrs:{buttons:[{icon:"check",text:t.$t("confirm"),click:()=>t.$refs.dialog.close()}]}})]:t._e()]},proxy:!0}])},[t.errors.length>0?[e("k-headline",[t._v(t._s(t.$t("upload.errors")))]),e("ul",{staticClass:"k-upload-error-list"},t._l(t.errors,(function(s,n){return e("li",{key:"error-"+n},[e("p",{staticClass:"k-upload-error-filename"},[t._v(" "+t._s(s.file.name)+" ")]),e("p",{staticClass:"k-upload-error-message"},[t._v(" "+t._s(s.message)+" ")])])})),0)]:[e("k-headline",[t._v(t._s(t.$t("upload.progress")))]),e("ul",{staticClass:"k-upload-list"},t._l(t.files,(function(s,n){return e("li",{key:"file-"+n},[e("k-progress",{ref:s.name,refInFor:!0}),e("p",{staticClass:"k-upload-list-filename"},[t._v(" "+t._s(s.name)+" ")]),e("p",[t._v(t._s(t.errors[s.name]))])],1)})),0)]],2)],1)}),[],!1,null,null,null,null).exports;const Nt=t=>({$from:e})=>((t,e)=>{for(let s=t.depth;s>0;s--){const n=t.node(s);if(e(n))return{pos:s>0?t.before(s):0,start:t.start(s),depth:s,node:n}}})(e,t),Ft=t=>e=>{if((t=>t instanceof r)(e)){const{node:s,$from:n}=e;if(((t,e)=>Array.isArray(t)&&t.indexOf(e.type)>-1||e.type===t)(t,s))return{node:s,pos:n.pos,depth:n.depth}}},qt=(t,e,s={})=>{const n=Ft(e)(t.selection)||Nt((t=>t.type===e))(t.selection);return Object.keys(s).length&&n?n.node.hasMarkup(e,{...n.node.attrs,...s}):!!n};function Rt(t=null,e=null){if(!t||!e)return!1;const s=t.parent.childAfter(t.parentOffset);if(!s.node)return!1;const n=s.node.marks.find((t=>t.type===e));if(!n)return!1;let i=t.index(),o=t.start()+s.offset,r=i+1,l=o+s.node.nodeSize;for(;i>0&&n.isInSet(t.parent.child(i-1).marks);)i-=1,o-=t.parent.child(i).nodeSize;for(;r{i=[...i,...t.marks]}));const o=i.find((t=>t.type.name===e.name));return o?o.attrs:{}},getNodeAttrs:function(t,e){const{from:s,to:n}=t.selection;let i=[];t.doc.nodesBetween(s,n,(t=>{i=[...i,t]}));const o=i.reverse().find((t=>t.type.name===e.name));return o?o.attrs:{}},markInputRule:function(t,e,n){return new s(t,((t,s,i,o)=>{const r=n instanceof Function?n(s):n,{tr:l}=t,a=s.length-1;let u=o,c=i;if(s[a]){const n=i+s[0].indexOf(s[a-1]),r=n+s[a-1].length-1,d=n+s[a-1].lastIndexOf(s[a]),p=d+s[a].length,h=function(t,e,s){let n=[];return s.doc.nodesBetween(t,e,((t,e)=>{n=[...n,...t.marks.map((s=>({start:e,end:e+t.nodeSize,mark:s})))]})),n}(i,o,t).filter((t=>{const{excluded:s}=t.mark.type;return s.find((t=>t.name===e.name))})).filter((t=>t.end>n));if(h.length)return!1;pn&&l.delete(n,d),c=n,u=c+s[a].length}return l.addMark(c,u,e.create(r)),l.removeStoredMark(e),l}))},markIsActive:function(t,e){const{from:s,$from:n,to:i,empty:o}=t.selection;return o?!!e.isInSet(t.storedMarks||n.marks()):!!t.doc.rangeHasMark(s,i,e)},markPasteRule:function(t,e,s){const r=(n,i)=>{const l=[];return n.forEach((n=>{var o;if(n.isText){const{text:r,marks:a}=n;let u,c=0;const d=!!a.filter((t=>"link"===t.type.name))[0];for(;!d&&null!==(u=t.exec(r));)if((null==(o=null==i?void 0:i.type)?void 0:o.allowsMarkType(e))&&u[1]){const t=u.index,i=t+u[0].length,o=t+u[0].indexOf(u[1]),r=o+u[1].length,a=s instanceof Function?s(u):s;t>0&&l.push(n.cut(c,t)),l.push(n.cut(o,r).mark(e.create(a).addToSet(n.marks))),c=i}cnew i(r(t.content),t.openStart,t.openEnd)}})},minMax:function(t=0,e=0,s=0){return Math.min(Math.max(parseInt(t,10),e),s)},nodeIsActive:qt,nodeInputRule:function(t,e,n){return new s(t,((t,s,i,o)=>{const r=n instanceof Function?n(s):n,{tr:l}=t;return s[0]&&l.replaceWith(i-1,o,e.create(r)),l}))},pasteRule:function(t,e,s){const r=n=>{const i=[];return n.forEach((n=>{if(n.isText){const{text:o}=n;let r,l=0;do{if(r=t.exec(o),r){const t=r.index,o=t+r[0].length,a=s instanceof Function?s(r[0]):s;t>0&&i.push(n.cut(l,t)),i.push(n.cut(t,o).mark(e.create(a).addToSet(n.marks))),l=o}}while(r);lnew i(r(t.content),t.openStart,t.openEnd)}})},removeMark:function(t){return(e,s)=>{const{tr:n,selection:i}=e;let{from:o,to:r}=i;const{$from:l,empty:a}=i;if(a){const e=Rt(l,t);o=e.from,r=e.to}return n.removeMark(o,r,t),s(n)}},toggleBlockType:function(t,e,s={}){return(n,i,o)=>qt(n,t,s)?l(e)(n,i,o):l(t,s)(n,i,o)},toggleList:function(t,e){return(s,n,i)=>{const{schema:o,selection:r}=s,{$from:l,$to:c}=r,d=l.blockRange(c);if(!d)return!1;const p=Nt((t=>zt(t,o)))(r);if(d.depth>=1&&p&&d.depth-p.depth<=1){if(p.node.type===t)return a(e)(s,n,i);if(zt(p.node,o)&&t.validContent(p.node.content)){const{tr:e}=s;return e.setNodeMarkup(p.pos,t),n&&n(e),!1}}return u(t)(s,n,i)}},updateMark:function(t,e){return(s,n)=>{const{tr:i,selection:o,doc:r}=s,{ranges:l,empty:a}=o;if(a){const{from:s,to:n}=Rt(o.$from,t);r.rangeHasMark(s,n,t)&&i.removeMark(s,n,t),i.addMark(s,n,t.create(e))}else l.forEach((s=>{const{$to:n,$from:o}=s;r.rangeHasMark(o.pos,n.pos,t)&&i.removeMark(o.pos,n.pos,t),i.addMark(o.pos,n.pos,t.create(e))}));return n(i)}}};class Ht{emit(t,...e){this._callbacks=this._callbacks||{};const s=this._callbacks[t];return s&&s.forEach((t=>t.apply(this,e))),this}off(t,e){if(arguments.length){const s=this._callbacks?this._callbacks[t]:null;s&&(e?this._callbacks[t]=s.filter((t=>t!==e)):delete this._callbacks[t])}else this._callbacks={};return this}on(t,e){return this._callbacks=this._callbacks||{},this._callbacks[t]=this._callbacks[t]||[],this._callbacks[t].push(e),this}}class Ut{constructor(t=[],e){t.forEach((t=>{t.bindEditor(e),t.init()})),this.extensions=t}commands({schema:t,view:e}){return this.extensions.filter((t=>t.commands)).reduce(((s,n)=>{const{name:i,type:o}=n,r={},l=n.commands({schema:t,utils:Yt,...["node","mark"].includes(o)?{type:t[`${o}s`][i]}:{}}),a=(t,s)=>{r[t]=t=>{if("function"!=typeof s||!e.editable)return!1;e.focus();const n=s(t);return"function"==typeof n?n(e.state,e.dispatch,e):n}};return"object"==typeof l?Object.entries(l).forEach((([t,e])=>{a(t,e)})):a(i,l),{...s,...r}}),{})}buttons(t="mark"){const e={};return this.extensions.filter((e=>e.type===t)).filter((t=>t.button)).forEach((t=>{Array.isArray(t.button)?t.button.forEach((t=>{e[t.id||t.name]=t})):e[t.name]=t.button})),e}getAllowedExtensions(t){return t instanceof Array||!t?t instanceof Array?this.extensions.filter((e=>!t.includes(e.name))):this.extensions:[]}getFromExtensions(t,e,s=this.extensions){return s.filter((t=>["extension"].includes(t.type))).filter((e=>e[t])).map((s=>s[t]({...e,utils:Yt})))}getFromNodesAndMarks(t,e,s=this.extensions){return s.filter((t=>["node","mark"].includes(t.type))).filter((e=>e[t])).map((s=>s[t]({...e,type:e.schema[`${s.type}s`][s.name],utils:Yt})))}inputRules({schema:t,excludedExtensions:e}){const s=this.getAllowedExtensions(e);return[...this.getFromExtensions("inputRules",{schema:t},s),...this.getFromNodesAndMarks("inputRules",{schema:t},s)].reduce(((t,e)=>[...t,...e]),[])}keymaps({schema:t}){return[...this.getFromExtensions("keys",{schema:t}),...this.getFromNodesAndMarks("keys",{schema:t})].map((t=>b(t)))}get marks(){return this.extensions.filter((t=>"mark"===t.type)).reduce(((t,{name:e,schema:s})=>({...t,[e]:s})),{})}get nodes(){return this.extensions.filter((t=>"node"===t.type)).reduce(((t,{name:e,schema:s})=>({...t,[e]:s})),{})}get options(){const{view:t}=this;return this.extensions.reduce(((e,s)=>({...e,[s.name]:new Proxy(s.options,{set(e,s,n){const i=e[s]!==n;return Object.assign(e,{[s]:n}),i&&t.updateState(t.state),!0}})})),{})}pasteRules({schema:t,excludedExtensions:e}){const s=this.getAllowedExtensions(e);return[...this.getFromExtensions("pasteRules",{schema:t},s),...this.getFromNodesAndMarks("pasteRules",{schema:t},s)].reduce(((t,e)=>[...t,...e]),[])}plugins({schema:t}){return[...this.getFromExtensions("plugins",{schema:t}),...this.getFromNodesAndMarks("plugins",{schema:t})].reduce(((t,e)=>[...t,...e]),[]).map((t=>t instanceof n?t:new n(t)))}}class Kt{constructor(t={}){this.options={...this.defaults,...t}}init(){return null}bindEditor(t=null){this.editor=t}get name(){return null}get type(){return"extension"}get defaults(){return{}}plugins(){return[]}inputRules(){return[]}pasteRules(){return[]}keys(){return{}}}class Vt extends Kt{constructor(t={}){super(t)}get type(){return"node"}get schema(){return null}commands(){return{}}}class Jt extends Vt{get defaults(){return{inline:!1}}get name(){return"doc"}get schema(){return{content:this.options.inline?"inline*":"block+"}}}class Gt extends Vt{get button(){return{id:this.name,icon:"paragraph",label:window.panel.$t("toolbar.button.paragraph"),name:this.name}}commands({utils:t,type:e}){return{paragraph:()=>t.setBlockType(e)}}get schema(){return{content:"inline*",group:"block",draggable:!1,parseDOM:[{tag:"p"}],toDOM:()=>["p",0]}}get name(){return"paragraph"}}class Wt extends Vt{get name(){return"text"}get schema(){return{group:"inline"}}}class Xt extends Ht{constructor(t={}){super(),this.defaults={autofocus:!1,content:"",disableInputRules:!1,disablePasteRules:!1,editable:!0,element:null,extensions:[],emptyDocument:{type:"doc",content:[]},events:{},inline:!1,parseOptions:{},topNode:"doc",useBuiltInExtensions:!0},this.init(t)}blur(){this.view.dom.blur()}get builtInExtensions(){return this.options.useBuiltInExtensions?[new Jt({inline:this.options.inline}),new Wt,new Gt]:[]}buttons(t){return this.extensions.buttons(t)}clearContent(t=!1){this.setContent(this.options.emptyDocument,t)}command(t,...e){this.commands[t]&&this.commands[t](...e)}createCommands(){return this.extensions.commands({schema:this.schema,view:this.view})}createDocument(t,e=this.options.parseOptions){if(null===t)return this.schema.nodeFromJSON(this.options.emptyDocument);if("object"==typeof t)try{return this.schema.nodeFromJSON(t)}catch(s){return window.console.warn("Invalid content.","Passed value:",t,"Error:",s),this.schema.nodeFromJSON(this.options.emptyDocument)}if("string"==typeof t){const s=`

${t}
`,n=(new window.DOMParser).parseFromString(s,"text/html").body.firstElementChild;return v.fromSchema(this.schema).parse(n,e)}return!1}createEvents(){const t=this.options.events||{};return Object.entries(t).forEach((([t,e])=>{this.on(t,e)})),t}createExtensions(){return new Ut([...this.builtInExtensions,...this.options.extensions],this)}createFocusEvents(){const t=(t,e,s=!0)=>{this.focused=s,this.emit(s?"focus":"blur",{event:e,state:t.state,view:t});const n=this.state.tr.setMeta("focused",s);this.view.dispatch(n)};return new n({props:{attributes:{tabindex:0},handleDOMEvents:{focus:(e,s)=>{t(e,s,!0)},blur:(e,s)=>{t(e,s,!1)}}}})}createInputRules(){return this.extensions.inputRules({schema:this.schema,excludedExtensions:this.options.disableInputRules})}createKeymaps(){return this.extensions.keymaps({schema:this.schema})}createMarks(){return this.extensions.marks}createNodes(){return this.extensions.nodes}createPasteRules(){return this.extensions.pasteRules({schema:this.schema,excludedExtensions:this.options.disablePasteRules})}createPlugins(){return this.extensions.plugins({schema:this.schema})}createSchema(){return new y({topNode:this.options.topNode,nodes:this.nodes,marks:this.marks})}createState(){return $.create({schema:this.schema,doc:this.createDocument(this.options.content),plugins:[...this.plugins,_({rules:this.inputRules}),...this.pasteRules,...this.keymaps,b({Backspace:C}),b(O),this.createFocusEvents()]})}createView(){return new x(this.element,{dispatchTransaction:this.dispatchTransaction.bind(this),editable:()=>this.options.editable,handlePaste:(t,e)=>{if("function"==typeof this.events.paste){const t=e.clipboardData.getData("text/html"),s=e.clipboardData.getData("text/plain");if(!0===this.events.paste(e,t,s))return!0}},handleDrop:(...t)=>{this.emit("drop",...t)},state:this.createState()})}destroy(){this.view&&this.view.destroy()}dispatchTransaction(t){const e=this.state,s=this.state.apply(t);this.view.updateState(s),this.selection={from:this.state.selection.from,to:this.state.selection.to},this.setActiveNodesAndMarks();const n={editor:this,getHTML:this.getHTML.bind(this),getJSON:this.getJSON.bind(this),state:this.state,transaction:t};this.emit("transaction",n),!t.docChanged&&t.getMeta("preventUpdate")||this.emit("update",n);const{from:i,to:o}=this.state.selection,r=!e||!e.selection.eq(s.selection);this.emit(s.selection.empty?"deselect":"select",{...n,from:i,hasChanged:r,to:o})}focus(t=null){if(this.view.focused&&null===t||!1===t)return;const{from:e,to:s}=this.selectionAtPosition(t);this.setSelection(e,s),setTimeout((()=>this.view.focus()),10)}getHTML(){const t=document.createElement("div"),e=w.fromSchema(this.schema).serializeFragment(this.state.doc.content);return t.appendChild(e),this.options.inline&&t.querySelector("p")?t.querySelector("p").innerHTML:t.innerHTML}getJSON(){return this.state.doc.toJSON()}getMarkAttrs(t=null){return this.activeMarkAttrs[t]}getSchemaJSON(){return JSON.parse(JSON.stringify({nodes:this.nodes,marks:this.marks}))}init(t={}){this.options={...this.defaults,...t},this.element=this.options.element,this.focused=!1,this.selection={from:0,to:0},this.events=this.createEvents(),this.extensions=this.createExtensions(),this.nodes=this.createNodes(),this.marks=this.createMarks(),this.schema=this.createSchema(),this.keymaps=this.createKeymaps(),this.inputRules=this.createInputRules(),this.pasteRules=this.createPasteRules(),this.plugins=this.createPlugins(),this.view=this.createView(),this.commands=this.createCommands(),this.setActiveNodesAndMarks(),!1!==this.options.autofocus&&this.focus(this.options.autofocus),this.emit("init",{view:this.view,state:this.state}),this.extensions.view=this.view,this.setContent(this.options.content,!0)}isEditable(){return this.options.editable}isEmpty(){if(this.state)return 0===this.state.doc.textContent.length}get isActive(){return Object.entries({...this.activeMarks,...this.activeNodes}).reduce(((t,[e,s])=>({...t,[e]:(t={})=>s(t)})),{})}removeMark(t){if(this.schema.marks[t])return Yt.removeMark(this.schema.marks[t])(this.state,this.view.dispatch)}selectionAtPosition(t=null){if(this.selection&&null===t)return this.selection;if("start"===t||!0===t)return{from:0,to:0};if("end"===t){const{doc:t}=this.state;return{from:t.content.size,to:t.content.size}}return{from:t,to:t}}setActiveNodesAndMarks(){this.activeMarks=Object.values(this.schema.marks).filter((t=>Yt.markIsActive(this.state,t))).map((t=>t.name)),this.activeMarkAttrs=Object.entries(this.schema.marks).reduce(((t,[e,s])=>({...t,[e]:Yt.getMarkAttrs(this.state,s)})),{}),this.activeNodes=Object.values(this.schema.nodes).filter((t=>Yt.nodeIsActive(this.state,t))).map((t=>t.name)),this.activeNodeAttrs=Object.entries(this.schema.nodes).reduce(((t,[e,s])=>({...t,[e]:Yt.getNodeAttrs(this.state,s)})),{})}setContent(t={},e=!1,s){const{doc:n,tr:i}=this.state,o=this.createDocument(t,s),r=i.replaceWith(0,n.content.size,o).setMeta("preventUpdate",!e);this.view.dispatch(r)}setSelection(t=0,e=0){const{doc:s,tr:n}=this.state,i=Yt.minMax(t,0,s.content.size),o=Yt.minMax(e,0,s.content.size),r=S.create(s,i,o),l=n.setSelection(r);this.view.dispatch(l)}get state(){return this.view?this.view.state:null}toggleMark(t){if(this.schema.marks[t])return Yt.toggleMark(this.schema.marks[t])(this.state,this.view.dispatch)}updateMark(t,e){if(this.schema.marks[t])return Yt.updateMark(this.schema.marks[t],e)(this.state,this.view.dispatch)}}const Zt=G({data:()=>({link:{href:null,title:null,target:!1}}),computed:{fields(){return{href:{label:this.$t("url"),type:"text",icon:"url"},title:{label:this.$t("title"),type:"text",icon:"title"},target:{label:this.$t("open.newWindow"),type:"toggle",text:[this.$t("no"),this.$t("yes")]}}}},methods:{open(t){this.link={title:null,target:!1,...t},this.link.target=Boolean(this.link.target),this.$refs.dialog.open()},submit(){this.$emit("submit",{...this.link,target:this.link.target?"_blank":null}),this.$refs.dialog.close()}}},(function(){var t=this;return(0,t._self._c)("k-form-dialog",{ref:"dialog",attrs:{fields:t.fields,"submit-button":t.$t("confirm"),value:t.link,size:"medium"},on:{close:function(e){return t.$emit("close")},input:function(e){t.link=e},submit:t.submit}})}),[],!1,null,null,null,null).exports;const Qt=G({data:()=>({email:{email:null,title:null}}),computed:{fields(){return{href:{label:this.$t("email"),type:"email",icon:"email"},title:{label:this.$t("title"),type:"text",icon:"title"}}}},methods:{open(t){this.email={title:null,...t},this.$refs.dialog.open()},submit(){this.$emit("submit",this.email),this.$refs.dialog.close()}}},(function(){var t=this;return(0,t._self._c)("k-form-dialog",{ref:"dialog",attrs:{fields:t.fields,"submit-button":t.$t("confirm"),value:t.email,size:"medium"},on:{input:function(e){t.email=e},close:function(e){return t.$emit("close")},submit:t.submit}})}),[],!1,null,null,null,null).exports;class te extends Kt{constructor(t={}){super(t)}command(){return()=>{}}remove(){this.editor.removeMark(this.name)}get schema(){return null}get type(){return"mark"}toggle(){return this.editor.toggleMark(this.name)}update(t){this.editor.updateMark(this.name,t)}}class ee extends te{get button(){return{icon:"code",label:window.panel.$t("toolbar.button.code")}}commands(){return()=>this.toggle()}inputRules({type:t,utils:e}){return[e.markInputRule(/(?:`)([^`]+)(?:`)$/,t)]}keys(){return{"Mod-`":()=>this.toggle()}}get name(){return"code"}pasteRules({type:t,utils:e}){return[e.markPasteRule(/(?:`)([^`]+)(?:`)/g,t)]}get schema(){return{excludes:"_",parseDOM:[{tag:"code"}],toDOM:()=>["code",0]}}}class se extends te{get button(){return{icon:"bold",label:window.panel.$t("toolbar.button.bold")}}commands(){return()=>this.toggle()}inputRules({type:t,utils:e}){return[e.markInputRule(/(?:\*\*|__)([^*_]+)(?:\*\*|__)$/,t)]}keys(){return{"Mod-b":()=>this.toggle()}}get name(){return"bold"}pasteRules({type:t,utils:e}){return[e.markPasteRule(/(?:\*\*|__)([^*_]+)(?:\*\*|__)/g,t)]}get schema(){return{parseDOM:[{tag:"strong"},{tag:"b",getAttrs:t=>"normal"!==t.style.fontWeight&&null},{style:"font-weight",getAttrs:t=>/^(bold(er)?|[5-9]\d{2,})$/.test(t)&&null}],toDOM:()=>["strong",0]}}}class ne extends te{get button(){return{icon:"italic",label:window.panel.$t("toolbar.button.italic")}}commands(){return()=>this.toggle()}inputRules({type:t,utils:e}){return[e.markInputRule(/(?:^|\s)((?:\*)((?:[^*]+))(?:\*))$/,t),e.markInputRule(/(?:^|\s)((?:_)((?:[^_]+))(?:_))$/,t)]}keys(){return{"Mod-i":()=>this.toggle()}}get name(){return"italic"}pasteRules({type:t,utils:e}){return[e.markPasteRule(/_([^_]+)_/g,t),e.markPasteRule(/\*([^*]+)\*/g,t)]}get schema(){return{parseDOM:[{tag:"i"},{tag:"em"},{style:"font-style=italic"}],toDOM:()=>["em",0]}}}class ie extends te{get button(){return{icon:"url",label:window.panel.$t("toolbar.button.link")}}commands(){return{link:()=>{this.editor.emit("link",this.editor)},insertLink:(t={})=>{if(t.href)return this.update(t)},removeLink:()=>this.remove(),toggleLink:(t={})=>{var e;(null==(e=t.href)?void 0:e.length)>0?this.editor.command("insertLink",t):this.editor.command("removeLink")}}}get defaults(){return{target:null}}get name(){return"link"}pasteRules({type:t,utils:e}){return[e.pasteRule(/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._+~#=]{1,256}\.[a-zA-Z]{2,}\b([-a-zA-Z0-9@:%_+.~#?&//=,]*)/gi,t,(t=>({href:t})))]}plugins(){return[{props:{handleClick:(t,e,s)=>{const n=this.editor.getMarkAttrs("link");n.href&&!0===s.altKey&&s.target instanceof HTMLAnchorElement&&(s.stopPropagation(),window.open(n.href,n.target))}}}]}get schema(){return{attrs:{href:{default:null},target:{default:null},title:{default:null}},inclusive:!1,parseDOM:[{tag:"a[href]:not([href^='mailto:'])",getAttrs:t=>({href:t.getAttribute("href"),target:t.getAttribute("target"),title:t.getAttribute("title")})}],toDOM:t=>["a",{...t.attrs,rel:"noopener noreferrer"},0]}}}class oe extends te{get button(){return{icon:"email",label:"Email"}}commands(){return{email:()=>{this.editor.emit("email")},insertEmail:(t={})=>{if(t.href)return this.update(t)},removeEmail:()=>this.remove(),toggleEmail:(t={})=>{var e;(null==(e=t.href)?void 0:e.length)>0?this.editor.command("insertEmail",t):this.editor.command("removeEmail")}}}get defaults(){return{target:null}}get name(){return"email"}pasteRules({type:t,utils:e}){return[e.pasteRule(/^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$/gi,t,(t=>({href:t})))]}plugins(){return[{props:{handleClick:(t,e,s)=>{const n=this.editor.getMarkAttrs("email");n.href&&!0===s.altKey&&s.target instanceof HTMLAnchorElement&&(s.stopPropagation(),window.open(n.href))}}}]}get schema(){return{attrs:{href:{default:null},title:{default:null}},inclusive:!1,parseDOM:[{tag:"a[href^='mailto:']",getAttrs:t=>({href:t.getAttribute("href").replace("mailto:",""),title:t.getAttribute("title")})}],toDOM:t=>["a",{...t.attrs,href:"mailto:"+t.attrs.href},0]}}}class re extends te{get button(){return{icon:"strikethrough",label:window.panel.$t("toolbar.button.strike")}}commands(){return()=>this.toggle()}inputRules({type:t,utils:e}){return[e.markInputRule(/~([^~]+)~$/,t)]}keys(){return{"Mod-d":()=>this.toggle()}}get name(){return"strike"}pasteRules({type:t,utils:e}){return[e.markPasteRule(/~([^~]+)~/g,t)]}get schema(){return{parseDOM:[{tag:"s"},{tag:"del"},{tag:"strike"},{style:"text-decoration",getAttrs:t=>"line-through"===t}],toDOM:()=>["s",0]}}}class le extends te{get button(){return{icon:"underline",label:window.panel.$t("toolbar.button.underline")}}commands(){return()=>this.toggle()}keys(){return{"Mod-u":()=>this.toggle()}}get name(){return"underline"}get schema(){return{parseDOM:[{tag:"u"},{style:"text-decoration",getAttrs:t=>"underline"===t}],toDOM:()=>["u",0]}}}class ae extends Vt{get button(){return{id:this.name,icon:"list-bullet",label:window.panel.$t("toolbar.button.ul"),name:this.name,when:["listItem","bulletList","orderedList"]}}commands({type:t,schema:e,utils:s}){return()=>s.toggleList(t,e.nodes.listItem)}inputRules({type:t,utils:e}){return[e.wrappingInputRule(/^\s*([-+*])\s$/,t)]}keys({type:t,schema:e,utils:s}){return{"Shift-Ctrl-8":s.toggleList(t,e.nodes.listItem)}}get name(){return"bulletList"}get schema(){return{content:"listItem+",group:"block",parseDOM:[{tag:"ul"}],toDOM:()=>["ul",0]}}}class ue extends Vt{commands({utils:t,type:e}){return()=>this.createHardBreak(t,e)}createHardBreak(t,e){return t.chainCommands(t.exitCode,((t,s)=>(s(t.tr.replaceSelectionWith(e.create()).scrollIntoView()),!0)))}get defaults(){return{enter:!1,text:!1}}keys({utils:t,type:e}){const s=this.createHardBreak(t,e);let n={"Mod-Enter":s,"Shift-Enter":s};return this.options.enter&&(n.Enter=s),n}get name(){return"hardBreak"}get schema(){return{inline:!0,group:"inline",selectable:!1,parseDOM:[{tag:"br"}],toDOM:()=>["br"]}}}class ce extends Vt{get button(){return this.options.levels.map((t=>({id:`h${t}`,command:`h${t}`,icon:`h${t}`,label:window.panel.$t("toolbar.button.heading."+t),attrs:{level:t},name:this.name,when:["heading","paragraph"]})))}commands({type:t,schema:e,utils:s}){let n={toggleHeading:n=>s.toggleBlockType(t,e.nodes.paragraph,n)};return this.options.levels.forEach((i=>{n[`h${i}`]=()=>s.toggleBlockType(t,e.nodes.paragraph,{level:i})})),n}get defaults(){return{levels:[1,2,3,4,5,6]}}inputRules({type:t,utils:e}){return this.options.levels.map((s=>e.textblockTypeInputRule(new RegExp(`^(#{1,${s}})\\s$`),t,(()=>({level:s})))))}keys({type:t,utils:e}){return this.options.levels.reduce(((s,n)=>({...s,[`Shift-Ctrl-${n}`]:e.setBlockType(t,{level:n})})),{})}get name(){return"heading"}get schema(){return{attrs:{level:{default:1}},content:"inline*",group:"block",defining:!0,draggable:!1,parseDOM:this.options.levels.map((t=>({tag:`h${t}`,attrs:{level:t}}))),toDOM:t=>[`h${t.attrs.level}`,0]}}}class de extends Vt{commands({type:t}){return()=>(e,s)=>s(e.tr.replaceSelectionWith(t.create()))}inputRules({type:t,utils:e}){return[e.nodeInputRule(/^(?:---|___\s|\*\*\*\s)$/,t)]}get name(){return"horizontalRule"}get schema(){return{group:"block",parseDOM:[{tag:"hr"}],toDOM:()=>["hr"]}}}class pe extends Vt{keys({type:t,utils:e}){return{Enter:e.splitListItem(t),"Shift-Tab":e.liftListItem(t),Tab:e.sinkListItem(t)}}get name(){return"listItem"}get schema(){return{content:"paragraph block*",defining:!0,draggable:!1,parseDOM:[{tag:"li"}],toDOM:()=>["li",0]}}}class he extends Vt{get button(){return{id:this.name,icon:"list-numbers",label:window.panel.$t("toolbar.button.ol"),name:this.name,when:["listItem","bulletList","orderedList"]}}commands({type:t,schema:e,utils:s}){return()=>s.toggleList(t,e.nodes.listItem)}inputRules({type:t,utils:e}){return[e.wrappingInputRule(/^(\d+)\.\s$/,t,(t=>({order:+t[1]})),((t,e)=>e.childCount+e.attrs.order===+t[1]))]}keys({type:t,schema:e,utils:s}){return{"Shift-Ctrl-9":s.toggleList(t,e.nodes.listItem)}}get name(){return"orderedList"}get schema(){return{attrs:{order:{default:1}},content:"listItem+",group:"block",parseDOM:[{tag:"ol",getAttrs:t=>({order:t.hasAttribute("start")?+t.getAttribute("start"):1})}],toDOM:t=>1===t.attrs.order?["ol",0]:["ol",{start:t.attrs.order},0]}}}class me extends Kt{commands(){return{undo:()=>A,redo:()=>T,undoDepth:()=>I,redoDepth:()=>j}}get defaults(){return{depth:"",newGroupDelay:""}}keys(){return{"Mod-z":A,"Mod-y":T,"Shift-Mod-z":T,"Mod-я":A,"Shift-Mod-я":T}}get name(){return"history"}plugins(){return[E({depth:this.options.depth,newGroupDelay:this.options.newGroupDelay})]}}class fe extends Kt{commands(){return{insertHtml:t=>(e,s)=>{let n=document.createElement("div");n.innerHTML=t.trim();const i=v.fromSchema(e.schema).parse(n);s(e.tr.replaceSelectionWith(i).scrollIntoView())}}}}class ge extends Kt{constructor(t={}){super(t)}close(){this.visible=!1,this.emit()}emit(){this.editor.emit("toolbar",{marks:this.marks,nodes:this.nodes,nodeAttrs:this.nodeAttrs,position:this.position,visible:this.visible})}init(){this.position={left:0,bottom:0},this.visible=!1,this.editor.on("blur",(()=>{this.close()})),this.editor.on("deselect",(()=>{this.close()})),this.editor.on("select",(({hasChanged:t})=>{!1!==t?this.open():this.emit()}))}get marks(){return this.editor.activeMarks}get nodes(){return this.editor.activeNodes}get nodeAttrs(){return this.editor.activeNodeAttrs}open(){this.visible=!0,this.reposition(),this.emit()}reposition(){const{from:t,to:e}=this.editor.selection,s=this.editor.view.coordsAtPos(t),n=this.editor.view.coordsAtPos(e,!0),i=this.editor.element.getBoundingClientRect();let o=(s.left+n.left)/2-i.left,r=Math.round(i.bottom-s.top);return this.position={bottom:r,left:o}}get type(){return"toolbar"}}const ke=G({props:{activeMarks:{type:Array,default:()=>[]},activeNodes:{type:Array,default:()=>[]},activeNodeAttrs:{type:[Array,Object],default:()=>[]},editor:{type:Object,required:!0},marks:{type:Array},isParagraphNodeHidden:{type:Boolean,default:!1}},computed:{activeButton(){return Object.values(this.nodeButtons).find((t=>this.isButtonActive(t)))||!1},hasVisibleButtons(){const t=Object.keys(this.nodeButtons);return t.length>1||1===t.length&&!1===t.includes("paragraph")},markButtons(){return this.buttons("mark")},nodeButtons(){let t=this.buttons("node");return!0===this.isParagraphNodeHidden&&t.paragraph&&delete t.paragraph,t}},methods:{buttons(t){const e=this.editor.buttons(t);let s=this.sorting;!1!==s&&!1!==Array.isArray(s)||(s=Object.keys(e));let n={};return s.forEach((t=>{e[t]&&(n[t]=e[t])})),n},command(t,...e){this.$emit("command",t,...e)},isButtonActive(t){if("paragraph"===t.name)return 1===this.activeNodes.length&&this.activeNodes.includes(t.name);let e=!0;if(t.attrs){const s=Object.values(this.activeNodeAttrs).find((e=>JSON.stringify(e)===JSON.stringify(t.attrs)));e=Boolean(s||!1)}return!0===e&&this.activeNodes.includes(t.name)},isButtonCurrent(t){return!!this.activeButton&&this.activeButton.id===t.id},isButtonDisabled(t){var e;if(null==(e=this.activeButton)?void 0:e.when){return!1===this.activeButton.when.includes(t.name)}return!1},needDividerAfterNode(t){let e=["paragraph"],s=Object.keys(this.nodeButtons);return(s.includes("bulletList")||s.includes("orderedList"))&&e.push("h6"),e.includes(t.id)}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-writer-toolbar"},[t.hasVisibleButtons?e("k-dropdown",{nativeOn:{mousedown:function(t){t.preventDefault()}}},[e("k-button",{class:{"k-writer-toolbar-button k-writer-toolbar-nodes":!0,"k-writer-toolbar-button-active":!!t.activeButton},attrs:{icon:t.activeButton.icon||"title"},on:{click:function(e){return t.$refs.nodes.toggle()}}}),e("k-dropdown-content",{ref:"nodes"},[t._l(t.nodeButtons,(function(s,n){return[e("k-dropdown-item",{key:n,attrs:{current:t.isButtonCurrent(s),disabled:t.isButtonDisabled(s),icon:s.icon},on:{click:function(e){return t.command(s.command||n)}}},[t._v(" "+t._s(s.label)+" ")]),t.needDividerAfterNode(s)?e("hr",{key:n+"-divider"}):t._e()]}))],2)],1):t._e(),t._l(t.markButtons,(function(s,n){return e("k-button",{key:n,class:{"k-writer-toolbar-button":!0,"k-writer-toolbar-button-active":t.activeMarks.includes(n)},attrs:{icon:s.icon,tooltip:s.label},on:{mousedown:function(e){return e.preventDefault(),t.command(s.command||n)}}})}))],2)}),[],!1,null,null,null,null).exports,be={props:{autofocus:Boolean,breaks:Boolean,code:Boolean,disabled:Boolean,emptyDocument:{type:Object,default:()=>({type:"doc",content:[]})},headings:[Array,Boolean],inline:{type:Boolean,default:!1},marks:{type:[Array,Boolean],default:!0},nodes:{type:[Array,Boolean],default:()=>["heading","bulletList","orderedList"]},paste:{type:Function,default:()=>()=>!1},placeholder:String,spellcheck:Boolean,extensions:Array,value:{type:String,default:""}}};const ve=G({components:{"k-writer-email-dialog":Qt,"k-writer-link-dialog":Zt,"k-writer-toolbar":ke},mixins:[be],data(){return{editor:null,json:{},html:this.value,isEmpty:!0,toolbar:!1}},computed:{isParagraphNodeHidden(){return!0===Array.isArray(this.nodes)&&3!==this.nodes.length&&!1===this.nodes.includes("paragraph")}},watch:{value(t,e){t!==e&&t!==this.html&&(this.html=t,this.editor.setContent(this.html))}},mounted(){this.editor=new Xt({autofocus:this.autofocus,content:this.value,editable:!this.disabled,element:this.$el,emptyDocument:this.emptyDocument,events:{link:t=>{this.$refs.linkDialog.open(t.getMarkAttrs("link"))},email:()=>{this.$refs.emailDialog.open(this.editor.getMarkAttrs("email"))},paste:this.paste,toolbar:t=>{this.toolbar=t,this.toolbar.visible&&this.$nextTick((()=>{this.onToolbarOpen()}))},update:t=>{if(!this.editor)return;const e=JSON.stringify(this.editor.getJSON());e!==JSON.stringify(this.json)&&(this.json=e,this.isEmpty=t.editor.isEmpty(),this.html=t.editor.getHTML(),this.isEmpty&&(0===t.editor.activeNodes.length||t.editor.activeNodes.includes("paragraph"))&&(this.html=""),this.$emit("input",this.html))}},extensions:[...this.createMarks(),...this.createNodes(),new me,new fe,new ge,...this.extensions||[]],inline:this.inline}),this.isEmpty=this.editor.isEmpty(),this.json=this.editor.getJSON()},beforeDestroy(){this.editor.destroy()},methods:{filterExtensions(t,e,s){!1===e?e=[]:!0!==e&&!1!==Array.isArray(e)||(e=Object.keys(t));let n=[];return e.forEach((e=>{t[e]&&n.push(t[e])})),"function"==typeof s&&(n=s(e,n)),n},command(t,...e){this.editor.command(t,...e)},createMarks(){return this.filterExtensions({bold:new se,italic:new ne,strike:new re,underline:new le,code:new ee,link:new ie,email:new oe},this.marks)},createNodes(){const t=new ue({text:!0,enter:this.inline});return!0===this.inline?[t]:this.filterExtensions({bulletList:new ae,orderedList:new he,heading:new ce,horizontalRule:new de,listItem:new pe},this.nodes,((e,s)=>((e.includes("bulletList")||e.includes("orderedList"))&&s.push(new pe),s.push(t),s)))},getHTML(){return this.editor.getHTML()},focus(){this.editor.focus()},onToolbarOpen(){if(this.$refs.toolbar){const t=this.$el.clientWidth,e=this.$refs.toolbar.$el.clientWidth;let s=this.toolbar.position.left;s-e/2<0&&(s=s+(e/2-s)-20),s+e/2>t&&(s=s-(s+e/2-t)+20),s!==this.toolbar.position.left&&(this.$refs.toolbar.$el.style.left=s+"px")}}}},(function(){var t=this,e=t._self._c;return e("div",{directives:[{name:"direction",rawName:"v-direction"}],ref:"editor",staticClass:"k-writer",attrs:{"data-empty":t.isEmpty,"data-placeholder":t.placeholder,spellcheck:t.spellcheck}},[t.editor?[t.toolbar.visible?e("k-writer-toolbar",{ref:"toolbar",style:{bottom:t.toolbar.position.bottom+"px","inset-inline-start":t.toolbar.position.left+"px"},attrs:{editor:t.editor,"active-marks":t.toolbar.marks,"active-nodes":t.toolbar.nodes,"active-node-attrs":t.toolbar.nodeAttrs,"is-paragraph-node-hidden":t.isParagraphNodeHidden},on:{command:function(e){return t.editor.command(e)}}}):t._e(),e("k-writer-link-dialog",{ref:"linkDialog",on:{close:function(e){return t.editor.focus()},submit:function(e){return t.editor.command("toggleLink",e)}}}),e("k-writer-email-dialog",{ref:"emailDialog",on:{close:function(e){return t.editor.focus()},submit:function(e){return t.editor.command("toggleEmail",e)}}})]:t._e()],2)}),[],!1,null,null,null,null).exports;const ye=G({},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-login-alert",on:{click:function(e){return t.$emit("click")}}},[e("span",[t._t("default")],2),e("k-icon",{attrs:{type:"alert"}})],1)}),[],!1,null,null,null,null).exports;const $e=G({props:{fields:Object,index:[Number,String],total:Number,value:Object},mounted(){this.$store.dispatch("content/disable"),this.$events.$on("keydown.cmd.s",this.onSubmit),this.$events.$on("keydown.esc",this.onDiscard)},destroyed(){this.$events.$off("keydown.cmd.s",this.onSubmit),this.$events.$off("keydown.esc",this.onDiscard),this.$store.dispatch("content/enable")},methods:{focus(t){this.$refs.form.focus(t)},onDiscard(){this.$emit("discard")},onInput(t){this.$emit("input",t)},onSubmit(){this.$emit("submit")}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-structure-form"},[e("div",{staticClass:"k-structure-backdrop",on:{click:t.onDiscard}}),e("section",[e("k-form",{ref:"form",staticClass:"k-structure-form-fields",attrs:{value:t.value,fields:t.fields},on:{input:t.onInput,submit:t.onSubmit}}),e("footer",{staticClass:"k-structure-form-buttons"},[e("k-button",{staticClass:"k-structure-form-cancel-button",attrs:{text:t.$t("cancel"),icon:"cancel"},on:{click:function(e){return t.$emit("close")}}}),"new"!==t.index?e("k-pagination",{attrs:{dropdown:!1,total:t.total,limit:1,page:t.index+1,details:!0},on:{paginate:function(e){return t.$emit("paginate",e)}}}):t._e(),e("k-button",{staticClass:"k-structure-form-submit-button",attrs:{text:t.$t("new"!==t.index?"confirm":"add"),icon:"check"},on:{click:t.onSubmit}})],1)],1)])}),[],!1,null,null,null,null).exports,_e=function(t){this.command("insert",((e,s)=>{let n=[];return s.split("\n").forEach(((e,s)=>{let i="ol"===t?s+1+".":"-";n.push(i+" "+e)})),n.join("\n")}))};const xe=G({layout:["headlines","bold","italic","|","link","email","file","|","code","ul","ol"],props:{buttons:{type:[Boolean,Array],default:!0},uploads:[Boolean,Object,Array]},data(){let t={},e={},s=[],n=this.commands();return!1===this.buttons?t:(Array.isArray(this.buttons)&&(s=this.buttons),!0!==Array.isArray(this.buttons)&&(s=this.$options.layout),s.forEach(((s,i)=>{if("|"===s)t["divider-"+i]={divider:!0};else if(n[s]){let i=n[s];t[s]=i,i.shortcut&&(e[i.shortcut]=s)}})),{layout:t,shortcuts:e})},methods:{command(t,e){"function"==typeof t?t.apply(this):this.$emit("command",t,e)},close(){Object.keys(this.$refs).forEach((t=>{const e=this.$refs[t][0];"function"==typeof(null==e?void 0:e.close)&&e.close()}))},fileCommandSetup(){let t={label:this.$t("toolbar.button.file"),icon:"attachment"};return!1===this.uploads?t.command="selectFile":t.dropdown={select:{label:this.$t("toolbar.button.file.select"),icon:"check",command:"selectFile"},upload:{label:this.$t("toolbar.button.file.upload"),icon:"upload",command:"uploadFile"}},t},commands(){return{headlines:{label:this.$t("toolbar.button.headings"),icon:"title",dropdown:{h1:{label:this.$t("toolbar.button.heading.1"),icon:"title",command:"prepend",args:"#"},h2:{label:this.$t("toolbar.button.heading.2"),icon:"title",command:"prepend",args:"##"},h3:{label:this.$t("toolbar.button.heading.3"),icon:"title",command:"prepend",args:"###"}}},bold:{label:this.$t("toolbar.button.bold"),icon:"bold",command:"wrap",args:"**",shortcut:"b"},italic:{label:this.$t("toolbar.button.italic"),icon:"italic",command:"wrap",args:"*",shortcut:"i"},link:{label:this.$t("toolbar.button.link"),icon:"url",shortcut:"k",command:"dialog",args:"link"},email:{label:this.$t("toolbar.button.email"),icon:"email",shortcut:"e",command:"dialog",args:"email"},file:this.fileCommandSetup(),code:{label:this.$t("toolbar.button.code"),icon:"code",command:"wrap",args:"`"},ul:{label:this.$t("toolbar.button.ul"),icon:"list-bullet",command(){return _e.apply(this,["ul"])}},ol:{label:this.$t("toolbar.button.ol"),icon:"list-numbers",command(){return _e.apply(this,["ol"])}}}},shortcut(t,e){if(this.shortcuts[t]){const s=this.layout[this.shortcuts[t]];if(!s)return!1;e.preventDefault(),this.command(s.command,s.args)}}}},(function(){var t=this,e=t._self._c;return e("nav",{staticClass:"k-toolbar"},[e("div",{staticClass:"k-toolbar-wrapper"},[e("div",{staticClass:"k-toolbar-buttons"},[t._l(t.layout,(function(s,n){return[s.divider?[e("span",{key:n,staticClass:"k-toolbar-divider"})]:s.dropdown?[e("k-dropdown",{key:n},[e("k-button",{key:n,staticClass:"k-toolbar-button",attrs:{icon:s.icon,tooltip:s.label,tabindex:"-1"},on:{click:function(e){t.$refs[n+"-dropdown"][0].toggle()}}}),e("k-dropdown-content",{ref:n+"-dropdown",refInFor:!0},t._l(s.dropdown,(function(s,n){return e("k-dropdown-item",{key:n,attrs:{icon:s.icon},on:{click:function(e){return t.command(s.command,s.args)}}},[t._v(" "+t._s(s.label)+" ")])})),1)],1)]:[e("k-button",{key:n,staticClass:"k-toolbar-button",attrs:{icon:s.icon,tooltip:s.label,tabindex:"-1"},on:{click:function(e){return t.command(s.command,s.args)}}})]]}))],2)])])}),[],!1,null,null,null,null).exports;const we=G({data(){return{value:{email:null,text:null},fields:{email:{label:this.$t("email"),type:"email"},text:{label:this.$t("link.text"),type:"text"}}}},computed:{kirbytext(){return this.$config.kirbytext}},methods:{open(t,e){this.value.text=e,this.$refs.dialog.open()},cancel(){this.$emit("cancel")},createKirbytext(){var t;const e=this.value.email||"";return(null==(t=this.value.text)?void 0:t.length)>0?`(email: ${e} text: ${this.value.text})`:`(email: ${e})`},createMarkdown(){var t;const e=this.value.email||"";return(null==(t=this.value.text)?void 0:t.length)>0?`[${this.value.text}](mailto:${e})`:`<${e}>`},submit(){this.$emit("submit",this.kirbytext?this.createKirbytext():this.createMarkdown()),this.value={email:null,text:null},this.$refs.dialog.close()}}},(function(){var t=this,e=t._self._c;return e("k-dialog",{ref:"dialog",attrs:{"submit-button":t.$t("insert")},on:{close:t.cancel,submit:function(e){return t.$refs.form.submit()}}},[e("k-form",{ref:"form",attrs:{fields:t.fields,value:t.value},on:{input:function(e){t.value=e},submit:t.submit}})],1)}),[],!1,null,null,null,null).exports;const Se=G({data(){return{value:{url:null,text:null},fields:{url:{label:this.$t("link"),type:"text",placeholder:this.$t("url.placeholder"),icon:"url"},text:{label:this.$t("link.text"),type:"text"}}}},computed:{kirbytext(){return this.$config.kirbytext}},methods:{open(t,e){this.value.text=e,this.$refs.dialog.open()},cancel(){this.$emit("cancel")},createKirbytext(){return this.value.text.length>0?`(link: ${this.value.url} text: ${this.value.text})`:`(link: ${this.value.url})`},createMarkdown(){return this.value.text.length>0?`[${this.value.text}](${this.value.url})`:`<${this.value.url}>`},submit(){this.$emit("submit",this.kirbytext?this.createKirbytext():this.createMarkdown()),this.value={url:null,text:null},this.$refs.dialog.close()}}},(function(){var t=this,e=t._self._c;return e("k-dialog",{ref:"dialog",attrs:{"submit-button":t.$t("insert")},on:{close:t.cancel,submit:function(e){return t.$refs.form.submit()}}},[e("k-form",{ref:"form",attrs:{fields:t.fields,value:t.value},on:{input:function(e){t.value=e},submit:t.submit}})],1)}),[],!1,null,null,null,null).exports;const Ce=G({mixins:[yt,_t,wt,Ct,At],inheritAttrs:!1,props:{value:Boolean},watch:{value(){this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus()},methods:{focus(){this.$refs.input.focus()},onChange(t){this.$emit("input",t)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},select(){this.focus()}},validations(){return{value:{required:!this.required||M.required}}}},(function(){var t=this,e=t._self._c;return e("label",{staticClass:"k-checkbox-input",on:{click:function(t){t.stopPropagation()}}},[e("input",{ref:"input",staticClass:"k-checkbox-input-native input-hidden",attrs:{id:t.id,disabled:t.disabled,type:"checkbox"},domProps:{checked:t.value},on:{change:function(e){return t.onChange(e.target.checked)}}}),e("span",{staticClass:"k-checkbox-input-icon",attrs:{"aria-hidden":"true"}},[e("svg",{attrs:{width:"12",height:"10",viewBox:"0 0 12 10",xmlns:"http://www.w3.org/2000/svg"}},[e("path",{attrs:{d:"M1 5l3.3 3L11 1","stroke-width":"2",fill:"none","fill-rule":"evenodd"}})])]),e("span",{staticClass:"k-checkbox-input-label",domProps:{innerHTML:t._s(t.label)}})])}),[],!1,null,null,null,null).exports,Oe={mixins:[yt,_t,wt,At],props:{columns:Number,max:Number,min:Number,options:Array,value:{type:[Array,Object],default:()=>[]}}};const Ae=G({mixins:[Oe],inheritAttrs:!1,data(){return{selected:this.toArray(this.value)}},watch:{value(t){this.selected=this.toArray(t)},selected(){this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus()},methods:{focus(){this.$el.querySelector("input").focus()},onInput(t,e){if(!0===e)this.selected.push(t);else{const e=this.selected.indexOf(t);-1!==e&&this.selected.splice(e,1)}this.$emit("input",this.selected)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},select(){this.focus()},toArray:t=>!0===Array.isArray(t)?t:"string"==typeof t?String(t).split(","):"object"==typeof t?Object.values(t):void 0},validations(){return{selected:{required:!this.required||M.required,min:!this.min||M.minLength(this.min),max:!this.max||M.maxLength(this.max)}}}},(function(){var t=this,e=t._self._c;return e("ul",{staticClass:"k-checkboxes-input",style:"--columns:"+t.columns},[t.options.length?t._l(t.options,(function(s,n){return e("li",{key:n},[e("k-checkbox-input",{attrs:{id:t.id+"-"+n,label:s.text,value:-1!==t.selected.indexOf(s.value)},on:{input:function(e){return t.onInput(s.value,e)}}})],1)})):e("k-box",{attrs:{theme:"info"}},[t._v(t._s(t.$t("options.none")))])],2)}),[],!1,null,null,null,null).exports,Te={mixins:[yt,_t,wt,At],props:{display:{type:String,default:"DD.MM.YYYY"},max:String,min:String,step:{type:Object,default:()=>({size:1,unit:"day"})},type:{type:String,default:"date"},value:String}};const Ie=G({mixins:[Te],inheritAttrs:!1,data:()=>({dt:null,formatted:null}),computed:{inputType:()=>"date",pattern(){return this.$library.dayjs.pattern(this.display)},rounding(){return{...this.$options.props.step.default(),...this.step}}},watch:{value:{handler(t,e){if(t!==e){const e=this.toDatetime(t);this.commit(e)}},immediate:!0}},created(){this.$events.$on("keydown.cmd.s",this.onBlur)},destroyed(){this.$events.$off("keydown.cmd.s",this.onBlur)},methods:{alter(t){let e=this.parse()||this.round(this.$library.dayjs()),s=this.rounding.unit,n=this.rounding.size;const i=this.selection();null!==i&&("meridiem"===i.unit?(t="pm"===e.format("a")?"subtract":"add",s="hour",n=12):(s=i.unit,s!==this.rounding.unit&&(n=1))),e=e[t](n,s).round(this.rounding.unit,this.rounding.size),this.commit(e),this.emit(e),this.$nextTick((()=>this.select(i)))},commit(t){this.dt=t,this.formatted=this.pattern.format(t),this.$emit("invalid",this.$v.$invalid,this.$v)},emit(t){this.$emit("input",this.toISO(t))},focus(){this.$refs.input.focus()},onArrowDown(){this.alter("subtract")},onArrowUp(){this.alter("add")},onBlur(){const t=this.parse();this.commit(t),this.emit(t)},onEnter(){this.onBlur(),this.$nextTick((()=>this.$emit("submit")))},onInput(t){const e=this.parse(),s=this.pattern.format(e);if(!t||s==t)return this.commit(e),this.emit(e)},onTab(t){""!=this.$refs.input.value&&(this.onBlur(),this.$nextTick((()=>{const e=this.selection();if(this.$refs.input&&e.start===this.$refs.input.selectionStart&&e.end===this.$refs.input.selectionEnd-1)if(t.shiftKey){if(0===e.index)return;this.selectPrev(e.index)}else{if(e.index===this.pattern.parts.length-1)return;this.selectNext(e.index)}else t.shiftKey?this.selectLast():this.selectFirst();t.preventDefault()})))},parse(){let t=this.$refs.input.value;return t=this.$library.dayjs.interpret(t,this.inputType),this.round(t)},round(t){return(null==t?void 0:t.round(this.rounding.unit,this.rounding.size))||null},select(t){var e;t||(t=this.selection()),null==(e=this.$refs.input)||e.setSelectionRange(t.start,t.end+1)},selectFirst(){this.select(this.pattern.parts[0])},selectLast(){this.select(this.pattern.parts[this.pattern.parts.length-1])},selectNext(t){this.select(this.pattern.parts[t+1])},selectPrev(t){this.select(this.pattern.parts[t-1])},selection(){return this.pattern.at(this.$refs.input.selectionStart,this.$refs.input.selectionEnd)},toDatetime(t){return this.round(this.$library.dayjs.iso(t,this.inputType))},toISO(t){return(null==t?void 0:t.toISO(this.inputType))||null}},validations(){return{value:{min:!this.dt||!this.min||(()=>this.dt.validate(this.min,"min",this.rounding.unit)),max:!this.dt||!this.max||(()=>this.dt.validate(this.max,"max",this.rounding.unit)),required:!this.required||(()=>!!this.dt)}}}},(function(){var t=this;return(0,t._self._c)("input",{directives:[{name:"direction",rawName:"v-direction"}],ref:"input",class:`k-text-input k-${t.type}-input`,attrs:{id:t.id,autofocus:t.autofocus,disabled:t.disabled,placeholder:t.display,required:t.required,autocomplete:"off",spellcheck:"false",type:"text"},domProps:{value:t.formatted},on:{blur:t.onBlur,focus:function(e){return t.$emit("focus")},input:function(e){return t.onInput(e.target.value)},keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"down",40,e.key,["Down","ArrowDown"])?null:(e.stopPropagation(),e.preventDefault(),t.onArrowDown.apply(null,arguments))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"up",38,e.key,["Up","ArrowUp"])?null:(e.stopPropagation(),e.preventDefault(),t.onArrowUp.apply(null,arguments))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:(e.stopPropagation(),e.preventDefault(),t.onEnter.apply(null,arguments))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"tab",9,e.key,"Tab")?null:t.onTab.apply(null,arguments)}]}})}),[],!1,null,null,null,null).exports,je={mixins:[yt,_t,wt,Ot,At],props:{autocomplete:{type:[Boolean,String],default:"off"},maxlength:Number,minlength:Number,pattern:String,placeholder:String,preselect:Boolean,spellcheck:{type:[Boolean,String],default:"off"},type:{type:String,default:"text"},value:String}};const Ee=G({mixins:[je],inheritAttrs:!1,data(){return{listeners:{...this.$listeners,input:t=>this.onInput(t.target.value)}}},watch:{value(){this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus(),this.$props.preselect&&this.select()},methods:{focus(){this.$refs.input.focus()},onInput(t){this.$emit("input",t)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},select(){this.$refs.input.select()}},validations(){return{value:{required:!this.required||M.required,minLength:!this.minlength||M.minLength(this.minlength),maxLength:!this.maxlength||M.maxLength(this.maxlength),email:"email"!==this.type||M.email,url:"url"!==this.type||M.url,pattern:!this.pattern||(t=>!this.required&&!t||!this.$refs.input.validity.patternMismatch)}}}},(function(){var t=this;return(0,t._self._c)("input",t._g(t._b({directives:[{name:"direction",rawName:"v-direction"}],ref:"input",staticClass:"k-text-input"},"input",{autocomplete:t.autocomplete,autofocus:t.autofocus,disabled:t.disabled,id:t.id,minlength:t.minlength,name:t.name,pattern:t.pattern,placeholder:t.placeholder,required:t.required,spellcheck:t.spellcheck,type:t.type,value:t.value},!1),t.listeners))}),[],!1,null,null,null,null).exports,Me={mixins:[je],props:{autocomplete:{type:String,default:"email"},placeholder:{type:String,default:()=>window.panel.$t("email.placeholder")},type:{type:String,default:"email"}}};const Le=G({extends:Ee,mixins:[Me]},null,null,!1,null,null,null,null).exports;class Be extends Jt{get schema(){return{content:"bulletList|orderedList"}}}const De=G({inheritAttrs:!1,props:{autofocus:Boolean,marks:{type:[Array,Boolean],default:!0},value:String},data(){return{list:this.value,html:this.value}},computed:{extensions:()=>[new Be({inline:!0})]},watch:{value(t){t!==this.html&&(this.list=t,this.html=t)}},methods:{focus(){this.$refs.input.focus()},onInput(t){let e=(new DOMParser).parseFromString(t,"text/html").querySelector("ul, ol");e&&0!==e.textContent.trim().length?(this.list=t,this.html=t.replace(/(

|<\/p>)/gi,""),this.$emit("input",this.html)):this.$emit("input",this.list="")}}},(function(){var t=this;return(0,t._self._c)("k-writer",t._b({ref:"input",staticClass:"k-list-input",attrs:{extensions:t.extensions,nodes:["bulletList","orderedList"],value:t.list},on:{input:t.onInput}},"k-writer",t.$props,!1))}),[],!1,null,null,null,null).exports,Pe={mixins:[_t,wt,At],props:{max:Number,min:Number,layout:String,options:Array,search:[Object,Boolean],separator:{type:String,default:","},sort:Boolean,value:{type:Array,required:!0,default:()=>[]}}};const Ne=G({mixins:[Pe],inheritAttrs:!1,data(){return{state:this.value,q:null,limit:!0,scrollTop:0}},computed:{draggable(){return this.state.length>1&&!this.sort},dragOptions(){return{disabled:!this.draggable,draggable:".k-tag",delay:1}},emptyLabel(){return this.q?this.$t("search.results.none"):this.$t("options.none")},filtered(){var t;return(null==(t=this.q)?void 0:t.length)>=(this.search.min||0)?this.options.filter((t=>this.isFiltered(t))).map((t=>({...t,text:this.toHighlightedString(t.text)}))):this.options},more(){return!this.max||this.state.lengththis.options.find((e=>e.value===t))));if(!1===this.sort)return t;const e=t=>this.options.findIndex((e=>e.value===t.value));return t.sort(((t,s)=>e(t)-e(s)))},visible(){return this.limit?this.filtered.slice(0,this.search.display||this.filtered.length):this.filtered}},watch:{value(t){this.state=t,this.onInvalid()}},mounted(){this.onInvalid(),this.$events.$on("click",this.close),this.$events.$on("keydown.cmd.s",this.close)},destroyed(){this.$events.$off("click",this.close),this.$events.$off("keydown.cmd.s",this.close)},methods:{add(t){!0===this.more&&(this.state.push(t.value),this.onInput())},blur(){this.close()},close(){var t;!0===(null==(t=this.$refs.dropdown)?void 0:t.isOpen)&&(this.$refs.dropdown.close(),this.limit=!0)},focus(){var t;null==(t=this.$refs.dropdown)||t.open()},index(t){return this.state.findIndex((e=>e===t.value))},isFiltered(t){return String(t.text).match(this.regex)||String(t.value).match(this.regex)},isSelected(t){return-1!==this.index(t)},navigate(t){var e,s,n;"prev"===t&&(t="previous"),null==(n=null==(s=null==(e=document.activeElement)?void 0:e[t+"Sibling"])?void 0:s.focus)||n.call(s)},onClose(){var t;!1===(null==(t=this.$refs.dropdown)?void 0:t.isOpen)&&(document.activeElement===this.$parent.$el&&(this.q=null),this.$parent.$el.focus())},onEscape(){this.q?this.q=null:this.close()},onInput(){this.$emit("input",this.state)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},onOpen(){this.$nextTick((()=>{var t,e,s;null==(e=null==(t=this.$refs.search)?void 0:t.focus)||e.call(t),(null==(s=this.$refs.dropdown)?void 0:s.$el)&&(this.$refs.dropdown.$el.querySelector(".k-multiselect-options").scrollTop=this.scrollTop)}))},remove(t){const e=this.index(t);this.state.splice(e,1),this.onInput()},select(t){this.scrollTop=this.$refs.dropdown.$el.querySelector(".k-multiselect-options").scrollTop,this.isSelected(t)?this.remove(t):this.add(t)},toHighlightedString(t){return(t=this.$helper.string.stripHTML(t)).replace(this.regex,"$1")}},validations(){return{state:{required:!this.required||M.required,minLength:!this.min||M.minLength(this.min),maxLength:!this.max||M.maxLength(this.max)}}}},(function(){var t=this,e=t._self._c;return e("k-draggable",{staticClass:"k-multiselect-input",attrs:{list:t.state,options:t.dragOptions,"data-layout":t.layout,element:"k-dropdown"},on:{end:t.onInput},nativeOn:{click:function(e){return t.$refs.dropdown.toggle.apply(null,arguments)}},scopedSlots:t._u([{key:"footer",fn:function(){return[e("k-dropdown-content",{ref:"dropdown",on:{open:t.onOpen,close:t.onClose},nativeOn:{keydown:function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"esc",27,e.key,["Esc","Escape"])?null:(e.stopPropagation(),t.close.apply(null,arguments))}}},[t.search?e("k-dropdown-item",{staticClass:"k-multiselect-search",attrs:{icon:"search"}},[e("input",{ref:"search",attrs:{placeholder:t.search.min?t.$t("search.min",{min:t.search.min}):t.$t("search")+" …"},domProps:{value:t.q},on:{input:function(e){t.q=e},keydown:function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"esc",27,e.key,["Esc","Escape"])?null:(e.stopPropagation(),t.onEscape.apply(null,arguments))}}})]):t._e(),e("div",{staticClass:"k-multiselect-options scroll-y-auto"},[t._l(t.visible,(function(s){return e("k-dropdown-item",{key:s.value,class:{"k-multiselect-option":!0,selected:t.isSelected(s),disabled:!t.more},attrs:{icon:t.isSelected(s)?"check":"circle-outline"},on:{click:function(e){return e.preventDefault(),t.select(s)}},nativeOn:{keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:(e.preventDefault(),e.stopPropagation(),t.select(s))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"space",32,e.key,[" ","Spacebar"])?null:(e.preventDefault(),e.stopPropagation(),t.select(s))}]}},[e("span",{domProps:{innerHTML:t._s(s.text)}})])})),0===t.filtered.length?e("k-dropdown-item",{staticClass:"k-multiselect-option",attrs:{disabled:!0}},[t._v(" "+t._s(t.emptyLabel)+" ")]):t._e()],2),t.visible.lengththis.onInput(t.target.value),blur:this.onBlur}}},watch:{value(t){this.number=t},number:{immediate:!0,handler(){this.onInvalid()}}},mounted(){this.$props.autofocus&&this.focus(),this.$props.preselect&&this.select()},methods:{decimals(){const t=Number(this.step||0);return Math.floor(t)===t?0:-1!==t.toString().indexOf("e")?parseInt(t.toFixed(16).split(".")[1].split("").reverse().join("")).toString().length:t.toString().split(".")[1].length||0},format(t){if(isNaN(t)||""===t)return"";const e=this.decimals();return t=e?parseFloat(t).toFixed(e):Number.isInteger(this.step)?parseInt(t):parseFloat(t)},clean(){this.number=this.format(this.number)},emit(t){t=parseFloat(t),isNaN(t)&&(t=""),t!==this.value&&this.$emit("input",t)},focus(){this.$refs.input.focus()},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},onInput(t){this.number=t,this.emit(t)},onBlur(){this.clean(),this.emit(this.number)},select(){this.$refs.input.select()}},validations(){return{value:{required:!this.required||M.required,min:!this.min||M.minValue(this.min),max:!this.max||M.maxValue(this.max)}}}},(function(){var t=this;return(0,t._self._c)("input",t._g(t._b({ref:"input",staticClass:"k-number-input",attrs:{step:t.stepNumber,type:"number"},domProps:{value:t.number},on:{keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"s",void 0,e.key,void 0)?null:e.ctrlKey?t.clean.apply(null,arguments):null},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"s",void 0,e.key,void 0)?null:e.metaKey?t.clean.apply(null,arguments):null}]}},"input",{autofocus:t.autofocus,disabled:t.disabled,id:t.id,max:t.max,min:t.min,name:t.name,placeholder:t.placeholder,required:t.required},!1),t.listeners))}),[],!1,null,null,null,null).exports,Re={mixins:[je],props:{autocomplete:{type:String,default:"new-password"},type:{type:String,default:"password"}}};const ze=G({extends:Ee,mixins:[Re]},null,null,!1,null,null,null,null).exports,Ye={mixins:[yt,_t,wt,At],props:{columns:Number,options:Array,value:[String,Number,Boolean]}};const He=G({mixins:[Ye],inheritAttrs:!1,watch:{value(){this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus()},methods:{focus(){this.$el.querySelector("input").focus()},onInput(t){this.$emit("input",t)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},select(){this.focus()}},validations(){return{value:{required:!this.required||M.required}}}},(function(){var t=this,e=t._self._c;return e("ul",{staticClass:"k-radio-input",style:"--columns:"+t.columns},[t.options.length?t._l(t.options,(function(s,n){return e("li",{key:n},[e("input",{staticClass:"k-radio-input-native",attrs:{id:t.id+"-"+n,name:t.id,type:"radio"},domProps:{value:s.value,checked:t.value===s.value},on:{change:function(e){return t.onInput(s.value)}}}),s.info?e("label",{attrs:{for:t.id+"-"+n}},[e("span",{staticClass:"k-radio-input-text",domProps:{innerHTML:t._s(s.text)}}),e("span",{staticClass:"k-radio-input-info",domProps:{innerHTML:t._s(s.info)}})]):e("label",{attrs:{for:t.id+"-"+n},domProps:{innerHTML:t._s(s.text)}}),s.icon?e("k-icon",{attrs:{type:s.icon}}):t._e()],1)})):e("k-box",{attrs:{theme:"info"}},[t._v(t._s(t.$t("options.none")))])],2)}),[],!1,null,null,null,null).exports,Ue={mixins:[yt,_t,wt,Ot,At],props:{default:[Number,String],max:{type:Number,default:100},min:{type:Number,default:0},step:{type:Number,default:1},tooltip:{type:[Boolean,Object],default:()=>({before:null,after:null})},value:[Number,String]}};const Ke=G({mixins:[Ue],inheritAttrs:!1,data(){return{listeners:{...this.$listeners,input:t=>this.onInput(t.target.value)}}},computed:{baseline(){return this.min<0?0:this.min},label(){return this.required||this.value||0===this.value?this.format(this.position):"–"},position(){return this.value||0===this.value?this.value:this.default||this.baseline}},watch:{position(){this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus()},methods:{focus(){this.$refs.input.focus()},format(t){const e=document.lang?document.lang.replace("_","-"):"en",s=this.step.toString().split("."),n=s.length>1?s[1].length:0;return new Intl.NumberFormat(e,{minimumFractionDigits:n}).format(t)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},onInput(t){this.$emit("input",t)}},validations(){return{position:{required:!this.required||M.required,min:!this.min||M.minValue(this.min),max:!this.max||M.maxValue(this.max)}}}},(function(){var t=this,e=t._self._c;return e("label",{staticClass:"k-range-input"},[e("input",t._g(t._b({ref:"input",staticClass:"k-range-input-native",style:`--min: ${t.min}; --max: ${t.max}; --value: ${t.position}`,attrs:{type:"range"},domProps:{value:t.position}},"input",{autofocus:t.autofocus,disabled:t.disabled,id:t.id,max:t.max,min:t.min,name:t.name,required:t.required,step:t.step},!1),t.listeners)),t.tooltip?e("span",{staticClass:"k-range-input-tooltip"},[t.tooltip.before?e("span",{staticClass:"k-range-input-tooltip-before"},[t._v(t._s(t.tooltip.before))]):t._e(),e("span",{staticClass:"k-range-input-tooltip-text"},[t._v(t._s(t.label))]),t.tooltip.after?e("span",{staticClass:"k-range-input-tooltip-after"},[t._v(t._s(t.tooltip.after))]):t._e()]):t._e()])}),[],!1,null,null,null,null).exports,Ve={mixins:[yt,_t,wt,Ot,At],props:{ariaLabel:String,default:String,empty:{type:[Boolean,String],default:!0},placeholder:String,options:Array,value:{type:[String,Number,Boolean],default:""}}};const Je=G({mixins:[Ve],inheritAttrs:!1,data(){return{selected:this.value,listeners:{...this.$listeners,click:t=>this.onClick(t),change:t=>this.onInput(t.target.value),input:()=>{}}}},computed:{emptyOption(){return this.placeholder||"—"},hasEmptyOption(){return!1!==this.empty&&!(this.required&&this.default)},label(){const t=this.text(this.selected);return""===this.selected||null===this.selected||null===t?this.emptyOption:t}},watch:{value(t){this.selected=t,this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus()},methods:{focus(){this.$refs.input.focus()},onClick(t){t.stopPropagation(),this.$emit("click",t)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},onInput(t){this.selected=t,this.$emit("input",this.selected)},select(){this.focus()},text(t){let e=null;return this.options.forEach((s=>{s.value==t&&(e=s.text)})),e}},validations(){return{selected:{required:!this.required||M.required}}}},(function(){var t=this,e=t._self._c;return e("span",{staticClass:"k-select-input",attrs:{"data-disabled":t.disabled,"data-empty":""===t.selected}},[e("select",t._g({ref:"input",staticClass:"k-select-input-native",attrs:{id:t.id,autofocus:t.autofocus,"aria-label":t.ariaLabel,disabled:t.disabled,name:t.name,required:t.required},domProps:{value:t.selected}},t.listeners),[t.hasEmptyOption?e("option",{attrs:{disabled:t.required,value:""}},[t._v(" "+t._s(t.emptyOption)+" ")]):t._e(),t._l(t.options,(function(s){return e("option",{key:s.value,attrs:{disabled:s.disabled},domProps:{value:s.value}},[t._v(" "+t._s(s.text)+" ")])}))],2),t._v(" "+t._s(t.label)+" ")])}),[],!1,null,null,null,null).exports,Ge={mixins:[je],props:{allow:{type:String,default:""},formData:{type:Object,default:()=>({})},sync:{type:String}}};const We=G({extends:Ee,mixins:[Ge],data(){return{slug:this.sluggify(this.value),slugs:this.$language?this.$language.rules:this.$system.slugs,syncValue:null}},watch:{formData:{handler(t){return!this.disabled&&(!(!this.sync||void 0===t[this.sync])&&(t[this.sync]!=this.syncValue&&(this.syncValue=t[this.sync],void this.onInput(this.sluggify(this.syncValue)))))},deep:!0,immediate:!0},value(t){(t=this.sluggify(t))!==this.slug&&(this.slug=t,this.$emit("input",this.slug))}},methods:{sluggify(t){return this.$helper.slug(t,[this.slugs,this.$system.ascii],this.allow)},onInput(t){this.slug=this.sluggify(t),this.$emit("input",this.slug)}}},(function(){var t=this;return(0,t._self._c)("input",t._g(t._b({directives:[{name:"direction",rawName:"v-direction"}],ref:"input",staticClass:"k-text-input",attrs:{autocomplete:"off",spellcheck:"false",type:"text"},domProps:{value:t.slug}},"input",{autofocus:t.autofocus,disabled:t.disabled,id:t.id,minlength:t.minlength,name:t.name,pattern:t.pattern,placeholder:t.placeholder,required:t.required},!1),t.listeners))}),[],!1,null,null,null,null).exports,Xe={mixins:[yt,_t,wt,Ot,At],props:{accept:{type:String,default:"all"},icon:{type:[String,Boolean],default:"tag"},layout:String,max:Number,min:Number,options:{type:Array,default:()=>[]},separator:{type:String,default:","},value:{type:Array,default:()=>[]}}};const Ze=G({mixins:[Xe],inheritAttrs:!1,data(){return{tags:this.toValues(this.value),selected:null,newTag:null}},computed:{dragOptions(){return{delay:1,disabled:!this.draggable,draggable:".k-tag"}},draggable(){return this.tags.length>1},skip(){return this.tags.map((t=>t.value))}},watch:{value(t){this.tags=this.toValues(t),this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus()},methods:{addString(t,e=!0){if(!t)return;if(0===(t=t.trim()).length)return;if(!0===t.includes(this.separator)){for(const e of t.split(this.separator))this.addString(e);return}const s=this.toValue(t);s&&this.addTag(s,e)},addTag(t,e=!0){this.addTagToIndex(t),this.$refs.autocomplete.close(),e&&this.$refs.input.focus()},addTagToIndex(t){if("options"===this.accept){if(!this.options.find((e=>e.value===t.value)))return}-1===this.index(t)&&(!this.max||this.tags.length=this.tags.length)return;break;case"first":e=0;break;case"last":e=this.tags.length-1;break;default:e=t}let n=this.tags[e];if(n){let t=this.$refs[n.value];if(null==t?void 0:t[0])return{ref:t[0],tag:n,index:e}}return!1},index(t){return this.tags.findIndex((e=>e.value===t.value))},navigate(t){var e=this.get(t);e?(e.ref.focus(),this.selectTag(e.tag)):"next"===t&&(this.$refs.input.focus(),this.selectTag(null))},onBack(t){0===t.target.selectionStart&&t.target.selectionStart===t.target.selectionEnd&&0!==this.tags.length&&(this.$refs.autocomplete.close(),this.navigate("last"),t.preventDefault())},onBlur(t){var e;let s=t.relatedTarget||t.explicitOriginalTarget;(null==(e=this.$refs.autocomplete.$el)?void 0:e.contains(s))||this.addString(this.$refs.input.value,!1)},onEnter(t){if(!this.newTag||0===this.newTag.length)return!0;t.preventDefault(),this.addString(this.newTag)},onInput(){const t=this.tags.map((t=>t.value));this.$emit("input",t)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},onSubmit(t){t.preventDefault(),t.stopImmediatePropagation(),this.onBlur(t),this.$emit("submit",t)},onTab(t){var e;(null==(e=this.newTag)?void 0:e.length)>0&&(t.preventDefault(),this.addString(this.newTag))},onType(t){this.newTag=t,this.$refs.autocomplete.search(t)},remove(t){const e=this.get("prev"),s=this.get("next");this.tags.splice(this.index(t),1),this.onInput(),e?(this.selectTag(e.tag),e.ref.focus()):s?this.selectTag(s.tag):(this.selectTag(null),this.$refs.input.focus())},select(){this.focus()},selectTag(t){this.selected=t},toValue(t){var e;const s=this.options.find((e=>e.value===t));return"options"===this.accept?s:s||("string"==typeof t&&(t={value:t}),{value:t.value,text:this.$helper.string.escapeHTML(null!=(e=t.text)?e:t.value)})},toValues(t){return"object"==typeof t&&(t=Object.values(t)),!1===Array.isArray(t)?[]:t.map(this.toValue).filter((t=>t))}},validations(){return{tags:{required:!this.required||M.required,minLength:!this.min||M.minLength(this.min),maxLength:!this.max||M.maxLength(this.max)}}}},(function(){var t=this,e=t._self._c;return e("k-draggable",{directives:[{name:"direction",rawName:"v-direction"}],staticClass:"k-tags-input",attrs:{list:t.tags,options:t.dragOptions,"data-layout":t.layout},on:{end:t.onInput},scopedSlots:t._u([{key:"footer",fn:function(){var s;return[e("span",{staticClass:"k-tags-input-element"},[e("k-autocomplete",{ref:"autocomplete",attrs:{html:!0,options:t.options,skip:t.skip},on:{select:t.addTag,leave:function(e){return t.$refs.input.focus()}}},[e("input",{ref:"input",attrs:{id:t.id,autofocus:t.autofocus,disabled:t.disabled||t.max&&t.tags.length>=t.max,name:t.name,autocomplete:"off",type:"text"},domProps:{value:null==(s=t.newTag)?void 0:s.trim()},on:{input:function(e){return t.onType(e.target.value)},blur:t.onBlur,keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"s",void 0,e.key,void 0)?null:e.metaKey?t.onSubmit.apply(null,arguments):null},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"left",37,e.key,["Left","ArrowLeft"])||"button"in e&&0!==e.button||e.ctrlKey||e.shiftKey||e.altKey||e.metaKey?null:t.onBack.apply(null,arguments)},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")||e.ctrlKey||e.shiftKey||e.altKey||e.metaKey?null:t.onEnter.apply(null,arguments)},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"tab",9,e.key,"Tab")||e.ctrlKey||e.shiftKey||e.altKey||e.metaKey?null:t.onTab.apply(null,arguments)},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"backspace",void 0,e.key,void 0)||e.ctrlKey||e.shiftKey||e.altKey||e.metaKey?null:t.onBack.apply(null,arguments)}]}})])],1)]},proxy:!0}])},t._l(t.tags,(function(s){return e("k-tag",{key:s.value,ref:s.value,refInFor:!0,attrs:{removable:!t.disabled,name:"tag"},on:{remove:function(e){return t.remove(s)}},nativeOn:{click:function(t){t.stopPropagation()},blur:function(e){return t.selectTag(null)},focus:function(e){return t.selectTag(s)},keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"left",37,e.key,["Left","ArrowLeft"])||"button"in e&&0!==e.button?null:t.navigate("prev")},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"right",39,e.key,["Right","ArrowRight"])||"button"in e&&2!==e.button?null:t.navigate("next")}],dblclick:function(e){return t.edit(s)}}},[e("span",{domProps:{innerHTML:t._s(s.text)}})])})),1)}),[],!1,null,null,null,null).exports,Qe={mixins:[je],props:{autocomplete:{type:String,default:"tel"},type:{type:String,default:"tel"}}};const ts=G({extends:Ee,mixins:[Qe]},null,null,!1,null,null,null,null).exports,es={mixins:[yt,_t,wt,Ot,At],props:{buttons:{type:[Boolean,Array],default:!0},endpoints:Object,font:String,maxlength:Number,minlength:Number,placeholder:String,preselect:Boolean,size:String,spellcheck:{type:[Boolean,String],default:"off"},theme:String,uploads:[Boolean,Object,Array],value:String}};const ss=G({mixins:[es],inheritAttrs:!1,data:()=>({over:!1}),watch:{value(){this.onInvalid(),this.$nextTick((()=>{this.resize()}))}},mounted(){this.$nextTick((()=>{this.$library.autosize(this.$refs.input)})),this.onInvalid(),this.$props.autofocus&&this.focus(),this.$props.preselect&&this.select()},methods:{cancel(){this.$refs.input.focus()},dialog(t){if(!this.$refs[t+"Dialog"])throw"Invalid toolbar dialog";this.$refs[t+"Dialog"].open(this.$refs.input,this.selection())},focus(){this.$refs.input.focus()},insert(t){const e=this.$refs.input,s=e.value;setTimeout((()=>{if(e.focus(),document.execCommand("insertText",!1,t),e.value===s){const s=e.value.slice(0,e.selectionStart)+t+e.value.slice(e.selectionEnd);e.value=s,this.$emit("input",s)}})),this.resize()},insertFile(t){(null==t?void 0:t.length)>0&&this.insert(t.map((t=>t.dragText)).join("\n\n"))},insertUpload(t,e){this.insert(e.map((t=>t.dragText)).join("\n\n")),this.$events.$emit("model.update")},onClick(){this.$refs.toolbar&&this.$refs.toolbar.close()},onCommand(t,e){"function"==typeof this[t]?"function"==typeof e?this[t](e(this.$refs.input,this.selection())):this[t](e):window.console.warn(t+" is not a valid command")},onDrop(t){if(this.uploads&&this.$helper.isUploadEvent(t))return this.$refs.fileUpload.drop(t.dataTransfer.files,{url:this.$urls.api+"/"+this.endpoints.field+"/upload",multiple:!1});const e=this.$store.state.drag;"text"===(null==e?void 0:e.type)&&(this.focus(),this.insert(e.data))},onFocus(t){this.$emit("focus",t)},onInput(t){this.$emit("input",t.target.value)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},onOut(){this.$refs.input.blur(),this.over=!1},onOver(t){if(this.uploads&&this.$helper.isUploadEvent(t))return t.dataTransfer.dropEffect="copy",this.focus(),void(this.over=!0);const e=this.$store.state.drag;"text"===(null==e?void 0:e.type)&&(t.dataTransfer.dropEffect="copy",this.focus(),this.over=!0)},onShortcut(t){!1!==this.buttons&&"Meta"!==t.key&&"Control"!==t.key&&this.$refs.toolbar&&this.$refs.toolbar.shortcut(t.key,t)},onSubmit(t){return this.$emit("submit",t)},prepend(t){this.insert(t+" "+this.selection())},resize(){this.$library.autosize.update(this.$refs.input)},select(){this.$refs.select()},selectFile(){this.$refs.fileDialog.open({endpoint:this.endpoints.field+"/files",multiple:!1})},selection(){const t=this.$refs.input,e=t.selectionStart,s=t.selectionEnd;return t.value.substring(e,s)},uploadFile(){this.$refs.fileUpload.open({url:this.$urls.api+"/"+this.endpoints.field+"/upload",multiple:!1})},wrap(t){this.insert(t+this.selection()+t)}},validations(){return{value:{required:!this.required||M.required,minLength:!this.minlength||M.minLength(this.minlength),maxLength:!this.maxlength||M.maxLength(this.maxlength)}}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-textarea-input",attrs:{"data-over":t.over,"data-size":t.size,"data-theme":t.theme}},[e("div",{staticClass:"k-textarea-input-wrapper"},[t.buttons&&!t.disabled?e("k-toolbar",{ref:"toolbar",attrs:{buttons:t.buttons,disabled:t.disabled,uploads:t.uploads},on:{command:t.onCommand},nativeOn:{mousedown:function(t){t.preventDefault()}}}):t._e(),e("textarea",t._b({directives:[{name:"direction",rawName:"v-direction"}],ref:"input",staticClass:"k-textarea-input-native",attrs:{"data-font":t.font},on:{click:t.onClick,focus:t.onFocus,input:t.onInput,keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:e.metaKey?t.onSubmit.apply(null,arguments):null},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:e.ctrlKey?t.onSubmit.apply(null,arguments):null},function(e){return e.metaKey?t.onShortcut.apply(null,arguments):null},function(e){return e.ctrlKey?t.onShortcut.apply(null,arguments):null}],dragover:t.onOver,dragleave:t.onOut,drop:t.onDrop}},"textarea",{autofocus:t.autofocus,disabled:t.disabled,id:t.id,minlength:t.minlength,name:t.name,placeholder:t.placeholder,required:t.required,spellcheck:t.spellcheck,value:t.value},!1))],1),e("k-toolbar-email-dialog",{ref:"emailDialog",on:{cancel:t.cancel,submit:function(e){return t.insert(e)}}}),e("k-toolbar-link-dialog",{ref:"linkDialog",on:{cancel:t.cancel,submit:function(e){return t.insert(e)}}}),e("k-files-dialog",{ref:"fileDialog",on:{cancel:t.cancel,submit:function(e){return t.insertFile(e)}}}),t.uploads?e("k-upload",{ref:"fileUpload",on:{success:t.insertUpload}}):t._e()],1)}),[],!1,null,null,null,null).exports,ns={props:{display:{type:String,default:"HH:mm"},max:String,min:String,step:{type:Object,default:()=>({size:5,unit:"minute"})},type:{type:String,default:"time"},value:String}};const is=G({mixins:[Ie,ns],computed:{inputType:()=>"time"}},null,null,!1,null,null,null,null).exports,os={props:{autofocus:Boolean,disabled:Boolean,id:[Number,String],text:{type:[Array,String]},required:Boolean,value:Boolean}};const rs=G({mixins:[os],inheritAttrs:!1,computed:{label(){const t=this.text||[this.$t("off"),this.$t("on")];return Array.isArray(t)?this.value?t[1]:t[0]:t}},watch:{value(){this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus()},methods:{focus(){this.$refs.input.focus()},onEnter(t){"Enter"===t.key&&this.$refs.input.click()},onInput(t){this.$emit("input",t)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},select(){this.$refs.input.focus()}},validations(){return{value:{required:!this.required||M.required}}}},(function(){var t=this,e=t._self._c;return e("label",{staticClass:"k-toggle-input",attrs:{"data-disabled":t.disabled}},[e("input",{ref:"input",staticClass:"k-toggle-input-native",attrs:{id:t.id,disabled:t.disabled,type:"checkbox"},domProps:{checked:t.value},on:{change:function(e){return t.onInput(e.target.checked)}}}),e("span",{staticClass:"k-toggle-input-label",domProps:{innerHTML:t._s(t.label)}})])}),[],!1,null,null,null,null).exports,ls={mixins:[yt,_t,wt,At],props:{columns:Number,grow:Boolean,labels:Boolean,options:Array,reset:Boolean,value:[String,Number,Boolean]}};const as=G({mixins:[ls],inheritAttrs:!1,watch:{value(){this.onInvalid()}},mounted(){this.onInvalid(),this.$props.autofocus&&this.focus()},methods:{focus(){(this.$el.querySelector("input[checked]")||this.$el.querySelector("input")).focus()},onClick(t){t===this.value&&this.reset&&!this.required&&this.$emit("input","")},onInput(t){this.$emit("input",t)},onInvalid(){this.$emit("invalid",this.$v.$invalid,this.$v)},select(){this.focus()}},validations(){return{value:{required:!this.required||M.required}}}},(function(){var t=this,e=t._self._c;return e("ul",{staticClass:"k-toggles-input",style:"--options:"+(t.columns||t.options.length),attrs:{"data-invalid":t.$v.$invalid,"data-labels":t.labels}},t._l(t.options,(function(s,n){return e("li",{key:n},[e("input",{staticClass:"input-hidden",attrs:{id:t.id+"-"+n,name:t.id,type:"radio"},domProps:{value:s.value,checked:t.value===s.value},on:{click:function(e){return t.onClick(s.value)},change:function(e){return t.onInput(s.value)}}}),e("label",{attrs:{for:t.id+"-"+n,title:s.text}},[s.icon?e("k-icon",{attrs:{type:s.icon}}):t._e(),t.labels?e("span",{staticClass:"k-toggles-text",domProps:{innerHTML:t._s(s.text)}}):t._e()],1)])})),0)}),[],!1,null,null,null,null).exports,us={mixins:[je],props:{autocomplete:{type:String,default:"url"},type:{type:String,default:"url"}}};const cs=G({extends:Ee,mixins:[us]},null,null,!1,null,null,null,null).exports,ds={install(t){t.component("k-checkbox-input",Ce),t.component("k-checkboxes-input",Ae),t.component("k-date-input",Ie),t.component("k-email-input",Le),t.component("k-list-input",De),t.component("k-multiselect-input",Ne),t.component("k-number-input",qe),t.component("k-password-input",ze),t.component("k-radio-input",He),t.component("k-range-input",Ke),t.component("k-select-input",Je),t.component("k-slug-input",We),t.component("k-tags-input",Ze),t.component("k-tel-input",ts),t.component("k-text-input",Ee),t.component("k-textarea-input",ss),t.component("k-time-input",is),t.component("k-toggle-input",rs),t.component("k-toggles-input",as),t.component("k-url-input",cs)}};const ps=G({mixins:[Tt],inheritAttrs:!1,props:{autofocus:Boolean,empty:String,fieldsets:Object,fieldsetGroups:Object,group:String,max:{type:Number,default:null},value:{type:Array,default:()=>[]}},data:()=>({opened:[]}),computed:{hasFieldsets(){return Object.keys(this.fieldsets).length},isEmpty(){return 0===this.value.length},isFull(){return null!==this.max&&this.value.length>=this.max}},methods:{focus(){this.$refs.blocks.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-blocks-field",scopedSlots:t._u([{key:"options",fn:function(){return[t.hasFieldsets?e("k-dropdown",[e("k-button",{attrs:{icon:"dots"},on:{click:function(e){return t.$refs.options.toggle()}}}),e("k-dropdown-content",{ref:"options",attrs:{align:"right"}},[e("k-dropdown-item",{attrs:{disabled:t.isFull,icon:"add"},on:{click:function(e){return t.$refs.blocks.choose(t.value.length)}}},[t._v(" "+t._s(t.$t("add"))+" ")]),e("hr"),e("k-dropdown-item",{attrs:{disabled:t.isEmpty,icon:"template"},on:{click:function(e){return t.$refs.blocks.copyAll()}}},[t._v(" "+t._s(t.$t("copy.all"))+" ")]),e("k-dropdown-item",{attrs:{disabled:t.isFull,icon:"download"},on:{click:function(e){return t.$refs.blocks.pasteboard()}}},[t._v(" "+t._s(t.$t("paste"))+" ")]),e("hr"),e("k-dropdown-item",{attrs:{disabled:t.isEmpty,icon:"trash"},on:{click:function(e){return t.$refs.blocks.confirmToRemoveAll()}}},[t._v(" "+t._s(t.$t("delete.all"))+" ")])],1)],1):t._e()]},proxy:!0}])},"k-field",t.$props,!1),[e("k-blocks",t._g({ref:"blocks",attrs:{autofocus:t.autofocus,compact:!1,empty:t.empty,endpoints:t.endpoints,fieldsets:t.fieldsets,"fieldset-groups":t.fieldsetGroups,group:t.group,max:t.max,value:t.value},on:{close:function(e){t.opened=e},open:function(e){t.opened=e}}},t.$listeners)),t.isEmpty||t.isFull?t._e():e("k-button",{staticClass:"k-field-add-item-button",attrs:{icon:"add",tooltip:t.$t("add")},on:{click:function(e){return t.$refs.blocks.choose(t.value.length)}}})],1)}),[],!1,null,null,null,null).exports,hs={props:{counter:{type:Boolean,default:!0}},computed:{counterOptions(){var t,e;if(null===this.value||this.disabled||!1===this.counter)return!1;let s=0;return this.value&&(s=Array.isArray(this.value)?this.value.length:String(this.value).length),{count:s,min:null!=(t=this.min)?t:this.minlength,max:null!=(e=this.max)?e:this.maxlength}}}};const ms=G({mixins:[Tt,Et,Oe,hs],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-checkboxes-field",attrs:{counter:t.counterOptions}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"checkboxes"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const fs=G({mixins:[Tt,Et,Te],inheritAttrs:!1,props:{calendar:{type:Boolean,default:!0},icon:{type:String,default:"calendar"},time:{type:[Boolean,Object],default:()=>({})},times:{type:Boolean,default:!0}},data(){return{isInvalid:!1,iso:this.toIso(this.value)}},computed:{isEmpty(){return this.time?null===this.iso.date&&this.iso.time:null===this.iso.date}},watch:{value(t,e){t!==e&&(this.iso=this.toIso(t))}},methods:{focus(){this.$refs.dateInput.focus()},now(){const t=this.$library.dayjs();return{date:t.toISO("date"),time:this.time?t.toISO("time"):"00:00:00"}},onInput(){if(this.isEmpty)return this.$emit("input","");const t=this.$library.dayjs.iso(this.iso.date+" "+this.iso.time);(t||null!==this.iso.date&&null!==this.iso.time)&&this.$emit("input",(null==t?void 0:t.toISO())||"")},onCalendarInput(t){var e;null==(e=this.$refs.calendar)||e.close(),this.onDateInput(t)},onDateInput(t){t&&!this.iso.time&&(this.iso.time=this.now().time),this.iso.date=t,this.onInput()},onDateInvalid(t){this.isInvalid=t},onTimeInput(t){t&&!this.iso.date&&(this.iso.date=this.now().date),this.iso.time=t,this.onInput()},onTimesInput(t){var e;null==(e=this.$refs.times)||e.close(),this.onTimeInput(t+":00")},toIso(t){const e=this.$library.dayjs.iso(t);return{date:(null==e?void 0:e.toISO("date"))||null,time:(null==e?void 0:e.toISO("time"))||null}}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-date-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("div",{ref:"body",staticClass:"k-date-field-body",attrs:{"data-invalid":!t.novalidate&&t.isInvalid,"data-theme":"field"}},[e("k-input",t._b({ref:"dateInput",attrs:{id:t._uid,autofocus:t.autofocus,disabled:t.disabled,display:t.display,max:t.max,min:t.min,required:t.required,value:t.value,theme:"field",type:"date"},on:{invalid:t.onDateInvalid,input:t.onDateInput,submit:function(e){return t.$emit("submit")}},scopedSlots:t._u([t.calendar?{key:"icon",fn:function(){return[e("k-dropdown",[e("k-button",{staticClass:"k-input-icon-button",attrs:{icon:t.icon,tooltip:t.$t("date.select")},on:{click:function(e){return t.$refs.calendar.toggle()}}}),e("k-dropdown-content",{ref:"calendar",attrs:{align:"right"}},[e("k-calendar",{attrs:{value:t.value,min:t.min,max:t.max},on:{input:t.onCalendarInput}})],1)],1)]},proxy:!0}:null],null,!0)},"k-input",t.$props,!1)),t.time?e("k-input",{ref:"timeInput",attrs:{disabled:t.disabled,display:t.time.display,required:t.required,step:t.time.step,value:t.iso.time,icon:t.time.icon,theme:"field",type:"time"},on:{input:t.onTimeInput,submit:function(e){return t.$emit("submit")}},scopedSlots:t._u([t.times?{key:"icon",fn:function(){return[e("k-dropdown",[e("k-button",{staticClass:"k-input-icon-button",attrs:{icon:t.time.icon||"clock",tooltip:t.$t("time.select")},on:{click:function(e){return t.$refs.times.toggle()}}}),e("k-dropdown-content",{ref:"times",attrs:{align:"right"}},[e("k-times",{attrs:{display:t.time.display,value:t.value},on:{input:t.onTimesInput}})],1)],1)]},proxy:!0}:null],null,!0)}):t._e()],1)])}),[],!1,null,null,null,null).exports;const gs=G({mixins:[Tt,Et,Me],inheritAttrs:!1,props:{link:{type:Boolean,default:!0},icon:{type:String,default:"email"}},computed:{mailto(){var t;return(null==(t=this.value)?void 0:t.length)>0?"mailto:"+this.value:null}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-email-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"email"},scopedSlots:t._u([{key:"icon",fn:function(){return[t.link?e("k-button",{staticClass:"k-input-icon-button",attrs:{icon:t.icon,link:t.mailto,tooltip:t.$t("open"),tabindex:"-1",target:"_blank"}}):t._e()]},proxy:!0}])},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports,ks={mixins:[Tt],inheritAttrs:!1,props:{empty:String,info:String,link:Boolean,layout:{type:String,default:"list"},max:Number,multiple:Boolean,parent:String,search:Boolean,size:String,text:String,value:{type:Array,default:()=>[]}},data(){return{selected:this.value}},computed:{btnIcon(){return!this.multiple&&this.selected.length>0?"refresh":"add"},btnLabel(){return!this.multiple&&this.selected.length>0?this.$t("change"):this.$t("add")},collection(){return{empty:this.emptyProps,items:this.selected,layout:this.layout,link:this.link,size:this.size,sortable:!this.disabled&&this.selected.length>1}},isInvalid(){return!(!this.required||0!==this.selected.length)||(!!(this.min&&this.selected.lengththis.max))},items(){return this.models.map(this.item)},more(){return!this.max||this.max>this.selected.length}},watch:{value(t){this.selected=t}},methods:{focus(){},item:t=>t,onInput(){this.$emit("input",this.selected)},open(){if(this.disabled)return!1;this.$refs.selector.open({endpoint:this.endpoints.field,max:this.max,multiple:this.multiple,search:this.search,selected:this.selected.map((t=>t.id))})},remove(t){this.selected.splice(t,1),this.onInput()},removeById(t){this.selected=this.selected.filter((e=>e.id!==t)),this.onInput()},select(t){0!==t.length?(this.selected=this.selected.filter((e=>t.filter((t=>t.id===e.id)).length>0)),t.forEach((t=>{0===this.selected.filter((e=>t.id===e.id)).length&&this.selected.push(t)})),this.onInput()):this.selected=[]}}};const bs=G({mixins:[ks],props:{uploads:[Boolean,Object,Array]},computed:{emptyProps(){return{icon:"image",text:this.empty||this.$t("field.files.empty")}},moreUpload(){return!this.disabled&&this.more&&this.uploads},options(){return this.uploads?{icon:this.btnIcon,text:this.btnLabel,options:[{icon:"check",text:this.$t("select"),click:"open"},{icon:"upload",text:this.$t("upload"),click:"upload"}]}:{options:[{icon:"check",text:this.$t("select"),click:()=>this.open()}]}},uploadParams(){return{accept:this.uploads.accept,max:this.max,multiple:this.multiple,url:this.$urls.api+"/"+this.endpoints.field+"/upload"}}},created(){this.$events.$on("file.delete",this.removeById)},destroyed(){this.$events.$off("file.delete",this.removeById)},methods:{drop(t){return!1!==this.uploads&&this.$refs.fileUpload.drop(t,this.uploadParams)},prompt(){if(this.disabled)return!1;this.moreUpload?this.$refs.options.toggle():this.open()},onAction(t){if(this.moreUpload)switch(t){case"open":return this.open();case"upload":return this.$refs.fileUpload.open(this.uploadParams)}},isSelected(t){return this.selected.find((e=>e.id===t.id))},upload(t,e){!1===this.multiple&&(this.selected=[]),e.forEach((t=>{this.isSelected(t)||this.selected.push(t)})),this.onInput(),this.$events.$emit("model.update")}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-files-field",scopedSlots:t._u([t.more&&!t.disabled?{key:"options",fn:function(){return[e("k-button-group",{staticClass:"k-field-options"},[e("k-options-dropdown",t._b({ref:"options",on:{action:t.onAction}},"k-options-dropdown",t.options,!1))],1)]},proxy:!0}:null],null,!0)},"k-field",t.$props,!1),[e("k-dropzone",{attrs:{disabled:!t.moreUpload},on:{drop:t.drop}},[e("k-collection",t._b({on:{empty:t.prompt,sort:t.onInput,sortChange:function(e){return t.$emit("change",e)}},scopedSlots:t._u([{key:"options",fn:function({index:s}){return[t.disabled?t._e():e("k-button",{attrs:{tooltip:t.$t("remove"),icon:"remove"},on:{click:function(e){return t.remove(s)}}})]}}])},"k-collection",t.collection,!1))],1),e("k-files-dialog",{ref:"selector",on:{submit:t.select}}),e("k-upload",{ref:"fileUpload",on:{success:t.upload}})],1)}),[],!1,null,null,null,null).exports;const vs=G({},(function(){return(0,this._self._c)("div",{staticClass:"k-field k-gap-field"})}),[],!1,null,null,null,null).exports;const ys=G({mixins:[xt,Ct],props:{numbered:Boolean}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-headline-field"},[e("k-headline",{attrs:{"data-numbered":t.numbered,size:"large"}},[t._v(" "+t._s(t.label)+" ")]),t.help?e("footer",{staticClass:"k-field-footer"},[t.help?e("k-text",{staticClass:"k-field-help",attrs:{theme:"help",html:t.help}}):t._e()],1):t._e()],1)}),[],!1,null,null,null,null).exports;const $s=G({mixins:[xt,Ct],props:{text:String,theme:{type:String,default:"info"}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-field k-info-field"},[e("k-headline",[t._v(t._s(t.label))]),e("k-box",{attrs:{theme:t.theme}},[e("k-text",{attrs:{html:t.text}})],1),t.help?e("footer",{staticClass:"k-field-footer"},[t.help?e("k-text",{staticClass:"k-field-help",attrs:{theme:"help",html:t.help}}):t._e()],1):t._e()],1)}),[],!1,null,null,null,null).exports;const _s=G({components:{"k-block-layouts":G({components:{"k-layout":G({components:{"k-layout-column":G({props:{blocks:Array,endpoints:Object,fieldsetGroups:Object,fieldsets:Object,id:String,isSelected:Boolean,width:String}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-column k-layout-column",attrs:{id:t.id,"data-width":t.width,tabindex:"0"},on:{dblclick:function(e){return t.$refs.blocks.choose(t.blocks.length)}}},[e("k-blocks",{ref:"blocks",attrs:{endpoints:t.endpoints,"fieldset-groups":t.fieldsetGroups,fieldsets:t.fieldsets,value:t.blocks,group:"layout"},on:{input:function(e){return t.$emit("input",e)}},nativeOn:{dblclick:function(t){t.stopPropagation()}}})],1)}),[],!1,null,null,null,null).exports},props:{attrs:[Array,Object],columns:Array,disabled:Boolean,endpoints:Object,fieldsetGroups:Object,fieldsets:Object,id:String,isSelected:Boolean,settings:Object},computed:{tabs(){let t=this.settings.tabs;return Object.entries(t).forEach((([e,s])=>{Object.entries(s.fields).forEach((([s])=>{t[e].fields[s].endpoints={field:this.endpoints.field+"/fields/"+s,section:this.endpoints.section,model:this.endpoints.model}}))})),t}}},(function(){var t=this,e=t._self._c;return e("section",{staticClass:"k-layout",attrs:{"data-selected":t.isSelected,tabindex:"0"},on:{click:function(e){return t.$emit("select")}}},[e("k-grid",{staticClass:"k-layout-columns"},t._l(t.columns,(function(s,n){return e("k-layout-column",t._b({key:s.id,attrs:{endpoints:t.endpoints,"fieldset-groups":t.fieldsetGroups,fieldsets:t.fieldsets},on:{input:function(e){return t.$emit("updateColumn",{column:s,columnIndex:n,blocks:e})}}},"k-layout-column",s,!1))})),1),t.disabled?t._e():e("nav",{staticClass:"k-layout-toolbar"},[t.settings?e("k-button",{staticClass:"k-layout-toolbar-button",attrs:{tooltip:t.$t("settings"),icon:"settings"},on:{click:function(e){return t.$refs.drawer.open()}}}):t._e(),e("k-dropdown",[e("k-button",{staticClass:"k-layout-toolbar-button",attrs:{icon:"angle-down"},on:{click:function(e){return t.$refs.options.toggle()}}}),e("k-dropdown-content",{ref:"options",attrs:{align:"right"}},[e("k-dropdown-item",{attrs:{icon:"angle-up"},on:{click:function(e){return t.$emit("prepend")}}},[t._v(" "+t._s(t.$t("insert.before"))+" ")]),e("k-dropdown-item",{attrs:{icon:"angle-down"},on:{click:function(e){return t.$emit("append")}}},[t._v(" "+t._s(t.$t("insert.after"))+" ")]),e("hr"),t.settings?e("k-dropdown-item",{attrs:{icon:"settings"},on:{click:function(e){return t.$refs.drawer.open()}}},[t._v(" "+t._s(t.$t("settings"))+" ")]):t._e(),e("k-dropdown-item",{attrs:{icon:"copy"},on:{click:function(e){return t.$emit("duplicate")}}},[t._v(" "+t._s(t.$t("duplicate"))+" ")]),e("hr"),e("k-dropdown-item",{attrs:{icon:"trash"},on:{click:function(e){return t.$refs.confirmRemoveDialog.open()}}},[t._v(" "+t._s(t.$t("field.layout.delete"))+" ")])],1)],1),e("k-sort-handle")],1),t.settings?e("k-form-drawer",{ref:"drawer",staticClass:"k-layout-drawer",attrs:{tabs:t.tabs,title:t.$t("settings"),value:t.attrs,icon:"settings"},on:{input:function(e){return t.$emit("updateAttrs",e)}}}):t._e(),e("k-remove-dialog",{ref:"confirmRemoveDialog",attrs:{text:t.$t("field.layout.delete.confirm")},on:{submit:function(e){return t.$emit("remove")}}})],1)}),[],!1,null,null,null,null).exports},props:{disabled:Boolean,empty:String,endpoints:Object,fieldsetGroups:Object,fieldsets:Object,layouts:Array,max:Number,settings:Object,value:Array},data(){return{currentLayout:null,nextIndex:null,rows:this.value,selected:null}},computed:{draggableOptions(){return{id:this._uid,handle:!0,list:this.rows}}},watch:{value(){this.rows=this.value}},methods:{async addLayout(t){let e=await this.$api.post(this.endpoints.field+"/layout",{columns:t});this.rows.splice(this.nextIndex,0,e),this.layouts.length>1&&this.$refs.selector.close(),this.save()},duplicateLayout(t,e){let s={...this.$helper.clone(e),id:this.$helper.uuid()};s.columns=s.columns.map((t=>(t.id=this.$helper.uuid(),t.blocks=t.blocks.map((t=>(t.id=this.$helper.uuid(),t))),t))),this.rows.splice(t+1,0,s),this.save()},removeLayout(t){const e=this.rows.findIndex((e=>e.id===t.id));-1!==e&&this.$delete(this.rows,e),this.save()},save(){this.$emit("input",this.rows)},selectLayout(t){this.nextIndex=t,1!==this.layouts.length?this.$refs.selector.open():this.addLayout(this.layouts[0])},updateColumn(t){this.rows[t.layoutIndex].columns[t.columnIndex].blocks=t.blocks,this.save()},updateAttrs(t,e){this.rows[t].attrs=e,this.save()}}},(function(){var t=this,e=t._self._c;return e("div",[t.rows.length?[e("k-draggable",t._b({staticClass:"k-layouts",on:{sort:t.save}},"k-draggable",t.draggableOptions,!1),t._l(t.rows,(function(s,n){return e("k-layout",t._b({key:s.id,attrs:{disabled:t.disabled,endpoints:t.endpoints,"fieldset-groups":t.fieldsetGroups,fieldsets:t.fieldsets,"is-selected":t.selected===s.id,settings:t.settings},on:{append:function(e){return t.selectLayout(n+1)},duplicate:function(e){return t.duplicateLayout(n,s)},prepend:function(e){return t.selectLayout(n)},remove:function(e){return t.removeLayout(s)},select:function(e){t.selected=s.id},updateAttrs:function(e){return t.updateAttrs(n,e)},updateColumn:function(e){return t.updateColumn({layout:s,layoutIndex:n,...e})}}},"k-layout",s,!1))})),1),t.disabled?t._e():e("k-button",{staticClass:"k-field-add-item-button",attrs:{icon:"add",tooltip:t.$t("add")},on:{click:function(e){return t.selectLayout(t.rows.length)}}})]:[e("k-empty",{staticClass:"k-layout-empty",attrs:{icon:"dashboard"},on:{click:function(e){return t.selectLayout(0)}}},[t._v(" "+t._s(t.empty||t.$t("field.layout.empty"))+" ")])],e("k-dialog",{ref:"selector",staticClass:"k-layout-selector",attrs:{"cancel-button":!1,"submit-button":!1,size:"medium"}},[e("k-headline",[t._v(t._s(t.$t("field.layout.select")))]),e("ul",t._l(t.layouts,(function(s,n){return e("li",{key:n,staticClass:"k-layout-selector-option"},[e("k-grid",{nativeOn:{click:function(e){return t.addLayout(s)}}},t._l(s,(function(t,s){return e("k-column",{key:s,attrs:{width:t}})})),1)],1)})),0)],1)],2)}),[],!1,null,null,null,null).exports},mixins:[Tt],inheritAttrs:!1,props:{empty:String,fieldsetGroups:Object,fieldsets:Object,layouts:{type:Array,default:()=>[["1/1"]]},settings:Object,value:{type:Array,default:()=>[]}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-layout-field"},"k-field",t.$props,!1),[e("k-block-layouts",t._b({on:{input:function(e){return t.$emit("input",e)}}},"k-block-layouts",t.$props,!1))],1)}),[],!1,null,null,null,null).exports;const xs=G({},(function(){return(0,this._self._c)("hr",{staticClass:"k-line-field"})}),[],!1,null,null,null,null).exports;const ws=G({mixins:[Tt,Et],inheritAttrs:!1,props:{marks:[Array,Boolean],value:String},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-list-field",attrs:{input:t._uid,counter:!1}},"k-field",t.$props,!1),[e("k-input",t._b({ref:"input",attrs:{id:t._uid,marks:t.marks,value:t.value,type:"list",theme:"field"},on:{input:function(e){return t.$emit("input",e)}}},"k-input",t.$props,!1))],1)}),[],!1,null,null,null,null).exports;const Ss=G({mixins:[Tt,Et,Pe,hs],inheritAttrs:!1,props:{icon:{type:String,default:"angle-down"}},mounted(){this.$refs.input.$el.setAttribute("tabindex",0)},methods:{blur(t){this.$refs.input.blur(t)},focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-multiselect-field",attrs:{input:t._uid,counter:t.counterOptions},on:{blur:t.blur},nativeOn:{keydown:function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:(e.preventDefault(),t.focus.apply(null,arguments))}}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"multiselect"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const Cs=G({mixins:[Tt,Et,Fe],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-number-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"number"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const Os=G({mixins:[Tt,Et],props:{empty:String,fields:Object,value:[String,Object]},data(){return{object:this.valueToObject(this.value)}},computed:{drawer(){return{icon:"box",tab:"object",tabs:{object:{fields:this.$helper.field.subfields(this,this.fields)}},title:this.label,value:this.object}},isEmpty(){return!this.object||!(!this.object||0!==Object.keys(this.object).length)},isInvalid(){return!0===this.required&&this.isEmpty}},watch:{value(t){this.object=this.valueToObject(t)}},methods:{onAdd(){this.object={};for(const t in this.fields){const e=this.fields[t];e.default&&(this.object[t]=this.$helper.clone(e.default))}this.$emit("input",this.object),this.open()},onCellInput(t,s){e(this.object,t,s),this.$emit("input",this.object)},onDrawerInput(t){this.object=t,this.$emit("input",this.object)},onRemove(){this.object={},this.$emit("input",this.object)},open(t){if(this.disabled)return!1;this.$refs.drawer.open(null,t)},valueToObject:t=>"object"!=typeof t?null:t}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-object-field",scopedSlots:t._u([t.disabled?null:{key:"options",fn:function(){return[t.isEmpty?e("k-button",{attrs:{icon:"add"},on:{click:t.onAdd}}):e("k-button",{attrs:{icon:"remove"},on:{click:t.onRemove}})]},proxy:!0}],null,!0)},"k-field",t.$props,!1),[t.isEmpty?e("k-empty",{attrs:{"data-invalid":t.isInvalid,icon:"box"},on:{click:t.onAdd}},[t._v(" "+t._s(t.empty||t.$t("field.object.empty"))+" ")]):e("table",{staticClass:"k-table k-object-field-table",attrs:{"data-invalid":t.isInvalid}},[e("tbody",[t._l(t.fields,(function(s){return[s.saveable&&t.$helper.field.isVisible(s,t.value)?e("tr",{key:s.name,on:{click:function(e){return t.open(s.name)}}},[e("th",{attrs:{"data-mobile":"true"}},[e("button",{attrs:{type:"button"}},[t._v(t._s(s.label))])]),e("k-table-cell",{attrs:{column:s,field:s,mobile:!0,value:t.object[s.name]},on:{input:function(e){return t.onCellInput(s.name,e)}}})],1):t._e()]}))],2)]),e("k-form-drawer",t._b({ref:"drawer",on:{input:t.onDrawerInput}},"k-form-drawer",t.drawer,!1))],1)}),[],!1,null,null,null,null).exports;const As=G({mixins:[ks],computed:{emptyProps(){return{icon:"page",text:this.empty||this.$t("field.pages.empty")}}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-pages-field",scopedSlots:t._u([{key:"options",fn:function(){return[e("k-button-group",{staticClass:"k-field-options"},[t.more&&!t.disabled?e("k-button",{staticClass:"k-field-options-button",attrs:{icon:t.btnIcon,text:t.btnLabel},on:{click:t.open}}):t._e()],1)]},proxy:!0}])},"k-field",t.$props,!1),[e("k-collection",t._b({on:{empty:t.open,sort:t.onInput,sortChange:function(e){return t.$emit("change",e)}},scopedSlots:t._u([{key:"options",fn:function({index:s}){return[t.disabled?t._e():e("k-button",{attrs:{tooltip:t.$t("remove"),icon:"remove"},on:{click:function(e){return t.remove(s)}}})]}}])},"k-collection",t.collection,!1)),e("k-pages-dialog",{ref:"selector",on:{submit:t.select}})],1)}),[],!1,null,null,null,null).exports;const Ts=G({mixins:[Tt,Et,Re,hs],inheritAttrs:!1,props:{minlength:{type:Number,default:8},icon:{type:String,default:"key"}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-password-field",attrs:{input:t._uid,counter:t.counterOptions},scopedSlots:t._u([{key:"options",fn:function(){return[t._t("options")]},proxy:!0}],null,!0)},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"password"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const Is=G({mixins:[Tt,Et,Ye],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-radio-field"},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"radio"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const js=G({mixins:[Et,Tt,Ue],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-range-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"range"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const Es=G({mixins:[Tt,Et,Ve],inheritAttrs:!1,props:{icon:{type:String,default:"angle-down"}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-select-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"select"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const Ms=G({mixins:[Tt,Et,Ge],inheritAttrs:!1,props:{icon:{type:String,default:"url"},path:{type:String},wizard:{type:[Boolean,Object],default:!1}},data(){return{slug:this.value}},computed:{preview(){return void 0!==this.help?this.help:void 0!==this.path?this.path+this.value:null}},watch:{value(){this.slug=this.value}},methods:{focus(){this.$refs.input.focus()},onWizard(){var t;this.formData[null==(t=this.wizard)?void 0:t.field]&&(this.slug=this.formData[this.wizard.field])}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-slug-field",attrs:{input:t._uid,help:t.preview},scopedSlots:t._u([t.wizard&&t.wizard.text?{key:"options",fn:function(){return[e("k-button",{attrs:{text:t.wizard.text,icon:"wand"},on:{click:t.onWizard}})]},proxy:!0}:null],null,!0)},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,value:t.slug,theme:"field",type:"slug"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const Ls=G({mixins:[Tt],inheritAttrs:!1,props:{columns:Object,duplicate:{type:Boolean,default:!0},empty:String,fields:Object,limit:Number,max:Number,min:Number,prepend:{type:Boolean,default:!1},sortable:{type:Boolean,default:!0},sortBy:String,value:{type:Array,default:()=>[]}},data(){return{autofocus:null,items:this.toItems(this.value),currentIndex:null,currentModel:null,trash:null,page:1}},computed:{dragOptions(){return{disabled:!this.isSortable,fallbackClass:"k-sortable-row-fallback"}},form(){return this.$helper.field.subfields(this,this.fields)},index(){return this.limit?(this.page-1)*this.limit+1:1},more(){return!0!==this.disabled&&!(this.max&&this.items.length>=this.max)},isInvalid(){return!0!==this.disabled&&(!!(this.min&&this.items.lengththis.max))},isSortable(){return!this.sortBy&&(!this.limit&&(!0!==this.disabled&&(!(this.items.length<=1)&&!1!==this.sortable)))},pagination(){let t=0;return this.limit&&(t=(this.page-1)*this.limit),{page:this.page,offset:t,limit:this.limit,total:this.items.length,align:"center",details:!0}},options(){if(this.disabled)return[];let t=[],e=this.duplicate&&this.more&&null===this.currentIndex;return e&&t.push({icon:"copy",text:this.$t("duplicate"),click:"duplicate"}),t.push({icon:"remove",text:e?this.$t("remove"):null,click:"remove"}),t},paginatedItems(){return this.limit?this.items.slice(this.pagination.offset,this.pagination.offset+this.limit):this.items}},watch:{value(t){t!=this.items&&(this.items=this.toItems(t))}},methods:{add(t){!0===this.prepend?this.items.unshift(t):this.items.push(t)},focus(){var t,e;null==(e=null==(t=this.$refs.add)?void 0:t.focus)||e.call(t)},jump(t,e){this.open(t+this.pagination.offset,e)},onAdd(){if(!0===this.disabled)return!1;if(null!==this.currentIndex)return this.onFormDiscard(),!1;let t={};for(const e in this.fields)t[e]=this.$helper.clone(this.fields[e].default);this.currentIndex="new",this.currentModel=t,this.onFormOpen()},onFormClose(){this.currentIndex=null,this.currentModel=null},onFormDiscard(){if("new"===this.currentIndex){if(0===Object.values(this.currentModel).filter((t=>!1===this.$helper.object.isEmpty(t))).length)return void this.onFormClose()}this.onFormSubmit()},onFormOpen(t=this.autofocus){this.$nextTick((()=>{var e;null==(e=this.$refs.form)||e.focus(t)}))},async onFormPaginate(t){await this.save(),this.open(t)},async onFormSubmit(){try{await this.save(),this.onFormClose()}catch(t){}},onInput(t=this.items){this.$emit("input",t)},onOption(t,e,s){switch(t){case"remove":this.onFormClose(),this.trash=s+this.pagination.offset,this.$refs.remove.open();break;case"duplicate":this.add(this.items[s+this.pagination.offset]),this.onInput()}},onRemove(){if(null===this.trash)return!1;this.items.splice(this.trash,1),this.trash=null,this.$refs.remove.close(),this.onInput(),0===this.paginatedItems.length&&this.page>1&&this.page--,this.items=this.sort(this.items)},open(t,e){this.currentIndex=t,this.currentModel=this.$helper.clone(this.items[t]),this.onFormOpen(e)},paginate({page:t}){this.page=t},sort(t){return this.sortBy?t.sortBy(this.sortBy):t},async save(){if(null!==this.currentIndex&&void 0!==this.currentIndex)try{return await this.validate(this.currentModel),"new"===this.currentIndex?this.add(this.currentModel):this.items[this.currentIndex]=this.currentModel,this.items=this.sort(this.items),this.onInput(),!0}catch(t){throw this.$store.dispatch("notification/error",{message:this.$t("error.form.incomplete"),details:t}),t}},toItems(t){return!1===Array.isArray(t)?[]:this.sort(t)},async validate(t){const e=await this.$api.post(this.endpoints.field+"/validate",t);if(e.length>0)throw e;return!0},onFormInput(t){this.currentModel=t,this.$emit("formInput",t)}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-structure-field",nativeOn:{click:function(t){t.stopPropagation()}},scopedSlots:t._u([{key:"options",fn:function(){return[t.more&&null===t.currentIndex?e("k-button",{ref:"add",attrs:{id:t._uid,text:t.$t("add"),icon:"add"},on:{click:t.onAdd}}):t._e()]},proxy:!0}])},"k-field",t.$props,!1),[null!==t.currentIndex?e("k-structure-form",{ref:"form",attrs:{fields:t.form,index:t.currentIndex,total:t.items.length,value:t.currentModel},on:{close:t.onFormClose,discard:t.onFormDiscard,input:t.onFormInput,paginate:function(e){return t.onFormPaginate(e.offset)},submit:t.onFormSubmit}}):0===t.items.length?e("k-empty",{attrs:{"data-invalid":t.isInvalid,icon:"list-bullet"},on:{click:t.onAdd}},[t._v(" "+t._s(t.empty||t.$t("field.structure.empty"))+" ")]):[e("k-table",{attrs:{columns:t.columns,disabled:t.disabled,fields:t.fields,empty:t.$t("field.structure.empty"),index:t.index,options:t.options,rows:t.paginatedItems,sortable:t.isSortable,"data-invalid":t.isInvalid},on:{cell:function(e){return t.jump(e.rowIndex,e.columnIndex)},input:t.onInput,option:t.onOption}}),t.limit?e("k-pagination",t._b({on:{paginate:t.paginate}},"k-pagination",t.pagination,!1)):t._e(),t.disabled?t._e():e("k-dialog",{ref:"remove",attrs:{"submit-button":t.$t("delete"),theme:"negative"},on:{submit:t.onRemove}},[e("k-text",[t._v(t._s(t.$t("field.structure.delete.confirm")))])],1)]],2)}),[],!1,null,null,null,null).exports;const Bs=G({mixins:[Tt,Et,Xe,hs],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-tags-field",attrs:{input:t._uid,counter:t.counterOptions}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"tags"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const Ds=G({mixins:[Tt,Et,Qe],inheritAttrs:!1,props:{icon:{type:String,default:"phone"}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-tel-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"tel"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const Ps=G({mixins:[Tt,Et,je,hs],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()},select(){this.$refs.input.select()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-text-field",attrs:{input:t._uid,counter:t.counterOptions},scopedSlots:t._u([{key:"options",fn:function(){return[t._t("options")]},proxy:!0}],null,!0)},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const Ns=G({mixins:[Tt,Et,es,hs],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-textarea-field",attrs:{input:t._uid,counter:t.counterOptions}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,type:"textarea",theme:"field"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const Fs=G({mixins:[Tt,Et,ns],inheritAttrs:!1,props:{icon:{type:String,default:"clock"},times:{type:Boolean,default:!0}},methods:{focus(){this.$refs.input.focus()},select(t){var e;this.$emit("input",t),null==(e=this.$refs.times)||e.close()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-time-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("k-input",t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"time"},on:{input:function(e){return t.$emit("input",e||"")}},scopedSlots:t._u([t.times?{key:"icon",fn:function(){return[e("k-dropdown",[e("k-button",{staticClass:"k-input-icon-button",attrs:{icon:t.icon||"clock",tooltip:t.$t("time.select")},on:{click:function(e){return t.$refs.times.toggle()}}}),e("k-dropdown-content",{ref:"times",attrs:{align:"right"}},[e("k-times",{attrs:{display:t.display,value:t.value},on:{input:t.select}})],1)],1)]},proxy:!0}:null],null,!0)},"k-input",t.$props,!1))],1)}),[],!1,null,null,null,null).exports;const qs=G({mixins:[Tt,Et,os],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-toggle-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"toggle"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const Rs=G({mixins:[Tt,Et,ls],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()},onInput(t){this.$emit("input",t)}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-toggles-field"},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",class:{grow:t.grow},attrs:{id:t._uid,theme:"field",type:"toggles"}},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const zs=G({mixins:[Tt,Et,us],inheritAttrs:!1,props:{link:{type:Boolean,default:!0},icon:{type:String,default:"url"}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-url-field",attrs:{input:t._uid}},"k-field",t.$props,!1),[e("k-input",t._g(t._b({ref:"input",attrs:{id:t._uid,theme:"field",type:"url"},scopedSlots:t._u([{key:"icon",fn:function(){return[t.link?e("k-button",{staticClass:"k-input-icon-button",attrs:{icon:t.icon,link:t.value,tooltip:t.$t("open"),tabindex:"-1",target:"_blank"}}):t._e()]},proxy:!0}])},"k-input",t.$props,!1),t.$listeners))],1)}),[],!1,null,null,null,null).exports;const Ys=G({mixins:[ks],computed:{emptyProps(){return{icon:"users",text:this.empty||this.$t("field.users.empty")}}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-users-field",scopedSlots:t._u([{key:"options",fn:function(){return[e("k-button-group",{staticClass:"k-field-options"},[t.more&&!t.disabled?e("k-button",{staticClass:"k-field-options-button",attrs:{icon:t.btnIcon,text:t.btnLabel},on:{click:t.open}}):t._e()],1)]},proxy:!0}])},"k-field",t.$props,!1),[e("k-collection",t._b({on:{empty:t.open,sort:t.onInput,sortChange:function(e){return t.$emit("change",e)}},scopedSlots:t._u([{key:"options",fn:function({index:s}){return[t.disabled?t._e():e("k-button",{attrs:{tooltip:t.$t("remove"),icon:"remove"},on:{click:function(e){return t.remove(s)}}})]}}])},"k-collection",t.collection,!1)),e("k-users-dialog",{ref:"selector",on:{submit:t.select}})],1)}),[],!1,null,null,null,null).exports;const Hs=G({mixins:[Tt,Et,be],inheritAttrs:!1,methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("k-field",t._b({staticClass:"k-writer-field",attrs:{input:t._uid,counter:!1}},"k-field",t.$props,!1),[e("k-input",t._b({attrs:{after:t.after,before:t.before,icon:t.icon,theme:"field"}},"k-input",t.$props,!1),[e("k-writer",t._b({ref:"input",staticClass:"k-writer-field-input",attrs:{value:t.value},on:{input:function(e){return t.$emit("input",e)}}},"k-writer",t.$props,!1))],1)],1)}),[],!1,null,null,null,null).exports,Us={install(t){t.component("k-blocks-field",ps),t.component("k-checkboxes-field",ms),t.component("k-date-field",fs),t.component("k-email-field",gs),t.component("k-files-field",bs),t.component("k-gap-field",vs),t.component("k-headline-field",ys),t.component("k-info-field",$s),t.component("k-layout-field",_s),t.component("k-line-field",xs),t.component("k-list-field",ws),t.component("k-multiselect-field",Ss),t.component("k-number-field",Cs),t.component("k-object-field",Os),t.component("k-pages-field",As),t.component("k-password-field",Ts),t.component("k-radio-field",Is),t.component("k-range-field",js),t.component("k-select-field",Es),t.component("k-slug-field",Ms),t.component("k-structure-field",Ls),t.component("k-tags-field",Bs),t.component("k-text-field",Ps),t.component("k-textarea-field",Ns),t.component("k-tel-field",Ds),t.component("k-time-field",Fs),t.component("k-toggle-field",qs),t.component("k-toggles-field",Rs),t.component("k-url-field",zs),t.component("k-users-field",Ys),t.component("k-writer-field",Hs)}},Ks={install(t){t.component("k-calendar",mt),t.component("k-counter",ft),t.component("k-autocomplete",ht),t.component("k-form",gt),t.component("k-form-buttons",kt),t.component("k-form-indicator",bt),t.component("k-field",It),t.component("k-fieldset",jt),t.component("k-input",Mt),t.component("k-login",Lt),t.component("k-login-code",Bt),t.component("k-times",Dt),t.component("k-upload",Pt),t.component("k-writer",ve),t.component("k-login-alert",ye),t.component("k-structure-form",$e),t.component("k-toolbar",xe),t.component("k-toolbar-email-dialog",we),t.component("k-toolbar-link-dialog",Se),t.use(ds),t.use(Us)}};const Vs=G({props:{cover:Boolean,ratio:String},computed:{ratioPadding(){return this.$helper.ratio(this.ratio)}}},(function(){var t=this;return(0,t._self._c)("span",{staticClass:"k-aspect-ratio",style:{"padding-bottom":t.ratioPadding},attrs:{"data-cover":t.cover}},[t._t("default")],2)}),[],!1,null,null,null,null).exports;const Js=G({},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-bar"},[t.$slots.left?e("div",{staticClass:"k-bar-slot",attrs:{"data-position":"left"}},[t._t("left")],2):t._e(),t.$slots.center?e("div",{staticClass:"k-bar-slot",attrs:{"data-position":"center"}},[t._t("center")],2):t._e(),t.$slots.right?e("div",{staticClass:"k-bar-slot",attrs:{"data-position":"right"}},[t._t("right")],2):t._e()])}),[],!1,null,null,null,null).exports;const Gs=G({props:{theme:{type:String,default:"none"},text:String,html:{type:Boolean,default:!1}}},(function(){var t=this,e=t._self._c;return e("div",t._g({staticClass:"k-box",attrs:{"data-theme":t.theme}},t.$listeners),[t._t("default",(function(){return[t.html?e("k-text",{attrs:{html:t.text}}):e("k-text",[t._v(" "+t._s(t.text)+" ")])]}))],2)}),[],!1,null,null,null,null).exports;const Ws=G({inheritAttrs:!1,props:{back:String,color:String,element:{type:String,default:"li"},image:Object,link:String,text:String}},(function(){var t=this,e=t._self._c;return e(t.link?"k-link":"p",{tag:"component",staticClass:"k-bubble",style:{color:t.$helper.color(t.color),background:t.$helper.color(t.back)},attrs:{to:t.link},nativeOn:{click:function(t){t.stopPropagation()}}},[t.image?e("k-item-image",{attrs:{image:t.image,layout:"list"}}):t._e(),t._v(" "+t._s(t.text)+" ")],1)}),[],!1,null,null,null,null).exports;const Xs=G({inheritAttrs:!1,props:{bubbles:Array},computed:{items(){let t=this.bubbles;return"string"==typeof t&&(t=t.split(",")),t.map((t=>"string"==typeof t?{text:t}:t))}}},(function(){var t=this,e=t._self._c;return e("ul",{staticClass:"k-bubbles"},t._l(t.items,(function(s,n){return e("li",{key:n},[e("k-bubble",t._b({},"k-bubble",s,!1))],1)})),0)}),[],!1,null,null,null,null).exports;const Zs=G({props:{columns:{type:[Object,Array],default:()=>({})},empty:Object,help:String,items:{type:[Array,Object],default:()=>[]},layout:{type:String,default:"list"},link:{type:Boolean,default:!0},size:String,sortable:Boolean,pagination:{type:[Boolean,Object],default:()=>!1}},computed:{hasPagination(){return!1!==this.pagination&&(!0!==this.paginationOptions.hide&&!(this.pagination.total<=this.pagination.limit))},hasFooter(){return!(!this.hasPagination&&!this.help)},paginationOptions(){return{limit:10,details:!0,keys:!1,total:0,hide:!1,..."object"!=typeof this.pagination?{}:this.pagination}}},watch:{$props(){this.$forceUpdate()}},methods:{onEmpty(t){t.stopPropagation(),this.$emit("empty")},onOption(...t){this.$emit("action",...t),this.$emit("option",...t)}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-collection"},[t.items.length?e("k-items",{attrs:{columns:t.columns,items:t.items,layout:t.layout,link:t.link,size:t.size,sortable:t.sortable},on:{change:function(e){return t.$emit("change",e)},item:function(e){return t.$emit("item",e)},option:t.onOption,sort:function(e){return t.$emit("sort",e)}},scopedSlots:t._u([{key:"options",fn:function({item:e,itemIndex:s}){return[t._t("options",null,null,{item:e,index:s})]}}],null,!0)}):e("k-empty",t._g(t._b({attrs:{layout:t.layout}},"k-empty",t.empty,!1),t.$listeners.empty?{click:t.onEmpty}:{})),t.hasFooter?e("footer",{staticClass:"k-collection-footer"},[t.help?e("k-text",{staticClass:"k-collection-help",attrs:{theme:"help",html:t.help}}):t._e(),e("div",{staticClass:"k-collection-pagination"},[t.hasPagination?e("k-pagination",t._b({on:{paginate:function(e){return t.$emit("paginate",e)}}},"k-pagination",t.paginationOptions,!1)):t._e()],1)],1):t._e()],1)}),[],!1,null,null,null,null).exports;const Qs=G({props:{width:String,sticky:Boolean}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-column",attrs:{"data-width":t.width,"data-sticky":t.sticky}},[e("div",[t._t("default")],2)])}),[],!1,null,null,null,null).exports;const tn=G({props:{disabled:{type:Boolean,default:!1}},data:()=>({files:[],dragging:!1,over:!1}),methods:{cancel(){this.reset()},reset(){this.dragging=!1,this.over=!1},onDrop(t){return!0===this.disabled||!1===this.$helper.isUploadEvent(t)?this.reset():(this.$events.$emit("dropzone.drop"),this.files=t.dataTransfer.files,this.$emit("drop",this.files),void this.reset())},onEnter(t){!1===this.disabled&&this.$helper.isUploadEvent(t)&&(this.dragging=!0)},onLeave(){this.reset()},onOver(t){!1===this.disabled&&this.$helper.isUploadEvent(t)&&(t.dataTransfer.dropEffect="copy",this.over=!0)}}},(function(){var t=this;return(0,t._self._c)("div",{staticClass:"k-dropzone",attrs:{"data-dragging":t.dragging,"data-over":t.over},on:{dragenter:t.onEnter,dragleave:t.onLeave,dragover:t.onOver,drop:t.onDrop}},[t._t("default")],2)}),[],!1,null,null,null,null).exports;const en=G({props:{text:String,icon:String,layout:{type:String,default:"list"}},computed:{element(){return void 0!==this.$listeners.click?"button":"div"}}},(function(){var t=this,e=t._self._c;return e(t.element,t._g({tag:"component",staticClass:"k-empty",attrs:{"data-layout":t.layout,type:"button"===t.element&&"button"}},t.$listeners),[t.icon?e("k-icon",{attrs:{type:t.icon}}):t._e(),e("p",[t._t("default",(function(){return[t._v(t._s(t.text))]}))],2)],1)}),[],!1,null,null,null,null).exports;const sn=G({props:{details:Array,image:Object,url:String}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-file-preview"},[e("k-view",{staticClass:"k-file-preview-layout"},[e("div",{staticClass:"k-file-preview-image"},[e("k-link",{staticClass:"k-file-preview-image-link",attrs:{to:t.url,title:t.$t("open"),target:"_blank"}},[e("k-item-image",{attrs:{image:t.image,layout:"cards"}})],1)],1),e("div",{staticClass:"k-file-preview-details"},[e("ul",t._l(t.details,(function(s){return e("li",{key:s.title},[e("h3",[t._v(t._s(s.title))]),e("p",[s.link?e("k-link",{attrs:{to:s.link,tabindex:"-1",target:"_blank"}},[t._v(" /"+t._s(s.text)+" ")]):[t._v(" "+t._s(s.text)+" ")]],2)])})),0)])])],1)}),[],!1,null,null,null,null).exports;const nn=G({props:{gutter:String}},(function(){var t=this;return(0,t._self._c)("div",{staticClass:"k-grid",attrs:{"data-gutter":t.gutter}},[t._t("default")],2)}),[],!1,null,null,null,null).exports;const on=G({props:{editable:Boolean,tab:String,tabs:{type:Array,default:()=>[]}},computed:{tabsWithBadges(){const t=Object.keys(this.$store.getters["content/changes"]());return this.tabs.map((e=>{let s=[];return Object.values(e.columns).forEach((t=>{Object.values(t.sections).forEach((t=>{"fields"===t.type&&Object.keys(t.fields).forEach((t=>{s.push(t)}))}))})),e.badge=s.filter((e=>t.includes(e.toLowerCase()))).length,e}))}}},(function(){var t=this,e=t._self._c;return e("header",{staticClass:"k-header",attrs:{"data-editable":t.editable,"data-tabs":t.tabsWithBadges.length>1}},[e("k-headline",{attrs:{tag:"h1",size:"huge"}},[t.editable&&t.$listeners.edit?e("span",{staticClass:"k-headline-editable",on:{click:function(e){return t.$emit("edit")}}},[t._t("default"),e("k-icon",{attrs:{type:"edit"}})],2):t._t("default")],2),t.$slots.left||t.$slots.right?e("k-bar",{staticClass:"k-header-buttons",scopedSlots:t._u([{key:"left",fn:function(){return[t._t("left")]},proxy:!0},{key:"right",fn:function(){return[t._t("right")]},proxy:!0}],null,!0)}):t._e(),e("k-tabs",{attrs:{tab:t.tab,tabs:t.tabsWithBadges,theme:"notice"}})],1)}),[],!1,null,null,null,null).exports;const rn=G({inheritAttrs:!1},(function(){var t=this,e=t._self._c;return e("k-panel",{staticClass:"k-panel-inside",attrs:{tabindex:"0"}},[e("header",{staticClass:"k-panel-header"},[e("k-topbar",{attrs:{breadcrumb:t.$view.breadcrumb,license:t.$license,menu:t.$menu,view:t.$view}})],1),e("main",{staticClass:"k-panel-view scroll-y"},[t._t("default")],2),t._t("footer")],2)}),[],!1,null,null,null,null).exports;const ln=G({inheritAttrs:!1,props:{data:Object,flag:Object,image:[Object,Boolean],info:String,layout:{type:String,default:"list"},link:{type:[Boolean,String,Function]},options:{type:[Array,Function,String]},sortable:Boolean,target:String,text:String,width:String},computed:{hasFigure(){return!1!==this.image&&Object.keys(this.image).length>0},title(){return this.text||"-"}},methods:{onOption(t){this.$emit("action",t),this.$emit("option",t)}}},(function(){var t=this,e=t._self._c;return e("article",t._b({staticClass:"k-item",class:!!t.layout&&"k-"+t.layout+"-item",attrs:{"data-has-figure":t.hasFigure,"data-has-flag":Boolean(t.flag),"data-has-info":Boolean(t.info),"data-has-options":Boolean(t.options),tabindex:"-1"},on:{click:function(e){return t.$emit("click",e)},dragstart:function(e){return t.$emit("drag",e)}}},"article",t.data,!1),[t._t("image",(function(){return[t.hasFigure?e("k-item-image",{attrs:{image:t.image,layout:t.layout,width:t.width}}):t._e()]})),t.sortable?e("k-sort-handle",{staticClass:"k-item-sort-handle"}):t._e(),e("header",{staticClass:"k-item-content"},[t._t("default",(function(){return[e("h3",{staticClass:"k-item-title"},[!1!==t.link?e("k-link",{staticClass:"k-item-title-link",attrs:{target:t.target,to:t.link}},[e("span",{domProps:{innerHTML:t._s(t.title)}})]):e("span",{domProps:{innerHTML:t._s(t.title)}})],1),t.info?e("p",{staticClass:"k-item-info",domProps:{innerHTML:t._s(t.info)}}):t._e()]}))],2),t.flag||t.options||t.$slots.options?e("footer",{staticClass:"k-item-footer"},[e("nav",{staticClass:"k-item-buttons",on:{click:function(t){t.stopPropagation()}}},[t.flag?e("k-status-icon",t._b({},"k-status-icon",t.flag,!1)):t._e(),t._t("options",(function(){return[t.options?e("k-options-dropdown",{staticClass:"k-item-options-dropdown",attrs:{options:t.options},on:{option:t.onOption}}):t._e()]}))],2)]):t._e()],2)}),[],!1,null,null,null,null).exports;const an=G({inheritAttrs:!1,props:{image:[Object,Boolean],layout:{type:String,default:"list"},width:String},computed:{back(){return this.image.back||"black"},ratio(){return"cards"===this.layout&&this.image.ratio||"1/1"},size(){switch(this.layout){case"cards":return"large";case"cardlets":return"medium";default:return"regular"}},sizes(){switch(this.width){case"1/2":case"2/4":return"(min-width: 30em) and (max-width: 65em) 59em, (min-width: 65em) 44em, 27em";case"1/3":return"(min-width: 30em) and (max-width: 65em) 59em, (min-width: 65em) 29.333em, 27em";case"1/4":return"(min-width: 30em) and (max-width: 65em) 59em, (min-width: 65em) 22em, 27em";case"2/3":return"(min-width: 30em) and (max-width: 65em) 59em, (min-width: 65em) 27em, 27em";case"3/4":return"(min-width: 30em) and (max-width: 65em) 59em, (min-width: 65em) 66em, 27em";default:return"(min-width: 30em) and (max-width: 65em) 59em, (min-width: 65em) 88em, 27em"}}}},(function(){var t=this,e=t._self._c;return t.image?e("div",{staticClass:"k-item-figure",style:{background:t.$helper.color(t.back)}},[t.image.src?e("k-image",{staticClass:"k-item-image",attrs:{cover:t.image.cover,ratio:t.ratio,sizes:t.sizes,src:t.image.src,srcset:t.image.srcset}}):e("k-aspect-ratio",{attrs:{ratio:t.ratio}},[e("k-icon",{staticClass:"k-item-icon",attrs:{color:t.$helper.color(t.image.color),type:t.image.icon}})],1)],1):t._e()}),[],!1,null,null,null,null).exports;const un=G({inheritAttrs:!1,props:{columns:{type:[Object,Array],default:()=>({})},items:{type:Array,default:()=>[]},layout:{type:String,default:"list"},link:{type:Boolean,default:!0},image:{type:[Object,Boolean],default:()=>({})},sortable:Boolean,empty:{type:[String,Object]},size:{type:String,default:"default"}},computed:{dragOptions(){return{sort:this.sortable,disabled:!1===this.sortable,draggable:".k-draggable-item"}},table(){return{columns:this.columns,rows:this.items,sortable:this.sortable}}},methods:{onDragStart(t,e){this.$store.dispatch("drag",{type:"text",data:e})},onOption(t,e,s){this.$emit("option",t,e,s)},imageOptions(t){let e=this.image,s=t.image;return!1!==e&&!1!==s&&("object"!=typeof e&&(e={}),"object"!=typeof s&&(s={}),{...s,...e})}}},(function(){var t=this,e=t._self._c;return"table"===t.layout?e("k-table",t._b({on:{change:function(e){return t.$emit("change",e)},sort:function(e){return t.$emit("sort",e)},option:t.onOption}},"k-table",t.table,!1)):e("k-draggable",{staticClass:"k-items",class:"k-"+t.layout+"-items",attrs:{handle:!0,options:t.dragOptions,"data-layout":t.layout,"data-size":t.size,list:t.items},on:{change:function(e){return t.$emit("change",e)},end:function(e){return t.$emit("sort",t.items,e)}}},[t._l(t.items,(function(s,n){return[t._t("default",(function(){return[e("k-item",t._b({key:s.id||n,class:{"k-draggable-item":t.sortable&&s.sortable},attrs:{image:t.imageOptions(s),layout:t.layout,link:!!t.link&&s.link,sortable:t.sortable&&s.sortable,width:s.column},on:{click:function(e){return t.$emit("item",s,n)},drag:function(e){return t.onDragStart(e,s.dragText)},option:function(e){return t.onOption(e,s,n)}},nativeOn:{mouseover:function(e){return t.$emit("hover",e,s,n)}},scopedSlots:t._u([{key:"options",fn:function(){return[t._t("options",null,null,{item:s,itemIndex:n})]},proxy:!0}],null,!0)},"k-item",s,!1))]}),null,{item:s,itemIndex:n})]}))],2)}),[],!1,null,null,null,null).exports;const cn=G({inheritAttrs:!0,props:{autofocus:{type:Boolean,default:!0},centered:{type:Boolean,default:!1},dimmed:{type:Boolean,default:!0},loading:{type:Boolean,default:!1}},data:()=>({isOpen:!1,scrollTop:0}),methods:{close(){!1!==this.isOpen&&(this.isOpen=!1,this.$emit("close"),this.restoreScrollPosition(),this.$events.$off("keydown.esc",this.close))},focus(){var t,e;let s=this.$refs.overlay.querySelector("\n [autofocus],\n [data-autofocus]\n ");return null===s&&(s=this.$refs.overlay.querySelector("\n input,\n textarea,\n select,\n button\n ")),"function"==typeof(null==s?void 0:s.focus)?s.focus():"function"==typeof(null==(e=null==(t=this.$slots.default[0])?void 0:t.context)?void 0:e.focus)?this.$slots.default[0].context.focus():void 0},open(){!0!==this.isOpen&&(this.storeScrollPosition(),this.isOpen=!0,this.$emit("open"),this.$events.$on("keydown.esc",this.close),setTimeout((()=>{!0===this.autofocus&&this.focus(),document.querySelector(".k-overlay > *").addEventListener("mousedown",(t=>t.stopPropagation())),this.$emit("ready")}),1))},restoreScrollPosition(){const t=document.querySelector(".k-panel-view");(null==t?void 0:t.scrollTop)&&(t.scrollTop=this.scrollTop)},storeScrollPosition(){const t=document.querySelector(".k-panel-view");(null==t?void 0:t.scrollTop)?this.scrollTop=t.scrollTop:this.scrollTop=0}}},(function(){var t=this,e=t._self._c;return t.isOpen?e("portal",[e("div",t._g({ref:"overlay",staticClass:"k-overlay",class:t.$vnode.data.staticClass,attrs:{"data-centered":t.loading||t.centered,"data-dimmed":t.dimmed,"data-loading":t.loading,dir:t.$translation.direction},on:{mousedown:t.close}},t.$listeners),[t.loading?e("k-loader",{staticClass:"k-overlay-loader"}):t._t("default",null,{close:t.close,isOpen:t.isOpen})],2)]):t._e()}),[],!1,null,null,null,null).exports;const dn=G({computed:{defaultLanguage(){return!!this.$language&&this.$language.default},dialog(){return this.$helper.clone(this.$store.state.dialog)},dir(){return this.$translation.direction},language(){return this.$language?this.$language.code:null},role(){return this.$user?this.$user.role:null},user(){return this.$user?this.$user.id:null}},watch:{dir:{handler(){document.body.dir=this.dir},immediate:!0}},created(){this.$events.$on("drop",this.drop)},destroyed(){this.$events.$off("drop",this.drop)},methods:{drop(){this.$store.dispatch("drag",null)}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-panel",attrs:{"data-dragging":t.$store.state.drag,"data-loading":t.$store.state.isLoading,"data-language":t.language,"data-language-default":t.defaultLanguage,"data-role":t.role,"data-translation":t.$translation.code,"data-user":t.user,dir:t.dir}},[t._t("default"),t.$store.state.dialog&&t.$store.state.dialog.props?[e("k-fiber-dialog",t._b({},"k-fiber-dialog",t.dialog,!1))]:t._e(),!1!==t.$store.state.fatal?e("k-fatal",{attrs:{html:t.$store.state.fatal}}):t._e(),!1===t.$system.isLocal?e("k-offline-warning"):t._e(),e("k-icons")],2)}),[],!1,null,null,null,null).exports;const pn=G({props:{reports:Array,size:{type:String,default:"large"}},methods:{component(t){return null!==this.target(t)?"k-link":"div"},target(t){return t.link?t.link:t.click?t.click:t.dialog?()=>this.$dialog(t.dialog):null}}},(function(){var t=this,e=t._self._c;return e("dl",{staticClass:"k-stats",attrs:{"data-size":t.size}},t._l(t.reports,(function(s,n){return e(t.component(s),{key:n,tag:"component",staticClass:"k-stat",attrs:{"data-theme":s.theme,to:t.target(s)}},[e("dt",{staticClass:"k-stat-label"},[t._v(t._s(s.label))]),e("dd",{staticClass:"k-stat-value"},[t._v(t._s(s.value))]),e("dd",{staticClass:"k-stat-info"},[t._v(t._s(s.info))])])})),1)}),[],!1,null,null,null,null).exports;const hn=G({inheritAttrs:!1,props:{columns:Object,disabled:Boolean,fields:{type:Object,default:()=>({})},empty:String,index:{type:[Number,Boolean],default:1},rows:Array,options:[Array,Function],sortable:Boolean},data(){return{values:this.rows}},computed:{columnsCount(){return Object.keys(this.columns).length},dragOptions(){return{disabled:!this.sortable,fallbackClass:"k-table-row-fallback",ghostClass:"k-table-row-ghost"}},hasIndexColumn(){return this.sortable||!1!==this.index},hasOptions(){var t;return(null==(t=this.options)?void 0:t.length)>0||Object.values(this.values).filter((t=>t.options)).length>0}},watch:{rows(){this.values=this.rows}},methods:{isColumnEmpty(t){return 0===this.rows.filter((e=>!1===this.$helper.object.isEmpty(e[t]))).length},label(t,e){return t.label||this.$helper.string.ucfirst(e)},onChange(t){this.$emit("change",t)},onCell(t){this.$emit("cell",t)},onCellUpdate({columnIndex:t,rowIndex:e,value:s}){this.values[e][t]=s,this.$emit("input",this.values)},onHeader(t){this.$emit("header",t)},onOption(t,e,s){this.$emit("option",t,e,s)},onSort(){this.$emit("input",this.values),this.$emit("sort",this.values)},width(t){return"string"!=typeof t?"auto":!1===t.includes("/")?t:this.$helper.ratio(t,"auto",!1)}}},(function(){var t=this,e=t._self._c;return e("table",{staticClass:"k-table",attrs:{"data-disabled":t.disabled,"data-indexed":t.hasIndexColumn}},[e("thead",[e("tr",[t.hasIndexColumn?e("th",{staticClass:"k-table-index-column",attrs:{"data-mobile":""}},[t._v(" # ")]):t._e(),t._l(t.columns,(function(s,n){return e("th",{key:n+"-header",staticClass:"k-table-column",style:"width:"+t.width(s.width),attrs:{"data-align":s.align,"data-mobile":s.mobile},on:{click:function(e){return t.onHeader({column:s,columnIndex:n})}}},[t._t("header",(function(){return[t._v(" "+t._s(t.label(s,n))+" ")]}),null,{column:s,columnIndex:n,label:t.label(s,n)})],2)})),t.hasOptions?e("th",{staticClass:"k-table-options-column",attrs:{"data-mobile":""}}):t._e()],2)]),e("k-draggable",{attrs:{list:t.values,options:t.dragOptions,handle:!0,element:"tbody"},on:{change:t.onChange,end:t.onSort}},[0===t.rows.length?e("tr",[e("td",{staticClass:"k-table-empty",attrs:{colspan:t.columnsCount}},[t._v(" "+t._s(t.empty)+" ")])]):t._l(t.values,(function(s,n){return e("tr",{key:n},[t.hasIndexColumn?e("td",{staticClass:"k-table-index-column",attrs:{"data-sortable":t.sortable&&!1!==s.sortable,"data-mobile":""}},[t._t("index",(function(){return[e("div",{staticClass:"k-table-index",domProps:{textContent:t._s(t.index+n)}})]}),null,{row:s,rowIndex:n}),t.sortable&&!1!==s.sortable?e("k-sort-handle",{staticClass:"k-table-sort-handle"}):t._e()],2):t._e(),t._l(t.columns,(function(i,o){return e("k-table-cell",{key:n+"-"+o,staticClass:"k-table-column",style:"width:"+t.width(i.width),attrs:{column:i,field:t.fields[o],row:s,mobile:i.mobile,value:s[o]},on:{input:function(e){return t.onCellUpdate({columnIndex:o,rowIndex:n,value:e})}},nativeOn:{click:function(e){return t.onCell({row:s,rowIndex:n,column:i,columnIndex:o})}}})})),t.hasOptions?e("td",{staticClass:"k-table-options-column",attrs:{"data-mobile":""}},[t._t("options",(function(){return[e("k-options-dropdown",{attrs:{options:s.options||t.options,text:(s.options||t.options).length>1},on:{option:function(e){return t.onOption(e,s,n)}}})]}),null,{row:s,rowIndex:n,options:t.options})],2):t._e()],2)}))],2)],1)}),[],!1,null,null,null,null).exports;const mn=G({inheritAttrs:!1,props:{column:Object,field:Object,mobile:{type:Boolean,default:!1},row:Object,value:{default:""}},computed:{component(){return this.$helper.isComponent(`k-${this.type}-field-preview`)?`k-${this.type}-field-preview`:this.$helper.isComponent(`k-table-${this.type}-cell`)?`k-table-${this.type}-cell`:Array.isArray(this.value)?"k-array-field-preview":"object"==typeof this.value?"k-object-field-preview":"k-text-field-preview"},type(){var t;return this.column.type||(null==(t=this.field)?void 0:t.type)}}},(function(){var t=this,e=t._self._c;return e("td",{attrs:{"data-align":t.column.align,"data-mobile":t.mobile}},[!1===t.$helper.object.isEmpty(t.value)?[e(t.component,{tag:"component",attrs:{column:t.column,field:t.field,row:t.row,value:t.value},on:{input:function(e){return t.$emit("input",e)}}})]:t._e()],2)}),[],!1,null,null,null,null).exports;const fn=G({props:{value:[String,Object]}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-table-update-status-cell"},["string"==typeof t.value?e("span",{staticClass:"k-table-update-status-cell-version"},[t._v(" "+t._s(t.value)+" ")]):e("k-dropdown",{attrs:{"data-theme":t.value.theme}},[e("k-button",{staticClass:"k-table-update-status-cell-button",attrs:{icon:t.value.icon,href:t.value.url},on:{click:function(e){return e.stopPropagation(),t.$refs.dropdown.toggle()}}},[t._v(" "+t._s(t.value.currentVersion)+" ")]),e("k-dropdown-content",{ref:"dropdown",attrs:{align:"right"}},[e("dl",{staticClass:"k-plugin-info"},[e("div",[e("dt",[t._v(t._s(t.$t("plugin")))]),e("dd",[t._v(t._s(t.value.pluginName))])]),e("div",[e("dt",[t._v(t._s(t.$t("version.current")))]),e("dd",[t._v(t._s(t.value.currentVersion))])]),e("div",[e("dt",[t._v(t._s(t.$t("version.latest")))]),e("dd",[t._v(t._s(t.value.latestVersion))])]),e("div",[e("dt",[t._v(t._s(t.$t("system.updateStatus")))]),e("dd",{attrs:{"data-theme":t.value.theme}},[t._v(t._s(t.value.label))])])]),t.value.url?e("k-dropdown-item",{attrs:{icon:"open",link:t.value.url}},[t._v(" "+t._s(t.$t("versionInformation"))+" ")]):t._e()],1)],1)],1)}),[],!1,null,null,null,null).exports;const gn=G({props:{tab:String,tabs:Array,theme:String},data(){return{size:null,visibleTabs:this.tabs,invisibleTabs:[]}},computed:{current(){return(this.tabs.find((t=>t.name===this.tab))||this.tabs[0]||{}).name}},watch:{tabs:{handler(t){this.visibleTabs=t,this.invisibleTabs=[],this.resize(!0)},immediate:!0}},created(){window.addEventListener("resize",this.resize)},destroyed(){window.removeEventListener("resize",this.resize)},methods:{resize(t){if(this.tabs&&!(this.tabs.length<=1)){if(this.tabs.length<=3)return this.visibleTabs=this.tabs,void(this.invisibleTabs=[]);if(window.innerWidth>=700){if("large"===this.size&&!t)return;this.visibleTabs=this.tabs,this.invisibleTabs=[],this.size="large"}else{if("small"===this.size&&!t)return;this.visibleTabs=this.tabs.slice(0,2),this.invisibleTabs=this.tabs.slice(2),this.size="small"}}}}},(function(){var t=this,e=t._self._c;return t.tabs&&t.tabs.length>1?e("div",{staticClass:"k-tabs",attrs:{"data-theme":t.theme}},[e("nav",[t._l(t.visibleTabs,(function(s){return e("k-button",{key:s.name,staticClass:"k-tab-button",attrs:{link:s.link,current:t.current===s.name,icon:s.icon,tooltip:s.label}},[t._v(" "+t._s(s.label||s.text||s.name)+" "),s.badge?e("span",{staticClass:"k-tabs-badge"},[t._v(" "+t._s(s.badge)+" ")]):t._e()])})),t.invisibleTabs.length?e("k-button",{staticClass:"k-tab-button k-tabs-dropdown-button",attrs:{text:t.$t("more"),icon:"dots"},on:{click:function(e){return e.stopPropagation(),t.$refs.more.toggle()}}}):t._e()],2),t.invisibleTabs.length?e("k-dropdown-content",{ref:"more",staticClass:"k-tabs-dropdown",attrs:{align:"right"}},t._l(t.invisibleTabs,(function(s){return e("k-dropdown-item",{key:"more-"+s.name,attrs:{link:s.link,current:t.tab===s.name,icon:s.icon,tooltip:s.label}},[t._v(" "+t._s(s.label||s.text||s.name)+" ")])})),1):t._e()],1):t._e()}),[],!1,null,null,null,null).exports;const kn=G({props:{align:String}},(function(){var t=this;return(0,t._self._c)("div",{staticClass:"k-view",attrs:{"data-align":t.align}},[t._t("default")],2)}),[],!1,null,null,null,null).exports,bn={install(t){t.component("k-aspect-ratio",Vs),t.component("k-bar",Js),t.component("k-box",Gs),t.component("k-bubble",Ws),t.component("k-bubbles",Xs),t.component("k-collection",Zs),t.component("k-column",Qs),t.component("k-dropzone",tn),t.component("k-empty",en),t.component("k-file-preview",sn),t.component("k-grid",nn),t.component("k-header",on),t.component("k-inside",rn),t.component("k-item",ln),t.component("k-item-image",an),t.component("k-items",un),t.component("k-overlay",cn),t.component("k-panel",dn),t.component("k-stats",pn),t.component("k-table",hn),t.component("k-table-cell",mn),t.component("k-table-update-status-cell",fn),t.component("k-tabs",gn),t.component("k-view",kn)}},vn={};const yn=G({components:{draggable:()=>function(t,e,s){if(!e||0===e.length)return t();const n=document.getElementsByTagName("link");return Promise.all(e.map((t=>{if((t=function(t){return"/"+t}(t))in vn)return;vn[t]=!0;const e=t.endsWith(".css"),i=e?'[rel="stylesheet"]':"";if(s)for(let s=n.length-1;s>=0;s--){const i=n[s];if(i.href===t&&(!e||"stylesheet"===i.rel))return}else if(document.querySelector(`link[href="${t}"]${i}`))return;const o=document.createElement("link");return o.rel=e?"stylesheet":"modulepreload",e||(o.as="script",o.crossOrigin=""),o.href=t,document.head.appendChild(o),e?new Promise(((e,s)=>{o.addEventListener("load",e),o.addEventListener("error",(()=>s(new Error(`Unable to preload CSS for ${t}`))))})):void 0}))).then((()=>t()))}((()=>import("./vuedraggable.js")),[])},props:{data:Object,element:String,handle:[String,Boolean],list:[Array,Object],move:Function,options:Object},data(){return{listeners:{...this.$listeners,start:t=>{this.$store.dispatch("drag",{}),this.$listeners.start&&this.$listeners.start(t)},end:t=>{this.$store.dispatch("drag",null),this.$listeners.end&&this.$listeners.end(t)}}}},computed:{dragOptions(){let t=!1;return t=!0===this.handle?".k-sort-handle":this.handle,{fallbackClass:"k-sortable-fallback",fallbackOnBody:!0,forceFallback:!0,ghostClass:"k-sortable-ghost",handle:t,scroll:document.querySelector(".k-panel-view"),...this.options}}}},(function(){var t=this;return(0,t._self._c)("draggable",t._g(t._b({staticClass:"k-draggable",attrs:{"component-data":t.data,tag:t.element,list:t.list,move:t.move},scopedSlots:t._u([{key:"footer",fn:function(){return[t._t("footer")]},proxy:!0}],null,!0)},"draggable",t.dragOptions,!1),t.listeners),[t._t("default")],2)}),[],!1,null,null,null,null).exports;const $n=G({data:()=>({error:null}),errorCaptured(t){return this.$config.debug&&window.console.warn(t),this.error=t,!1},render(){return this.error?this.$slots.error?this.$slots.error[0]:this.$scopedSlots.error?this.$scopedSlots.error({error:this.error}):L("k-box",{attrs:{theme:"negative"}},this.error.message||this.error):this.$slots.default[0]}},null,null,!1,null,null,null,null).exports;const _n=G({props:{html:String},mounted(){try{let t=this.$refs.iframe.contentWindow.document;t.open(),t.write(this.html),t.close()}catch(t){console.error(t)}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-fatal"},[e("div",{staticClass:"k-fatal-box"},[e("k-bar",{scopedSlots:t._u([{key:"left",fn:function(){return[e("k-headline",[t._v(" The JSON response could not be parsed ")])]},proxy:!0},{key:"right",fn:function(){return[e("k-button",{attrs:{icon:"cancel",text:"Close"},on:{click:function(e){return t.$store.dispatch("fatal",!1)}}})]},proxy:!0}])}),e("iframe",{ref:"iframe",staticClass:"k-fatal-iframe"})],1)])}),[],!1,null,null,null,null).exports;const xn=G({props:{link:String,size:{type:String},tag:{type:String,default:"h2"},theme:{type:String}}},(function(){var t=this,e=t._self._c;return e(t.tag,t._g({tag:"component",staticClass:"k-headline",attrs:{"data-theme":t.theme,"data-size":t.size}},t.$listeners),[t.link?e("k-link",{attrs:{to:t.link}},[t._t("default")],2):t._t("default")],2)}),[],!1,null,null,null,null).exports;const wn=G({props:{alt:String,color:String,back:String,size:String,type:String},computed:{isEmoji(){return this.$helper.string.hasEmoji(this.type)}}},(function(){var t=this,e=t._self._c;return e("span",{class:"k-icon k-icon-"+t.type,style:{background:t.$helper.color(t.back)},attrs:{"aria-label":t.alt,role:t.alt?"img":null,"aria-hidden":!t.alt,"data-back":t.back,"data-size":t.size}},[t.isEmoji?e("span",{staticClass:"k-icon-emoji"},[t._v(t._s(t.type))]):e("svg",{style:{color:t.$helper.color(t.color)},attrs:{viewBox:"0 0 16 16"}},[e("use",{attrs:{"xlink:href":"#icon-"+t.type}})])])}),[],!1,null,null,null,null).exports;const Sn=G({icons:window.panel.plugins.icons},(function(){var t=this,e=t._self._c;return e("svg",{staticClass:"k-icons",attrs:{"aria-hidden":"true",xmlns:"http://www.w3.org/2000/svg",overflow:"hidden"}},[e("defs",t._l(t.$options.icons,(function(s,n){return e("symbol",{key:n,attrs:{id:"icon-"+n,viewBox:"0 0 16 16"},domProps:{innerHTML:t._s(s)}})})),0)])}),[],!1,null,null,null,null).exports;const Cn=G({props:{alt:String,back:String,cover:Boolean,ratio:String,sizes:String,src:String,srcset:String},data:()=>({loaded:{type:Boolean,default:!1},error:{type:Boolean,default:!1}}),computed:{ratioPadding(){return this.$helper.ratio(this.ratio||"1/1")}},created(){let t=new Image;t.onload=()=>{this.loaded=!0,this.$emit("load")},t.onerror=()=>{this.error=!0,this.$emit("error")},t.src=this.src}},(function(){var t=this,e=t._self._c;return e("span",t._g({staticClass:"k-image",attrs:{"data-ratio":t.ratio,"data-back":t.back,"data-cover":t.cover}},t.$listeners),[e("span",{style:"padding-bottom:"+t.ratioPadding},[t.loaded?e("img",{key:t.src,attrs:{alt:t.alt||"",src:t.src,srcset:t.srcset,sizes:t.sizes},on:{dragstart:function(t){t.preventDefault()}}}):t._e(),t.loaded||t.error?t._e():e("k-loader",{attrs:{position:"center",theme:"light"}}),!t.loaded&&t.error?e("k-icon",{staticClass:"k-image-error",attrs:{type:"cancel"}}):t._e()],1)])}),[],!1,null,null,null,null).exports;const On=G({},(function(){var t=this._self._c;return t("span",{staticClass:"k-loader"},[t("k-icon",{staticClass:"k-loader-icon",attrs:{type:"loader"}})],1)}),[],!1,null,null,null,null).exports;const An=G({data:()=>({offline:!1}),created(){this.$events.$on("offline",this.isOffline),this.$events.$on("online",this.isOnline)},destroyed(){this.$events.$off("offline",this.isOffline),this.$events.$off("online",this.isOnline)},methods:{isOnline(){this.offline=!1},isOffline(){this.offline=!0}}},(function(){var t=this,e=t._self._c;return t.offline?e("div",{staticClass:"k-offline-warning"},[e("p",[e("k-icon",{attrs:{type:"bolt"}}),t._v(" "+t._s(t.$t("error.offline")))],1)]):t._e()}),[],!1,null,null,null,null).exports,Tn=(t,e=!1)=>{if(t>=0&&t<=100)return!0;if(e)throw new Error("value has to be between 0 and 100");return!1};const In=G({props:{value:{type:Number,default:0,validator:Tn}},data(){return{state:this.value}},watch:{value(t){this.state=t}},methods:{set(t){Tn(t,!0),this.state=t}}},(function(){var t=this;return(0,t._self._c)("progress",{staticClass:"k-progress",attrs:{max:"100"},domProps:{value:t.state}},[t._v(t._s(t.state)+"%")])}),[],!1,null,null,null,null).exports;const jn=G({},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-registration"},[e("p",[t._v(t._s(t.$t("license.unregistered")))]),e("k-button",{staticClass:"k-topbar-button",attrs:{responsive:!0,tooltip:t.$t("license.unregistered"),icon:"key"},on:{click:function(e){return t.$dialog("registration")}}},[t._v(" "+t._s(t.$t("license.register"))+" ")]),e("k-button",{staticClass:"k-topbar-button",attrs:{responsive:!0,link:"https://getkirby.com/buy",target:"_blank",icon:"cart"}},[t._v(" "+t._s(t.$t("license.buy"))+" ")])],1)}),[],!1,null,null,null,null).exports;const En=G({props:{icon:{type:String,default:"sort"}}},(function(){return(0,this._self._c)("k-icon",{staticClass:"k-sort-handle",attrs:{type:this.icon,"aria-hidden":"true"}})}),[],!1,null,null,null,null).exports;const Mn=G({props:{click:{type:Function,default:()=>{}},disabled:Boolean,responsive:Boolean,status:String,text:String,tooltip:String},computed:{icon(){return"draft"===this.status?"circle-outline":"unlisted"===this.status?"circle-half":"circle"},theme(){return"draft"===this.status?"negative":"unlisted"===this.status?"info":"positive"},title(){let t=this.tooltip||this.text;return this.disabled&&(t+=` (${this.$t("disabled")})`),t}},methods:{onClick(){this.click(),this.$emit("click")}}},(function(){var t=this;return(0,t._self._c)("k-button",{class:"k-status-icon k-status-icon-"+t.status,attrs:{disabled:t.disabled,icon:t.icon,responsive:t.responsive,text:t.text,theme:t.theme,tooltip:t.title},on:{click:t.onClick}})}),[],!1,null,null,null,null).exports;const Ln=G({props:{align:String,html:String,size:String,theme:String},computed:{attrs(){return{class:"k-text","data-align":this.align,"data-size":this.size,"data-theme":this.theme}}}},(function(){var t=this,e=t._self._c;return t.html?e("div",t._b({domProps:{innerHTML:t._s(t.html)}},"div",t.attrs,!1)):e("div",t._b({},"div",t.attrs,!1),[t._t("default")],2)}),[],!1,null,null,null,null).exports;const Bn=G({props:{user:[Object,String]}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-user-info"},[t.user.avatar?e("k-image",{attrs:{cover:!0,src:t.user.avatar.url,ratio:"1/1"}}):e("k-icon",{attrs:{type:"user"}}),t._v(" "+t._s(t.user.name||t.user.email||t.user)+" ")],1)}),[],!1,null,null,null,null).exports,Dn={install(t){t.component("k-draggable",yn),t.component("k-error-boundary",$n),t.component("k-fatal",_n),t.component("k-headline",xn),t.component("k-icon",wn),t.component("k-icons",Sn),t.component("k-image",Cn),t.component("k-loader",On),t.component("k-offline-warning",An),t.component("k-progress",In),t.component("k-registration",jn),t.component("k-status-icon",Mn),t.component("k-sort-handle",En),t.component("k-text",Ln),t.component("k-user-info",Bn)}};const Pn=G({props:{crumbs:{type:Array,default:()=>[]},label:{type:String,default:"Breadcrumb"},view:Object},computed:{dropdown(){return this.segments.map((t=>({...t,text:t.label,icon:"angle-right"})))},segments(){return[{link:this.view.link,label:this.view.breadcrumbLabel,icon:this.view.icon,loading:this.$store.state.isLoading},...this.crumbs]}},methods:{isLast(t){return this.crumbs.length-1===t}}},(function(){var t=this,e=t._self._c;return e("nav",{staticClass:"k-breadcrumb",attrs:{"aria-label":t.label}},[e("k-dropdown",{staticClass:"k-breadcrumb-dropdown"},[e("k-button",{attrs:{icon:"road-sign"},on:{click:function(e){return t.$refs.dropdown.toggle()}}}),e("k-dropdown-content",{ref:"dropdown",attrs:{options:t.dropdown,theme:"light"}})],1),e("ol",t._l(t.segments,(function(s,n){return e("li",{key:n},[e("k-link",{staticClass:"k-breadcrumb-link",attrs:{title:s.text||s.label,to:s.link,"aria-current":!!t.isLast(n)&&"page"}},[s.loading?e("k-loader",{staticClass:"k-breadcrumb-icon"}):s.icon?e("k-icon",{staticClass:"k-breadcrumb-icon",attrs:{type:s.icon}}):t._e(),e("span",{staticClass:"k-breadcrumb-link-text"},[t._v(" "+t._s(s.text||s.label)+" ")])],1)],1)})),0)],1)}),[],!1,null,null,null,null).exports;const Nn=G({inheritAttrs:!1,props:{autofocus:Boolean,click:Function,current:[String,Boolean],disabled:Boolean,icon:String,id:[String,Number],link:String,responsive:Boolean,rel:String,role:String,target:String,tabindex:String,text:[String,Number],theme:String,tooltip:String,type:{type:String,default:"button"}},computed:{component(){return!0===this.disabled?"k-button-disabled":this.link?"k-button-link":"k-button-native"}},methods:{focus(){this.$refs.button.focus&&this.$refs.button.focus()},tab(){this.$refs.button.tab&&this.$refs.button.tab()},untab(){this.$refs.button.untab&&this.$refs.button.untab()}}},(function(){var t=this;return(0,t._self._c)(t.component,t._g(t._b({ref:"button",tag:"component"},"component",t.$props,!1),t.$listeners),[t.text?[t._v(" "+t._s(t.text)+" ")]:t._t("default")],2)}),[],!1,null,null,null,null).exports;const Fn=G({inheritAttrs:!1,props:{icon:String,id:[String,Number],responsive:Boolean,theme:String,tooltip:String}},(function(){var t=this,e=t._self._c;return e("span",{staticClass:"k-button",attrs:{id:t.id,"data-disabled":!0,"data-responsive":t.responsive,"data-theme":t.theme,title:t.tooltip}},[t.icon?e("k-icon",{staticClass:"k-button-icon",attrs:{type:t.icon,alt:t.tooltip}}):t._e(),t.$slots.default?e("span",{staticClass:"k-button-text"},[t._t("default")],2):t._e()],1)}),[],!1,null,null,null,null).exports;const qn=G({props:{buttons:Array}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-button-group"},[t.$slots.default?t._t("default"):t._l(t.buttons,(function(s,n){return e("k-button",t._b({key:n},"k-button",s,!1))}))],2)}),[],!1,null,null,null,null).exports;const Rn=G({inheritAttrs:!1,props:{autofocus:Boolean,current:[String,Boolean],icon:String,id:[String,Number],link:String,rel:String,responsive:Boolean,role:String,target:String,tabindex:String,theme:String,tooltip:String},methods:{focus(){this.$el.focus()}}},(function(){var t=this,e=t._self._c;return e("k-link",t._g({staticClass:"k-button",attrs:{id:t.id,"aria-current":t.current,autofocus:t.autofocus,"data-theme":t.theme,"data-responsive":t.responsive,rel:t.rel,role:t.role,tabindex:t.tabindex,target:t.target,title:t.tooltip,to:t.link}},t.$listeners),[t.icon?e("k-icon",{staticClass:"k-button-icon",attrs:{type:t.icon,alt:t.tooltip}}):t._e(),t.$slots.default?e("span",{staticClass:"k-button-text"},[t._t("default")],2):t._e()],1)}),[],!1,null,null,null,null).exports,zn={mounted(){this.$el.addEventListener("keyup",this.onTab,!0),this.$el.addEventListener("blur",this.onUntab,!0)},destroyed(){this.$el.removeEventListener("keyup",this.onTab,!0),this.$el.removeEventListener("blur",this.onUntab,!0)},methods:{focus(){this.$el.focus&&this.$el.focus()},onTab(t){9===t.keyCode&&this.$el.setAttribute("data-tabbed",!0)},onUntab(){this.$el.removeAttribute("data-tabbed")},tab(){this.$el.focus(),this.$el.setAttribute("data-tabbed",!0)},untab(){this.$el.removeAttribute("data-tabbed")}}};const Yn=G({mixins:[zn],inheritAttrs:!1,props:{autofocus:Boolean,click:{type:Function,default:()=>{}},current:[String,Boolean],icon:String,id:[String,Number],responsive:Boolean,role:String,tabindex:String,theme:String,tooltip:String,type:{type:String,default:"button"}}},(function(){var t=this,e=t._self._c;return e("button",t._g({staticClass:"k-button",attrs:{id:t.id,"aria-current":t.current,autofocus:t.autofocus,"data-theme":t.theme,"data-responsive":t.responsive,role:t.role,tabindex:t.tabindex,title:t.tooltip,type:t.type},on:{click:t.click}},t.$listeners),[t.icon?e("k-icon",{staticClass:"k-button-icon",attrs:{type:t.icon,alt:t.tooltip}}):t._e(),t.$slots.default?e("span",{staticClass:"k-button-text"},[t._t("default")],2):t._e()],1)}),[],!1,null,null,null,null).exports;const Hn=G({},(function(){return(0,this._self._c)("span",{staticClass:"k-dropdown",on:{click:function(t){t.stopPropagation()}}},[this._t("default")],2)}),[],!1,null,null,null,null).exports;let Un=null;const Kn=G({props:{align:{type:String,default:"left"},options:[Array,Function,String],theme:{type:String,default:"dark"}},data:()=>({current:-1,dropup:!1,isOpen:!1,items:[]}),methods:{async fetchOptions(t){if(!this.options)return t(this.items);"string"==typeof this.options?this.$dropdown(this.options)(t):"function"==typeof this.options?this.options(t):Array.isArray(this.options)&&t(this.options)},onOptionClick(t){"function"==typeof t.click?t.click.call(this):t.click&&this.$emit("action",t.click)},open(){this.reset(),Un&&Un!==this&&Un.close(),this.fetchOptions((t=>{this.$events.$on("keydown",this.navigate),this.$events.$on("click",this.close),this.items=t,this.isOpen=!0,Un=this,this.onOpen(),this.$emit("open")}))},reset(){this.current=-1,this.$events.$off("keydown",this.navigate),this.$events.$off("click",this.close)},close(){this.reset(),this.isOpen=Un=!1,this.$emit("close")},toggle(){this.isOpen?this.close():this.open()},focus(t=0){var e;const s=null==(e=this.$refs[t+"-item"])?void 0:e[0];(null==s?void 0:s.focus)&&(this.current=t,s.focus())},onOpen(){this.dropup=!1,this.$nextTick((()=>{if(this.$el){let t=window.innerHeight||document.body.clientHeight||document.documentElement.clientHeight,e=50,s=this.$el.getBoundingClientRect().top||0,n=this.$el.clientHeight;s+n>t-e&&n+2*ethis.items.length-1){const t=this.items.filter((t=>!1===t.disabled));this.current=this.items.indexOf(t[t.length-1]);break}if(this.items[this.current]&&!1===this.items[this.current].disabled){this.focus(this.current);break}}break;case"Tab":for(;;){if(this.current++,this.current>this.items.length-1){this.close(),this.$emit("leave",t.code);break}if(this.items[this.current]&&!1===this.items[this.current].disabled)break}}}}},(function(){var t=this,e=t._self._c;return t.isOpen?e("div",{staticClass:"k-dropdown-content",attrs:{"data-align":t.align,"data-dropup":t.dropup,"data-theme":t.theme}},[t._t("default",(function(){return[t._l(t.items,(function(s,n){return["-"===s?e("hr",{key:n+"separator"}):e("k-dropdown-item",t._b({key:n+"-item",ref:n+"-item",refInFor:!0,on:{click:function(e){return t.onOptionClick(s)}}},"k-dropdown-item",s,!1),[t._v(" "+t._s(s.text)+" ")])]}))]}))],2):t._e()}),[],!1,null,null,null,null).exports;const Vn=G({inheritAttrs:!1,props:{disabled:Boolean,icon:String,image:[String,Object],link:String,target:String,theme:String,upload:String,current:[String,Boolean]},data(){return{listeners:{...this.$listeners,click:t=>{this.$parent.close(),this.$emit("click",t)}}}},methods:{focus(){this.$refs.button.focus()},tab(){this.$refs.button.tab()}}},(function(){var t=this;return(0,t._self._c)("k-button",t._g(t._b({ref:"button",staticClass:"k-dropdown-item"},"k-button",t.$props,!1),t.listeners),[t._t("default")],2)}),[],!1,null,null,null,null).exports;const Jn=G({mixins:[zn],props:{disabled:Boolean,rel:String,tabindex:[String,Number],target:String,title:String,to:[String,Function]},data(){return{relAttr:"_blank"===this.target?"noreferrer noopener":this.rel,listeners:{...this.$listeners,click:this.onClick}}},computed:{href(){return"function"==typeof this.to?"":"/"!==this.to[0]||this.target?!0===this.to.includes("@")&&!1===this.to.includes("/")?"mailto:"+this.to:this.to:this.$url(this.to)}},methods:{isRoutable(t){if(t.metaKey||t.altKey||t.ctrlKey||t.shiftKey)return!1;if(t.defaultPrevented)return!1;if(void 0!==t.button&&0!==t.button)return!1;if(this.target)return!1;if("string"==typeof this.href){if(this.href.includes("://")||this.href.startsWith("//"))return!1;if(this.href.includes("mailto:"))return!1}return!0},onClick(t){if(!0===this.disabled)return t.preventDefault(),!1;"function"==typeof this.to&&(t.preventDefault(),this.to()),this.isRoutable(t)&&(t.preventDefault(),this.$go(this.to)),this.$emit("click",t)}}},(function(){var t=this,e=t._self._c;return t.to&&!t.disabled?e("a",t._g({ref:"link",staticClass:"k-link",attrs:{href:t.href,rel:t.relAttr,tabindex:t.tabindex,target:t.target,title:t.title}},t.listeners),[t._t("default")],2):e("span",{staticClass:"k-link",attrs:{title:t.title,"data-disabled":""}},[t._t("default")],2)}),[],!1,null,null,null,null).exports;const Gn=G({computed:{defaultLanguage(){return this.$languages.find((t=>!0===t.default))},language(){return this.$language},languages(){return this.$languages.filter((t=>!1===t.default))}},methods:{change(t){this.$emit("change",t),this.$go(window.location,{query:{language:t.code}})}}},(function(){var t=this,e=t._self._c;return t.languages.length?e("k-dropdown",{staticClass:"k-languages-dropdown"},[e("k-button",{attrs:{text:t.language.name,responsive:!0,icon:"globe"},on:{click:function(e){return t.$refs.languages.toggle()}}}),t.languages?e("k-dropdown-content",{ref:"languages"},[e("k-dropdown-item",{on:{click:function(e){return t.change(t.defaultLanguage)}}},[t._v(" "+t._s(t.defaultLanguage.name)+" ")]),e("hr"),t._l(t.languages,(function(s){return e("k-dropdown-item",{key:s.code,on:{click:function(e){return t.change(s)}}},[t._v(" "+t._s(s.name)+" ")])}))],2):t._e()],1):t._e()}),[],!1,null,null,null,null).exports;const Wn=G({props:{align:{type:String,default:"right"},icon:{type:String,default:"dots"},options:{type:[Array,Function,String],default:()=>[]},text:{type:[Boolean,String],default:!0},theme:{type:String,default:"dark"}},computed:{hasSingleOption(){return Array.isArray(this.options)&&1===this.options.length}},methods:{onAction(t,e,s){"function"==typeof t?t.call(this):(this.$emit("action",t,e,s),this.$emit("option",t,e,s))},toggle(){this.$refs.options.toggle()}}},(function(){var t=this,e=t._self._c;return t.hasSingleOption?e("k-button",{staticClass:"k-options-dropdown-toggle",attrs:{icon:t.options[0].icon||t.icon,tooltip:t.options[0].tooltip||t.options[0].text},on:{click:function(e){return t.onAction(t.options[0].option||t.options[0].click,t.options[0],0)}}},[!0===t.text?[t._v(" "+t._s(t.options[0].text)+" ")]:!1!==t.text?[t._v(" "+t._s(t.text)+" ")]:t._e()],2):t.options.length?e("k-dropdown",{staticClass:"k-options-dropdown"},[e("k-button",{staticClass:"k-options-dropdown-toggle",attrs:{icon:t.icon,tooltip:t.$t("options")},on:{click:function(e){return t.$refs.options.toggle()}}},[t.text&&!0!==t.text?[t._v(" "+t._s(t.text)+" ")]:t._e()],2),e("k-dropdown-content",{ref:"options",staticClass:"k-options-dropdown-content",attrs:{align:t.align,options:t.options},on:{action:t.onAction}})],1):t._e()}),[],!1,null,null,null,null).exports;const Xn=G({props:{align:{type:String,default:"left"},details:{type:Boolean,default:!1},dropdown:{type:Boolean,default:!0},keys:{type:Boolean,default:!1},limit:{type:Number,default:10},page:{type:Number,default:1},pageLabel:{type:String,default:()=>window.panel.$t("pagination.page")},total:{type:Number,default:0},prevLabel:{type:String,default:()=>window.panel.$t("prev")},nextLabel:{type:String,default:()=>window.panel.$t("next")},validate:{type:Function,default:()=>Promise.resolve()}},data(){return{currentPage:this.page}},computed:{show(){return this.pages>1},start(){return(this.currentPage-1)*this.limit+1},end(){let t=this.start-1+this.limit;return t>this.total?this.total:t},detailsText(){return 1===this.limit?this.start+" / ":this.start+"-"+this.end+" / "},pages(){return Math.ceil(this.total/this.limit)},hasPrev(){return this.start>1},hasNext(){return this.endthis.limit},offset(){return this.start-1}},watch:{page(t){this.currentPage=parseInt(t)}},created(){!0===this.keys&&window.addEventListener("keydown",this.navigate,!1)},destroyed(){window.removeEventListener("keydown",this.navigate,!1)},methods:{async goTo(t){try{await this.validate(t),t<1&&(t=1),t>this.pages&&(t=this.pages),this.currentPage=t,this.$refs.dropdown&&this.$refs.dropdown.close(),this.$emit("paginate",{page:this.currentPage,start:this.start,end:this.end,limit:this.limit,offset:this.offset})}catch(e){}},prev(){this.goTo(this.currentPage-1)},next(){this.goTo(this.currentPage+1)},navigate(t){switch(t.code){case"ArrowLeft":this.prev();break;case"ArrowRight":this.next()}}}},(function(){var t=this,e=t._self._c;return t.show?e("nav",{staticClass:"k-pagination",attrs:{"data-align":t.align}},[t.show?e("k-button",{attrs:{disabled:!t.hasPrev,tooltip:t.prevLabel,icon:"angle-left"},on:{click:t.prev}}):t._e(),t.details?[t.dropdown?[e("k-dropdown",[e("k-button",{staticClass:"k-pagination-details",attrs:{disabled:!t.hasPages},on:{click:function(e){return t.$refs.dropdown.toggle()}}},[t.total>1?[t._v(" "+t._s(t.detailsText)+" ")]:t._e(),t._v(" "+t._s(t.total)+" ")],2),e("k-dropdown-content",{ref:"dropdown",staticClass:"k-pagination-selector",on:{open:function(e){t.$nextTick((()=>t.$refs.page.focus()))}}},[e("div",{staticClass:"k-pagination-settings"},[e("label",{attrs:{for:"k-pagination-page"}},[e("span",[t._v(t._s(t.pageLabel)+":")]),e("select",{ref:"page",attrs:{id:"k-pagination-page"}},t._l(t.pages,(function(s){return e("option",{key:s,domProps:{selected:t.page===s,value:s}},[t._v(" "+t._s(s)+" ")])})),0)]),e("k-button",{attrs:{icon:"check"},on:{click:function(e){return t.goTo(t.$refs.page.value)}}})],1)])],1)]:[e("span",{staticClass:"k-pagination-details"},[t.total>1?[t._v(" "+t._s(t.detailsText)+" ")]:t._e(),t._v(" "+t._s(t.total)+" ")],2)]]:t._e(),t.show?e("k-button",{attrs:{disabled:!t.hasNext,tooltip:t.nextLabel,icon:"angle-right"},on:{click:t.next}}):t._e()],2):t._e()}),[],!1,null,null,null,null).exports;const Zn=G({props:{prev:{type:[Boolean,Object],default:!1},next:{type:[Boolean,Object],default:!1}},computed:{buttons(){return[{...this.button(this.prev),icon:"angle-left"},{...this.button(this.next),icon:"angle-right"}]}},methods:{button:t=>t||{disabled:!0,link:"#"}}},(function(){return(0,this._self._c)("k-button-group",{staticClass:"k-prev-next",attrs:{buttons:this.buttons}})}),[],!1,null,null,null,null).exports;const Qn=G({props:{types:{type:Object,default:()=>({})},type:String},data(){return{isLoading:!1,hasResults:!0,items:[],currentType:this.getType(this.type),q:null,selected:-1}},watch:{q(t,e){t!==e&&this.search(this.q)},currentType(t,e){t!==e&&this.search(this.q)},type(){this.currentType=this.getType(this.type)}},created(){this.search=tt(this.search,250),this.$events.$on("keydown.cmd.shift.f",this.open)},destroyed(){this.$events.$off("keydown.cmd.shift.f",this.open)},methods:{changeType(t){this.currentType=this.getType(t),this.$nextTick((()=>{this.$refs.input.focus()}))},close(){this.$refs.overlay.close(),this.hasResults=!0,this.items=[],this.q=null},getType(t){return this.types[t]||this.types[Object.keys(this.types)[0]]},navigate(t){this.$go(t.link),this.close()},onDown(){this.selected=0&&this.select(this.selected-1)},open(){this.$refs.overlay.open()},async search(t){this.isLoading=!0,this.$refs.types&&this.$refs.types.close();try{if(null===t||""===t)throw Error("Empty query");const e=await this.$search(this.currentType.id,t);if(!1===e)throw Error("JSON parsing failed");this.items=e.results}catch(e){this.items=[]}finally{this.select(-1),this.isLoading=!1,this.hasResults=this.items.length>0}},select(t){if(this.selected=t,this.$refs.items){const e=this.$refs.items.$el.querySelectorAll(".k-item");[...e].forEach((t=>delete t.dataset.selected)),t>=0&&(e[t].dataset.selected=!0)}}}},(function(){var t=this,e=t._self._c;return e("k-overlay",{ref:"overlay"},[e("div",{staticClass:"k-search",attrs:{role:"search"}},[e("div",{staticClass:"k-search-input"},[e("k-dropdown",{staticClass:"k-search-types"},[e("k-button",{attrs:{icon:t.currentType.icon,text:t.currentType.label},on:{click:function(e){return t.$refs.types.toggle()}}}),e("k-dropdown-content",{ref:"types"},t._l(t.types,(function(s,n){return e("k-dropdown-item",{key:n,attrs:{icon:s.icon},on:{click:function(e){return t.changeType(n)}}},[t._v(" "+t._s(s.label)+" ")])})),1)],1),e("input",{ref:"input",attrs:{placeholder:t.$t("search")+" …","aria-label":t.$t("search"),autofocus:!0,type:"text"},domProps:{value:t.q},on:{input:function(e){return t.onInput(e.target.value)},keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"down",40,e.key,["Down","ArrowDown"])?null:(e.preventDefault(),t.onDown.apply(null,arguments))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"up",38,e.key,["Up","ArrowUp"])?null:(e.preventDefault(),t.onUp.apply(null,arguments))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"tab",9,e.key,"Tab")?null:(e.preventDefault(),t.onTab.apply(null,arguments))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"enter",13,e.key,"Enter")?null:t.onEnter.apply(null,arguments)},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"esc",27,e.key,["Esc","Escape"])?null:t.close.apply(null,arguments)}]}}),e("k-button",{staticClass:"k-search-close",attrs:{icon:t.isLoading?"loader":"cancel",tooltip:t.$t("close")},on:{click:t.close}})],1),!t.q||t.hasResults&&!t.items.length?t._e():e("div",{staticClass:"k-search-results"},[t.items.length?e("k-collection",{ref:"items",attrs:{items:t.items},on:{hover:t.onHover},nativeOn:{mouseout:function(e){return t.select(-1)}}}):t.hasResults?t._e():e("p",{staticClass:"k-search-empty"},[t._v(" "+t._s(t.$t("search.results.none"))+" ")])],1)])])}),[],!1,null,null,null,null).exports;const ti=G({props:{removable:Boolean},methods:{remove(){this.removable&&this.$emit("remove")},focus(){this.$refs.button.focus()}}},(function(){var t=this,e=t._self._c;return e("span",{ref:"button",staticClass:"k-tag",attrs:{tabindex:"0"},on:{keydown:function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"delete",[8,46],e.key,["Backspace","Delete","Del"])?null:(e.preventDefault(),t.remove.apply(null,arguments))}}},[e("span",{staticClass:"k-tag-text"},[t._t("default")],2),t.removable?e("k-icon",{staticClass:"k-tag-toggle",attrs:{type:"cancel-small"},nativeOn:{click:function(e){return t.remove.apply(null,arguments)}}}):t._e()],1)}),[],!1,null,null,null,null).exports;const ei=G({props:{breadcrumb:Array,license:Boolean,menu:Array,title:String,view:Object},computed:{notification(){return this.$store.state.notification.type&&"error"!==this.$store.state.notification.type?this.$store.state.notification:null}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-topbar"},[e("k-view",[e("div",{staticClass:"k-topbar-wrapper"},[e("k-dropdown",{staticClass:"k-topbar-menu"},[e("k-button",{staticClass:"k-topbar-button k-topbar-menu-button",attrs:{tooltip:t.$t("menu"),icon:"bars"},on:{click:function(e){return t.$refs.menu.toggle()}}},[e("k-icon",{attrs:{type:"angle-down"}})],1),e("k-dropdown-content",{ref:"menu",staticClass:"k-topbar-menu",attrs:{options:t.menu,theme:"light"}})],1),e("k-breadcrumb",{staticClass:"k-topbar-breadcrumb",attrs:{crumbs:t.breadcrumb,view:t.view}}),e("div",{staticClass:"k-topbar-signals"},[t.notification?e("k-button",{staticClass:"k-topbar-notification k-topbar-button",attrs:{text:t.notification.message,theme:"positive"},on:{click:function(e){return t.$store.dispatch("notification/close")}}}):t.license?t._e():e("k-registration"),e("k-form-indicator"),e("k-button",{staticClass:"k-topbar-button",attrs:{tooltip:t.$t("search"),icon:"search"},on:{click:function(e){return t.$refs.search.open()}}})],1)],1)]),e("k-search",{ref:"search",attrs:{type:t.$view.search||"pages",types:t.$searches}})],1)}),[],!1,null,null,null,null).exports,si={install(t){t.component("k-breadcrumb",Pn),t.component("k-button",Nn),t.component("k-button-disabled",Fn),t.component("k-button-group",qn),t.component("k-button-link",Rn),t.component("k-button-native",Yn),t.component("k-dropdown",Hn),t.component("k-dropdown-content",Kn),t.component("k-dropdown-item",Vn),t.component("k-languages-dropdown",Gn),t.component("k-link",Jn),t.component("k-options-dropdown",Wn),t.component("k-pagination",Xn),t.component("k-prev-next",Zn),t.component("k-search",Qn),t.component("k-tag",ti),t.component("k-topbar",ei)}};const ni=G({props:{empty:String,blueprint:String,lock:[Boolean,Object],parent:String,tab:Object},computed:{content(){return this.$store.getters["content/values"]()}},methods:{exists(t){return this.$helper.isComponent(`k-${t}-section`)}}},(function(){var t=this,e=t._self._c;return 0===t.tab.columns.length?e("k-box",{attrs:{html:!0,text:t.empty,theme:"info"}}):e("k-grid",{staticClass:"k-sections",attrs:{gutter:"large"}},t._l(t.tab.columns,(function(s,n){return e("k-column",{key:t.parent+"-column-"+n,attrs:{width:s.width,sticky:s.sticky}},[t._l(s.sections,(function(i,o){return[t.$helper.field.isVisible(i,t.content)?[t.exists(i.type)?e("k-"+i.type+"-section",t._b({key:t.parent+"-column-"+n+"-section-"+o+"-"+t.blueprint,tag:"component",class:"k-section k-section-name-"+i.name,attrs:{column:s.width,lock:t.lock,name:i.name,parent:t.parent,timestamp:t.$view.timestamp},on:{submit:function(e){return t.$emit("submit",e)}}},"component",i,!1)):[e("k-box",{key:t.parent+"-column-"+n+"-section-"+o,attrs:{text:t.$t("error.section.type.invalid",{type:i.type}),theme:"negative"}})]]:t._e()]}))],2)})),1)}),[],!1,null,null,null,null).exports,ii={props:{blueprint:String,lock:[Boolean,Object],help:String,name:String,parent:String,timestamp:Number},methods:{load(){return this.$api.get(this.parent+"/sections/"+this.name)}}};const oi=G({mixins:[ii],inheritAttrs:!1,data:()=>({fields:{},isLoading:!0,issue:null}),computed:{values(){return this.$store.getters["content/values"]()}},watch:{timestamp(){this.fetch()}},created(){this.input=tt(this.input,50),this.fetch()},methods:{input(t,e,s){this.$store.dispatch("content/update",[s,t[s]])},async fetch(){try{const t=await this.load();this.fields=t.fields,Object.keys(this.fields).forEach((t=>{this.fields[t].section=this.name,this.fields[t].endpoints={field:this.parent+"/fields/"+t,section:this.parent+"/sections/"+this.name,model:this.parent}}))}catch(t){this.issue=t}finally{this.isLoading=!1}},onSubmit(t){this.$store.dispatch("content/update",[null,t]),this.$events.$emit("keydown.cmd.s",t)}}},(function(){var t=this,e=t._self._c;return t.isLoading?t._e():e("section",{staticClass:"k-fields-section"},[t.issue?[e("k-headline",{staticClass:"k-fields-issue-headline"},[t._v(" Error ")]),e("k-box",{attrs:{text:t.issue.message,html:!1,theme:"negative"}})]:t._e(),e("k-form",{attrs:{fields:t.fields,validate:!0,value:t.values,disabled:t.lock&&"lock"===t.lock.state},on:{input:t.input,submit:t.onSubmit}})],2)}),[],!1,null,null,null,null).exports;const ri=G({inheritAttrs:!1,props:{blueprint:String,column:String,parent:String,name:String,timestamp:Number},data:()=>({data:[],error:null,isLoading:!1,isProcessing:!1,options:{columns:{},empty:null,headline:null,help:null,layout:"list",link:null,max:null,min:null,size:null,sortable:null},pagination:{page:null},searchterm:null,searching:!1}),computed:{addIcon:()=>"add",buttons(){let t=[];return this.canSearch&&t.push({icon:"filter",text:this.$t("search"),click:this.onSearchToggle,responsive:!0}),this.canAdd&&t.push({icon:this.addIcon,text:this.$t("add"),click:this.onAdd}),t},canAdd:()=>!0,canDrop:()=>!1,canSearch(){return this.options.search},collection(){return{columns:this.options.columns,empty:this.emptyPropsWithSearch,layout:this.options.layout,help:this.options.help,items:this.items,pagination:this.pagination,sortable:!this.isProcessing&&this.options.sortable,size:this.options.size}},emptyProps(){return{icon:"page",text:this.$t("pages.empty")}},emptyPropsWithSearch(){return{...this.emptyProps,text:this.searching?this.$t("search.results.none"):this.options.empty||this.emptyProps.text}},items(){return this.data},isInvalid(){var t;return!((null==(t=this.searchterm)?void 0:t.length)>0)&&(!!(this.options.min&&this.data.lengththis.options.max))},paginationId(){return"kirby$pagination$"+this.parent+"/"+this.name},type:()=>"models"},watch:{searchterm:tt((function(){this.pagination.page=0,this.reload()}),200),timestamp(){this.reload()}},created(){this.load()},methods:{async load(t){t||(this.isLoading=!0),this.isProcessing=!0,null===this.pagination.page&&(this.pagination.page=localStorage.getItem(this.paginationId)||1);try{const t=await this.$api.get(this.parent+"/sections/"+this.name,{page:this.pagination.page,searchterm:this.searchterm});this.options=t.options,this.pagination=t.pagination,this.data=t.data}catch(e){this.error=e.message}finally{this.isProcessing=!1,this.isLoading=!1}},onAction(){},onAdd(){},onChange(){},onDrop(){},onSort(){},onPaginate(t){localStorage.setItem(this.paginationId,t.page),this.pagination=t,this.reload()},onSearchToggle(){this.searching=!this.searching,this.searchterm=null},onUpload(){},async reload(){await this.load(!0)},update(){this.reload(),this.$events.$emit("model.update")}}},(function(){var t=this,e=t._self._c;return!1===t.isLoading?e("section",{class:`k-models-section k-${t.type}-section`,attrs:{"data-processing":t.isProcessing}},[e("header",{staticClass:"k-section-header"},[e("k-headline",{attrs:{link:t.options.link}},[t._v(" "+t._s(t.options.headline||" ")+" "),t.options.min?e("abbr",{attrs:{title:t.$t("section.required")}},[t._v("*")]):t._e()]),e("k-button-group",{attrs:{buttons:t.buttons}})],1),t.error?e("k-box",{attrs:{theme:"negative"}},[e("k-text",{attrs:{size:"small"}},[e("strong",[t._v(" "+t._s(t.$t("error.section.notLoaded",{name:t.name}))+": ")]),t._v(" "+t._s(t.error)+" ")])],1):[e("k-dropzone",{attrs:{disabled:!t.canDrop},on:{drop:t.onDrop}},[t.searching&&t.options.search?e("k-input",{staticClass:"k-models-section-search",attrs:{autofocus:!0,placeholder:t.$t("search")+" …",value:t.searchterm,type:"text"},on:{input:function(e){t.searchterm=e},keydown:function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"esc",27,e.key,["Esc","Escape"])?null:t.onSearchToggle.apply(null,arguments)}}}):t._e(),e("k-collection",t._g(t._b({attrs:{"data-invalid":t.isInvalid},on:{action:t.onAction,change:t.onChange,sort:t.onSort,paginate:t.onPaginate}},"k-collection",t.collection,!1),t.canAdd?{empty:t.onAdd}:{}))],1),e("k-upload",{ref:"upload",on:{success:t.onUpload,error:t.reload}})]],2):t._e()}),[],!1,null,null,null,null).exports;const li=G({extends:ri,computed:{addIcon:()=>"upload",canAdd(){return this.$permissions.files.create&&!1!==this.options.upload},canDrop(){return!1!==this.canAdd},emptyProps(){return{icon:"image",text:this.$t("files.empty")}},items(){return this.data.map((t=>(t.sortable=this.options.sortable,t.column=this.column,t.options=this.$dropdown(t.link,{query:{view:"list",update:this.options.sortable,delete:this.data.length>this.options.min}}),t.data={"data-id":t.id,"data-template":t.template},t)))},type:()=>"files",uploadProps(){return{...this.options.upload,url:this.$urls.api+"/"+this.options.upload.api}}},created(){this.$events.$on("model.update",this.reload),this.$events.$on("file.sort",this.reload)},destroyed(){this.$events.$off("model.update",this.reload),this.$events.$off("file.sort",this.reload)},methods:{onAction(t,e){"replace"===t&&this.replace(e)},onAdd(){this.canAdd&&this.$refs.upload.open(this.uploadProps)},onDrop(t){this.canAdd&&this.$refs.upload.drop(t,this.uploadProps)},async onSort(t){if(!1===this.options.sortable)return!1;this.isProcessing=!0;try{await this.$api.patch(this.options.apiUrl+"/files/sort",{files:t.map((t=>t.id)),index:this.pagination.offset}),this.$store.dispatch("notification/success",":)"),this.$events.$emit("file.sort")}catch(e){this.reload(),this.$store.dispatch("notification/error",e.message)}finally{this.isProcessing=!1}},onUpload(){this.$events.$emit("file.create"),this.$events.$emit("model.update"),this.$store.dispatch("notification/success",":)")},replace(t){this.$refs.upload.open({url:this.$urls.api+"/"+t.link,accept:"."+t.extension+","+t.mime,multiple:!1})}}},null,null,!1,null,null,null,null).exports;const ai=G({mixins:[ii],data:()=>({label:null,text:null,theme:null}),async created(){const t=await this.load();this.label=t.label,this.text=t.text,this.theme=t.theme||"info"}},(function(){var t=this,e=t._self._c;return e("section",{staticClass:"k-info-section"},[e("k-headline",{staticClass:"k-info-section-label"},[t._v(" "+t._s(t.label)+" ")]),e("k-box",{attrs:{theme:t.theme}},[e("k-text",{attrs:{html:t.text}})],1)],1)}),[],!1,null,null,null,null).exports;const ui=G({extends:ri,computed:{canAdd(){return this.options.add&&this.$permissions.pages.create},items(){return this.data.map((t=>{const e=!1!==t.permissions.changeStatus;return t.flag={status:t.status,tooltip:this.$t("page.status"),disabled:!e,click:()=>this.$dialog(t.link+"/changeStatus")},t.sortable=t.permissions.sort&&this.options.sortable,t.deletable=this.data.length>this.options.min,t.column=this.column,t.options=this.$dropdown(t.link,{query:{view:"list",delete:t.deletable,sort:t.sortable}}),t.data={"data-id":t.id,"data-status":t.status,"data-template":t.template},t}))}},created(){this.$events.$on("page.changeStatus",this.reload),this.$events.$on("page.sort",this.reload)},destroyed(){this.$events.$off("page.changeStatus",this.reload),this.$events.$off("page.sort",this.reload)},methods:{onAdd(){this.canAdd&&this.$dialog("pages/create",{query:{parent:this.options.link||this.parent,view:this.parent,section:this.name}})},async onChange(t){let e=null;if(t.added&&(e="added"),t.moved&&(e="moved"),e){this.isProcessing=!0;const n=t[e].element,i=t[e].newIndex+1+this.pagination.offset;try{await this.$api.pages.changeStatus(n.id,"listed",i),this.$store.dispatch("notification/success",":)"),this.$events.$emit("page.sort",n)}catch(s){this.$store.dispatch("notification/error",{message:s.message,details:s.details}),await this.reload()}finally{this.isProcessing=!1}}}}},null,null,!1,null,null,null,null).exports;const ci=G({mixins:[ii],data:()=>({isLoading:!0,headline:null,reports:null,size:null}),async created(){const t=await this.load();this.isLoading=!1,this.headline=t.headline,this.reports=t.reports,this.size=t.size},methods:{}},(function(){var t=this,e=t._self._c;return!1===t.isLoading?e("section",{staticClass:"k-stats-section"},[e("header",{staticClass:"k-section-header"},[e("k-headline",[t._v(" "+t._s(t.headline)+" ")])],1),t.reports.length>0?e("k-stats",{attrs:{reports:t.reports,size:t.size}}):e("k-empty",{attrs:{icon:"chart"}},[t._v(" "+t._s(t.empty||t.$t("stats.empty")))])],1):t._e()}),[],!1,null,null,null,null).exports,di={install(t){t.component("k-sections",ni),t.component("k-fields-section",oi),t.component("k-files-section",li),t.component("k-info-section",ai),t.component("k-pages-section",ui),t.component("k-stats-section",ci)}};const pi=G({props:{blueprint:String,next:Object,prev:Object,permissions:{type:Object,default:()=>({})},lock:{type:[Boolean,Object]},model:{type:Object,default:()=>({})},tab:{type:Object,default:()=>({columns:[]})},tabs:{type:Array,default:()=>[]}},computed:{id(){return this.model.link},isLocked(){var t;return"lock"===(null==(t=this.lock)?void 0:t.state)},protectedFields:()=>[]},watch:{"model.id":{handler(){this.content()},immediate:!0}},created(){this.$events.$on("model.reload",this.reload),this.$events.$on("keydown.left",this.toPrev),this.$events.$on("keydown.right",this.toNext)},destroyed(){this.$events.$off("model.reload",this.reload),this.$events.$off("keydown.left",this.toPrev),this.$events.$off("keydown.right",this.toNext)},methods:{content(){this.$store.dispatch("content/create",{id:this.id,api:this.id,content:this.model.content,ignore:this.protectedFields})},async reload(){await this.$reload(),this.content()},toPrev(t){this.prev&&"body"===t.target.localName&&this.$go(this.prev.link)},toNext(t){this.next&&"body"===t.target.localName&&this.$go(this.next.link)}}},null,null,!1,null,null,null,null).exports;const hi=G({extends:pi,computed:{avatarOptions(){return[{icon:"upload",text:this.$t("change"),click:()=>this.$refs.upload.open()},{icon:"trash",text:this.$t("delete"),click:this.deleteAvatar}]},buttons(){return[{icon:"email",text:`${this.$t("email")}: ${this.model.email}`,disabled:!this.permissions.changeEmail||this.isLocked,click:()=>this.$dialog(this.id+"/changeEmail")},{icon:"bolt",text:`${this.$t("role")}: ${this.model.role}`,disabled:!this.permissions.changeRole||this.isLocked,click:()=>this.$dialog(this.id+"/changeRole")},{icon:"globe",text:`${this.$t("language")}: ${this.model.language}`,disabled:!this.permissions.changeLanguage||this.isLocked,click:()=>this.$dialog(this.id+"/changeLanguage")}]},uploadApi(){return this.$urls.api+"/"+this.id+"/avatar"}},methods:{async deleteAvatar(){await this.$api.users.deleteAvatar(this.model.id),this.avatar=null,this.$store.dispatch("notification/success",":)"),this.$reload()},onAvatar(){this.model.avatar?this.$refs.picture.toggle():this.$refs.upload.open()},uploadedAvatar(){this.$store.dispatch("notification/success",":)"),this.$reload()}}},(function(){var t=this,e=t._self._c;return e("k-inside",{scopedSlots:t._u([{key:"footer",fn:function(){return[e("k-form-buttons",{attrs:{lock:t.lock}})]},proxy:!0}])},[e("div",{staticClass:"k-user-view",attrs:{"data-locked":t.isLocked,"data-id":t.model.id,"data-template":t.blueprint}},[e("div",{staticClass:"k-user-profile"},[e("k-view",[e("k-dropdown",[e("k-button",{staticClass:"k-user-view-image",attrs:{tooltip:t.$t("avatar"),disabled:t.isLocked},on:{click:t.onAvatar}},[t.model.avatar?e("k-image",{attrs:{cover:!0,src:t.model.avatar,ratio:"1/1"}}):e("k-icon",{attrs:{back:"gray-900",color:"gray-200",type:"user"}})],1),t.model.avatar?e("k-dropdown-content",{ref:"picture",attrs:{options:t.avatarOptions}}):t._e()],1),e("k-button-group",{attrs:{buttons:t.buttons}})],1)],1),e("k-view",[e("k-header",{attrs:{editable:t.permissions.changeName&&!t.isLocked,tab:t.tab.name,tabs:t.tabs},on:{edit:function(e){return t.$dialog(t.id+"/changeName")}},scopedSlots:t._u([{key:"left",fn:function(){return[e("k-button-group",[e("k-dropdown",{staticClass:"k-user-view-options"},[e("k-button",{attrs:{disabled:t.isLocked,text:t.$t("settings"),icon:"cog"},on:{click:function(e){return t.$refs.settings.toggle()}}}),e("k-dropdown-content",{ref:"settings",attrs:{options:t.$dropdown(t.id)}})],1),e("k-languages-dropdown")],1)]},proxy:!0},{key:"right",fn:function(){return[t.model.account?t._e():e("k-prev-next",{attrs:{prev:t.prev,next:t.next}})]},proxy:!0}])},[t.model.name&&0!==t.model.name.length?[t._v(" "+t._s(t.model.name)+" ")]:e("span",{staticClass:"k-user-name-placeholder"},[t._v(" "+t._s(t.$t("name"))+" … ")])],2),e("k-sections",{attrs:{blueprint:t.blueprint,empty:t.$t("user.blueprint",{blueprint:t.$esc(t.blueprint)}),lock:t.lock,parent:t.id,tab:t.tab}}),e("k-upload",{ref:"upload",attrs:{url:t.uploadApi,multiple:!1,accept:"image/*"},on:{success:t.uploadedAvatar}})],1)],1)])}),[],!1,null,null,null,null).exports;const mi=G({extends:hi,prevnext:!1},null,null,!1,null,null,null,null).exports;const fi=G({props:{error:String,layout:String}},(function(){var t=this,e=t._self._c;return e(`k-${t.layout}`,{tag:"component"},[e("k-view",{staticClass:"k-error-view"},[e("div",{staticClass:"k-error-view-content"},[e("k-text",[e("p",[e("k-icon",{staticClass:"k-error-view-icon",attrs:{type:"alert"}})],1),t._t("default",(function(){return[e("p",[t._v(" "+t._s(t.error)+" ")])]}))],2)],1)])],1)}),[],!1,null,null,null,null).exports;const gi=G({extends:pi,props:{preview:Object},methods:{action(t){if("replace"===t)this.$refs.upload.open({url:this.$urls.api+"/"+this.id,accept:"."+this.model.extension+","+this.model.mime,multiple:!1})},onUpload(){this.$store.dispatch("notification/success",":)"),this.$reload()}}},(function(){var t=this,e=t._self._c;return e("k-inside",{scopedSlots:t._u([{key:"footer",fn:function(){return[e("k-form-buttons",{attrs:{lock:t.lock}})]},proxy:!0}])},[e("div",{staticClass:"k-file-view",attrs:{"data-locked":t.isLocked,"data-id":t.model.id,"data-template":t.blueprint}},[e("k-file-preview",t._b({},"k-file-preview",t.preview,!1)),e("k-view",{staticClass:"k-file-content"},[e("k-header",{attrs:{editable:t.permissions.changeName&&!t.isLocked,tab:t.tab.name,tabs:t.tabs},on:{edit:function(e){return t.$dialog(t.id+"/changeName")}},scopedSlots:t._u([{key:"left",fn:function(){return[e("k-button-group",[e("k-button",{staticClass:"k-file-view-options",attrs:{link:t.preview.url,responsive:!0,text:t.$t("open"),icon:"open",target:"_blank"}}),e("k-dropdown",{staticClass:"k-file-view-options"},[e("k-button",{attrs:{disabled:t.isLocked,responsive:!0,text:t.$t("settings"),icon:"cog"},on:{click:function(e){return t.$refs.settings.toggle()}}}),e("k-dropdown-content",{ref:"settings",attrs:{options:t.$dropdown(t.id)},on:{action:t.action}})],1),e("k-languages-dropdown")],1)]},proxy:!0},{key:"right",fn:function(){return[e("k-prev-next",{attrs:{prev:t.prev,next:t.next}})]},proxy:!0}])},[t._v(" "+t._s(t.model.filename)+" ")]),e("k-sections",{attrs:{blueprint:t.blueprint,empty:t.$t("file.blueprint",{blueprint:t.$esc(t.blueprint)}),lock:t.lock,parent:t.id,tab:t.tab}}),e("k-upload",{ref:"upload",on:{success:t.onUpload}})],1)],1)])}),[],!1,null,null,null,null).exports;const ki=G({props:{isInstallable:Boolean,isInstalled:Boolean,isOk:Boolean,requirements:Object,translations:Array},data(){return{user:{name:"",email:"",language:this.$translation.code,password:"",role:"admin"}}},computed:{fields(){return{email:{label:this.$t("email"),type:"email",link:!1,autofocus:!0,required:!0},password:{label:this.$t("password"),type:"password",placeholder:this.$t("password")+" …",required:!0},language:{label:this.$t("language"),type:"select",options:this.translations,icon:"globe",empty:!1,required:!0}}},isReady(){return this.isOk&&this.isInstallable},isComplete(){return this.isOk&&this.isInstalled}},methods:{async install(){try{await this.$api.system.install(this.user),await this.$reload({globals:["$system","$translation"]}),this.$store.dispatch("notification/success",this.$t("welcome")+"!")}catch(t){this.$store.dispatch("notification/error",t)}}}},(function(){var t=this,e=t._self._c;return e("k-panel",[e("k-view",{staticClass:"k-installation-view",attrs:{align:"center"}},[t.isComplete?e("k-text",[e("k-headline",[t._v(t._s(t.$t("installation.completed")))]),e("k-link",{attrs:{to:"/login"}},[t._v(" "+t._s(t.$t("login"))+" ")])],1):t.isReady?e("form",{on:{submit:function(e){return e.preventDefault(),t.install.apply(null,arguments)}}},[e("h1",{staticClass:"sr-only"},[t._v(" "+t._s(t.$t("installation"))+" ")]),e("k-fieldset",{attrs:{fields:t.fields,novalidate:!0,value:t.user},on:{input:function(e){t.user=e}}}),e("k-button",{attrs:{text:t.$t("install"),type:"submit",icon:"check"}})],1):e("div",[e("k-headline",[t._v(" "+t._s(t.$t("installation.issues.headline"))+" ")]),e("ul",{staticClass:"k-installation-issues"},[!1===t.isInstallable?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.disabled"))}})],1):t._e(),!1===t.requirements.php?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.issues.php"))}})],1):t._e(),!1===t.requirements.server?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.issues.server"))}})],1):t._e(),!1===t.requirements.mbstring?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.issues.mbstring"))}})],1):t._e(),!1===t.requirements.curl?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.issues.curl"))}})],1):t._e(),!1===t.requirements.accounts?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.issues.accounts"))}})],1):t._e(),!1===t.requirements.content?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.issues.content"))}})],1):t._e(),!1===t.requirements.media?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.issues.media"))}})],1):t._e(),!1===t.requirements.sessions?e("li",[e("k-icon",{attrs:{type:"alert"}}),e("span",{domProps:{innerHTML:t._s(t.$t("installation.issues.sessions"))}})],1):t._e()]),e("k-button",{attrs:{text:t.$t("retry"),icon:"refresh"},on:{click:t.$reload}})],1)],1)],1)}),[],!1,null,null,null,null).exports;const bi=G({props:{languages:{type:Array,default:()=>[]}},computed:{languagesCollection(){return this.languages.map((t=>({...t,image:{back:"black",color:"gray",icon:"globe"},link:()=>{this.$dialog(`languages/${t.id}/update`)},options:[{icon:"edit",text:this.$t("edit"),click(){this.$dialog(`languages/${t.id}/update`)}},{icon:"trash",text:this.$t("delete"),disabled:t.default&&1!==this.languages.length,click(){this.$dialog(`languages/${t.id}/delete`)}}]})))},primaryLanguage(){return this.languagesCollection.filter((t=>t.default))},secondaryLanguages(){return this.languagesCollection.filter((t=>!1===t.default))}}},(function(){var t=this,e=t._self._c;return e("k-inside",[e("k-view",{staticClass:"k-languages-view"},[e("k-header",[t._v(" "+t._s(t.$t("view.languages"))+" "),e("k-button-group",{attrs:{slot:"left"},slot:"left"},[e("k-button",{attrs:{text:t.$t("language.create"),icon:"add"},on:{click:function(e){return t.$dialog("languages/create")}}})],1)],1),e("section",{staticClass:"k-languages"},[t.languages.length>0?[e("section",{staticClass:"k-languages-view-section"},[e("header",{staticClass:"k-languages-view-section-header"},[e("k-headline",[t._v(t._s(t.$t("languages.default")))])],1),e("k-collection",{attrs:{items:t.primaryLanguage}})],1),e("section",{staticClass:"k-languages-view-section"},[e("header",{staticClass:"k-languages-view-section-header"},[e("k-headline",[t._v(t._s(t.$t("languages.secondary")))])],1),t.secondaryLanguages.length?e("k-collection",{attrs:{items:t.secondaryLanguages}}):e("k-empty",{attrs:{icon:"globe"},on:{click:function(e){return t.$dialog("languages/create")}}},[t._v(" "+t._s(t.$t("languages.secondary.empty"))+" ")])],1)]:0===t.languages.length?[e("k-empty",{attrs:{icon:"globe"},on:{click:function(e){return t.$dialog("languages/create")}}},[t._v(" "+t._s(t.$t("languages.empty"))+" ")])]:t._e()],2)],1)],1)}),[],!1,null,null,null,null).exports;const vi=G({components:{"k-login-plugin":window.panel.plugins.login||Lt},props:{methods:Array,pending:Object},data:()=>({issue:""}),computed:{form(){return this.pending.email?"code":"login"},viewClass(){return"code"===this.form?"k-login-code-view":"k-login-view"}},created(){this.$store.dispatch("content/clear")},methods:{async onError(t){null!==t?(!0===t.details.challengeDestroyed&&await this.$reload({globals:["$system"]}),this.issue=t.message):this.issue=null}}},(function(){var t=this,e=t._self._c;return e("k-panel",[e("k-view",{class:t.viewClass,attrs:{align:"center"}},[e("div",[e("h1",{staticClass:"sr-only"},[t._v(" "+t._s(t.$t("login"))+" ")]),t.issue?e("k-login-alert",{on:{click:function(e){t.issue=null}}},[t._v(" "+t._s(t.issue)+" ")]):t._e(),"code"===t.form?e("k-login-code",t._b({on:{error:t.onError}},"k-login-code",t.$props,!1)):e("k-login-plugin",{attrs:{methods:t.methods},on:{error:t.onError}})],1)])],1)}),[],!1,null,null,null,null).exports;const yi=G({extends:pi,props:{status:Object},computed:{protectedFields:()=>["title"]}},(function(){var t=this,e=t._self._c;return e("k-inside",{scopedSlots:t._u([{key:"footer",fn:function(){return[e("k-form-buttons",{attrs:{lock:t.lock}})]},proxy:!0}])},[e("k-view",{staticClass:"k-page-view",attrs:{"data-locked":t.isLocked,"data-id":t.model.id,"data-template":t.blueprint}},[e("k-header",{attrs:{editable:t.permissions.changeTitle&&!t.isLocked,tab:t.tab.name,tabs:t.tabs},on:{edit:function(e){return t.$dialog(t.id+"/changeTitle")}},scopedSlots:t._u([{key:"left",fn:function(){return[e("k-button-group",[t.permissions.preview&&t.model.previewUrl?e("k-button",{staticClass:"k-page-view-preview",attrs:{link:t.model.previewUrl,responsive:!0,text:t.$t("open"),icon:"open",target:"_blank"}}):t._e(),t.status?e("k-status-icon",{attrs:{status:t.model.status,disabled:!t.permissions.changeStatus||t.isLocked,responsive:!0,text:t.status.label},on:{click:function(e){return t.$dialog(t.id+"/changeStatus")}}}):t._e(),e("k-dropdown",{staticClass:"k-page-view-options"},[e("k-button",{attrs:{disabled:!0===t.isLocked,responsive:!0,text:t.$t("settings"),icon:"cog"},on:{click:function(e){return t.$refs.settings.toggle()}}}),e("k-dropdown-content",{ref:"settings",attrs:{options:t.$dropdown(t.id)}})],1),e("k-languages-dropdown")],1)]},proxy:!0},{key:"right",fn:function(){return[t.model.id?e("k-prev-next",{attrs:{prev:t.prev,next:t.next}}):t._e()]},proxy:!0}])},[t._v(" "+t._s(t.model.title)+" ")]),e("k-sections",{attrs:{blueprint:t.blueprint,empty:t.$t("page.blueprint",{blueprint:t.$esc(t.blueprint)}),lock:t.lock,parent:t.id,tab:t.tab}})],1)],1)}),[],!1,null,null,null,null).exports;const $i=G({props:{id:String},computed:{view(){return"k-"+this.id+"-plugin-view"}}},(function(){var t=this._self._c;return t("k-inside",[t(this.view,{tag:"component"})],1)}),[],!1,null,null,null,null).exports;const _i=G({data:()=>({isLoading:!1,issue:"",values:{password:null,passwordConfirmation:null}}),computed:{fields(){return{password:{autofocus:!0,label:this.$t("user.changePassword.new"),icon:"key",type:"password"},passwordConfirmation:{label:this.$t("user.changePassword.new.confirm"),icon:"key",type:"password"}}}},mounted(){this.$store.dispatch("title",this.$t("view.resetPassword"))},methods:{async submit(){if(!this.values.password||this.values.password.length<8)return this.issue=this.$t("error.user.password.invalid"),!1;if(this.values.password!==this.values.passwordConfirmation)return this.issue=this.$t("error.user.password.notSame"),!1;this.isLoading=!0;try{await this.$api.users.changePassword(this.$user.id,this.values.password),this.$store.dispatch("notification/success",":)"),this.$go("/")}catch(t){this.issue=t.message}finally{this.isLoading=!1}}}},(function(){var t=this,e=t._self._c;return e("k-inside",[e("k-view",{staticClass:"k-password-reset-view",attrs:{align:"center"}},[e("k-form",{attrs:{fields:t.fields,"submit-button":t.$t("change"),value:t.values},on:{input:function(e){t.values=e},submit:t.submit},scopedSlots:t._u([{key:"header",fn:function(){return[e("h1",{staticClass:"sr-only"},[t._v(" "+t._s(t.$t("view.resetPassword"))+" ")]),t.issue?e("k-login-alert",{on:{click:function(e){t.issue=null}}},[t._v(" "+t._s(t.issue)+" ")]):t._e(),e("k-user-info",{attrs:{user:t.$user}})]},proxy:!0},{key:"footer",fn:function(){return[e("div",{staticClass:"k-login-buttons"},[e("k-button",{staticClass:"k-login-button",attrs:{icon:"check",type:"submit"}},[t._v(" "+t._s(t.$t("change"))+" "),t.isLoading?[t._v(" … ")]:t._e()],2)],1)]},proxy:!0}])})],1)],1)}),[],!1,null,null,null,null).exports;const xi=G({extends:pi,computed:{protectedFields:()=>["title"]}},(function(){var t=this,e=t._self._c;return e("k-inside",{scopedSlots:t._u([{key:"footer",fn:function(){return[e("k-form-buttons",{attrs:{lock:t.lock}})]},proxy:!0}])},[e("k-view",{staticClass:"k-site-view",attrs:{"data-locked":t.isLocked,"data-id":"/","data-template":"site"}},[e("k-header",{attrs:{editable:t.permissions.changeTitle&&!t.isLocked,tabs:t.tabs,tab:t.tab.name},on:{edit:function(e){return t.$dialog("site/changeTitle")}},scopedSlots:t._u([{key:"left",fn:function(){return[e("k-button-group",[e("k-button",{staticClass:"k-site-view-preview",attrs:{link:t.model.previewUrl,responsive:!0,text:t.$t("open"),icon:"open",target:"_blank"}}),e("k-languages-dropdown")],1)]},proxy:!0}])},[t._v(" "+t._s(t.model.title)+" ")]),e("k-sections",{attrs:{blueprint:t.blueprint,empty:t.$t("site.blueprint"),lock:t.lock,tab:t.tab,parent:"site"},on:{submit:function(e){return t.$emit("submit",e)}}})],1)],1)}),[],!1,null,null,null,null).exports;const wi=G({props:{environment:Array,exceptions:Array,plugins:Array,security:Array,urls:Object},data:()=>({accessible:[]}),computed:{securityIssues(){const t=this.accessible.map((t=>({id:t,text:this.$t("system.issues."+t),link:"https://getkirby.com/security/"+t,icon:"folder"})));return this.security.concat(t).map((t=>({image:{back:"var(--color-red-200)",icon:t.icon||"alert",color:"var(--color-red)"},...t})))}},async created(){this.exceptions.length>0&&(console.info("The following errors occurred during the update check of Kirby and/or plugins:"),this.exceptions.map((t=>console.warn(t))),console.info("End of errors from the update check.")),console.info("Running system health checks for the Panel system view; failed requests in the following console output are expected behavior.");const t=(Promise.allSettled||Promise.all).bind(Promise),e=Object.entries(this.urls).map(this.check);await t(e),console.info(`System health checks ended. ${this.accessible.length} issues with accessible files/folders found (see the security list in the system view).`)},methods:{async check([t,e]){if(!e)return!1;!0===await this.isAccessible(e)&&this.accessible.push(t)},isAccessible:async t=>(await fetch(t,{cache:"no-store"})).status<400,retry(){this.$go(window.location.href)}}},(function(){var t=this,e=t._self._c;return e("k-inside",[e("k-view",{staticClass:"k-system-view"},[e("k-header",[t._v(" "+t._s(t.$t("view.system"))+" ")]),e("section",{staticClass:"k-system-view-section"},[e("header",{staticClass:"k-system-view-section-header"},[e("k-headline",[t._v(t._s(t.$t("environment")))])],1),e("k-stats",{staticClass:"k-system-info",attrs:{reports:t.environment,size:"medium"}})],1),t.securityIssues.length?e("section",{staticClass:"k-system-view-section"},[e("header",{staticClass:"k-system-view-section-header"},[e("k-headline",[t._v(t._s(t.$t("security")))]),e("k-button",{attrs:{tooltip:t.$t("retry"),icon:"refresh"},on:{click:t.retry}})],1),e("k-items",{attrs:{items:t.securityIssues}})],1):t._e(),t.plugins.length?e("section",{staticClass:"k-system-view-section"},[e("header",{staticClass:"k-system-view-section-header"},[e("k-headline",{attrs:{link:"https://getkirby.com/plugins"}},[t._v(" "+t._s(t.$t("plugins"))+" ")])],1),e("k-table",{attrs:{index:!1,columns:{name:{label:t.$t("name"),type:"url",mobile:!0},author:{label:t.$t("author")},license:{label:t.$t("license")},version:{label:t.$t("version"),type:"update-status",mobile:!0,width:"10rem"}},rows:t.plugins}})],1):t._e()],1)],1)}),[],!1,null,null,null,null).exports;const Si=G({props:{role:Object,roles:Array,search:String,title:String,users:Object},computed:{items(){return this.users.data.map((t=>(t.options=this.$dropdown(t.link),t)))}},methods:{paginate(t){this.$reload({query:{page:t.page}})}}},(function(){var t=this,e=t._self._c;return e("k-inside",[e("k-view",{staticClass:"k-users-view"},[e("k-header",{scopedSlots:t._u([{key:"left",fn:function(){return[e("k-button-group",{attrs:{buttons:[{disabled:!1===t.$permissions.users.create,text:t.$t("user.create"),icon:"add",click:()=>t.$dialog("users/create")}]}})]},proxy:!0},t.roles.length>1?{key:"right",fn:function(){return[e("k-button-group",[e("k-dropdown",[e("k-button",{attrs:{responsive:!0,text:`${t.$t("role")}: ${t.role?t.role.title:t.$t("role.all")}`,icon:"funnel"},on:{click:function(e){return t.$refs.roles.toggle()}}}),e("k-dropdown-content",{ref:"roles",attrs:{align:"right"}},[e("k-dropdown-item",{attrs:{icon:"bolt",link:"/users"}},[t._v(" "+t._s(t.$t("role.all"))+" ")]),e("hr"),t._l(t.roles,(function(s){return e("k-dropdown-item",{key:s.id,attrs:{link:"/users/?role="+s.id,icon:"bolt"}},[t._v(" "+t._s(s.title)+" ")])}))],2)],1)],1)]},proxy:!0}:null],null,!0)},[t._v(" "+t._s(t.$t("view.users"))+" ")]),t.users.data.length>0?[e("k-collection",{attrs:{items:t.items,pagination:t.users.pagination},on:{paginate:t.paginate}})]:0===t.users.pagination.total?[e("k-empty",{attrs:{icon:"users"}},[t._v(" "+t._s(t.$t("role.empty"))+" ")])]:t._e()],2)],1)}),[],!1,null,null,null,null).exports,Ci={install(t){t.component("k-account-view",mi),t.component("k-error-view",fi),t.component("k-file-view",gi),t.component("k-installation-view",ki),t.component("k-languages-view",bi),t.component("k-login-view",vi),t.component("k-page-view",yi),t.component("k-plugin-view",$i),t.component("k-reset-password-view",_i),t.component("k-site-view",xi),t.component("k-system-view",wi),t.component("k-users-view",Si),t.component("k-user-view",hi)}};const Oi=G({computed:{placeholder(){return this.field("code",{}).placeholder},languages(){return this.field("language",{options:[]}).options}},methods:{focus(){this.$refs.code.focus()}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-block-type-code-editor"},[e("k-input",{ref:"code",attrs:{buttons:!1,placeholder:t.placeholder,spellcheck:!1,value:t.content.code,type:"textarea"},on:{input:function(e){return t.update({code:e})}}}),t.languages.length?e("div",{staticClass:"k-block-type-code-editor-language"},[e("k-icon",{attrs:{type:"code"}}),e("k-input",{ref:"language",attrs:{empty:!1,options:t.languages,value:t.content.language,type:"select"},on:{input:function(e){return t.update({language:e})}}})],1):t._e()],1)}),[],!1,null,null,null,null).exports,Ai=Object.freeze(Object.defineProperty({__proto__:null,default:Oi},Symbol.toStringTag,{value:"Module"}));const Ti=G({},(function(){var t=this;return(0,t._self._c)("k-block-title",{attrs:{content:t.content,fieldset:t.fieldset},on:{dblclick:function(e){return t.$emit("open")}}})}),[],!1,null,null,null,null).exports,Ii=Object.freeze(Object.defineProperty({__proto__:null,default:Ti},Symbol.toStringTag,{value:"Module"}));const ji=G({computed:{captionMarks(){return this.field("caption",{marks:!0}).marks},crop(){return this.content.crop||!1},ratio(){return this.content.ratio||!1}}},(function(){var t=this,e=t._self._c;return e("figure",[e("ul",{on:{dblclick:t.open}},[0===t.content.images.length?t._l(5,(function(s){return e("li",{key:s,staticClass:"k-block-type-gallery-placeholder"},[e("k-aspect-ratio",{attrs:{ratio:t.ratio}})],1)})):t._l(t.content.images,(function(s){return e("li",{key:s.id},[e("k-aspect-ratio",{attrs:{ratio:t.ratio,cover:t.crop}},[e("img",{attrs:{src:s.url,srcset:s.image.srcset,alt:s.alt}})])],1)}))],2),t.content.caption?e("figcaption",[e("k-writer",{attrs:{inline:!0,marks:t.captionMarks,value:t.content.caption},on:{input:function(e){return t.$emit("update",{caption:e})}}})],1):t._e()])}),[],!1,null,null,null,null).exports,Ei=Object.freeze(Object.defineProperty({__proto__:null,default:ji},Symbol.toStringTag,{value:"Module"}));const Mi=G({computed:{textField(){return this.field("text",{marks:!0})}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-block-type-heading-input",attrs:{"data-level":t.content.level}},[e("k-writer",{ref:"input",attrs:{inline:!0,marks:t.textField.marks,placeholder:t.textField.placeholder,value:t.content.text},on:{input:function(e){return t.update({text:e})}}})],1)}),[],!1,null,null,null,null).exports,Li=Object.freeze(Object.defineProperty({__proto__:null,default:Mi},Symbol.toStringTag,{value:"Module"}));const Bi=G({computed:{captionMarks(){return this.field("caption",{marks:!0}).marks},crop(){return this.content.crop||!1},src(){var t;return"web"===this.content.location?this.content.src:!!(null==(t=this.content.image[0])?void 0:t.url)&&this.content.image[0].url},ratio(){return this.content.ratio||!1}}},(function(){var t=this,e=t._self._c;return e("k-block-figure",{attrs:{caption:t.content.caption,"caption-marks":t.captionMarks,"empty-text":t.$t("field.blocks.image.placeholder")+" …","is-empty":!t.src,"empty-icon":"image"},on:{open:t.open,update:t.update}},[t.src?[t.ratio?e("k-aspect-ratio",{attrs:{ratio:t.ratio,cover:t.crop}},[e("img",{attrs:{alt:t.content.alt,src:t.src}})]):e("img",{staticClass:"k-block-type-image-auto",attrs:{alt:t.content.alt,src:t.src}})]:t._e()],2)}),[],!1,null,null,null,null).exports,Di=Object.freeze(Object.defineProperty({__proto__:null,default:Bi},Symbol.toStringTag,{value:"Module"}));const Pi=G({},(function(){return this._self._c,this._m(0)}),[function(){var t=this._self._c;return t("div",[t("hr")])}],!1,null,null,null,null).exports,Ni=Object.freeze(Object.defineProperty({__proto__:null,default:Pi},Symbol.toStringTag,{value:"Module"}));const Fi=G({computed:{marks(){return this.field("text",{}).marks}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this;return(0,t._self._c)("k-input",{ref:"input",staticClass:"k-block-type-list-input",attrs:{marks:t.marks,value:t.content.text,type:"list"},on:{input:function(e){return t.update({text:e})}}})}),[],!1,null,null,null,null).exports,qi=Object.freeze(Object.defineProperty({__proto__:null,default:Fi},Symbol.toStringTag,{value:"Module"}));const Ri=G({computed:{placeholder(){return this.field("text",{}).placeholder}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this;return(0,t._self._c)("k-input",{ref:"input",staticClass:"k-block-type-markdown-input",attrs:{buttons:!1,placeholder:t.placeholder,spellcheck:!1,value:t.content.text,type:"textarea"},on:{input:function(e){return t.update({text:e})}}})}),[],!1,null,null,null,null).exports,zi=Object.freeze(Object.defineProperty({__proto__:null,default:Ri},Symbol.toStringTag,{value:"Module"}));const Yi=G({computed:{citationField(){return this.field("citation",{})},textField(){return this.field("text",{})}},methods:{focus(){this.$refs.text.focus()}}},(function(){var t,e,s=this,n=s._self._c;return n("div",{staticClass:"k-block-type-quote-editor"},[n("k-writer",{ref:"text",staticClass:"k-block-type-quote-text",attrs:{inline:null!=(t=s.textField.inline)&&t,marks:s.textField.marks,placeholder:s.textField.placeholder,value:s.content.text},on:{input:function(t){return s.update({text:t})}}}),n("k-writer",{ref:"citation",staticClass:"k-block-type-quote-citation",attrs:{inline:null==(e=s.citationField.inline)||e,marks:s.citationField.marks,placeholder:s.citationField.placeholder,value:s.content.citation},on:{input:function(t){return s.update({citation:t})}}})],1)}),[],!1,null,null,null,null).exports,Hi=Object.freeze(Object.defineProperty({__proto__:null,default:Yi},Symbol.toStringTag,{value:"Module"}));const Ui=G({inheritAttrs:!1,computed:{columns(){return this.table.columns||this.fields},fields(){return this.table.fields||{}},rows(){return this.content.rows||[]},table(){let t=null;for(const e of Object.values(this.fieldset.tabs))e.fields.rows&&(t=e.fields.rows);return t||{}}}},(function(){var t=this;return(0,t._self._c)("k-table",{staticClass:"k-block-type-table-preview",attrs:{columns:t.columns,empty:t.$t("field.structure.empty"),rows:t.rows},nativeOn:{dblclick:function(e){return t.open.apply(null,arguments)}}})}),[],!1,null,null,null,null).exports,Ki=Object.freeze(Object.defineProperty({__proto__:null,default:Ui},Symbol.toStringTag,{value:"Module"}));const Vi=G({computed:{component(){const t="k-"+this.textField.type+"-input";return this.$helper.isComponent(t)?t:"k-writer"},textField(){return this.field("text",{})}},methods:{focus(){this.$refs.input.focus()}}},(function(){var t=this;return(0,t._self._c)(t.component,t._b({ref:"input",tag:"component",staticClass:"k-block-type-text-input",attrs:{value:t.content.text},on:{input:function(e){return t.update({text:e})}}},"component",t.textField,!1))}),[],!1,null,null,null,null).exports,Ji=Object.freeze(Object.defineProperty({__proto__:null,default:Vi},Symbol.toStringTag,{value:"Module"}));const Gi=G({computed:{captionMarks(){return this.field("caption",{marks:!0}).marks},video(){return this.$helper.embed.video(this.content.url,!0)}}},(function(){var t=this,e=t._self._c;return e("k-block-figure",{attrs:{caption:t.content.caption,"caption-marks":t.captionMarks,"empty-text":t.$t("field.blocks.video.placeholder")+" …","is-empty":!t.video,"empty-icon":"video"},on:{open:t.open,update:t.update}},[e("k-aspect-ratio",{attrs:{ratio:"16/9"}},[t.video?e("iframe",{attrs:{src:t.video,referrerpolicy:"strict-origin-when-cross-origin"}}):t._e()])],1)}),[],!1,null,null,null,null).exports,Wi=Object.freeze(Object.defineProperty({__proto__:null,default:Gi},Symbol.toStringTag,{value:"Module"}));const Xi=G({inheritAttrs:!1,props:{attrs:[Array,Object],content:[Array,Object],endpoints:Object,fieldset:Object,id:String,isBatched:Boolean,isFull:Boolean,isHidden:Boolean,isLastInBatch:Boolean,isSelected:Boolean,name:String,next:Object,prev:Object,type:String},data:()=>({skipFocus:!1}),computed:{className(){let t=["k-block-type-"+this.type];return this.fieldset.preview!==this.type&&t.push("k-block-type-"+this.fieldset.preview),!1===this.wysiwyg&&t.push("k-block-type-default"),t},customComponent(){return this.wysiwyg?this.wysiwygComponent:"k-block-type-default"},isEditable(){return!1!==this.fieldset.editable},listeners(){return{...this.$listeners,confirmToRemove:this.confirmToRemove,open:this.open}},tabs(){let t=this.fieldset.tabs;return Object.entries(t).forEach((([e,s])=>{Object.entries(s.fields).forEach((([s])=>{t[e].fields[s].section=this.name,t[e].fields[s].endpoints={field:this.endpoints.field+"/fieldsets/"+this.type+"/fields/"+s,section:this.endpoints.section,model:this.endpoints.model}}))})),t},wysiwyg(){return!1!==this.wysiwygComponent},wysiwygComponent(){if(!1===this.fieldset.preview)return!1;let t;return this.fieldset.preview&&(t="k-block-type-"+this.fieldset.preview,this.$helper.isComponent(t))?t:(t="k-block-type-"+this.type,!!this.$helper.isComponent(t)&&t)}},methods:{close(){this.$refs.drawer.close()},confirmToRemove(){this.$refs.removeDialog.open()},focus(){!0!==this.skipFocus&&("function"==typeof this.$refs.editor.focus?this.$refs.editor.focus():this.$refs.container.focus())},onFocusIn(t){var e,s;(null==(s=null==(e=this.$refs.options)?void 0:e.$el)?void 0:s.contains(t.target))||this.$emit("focus",t)},goTo(t){t&&(this.skipFocus=!0,this.close(),this.$nextTick((()=>{t.$refs.container.focus(),t.open(),this.skipFocus=!1})))},open(){var t;null==(t=this.$refs.drawer)||t.open()},remove(){this.$refs.removeDialog.close(),this.$emit("remove",this.id)}}},(function(){var t=this,e=t._self._c;return e("div",{ref:"container",staticClass:"k-block-container",class:"k-block-container-type-"+t.type,attrs:{"data-batched":t.isBatched,"data-disabled":t.fieldset.disabled,"data-hidden":t.isHidden,"data-id":t.id,"data-last-in-batch":t.isLastInBatch,"data-selected":t.isSelected,"data-translate":t.fieldset.translate,tabindex:"0"},on:{keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"down",40,e.key,["Down","ArrowDown"])?null:e.ctrlKey&&e.shiftKey?(e.preventDefault(),t.$emit("sortDown")):null},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"up",38,e.key,["Up","ArrowUp"])?null:e.ctrlKey&&e.shiftKey?(e.preventDefault(),t.$emit("sortUp")):null}],focus:function(e){return t.$emit("focus")},focusin:t.onFocusIn}},[e("div",{staticClass:"k-block",class:t.className},[e(t.customComponent,t._g(t._b({ref:"editor",tag:"component"},"component",t.$props,!1),t.listeners))],1),e("k-block-options",t._g({ref:"options",attrs:{"is-batched":t.isBatched,"is-editable":t.isEditable,"is-full":t.isFull,"is-hidden":t.isHidden}},t.listeners)),t.isEditable&&!t.isBatched?e("k-form-drawer",{ref:"drawer",staticClass:"k-block-drawer",attrs:{id:t.id,icon:t.fieldset.icon||"box",tabs:t.tabs,title:t.fieldset.name,value:t.content},on:{close:function(e){return t.focus()},input:function(e){return t.$emit("update",e)}},scopedSlots:t._u([{key:"options",fn:function(){return[t.isHidden?e("k-button",{staticClass:"k-drawer-option",attrs:{icon:"hidden"},on:{click:function(e){return t.$emit("show")}}}):t._e(),e("k-button",{staticClass:"k-drawer-option",attrs:{disabled:!t.prev,icon:"angle-left"},on:{click:function(e){return e.preventDefault(),e.stopPropagation(),t.goTo(t.prev)}}}),e("k-button",{staticClass:"k-drawer-option",attrs:{disabled:!t.next,icon:"angle-right"},on:{click:function(e){return e.preventDefault(),e.stopPropagation(),t.goTo(t.next)}}}),e("k-button",{staticClass:"k-drawer-option",attrs:{icon:"trash"},on:{click:function(e){return e.preventDefault(),e.stopPropagation(),t.confirmToRemove.apply(null,arguments)}}})]},proxy:!0}],null,!1,2211169536)}):t._e(),e("k-remove-dialog",{ref:"removeDialog",attrs:{text:t.$t("field.blocks.delete.confirm")},on:{submit:t.remove}})],1)}),[],!1,null,null,null,null).exports;const Zi=G({components:{"k-block-pasteboard":G({inheritAttrs:!1,computed:{shortcut(){return this.$helper.keyboard.metaKey()+"+v"}},methods:{close(){this.$refs.dialog.close()},open(){this.$refs.dialog.open()},onPaste(t){this.$emit("paste",t),this.close()}}},(function(){var t=this,e=t._self._c;return e("k-dialog",{ref:"dialog",staticClass:"k-block-importer",attrs:{"cancel-button":!1,"submit-button":!1,size:"large"}},[e("label",{attrs:{for:"pasteboard"},domProps:{innerHTML:t._s(t.$t("field.blocks.fieldsets.paste",{shortcut:t.shortcut}))}}),e("textarea",{attrs:{id:"pasteboard"},on:{paste:function(e){return e.preventDefault(),t.onPaste.apply(null,arguments)}}})])}),[],!1,null,null,null,null).exports},inheritAttrs:!1,props:{autofocus:Boolean,empty:String,endpoints:Object,fieldsets:Object,fieldsetGroups:Object,group:String,max:{type:Number,default:null},value:{type:Array,default:()=>[]}},data(){return{isMultiSelectKey:!1,batch:[],blocks:this.value,current:null,isFocussed:!1}},computed:{draggableOptions(){return{id:this._uid,handle:".k-sort-handle",list:this.blocks,move:this.move,delay:10,data:{fieldsets:this.fieldsets,isFull:this.isFull},options:{group:this.group}}},hasFieldsets(){return Object.keys(this.fieldsets).length},isEditing(){return this.$store.state.dialog||this.$store.state.drawers.open.length>0},isEmpty(){return 0===this.blocks.length},isFull(){return null!==this.max&&this.blocks.length>=this.max},selected(){return this.current},selectedOrBatched(){return this.batch.length>0?this.batch:this.selected?[this.selected]:[]}},watch:{value(){this.blocks=this.value}},created(){this.$events.$on("blur",this.onBlur),this.$events.$on("copy",this.copy),this.$events.$on("focus",this.onOutsideFocus),this.$events.$on("keydown",this.onKey),this.$events.$on("keyup",this.onKey),this.$events.$on("paste",this.onPaste)},destroyed(){this.$events.$off("blur",this.onBlur),this.$events.$off("copy",this.copy),this.$events.$off("focus",this.onOutsideFocus),this.$events.$off("keydown",this.onKey),this.$events.$off("keyup",this.onKey),this.$events.$off("paste",this.onPaste)},mounted(){setTimeout((()=>{!0===this.$props.autofocus&&this.focus()}),100)},methods:{append(t,e){if("string"!=typeof t){if(Array.isArray(t)){let s=this.$helper.clone(t).map((t=>(t.id=this.$helper.uuid(),t)));const n=Object.keys(this.fieldsets);if(s=s.filter((t=>n.includes(t.type))),this.max){const t=this.max-this.blocks.length;s=s.slice(0,t)}this.blocks.splice(e,0,...s),this.save()}}else this.add(t,e)},async add(t="text",e){const s=await this.$api.get(this.endpoints.field+"/fieldsets/"+t);this.blocks.splice(e,0,s),this.save(),this.$nextTick((()=>{this.focusOrOpen(s)}))},addToBatch(t){null!==this.selected&&!1===this.batch.includes(this.selected)&&(this.batch.push(this.selected),this.current=null),!1===this.batch.includes(t.id)&&this.batch.push(t.id)},choose(t){if(1===Object.keys(this.fieldsets).length){const e=Object.values(this.fieldsets)[0].type;this.add(e,t)}else this.$refs.selector.open(t)},chooseToConvert(t){this.$refs.selector.open(t,{disabled:[t.type],headline:this.$t("field.blocks.changeType"),event:"convert"})},click(t){this.$emit("click",t)},confirmToRemoveAll(){this.$refs.removeAll.open()},confirmToRemoveSelected(){this.$refs.removeSelected.open()},copy(t){if(!0===this.isEditing)return!1;if(0===this.blocks.length)return!1;if(0===this.selectedOrBatched.length)return!1;if(!0===this.isInputEvent(t))return!1;let e=[];if(this.blocks.forEach((t=>{this.selectedOrBatched.includes(t.id)&&e.push(t)})),0===e.length)return!1;this.$helper.clipboard.write(e,t),t instanceof ClipboardEvent==!1&&(this.batch=this.selectedOrBatched),this.$store.dispatch("notification/success",`${e.length} copied!`)},copyAll(){this.selectAll(),this.copy(),this.deselectAll()},async convert(t,e){var s;const n=this.findIndex(e.id);if(-1===n)return!1;const i=t=>{var e;let s={};for(const n of Object.values(null!=(e=null==t?void 0:t.tabs)?e:{}))s={...s,...n.fields};return s},o=this.blocks[n],r=await this.$api.get(this.endpoints.field+"/fieldsets/"+t),l=this.fieldsets[o.type],a=this.fieldsets[t];if(!a)return!1;let u=r.content;const c=i(a),d=i(l);for(const[p,h]of Object.entries(c)){const t=d[p];(null==t?void 0:t.type)===h.type&&(null==(s=null==o?void 0:o.content)?void 0:s[p])&&(u[p]=o.content[p])}this.blocks[n]={...r,id:o.id,content:u},this.save()},deselectAll(){this.batch=[],this.current=null},async duplicate(t,e){const s={...this.$helper.clone(t),id:this.$helper.uuid()};this.blocks.splice(e+1,0,s),this.save()},fieldset(t){return this.fieldsets[t.type]||{icon:"box",name:t.type,tabs:{content:{fields:{}}},type:t.type}},find(t){return this.blocks.find((e=>e.id===t))},findIndex(t){return this.blocks.findIndex((e=>e.id===t))},focus(t){var e,s,n,i;null==(i=null==(n=this.$refs["block-"+(null!=(s=null==t?void 0:t.id)?s:null==(e=this.blocks[0])?void 0:e.id)])?void 0:n[0])||i.focus()},focusOrOpen(t){this.fieldsets[t.type].wysiwyg?this.focus(t):this.open(t)},hide(t){e(t,"isHidden",!0),this.save()},isBatched(t){return this.batch.includes(t.id)},isInputEvent(){const t=document.querySelector(":focus");return t&&t.matches("input, textarea, [contenteditable], .k-writer")},isLastInBatch(t){const[e]=this.batch.slice(-1);return e&&t.id===e},isOnlyInstance:()=>1===document.querySelectorAll(".k-blocks").length,isSelected(t){return this.selected&&this.selected===t.id},move(t){if(t.from!==t.to){const e=t.draggedContext.element,s=t.relatedContext.component.componentData||t.relatedContext.component.$parent.componentData;if(!1===Object.keys(s.fieldsets).includes(e.type))return!1;if(!0===s.isFull)return!1}return!0},onBlur(){0===this.batch.length&&(this.isMultiSelectKey=!1)},onKey(t){this.isMultiSelectKey=t.metaKey||t.ctrlKey||t.altKey},onOutsideFocus(t){if("function"==typeof t.target.closest&&t.target.closest(".k-dialog"))return;const e=document.querySelector(".k-overlay:last-of-type");if(!1===this.$el.contains(t.target)&&(!e||!1===e.contains(t.target)))return this.select(null);if(e){const e=this.$el.closest(".k-layout-column");if(!1===(null==e?void 0:e.contains(t.target)))return this.select(null)}},onPaste(t){var e;return!0!==this.isInputEvent(t)&&(!0===this.isEditing?!0===(null==(e=this.$refs.selector)?void 0:e.isOpen())&&this.paste(t):(0!==this.selectedOrBatched.length||!0===this.isOnlyInstance())&&this.paste(t))},open(t){this.$refs["block-"+t.id]&&this.$refs["block-"+t.id][0].open()},async paste(t){const e=this.$helper.clipboard.read(t),s=await this.$api.post(this.endpoints.field+"/paste",{html:e});let n=this.selectedOrBatched[this.selectedOrBatched.length-1],i=this.findIndex(n);-1===i&&(i=this.blocks.length),this.append(s,i+1)},pasteboard(){this.$refs.pasteboard.open()},prevNext(t){if(this.blocks[t]){let e=this.blocks[t];if(this.$refs["block-"+e.id])return this.$refs["block-"+e.id][0]}},remove(t){var e;const s=this.findIndex(t.id);-1!==s&&((null==(e=this.selected)?void 0:e.id)===t.id&&this.select(null),this.$delete(this.blocks,s),this.save())},removeAll(){this.batch=[],this.blocks=[],this.save(),this.$refs.removeAll.close()},removeSelected(){this.batch.forEach((t=>{const e=this.findIndex(t);-1!==e&&this.$delete(this.blocks,e)})),this.deselectAll(),this.save(),this.$refs.removeSelected.close()},save(){this.$emit("input",this.blocks)},select(t,e=null){if(e&&this.isMultiSelectKey&&this.onKey(e),t&&this.isMultiSelectKey)return this.addToBatch(t),void(this.current=null);this.batch=[],this.current=t?t.id:null},selectAll(){this.batch=Object.values(this.blocks).map((t=>t.id))},show(t){e(t,"isHidden",!1),this.save()},sort(t,e,s){if(s<0)return;let n=this.$helper.clone(this.blocks);n.splice(e,1),n.splice(s,0,t),this.blocks=n,this.save(),this.$nextTick((()=>{this.focus(t)}))},update(t,s){const n=this.findIndex(t.id);if(-1!==n)for(const i in s)e(this.blocks[n].content,i,s[i]);this.save()}}},(function(){var t=this,e=t._self._c;return e("div",{ref:"wrapper",staticClass:"k-blocks",attrs:{"data-empty":0===t.blocks.length,"data-multi-select-key":t.isMultiSelectKey},on:{focusin:function(e){t.focussed=!0},focusout:function(e){t.focussed=!1}}},[t.hasFieldsets?[e("k-draggable",t._b({staticClass:"k-blocks-list",on:{sort:t.save},scopedSlots:t._u([{key:"footer",fn:function(){return[e("k-empty",{staticClass:"k-blocks-empty",attrs:{icon:"box"},on:{click:function(e){return t.choose(t.blocks.length)}}},[t._v(" "+t._s(t.empty||t.$t("field.blocks.empty"))+" ")])]},proxy:!0}],null,!1,2413899928)},"k-draggable",t.draggableOptions,!1),t._l(t.blocks,(function(s,n){return e("k-block",t._b({key:s.id,ref:"block-"+s.id,refInFor:!0,attrs:{endpoints:t.endpoints,fieldset:t.fieldset(s),"is-batched":t.isBatched(s),"is-last-in-batch":t.isLastInBatch(s),"is-full":t.isFull,"is-hidden":!0===s.isHidden,"is-selected":t.isSelected(s),next:t.prevNext(n+1),prev:t.prevNext(n-1)},on:{append:function(e){return t.append(e,n+1)},blur:function(e){return t.select(null)},choose:function(e){return t.choose(e)},chooseToAppend:function(e){return t.choose(n+1)},chooseToConvert:function(e){return t.chooseToConvert(s)},chooseToPrepend:function(e){return t.choose(n)},copy:function(e){return t.copy()},confirmToRemoveSelected:t.confirmToRemoveSelected,duplicate:function(e){return t.duplicate(s,n)},focus:function(e){return t.select(s)},hide:function(e){return t.hide(s)},paste:function(e){return t.pasteboard()},prepend:function(e){return t.add(e,n)},remove:function(e){return t.remove(s)},sortDown:function(e){return t.sort(s,n,n+1)},sortUp:function(e){return t.sort(s,n,n-1)},show:function(e){return t.show(s)},update:function(e){return t.update(s,e)}},nativeOn:{click:function(e){return e.stopPropagation(),t.select(s,e)}}},"k-block",s,!1))})),1),e("k-block-selector",{ref:"selector",attrs:{fieldsets:t.fieldsets,"fieldset-groups":t.fieldsetGroups},on:{add:t.add,convert:t.convert,paste:function(e){return t.paste(e)}}}),e("k-remove-dialog",{ref:"removeAll",attrs:{text:t.$t("field.blocks.delete.confirm.all")},on:{submit:t.removeAll}}),e("k-remove-dialog",{ref:"removeSelected",attrs:{text:t.$t("field.blocks.delete.confirm.selected")},on:{submit:t.removeSelected}}),e("k-block-pasteboard",{ref:"pasteboard",on:{paste:function(e){return t.paste(e)}}})]:[e("k-box",{attrs:{theme:"info"}},[t._v(" No fieldsets yet ")])]],2)}),[],!1,null,null,null,null).exports;const Qi=G({inheritAttrs:!1,props:{caption:String,captionMarks:[Boolean,Array],cover:{type:Boolean,default:!0},isEmpty:Boolean,emptyIcon:String,emptyText:String,ratio:String},computed:{ratioPadding(){return this.$helper.ratio(this.ratio||"16/9")}}},(function(){var t=this,e=t._self._c;return e("figure",{staticClass:"k-block-figure"},[t.isEmpty?e("k-button",{staticClass:"k-block-figure-empty",attrs:{icon:t.emptyIcon,text:t.emptyText},on:{click:function(e){return t.$emit("open")}}}):e("span",{staticClass:"k-block-figure-container",on:{dblclick:function(e){return t.$emit("open")}}},[t._t("default")],2),t.caption?e("figcaption",[e("k-writer",{attrs:{inline:!0,marks:t.captionMarks,value:t.caption},on:{input:function(e){return t.$emit("update",{caption:e})}}})],1):t._e()],1)}),[],!1,null,null,null,null).exports;const to=G({props:{isBatched:Boolean,isEditable:Boolean,isFull:Boolean,isHidden:Boolean},methods:{open(){this.$refs.options.open()}}},(function(){var t=this,e=t._self._c;return e("k-dropdown",{staticClass:"k-block-options"},[t.isBatched?[e("k-button",{staticClass:"k-block-options-button",attrs:{tooltip:t.$t("copy"),icon:"template"},on:{click:function(e){return e.preventDefault(),t.$emit("copy")}}}),e("k-button",{staticClass:"k-block-options-button",attrs:{tooltip:t.$t("remove"),icon:"trash"},on:{click:function(e){return e.preventDefault(),t.$emit("confirmToRemoveSelected")}}})]:[t.isEditable?e("k-button",{staticClass:"k-block-options-button",attrs:{tooltip:t.$t("edit"),icon:"edit"},on:{click:function(e){return t.$emit("open")}}}):t._e(),e("k-button",{staticClass:"k-block-options-button",attrs:{disabled:t.isFull,tooltip:t.$t("insert.after"),icon:"add"},on:{click:function(e){return t.$emit("chooseToAppend")}}}),e("k-button",{staticClass:"k-block-options-button",attrs:{tooltip:t.$t("delete"),icon:"trash"},on:{click:function(e){return t.$emit("confirmToRemove")}}}),e("k-button",{staticClass:"k-block-options-button",attrs:{tooltip:t.$t("more"),icon:"dots"},on:{click:function(e){return t.$refs.options.toggle()}}}),e("k-button",{staticClass:"k-block-options-button k-sort-handle",attrs:{tooltip:t.$t("sort"),icon:"sort"},on:{keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"up",38,e.key,["Up","ArrowUp"])?null:(e.preventDefault(),t.$emit("sortUp"))},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"down",40,e.key,["Down","ArrowDown"])?null:(e.preventDefault(),t.$emit("sortDown"))}]}}),e("k-dropdown-content",{ref:"options",attrs:{align:"right"}},[e("k-dropdown-item",{attrs:{disabled:t.isFull,icon:"angle-up"},on:{click:function(e){return t.$emit("chooseToPrepend")}}},[t._v(" "+t._s(t.$t("insert.before"))+" ")]),e("k-dropdown-item",{attrs:{disabled:t.isFull,icon:"angle-down"},on:{click:function(e){return t.$emit("chooseToAppend")}}},[t._v(" "+t._s(t.$t("insert.after"))+" ")]),e("hr"),t.isEditable?e("k-dropdown-item",{attrs:{icon:"edit"},on:{click:function(e){return t.$emit("open")}}},[t._v(" "+t._s(t.$t("edit"))+" ")]):t._e(),e("k-dropdown-item",{attrs:{icon:"refresh"},on:{click:function(e){return t.$emit("chooseToConvert")}}},[t._v(" "+t._s(t.$t("field.blocks.changeType"))+" ")]),e("hr"),e("k-dropdown-item",{attrs:{icon:"template"},on:{click:function(e){return t.$emit("copy")}}},[t._v(" "+t._s(t.$t("copy"))+" ")]),e("k-dropdown-item",{attrs:{icon:"download"},on:{click:function(e){return t.$emit("paste")}}},[t._v(" "+t._s(t.$t("paste.after"))+" ")]),e("hr"),e("k-dropdown-item",{attrs:{icon:t.isHidden?"preview":"hidden"},on:{click:function(e){return t.$emit(t.isHidden?"show":"hide")}}},[t._v(" "+t._s(!0===t.isHidden?t.$t("show"):t.$t("hide"))+" ")]),e("k-dropdown-item",{attrs:{disabled:t.isFull,icon:"copy"},on:{click:function(e){return t.$emit("duplicate")}}},[t._v(" "+t._s(t.$t("duplicate"))+" ")]),e("hr"),e("k-dropdown-item",{attrs:{icon:"trash"},on:{click:function(e){return t.$emit("confirmToRemove")}}},[t._v(" "+t._s(t.$t("delete"))+" ")])],1)]],2)}),[],!1,null,null,null,null).exports;const eo=G({inheritAttrs:!1,props:{endpoint:String,fieldsets:Object,fieldsetGroups:Object},data(){return{dialogIsOpen:!1,disabled:[],headline:null,payload:null,event:"add",groups:this.createGroups()}},computed:{shortcut(){return this.$helper.keyboard.metaKey()+"+v"}},methods:{add(t){this.$emit(this.event,t,this.payload),this.$refs.dialog.close()},close(){this.$refs.dialog.close()},createGroups(){let t={},e=0;const s=this.fieldsetGroups||{blocks:{label:this.$t("field.blocks.fieldsets.label"),sets:Object.keys(this.fieldsets)}};return Object.keys(s).forEach((n=>{let i=s[n];i.open=!1!==i.open,i.fieldsets=i.sets.filter((t=>this.fieldsets[t])).map((t=>(e++,{...this.fieldsets[t],index:e}))),0!==i.fieldsets.length&&(t[n]=i)})),t},isOpen(){return this.dialogIsOpen},navigate(t){var e,s;null==(s=null==(e=this.$refs["fieldset-"+t])?void 0:e[0])||s.focus()},onClose(){this.dialogIsOpen=!1,this.$events.$off("paste",this.close)},onOpen(){this.dialogIsOpen=!0,this.$events.$on("paste",this.close)},open(t,e={}){const s={event:"add",disabled:[],headline:null,...e};this.event=s.event,this.disabled=s.disabled,this.headline=s.headline,this.payload=t,this.$refs.dialog.open()}}},(function(){var t=this,e=t._self._c;return e("k-dialog",{ref:"dialog",staticClass:"k-block-selector",attrs:{"cancel-button":!1,"submit-button":!1,size:"medium"},on:{open:t.onOpen,close:t.onClose}},[t.headline?e("k-headline",[t._v(" "+t._s(t.headline)+" ")]):t._e(),t._l(t.groups,(function(s,n){return e("details",{key:n,attrs:{open:s.open}},[e("summary",[t._v(t._s(s.label))]),e("div",{staticClass:"k-block-types"},t._l(s.fieldsets,(function(s){return e("k-button",{key:s.name,ref:"fieldset-"+s.index,refInFor:!0,attrs:{disabled:t.disabled.includes(s.type),icon:s.icon||"box",text:s.name},on:{keydown:[function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"up",38,e.key,["Up","ArrowUp"])?null:t.navigate(s.index-1)},function(e){return!e.type.indexOf("key")&&t._k(e.keyCode,"down",40,e.key,["Down","ArrowDown"])?null:t.navigate(s.index+1)}],click:function(e){return t.add(s.type)}}})})),1)])})),e("p",{staticClass:"k-clipboard-hint",domProps:{innerHTML:t._s(t.$t("field.blocks.fieldsets.paste",{shortcut:t.shortcut}))}})],2)}),[],!1,null,null,null,null).exports;const so=G({inheritAttrs:!1,props:{fieldset:Object,content:Object},computed:{icon(){return this.fieldset.icon||"box"},label(){if(!this.fieldset.label||0===this.fieldset.label.length)return!1;if(this.fieldset.label===this.fieldset.name)return!1;const t=this.$helper.string.template(this.fieldset.label,this.content);return"…"!==t&&t},name(){return this.fieldset.name}}},(function(){var t=this,e=t._self._c;return e("div",t._g({staticClass:"k-block-title"},t.$listeners),[e("k-icon",{staticClass:"k-block-icon",attrs:{type:t.icon}}),e("span",{staticClass:"k-block-name"},[t._v(" "+t._s(t.name)+" ")]),t.label?e("span",{staticClass:"k-block-label"},[t._v(" "+t._s(t.label)+" ")]):t._e()],1)}),[],!1,null,null,null,null).exports;const no=G({inheritAttrs:!1,props:{content:[Object,Array],fieldset:Object},methods:{field(t,e=null){let s=null;return Object.values(this.fieldset.tabs).forEach((e=>{e.fields[t]&&(s=e.fields[t])})),s||e},open(){this.$emit("open")},update(t){this.$emit("update",{...this.content,...t})}}},null,null,!1,null,null,null,null).exports,io={install(t){t.component("k-block",Xi),t.component("k-blocks",Zi),t.component("k-block-figure",Qi),t.component("k-block-options",to),t.component("k-block-selector",eo),t.component("k-block-title",so),t.component("k-block-type",no);const e=Object.assign({"./Types/Code.vue":Ai,"./Types/Default.vue":Ii,"./Types/Gallery.vue":Ei,"./Types/Heading.vue":Li,"./Types/Image.vue":Di,"./Types/Line.vue":Ni,"./Types/List.vue":qi,"./Types/Markdown.vue":zi,"./Types/Quote.vue":Hi,"./Types/Table.vue":Ki,"./Types/Text.vue":Ji,"./Types/Video.vue":Wi});for(const s in e){const n=s.match(/\/([a-zA-Z]*)\.vue/)[1].toLowerCase();let i=e[s].default;i.extends=no,t.component("k-block-type-"+n,i)}}},oo={inheritAttrs:!1,props:{column:{type:Object,default:()=>({})},field:Object,value:{}}};const ro=G({mixins:[oo],inheritAttrs:!1,props:{value:[Array,String]},computed:{bubbles(){var t,e;let s=this.value;const n=(null==(t=this.column)?void 0:t.options)||(null==(e=this.field)?void 0:e.options)||[];return"string"==typeof s&&(s=s.split(",")),s.map((t=>{"string"==typeof t&&(t={value:t,text:t});for(const e of n)e.value===t.value&&(t.text=e.text);return{back:"light",color:"black",...t}}))}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-bubbles-field-preview",class:t.$options.class},[e("k-bubbles",{attrs:{bubbles:t.bubbles}})],1)}),[],!1,null,null,null,null).exports;const lo=G({extends:ro,inheritAttrs:!1,class:"k-array-field-preview",computed:{bubbles(){return[{text:1===this.value.length?`1 ${this.$t("entry")}`:`${this.value.length} ${this.$t("entries")}`}]}}},null,null,!1,null,null,null,null).exports;const ao=G({mixins:[oo],inheritAttrs:!1,computed:{text(){return this.value}}},(function(){var t=this;return(0,t._self._c)("p",{staticClass:"k-text-field-preview",class:t.$options.class},[t._v(" "+t._s(t.column.before)+" "),t._t("default",(function(){return[t._v(t._s(t.text))]})),t._v(" "+t._s(t.column.after)+" ")],2)}),[],!1,null,null,null,null).exports;const uo=G({extends:ao,inheritAttrs:!1,props:{value:String},class:"k-date-field-preview",computed:{text(){var t,e,s,n,i,o;if("string"!=typeof this.value)return"";const r=this.$library.dayjs(this.value);if(!r)return"";let l=(null==(t=this.column)?void 0:t.display)||(null==(e=this.field)?void 0:e.display)||"YYYY-MM-DD",a=(null==(n=null==(s=this.column)?void 0:s.time)?void 0:n.display)||(null==(o=null==(i=this.field)?void 0:i.time)?void 0:o.display);return a&&(l+=" "+a),r.format(l)}}},null,null,!1,null,null,null,null).exports;const co=G({mixins:[oo],props:{value:[String,Object]},computed:{link(){return"object"==typeof this.value?this.value.href:this.value},text(){return"object"==typeof this.value?this.value.text:this.link}}},(function(){var t=this,e=t._self._c;return e("p",{staticClass:"k-url-field-preview",class:t.$options.class,attrs:{"data-link":t.link}},[t._v(" "+t._s(t.column.before)+" "),e("k-link",{attrs:{to:t.link},nativeOn:{click:function(t){t.stopPropagation()}}},[t._v(" "+t._s(t.text)+" ")]),t._v(" "+t._s(t.column.after)+" ")],1)}),[],!1,null,null,null,null).exports;const po=G({extends:co,class:"k-email-field-preview"},null,null,!1,null,null,null,null).exports;const ho=G({extends:ro,inheritAttrs:!1,class:"k-files-field-preview",computed:{bubbles(){return this.value.map((t=>({text:t.filename,link:t.link,image:t.image})))}}},null,null,!1,null,null,null,null).exports;const mo=G({mixins:[oo],inheritAttrs:!1,props:{value:Object}},(function(){var t=this;return(0,t._self._c)("k-status-icon",t._b({staticClass:"k-flag-field-preview"},"k-status-icon",t.value,!1))}),[],!1,null,null,null,null).exports;const fo=G({mixins:[oo],inheritAttrs:!1,props:{value:String},computed:{html(){return this.value}}},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"k-html-field-preview",class:t.$options.class},[t._v(" "+t._s(t.column.before)+" "),e("div",{domProps:{innerHTML:t._s(t.html)}}),t._v(" "+t._s(t.column.after)+" ")])}),[],!1,null,null,null,null).exports;const go=G({mixins:[oo],inheritAttrs:!1,props:{value:[Object]}},(function(){return(0,this._self._c)("k-item-image",{staticClass:"k-image-field-preview",attrs:{image:this.value,layout:"list"}})}),[],!1,null,null,null,null).exports;const ko=G({extends:ro,inheritAttrs:!1,class:"k-object-field-preview",props:{value:[Array,Object]},computed:{bubbles:()=>[{text:"{ ... }"}]}},null,null,!1,null,null,null,null).exports;const bo=G({extends:ro,inheritAttrs:!1,class:"k-pages-field-preview"},null,null,!1,null,null,null,null).exports;const vo=G({extends:ao,inheritAttrs:!1,props:{value:String},class:"k-time-field-preview",computed:{text(){const t=this.$library.dayjs.iso(this.value,"time");return(null==t?void 0:t.format(this.field.display))||""}}},null,null,!1,null,null,null,null).exports;const yo=G({props:{field:Object,value:Boolean,column:Object},computed:{text(){return!1!==this.column.text?this.field.text:null}}},(function(){var t=this;return(0,t._self._c)("k-input",{staticClass:"k-toggle-field-preview",attrs:{text:t.text,value:t.value,type:"toggle"},on:{input:function(e){return t.$emit("input",e)}}})}),[],!1,null,null,null,null).exports;const $o=G({extends:ro,inheritAttrs:!1,class:"k-users-field-preview",computed:{bubble(){return this.value.map((t=>({text:t.username,link:t.link,image:t.image})))}}},null,null,!1,null,null,null,null).exports,_o={install(t){t.component("k-array-field-preview",lo),t.component("k-bubbles-field-preview",ro),t.component("k-date-field-preview",uo),t.component("k-email-field-preview",po),t.component("k-files-field-preview",ho),t.component("k-flag-field-preview",mo),t.component("k-html-field-preview",fo),t.component("k-image-field-preview",go),t.component("k-object-field-preview",ko),t.component("k-pages-field-preview",bo),t.component("k-text-field-preview",ao),t.component("k-toggle-field-preview",yo),t.component("k-time-field-preview",vo),t.component("k-url-field-preview",co),t.component("k-users-field-preview",$o),t.component("k-list-field-preview",fo),t.component("k-writer-field-preview",fo),t.component("k-checkboxes-field-preview",ro),t.component("k-multiselect-field-preview",ro),t.component("k-radio-field-preview",ro),t.component("k-select-field-preview",ro),t.component("k-tags-field-preview",ro),t.component("k-toggles-field-preview",ro)}},xo={install(t){t.use(ut),t.use(pt),t.use(Ks),t.use(bn),t.use(Dn),t.use(si),t.use(di),t.use(Ci),t.use(io),t.use(_o),t.use(B)}};function wo(t){if(void 0!==t)return JSON.parse(JSON.stringify(t))}function So(t,e){for(const s of Object.keys(e))e[s]instanceof Object&&Object.assign(e[s],So(t[s]||{},e[s]));return Object.assign(t||{},e),t}const Co={clone:wo,isEmpty:function(t){return null==t||""===t||("object"==typeof t&&0===Object.keys(t).length&&t.constructor===Object||void 0!==t.length&&0===t.length)},merge:So},Oo=(t,e)=>{localStorage.setItem("kirby$content$"+t,JSON.stringify(e))},Ao={namespaced:!0,state:{current:null,models:{},status:{enabled:!0}},getters:{exists:t=>e=>Object.prototype.hasOwnProperty.call(t.models,e),hasChanges:(t,e)=>t=>{const s=e.model(t).changes;return Object.keys(s).length>0},isCurrent:t=>e=>t.current===e,id:t=>e=>(e=e||t.current,window.panel.$language?e+"?language="+window.panel.$language.code:e),model:(t,e)=>s=>(s=s||t.current,!0===e.exists(s)?t.models[s]:{api:null,originals:{},values:{},changes:{}}),originals:(t,e)=>t=>wo(e.model(t).originals),values:(t,e)=>t=>({...e.originals(t),...e.changes(t)}),changes:(t,e)=>t=>wo(e.model(t).changes)},mutations:{CLEAR(t){Object.keys(t.models).forEach((e=>{t.models[e].changes={}})),Object.keys(localStorage).forEach((t=>{t.startsWith("kirby$content$")&&localStorage.removeItem(t)}))},CREATE(t,[s,n]){if(!n)return!1;let i=t.models[s]?t.models[s].changes:n.changes;e(t.models,s,{api:n.api,originals:n.originals,changes:i||{}})},CURRENT(t,e){t.current=e},MOVE(t,[s,n]){const i=wo(t.models[s]);D(t.models,s),e(t.models,n,i);const o=localStorage.getItem("kirby$content$"+s);localStorage.removeItem("kirby$content$"+s),localStorage.setItem("kirby$content$"+n,o)},REMOVE(t,e){D(t.models,e),localStorage.removeItem("kirby$content$"+e)},REVERT(t,s){t.models[s]&&(e(t.models[s],"changes",{}),localStorage.removeItem("kirby$content$"+s))},STATUS(t,s){e(t.status,"enabled",s)},UPDATE(t,[s,n,i]){if(!t.models[s])return!1;void 0===i&&(i=null),i=wo(i);const o=JSON.stringify(i);JSON.stringify(t.models[s].originals[n])==o?D(t.models[s].changes,n):e(t.models[s].changes,n,i),Oo(s,{api:t.models[s].api,originals:t.models[s].originals,changes:t.models[s].changes})}},actions:{init(t){Object.keys(localStorage).filter((t=>t.startsWith("kirby$content$"))).map((t=>t.split("kirby$content$")[1])).forEach((e=>{const s=localStorage.getItem("kirby$content$"+e);t.commit("CREATE",[e,JSON.parse(s)])})),Object.keys(localStorage).filter((t=>t.startsWith("kirby$form$"))).map((t=>t.split("kirby$form$")[1])).forEach((e=>{const s=localStorage.getItem("kirby$form$"+e);let n=null;try{n=JSON.parse(s)}catch(o){}if(!n||!n.api)return localStorage.removeItem("kirby$form$"+e),!1;const i={api:n.api,originals:n.originals,changes:n.values};t.commit("CREATE",[e,i]),Oo(e,i),localStorage.removeItem("kirby$form$"+e)}))},clear(t){t.commit("CLEAR")},create(t,e){const s=wo(e.content);Array.isArray(e.ignore)&&e.ignore.forEach((t=>delete s[t])),e.id=t.getters.id(e.id);const n={api:e.api,originals:s,changes:{}};t.commit("CREATE",[e.id,n]),t.dispatch("current",e.id)},current(t,e){t.commit("CURRENT",e)},disable(t){t.commit("STATUS",!1)},enable(t){t.commit("STATUS",!0)},move(t,[e,s]){e=t.getters.id(e),s=t.getters.id(s),t.commit("MOVE",[e,s])},remove(t,e){t.commit("REMOVE",e),t.getters.isCurrent(e)&&t.commit("CURRENT",null)},revert(t,e){e=e||t.state.current,t.commit("REVERT",e)},async save(e,s){if(s=s||e.state.current,e.getters.isCurrent(s)&&!1===e.state.status.enabled)return!1;e.dispatch("disable");const n=e.getters.model(s),i={...n.originals,...n.changes};try{await t.$api.patch(n.api,i),e.commit("CREATE",[s,{...n,originals:i}]),e.dispatch("revert",s)}finally{e.dispatch("enable")}},update(t,[e,s,n]){if(n=n||t.state.current,null===e)for(const i in s)t.commit("UPDATE",[n,i,s[i]]);else t.commit("UPDATE",[n,e,s])}}},To={namespaced:!0,state:{open:[]},mutations:{CLOSE(t,e){t.open=e?t.open.filter((t=>t.id!==e)):[]},GOTO(t,e){t.open=t.open.slice(0,t.open.findIndex((t=>t.id===e))+1)},OPEN(t,e){t.open.push(e)}},actions:{close(t,e){t.commit("CLOSE",e)},goto(t,e){t.commit("GOTO",e)},open(t,e){t.commit("OPEN",e)}}},Io={timer:null,namespaced:!0,state:{type:null,message:null,details:null,timeout:null},mutations:{SET(t,e){t.type=e.type,t.message=e.message,t.details=e.details,t.timeout=e.timeout},UNSET(t){t.type=null,t.message=null,t.details=null,t.timeout=null}},actions:{close(t){clearTimeout(this.timer),t.commit("UNSET")},deprecated(t,e){console.warn("Deprecated: "+e)},error(t,e){let s=e;"string"==typeof e&&(s={message:e}),e instanceof Error&&(s={message:e.message},window.panel.$config.debug&&window.console.error(e)),t.dispatch("dialog",{component:"k-error-dialog",props:s},{root:!0}),t.dispatch("close")},open(t,e){t.dispatch("close"),t.commit("SET",e),e.timeout&&(this.timer=setTimeout((()=>{t.dispatch("close")}),e.timeout))},success(t,e){"string"==typeof e&&(e={message:e}),t.dispatch("open",{type:"success",timeout:4e3,...e})}}};t.use(P);const jo=new P.Store({strict:!1,state:{dialog:null,drag:null,fatal:!1,isLoading:!1},mutations:{SET_DIALOG(t,e){t.dialog=e},SET_DRAG(t,e){t.drag=e},SET_FATAL(t,e){t.fatal=e},SET_LOADING(t,e){t.isLoading=e}},actions:{dialog(t,e){t.commit("SET_DIALOG",e)},drag(t,e){t.commit("SET_DRAG",e)},fatal(t,e){!1!==e?(console.error("The JSON response could not be parsed"),window.panel.$config.debug&&console.info(e.html),e.silent||t.commit("SET_FATAL",e.html)):t.commit("SET_FATAL",!1)},isLoading(t,e){t.commit("SET_LOADING",!0===e)},navigate(t){t.dispatch("dialog",null),t.dispatch("drawers/close")}},modules:{content:Ao,drawers:To,notification:Io}}),Eo={install(t){window.panel=window.panel||{},window.onunhandledrejection=t=>{t.preventDefault(),jo.dispatch("notification/error",t.reason)},window.panel.deprecated=t=>{jo.dispatch("notification/deprecated",t)},window.panel.error=t.config.errorHandler=t=>{jo.dispatch("notification/error",t)}}},Mo={install(t){const e=N(),s={$on:e.on,$off:e.off,$emit:e.emit,blur(t){s.$emit("blur",t)},click(t){s.$emit("click",t)},copy(t){s.$emit("copy",t)},dragenter(t){s.entered=t.target,s.prevent(t),s.$emit("dragenter",t)},dragleave(t){s.prevent(t),s.entered===t.target&&s.$emit("dragleave",t)},drop(t){s.prevent(t),s.$emit("drop",t)},entered:null,focus(t){s.$emit("focus",t)},keydown(e){let n=["keydown"];(e.metaKey||e.ctrlKey)&&n.push("cmd"),!0===e.altKey&&n.push("alt"),!0===e.shiftKey&&n.push("shift");let i=t.prototype.$helper.string.lcfirst(e.key);const o={escape:"esc",arrowUp:"up",arrowDown:"down",arrowLeft:"left",arrowRight:"right"};o[i]&&(i=o[i]),!1===["alt","control","shift","meta"].includes(i)&&n.push(i),s.$emit(n.join("."),e),s.$emit("keydown",e)},keyup(t){s.$emit("keyup",t)},online(t){s.$emit("online",t)},offline(t){s.$emit("offline",t)},paste(t){s.$emit("paste",t)},prevent(t){t.stopPropagation(),t.preventDefault()}};document.addEventListener("click",s.click,!1),document.addEventListener("copy",s.copy,!0),document.addEventListener("focus",s.focus,!0),document.addEventListener("paste",s.paste,!0),window.addEventListener("blur",s.blur,!1),window.addEventListener("dragenter",s.dragenter,!1),window.addEventListener("dragexit",s.prevent,!1),window.addEventListener("dragleave",s.dragleave,!1),window.addEventListener("drop",s.drop,!1),window.addEventListener("dragover",s.prevent,!1),window.addEventListener("keydown",s.keydown,!1),window.addEventListener("keyup",s.keyup,!1),window.addEventListener("offline",s.offline),window.addEventListener("online",s.online),t.prototype.$events=s}};class Lo{constructor(t={}){this.options={base:"/",headers:()=>({}),onFatal:()=>{},onFinish:()=>{},onPushState:()=>{},onReplaceState:()=>{},onStart:()=>{},onSwap:()=>{},query:()=>({}),...t},this.state={}}init(t={},e={}){this.options={...this.options,...e},this.setState(t)}arrayToString(t){return!1===Array.isArray(t)?String(t):t.join(",")}body(t){return"object"==typeof t?JSON.stringify(t):t}async fetch(t,e){return fetch(t,e)}async go(t,e){try{const s=await this.request(t,e);return!1!==s&&this.setState(s,e)}catch(s){if(!0!==(null==e?void 0:e.silent))throw s}}query(t={},e={}){let s=new URLSearchParams(e);return"object"!=typeof t&&(t={}),Object.entries(t).forEach((([t,e])=>{null!==e&&s.set(t,e)})),Object.entries(this.options.query()).forEach((([t,e])=>{var n,i;null!==(e=null!=(i=null!=(n=s.get(t))?n:e)?i:null)&&s.set(t,e)})),s}redirect(t){window.location.href=t}reload(t={}){return this.go(window.location.href,{...t,replace:!0})}async request(t="",e={}){var s;const n=!!(e={globals:!1,method:"GET",only:[],query:{},silent:!1,type:"$view",...e}).globals&&this.arrayToString(e.globals),i=this.arrayToString(e.only);this.options.onStart(e);try{const r=this.url(t,e.query);if(new URL(r).origin!==location.origin)return this.redirect(r),!1;const l=await this.fetch(r,{method:e.method,body:this.body(e.body),credentials:"same-origin",cache:"no-store",headers:{...this.options.headers(),"X-Fiber":!0,"X-Fiber-Globals":n,"X-Fiber-Only":i,"X-Fiber-Referrer":(null==(s=this.state.$view)?void 0:s.path)||null,...e.headers}});if(!1===l.headers.has("X-Fiber"))return this.redirect(l.url),!1;const a=await l.text();let u;try{u=JSON.parse(a)}catch(o){return this.options.onFatal({url:r,path:t,options:e,response:l,text:a}),!1}if(!u[e.type])throw Error(`The ${e.type} could not be loaded`);const c=u[e.type];if(c.error)throw Error(c.error);return"$view"===e.type?i.length?So(this.state,u):u:c}finally{this.options.onFinish(e)}}async setState(t,e={}){return"object"==typeof t&&(this.state=wo(t),!0===e.replace||this.url(this.state.$url).href===window.location.href?this.options.onReplaceState(this.state,e):this.options.onPushState(this.state,e),this.options.onSwap(this.state,e),this.state)}url(t="",e={}){return(t="string"==typeof t&&null===t.match(/^https?:\/\//)?new URL(this.options.base+t.replace(/^\//,"")):new URL(t)).search=this.query(e,t.search),t}}const Bo=async function(t){return{cancel:null,submit:null,props:{},...t}},Do=async function(t,e={}){let s=null,n=null;"function"==typeof e?(s=e,e={}):(s=e.submit,n=e.cancel);let i=await this.$fiber.request("dialogs/"+t,{...e,type:"$dialog"});return"object"==typeof i&&(i.submit=s||null,i.cancel=n||null,i)};async function Po(t,e={}){let s=null;if(s="object"==typeof t?await Bo.call(this,t):await Do.call(this,t,e),!s)return!1;if(!s.component||!1===this.$helper.isComponent(s.component))throw Error("The dialog component does not exist");return s.props=s.props||{},this.$store.dispatch("dialog",s),s}function No(t,e={}){return async s=>{const n=await this.$fiber.request("dropdowns/"+t,{...e,type:"$dropdown"});if(!n)return!1;if(!1===Array.isArray(n.options)||0===n.options.length)throw Error("The dropdown is empty");n.options.map((t=>(t.dialog&&(t.click=()=>{const e="string"==typeof t.dialog?t.dialog:t.dialog.url,s="object"==typeof t.dialog?t.dialog:{};return this.$dialog(e,s)}),t))),s(n.options)}}async function Fo(t,e,s={}){return await this.$fiber.request("search/"+t,{query:{query:e},type:"$search",...s})}const qo={install(t){const e=new Lo;t.prototype.$fiber=window.panel.$fiber=e,t.prototype.$dialog=window.panel.$dialog=Po,t.prototype.$dropdown=window.panel.$dropdown=No,t.prototype.$go=window.panel.$go=e.go.bind(e),t.prototype.$reload=window.panel.$reload=e.reload.bind(e),t.prototype.$request=window.panel.$request=e.request.bind(e),t.prototype.$search=window.panel.$search=Fo,t.prototype.$url=window.panel.$url=e.url.bind(e)}};const Ro={read:function(t){if(!t)return null;if("string"==typeof t)return t;if(t instanceof ClipboardEvent){t.preventDefault();const e=t.clipboardData.getData("text/html")||t.clipboardData.getData("text/plain")||null;if(e)return e.replace(/\u00a0/g," ")}return null},write:function(t,e){if("string"!=typeof t&&(t=JSON.stringify(t,null,2)),e&&e instanceof ClipboardEvent)return e.preventDefault(),e.clipboardData.setData("text/plain",t),!0;const s=document.createElement("textarea");if(s.value=t,document.body.append(s),navigator.userAgent.match(/ipad|ipod|iphone/i)){s.contentEditable=!0,s.readOnly=!0;const t=document.createRange();t.selectNodeContents(s);const e=window.getSelection();e.removeAllRanges(),e.addRange(t),s.setSelectionRange(0,999999)}else s.select();return document.execCommand("copy"),s.remove(),!0}};function zo(t){if("string"==typeof t){if("pattern"===(t=t.toLowerCase()))return"var(--color-gray-800) var(--bg-pattern)";if(!1===t.startsWith("#")&&!1===t.startsWith("var(")){const e="--color-"+t;if(window.getComputedStyle(document.documentElement).getPropertyValue(e))return`var(${e})`}return t}}function Yo(t,e=!1){if(!t.match("youtu"))return!1;let s=null;try{s=new URL(t)}catch(d){return!1}const n=s.pathname.split("/").filter((t=>""!==t)),i=n[0],o=n[1],r="https://"+(!0===e?"www.youtube-nocookie.com":s.host)+"/embed",l=t=>!!t&&null!==t.match(/^[a-zA-Z0-9_-]+$/);let a=s.searchParams,u=null;switch(n.join("/")){case"embed/videoseries":case"playlist":l(a.get("list"))&&(u=r+"/videoseries");break;case"watch":l(a.get("v"))&&(u=r+"/"+a.get("v"),a.has("t")&&a.set("start",a.get("t")),a.delete("v"),a.delete("t"));break;default:s.host.includes("youtu.be")&&l(i)?(u="https://www.youtube.com/embed/"+i,a.has("t")&&a.set("start",a.get("t")),a.delete("t")):"embed"===i&&l(o)&&(u=r+"/"+o)}if(!u)return!1;const c=a.toString();return c.length&&(u+="?"+c),u}function Ho(t,e=!1){let s=null;try{s=new URL(t)}catch(a){return!1}const n=s.pathname.split("/").filter((t=>""!==t));let i=s.searchParams,o=null;switch(!0===e&&i.append("dnt",1),s.host){case"vimeo.com":case"www.vimeo.com":o=n[0];break;case"player.vimeo.com":o=n[1]}if(!o||!o.match(/^[0-9]*$/))return!1;let r="https://player.vimeo.com/video/"+o;const l=i.toString();return l.length&&(r+="?"+l),r}const Uo={youtube:Yo,vimeo:Ho,video:function(t,e=!1){return t.includes("youtu")?Yo(t,e):!!t.includes("vimeo")&&Ho(t,e)}};const Ko={isVisible:function(t,e){if("hidden"===t.type)return!1;if(!t.when)return!0;let s=!0;return Object.keys(t.when).forEach((n=>{e[n.toLowerCase()]!==t.when[n]&&(s=!1)})),s},subfields:function(t,e){let s={};return Object.keys(e).forEach((n=>{let i=e[n];i.section=t.name,i.endpoints={field:t.endpoints.field+"+"+n,section:t.endpoints.section,model:t.endpoints.model},s[n]=i})),s}},Vo=e=>void 0!==t.options.components[e],Jo=t=>!!t.dataTransfer&&(!!t.dataTransfer.types&&(!0===t.dataTransfer.types.includes("Files")&&!1===t.dataTransfer.types.includes("text/plain")));const Go={metaKey:function(){return window.navigator.userAgent.indexOf("Mac")>-1?"cmd":"ctrl"}},Wo=(t="3/2",e="100%",s=!0)=>{const n=String(t).split("/");if(2!==n.length)return e;const i=Number(n[0]),o=Number(n[1]);let r=100;return 0!==i&&0!==o&&(r=s?r/i*o:r/o*i,r=parseFloat(String(r)).toFixed(2)),r+"%"},Xo=t=>{var e=(t=t||{}).desc?-1:1,s=-e,n=/^0/,i=/\s+/g,o=/^\s+|\s+$/g,r=/[^\x00-\x80]/,l=/^0x[0-9a-f]+$/i,a=/(0x[\da-fA-F]+|(^[\+\-]?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?(?=\D|\s|$))|\d+)/g,u=/(^([\w ]+,?[\w ]+)?[\w ]+,?[\w ]+\d+:\d+(:\d+)?[\w ]?|^\d{1,4}[\/\-]\d{1,4}[\/\-]\d{1,4}|^\w+, \w+ \d+, \d{4})/,c=t.insensitive?function(t){return function(t){if(t.toLocaleLowerCase)return t.toLocaleLowerCase();return t.toLowerCase()}(""+t).replace(o,"")}:function(t){return(""+t).replace(o,"")};function d(t){return t.replace(a,"\0$1\0").replace(/\0$/,"").replace(/^\0/,"").split("\0")}function p(t,e){return(!t.match(n)||1===e)&&parseFloat(t)||t.replace(i," ").replace(o,"")||0}return function(t,n){var i=c(t),o=c(n);if(!i&&!o)return 0;if(!i&&o)return s;if(i&&!o)return e;var a=d(i),h=d(o),m=parseInt(i.match(l),16)||1!==a.length&&Date.parse(i),f=parseInt(o.match(l),16)||m&&o.match(u)&&Date.parse(o)||null;if(f){if(mf)return e}for(var g=a.length,k=h.length,b=0,v=Math.max(g,k);b0)return e;if(_<0)return s;if(b===v-1)return 0}else{if(y<$)return s;if(y>$)return e}}return 0}};RegExp.escape=function(t){return t.replace(new RegExp("[-/\\\\^$*+?.()[\\]{}]","gu"),"\\$&")};const Zo={"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="};function Qo(t){return String(t).replace(/[&<>"'`=/]/g,(t=>Zo[t]))}function tr(t,e={}){const s=(t,e={})=>{var n;const i=Qo(t.shift()),o=null!=(n=e[i])?n:null;return null===o?Object.prototype.hasOwnProperty.call(e,i)||"…":0===t.length?o:s(t,o)},n="[{]{1,2}[\\s]?",i="[\\s]?[}]{1,2}";return(t=t.replace(new RegExp(`${n}(.*?)${i}`,"gi"),((t,n)=>s(n.split("."),e)))).replace(new RegExp(`${n}.*${i}`,"gi"),"…")}function er(t){const e=String(t);return e.charAt(0).toUpperCase()+e.slice(1)}const sr={camelToKebab:function(t){return t.replace(/([a-z0-9])([A-Z])/g,"$1-$2").toLowerCase()},escapeHTML:Qo,hasEmoji:function(t){if("string"!=typeof t)return!1;const e=t.match(/(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|[\ud83c\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|[\ud83c\ude32-\ude3a]|[\ud83c\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/i);return null!==e&&null!==e.length},lcfirst:function(t){const e=String(t);return e.charAt(0).toLowerCase()+e.slice(1)},pad:function(t,e=2){t=String(t);let s="";for(;s.length]+)>)/gi,"")},template:tr,ucfirst:er,ucwords:function(t){return String(t).split(/ /g).map((t=>er(t))).join(" ")},unescapeHTML:function(t){for(const e in Zo)t=String(t).replaceAll(Zo[e],e);return t},uuid:function(){let t,e,s="";for(t=0;t<32;t++)e=16*Math.random()|0,8!=t&&12!=t&&16!=t&&20!=t||(s+="-"),s+=(12==t?4:16==t?3&e|8:e).toString(16);return s}},nr=(t,e)=>{const s=Object.assign({url:"/",field:"file",method:"POST",attributes:{},complete:function(){},error:function(){},success:function(){},progress:function(){}},e),n=new FormData;n.append(s.field,t,t.name),s.attributes&&Object.keys(s.attributes).forEach((t=>{n.append(t,s.attributes[t])}));const i=new XMLHttpRequest,o=e=>{if(!e.lengthComputable||!s.progress)return;let n=Math.max(0,Math.min(100,e.loaded/e.total*100));s.progress(i,t,Math.ceil(n))};i.upload.addEventListener("loadstart",o),i.upload.addEventListener("progress",o),i.addEventListener("load",(e=>{let n=null;try{n=JSON.parse(e.target.response)}catch(o){n={status:"error",message:"The file could not be uploaded"}}"error"===n.status?s.error(i,t,n):(s.success(i,t,n),s.progress(i,t,100))})),i.addEventListener("error",(e=>{const n=JSON.parse(e.target.response);s.error(i,t,n),s.progress(i,t,100)})),i.open(s.method,s.url,!0),s.headers&&Object.keys(s.headers).forEach((t=>{const e=s.headers[t];i.setRequestHeader(t,e)})),i.send(n)},ir={install(t){Array.prototype.sortBy=function(e){const s=t.prototype.$helper.sort(),n=e.split(" "),i=n[0],o=n[1]||"asc";return this.sort(((t,e)=>{const n=String(t[i]).toLowerCase(),r=String(e[i]).toLowerCase();return"desc"===o?s(r,n):s(n,r)}))},t.prototype.$helper={clipboard:Ro,clone:Co.clone,color:zo,embed:Uo,isComponent:Vo,isUploadEvent:Jo,debounce:tt,field:Ko,keyboard:Go,object:Co,pad:sr.pad,ratio:Wo,slug:sr.slug,sort:Xo,string:sr,upload:nr,uuid:sr.uuid},t.prototype.$esc=sr.escapeHTML}},or={install(t){t.$t=t.prototype.$t=window.panel.$t=(t,e,s=null)=>{if("string"!=typeof t)return;const n=window.panel.$translation.data[t]||s;return"string"!=typeof n?n:tr(n,e)},t.directive("direction",{inserted(t,e,s){!0!==s.context.disabled?t.dir=s.context.$direction:t.dir=null}})}};F.extend(q),F.extend(((t,e,s)=>{s.interpret=(t,e="date")=>{const n={date:{"YYYY-MM-DD":!0,"YYYY-MM-D":!0,"YYYY-MM-":!0,"YYYY-MM":!0,"YYYY-M-DD":!0,"YYYY-M-D":!0,"YYYY-M-":!0,"YYYY-M":!0,"YYYY-":!0,YYYYMMDD:!0,"MMM DD YYYY":!1,"MMM D YYYY":!1,"MMM DD YY":!1,"MMM D YY":!1,"MMM DD":!1,"MMM D":!1,"DD MMMM YYYY":!1,"DD MMMM YY":!1,"DD MMMM":!1,"D MMMM YYYY":!1,"D MMMM YY":!1,"D MMMM":!1,"DD MMM YYYY":!1,"D MMM YYYY":!1,"DD MMM YY":!1,"D MMM YY":!1,"DD MMM":!1,"D MMM":!1,"DD MM YYYY":!1,"DD M YYYY":!1,"D MM YYYY":!1,"D M YYYY":!1,"DD MM YY":!1,"D MM YY":!1,"DD M YY":!1,"D M YY":!1,YYYY:!0,MMMM:!0,MMM:!0,"DD MM":!1,"DD M":!1,"D MM":!1,"D M":!1,DD:!1,D:!1},time:{"HH:mm:ss a":!1,"HH:mm:ss":!1,"HH:mm a":!1,"HH:mm":!1,"HH a":!1,HH:!1}};if("string"==typeof t&&""!==t)for(const i in n[e]){const o=s(t,i,n[e][i]);if(!0===o.isValid())return o}return null}})),F.extend(((t,e,s)=>{const n=t=>"date"===t?"YYYY-MM-DD":"time"===t?"HH:mm:ss":"YYYY-MM-DD HH:mm:ss";e.prototype.toISO=function(t="datetime"){return this.format(n(t))},s.iso=function(t,e="datetime"){const i=s(t,n(e));return i&&i.isValid()?i:null}})),F.extend(((t,e)=>{e.prototype.merge=function(t,e="date"){let s=this.clone();if(!t||!t.isValid())return this;if("string"==typeof e){const t={date:["year","month","date"],time:["hour","minute","second"]};if(!1===Object.prototype.hasOwnProperty.call(t,e))throw new Error("Invalid merge unit alias");e=t[e]}for(const n of e)s=s.set(n,t.get(n));return s}})),F.extend(((t,e,s)=>{s.pattern=t=>new class{constructor(t,e){this.dayjs=t,this.pattern=e;const s={year:["YY","YYYY"],month:["M","MM","MMM","MMMM"],day:["D","DD"],hour:["h","hh","H","HH"],minute:["m","mm"],second:["s","ss"],meridiem:["a"]};this.parts=this.pattern.split(/\W/).map(((t,e)=>{const n=this.pattern.indexOf(t);return{index:e,unit:Object.keys(s)[Object.values(s).findIndex((e=>e.includes(t)))],start:n,end:n+(t.length-1)}}))}at(t,e=t){const s=this.parts.filter((s=>s.start<=t&&s.end>=e-1));return s[0]?s[0]:this.parts.filter((e=>e.start<=t)).pop()}format(t){return t&&t.isValid()?t.format(this.pattern):null}}(s,t)})),F.extend(((t,e)=>{e.prototype.round=function(t="date",e=1){const s=["second","minute","hour","date","month","year"];if("day"===t&&(t="date"),!1===s.includes(t))throw new Error("Invalid rounding unit");if(["date","month","year"].includes(t)&&1!==e||"hour"===t&&24%e!=0||["second","minute"].includes(t)&&60%e!=0)throw"Invalid rounding size for "+t;let n=this.clone();const i=s.indexOf(t),o=s.slice(0,i),r=o.pop();if(o.forEach((t=>n=n.startOf(t))),r){const e={month:12,date:n.daysInMonth(),hour:24,minute:60,second:60}[r];Math.round(n.get(r)/e)*e===e&&(n=n.add(1,"date"===t?"day":t)),n=n.startOf(t)}return n=n.set(t,Math.round(n.get(t)/e)*e),n}})),F.extend(((t,e,s)=>{e.prototype.validate=function(t,e,n="day"){if(!this.isValid())return!1;if(!t)return!0;t=s.iso(t);const i={min:"isAfter",max:"isBefore"}[e];return this.isSame(t,n)||this[i](t,n)}}));const rr={install(t){t.prototype.$library={autosize:R,dayjs:F}}},lr={install(t){const e={...t.options.components},s={section:ii};for(const[n,i]of Object.entries(window.panel.plugins.components))i.template||i.render||i.extends?("string"==typeof(null==i?void 0:i.extends)&&(e[i.extends]?i.extends=e[i.extends].extend({options:i,components:{...e,...i.components||{}}}):(window.console.warn(`Problem with plugin trying to register component "${n}": cannot extend non-existent component "${i.extends}"`),i.extends=null)),i.template&&(i.render=null),i.mixins&&(i.mixins=i.mixins.map((t=>"string"==typeof t?s[t]:t))),e[n]&&window.console.warn(`Plugin is replacing "${n}"`),t.component(n,i),e[n]=t.options.components[n]):jo.dispatch("notification/error",`Neither template or render method provided nor extending a component when loading plugin component "${n}". The component has not been registered.`);for(const n of window.panel.plugins.use)t.use(n)}};t.config.productionTip=!1,t.config.devtools=!0;const ar=new t({store:jo,created(){window.panel.$vue=window.panel.app=this,window.panel.plugins.created.forEach((t=>t(this))),this.$store.dispatch("content/init")},render:()=>L(J)});t.use(Eo),t.use(ir),t.use(rr),t.use(V,jo),t.use(Mo),t.use(or),t.use(qo),t.use(z),t.use(xo),t.use(lr),ar.$mount("#app"); diff --git a/kirby/panel/dist/js/vendor.js b/kirby/panel/dist/js/vendor.js index e918936..d965b54 100644 --- a/kirby/panel/dist/js/vendor.js +++ b/kirby/panel/dist/js/vendor.js @@ -1,12 +1,11 @@ /*! - * Vue.js v2.7.10 + * Vue.js v2.7.14 * (c) 2014-2022 Evan You * Released under the MIT License. */ -var t=Object.freeze({}),e=Array.isArray;function n(t){return null==t}function r(t){return null!=t}function i(t){return!0===t}function o(t){return"string"==typeof t||"number"==typeof t||"symbol"==typeof t||"boolean"==typeof t}function s(t){return"function"==typeof t}function a(t){return null!==t&&"object"==typeof t}var l=Object.prototype.toString;function c(t){return"[object Object]"===l.call(t)}function u(t){var e=parseFloat(String(t));return e>=0&&Math.floor(e)===e&&isFinite(t)}function d(t){return r(t)&&"function"==typeof t.then&&"function"==typeof t.catch}function f(t){return null==t?"":Array.isArray(t)||c(t)&&t.toString===l?JSON.stringify(t,null,2):String(t)}function h(t){var e=parseFloat(t);return isNaN(e)?t:e}function p(t,e){for(var n=Object.create(null),r=t.split(","),i=0;i-1)return t.splice(n,1)}}var y=Object.prototype.hasOwnProperty;function b(t,e){return y.call(t,e)}function w(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}var x=/-(\w)/g,S=w((function(t){return t.replace(x,(function(t,e){return e?e.toUpperCase():""}))})),k=w((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),O=/\B([A-Z])/g,_=w((function(t){return t.replace(O,"-$1").toLowerCase()}));var M=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n};function C(t,e){e=e||0;for(var n=t.length-e,r=new Array(n);n--;)r[n]=t[n+e];return r}function $(t,e){for(var n in e)t[n]=e[n];return t}function T(t){for(var e={},n=0;n0,Y=K&&K.indexOf("edge/")>0;K&&K.indexOf("android");var G=K&&/iphone|ipad|ipod|ios/.test(K);K&&/chrome\/\d+/.test(K),K&&/phantomjs/.test(K);var Z,X=K&&K.match(/firefox\/(\d+)/),Q={}.watch,tt=!1;if(J)try{var et={};Object.defineProperty(et,"passive",{get:function(){tt=!0}}),window.addEventListener("test-passive",null,et)}catch(_g){}var nt=function(){return void 0===Z&&(Z=!J&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),Z},rt=J&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function it(t){return"function"==typeof t&&/native code/.test(t.toString())}var ot,st="undefined"!=typeof Symbol&&it(Symbol)&&"undefined"!=typeof Reflect&&it(Reflect.ownKeys);ot="undefined"!=typeof Set&&it(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var at=null;function lt(t){void 0===t&&(t=null),t||at&&at._scope.off(),at=t,t&&t._scope.on()}var ct=function(){function t(t,e,n,r,i,o,s,a){this.tag=t,this.data=e,this.children=n,this.text=r,this.elm=i,this.ns=void 0,this.context=o,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=e&&e.key,this.componentOptions=s,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=a,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1}return Object.defineProperty(t.prototype,"child",{get:function(){return this.componentInstance},enumerable:!1,configurable:!0}),t}(),ut=function(t){void 0===t&&(t="");var e=new ct;return e.text=t,e.isComment=!0,e};function dt(t){return new ct(void 0,void 0,void 0,String(t))}function ft(t){var e=new ct(t.tag,t.data,t.children&&t.children.slice(),t.text,t.elm,t.context,t.componentOptions,t.asyncFactory);return e.ns=t.ns,e.isStatic=t.isStatic,e.key=t.key,e.isComment=t.isComment,e.fnContext=t.fnContext,e.fnOptions=t.fnOptions,e.fnScopeId=t.fnScopeId,e.asyncMeta=t.asyncMeta,e.isCloned=!0,e}var ht=0,pt=function(){function t(){this.id=ht++,this.subs=[]}return t.prototype.addSub=function(t){this.subs.push(t)},t.prototype.removeSub=function(t){v(this.subs,t)},t.prototype.depend=function(e){t.target&&t.target.addDep(this)},t.prototype.notify=function(t){for(var e=this.subs.slice(),n=0,r=e.length;n0&&(Bt((l=Vt(l,"".concat(s||"","_").concat(a)))[0])&&Bt(u)&&(d[c]=dt(u.text+l[0].text),l.shift()),d.push.apply(d,l)):o(l)?Bt(u)?d[c]=dt(u.text+l):""!==l&&d.push(dt(l)):Bt(l)&&Bt(u)?d[c]=dt(u.text+l.text):(i(t._isVList)&&r(l.tag)&&n(l.key)&&r(s)&&(l.key="__vlist".concat(s,"_").concat(a,"__")),d.push(l)));return d}function Wt(t,n,l,c,u,d){return(e(l)||o(l))&&(u=c,c=l,l=void 0),i(d)&&(u=2),function(t,n,i,o,l){if(r(i)&&r(i.__ob__))return ut();r(i)&&r(i.is)&&(n=i.is);if(!n)return ut();e(o)&&s(o[0])&&((i=i||{}).scopedSlots={default:o[0]},o.length=0);2===l?o=Lt(o):1===l&&(o=function(t){for(var n=0;n0,a=n?!!n.$stable:!s,l=n&&n.$key;if(n){if(n._normalized)return n._normalized;if(a&&i&&i!==t&&l===i.$key&&!s&&!i.$hasNormal)return i;for(var c in o={},n)n[c]&&"$"!==c[0]&&(o[c]=ue(e,r,c,n[c]))}else o={};for(var u in r)u in o||(o[u]=de(r,u));return n&&Object.isExtensible(n)&&(n._normalized=o),V(o,"$stable",a),V(o,"$key",l),V(o,"$hasNormal",s),o}function ue(t,n,r,i){var o=function(){var n=at;lt(t);var r=arguments.length?i.apply(null,arguments):i({}),o=(r=r&&"object"==typeof r&&!e(r)?[r]:Lt(r))&&r[0];return lt(n),r&&(!o||1===r.length&&o.isComment&&!le(o))?void 0:r};return i.proxy&&Object.defineProperty(n,r,{get:o,enumerable:!0,configurable:!0}),o}function de(t,e){return function(){return t[e]}}function fe(e){var n=e.$options,r=n.setup;if(r){var i=e._setupContext=function(e){return{get attrs(){if(!e._attrsProxy){var n=e._attrsProxy={};V(n,"_v_attr_proxy",!0),he(n,e.$attrs,t,e,"$attrs")}return e._attrsProxy},get listeners(){e._listenersProxy||he(e._listenersProxy={},e.$listeners,t,e,"$listeners");return e._listenersProxy},get slots(){return function(t){t._slotsProxy||me(t._slotsProxy={},t.$scopedSlots);return t._slotsProxy}(e)},emit:M(e.$emit,e),expose:function(t){t&&Object.keys(t).forEach((function(n){return Pt(e,t,n)}))}}}(e);lt(e),gt();var o=qe(r,null,[e._props||Nt({}),i],e,"setup");if(vt(),lt(),s(o))n.render=o;else if(a(o))if(e._setupState=o,o.__sfc){var l=e._setupProxy={};for(var c in o)"__sfc"!==c&&Pt(l,o,c)}else for(var c in o)B(c)||Pt(e,o,c)}}function he(t,e,n,r,i){var o=!1;for(var s in e)s in t?e[s]!==n[s]&&(o=!0):(o=!0,pe(t,s,r,i));for(var s in t)s in e||(o=!0,delete t[s]);return o}function pe(t,e,n,r){Object.defineProperty(t,e,{enumerable:!0,configurable:!0,get:function(){return n[r][e]}})}function me(t,e){for(var n in e)t[n]=e[n];for(var n in t)n in e||delete t[n]}var ge,ve=null;function ye(t,e){return(t.__esModule||st&&"Module"===t[Symbol.toStringTag])&&(t=t.default),a(t)?e.extend(t):t}function be(t){if(e(t))for(var n=0;ndocument.createEvent("Event").timeStamp&&(ze=function(){return je.now()})}var Fe,Le=function(t,e){if(t.post){if(!e.post)return 1}else if(e.post)return-1;return t.id-e.id};function Be(){var t,e;for(Re=ze(),Pe=!0,De.sort(Le),Ie=0;IeIe&&De[n].id>t.id;)n--;De.splice(n+1,0,t)}else De.push(t);Ee||(Ee=!0,nn(Be))}}(this)},t.prototype.run=function(){if(this.active){var t=this.get();if(t!==this.value||a(t)||this.deep){var e=this.value;if(this.value=t,this.user){var n='callback for watcher "'.concat(this.expression,'"');qe(this.cb,this.vm,[t,e],this.vm,n)}else this.cb.call(this.vm,t,e)}}},t.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},t.prototype.depend=function(){for(var t=this.deps.length;t--;)this.deps[t].depend()},t.prototype.teardown=function(){if(this.vm&&!this.vm._isBeingDestroyed&&v(this.vm._scope.effects,this),this.active){for(var t=this.deps.length;t--;)this.deps[t].removeSub(this);this.active=!1,this.onStop&&this.onStop()}},t}(),cn={enumerable:!0,configurable:!0,get:D,set:D};function un(t,e,n){cn.get=function(){return this[e][n]},cn.set=function(t){this[e][n]=t},Object.defineProperty(t,n,cn)}function dn(t){var n=t.$options;if(n.props&&function(t,e){var n=t.$options.propsData||{},r=t._props=Nt({}),i=t.$options._propKeys=[];t.$parent&&kt(!1);var o=function(o){i.push(o);var s=jn(o,e,n,t);Ct(r,o,s),o in t||un(t,"_props",o)};for(var s in e)o(s);kt(!0)}(t,n.props),fe(t),n.methods&&function(t,e){for(var n in t.$options.props,e)t[n]="function"!=typeof e[n]?D:M(e[n],t)}(t,n.methods),n.data)!function(t){var e=t.$options.data;c(e=t._data=s(e)?function(t,e){gt();try{return t.call(e,e)}catch(_g){return We(_g,e,"data()"),{}}finally{vt()}}(e,t):e||{})||(e={});var n=Object.keys(e),r=t.$options.props;t.$options.methods;var i=n.length;for(;i--;){var o=n[i];r&&b(r,o)||B(o)||un(t,"_data",o)}var a=Mt(e);a&&a.vmCount++}(t);else{var r=Mt(t._data={});r&&r.vmCount++}n.computed&&function(t,e){var n=t._computedWatchers=Object.create(null),r=nt();for(var i in e){var o=e[i],a=s(o)?o:o.get;r||(n[i]=new ln(t,a||D,D,fn)),i in t||hn(t,i,o)}}(t,n.computed),n.watch&&n.watch!==Q&&function(t,n){for(var r in n){var i=n[r];if(e(i))for(var o=0;o-1)if(o&&!b(i,"default"))a=!1;else if(""===a||a===_(t)){var c=Vn(String,i.type);(c<0||l-1:"string"==typeof t?t.split(",").indexOf(n)>-1:(r=t,"[object RegExp]"===l.call(r)&&t.test(n));var r}function Hn(t,e){var n=t.cache,r=t.keys,i=t._vnode;for(var o in n){var s=n[o];if(s){var a=s.name;a&&!e(a)&&Un(n,o,r,i)}}}function Un(t,e,n,r){var i=t[e];!i||r&&i.tag===r.tag||i.componentInstance.$destroy(),t[e]=null,v(n,e)}Wn.prototype._init=function(e){var n=this;n._uid=bn++,n._isVue=!0,n.__v_skip=!0,n._scope=new Ve(!0),n._scope._vm=!0,e&&e._isComponent?function(t,e){var n=t.$options=Object.create(t.constructor.options),r=e._parentVnode;n.parent=e.parent,n._parentVnode=r;var i=r.componentOptions;n.propsData=i.propsData,n._parentListeners=i.listeners,n._renderChildren=i.children,n._componentTag=i.tag,e.render&&(n.render=e.render,n.staticRenderFns=e.staticRenderFns)}(n,e):n.$options=Rn(wn(n.constructor),e||{},n),n._renderProxy=n,n._self=n,function(t){var e=t.$options,n=e.parent;if(n&&!e.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(t)}t.$parent=n,t.$root=n?n.$root:t,t.$children=[],t.$refs={},t._provided=n?n._provided:Object.create(null),t._watcher=null,t._inactive=null,t._directInactive=!1,t._isMounted=!1,t._isDestroyed=!1,t._isBeingDestroyed=!1}(n),function(t){t._events=Object.create(null),t._hasHookEvent=!1;var e=t.$options._parentListeners;e&&ke(t,e)}(n),function(e){e._vnode=null,e._staticTrees=null;var n=e.$options,r=e.$vnode=n._parentVnode,i=r&&r.context;e.$slots=se(n._renderChildren,i),e.$scopedSlots=r?ce(e.$parent,r.data.scopedSlots,e.$slots):t,e._c=function(t,n,r,i){return Wt(e,t,n,r,i,!1)},e.$createElement=function(t,n,r,i){return Wt(e,t,n,r,i,!0)};var o=r&&r.data;Ct(e,"$attrs",o&&o.attrs||t,null,!0),Ct(e,"$listeners",n._parentListeners||t,null,!0)}(n),Te(n,"beforeCreate",void 0,!1),function(t){var e=yn(t.$options.inject,t);e&&(kt(!1),Object.keys(e).forEach((function(n){Ct(t,n,e[n])})),kt(!0))}(n),dn(n),vn(n),Te(n,"created"),n.$options.el&&n.$mount(n.$options.el)},function(t){var e={get:function(){return this._data}},n={get:function(){return this._props}};Object.defineProperty(t.prototype,"$data",e),Object.defineProperty(t.prototype,"$props",n),t.prototype.$set=$t,t.prototype.$delete=Tt,t.prototype.$watch=function(t,e,n){var r=this;if(c(e))return gn(r,t,e,n);(n=n||{}).user=!0;var i=new ln(r,t,e,n);if(n.immediate){var o='callback for immediate watcher "'.concat(i.expression,'"');gt(),qe(e,r,[i.value],r,o),vt()}return function(){i.teardown()}}}(Wn),function(t){var n=/^hook:/;t.prototype.$on=function(t,r){var i=this;if(e(t))for(var o=0,s=t.length;o1?C(n):n;for(var r=C(arguments,1),i='event handler for "'.concat(t,'"'),o=0,s=n.length;oparseInt(this.max)&&Un(e,n[0],n,this._vnode),this.vnodeToCache=null}}},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var t in this.cache)Un(this.cache,t,this.keys)},mounted:function(){var t=this;this.cacheVNode(),this.$watch("include",(function(e){Hn(t,(function(t){return Kn(e,t)}))})),this.$watch("exclude",(function(e){Hn(t,(function(t){return!Kn(e,t)}))}))},updated:function(){this.cacheVNode()},render:function(){var t=this.$slots.default,e=be(t),n=e&&e.componentOptions;if(n){var r=Jn(n),i=this.include,o=this.exclude;if(i&&(!r||!Kn(i,r))||o&&r&&Kn(o,r))return e;var s=this.cache,a=this.keys,l=null==e.key?n.Ctor.cid+(n.tag?"::".concat(n.tag):""):e.key;s[l]?(e.componentInstance=s[l].componentInstance,v(a,l),a.push(l)):(this.vnodeToCache=e,this.keyToCache=l),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={get:function(){return F}};Object.defineProperty(t,"config",e),t.util={warn:Tn,extend:$,mergeOptions:Rn,defineReactive:Ct},t.set=$t,t.delete=Tt,t.nextTick=nn,t.observable=function(t){return Mt(t),t},t.options=Object.create(null),z.forEach((function(e){t.options[e+"s"]=Object.create(null)})),t.options._base=t,$(t.options.components,Gn),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=C(arguments,1);return n.unshift(this),s(t.install)?t.install.apply(t,n):s(t)&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=Rn(this.options,t),this}}(t),qn(t),function(t){z.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&c(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&s(n)&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}}))}(t)}(Wn),Object.defineProperty(Wn.prototype,"$isServer",{get:nt}),Object.defineProperty(Wn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Wn,"FunctionalRenderContext",{value:xn}),Wn.version="2.7.10";var Zn=p("style,class"),Xn=p("input,textarea,option,select,progress"),Qn=function(t,e,n){return"value"===n&&Xn(t)&&"button"!==e||"selected"===n&&"option"===t||"checked"===n&&"input"===t||"muted"===n&&"video"===t},tr=p("contenteditable,draggable,spellcheck"),er=p("events,caret,typing,plaintext-only"),nr=p("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),rr="http://www.w3.org/1999/xlink",ir=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},or=function(t){return ir(t)?t.slice(6,t.length):""},sr=function(t){return null==t||!1===t};function ar(t){for(var e=t.data,n=t,i=t;r(i.componentInstance);)(i=i.componentInstance._vnode)&&i.data&&(e=lr(i.data,e));for(;r(n=n.parent);)n&&n.data&&(e=lr(e,n.data));return function(t,e){if(r(t)||r(e))return cr(t,ur(e));return""}(e.staticClass,e.class)}function lr(t,e){return{staticClass:cr(t.staticClass,e.staticClass),class:r(t.class)?[t.class,e.class]:e.class}}function cr(t,e){return t?e?t+" "+e:t:e||""}function ur(t){return Array.isArray(t)?function(t){for(var e,n="",i=0,o=t.length;i-1?Rr(t,e,n):nr(e)?sr(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):tr(e)?t.setAttribute(e,function(t,e){return sr(e)||"false"===e?"false":"contenteditable"===t&&er(e)?e:"true"}(e,n)):ir(e)?sr(n)?t.removeAttributeNS(rr,or(e)):t.setAttributeNS(rr,e,n):Rr(t,e,n)}function Rr(t,e,n){if(sr(n))t.removeAttribute(e);else{if(H&&!U&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var r=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",r)};t.addEventListener("input",r),t.__ieph=!0}t.setAttribute(e,n)}}var zr={create:Pr,update:Pr};function jr(t,e){var i=e.elm,o=e.data,s=t.data;if(!(n(o.staticClass)&&n(o.class)&&(n(s)||n(s.staticClass)&&n(s.class)))){var a=ar(e),l=i._transitionClasses;r(l)&&(a=cr(a,ur(l))),a!==i._prevClass&&(i.setAttribute("class",a),i._prevClass=a)}}var Fr,Lr,Br,Vr,Wr,qr,Jr={create:jr,update:jr},Kr=/[\w).+\-_$\]]/;function Hr(t){var e,n,r,i,o,s=!1,a=!1,l=!1,c=!1,u=0,d=0,f=0,h=0;for(r=0;r=0&&" "===(m=t.charAt(p));p--);m&&Kr.test(m)||(c=!0)}}else void 0===i?(h=r+1,i=t.slice(0,r).trim()):g();function g(){(o||(o=[])).push(t.slice(h,r).trim()),h=r+1}if(void 0===i?i=t.slice(0,r).trim():0!==h&&g(),o)for(r=0;r-1?{exp:t.slice(0,Vr),key:'"'+t.slice(Vr+1)+'"'}:{exp:t,key:null};Lr=t,Vr=Wr=qr=0;for(;!ui();)di(Br=ci())?hi(Br):91===Br&&fi(Br);return{exp:t.slice(0,Wr),key:t.slice(Wr+1,qr)}}(t);return null===n.key?"".concat(t,"=").concat(e):"$set(".concat(n.exp,", ").concat(n.key,", ").concat(e,")")}function ci(){return Lr.charCodeAt(++Vr)}function ui(){return Vr>=Fr}function di(t){return 34===t||39===t}function fi(t){var e=1;for(Wr=Vr;!ui();)if(di(t=ci()))hi(t);else if(91===t&&e++,93===t&&e--,0===e){qr=Vr;break}}function hi(t){for(var e=t;!ui()&&(t=ci())!==e;);}var pi;function mi(t,e,n){var r=pi;return function i(){var o=e.apply(null,arguments);null!==o&&yi(t,i,n,r)}}var gi=Ue&&!(X&&Number(X[1])<=53);function vi(t,e,n,r){if(gi){var i=Re,o=e;e=o._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=i||t.timeStamp<=0||t.target.ownerDocument!==document)return o.apply(this,arguments)}}pi.addEventListener(t,e,tt?{capture:n,passive:r}:n)}function yi(t,e,n,r){(r||pi).removeEventListener(t,e._wrapper||e,n)}function bi(t,e){if(!n(t.data.on)||!n(e.data.on)){var i=e.data.on||{},o=t.data.on||{};pi=e.elm||t.elm,function(t){if(r(t.__r)){var e=H?"change":"input";t[e]=[].concat(t.__r,t[e]||[]),delete t.__r}r(t.__c)&&(t.change=[].concat(t.__c,t.change||[]),delete t.__c)}(i),zt(i,o,vi,yi,mi,e.context),pi=void 0}}var wi,xi={create:bi,update:bi,destroy:function(t){return bi(t,kr)}};function Si(t,e){if(!n(t.data.domProps)||!n(e.data.domProps)){var o,s,a=e.elm,l=t.data.domProps||{},c=e.data.domProps||{};for(o in(r(c.__ob__)||i(c._v_attr_proxy))&&(c=e.data.domProps=$({},c)),l)o in c||(a[o]="");for(o in c){if(s=c[o],"textContent"===o||"innerHTML"===o){if(e.children&&(e.children.length=0),s===l[o])continue;1===a.childNodes.length&&a.removeChild(a.childNodes[0])}if("value"===o&&"PROGRESS"!==a.tagName){a._value=s;var u=n(s)?"":String(s);ki(a,u)&&(a.value=u)}else if("innerHTML"===o&&hr(a.tagName)&&n(a.innerHTML)){(wi=wi||document.createElement("div")).innerHTML="".concat(s,"");for(var d=wi.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;d.firstChild;)a.appendChild(d.firstChild)}else if(s!==l[o])try{a[o]=s}catch(_g){}}}}function ki(t,e){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(_g){}return n&&t.value!==e}(t,e)||function(t,e){var n=t.value,i=t._vModifiers;if(r(i)){if(i.number)return h(n)!==h(e);if(i.trim)return n.trim()!==e.trim()}return n!==e}(t,e))}var Oi={create:Si,update:Si},_i=w((function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach((function(t){if(t){var r=t.split(n);r.length>1&&(e[r[0].trim()]=r[1].trim())}})),e}));function Mi(t){var e=Ci(t.style);return t.staticStyle?$(t.staticStyle,e):e}function Ci(t){return Array.isArray(t)?T(t):"string"==typeof t?_i(t):t}var $i,Ti=/^--/,Di=/\s*!important$/,Ni=function(t,e,n){if(Ti.test(e))t.style.setProperty(e,n);else if(Di.test(n))t.style.setProperty(_(e),n.replace(Di,""),"important");else{var r=Ei(e);if(Array.isArray(n))for(var i=0,o=n.length;i-1?e.split(Ri).forEach((function(e){return t.classList.add(e)})):t.classList.add(e);else{var n=" ".concat(t.getAttribute("class")||""," ");n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function ji(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(Ri).forEach((function(e){return t.classList.remove(e)})):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" ".concat(t.getAttribute("class")||""," "),r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function Fi(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&$(e,Li(t.name||"v")),$(e,t),e}return"string"==typeof t?Li(t):void 0}}var Li=w((function(t){return{enterClass:"".concat(t,"-enter"),enterToClass:"".concat(t,"-enter-to"),enterActiveClass:"".concat(t,"-enter-active"),leaveClass:"".concat(t,"-leave"),leaveToClass:"".concat(t,"-leave-to"),leaveActiveClass:"".concat(t,"-leave-active")}})),Bi=J&&!U,Vi="transition",Wi="transitionend",qi="animation",Ji="animationend";Bi&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(Vi="WebkitTransition",Wi="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(qi="WebkitAnimation",Ji="webkitAnimationEnd"));var Ki=J?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function Hi(t){Ki((function(){Ki(t)}))}function Ui(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),zi(t,e))}function Yi(t,e){t._transitionClasses&&v(t._transitionClasses,e),ji(t,e)}function Gi(t,e,n){var r=Xi(t,e),i=r.type,o=r.timeout,s=r.propCount;if(!i)return n();var a="transition"===i?Wi:Ji,l=0,c=function(){t.removeEventListener(a,u),n()},u=function(e){e.target===t&&++l>=s&&c()};setTimeout((function(){l0&&(n="transition",u=s,d=o.length):"animation"===e?c>0&&(n="animation",u=c,d=l.length):d=(n=(u=Math.max(s,c))>0?s>c?"transition":"animation":null)?"transition"===n?o.length:l.length:0,{type:n,timeout:u,propCount:d,hasTransform:"transition"===n&&Zi.test(r[Vi+"Property"])}}function Qi(t,e){for(;t.length1}function oo(t,e){!0!==e.data.show&&eo(e)}var so=function(t){var s,a,l={},c=t.modules,u=t.nodeOps;for(s=0;sp?w(t,n(i[v+1])?null:i[v+1].elm,i,h,v,o):h>v&&S(e,d,p)}(d,m,g,o,c):r(g)?(r(t.text)&&u.setTextContent(d,""),w(d,null,g,0,g.length-1,o)):r(m)?S(m,0,m.length-1):r(t.text)&&u.setTextContent(d,""):t.text!==e.text&&u.setTextContent(d,e.text),r(p)&&r(h=p.hook)&&r(h=h.postpatch)&&h(t,e)}}}function M(t,e,n){if(i(n)&&r(t.parent))t.parent.data.pendingInsert=e;else for(var o=0;o-1,s.selected!==o&&(s.selected=o);else if(E(fo(s),r))return void(t.selectedIndex!==a&&(t.selectedIndex=a));i||(t.selectedIndex=-1)}}function uo(t,e){return e.every((function(e){return!E(e,t)}))}function fo(t){return"_value"in t?t._value:t.value}function ho(t){t.target.composing=!0}function po(t){t.target.composing&&(t.target.composing=!1,mo(t.target,"input"))}function mo(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function go(t){return!t.componentInstance||t.data&&t.data.transition?t:go(t.componentInstance._vnode)}var vo={model:ao,show:{bind:function(t,e,n){var r=e.value,i=(n=go(n)).data&&n.data.transition,o=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;r&&i?(n.data.show=!0,eo(n,(function(){t.style.display=o}))):t.style.display=r?o:"none"},update:function(t,e,n){var r=e.value;!r!=!e.oldValue&&((n=go(n)).data&&n.data.transition?(n.data.show=!0,r?eo(n,(function(){t.style.display=t.__vOriginalDisplay})):no(n,(function(){t.style.display="none"}))):t.style.display=r?t.__vOriginalDisplay:"none")},unbind:function(t,e,n,r,i){i||(t.style.display=t.__vOriginalDisplay)}}},yo={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function bo(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?bo(be(e.children)):t}function wo(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var i=n._parentListeners;for(var r in i)e[S(r)]=i[r];return e}function xo(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}var So=function(t){return t.tag||le(t)},ko=function(t){return"show"===t.name},Oo={name:"transition",props:yo,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(So)).length){var r=this.mode,i=n[0];if(function(t){for(;t=t.parent;)if(t.data.transition)return!0}(this.$vnode))return i;var s=bo(i);if(!s)return i;if(this._leaving)return xo(t,i);var a="__transition-".concat(this._uid,"-");s.key=null==s.key?s.isComment?a+"comment":a+s.tag:o(s.key)?0===String(s.key).indexOf(a)?s.key:a+s.key:s.key;var l=(s.data||(s.data={})).transition=wo(this),c=this._vnode,u=bo(c);if(s.data.directives&&s.data.directives.some(ko)&&(s.data.show=!0),u&&u.data&&!function(t,e){return e.key===t.key&&e.tag===t.tag}(s,u)&&!le(u)&&(!u.componentInstance||!u.componentInstance._vnode.isComment)){var d=u.data.transition=$({},l);if("out-in"===r)return this._leaving=!0,jt(d,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),xo(t,i);if("in-out"===r){if(le(s))return c;var f,h=function(){f()};jt(l,"afterEnter",h),jt(l,"enterCancelled",h),jt(d,"delayLeave",(function(t){f=t}))}}return i}}},_o=$({tag:String,moveClass:String},yo);delete _o.mode;var Mo={props:_o,beforeMount:function(){var t=this,e=this._update;this._update=function(n,r){var i=_e(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,i(),e.call(t,n,r)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,i=this.$slots.default||[],o=this.children=[],s=wo(this),a=0;a-1?gr[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:gr[t]=/HTMLUnknownElement/.test(e.toString())},$(Wn.options.directives,vo),$(Wn.options.components,Do),Wn.prototype.__patch__=J?so:D,Wn.prototype.$mount=function(t,e){return function(t,e,n){var r;t.$el=e,t.$options.render||(t.$options.render=ut),Te(t,"beforeMount"),r=function(){t._update(t._render(),n)},new ln(t,r,D,{before:function(){t._isMounted&&!t._isDestroyed&&Te(t,"beforeUpdate")}},!0),n=!1;var i=t._preWatchers;if(i)for(var o=0;o\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,Vo=/^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+?\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,Wo="[a-zA-Z_][\\-\\.0-9_a-zA-Z".concat(L.source,"]*"),qo="((?:".concat(Wo,"\\:)?").concat(Wo,")"),Jo=new RegExp("^<".concat(qo)),Ko=/^\s*(\/?)>/,Ho=new RegExp("^<\\/".concat(qo,"[^>]*>")),Uo=/^]+>/i,Yo=/^",""":'"',"&":"&"," ":"\n"," ":"\t","'":"'"},ts=/&(?:lt|gt|quot|amp|#39);/g,es=/&(?:lt|gt|quot|amp|#39|#10|#9);/g,ns=p("pre,textarea",!0),rs=function(t,e){return t&&ns(t)&&"\n"===e[0]};function is(t,e){var n=e?es:ts;return t.replace(n,(function(t){return Qo[t]}))}function ss(t,e){for(var n,r,i=[],o=e.expectHTML,s=e.isUnaryTag||N,a=e.canBeLeftOpenTag||N,l=0,c=function(){if(n=t,r&&Zo(r)){var c=0,f=r.toLowerCase(),h=Xo[f]||(Xo[f]=new RegExp("([\\s\\S]*?)(]*>)","i"));S=t.replace(h,(function(t,n,r){return c=r.length,Zo(f)||"noscript"===f||(n=n.replace(//g,"$1").replace(//g,"$1")),rs(f,n)&&(n=n.slice(1)),e.chars&&e.chars(n),""}));l+=t.length-S.length,t=S,d(f,l-c,l)}else{var p=t.indexOf("<");if(0===p){if(Yo.test(t)){var m=t.indexOf("--\x3e");if(m>=0)return e.shouldKeepComment&&e.comment&&e.comment(t.substring(4,m),l,l+m+3),u(m+3),"continue"}if(Go.test(t)){var g=t.indexOf("]>");if(g>=0)return u(g+2),"continue"}var v=t.match(Uo);if(v)return u(v[0].length),"continue";var y=t.match(Ho);if(y){var b=l;return u(y[0].length),d(y[1],b,l),"continue"}var w=function(){var e=t.match(Jo);if(e){var n={tagName:e[1],attrs:[],start:l};u(e[0].length);for(var r=void 0,i=void 0;!(r=t.match(Ko))&&(i=t.match(Vo)||t.match(Bo));)i.start=l,u(i[0].length),i.end=l,n.attrs.push(i);if(r)return n.unarySlash=r[1],u(r[0].length),n.end=l,n}}();if(w)return function(t){var n=t.tagName,l=t.unarySlash;o&&("p"===r&&Lo(n)&&d(r),a(n)&&r===n&&d(n));for(var c=s(n)||!!l,u=t.attrs.length,f=new Array(u),h=0;h=0){for(S=t.slice(p);!(Ho.test(S)||Jo.test(S)||Yo.test(S)||Go.test(S)||(k=S.indexOf("<",1))<0);)p+=k,S=t.slice(p);x=t.substring(0,p)}p<0&&(x=t),x&&u(x.length),e.chars&&x&&e.chars(x,l-x.length,l)}if(t===n)return e.chars&&e.chars(t),"break"};t;){if("break"===c())break}function u(e){l+=e,t=t.substring(e)}function d(t,n,o){var s,a;if(null==n&&(n=l),null==o&&(o=l),t)for(a=t.toLowerCase(),s=i.length-1;s>=0&&i[s].lowerCasedTag!==a;s--);else s=0;if(s>=0){for(var c=i.length-1;c>=s;c--)e.end&&e.end(i[c].tag,n,o);i.length=s,r=s&&i[s-1].tag}else"br"===a?e.start&&e.start(t,[],!0,n,o):"p"===a&&(e.start&&e.start(t,[],!1,n,o),e.end&&e.end(t,n,o))}d()}var as,ls,cs,us,ds,fs,hs,ps,ms=/^@|^v-on:/,gs=/^v-|^@|^:|^#/,vs=/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/,ys=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,bs=/^\(|\)$/g,ws=/^\[.*\]$/,xs=/:(.*)$/,Ss=/^:|^\.|^v-bind:/,ks=/\.[^.\]]+(?=[^\]]*$)/g,Os=/^v-slot(:|$)|^#/,_s=/[\r\n]/,Ms=/[ \f\t\r\n]+/g,Cs=w(zo);function $s(t,e,n){return{type:1,tag:t,attrsList:e,attrsMap:Is(e),rawAttrsMap:{},parent:n,children:[]}}function Ts(t,e){as=e.warn||Yr,fs=e.isPreTag||N,hs=e.mustUseProp||N,ps=e.getTagNamespace||N,e.isReservedTag,cs=Gr(e.modules,"transformNode"),us=Gr(e.modules,"preTransformNode"),ds=Gr(e.modules,"postTransformNode"),ls=e.delimiters;var n,r,i=[],o=!1!==e.preserveWhitespace,s=e.whitespace,a=!1,l=!1;function c(t){if(u(t),a||t.processed||(t=Ds(t,e)),i.length||t===n||n.if&&(t.elseif||t.else)&&As(n,{exp:t.elseif,block:t}),r&&!t.forbidden)if(t.elseif||t.else)s=t,c=function(t){for(var e=t.length;e--;){if(1===t[e].type)return t[e];t.pop()}}(r.children),c&&c.if&&As(c,{exp:s.elseif,block:s});else{if(t.slotScope){var o=t.slotTarget||'"default"';(r.scopedSlots||(r.scopedSlots={}))[o]=t}r.children.push(t),t.parent=r}var s,c;t.children=t.children.filter((function(t){return!t.slotScope})),u(t),t.pre&&(a=!1),fs(t.tag)&&(l=!1);for(var d=0;dl&&(a.push(o=t.slice(l,i)),s.push(JSON.stringify(o)));var c=Hr(r[1].trim());s.push("_s(".concat(c,")")),a.push({"@binding":c}),l=i+r[0].length}return l-1")+("true"===o?":(".concat(e,")"):":_q(".concat(e,",").concat(o,")"))),ni(t,"change","var $$a=".concat(e,",")+"$$el=$event.target,"+"$$c=$$el.checked?(".concat(o,"):(").concat(s,");")+"if(Array.isArray($$a)){"+"var $$v=".concat(r?"_n("+i+")":i,",")+"$$i=_i($$a,$$v);"+"if($$el.checked){$$i<0&&(".concat(li(e,"$$a.concat([$$v])"),")}")+"else{$$i>-1&&(".concat(li(e,"$$a.slice(0,$$i).concat($$a.slice($$i+1))"),")}")+"}else{".concat(li(e,"$$c"),"}"),null,!0)}(t,r,i);else if("input"===o&&"radio"===s)!function(t,e,n){var r=n&&n.number,i=ri(t,"value")||"null";i=r?"_n(".concat(i,")"):i,Zr(t,"checked","_q(".concat(e,",").concat(i,")")),ni(t,"change",li(e,i),null,!0)}(t,r,i);else if("input"===o||"textarea"===o)!function(t,e,n){var r=t.attrsMap.type,i=n||{},o=i.lazy,s=i.number,a=i.trim,l=!o&&"range"!==r,c=o?"change":"range"===r?"__r":"input",u="$event.target.value";a&&(u="$event.target.value.trim()");s&&(u="_n(".concat(u,")"));var d=li(e,u);l&&(d="if($event.target.composing)return;".concat(d));Zr(t,"value","(".concat(e,")")),ni(t,c,d,null,!0),(a||s)&&ni(t,"blur","$forceUpdate()")}(t,r,i);else if(!F.isReservedTag(o))return ai(t,r,i),!1;return!0},text:function(t,e){e.value&&Zr(t,"textContent","_s(".concat(e.value,")"),e)},html:function(t,e){e.value&&Zr(t,"innerHTML","_s(".concat(e.value,")"),e)}},qs={expectHTML:!0,modules:Fs,directives:Ws,isPreTag:function(t){return"pre"===t},isUnaryTag:jo,mustUseProp:Qn,canBeLeftOpenTag:Fo,isReservedTag:pr,getTagNamespace:mr,staticKeys:(Ls=Fs,Ls.reduce((function(t,e){return t.concat(e.staticKeys||[])}),[]).join(","))},Js=w((function(t){return p("type,tag,attrsList,attrsMap,plain,parent,children,attrs,start,end,rawAttrsMap"+(t?","+t:""))}));function Ks(t,e){t&&(Bs=Js(e.staticKeys||""),Vs=e.isReservedTag||N,Hs(t),Us(t,!1))}function Hs(t){if(t.static=function(t){if(2===t.type)return!1;if(3===t.type)return!0;return!(!t.pre&&(t.hasBindings||t.if||t.for||m(t.tag)||!Vs(t.tag)||function(t){for(;t.parent;){if("template"!==(t=t.parent).tag)return!1;if(t.for)return!0}return!1}(t)||!Object.keys(t).every(Bs)))}(t),1===t.type){if(!Vs(t.tag)&&"slot"!==t.tag&&null==t.attrsMap["inline-template"])return;for(var e=0,n=t.children.length;e|^function(?:\s+[\w$]+)?\s*\(/,Gs=/\([^)]*?\);*$/,Zs=/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/,Xs={esc:27,tab:9,enter:13,space:32,up:38,left:37,right:39,down:40,delete:[8,46]},Qs={esc:["Esc","Escape"],tab:"Tab",enter:"Enter",space:[" ","Spacebar"],up:["Up","ArrowUp"],left:["Left","ArrowLeft"],right:["Right","ArrowRight"],down:["Down","ArrowDown"],delete:["Backspace","Delete","Del"]},ta=function(t){return"if(".concat(t,")return null;")},ea={stop:"$event.stopPropagation();",prevent:"$event.preventDefault();",self:ta("$event.target !== $event.currentTarget"),ctrl:ta("!$event.ctrlKey"),shift:ta("!$event.shiftKey"),alt:ta("!$event.altKey"),meta:ta("!$event.metaKey"),left:ta("'button' in $event && $event.button !== 0"),middle:ta("'button' in $event && $event.button !== 1"),right:ta("'button' in $event && $event.button !== 2")};function na(t,e){var n=e?"nativeOn:":"on:",r="",i="";for(var o in t){var s=ra(t[o]);t[o]&&t[o].dynamic?i+="".concat(o,",").concat(s,","):r+='"'.concat(o,'":').concat(s,",")}return r="{".concat(r.slice(0,-1),"}"),i?n+"_d(".concat(r,",[").concat(i.slice(0,-1),"])"):n+r}function ra(t){if(!t)return"function(){}";if(Array.isArray(t))return"[".concat(t.map((function(t){return ra(t)})).join(","),"]");var e=Zs.test(t.value),n=Ys.test(t.value),r=Zs.test(t.value.replace(Gs,""));if(t.modifiers){var i="",o="",s=[],a=function(e){if(ea[e])o+=ea[e],Xs[e]&&s.push(e);else if("exact"===e){var n=t.modifiers;o+=ta(["ctrl","shift","alt","meta"].filter((function(t){return!n[t]})).map((function(t){return"$event.".concat(t,"Key")})).join("||"))}else s.push(e)};for(var l in t.modifiers)a(l);s.length&&(i+=function(t){return"if(!$event.type.indexOf('key')&&"+"".concat(t.map(ia).join("&&"),")return null;")}(s)),o&&(i+=o);var c=e?"return ".concat(t.value,".apply(null, arguments)"):n?"return (".concat(t.value,").apply(null, arguments)"):r?"return ".concat(t.value):t.value;return"function($event){".concat(i).concat(c,"}")}return e||n?t.value:"function($event){".concat(r?"return ".concat(t.value):t.value,"}")}function ia(t){var e=parseInt(t,10);if(e)return"$event.keyCode!==".concat(e);var n=Xs[t],r=Qs[t];return"_k($event.keyCode,"+"".concat(JSON.stringify(t),",")+"".concat(JSON.stringify(n),",")+"$event.key,"+"".concat(JSON.stringify(r))+")"}var oa={on:function(t,e){t.wrapListeners=function(t){return"_g(".concat(t,",").concat(e.value,")")}},bind:function(t,e){t.wrapData=function(n){return"_b(".concat(n,",'").concat(t.tag,"',").concat(e.value,",").concat(e.modifiers&&e.modifiers.prop?"true":"false").concat(e.modifiers&&e.modifiers.sync?",true":"",")")}},cloak:D},sa=function(t){this.options=t,this.warn=t.warn||Yr,this.transforms=Gr(t.modules,"transformCode"),this.dataGenFns=Gr(t.modules,"genData"),this.directives=$($({},oa),t.directives);var e=t.isReservedTag||N;this.maybeComponent=function(t){return!!t.component||!e(t.tag)},this.onceId=0,this.staticRenderFns=[],this.pre=!1};function aa(t,e){var n=new sa(e),r=t?"script"===t.tag?"null":la(t,n):'_c("div")';return{render:"with(this){return ".concat(r,"}"),staticRenderFns:n.staticRenderFns}}function la(t,e){if(t.parent&&(t.pre=t.pre||t.parent.pre),t.staticRoot&&!t.staticProcessed)return ca(t,e);if(t.once&&!t.onceProcessed)return ua(t,e);if(t.for&&!t.forProcessed)return ha(t,e);if(t.if&&!t.ifProcessed)return da(t,e);if("template"!==t.tag||t.slotTarget||e.pre){if("slot"===t.tag)return function(t,e){var n=t.slotName||'"default"',r=va(t,e),i="_t(".concat(n).concat(r?",function(){return ".concat(r,"}"):""),o=t.attrs||t.dynamicAttrs?wa((t.attrs||[]).concat(t.dynamicAttrs||[]).map((function(t){return{name:S(t.name),value:t.value,dynamic:t.dynamic}}))):null,s=t.attrsMap["v-bind"];!o&&!s||r||(i+=",null");o&&(i+=",".concat(o));s&&(i+="".concat(o?"":",null",",").concat(s));return i+")"}(t,e);var n=void 0;if(t.component)n=function(t,e,n){var r=e.inlineTemplate?null:va(e,n,!0);return"_c(".concat(t,",").concat(pa(e,n)).concat(r?",".concat(r):"",")")}(t.component,t,e);else{var r=void 0,i=e.maybeComponent(t);(!t.plain||t.pre&&i)&&(r=pa(t,e));var o=void 0,s=e.options.bindings;i&&s&&!1!==s.__isScriptSetup&&(o=function(t,e){var n=S(e),r=k(n),i=function(i){return t[e]===i?e:t[n]===i?n:t[r]===i?r:void 0},o=i("setup-const")||i("setup-reactive-const");if(o)return o;var s=i("setup-let")||i("setup-ref")||i("setup-maybe-ref");if(s)return s}(s,t.tag)),o||(o="'".concat(t.tag,"'"));var a=t.inlineTemplate?null:va(t,e,!0);n="_c(".concat(o).concat(r?",".concat(r):"").concat(a?",".concat(a):"",")")}for(var l=0;l>>0}(s)):"",")")}(t,t.scopedSlots,e),",")),t.model&&(n+="model:{value:".concat(t.model.value,",callback:").concat(t.model.callback,",expression:").concat(t.model.expression,"},")),t.inlineTemplate){var o=function(t,e){var n=t.children[0];if(n&&1===n.type){var r=aa(n,e.options);return"inlineTemplate:{render:function(){".concat(r.render,"},staticRenderFns:[").concat(r.staticRenderFns.map((function(t){return"function(){".concat(t,"}")})).join(","),"]}")}}(t,e);o&&(n+="".concat(o,","))}return n=n.replace(/,$/,"")+"}",t.dynamicAttrs&&(n="_b(".concat(n,',"').concat(t.tag,'",').concat(wa(t.dynamicAttrs),")")),t.wrapData&&(n=t.wrapData(n)),t.wrapListeners&&(n=t.wrapListeners(n)),n}function ma(t){return 1===t.type&&("slot"===t.tag||t.children.some(ma))}function ga(t,e){var n=t.attrsMap["slot-scope"];if(t.if&&!t.ifProcessed&&!n)return da(t,e,ga,"null");if(t.for&&!t.forProcessed)return ha(t,e,ga);var r="_empty_"===t.slotScope?"":String(t.slotScope),i="function(".concat(r,"){")+"return ".concat("template"===t.tag?t.if&&n?"(".concat(t.if,")?").concat(va(t,e)||"undefined",":undefined"):va(t,e)||"undefined":la(t,e),"}"),o=r?"":",proxy:true";return"{key:".concat(t.slotTarget||'"default"',",fn:").concat(i).concat(o,"}")}function va(t,e,n,r,i){var o=t.children;if(o.length){var s=o[0];if(1===o.length&&s.for&&"template"!==s.tag&&"slot"!==s.tag){var a=n?e.maybeComponent(s)?",1":",0":"";return"".concat((r||la)(s,e)).concat(a)}var l=n?function(t,e){for(var n=0,r=0;r':'

',_a.innerHTML.indexOf(" ")>0}var Ta=!!J&&$a(!1),Da=!!J&&$a(!0),Na=w((function(t){var e=yr(t);return e&&e.innerHTML})),Aa=Wn.prototype.$mount;Wn.prototype.$mount=function(t,e){if((t=t&&yr(t))===document.body||t===document.documentElement)return this;var n=this.$options;if(!n.render){var r=n.template;if(r)if("string"==typeof r)"#"===r.charAt(0)&&(r=Na(r));else{if(!r.nodeType)return this;r=r.innerHTML}else t&&(r=function(t){if(t.outerHTML)return t.outerHTML;var e=document.createElement("div");return e.appendChild(t.cloneNode(!0)),e.innerHTML}(t));if(r){var i=Ca(r,{outputSourceRange:!1,shouldDecodeNewlines:Ta,shouldDecodeNewlinesForHref:Da,delimiters:n.delimiters,comments:n.comments},this),o=i.render,s=i.staticRenderFns;n.render=o,n.staticRenderFns=s}}return Aa.call(this,t,e)},Wn.compile=Ca;var Ea=("undefined"!=typeof window?window:"undefined"!=typeof global?global:{}).__VUE_DEVTOOLS_GLOBAL_HOOK__;function Pa(t,e){if(void 0===e&&(e=[]),null===t||"object"!=typeof t)return t;var n,r=(n=function(e){return e.original===t},e.filter(n)[0]);if(r)return r.copy;var i=Array.isArray(t)?[]:{};return e.push({original:t,copy:i}),Object.keys(t).forEach((function(n){i[n]=Pa(t[n],e)})),i}function Ia(t,e){Object.keys(t).forEach((function(n){return e(t[n],n)}))}function Ra(t){return null!==t&&"object"==typeof t}var za=function(t,e){this.runtime=e,this._children=Object.create(null),this._rawModule=t;var n=t.state;this.state=("function"==typeof n?n():n)||{}},ja={namespaced:{configurable:!0}};ja.namespaced.get=function(){return!!this._rawModule.namespaced},za.prototype.addChild=function(t,e){this._children[t]=e},za.prototype.removeChild=function(t){delete this._children[t]},za.prototype.getChild=function(t){return this._children[t]},za.prototype.hasChild=function(t){return t in this._children},za.prototype.update=function(t){this._rawModule.namespaced=t.namespaced,t.actions&&(this._rawModule.actions=t.actions),t.mutations&&(this._rawModule.mutations=t.mutations),t.getters&&(this._rawModule.getters=t.getters)},za.prototype.forEachChild=function(t){Ia(this._children,t)},za.prototype.forEachGetter=function(t){this._rawModule.getters&&Ia(this._rawModule.getters,t)},za.prototype.forEachAction=function(t){this._rawModule.actions&&Ia(this._rawModule.actions,t)},za.prototype.forEachMutation=function(t){this._rawModule.mutations&&Ia(this._rawModule.mutations,t)},Object.defineProperties(za.prototype,ja);var Fa,La=function(t){this.register([],t,!1)};function Ba(t,e,n){if(e.update(n),n.modules)for(var r in n.modules){if(!e.getChild(r))return;Ba(t.concat(r),e.getChild(r),n.modules[r])}}La.prototype.get=function(t){return t.reduce((function(t,e){return t.getChild(e)}),this.root)},La.prototype.getNamespace=function(t){var e=this.root;return t.reduce((function(t,n){return t+((e=e.getChild(n)).namespaced?n+"/":"")}),"")},La.prototype.update=function(t){Ba([],this.root,t)},La.prototype.register=function(t,e,n){var r=this;void 0===n&&(n=!0);var i=new za(e,n);0===t.length?this.root=i:this.get(t.slice(0,-1)).addChild(t[t.length-1],i);e.modules&&Ia(e.modules,(function(e,i){r.register(t.concat(i),e,n)}))},La.prototype.unregister=function(t){var e=this.get(t.slice(0,-1)),n=t[t.length-1],r=e.getChild(n);r&&r.runtime&&e.removeChild(n)},La.prototype.isRegistered=function(t){var e=this.get(t.slice(0,-1)),n=t[t.length-1];return!!e&&e.hasChild(n)};var Va=function(t){var e=this;void 0===t&&(t={}),!Fa&&"undefined"!=typeof window&&window.Vue&&Ga(window.Vue);var n=t.plugins;void 0===n&&(n=[]);var r=t.strict;void 0===r&&(r=!1),this._committing=!1,this._actions=Object.create(null),this._actionSubscribers=[],this._mutations=Object.create(null),this._wrappedGetters=Object.create(null),this._modules=new La(t),this._modulesNamespaceMap=Object.create(null),this._subscribers=[],this._watcherVM=new Fa,this._makeLocalGettersCache=Object.create(null);var i=this,o=this.dispatch,s=this.commit;this.dispatch=function(t,e){return o.call(i,t,e)},this.commit=function(t,e,n){return s.call(i,t,e,n)},this.strict=r;var a=this._modules.root.state;Ha(this,a,[],this._modules.root),Ka(this,a),n.forEach((function(t){return t(e)})),(void 0!==t.devtools?t.devtools:Fa.config.devtools)&&function(t){Ea&&(t._devtoolHook=Ea,Ea.emit("vuex:init",t),Ea.on("vuex:travel-to-state",(function(e){t.replaceState(e)})),t.subscribe((function(t,e){Ea.emit("vuex:mutation",t,e)}),{prepend:!0}),t.subscribeAction((function(t,e){Ea.emit("vuex:action",t,e)}),{prepend:!0}))}(this)},Wa={state:{configurable:!0}};function qa(t,e,n){return e.indexOf(t)<0&&(n&&n.prepend?e.unshift(t):e.push(t)),function(){var n=e.indexOf(t);n>-1&&e.splice(n,1)}}function Ja(t,e){t._actions=Object.create(null),t._mutations=Object.create(null),t._wrappedGetters=Object.create(null),t._modulesNamespaceMap=Object.create(null);var n=t.state;Ha(t,n,[],t._modules.root,!0),Ka(t,n,e)}function Ka(t,e,n){var r=t._vm;t.getters={},t._makeLocalGettersCache=Object.create(null);var i=t._wrappedGetters,o={};Ia(i,(function(e,n){o[n]=function(t,e){return function(){return t(e)}}(e,t),Object.defineProperty(t.getters,n,{get:function(){return t._vm[n]},enumerable:!0})}));var s=Fa.config.silent;Fa.config.silent=!0,t._vm=new Fa({data:{$$state:e},computed:o}),Fa.config.silent=s,t.strict&&function(t){t._vm.$watch((function(){return this._data.$$state}),(function(){}),{deep:!0,sync:!0})}(t),r&&(n&&t._withCommit((function(){r._data.$$state=null})),Fa.nextTick((function(){return r.$destroy()})))}function Ha(t,e,n,r,i){var o=!n.length,s=t._modules.getNamespace(n);if(r.namespaced&&(t._modulesNamespaceMap[s],t._modulesNamespaceMap[s]=r),!o&&!i){var a=Ua(e,n.slice(0,-1)),l=n[n.length-1];t._withCommit((function(){Fa.set(a,l,r.state)}))}var c=r.context=function(t,e,n){var r=""===e,i={dispatch:r?t.dispatch:function(n,r,i){var o=Ya(n,r,i),s=o.payload,a=o.options,l=o.type;return a&&a.root||(l=e+l),t.dispatch(l,s)},commit:r?t.commit:function(n,r,i){var o=Ya(n,r,i),s=o.payload,a=o.options,l=o.type;a&&a.root||(l=e+l),t.commit(l,s,a)}};return Object.defineProperties(i,{getters:{get:r?function(){return t.getters}:function(){return function(t,e){if(!t._makeLocalGettersCache[e]){var n={},r=e.length;Object.keys(t.getters).forEach((function(i){if(i.slice(0,r)===e){var o=i.slice(r);Object.defineProperty(n,o,{get:function(){return t.getters[i]},enumerable:!0})}})),t._makeLocalGettersCache[e]=n}return t._makeLocalGettersCache[e]}(t,e)}},state:{get:function(){return Ua(t.state,n)}}}),i}(t,s,n);r.forEachMutation((function(e,n){!function(t,e,n,r){(t._mutations[e]||(t._mutations[e]=[])).push((function(e){n.call(t,r.state,e)}))}(t,s+n,e,c)})),r.forEachAction((function(e,n){var r=e.root?n:s+n,i=e.handler||e;!function(t,e,n,r){(t._actions[e]||(t._actions[e]=[])).push((function(e){var i,o=n.call(t,{dispatch:r.dispatch,commit:r.commit,getters:r.getters,state:r.state,rootGetters:t.getters,rootState:t.state},e);return(i=o)&&"function"==typeof i.then||(o=Promise.resolve(o)),t._devtoolHook?o.catch((function(e){throw t._devtoolHook.emit("vuex:error",e),e})):o}))}(t,r,i,c)})),r.forEachGetter((function(e,n){!function(t,e,n,r){if(t._wrappedGetters[e])return;t._wrappedGetters[e]=function(t){return n(r.state,r.getters,t.state,t.getters)}}(t,s+n,e,c)})),r.forEachChild((function(r,o){Ha(t,e,n.concat(o),r,i)}))}function Ua(t,e){return e.reduce((function(t,e){return t[e]}),t)}function Ya(t,e,n){return Ra(t)&&t.type&&(n=e,e=t,t=t.type),{type:t,payload:e,options:n}}function Ga(t){Fa&&t===Fa|| +var t=Object.freeze({}),e=Array.isArray;function n(t){return null==t}function r(t){return null!=t}function i(t){return!0===t}function o(t){return"string"==typeof t||"number"==typeof t||"symbol"==typeof t||"boolean"==typeof t}function s(t){return"function"==typeof t}function a(t){return null!==t&&"object"==typeof t}var l=Object.prototype.toString;function c(t){return"[object Object]"===l.call(t)}function u(t){var e=parseFloat(String(t));return e>=0&&Math.floor(e)===e&&isFinite(t)}function d(t){return r(t)&&"function"==typeof t.then&&"function"==typeof t.catch}function f(t){return null==t?"":Array.isArray(t)||c(t)&&t.toString===l?JSON.stringify(t,null,2):String(t)}function h(t){var e=parseFloat(t);return isNaN(e)?t:e}function p(t,e){for(var n=Object.create(null),r=t.split(","),i=0;i-1)return t.splice(r,1)}}var y=Object.prototype.hasOwnProperty;function b(t,e){return y.call(t,e)}function w(t){var e=Object.create(null);return function(n){return e[n]||(e[n]=t(n))}}var x=/-(\w)/g,k=w((function(t){return t.replace(x,(function(t,e){return e?e.toUpperCase():""}))})),S=w((function(t){return t.charAt(0).toUpperCase()+t.slice(1)})),O=/\B([A-Z])/g,_=w((function(t){return t.replace(O,"-$1").toLowerCase()}));var M=Function.prototype.bind?function(t,e){return t.bind(e)}:function(t,e){function n(n){var r=arguments.length;return r?r>1?t.apply(e,arguments):t.call(e,n):t.call(e)}return n._length=t.length,n};function C(t,e){e=e||0;for(var n=t.length-e,r=new Array(n);n--;)r[n]=t[n+e];return r}function $(t,e){for(var n in e)t[n]=e[n];return t}function N(t){for(var e={},n=0;n0,Y=H&&H.indexOf("edge/")>0;H&&H.indexOf("android");var G=H&&/iphone|ipad|ipod|ios/.test(H);H&&/chrome\/\d+/.test(H),H&&/phantomjs/.test(H);var Z,X=H&&H.match(/firefox\/(\d+)/),Q={}.watch,tt=!1;if(W)try{var et={};Object.defineProperty(et,"passive",{get:function(){tt=!0}}),window.addEventListener("test-passive",null,et)}catch(Tg){}var nt=function(){return void 0===Z&&(Z=!W&&"undefined"!=typeof global&&(global.process&&"server"===global.process.env.VUE_ENV)),Z},rt=W&&window.__VUE_DEVTOOLS_GLOBAL_HOOK__;function it(t){return"function"==typeof t&&/native code/.test(t.toString())}var ot,st="undefined"!=typeof Symbol&&it(Symbol)&&"undefined"!=typeof Reflect&&it(Reflect.ownKeys);ot="undefined"!=typeof Set&&it(Set)?Set:function(){function t(){this.set=Object.create(null)}return t.prototype.has=function(t){return!0===this.set[t]},t.prototype.add=function(t){this.set[t]=!0},t.prototype.clear=function(){this.set=Object.create(null)},t}();var at=null;function lt(t){void 0===t&&(t=null),t||at&&at._scope.off(),at=t,t&&t._scope.on()}var ct=function(){function t(t,e,n,r,i,o,s,a){this.tag=t,this.data=e,this.children=n,this.text=r,this.elm=i,this.ns=void 0,this.context=o,this.fnContext=void 0,this.fnOptions=void 0,this.fnScopeId=void 0,this.key=e&&e.key,this.componentOptions=s,this.componentInstance=void 0,this.parent=void 0,this.raw=!1,this.isStatic=!1,this.isRootInsert=!0,this.isComment=!1,this.isCloned=!1,this.isOnce=!1,this.asyncFactory=a,this.asyncMeta=void 0,this.isAsyncPlaceholder=!1}return Object.defineProperty(t.prototype,"child",{get:function(){return this.componentInstance},enumerable:!1,configurable:!0}),t}(),ut=function(t){void 0===t&&(t="");var e=new ct;return e.text=t,e.isComment=!0,e};function dt(t){return new ct(void 0,void 0,void 0,String(t))}function ft(t){var e=new ct(t.tag,t.data,t.children&&t.children.slice(),t.text,t.elm,t.context,t.componentOptions,t.asyncFactory);return e.ns=t.ns,e.isStatic=t.isStatic,e.key=t.key,e.isComment=t.isComment,e.fnContext=t.fnContext,e.fnOptions=t.fnOptions,e.fnScopeId=t.fnScopeId,e.asyncMeta=t.asyncMeta,e.isCloned=!0,e}var ht=0,pt=[],mt=function(){function t(){this._pending=!1,this.id=ht++,this.subs=[]}return t.prototype.addSub=function(t){this.subs.push(t)},t.prototype.removeSub=function(t){this.subs[this.subs.indexOf(t)]=null,this._pending||(this._pending=!0,pt.push(this))},t.prototype.depend=function(e){t.target&&t.target.addDep(this)},t.prototype.notify=function(t){for(var e=this.subs.filter((function(t){return t})),n=0,r=e.length;n0&&(Vt((l=qt(l,"".concat(s||"","_").concat(a)))[0])&&Vt(u)&&(d[c]=dt(u.text+l[0].text),l.shift()),d.push.apply(d,l)):o(l)?Vt(u)?d[c]=dt(u.text+l):""!==l&&d.push(dt(l)):Vt(l)&&Vt(u)?d[c]=dt(u.text+l.text):(i(t._isVList)&&r(l.tag)&&n(l.key)&&r(s)&&(l.key="__vlist".concat(s,"_").concat(a,"__")),d.push(l)));return d}function Jt(t,n,l,c,u,d){return(e(l)||o(l))&&(u=c,c=l,l=void 0),i(d)&&(u=2),function(t,n,i,o,l){if(r(i)&&r(i.__ob__))return ut();r(i)&&r(i.is)&&(n=i.is);if(!n)return ut();e(o)&&s(o[0])&&((i=i||{}).scopedSlots={default:o[0]},o.length=0);2===l?o=Bt(o):1===l&&(o=function(t){for(var n=0;n0,a=n?!!n.$stable:!s,l=n&&n.$key;if(n){if(n._normalized)return n._normalized;if(a&&i&&i!==t&&l===i.$key&&!s&&!i.$hasNormal)return i;for(var c in o={},n)n[c]&&"$"!==c[0]&&(o[c]=de(e,r,c,n[c]))}else o={};for(var u in r)u in o||(o[u]=fe(r,u));return n&&Object.isExtensible(n)&&(n._normalized=o),V(o,"$stable",a),V(o,"$key",l),V(o,"$hasNormal",s),o}function de(t,n,r,i){var o=function(){var n=at;lt(t);var r=arguments.length?i.apply(null,arguments):i({}),o=(r=r&&"object"==typeof r&&!e(r)?[r]:Bt(r))&&r[0];return lt(n),r&&(!o||1===r.length&&o.isComment&&!ce(o))?void 0:r};return i.proxy&&Object.defineProperty(n,r,{get:o,enumerable:!0,configurable:!0}),o}function fe(t,e){return function(){return t[e]}}function he(e){var n=e.$options,r=n.setup;if(r){var i=e._setupContext=function(e){return{get attrs(){if(!e._attrsProxy){var n=e._attrsProxy={};V(n,"_v_attr_proxy",!0),pe(n,e.$attrs,t,e,"$attrs")}return e._attrsProxy},get listeners(){e._listenersProxy||pe(e._listenersProxy={},e.$listeners,t,e,"$listeners");return e._listenersProxy},get slots(){return function(t){t._slotsProxy||ge(t._slotsProxy={},t.$scopedSlots);return t._slotsProxy}(e)},emit:M(e.$emit,e),expose:function(t){t&&Object.keys(t).forEach((function(n){return It(e,t,n)}))}}}(e);lt(e),vt();var o=He(r,null,[e._props||At({}),i],e,"setup");if(yt(),lt(),s(o))n.render=o;else if(a(o))if(e._setupState=o,o.__sfc){var l=e._setupProxy={};for(var c in o)"__sfc"!==c&&It(l,o,c)}else for(var c in o)B(c)||It(e,o,c)}}function pe(t,e,n,r,i){var o=!1;for(var s in e)s in t?e[s]!==n[s]&&(o=!0):(o=!0,me(t,s,r,i));for(var s in t)s in e||(o=!0,delete t[s]);return o}function me(t,e,n,r){Object.defineProperty(t,e,{enumerable:!0,configurable:!0,get:function(){return n[r][e]}})}function ge(t,e){for(var n in e)t[n]=e[n];for(var n in t)n in e||delete t[n]}var ve,ye=null;function be(t,e){return(t.__esModule||st&&"Module"===t[Symbol.toStringTag])&&(t=t.default),a(t)?e.extend(t):t}function we(t){if(e(t))for(var n=0;ndocument.createEvent("Event").timeStamp&&(je=function(){return Fe.now()})}var Le,Be=function(t,e){if(t.post){if(!e.post)return 1}else if(e.post)return-1;return t.id-e.id};function Ve(){var t,e;for(ze=je(),Ie=!0,De.sort(Be),Re=0;ReRe&&De[n].id>t.id;)n--;De.splice(n+1,0,t)}else De.push(t);Pe||(Pe=!0,on(Ve))}}(this)},t.prototype.run=function(){if(this.active){var t=this.get();if(t!==this.value||a(t)||this.deep){var e=this.value;if(this.value=t,this.user){var n='callback for watcher "'.concat(this.expression,'"');He(this.cb,this.vm,[t,e],this.vm,n)}else this.cb.call(this.vm,t,e)}}},t.prototype.evaluate=function(){this.value=this.get(),this.dirty=!1},t.prototype.depend=function(){for(var t=this.deps.length;t--;)this.deps[t].depend()},t.prototype.teardown=function(){if(this.vm&&!this.vm._isBeingDestroyed&&v(this.vm._scope.effects,this),this.active){for(var t=this.deps.length;t--;)this.deps[t].removeSub(this);this.active=!1,this.onStop&&this.onStop()}},t}(),dn={enumerable:!0,configurable:!0,get:T,set:T};function fn(t,e,n){dn.get=function(){return this[e][n]},dn.set=function(t){this[e][n]=t},Object.defineProperty(t,n,dn)}function hn(t){var n=t.$options;if(n.props&&function(t,e){var n=t.$options.propsData||{},r=t._props=At({}),i=t.$options._propKeys=[];t.$parent&&Ot(!1);var o=function(o){i.push(o);var s=Ln(o,e,n,t);$t(r,o,s),o in t||fn(t,"_props",o)};for(var s in e)o(s);Ot(!0)}(t,n.props),he(t),n.methods&&function(t,e){for(var n in t.$options.props,e)t[n]="function"!=typeof e[n]?T:M(e[n],t)}(t,n.methods),n.data)!function(t){var e=t.$options.data;c(e=t._data=s(e)?function(t,e){vt();try{return t.call(e,e)}catch(Tg){return We(Tg,e,"data()"),{}}finally{yt()}}(e,t):e||{})||(e={});var n=Object.keys(e),r=t.$options.props;t.$options.methods;var i=n.length;for(;i--;){var o=n[i];r&&b(r,o)||B(o)||fn(t,"_data",o)}var a=Ct(e);a&&a.vmCount++}(t);else{var r=Ct(t._data={});r&&r.vmCount++}n.computed&&function(t,e){var n=t._computedWatchers=Object.create(null),r=nt();for(var i in e){var o=e[i],a=s(o)?o:o.get;r||(n[i]=new un(t,a||T,T,pn)),i in t||mn(t,i,o)}}(t,n.computed),n.watch&&n.watch!==Q&&function(t,n){for(var r in n){var i=n[r];if(e(i))for(var o=0;o-1)if(o&&!b(i,"default"))a=!1;else if(""===a||a===_(t)){var c=Jn(String,i.type);(c<0||l-1:"string"==typeof t?t.split(",").indexOf(n)>-1:(r=t,"[object RegExp]"===l.call(r)&&t.test(n));var r}function Yn(t,e){var n=t.cache,r=t.keys,i=t._vnode;for(var o in n){var s=n[o];if(s){var a=s.name;a&&!e(a)&&Gn(n,o,r,i)}}}function Gn(t,e,n,r){var i=t[e];!i||r&&i.tag===r.tag||i.componentInstance.$destroy(),t[e]=null,v(n,e)}Wn.prototype._init=function(e){var n=this;n._uid=xn++,n._isVue=!0,n.__v_skip=!0,n._scope=new qe(!0),n._scope._vm=!0,e&&e._isComponent?function(t,e){var n=t.$options=Object.create(t.constructor.options),r=e._parentVnode;n.parent=e.parent,n._parentVnode=r;var i=r.componentOptions;n.propsData=i.propsData,n._parentListeners=i.listeners,n._renderChildren=i.children,n._componentTag=i.tag,e.render&&(n.render=e.render,n.staticRenderFns=e.staticRenderFns)}(n,e):n.$options=jn(kn(n.constructor),e||{},n),n._renderProxy=n,n._self=n,function(t){var e=t.$options,n=e.parent;if(n&&!e.abstract){for(;n.$options.abstract&&n.$parent;)n=n.$parent;n.$children.push(t)}t.$parent=n,t.$root=n?n.$root:t,t.$children=[],t.$refs={},t._provided=n?n._provided:Object.create(null),t._watcher=null,t._inactive=null,t._directInactive=!1,t._isMounted=!1,t._isDestroyed=!1,t._isBeingDestroyed=!1}(n),function(t){t._events=Object.create(null),t._hasHookEvent=!1;var e=t.$options._parentListeners;e&&Oe(t,e)}(n),function(e){e._vnode=null,e._staticTrees=null;var n=e.$options,r=e.$vnode=n._parentVnode,i=r&&r.context;e.$slots=ae(n._renderChildren,i),e.$scopedSlots=r?ue(e.$parent,r.data.scopedSlots,e.$slots):t,e._c=function(t,n,r,i){return Jt(e,t,n,r,i,!1)},e.$createElement=function(t,n,r,i){return Jt(e,t,n,r,i,!0)};var o=r&&r.data;$t(e,"$attrs",o&&o.attrs||t,null,!0),$t(e,"$listeners",n._parentListeners||t,null,!0)}(n),Te(n,"beforeCreate",void 0,!1),function(t){var e=wn(t.$options.inject,t);e&&(Ot(!1),Object.keys(e).forEach((function(n){$t(t,n,e[n])})),Ot(!0))}(n),hn(n),bn(n),Te(n,"created"),n.$options.el&&n.$mount(n.$options.el)},function(t){var e={get:function(){return this._data}},n={get:function(){return this._props}};Object.defineProperty(t.prototype,"$data",e),Object.defineProperty(t.prototype,"$props",n),t.prototype.$set=Nt,t.prototype.$delete=Tt,t.prototype.$watch=function(t,e,n){var r=this;if(c(e))return yn(r,t,e,n);(n=n||{}).user=!0;var i=new un(r,t,e,n);if(n.immediate){var o='callback for immediate watcher "'.concat(i.expression,'"');vt(),He(e,r,[i.value],r,o),yt()}return function(){i.teardown()}}}(Wn),function(t){var n=/^hook:/;t.prototype.$on=function(t,r){var i=this;if(e(t))for(var o=0,s=t.length;o1?C(n):n;for(var r=C(arguments,1),i='event handler for "'.concat(t,'"'),o=0,s=n.length;oparseInt(this.max)&&Gn(e,n[0],n,this._vnode),this.vnodeToCache=null}}},created:function(){this.cache=Object.create(null),this.keys=[]},destroyed:function(){for(var t in this.cache)Gn(this.cache,t,this.keys)},mounted:function(){var t=this;this.cacheVNode(),this.$watch("include",(function(e){Yn(t,(function(t){return Un(e,t)}))})),this.$watch("exclude",(function(e){Yn(t,(function(t){return!Un(e,t)}))}))},updated:function(){this.cacheVNode()},render:function(){var t=this.$slots.default,e=we(t),n=e&&e.componentOptions;if(n){var r=Kn(n),i=this.include,o=this.exclude;if(i&&(!r||!Un(i,r))||o&&r&&Un(o,r))return e;var s=this.cache,a=this.keys,l=null==e.key?n.Ctor.cid+(n.tag?"::".concat(n.tag):""):e.key;s[l]?(e.componentInstance=s[l].componentInstance,v(a,l),a.push(l)):(this.vnodeToCache=e,this.keyToCache=l),e.data.keepAlive=!0}return e||t&&t[0]}}};!function(t){var e={get:function(){return F}};Object.defineProperty(t,"config",e),t.util={warn:Dn,extend:$,mergeOptions:jn,defineReactive:$t},t.set=Nt,t.delete=Tt,t.nextTick=on,t.observable=function(t){return Ct(t),t},t.options=Object.create(null),z.forEach((function(e){t.options[e+"s"]=Object.create(null)})),t.options._base=t,$(t.options.components,Xn),function(t){t.use=function(t){var e=this._installedPlugins||(this._installedPlugins=[]);if(e.indexOf(t)>-1)return this;var n=C(arguments,1);return n.unshift(this),s(t.install)?t.install.apply(t,n):s(t)&&t.apply(null,n),e.push(t),this}}(t),function(t){t.mixin=function(t){return this.options=jn(this.options,t),this}}(t),Hn(t),function(t){z.forEach((function(e){t[e]=function(t,n){return n?("component"===e&&c(n)&&(n.name=n.name||t,n=this.options._base.extend(n)),"directive"===e&&s(n)&&(n={bind:n,update:n}),this.options[e+"s"][t]=n,n):this.options[e+"s"][t]}}))}(t)}(Wn),Object.defineProperty(Wn.prototype,"$isServer",{get:nt}),Object.defineProperty(Wn.prototype,"$ssrContext",{get:function(){return this.$vnode&&this.$vnode.ssrContext}}),Object.defineProperty(Wn,"FunctionalRenderContext",{value:Sn}),Wn.version="2.7.14";var Qn=p("style,class"),tr=p("input,textarea,option,select,progress"),er=function(t,e,n){return"value"===n&&tr(t)&&"button"!==e||"selected"===n&&"option"===t||"checked"===n&&"input"===t||"muted"===n&&"video"===t},nr=p("contenteditable,draggable,spellcheck"),rr=p("events,caret,typing,plaintext-only"),ir=p("allowfullscreen,async,autofocus,autoplay,checked,compact,controls,declare,default,defaultchecked,defaultmuted,defaultselected,defer,disabled,enabled,formnovalidate,hidden,indeterminate,inert,ismap,itemscope,loop,multiple,muted,nohref,noresize,noshade,novalidate,nowrap,open,pauseonexit,readonly,required,reversed,scoped,seamless,selected,sortable,truespeed,typemustmatch,visible"),or="http://www.w3.org/1999/xlink",sr=function(t){return":"===t.charAt(5)&&"xlink"===t.slice(0,5)},ar=function(t){return sr(t)?t.slice(6,t.length):""},lr=function(t){return null==t||!1===t};function cr(t){for(var e=t.data,n=t,i=t;r(i.componentInstance);)(i=i.componentInstance._vnode)&&i.data&&(e=ur(i.data,e));for(;r(n=n.parent);)n&&n.data&&(e=ur(e,n.data));return function(t,e){if(r(t)||r(e))return dr(t,fr(e));return""}(e.staticClass,e.class)}function ur(t,e){return{staticClass:dr(t.staticClass,e.staticClass),class:r(t.class)?[t.class,e.class]:e.class}}function dr(t,e){return t?e?t+" "+e:t:e||""}function fr(t){return Array.isArray(t)?function(t){for(var e,n="",i=0,o=t.length;i-1?jr(t,e,n):ir(e)?lr(n)?t.removeAttribute(e):(n="allowfullscreen"===e&&"EMBED"===t.tagName?"true":e,t.setAttribute(e,n)):nr(e)?t.setAttribute(e,function(t,e){return lr(e)||"false"===e?"false":"contenteditable"===t&&rr(e)?e:"true"}(e,n)):sr(e)?lr(n)?t.removeAttributeNS(or,ar(e)):t.setAttributeNS(or,e,n):jr(t,e,n)}function jr(t,e,n){if(lr(n))t.removeAttribute(e);else{if(K&&!U&&"TEXTAREA"===t.tagName&&"placeholder"===e&&""!==n&&!t.__ieph){var r=function(e){e.stopImmediatePropagation(),t.removeEventListener("input",r)};t.addEventListener("input",r),t.__ieph=!0}t.setAttribute(e,n)}}var Fr={create:Rr,update:Rr};function Lr(t,e){var i=e.elm,o=e.data,s=t.data;if(!(n(o.staticClass)&&n(o.class)&&(n(s)||n(s.staticClass)&&n(s.class)))){var a=cr(e),l=i._transitionClasses;r(l)&&(a=dr(a,fr(l))),a!==i._prevClass&&(i.setAttribute("class",a),i._prevClass=a)}}var Br,Vr,qr,Jr,Wr,Hr,Kr={create:Lr,update:Lr},Ur=/[\w).+\-_$\]]/;function Yr(t){var e,n,r,i,o,s=!1,a=!1,l=!1,c=!1,u=0,d=0,f=0,h=0;for(r=0;r=0&&" "===(m=t.charAt(p));p--);m&&Ur.test(m)||(c=!0)}}else void 0===i?(h=r+1,i=t.slice(0,r).trim()):g();function g(){(o||(o=[])).push(t.slice(h,r).trim()),h=r+1}if(void 0===i?i=t.slice(0,r).trim():0!==h&&g(),o)for(r=0;r-1?{exp:t.slice(0,Jr),key:'"'+t.slice(Jr+1)+'"'}:{exp:t,key:null};Vr=t,Jr=Wr=Hr=0;for(;!fi();)hi(qr=di())?mi(qr):91===qr&&pi(qr);return{exp:t.slice(0,Wr),key:t.slice(Wr+1,Hr)}}(t);return null===n.key?"".concat(t,"=").concat(e):"$set(".concat(n.exp,", ").concat(n.key,", ").concat(e,")")}function di(){return Vr.charCodeAt(++Jr)}function fi(){return Jr>=Br}function hi(t){return 34===t||39===t}function pi(t){var e=1;for(Wr=Jr;!fi();)if(hi(t=di()))mi(t);else if(91===t&&e++,93===t&&e--,0===e){Hr=Jr;break}}function mi(t){for(var e=t;!fi()&&(t=di())!==e;);}var gi;function vi(t,e,n){var r=gi;return function i(){var o=e.apply(null,arguments);null!==o&&wi(t,i,n,r)}}var yi=Ge&&!(X&&Number(X[1])<=53);function bi(t,e,n,r){if(yi){var i=ze,o=e;e=o._wrapper=function(t){if(t.target===t.currentTarget||t.timeStamp>=i||t.timeStamp<=0||t.target.ownerDocument!==document)return o.apply(this,arguments)}}gi.addEventListener(t,e,tt?{capture:n,passive:r}:n)}function wi(t,e,n,r){(r||gi).removeEventListener(t,e._wrapper||e,n)}function xi(t,e){if(!n(t.data.on)||!n(e.data.on)){var i=e.data.on||{},o=t.data.on||{};gi=e.elm||t.elm,function(t){if(r(t.__r)){var e=K?"change":"input";t[e]=[].concat(t.__r,t[e]||[]),delete t.__r}r(t.__c)&&(t.change=[].concat(t.__c,t.change||[]),delete t.__c)}(i),jt(i,o,bi,wi,vi,e.context),gi=void 0}}var ki,Si={create:xi,update:xi,destroy:function(t){return xi(t,_r)}};function Oi(t,e){if(!n(t.data.domProps)||!n(e.data.domProps)){var o,s,a=e.elm,l=t.data.domProps||{},c=e.data.domProps||{};for(o in(r(c.__ob__)||i(c._v_attr_proxy))&&(c=e.data.domProps=$({},c)),l)o in c||(a[o]="");for(o in c){if(s=c[o],"textContent"===o||"innerHTML"===o){if(e.children&&(e.children.length=0),s===l[o])continue;1===a.childNodes.length&&a.removeChild(a.childNodes[0])}if("value"===o&&"PROGRESS"!==a.tagName){a._value=s;var u=n(s)?"":String(s);_i(a,u)&&(a.value=u)}else if("innerHTML"===o&&mr(a.tagName)&&n(a.innerHTML)){(ki=ki||document.createElement("div")).innerHTML="".concat(s,"");for(var d=ki.firstChild;a.firstChild;)a.removeChild(a.firstChild);for(;d.firstChild;)a.appendChild(d.firstChild)}else if(s!==l[o])try{a[o]=s}catch(Tg){}}}}function _i(t,e){return!t.composing&&("OPTION"===t.tagName||function(t,e){var n=!0;try{n=document.activeElement!==t}catch(Tg){}return n&&t.value!==e}(t,e)||function(t,e){var n=t.value,i=t._vModifiers;if(r(i)){if(i.number)return h(n)!==h(e);if(i.trim)return n.trim()!==e.trim()}return n!==e}(t,e))}var Mi={create:Oi,update:Oi},Ci=w((function(t){var e={},n=/:(.+)/;return t.split(/;(?![^(]*\))/g).forEach((function(t){if(t){var r=t.split(n);r.length>1&&(e[r[0].trim()]=r[1].trim())}})),e}));function $i(t){var e=Ni(t.style);return t.staticStyle?$(t.staticStyle,e):e}function Ni(t){return Array.isArray(t)?N(t):"string"==typeof t?Ci(t):t}var Ti,Di=/^--/,Ai=/\s*!important$/,Ei=function(t,e,n){if(Di.test(e))t.style.setProperty(e,n);else if(Ai.test(n))t.style.setProperty(_(e),n.replace(Ai,""),"important");else{var r=Ii(e);if(Array.isArray(n))for(var i=0,o=n.length;i-1?e.split(ji).forEach((function(e){return t.classList.add(e)})):t.classList.add(e);else{var n=" ".concat(t.getAttribute("class")||""," ");n.indexOf(" "+e+" ")<0&&t.setAttribute("class",(n+e).trim())}}function Li(t,e){if(e&&(e=e.trim()))if(t.classList)e.indexOf(" ")>-1?e.split(ji).forEach((function(e){return t.classList.remove(e)})):t.classList.remove(e),t.classList.length||t.removeAttribute("class");else{for(var n=" ".concat(t.getAttribute("class")||""," "),r=" "+e+" ";n.indexOf(r)>=0;)n=n.replace(r," ");(n=n.trim())?t.setAttribute("class",n):t.removeAttribute("class")}}function Bi(t){if(t){if("object"==typeof t){var e={};return!1!==t.css&&$(e,Vi(t.name||"v")),$(e,t),e}return"string"==typeof t?Vi(t):void 0}}var Vi=w((function(t){return{enterClass:"".concat(t,"-enter"),enterToClass:"".concat(t,"-enter-to"),enterActiveClass:"".concat(t,"-enter-active"),leaveClass:"".concat(t,"-leave"),leaveToClass:"".concat(t,"-leave-to"),leaveActiveClass:"".concat(t,"-leave-active")}})),qi=W&&!U,Ji="transition",Wi="transitionend",Hi="animation",Ki="animationend";qi&&(void 0===window.ontransitionend&&void 0!==window.onwebkittransitionend&&(Ji="WebkitTransition",Wi="webkitTransitionEnd"),void 0===window.onanimationend&&void 0!==window.onwebkitanimationend&&(Hi="WebkitAnimation",Ki="webkitAnimationEnd"));var Ui=W?window.requestAnimationFrame?window.requestAnimationFrame.bind(window):setTimeout:function(t){return t()};function Yi(t){Ui((function(){Ui(t)}))}function Gi(t,e){var n=t._transitionClasses||(t._transitionClasses=[]);n.indexOf(e)<0&&(n.push(e),Fi(t,e))}function Zi(t,e){t._transitionClasses&&v(t._transitionClasses,e),Li(t,e)}function Xi(t,e,n){var r=to(t,e),i=r.type,o=r.timeout,s=r.propCount;if(!i)return n();var a="transition"===i?Wi:Ki,l=0,c=function(){t.removeEventListener(a,u),n()},u=function(e){e.target===t&&++l>=s&&c()};setTimeout((function(){l0&&(n="transition",u=s,d=o.length):"animation"===e?c>0&&(n="animation",u=c,d=l.length):d=(n=(u=Math.max(s,c))>0?s>c?"transition":"animation":null)?"transition"===n?o.length:l.length:0,{type:n,timeout:u,propCount:d,hasTransform:"transition"===n&&Qi.test(r[Ji+"Property"])}}function eo(t,e){for(;t.length1}function ao(t,e){!0!==e.data.show&&ro(e)}var lo=function(t){var s,a,l={},c=t.modules,u=t.nodeOps;for(s=0;sp?w(t,n(i[v+1])?null:i[v+1].elm,i,h,v,o):h>v&&k(e,d,p)}(d,m,g,o,c):r(g)?(r(t.text)&&u.setTextContent(d,""),w(d,null,g,0,g.length-1,o)):r(m)?k(m,0,m.length-1):r(t.text)&&u.setTextContent(d,""):t.text!==e.text&&u.setTextContent(d,e.text),r(p)&&r(h=p.hook)&&r(h=h.postpatch)&&h(t,e)}}}function M(t,e,n){if(i(n)&&r(t.parent))t.parent.data.pendingInsert=e;else for(var o=0;o-1,s.selected!==o&&(s.selected=o);else if(E(po(s),r))return void(t.selectedIndex!==a&&(t.selectedIndex=a));i||(t.selectedIndex=-1)}}function ho(t,e){return e.every((function(e){return!E(e,t)}))}function po(t){return"_value"in t?t._value:t.value}function mo(t){t.target.composing=!0}function go(t){t.target.composing&&(t.target.composing=!1,vo(t.target,"input"))}function vo(t,e){var n=document.createEvent("HTMLEvents");n.initEvent(e,!0,!0),t.dispatchEvent(n)}function yo(t){return!t.componentInstance||t.data&&t.data.transition?t:yo(t.componentInstance._vnode)}var bo={model:co,show:{bind:function(t,e,n){var r=e.value,i=(n=yo(n)).data&&n.data.transition,o=t.__vOriginalDisplay="none"===t.style.display?"":t.style.display;r&&i?(n.data.show=!0,ro(n,(function(){t.style.display=o}))):t.style.display=r?o:"none"},update:function(t,e,n){var r=e.value;!r!=!e.oldValue&&((n=yo(n)).data&&n.data.transition?(n.data.show=!0,r?ro(n,(function(){t.style.display=t.__vOriginalDisplay})):io(n,(function(){t.style.display="none"}))):t.style.display=r?t.__vOriginalDisplay:"none")},unbind:function(t,e,n,r,i){i||(t.style.display=t.__vOriginalDisplay)}}},wo={name:String,appear:Boolean,css:Boolean,mode:String,type:String,enterClass:String,leaveClass:String,enterToClass:String,leaveToClass:String,enterActiveClass:String,leaveActiveClass:String,appearClass:String,appearActiveClass:String,appearToClass:String,duration:[Number,String,Object]};function xo(t){var e=t&&t.componentOptions;return e&&e.Ctor.options.abstract?xo(we(e.children)):t}function ko(t){var e={},n=t.$options;for(var r in n.propsData)e[r]=t[r];var i=n._parentListeners;for(var r in i)e[k(r)]=i[r];return e}function So(t,e){if(/\d-keep-alive$/.test(e.tag))return t("keep-alive",{props:e.componentOptions.propsData})}var Oo=function(t){return t.tag||ce(t)},_o=function(t){return"show"===t.name},Mo={name:"transition",props:wo,abstract:!0,render:function(t){var e=this,n=this.$slots.default;if(n&&(n=n.filter(Oo)).length){var r=this.mode,i=n[0];if(function(t){for(;t=t.parent;)if(t.data.transition)return!0}(this.$vnode))return i;var s=xo(i);if(!s)return i;if(this._leaving)return So(t,i);var a="__transition-".concat(this._uid,"-");s.key=null==s.key?s.isComment?a+"comment":a+s.tag:o(s.key)?0===String(s.key).indexOf(a)?s.key:a+s.key:s.key;var l=(s.data||(s.data={})).transition=ko(this),c=this._vnode,u=xo(c);if(s.data.directives&&s.data.directives.some(_o)&&(s.data.show=!0),u&&u.data&&!function(t,e){return e.key===t.key&&e.tag===t.tag}(s,u)&&!ce(u)&&(!u.componentInstance||!u.componentInstance._vnode.isComment)){var d=u.data.transition=$({},l);if("out-in"===r)return this._leaving=!0,Ft(d,"afterLeave",(function(){e._leaving=!1,e.$forceUpdate()})),So(t,i);if("in-out"===r){if(ce(s))return c;var f,h=function(){f()};Ft(l,"afterEnter",h),Ft(l,"enterCancelled",h),Ft(d,"delayLeave",(function(t){f=t}))}}return i}}},Co=$({tag:String,moveClass:String},wo);function $o(t){t.elm._moveCb&&t.elm._moveCb(),t.elm._enterCb&&t.elm._enterCb()}function No(t){t.data.newPos=t.elm.getBoundingClientRect()}function To(t){var e=t.data.pos,n=t.data.newPos,r=e.left-n.left,i=e.top-n.top;if(r||i){t.data.moved=!0;var o=t.elm.style;o.transform=o.WebkitTransform="translate(".concat(r,"px,").concat(i,"px)"),o.transitionDuration="0s"}}delete Co.mode;var Do={Transition:Mo,TransitionGroup:{props:Co,beforeMount:function(){var t=this,e=this._update;this._update=function(n,r){var i=Me(t);t.__patch__(t._vnode,t.kept,!1,!0),t._vnode=t.kept,i(),e.call(t,n,r)}},render:function(t){for(var e=this.tag||this.$vnode.data.tag||"span",n=Object.create(null),r=this.prevChildren=this.children,i=this.$slots.default||[],o=this.children=[],s=ko(this),a=0;a-1?yr[t]=e.constructor===window.HTMLUnknownElement||e.constructor===window.HTMLElement:yr[t]=/HTMLUnknownElement/.test(e.toString())},$(Wn.options.directives,bo),$(Wn.options.components,Do),Wn.prototype.__patch__=W?lo:T,Wn.prototype.$mount=function(t,e){return function(t,e,n){var r;t.$el=e,t.$options.render||(t.$options.render=ut),Te(t,"beforeMount"),r=function(){t._update(t._render(),n)},new un(t,r,T,{before:function(){t._isMounted&&!t._isDestroyed&&Te(t,"beforeUpdate")}},!0),n=!1;var i=t._preWatchers;if(i)for(var o=0;o\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,qo=/^\s*((?:v-[\w-]+:|@|:|#)\[[^=]+?\][^\s"'<>\/=]*)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/,Jo="[a-zA-Z_][\\-\\.0-9_a-zA-Z".concat(L.source,"]*"),Wo="((?:".concat(Jo,"\\:)?").concat(Jo,")"),Ho=new RegExp("^<".concat(Wo)),Ko=/^\s*(\/?)>/,Uo=new RegExp("^<\\/".concat(Wo,"[^>]*>")),Yo=/^]+>/i,Go=/^",""":'"',"&":"&"," ":"\n"," ":"\t","'":"'"},es=/&(?:lt|gt|quot|amp|#39);/g,ns=/&(?:lt|gt|quot|amp|#39|#10|#9);/g,rs=p("pre,textarea",!0),is=function(t,e){return t&&rs(t)&&"\n"===e[0]};function ss(t,e){var n=e?ns:es;return t.replace(n,(function(t){return ts[t]}))}function as(t,e){for(var n,r,i=[],o=e.expectHTML,s=e.isUnaryTag||D,a=e.canBeLeftOpenTag||D,l=0,c=function(){if(n=t,r&&Xo(r)){var c=0,f=r.toLowerCase(),h=Qo[f]||(Qo[f]=new RegExp("([\\s\\S]*?)(]*>)","i"));k=t.replace(h,(function(t,n,r){return c=r.length,Xo(f)||"noscript"===f||(n=n.replace(//g,"$1").replace(//g,"$1")),is(f,n)&&(n=n.slice(1)),e.chars&&e.chars(n),""}));l+=t.length-k.length,t=k,d(f,l-c,l)}else{var p=t.indexOf("<");if(0===p){if(Go.test(t)){var m=t.indexOf("--\x3e");if(m>=0)return e.shouldKeepComment&&e.comment&&e.comment(t.substring(4,m),l,l+m+3),u(m+3),"continue"}if(Zo.test(t)){var g=t.indexOf("]>");if(g>=0)return u(g+2),"continue"}var v=t.match(Yo);if(v)return u(v[0].length),"continue";var y=t.match(Uo);if(y){var b=l;return u(y[0].length),d(y[1],b,l),"continue"}var w=function(){var e=t.match(Ho);if(e){var n={tagName:e[1],attrs:[],start:l};u(e[0].length);for(var r=void 0,i=void 0;!(r=t.match(Ko))&&(i=t.match(qo)||t.match(Vo));)i.start=l,u(i[0].length),i.end=l,n.attrs.push(i);if(r)return n.unarySlash=r[1],u(r[0].length),n.end=l,n}}();if(w)return function(t){var n=t.tagName,l=t.unarySlash;o&&("p"===r&&Bo(n)&&d(r),a(n)&&r===n&&d(n));for(var c=s(n)||!!l,u=t.attrs.length,f=new Array(u),h=0;h=0){for(k=t.slice(p);!(Uo.test(k)||Ho.test(k)||Go.test(k)||Zo.test(k)||(S=k.indexOf("<",1))<0);)p+=S,k=t.slice(p);x=t.substring(0,p)}p<0&&(x=t),x&&u(x.length),e.chars&&x&&e.chars(x,l-x.length,l)}if(t===n)return e.chars&&e.chars(t),"break"};t;){if("break"===c())break}function u(e){l+=e,t=t.substring(e)}function d(t,n,o){var s,a;if(null==n&&(n=l),null==o&&(o=l),t)for(a=t.toLowerCase(),s=i.length-1;s>=0&&i[s].lowerCasedTag!==a;s--);else s=0;if(s>=0){for(var c=i.length-1;c>=s;c--)e.end&&e.end(i[c].tag,n,o);i.length=s,r=s&&i[s-1].tag}else"br"===a?e.start&&e.start(t,[],!0,n,o):"p"===a&&(e.start&&e.start(t,[],!1,n,o),e.end&&e.end(t,n,o))}d()}var ls,cs,us,ds,fs,hs,ps,ms,gs=/^@|^v-on:/,vs=/^v-|^@|^:|^#/,ys=/([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/,bs=/,([^,\}\]]*)(?:,([^,\}\]]*))?$/,ws=/^\(|\)$/g,xs=/^\[.*\]$/,ks=/:(.*)$/,Ss=/^:|^\.|^v-bind:/,Os=/\.[^.\]]+(?=[^\]]*$)/g,_s=/^v-slot(:|$)|^#/,Ms=/[\r\n]/,Cs=/[ \f\t\r\n]+/g,$s=w(jo);function Ns(t,e,n){return{type:1,tag:t,attrsList:e,attrsMap:Rs(e),rawAttrsMap:{},parent:n,children:[]}}function Ts(t,e){ls=e.warn||Zr,hs=e.isPreTag||D,ps=e.mustUseProp||D,ms=e.getTagNamespace||D,e.isReservedTag,us=Xr(e.modules,"transformNode"),ds=Xr(e.modules,"preTransformNode"),fs=Xr(e.modules,"postTransformNode"),cs=e.delimiters;var n,r,i=[],o=!1!==e.preserveWhitespace,s=e.whitespace,a=!1,l=!1;function c(t){if(u(t),a||t.processed||(t=Ds(t,e)),i.length||t===n||n.if&&(t.elseif||t.else)&&Es(n,{exp:t.elseif,block:t}),r&&!t.forbidden)if(t.elseif||t.else)s=t,c=function(t){for(var e=t.length;e--;){if(1===t[e].type)return t[e];t.pop()}}(r.children),c&&c.if&&Es(c,{exp:s.elseif,block:s});else{if(t.slotScope){var o=t.slotTarget||'"default"';(r.scopedSlots||(r.scopedSlots={}))[o]=t}r.children.push(t),t.parent=r}var s,c;t.children=t.children.filter((function(t){return!t.slotScope})),u(t),t.pre&&(a=!1),hs(t.tag)&&(l=!1);for(var d=0;dl&&(a.push(o=t.slice(l,i)),s.push(JSON.stringify(o)));var c=Yr(r[1].trim());s.push("_s(".concat(c,")")),a.push({"@binding":c}),l=i+r[0].length}return l-1")+("true"===o?":(".concat(e,")"):":_q(".concat(e,",").concat(o,")"))),ii(t,"change","var $$a=".concat(e,",")+"$$el=$event.target,"+"$$c=$$el.checked?(".concat(o,"):(").concat(s,");")+"if(Array.isArray($$a)){"+"var $$v=".concat(r?"_n("+i+")":i,",")+"$$i=_i($$a,$$v);"+"if($$el.checked){$$i<0&&(".concat(ui(e,"$$a.concat([$$v])"),")}")+"else{$$i>-1&&(".concat(ui(e,"$$a.slice(0,$$i).concat($$a.slice($$i+1))"),")}")+"}else{".concat(ui(e,"$$c"),"}"),null,!0)}(t,r,i);else if("input"===o&&"radio"===s)!function(t,e,n){var r=n&&n.number,i=oi(t,"value")||"null";i=r?"_n(".concat(i,")"):i,Qr(t,"checked","_q(".concat(e,",").concat(i,")")),ii(t,"change",ui(e,i),null,!0)}(t,r,i);else if("input"===o||"textarea"===o)!function(t,e,n){var r=t.attrsMap.type,i=n||{},o=i.lazy,s=i.number,a=i.trim,l=!o&&"range"!==r,c=o?"change":"range"===r?"__r":"input",u="$event.target.value";a&&(u="$event.target.value.trim()");s&&(u="_n(".concat(u,")"));var d=ui(e,u);l&&(d="if($event.target.composing)return;".concat(d));Qr(t,"value","(".concat(e,")")),ii(t,c,d,null,!0),(a||s)&&ii(t,"blur","$forceUpdate()")}(t,r,i);else if(!F.isReservedTag(o))return ci(t,r,i),!1;return!0},text:function(t,e){e.value&&Qr(t,"textContent","_s(".concat(e.value,")"),e)},html:function(t,e){e.value&&Qr(t,"innerHTML","_s(".concat(e.value,")"),e)}},Ws={expectHTML:!0,modules:Ls,directives:Js,isPreTag:function(t){return"pre"===t},isUnaryTag:Fo,mustUseProp:er,canBeLeftOpenTag:Lo,isReservedTag:gr,getTagNamespace:vr,staticKeys:(Bs=Ls,Bs.reduce((function(t,e){return t.concat(e.staticKeys||[])}),[]).join(","))},Hs=w((function(t){return p("type,tag,attrsList,attrsMap,plain,parent,children,attrs,start,end,rawAttrsMap"+(t?","+t:""))}));function Ks(t,e){t&&(Vs=Hs(e.staticKeys||""),qs=e.isReservedTag||D,Us(t),Ys(t,!1))}function Us(t){if(t.static=function(t){if(2===t.type)return!1;if(3===t.type)return!0;return!(!t.pre&&(t.hasBindings||t.if||t.for||m(t.tag)||!qs(t.tag)||function(t){for(;t.parent;){if("template"!==(t=t.parent).tag)return!1;if(t.for)return!0}return!1}(t)||!Object.keys(t).every(Vs)))}(t),1===t.type){if(!qs(t.tag)&&"slot"!==t.tag&&null==t.attrsMap["inline-template"])return;for(var e=0,n=t.children.length;e|^function(?:\s+[\w$]+)?\s*\(/,Zs=/\([^)]*?\);*$/,Xs=/^[A-Za-z_$][\w$]*(?:\.[A-Za-z_$][\w$]*|\['[^']*?']|\["[^"]*?"]|\[\d+]|\[[A-Za-z_$][\w$]*])*$/,Qs={esc:27,tab:9,enter:13,space:32,up:38,left:37,right:39,down:40,delete:[8,46]},ta={esc:["Esc","Escape"],tab:"Tab",enter:"Enter",space:[" ","Spacebar"],up:["Up","ArrowUp"],left:["Left","ArrowLeft"],right:["Right","ArrowRight"],down:["Down","ArrowDown"],delete:["Backspace","Delete","Del"]},ea=function(t){return"if(".concat(t,")return null;")},na={stop:"$event.stopPropagation();",prevent:"$event.preventDefault();",self:ea("$event.target !== $event.currentTarget"),ctrl:ea("!$event.ctrlKey"),shift:ea("!$event.shiftKey"),alt:ea("!$event.altKey"),meta:ea("!$event.metaKey"),left:ea("'button' in $event && $event.button !== 0"),middle:ea("'button' in $event && $event.button !== 1"),right:ea("'button' in $event && $event.button !== 2")};function ra(t,e){var n=e?"nativeOn:":"on:",r="",i="";for(var o in t){var s=ia(t[o]);t[o]&&t[o].dynamic?i+="".concat(o,",").concat(s,","):r+='"'.concat(o,'":').concat(s,",")}return r="{".concat(r.slice(0,-1),"}"),i?n+"_d(".concat(r,",[").concat(i.slice(0,-1),"])"):n+r}function ia(t){if(!t)return"function(){}";if(Array.isArray(t))return"[".concat(t.map((function(t){return ia(t)})).join(","),"]");var e=Xs.test(t.value),n=Gs.test(t.value),r=Xs.test(t.value.replace(Zs,""));if(t.modifiers){var i="",o="",s=[],a=function(e){if(na[e])o+=na[e],Qs[e]&&s.push(e);else if("exact"===e){var n=t.modifiers;o+=ea(["ctrl","shift","alt","meta"].filter((function(t){return!n[t]})).map((function(t){return"$event.".concat(t,"Key")})).join("||"))}else s.push(e)};for(var l in t.modifiers)a(l);s.length&&(i+=function(t){return"if(!$event.type.indexOf('key')&&"+"".concat(t.map(oa).join("&&"),")return null;")}(s)),o&&(i+=o);var c=e?"return ".concat(t.value,".apply(null, arguments)"):n?"return (".concat(t.value,").apply(null, arguments)"):r?"return ".concat(t.value):t.value;return"function($event){".concat(i).concat(c,"}")}return e||n?t.value:"function($event){".concat(r?"return ".concat(t.value):t.value,"}")}function oa(t){var e=parseInt(t,10);if(e)return"$event.keyCode!==".concat(e);var n=Qs[t],r=ta[t];return"_k($event.keyCode,"+"".concat(JSON.stringify(t),",")+"".concat(JSON.stringify(n),",")+"$event.key,"+"".concat(JSON.stringify(r))+")"}var sa={on:function(t,e){t.wrapListeners=function(t){return"_g(".concat(t,",").concat(e.value,")")}},bind:function(t,e){t.wrapData=function(n){return"_b(".concat(n,",'").concat(t.tag,"',").concat(e.value,",").concat(e.modifiers&&e.modifiers.prop?"true":"false").concat(e.modifiers&&e.modifiers.sync?",true":"",")")}},cloak:T},aa=function(t){this.options=t,this.warn=t.warn||Zr,this.transforms=Xr(t.modules,"transformCode"),this.dataGenFns=Xr(t.modules,"genData"),this.directives=$($({},sa),t.directives);var e=t.isReservedTag||D;this.maybeComponent=function(t){return!!t.component||!e(t.tag)},this.onceId=0,this.staticRenderFns=[],this.pre=!1};function la(t,e){var n=new aa(e),r=t?"script"===t.tag?"null":ca(t,n):'_c("div")';return{render:"with(this){return ".concat(r,"}"),staticRenderFns:n.staticRenderFns}}function ca(t,e){if(t.parent&&(t.pre=t.pre||t.parent.pre),t.staticRoot&&!t.staticProcessed)return ua(t,e);if(t.once&&!t.onceProcessed)return da(t,e);if(t.for&&!t.forProcessed)return pa(t,e);if(t.if&&!t.ifProcessed)return fa(t,e);if("template"!==t.tag||t.slotTarget||e.pre){if("slot"===t.tag)return function(t,e){var n=t.slotName||'"default"',r=ya(t,e),i="_t(".concat(n).concat(r?",function(){return ".concat(r,"}"):""),o=t.attrs||t.dynamicAttrs?xa((t.attrs||[]).concat(t.dynamicAttrs||[]).map((function(t){return{name:k(t.name),value:t.value,dynamic:t.dynamic}}))):null,s=t.attrsMap["v-bind"];!o&&!s||r||(i+=",null");o&&(i+=",".concat(o));s&&(i+="".concat(o?"":",null",",").concat(s));return i+")"}(t,e);var n=void 0;if(t.component)n=function(t,e,n){var r=e.inlineTemplate?null:ya(e,n,!0);return"_c(".concat(t,",").concat(ma(e,n)).concat(r?",".concat(r):"",")")}(t.component,t,e);else{var r=void 0,i=e.maybeComponent(t);(!t.plain||t.pre&&i)&&(r=ma(t,e));var o=void 0,s=e.options.bindings;i&&s&&!1!==s.__isScriptSetup&&(o=function(t,e){var n=k(e),r=S(n),i=function(i){return t[e]===i?e:t[n]===i?n:t[r]===i?r:void 0},o=i("setup-const")||i("setup-reactive-const");if(o)return o;var s=i("setup-let")||i("setup-ref")||i("setup-maybe-ref");if(s)return s}(s,t.tag)),o||(o="'".concat(t.tag,"'"));var a=t.inlineTemplate?null:ya(t,e,!0);n="_c(".concat(o).concat(r?",".concat(r):"").concat(a?",".concat(a):"",")")}for(var l=0;l>>0}(s)):"",")")}(t,t.scopedSlots,e),",")),t.model&&(n+="model:{value:".concat(t.model.value,",callback:").concat(t.model.callback,",expression:").concat(t.model.expression,"},")),t.inlineTemplate){var o=function(t,e){var n=t.children[0];if(n&&1===n.type){var r=la(n,e.options);return"inlineTemplate:{render:function(){".concat(r.render,"},staticRenderFns:[").concat(r.staticRenderFns.map((function(t){return"function(){".concat(t,"}")})).join(","),"]}")}}(t,e);o&&(n+="".concat(o,","))}return n=n.replace(/,$/,"")+"}",t.dynamicAttrs&&(n="_b(".concat(n,',"').concat(t.tag,'",').concat(xa(t.dynamicAttrs),")")),t.wrapData&&(n=t.wrapData(n)),t.wrapListeners&&(n=t.wrapListeners(n)),n}function ga(t){return 1===t.type&&("slot"===t.tag||t.children.some(ga))}function va(t,e){var n=t.attrsMap["slot-scope"];if(t.if&&!t.ifProcessed&&!n)return fa(t,e,va,"null");if(t.for&&!t.forProcessed)return pa(t,e,va);var r="_empty_"===t.slotScope?"":String(t.slotScope),i="function(".concat(r,"){")+"return ".concat("template"===t.tag?t.if&&n?"(".concat(t.if,")?").concat(ya(t,e)||"undefined",":undefined"):ya(t,e)||"undefined":ca(t,e),"}"),o=r?"":",proxy:true";return"{key:".concat(t.slotTarget||'"default"',",fn:").concat(i).concat(o,"}")}function ya(t,e,n,r,i){var o=t.children;if(o.length){var s=o[0];if(1===o.length&&s.for&&"template"!==s.tag&&"slot"!==s.tag){var a=n?e.maybeComponent(s)?",1":",0":"";return"".concat((r||ca)(s,e)).concat(a)}var l=n?function(t,e){for(var n=0,r=0;r':'
',Ma.innerHTML.indexOf(" ")>0}var Ta=!!W&&Na(!1),Da=!!W&&Na(!0),Aa=w((function(t){var e=wr(t);return e&&e.innerHTML})),Ea=Wn.prototype.$mount;function Pa(t){this.content=t}function Ia(t,e,n){for(let r=0;;r++){if(r==t.childCount||r==e.childCount)return t.childCount==e.childCount?null:n;let i=t.child(r),o=e.child(r);if(i!=o){if(!i.sameMarkup(o))return n;if(i.isText&&i.text!=o.text){for(let t=0;i.text[t]==o.text[t];t++)n++;return n}if(i.content.size||o.content.size){let t=Ia(i.content,o.content,n+1);if(null!=t)return t}n+=i.nodeSize}else n+=i.nodeSize}}function Ra(t,e,n,r){for(let i=t.childCount,o=e.childCount;;){if(0==i||0==o)return i==o?null:{a:n,b:r};let s=t.child(--i),a=e.child(--o),l=s.nodeSize;if(s!=a){if(!s.sameMarkup(a))return{a:n,b:r};if(s.isText&&s.text!=a.text){let t=0,e=Math.min(s.text.length,a.text.length);for(;t>1}},Pa.from=function(t){if(t instanceof Pa)return t;var e=[];if(t)for(var n in t)e.push(n,t[n]);return new Pa(e)};class za{constructor(t,e){if(this.content=t,this.size=e||0,null==e)for(let n=0;nt&&!1!==n(a,r+s,i||null,o)&&a.content.size){let i=s+1;a.nodesBetween(Math.max(0,t-i),Math.min(a.content.size,e-i),n,r+i)}s=l}}descendants(t){this.nodesBetween(0,this.size,t)}textBetween(t,e,n,r){let i="",o=!0;return this.nodesBetween(t,e,((s,a)=>{s.isText?(i+=s.text.slice(Math.max(t,a)-a,e-a),o=!n):s.isLeaf?(r?i+="function"==typeof r?r(s):r:s.type.spec.leafText&&(i+=s.type.spec.leafText(s)),o=!n):!o&&s.isBlock&&(i+=n,o=!0)}),0),i}append(t){if(!t.size)return this;if(!this.size)return t;let e=this.lastChild,n=t.firstChild,r=this.content.slice(),i=0;for(e.isText&&e.sameMarkup(n)&&(r[r.length-1]=e.withText(e.text+n.text),i=1);it)for(let i=0,o=0;ot&&((oe)&&(s=s.isText?s.cut(Math.max(0,t-o),Math.min(s.text.length,e-o)):s.cut(Math.max(0,t-o-1),Math.min(s.content.size,e-o-1))),n.push(s),r+=s.nodeSize),o=a}return new za(n,r)}cutByIndex(t,e){return t==e?za.empty:0==t&&e==this.content.length?this:new za(this.content.slice(t,e))}replaceChild(t,e){let n=this.content[t];if(n==e)return this;let r=this.content.slice(),i=this.size+e.nodeSize-n.nodeSize;return r[t]=e,new za(r,i)}addToStart(t){return new za([t].concat(this.content),this.size+t.nodeSize)}addToEnd(t){return new za(this.content.concat(t),this.size+t.nodeSize)}eq(t){if(this.content.length!=t.content.length)return!1;for(let e=0;ethis.size||t<0)throw new RangeError(`Position ${t} outside of fragment (${this})`);for(let n=0,r=0;;n++){let i=r+this.child(n).nodeSize;if(i>=t)return i==t||e>0?Fa(n+1,i):Fa(n,r);r=i}}toString(){return"<"+this.toStringInner()+">"}toStringInner(){return this.content.join(", ")}toJSON(){return this.content.length?this.content.map((t=>t.toJSON())):null}static fromJSON(t,e){if(!e)return za.empty;if(!Array.isArray(e))throw new RangeError("Invalid input for Fragment.fromJSON");return new za(e.map(t.nodeFromJSON))}static fromArray(t){if(!t.length)return za.empty;let e,n=0;for(let r=0;rthis.type.rank&&(e||(e=t.slice(0,r)),e.push(this),n=!0),e&&e.push(i)}}return e||(e=t.slice()),n||e.push(this),e}removeFromSet(t){for(let e=0;et.type.rank-e.type.rank)),e}}Ba.none=[];class Va extends Error{}class qa{constructor(t,e,n){this.content=t,this.openStart=e,this.openEnd=n}get size(){return this.content.size-this.openStart-this.openEnd}insertAt(t,e){let n=Wa(this.content,t+this.openStart,e);return n&&new qa(n,this.openStart,this.openEnd)}removeBetween(t,e){return new qa(Ja(this.content,t+this.openStart,e+this.openStart),this.openStart,this.openEnd)}eq(t){return this.content.eq(t.content)&&this.openStart==t.openStart&&this.openEnd==t.openEnd}toString(){return this.content+"("+this.openStart+","+this.openEnd+")"}toJSON(){if(!this.content.size)return null;let t={content:this.content.toJSON()};return this.openStart>0&&(t.openStart=this.openStart),this.openEnd>0&&(t.openEnd=this.openEnd),t}static fromJSON(t,e){if(!e)return qa.empty;let n=e.openStart||0,r=e.openEnd||0;if("number"!=typeof n||"number"!=typeof r)throw new RangeError("Invalid input for Slice.fromJSON");return new qa(za.fromJSON(t,e.content),n,r)}static maxOpen(t,e=!0){let n=0,r=0;for(let i=t.firstChild;i&&!i.isLeaf&&(e||!i.type.spec.isolating);i=i.firstChild)n++;for(let i=t.lastChild;i&&!i.isLeaf&&(e||!i.type.spec.isolating);i=i.lastChild)r++;return new qa(t,n,r)}}function Ja(t,e,n){let{index:r,offset:i}=t.findIndex(e),o=t.maybeChild(r),{index:s,offset:a}=t.findIndex(n);if(i==e||o.isText){if(a!=n&&!t.child(s).isText)throw new RangeError("Removing non-flat range");return t.cut(0,e).append(t.cut(n))}if(r!=s)throw new RangeError("Removing non-flat range");return t.replaceChild(r,o.copy(Ja(o.content,e-i-1,n-i-1)))}function Wa(t,e,n,r){let{index:i,offset:o}=t.findIndex(e),s=t.maybeChild(i);if(o==e||s.isText)return r&&!r.canReplace(i,i,n)?null:t.cut(0,e).append(n).append(t.cut(e));let a=Wa(s.content,e-o-1,n);return a&&t.replaceChild(i,s.copy(a))}function Ha(t,e,n){if(n.openStart>t.depth)throw new Va("Inserted content deeper than insertion position");if(t.depth-n.openStart!=e.depth-n.openEnd)throw new Va("Inconsistent open depths");return Ka(t,e,n,0)}function Ka(t,e,n,r){let i=t.index(r),o=t.node(r);if(i==e.index(r)&&r=0;i--)r=e.node(i).copy(za.from(r));return{start:r.resolveNoCache(t.openStart+n),end:r.resolveNoCache(r.content.size-t.openEnd-n)}}(n,t);return Xa(o,Qa(t,i,s,e,r))}{let r=t.parent,i=r.content;return Xa(r,i.cut(0,t.parentOffset).append(n.content).append(i.cut(e.parentOffset)))}}return Xa(o,tl(t,e,r))}function Ua(t,e){if(!e.type.compatibleContent(t.type))throw new Va("Cannot join "+e.type.name+" onto "+t.type.name)}function Ya(t,e,n){let r=t.node(n);return Ua(r,e.node(n)),r}function Ga(t,e){let n=e.length-1;n>=0&&t.isText&&t.sameMarkup(e[n])?e[n]=t.withText(e[n].text+t.text):e.push(t)}function Za(t,e,n,r){let i=(e||t).node(n),o=0,s=e?e.index(n):i.childCount;t&&(o=t.index(n),t.depth>n?o++:t.textOffset&&(Ga(t.nodeAfter,r),o++));for(let a=o;ai&&Ya(t,e,i+1),s=r.depth>i&&Ya(n,r,i+1),a=[];return Za(null,t,i,a),o&&s&&e.index(i)==n.index(i)?(Ua(o,s),Ga(Xa(o,Qa(t,e,n,r,i+1)),a)):(o&&Ga(Xa(o,tl(t,e,i+1)),a),Za(e,n,i,a),s&&Ga(Xa(s,tl(n,r,i+1)),a)),Za(r,null,i,a),new za(a)}function tl(t,e,n){let r=[];if(Za(null,t,n,r),t.depth>n){Ga(Xa(Ya(t,e,n+1),tl(t,e,n+1)),r)}return Za(e,null,n,r),new za(r)}qa.empty=new qa(za.empty,0,0);class el{constructor(t,e,n){this.pos=t,this.path=e,this.parentOffset=n,this.depth=e.length/3-1}resolveDepth(t){return null==t?this.depth:t<0?this.depth+t:t}get parent(){return this.node(this.depth)}get doc(){return this.node(0)}node(t){return this.path[3*this.resolveDepth(t)]}index(t){return this.path[3*this.resolveDepth(t)+1]}indexAfter(t){return t=this.resolveDepth(t),this.index(t)+(t!=this.depth||this.textOffset?1:0)}start(t){return 0==(t=this.resolveDepth(t))?0:this.path[3*t-1]+1}end(t){return t=this.resolveDepth(t),this.start(t)+this.node(t).content.size}before(t){if(!(t=this.resolveDepth(t)))throw new RangeError("There is no position before the top-level node");return t==this.depth+1?this.pos:this.path[3*t-1]}after(t){if(!(t=this.resolveDepth(t)))throw new RangeError("There is no position after the top-level node");return t==this.depth+1?this.pos:this.path[3*t-1]+this.path[3*t].nodeSize}get textOffset(){return this.pos-this.path[this.path.length-1]}get nodeAfter(){let t=this.parent,e=this.index(this.depth);if(e==t.childCount)return null;let n=this.pos-this.path[this.path.length-1],r=t.child(e);return n?t.child(e).cut(n):r}get nodeBefore(){let t=this.index(this.depth),e=this.pos-this.path[this.path.length-1];return e?this.parent.child(t).cut(0,e):0==t?null:this.parent.child(t-1)}posAtIndex(t,e){e=this.resolveDepth(e);let n=this.path[3*e],r=0==e?0:this.path[3*e-1]+1;for(let i=0;i0;e--)if(this.start(e)<=t&&this.end(e)>=t)return e;return 0}blockRange(t=this,e){if(t.pos=0;n--)if(t.pos<=this.end(n)&&(!e||e(this.node(n))))return new ol(this,t,n);return null}sameParent(t){return this.pos-this.parentOffset==t.pos-t.parentOffset}max(t){return t.pos>this.pos?t:this}min(t){return t.pos=0&&e<=t.content.size))throw new RangeError("Position "+e+" out of range");let n=[],r=0,i=e;for(let o=t;;){let{index:t,offset:e}=o.content.findIndex(i),s=i-e;if(n.push(o,t,r+e),!s)break;if(o=o.child(t),o.isText)break;i=s-1,r+=e+1}return new el(e,n,i)}static resolveCached(t,e){for(let r=0;rt&&this.nodesBetween(t,e,(t=>(n.isInSet(t.marks)&&(r=!0),!r))),r}get isBlock(){return this.type.isBlock}get isTextblock(){return this.type.isTextblock}get inlineContent(){return this.type.inlineContent}get isInline(){return this.type.isInline}get isText(){return this.type.isText}get isLeaf(){return this.type.isLeaf}get isAtom(){return this.type.isAtom}toString(){if(this.type.spec.toDebugString)return this.type.spec.toDebugString(this);let t=this.type.name;return this.content.size&&(t+="("+this.content.toStringInner()+")"),cl(this.marks,t)}contentMatchAt(t){let e=this.type.contentMatch.matchFragment(this.content,0,t);if(!e)throw new Error("Called contentMatchAt on a node with invalid content");return e}canReplace(t,e,n=za.empty,r=0,i=n.childCount){let o=this.contentMatchAt(t).matchFragment(n,r,i),s=o&&o.matchFragment(this.content,e);if(!s||!s.validEnd)return!1;for(let a=r;at.type.name))}`);this.content.forEach((t=>t.check()))}toJSON(){let t={type:this.type.name};for(let e in this.attrs){t.attrs=this.attrs;break}return this.content.size&&(t.content=this.content.toJSON()),this.marks.length&&(t.marks=this.marks.map((t=>t.toJSON()))),t}static fromJSON(t,e){if(!e)throw new RangeError("Invalid input for Node.fromJSON");let n=null;if(e.marks){if(!Array.isArray(e.marks))throw new RangeError("Invalid mark data for Node.fromJSON");n=e.marks.map(t.markFromJSON)}if("text"==e.type){if("string"!=typeof e.text)throw new RangeError("Invalid text node in JSON");return t.text(e.text,n)}let r=za.fromJSON(t,e.content);return t.nodeType(e.type).create(e.attrs,r,n)}}al.prototype.text=void 0;class ll extends al{constructor(t,e,n,r){if(super(t,e,null,r),!n)throw new RangeError("Empty text nodes are not allowed");this.text=n}toString(){return this.type.spec.toDebugString?this.type.spec.toDebugString(this):cl(this.marks,JSON.stringify(this.text))}get textContent(){return this.text}textBetween(t,e){return this.text.slice(t,e)}get nodeSize(){return this.text.length}mark(t){return t==this.marks?this:new ll(this.type,this.attrs,this.text,t)}withText(t){return t==this.text?this:new ll(this.type,this.attrs,t,this.marks)}cut(t=0,e=this.text.length){return 0==t&&e==this.text.length?this:this.withText(this.text.slice(t,e))}eq(t){return this.sameMarkup(t)&&this.text==t.text}toJSON(){let t=super.toJSON();return t.text=this.text,t}}function cl(t,e){for(let n=t.length-1;n>=0;n--)e=t[n].type.name+"("+e+")";return e}class ul{constructor(t){this.validEnd=t,this.next=[],this.wrapCache=[]}static parse(t,e){let n=new dl(t,e);if(null==n.next)return ul.empty;let r=fl(n);n.next&&n.err("Unexpected trailing text");let i=function(t){let e=Object.create(null);return n(yl(t,0));function n(r){let i=[];r.forEach((e=>{t[e].forEach((({term:e,to:n})=>{if(!e)return;let r;for(let t=0;t{r||i.push([e,r=[]]),-1==r.indexOf(t)&&r.push(t)}))}))}));let o=e[r.join(",")]=new ul(r.indexOf(t.length-1)>-1);for(let t=0;tt.to=e))}function o(t,e){if("choice"==t.type)return t.exprs.reduce(((t,n)=>t.concat(o(n,e))),[]);if("seq"!=t.type){if("star"==t.type){let s=n();return r(e,s),i(o(t.expr,s),s),[r(s)]}if("plus"==t.type){let s=n();return i(o(t.expr,e),s),i(o(t.expr,s),s),[r(s)]}if("opt"==t.type)return[r(e)].concat(o(t.expr,e));if("range"==t.type){let s=e;for(let e=0;et.createAndFill())));for(let t=0;t=this.next.length)throw new RangeError(`There's no ${t}th edge in this content match`);return this.next[t]}toString(){let t=[];return function e(n){t.push(n);for(let r=0;r{let r=n+(e.validEnd?"*":" ")+" ";for(let i=0;i"+t.indexOf(e.next[i].next);return r})).join("\n")}}ul.empty=new ul(!0);class dl{constructor(t,e){this.string=t,this.nodeTypes=e,this.inline=null,this.pos=0,this.tokens=t.split(/\s*(?=\b|\W|$)/),""==this.tokens[this.tokens.length-1]&&this.tokens.pop(),""==this.tokens[0]&&this.tokens.shift()}get next(){return this.tokens[this.pos]}eat(t){return this.next==t&&(this.pos++||!0)}err(t){throw new SyntaxError(t+" (in content expression '"+this.string+"')")}}function fl(t){let e=[];do{e.push(hl(t))}while(t.eat("|"));return 1==e.length?e[0]:{type:"choice",exprs:e}}function hl(t){let e=[];do{e.push(pl(t))}while(t.next&&")"!=t.next&&"|"!=t.next);return 1==e.length?e[0]:{type:"seq",exprs:e}}function pl(t){let e=function(t){if(t.eat("(")){let e=fl(t);return t.eat(")")||t.err("Missing closing paren"),e}if(!/\W/.test(t.next)){let e=function(t,e){let n=t.nodeTypes,r=n[e];if(r)return[r];let i=[];for(let o in n){let t=n[o];t.groups.indexOf(e)>-1&&i.push(t)}0==i.length&&t.err("No node type or group '"+e+"' found");return i}(t,t.next).map((e=>(null==t.inline?t.inline=e.isInline:t.inline!=e.isInline&&t.err("Mixing inline and block content"),{type:"name",value:e})));return t.pos++,1==e.length?e[0]:{type:"choice",exprs:e}}t.err("Unexpected token '"+t.next+"'")}(t);for(;;)if(t.eat("+"))e={type:"plus",expr:e};else if(t.eat("*"))e={type:"star",expr:e};else if(t.eat("?"))e={type:"opt",expr:e};else{if(!t.eat("{"))break;e=gl(t,e)}return e}function ml(t){/\D/.test(t.next)&&t.err("Expected number, got '"+t.next+"'");let e=Number(t.next);return t.pos++,e}function gl(t,e){let n=ml(t),r=n;return t.eat(",")&&(r="}"!=t.next?ml(t):-1),t.eat("}")||t.err("Unclosed braced range"),{type:"range",min:n,max:r,expr:e}}function vl(t,e){return e-t}function yl(t,e){let n=[];return function e(r){let i=t[r];if(1==i.length&&!i[0].term)return e(i[0].to);n.push(r);for(let t=0;t-1}allowsMarks(t){if(null==this.markSet)return!0;for(let e=0;en[t]=new kl(t,e,r)));let r=e.spec.topNode||"doc";if(!n[r])throw new RangeError("Schema is missing its top node type ('"+r+"')");if(!n.text)throw new RangeError("Every schema needs a 'text' type");for(let i in n.text.attrs)throw new RangeError("The text node type should not have attributes");return n}}class Sl{constructor(t){this.hasDefault=Object.prototype.hasOwnProperty.call(t,"default"),this.default=t.default}get isRequired(){return!this.hasDefault}}class Ol{constructor(t,e,n,r){this.name=t,this.rank=e,this.schema=n,this.spec=r,this.attrs=xl(r.attrs),this.excluded=null;let i=bl(this.attrs);this.instance=i?new Ba(this,i):null}create(t=null){return!t&&this.instance?this.instance:new Ba(this,wl(this.attrs,t))}static compile(t,e){let n=Object.create(null),r=0;return t.forEach(((t,i)=>n[t]=new Ol(t,r++,e,i))),n}removeFromSet(t){for(var e=0;e-1}}class _l{constructor(t){this.cached=Object.create(null);let e=this.spec={};for(let r in t)e[r]=t[r];e.nodes=Pa.from(t.nodes),e.marks=Pa.from(t.marks||{}),this.nodes=kl.compile(this.spec.nodes,this),this.marks=Ol.compile(this.spec.marks,this);let n=Object.create(null);for(let r in this.nodes){if(r in this.marks)throw new RangeError(r+" can not be both a node and a mark");let t=this.nodes[r],e=t.spec.content||"",i=t.spec.marks;t.contentMatch=n[e]||(n[e]=ul.parse(e,this.nodes)),t.inlineContent=t.contentMatch.inlineContent,t.markSet="_"==i?null:i?Ml(this,i.split(" ")):""!=i&&t.inlineContent?null:[]}for(let r in this.marks){let t=this.marks[r],e=t.spec.excludes;t.excluded=null==e?[t]:""==e?[]:Ml(this,e.split(" "))}this.nodeFromJSON=this.nodeFromJSON.bind(this),this.markFromJSON=this.markFromJSON.bind(this),this.topNodeType=this.nodes[this.spec.topNode||"doc"],this.cached.wrappings=Object.create(null)}node(t,e=null,n,r){if("string"==typeof t)t=this.nodeType(t);else{if(!(t instanceof kl))throw new RangeError("Invalid node type: "+t);if(t.schema!=this)throw new RangeError("Node type from different schema used ("+t.name+")")}return t.createChecked(e,n,r)}text(t,e){let n=this.nodes.text;return new ll(n,n.defaultAttrs,t,Ba.setFrom(e))}mark(t,e){return"string"==typeof t&&(t=this.marks[t]),t.create(e)}nodeFromJSON(t){return al.fromJSON(this,t)}markFromJSON(t){return Ba.fromJSON(this,t)}nodeType(t){let e=this.nodes[t];if(!e)throw new RangeError("Unknown node type: "+t);return e}}function Ml(t,e){let n=[];for(let r=0;r-1)&&n.push(s=r)}if(!s)throw new SyntaxError("Unknown mark type: '"+e[r]+"'")}return n}class Cl{constructor(t,e){this.schema=t,this.rules=e,this.tags=[],this.styles=[],e.forEach((t=>{t.tag?this.tags.push(t):t.style&&this.styles.push(t)})),this.normalizeLists=!this.tags.some((e=>{if(!/^(ul|ol)\b/.test(e.tag)||!e.node)return!1;let n=t.nodes[e.node];return n.contentMatch.matchType(n)}))}parse(t,e={}){let n=new El(this,e,!1);return n.addAll(t,e.from,e.to),n.finish()}parseSlice(t,e={}){let n=new El(this,e,!0);return n.addAll(t,e.from,e.to),qa.maxOpen(n.finish())}matchTag(t,e,n){for(let r=n?this.tags.indexOf(n)+1:0;rt.length&&(61!=o.charCodeAt(t.length)||o.slice(t.length+1)!=e))){if(r.getAttrs){let t=r.getAttrs(e);if(!1===t)continue;r.attrs=t||void 0}return r}}}static schemaRules(t){let e=[];function n(t){let n=null==t.priority?50:t.priority,r=0;for(;r{n(t=Il(t)),t.mark=r}))}for(let r in t.nodes){let e=t.nodes[r].spec.parseDOM;e&&e.forEach((t=>{n(t=Il(t)),t.node=r}))}return e}static fromSchema(t){return t.cached.domParser||(t.cached.domParser=new Cl(t,Cl.schemaRules(t)))}}const $l={address:!0,article:!0,aside:!0,blockquote:!0,canvas:!0,dd:!0,div:!0,dl:!0,fieldset:!0,figcaption:!0,figure:!0,footer:!0,form:!0,h1:!0,h2:!0,h3:!0,h4:!0,h5:!0,h6:!0,header:!0,hgroup:!0,hr:!0,li:!0,noscript:!0,ol:!0,output:!0,p:!0,pre:!0,section:!0,table:!0,tfoot:!0,ul:!0},Nl={head:!0,noscript:!0,object:!0,script:!0,style:!0,title:!0},Tl={ol:!0,ul:!0};function Dl(t,e,n){return null!=e?(e?1:0)|("full"===e?2:0):t&&"pre"==t.whitespace?3:-5&n}class Al{constructor(t,e,n,r,i,o,s){this.type=t,this.attrs=e,this.marks=n,this.pendingMarks=r,this.solid=i,this.options=s,this.content=[],this.activeMarks=Ba.none,this.stashMarks=[],this.match=o||(4&s?null:t.contentMatch)}findWrapping(t){if(!this.match){if(!this.type)return[];let e=this.type.contentMatch.fillBefore(za.from(t));if(!e){let e,n=this.type.contentMatch;return(e=n.findWrapping(t.type))?(this.match=n,e):null}this.match=this.type.contentMatch.matchFragment(e)}return this.match.findWrapping(t.type)}finish(t){if(!(1&this.options)){let t,e=this.content[this.content.length-1];if(e&&e.isText&&(t=/[ \t\r\n\u000c]+$/.exec(e.text))){let n=e;e.text.length==t[0].length?this.content.pop():this.content[this.content.length-1]=n.withText(n.text.slice(0,n.text.length-t[0].length))}}let e=za.from(this.content);return!t&&this.match&&(e=e.append(this.match.fillBefore(za.empty,!0))),this.type?this.type.create(this.attrs,e,this.marks):e}popFromStashMark(t){for(let e=this.stashMarks.length-1;e>=0;e--)if(t.eq(this.stashMarks[e]))return this.stashMarks.splice(e,1)[0]}applyPending(t){for(let e=0,n=this.pendingMarks;ethis.insertNode(t)));else{let n=t;"string"==typeof e.contentElement?n=t.querySelector(e.contentElement):"function"==typeof e.contentElement?n=e.contentElement(t):e.contentElement&&(n=e.contentElement),this.findAround(t,n,!0),this.addAll(n)}r&&this.sync(s)&&this.open--,o&&this.removePendingMark(o,s)}addAll(t,e,n){let r=e||0;for(let i=e?t.childNodes[e]:t.firstChild,o=null==n?null:t.childNodes[n];i!=o;i=i.nextSibling,++r)this.findAtPoint(t,r),this.addDOM(i);this.findAtPoint(t,r)}findPlace(t){let e,n;for(let r=this.open;r>=0;r--){let i=this.nodes[r],o=i.findWrapping(t);if(o&&(!e||e.length>o.length)&&(e=o,n=i,!o.length))break;if(i.solid)break}if(!e)return!1;this.sync(n);for(let r=0;rthis.open){for(;e>this.open;e--)this.nodes[e-1].content.push(this.nodes[e].finish(t));this.nodes.length=this.open+1}}finish(){return this.open=0,this.closeExtra(this.isOpen),this.nodes[0].finish(this.isOpen||this.options.topOpen)}sync(t){for(let e=this.open;e>=0;e--)if(this.nodes[e]==t)return this.open=e,!0;return!1}get currentPos(){this.closeExtra();let t=0;for(let e=this.open;e>=0;e--){let n=this.nodes[e].content;for(let e=n.length-1;e>=0;e--)t+=n[e].nodeSize;e&&t++}return t}findAtPoint(t,e){if(this.find)for(let n=0;n-1)return t.split(/\s*\|\s*/).some(this.matchesContext,this);let e=t.split("/"),n=this.options.context,r=!(this.isOpen||n&&n.parent.type!=this.nodes[0].type),i=-(n?n.depth+1:0)+(r?0:1),o=(t,s)=>{for(;t>=0;t--){let a=e[t];if(""==a){if(t==e.length-1||0==t)continue;for(;s>=i;s--)if(o(t-1,s))return!0;return!1}{let t=s>0||0==s&&r?this.nodes[s].type:n&&s>=i?n.node(s-i).type:null;if(!t||t.name!=a&&-1==t.groups.indexOf(a))return!1;s--}}return!0};return o(e.length-1,this.open)}textblockFromContext(){let t=this.options.context;if(t)for(let e=t.depth;e>=0;e--){let n=t.node(e).contentMatchAt(t.indexAfter(e)).defaultType;if(n&&n.isTextblock&&n.defaultAttrs)return n}for(let e in this.parser.schema.nodes){let t=this.parser.schema.nodes[e];if(t.isTextblock&&t.defaultAttrs)return t}}addPendingMark(t){let e=function(t,e){for(let n=0;n=0;n--){let r=this.nodes[n];if(r.pendingMarks.lastIndexOf(t)>-1)r.pendingMarks=t.removeFromSet(r.pendingMarks);else{r.activeMarks=t.removeFromSet(r.activeMarks);let e=r.popFromStashMark(t);e&&r.type&&r.type.allowsMarkType(e.type)&&(r.activeMarks=e.addToSet(r.activeMarks))}if(r==e)break}}}function Pl(t,e){return(t.matches||t.msMatchesSelector||t.webkitMatchesSelector||t.mozMatchesSelector).call(t,e)}function Il(t){let e={};for(let n in t)e[n]=t[n];return e}function Rl(t,e){let n=e.schema.nodes;for(let r in n){let i=n[r];if(!i.allowsMarkType(t))continue;let o=[],s=t=>{o.push(t);for(let n=0;n{if(i.length||t.marks.length){let n=0,o=0;for(;n=0;r--){let i=this.serializeMark(t.marks[r],t.isInline,e);i&&((i.contentDOM||i.dom).appendChild(n),n=i.dom)}return n}serializeMark(t,e,n={}){let r=this.marks[t.type.name];return r&&zl.renderSpec(Fl(n),r(t,e))}static renderSpec(t,e,n=null){if("string"==typeof e)return{dom:t.createTextNode(e)};if(null!=e.nodeType)return{dom:e};if(e.dom&&null!=e.dom.nodeType)return e;let r,i=e[0],o=i.indexOf(" ");o>0&&(n=i.slice(0,o),i=i.slice(o+1));let s=n?t.createElementNS(n,i):t.createElement(i),a=e[1],l=1;if(a&&"object"==typeof a&&null==a.nodeType&&!Array.isArray(a)){l=2;for(let t in a)if(null!=a[t]){let e=t.indexOf(" ");e>0?s.setAttributeNS(t.slice(0,e),t.slice(e+1),a[t]):s.setAttribute(t,a[t])}}for(let c=l;cl)throw new RangeError("Content hole must be the only child of its parent node");return{dom:s,contentDOM:s}}{let{dom:e,contentDOM:o}=zl.renderSpec(t,i,n);if(s.appendChild(e),o){if(r)throw new RangeError("Multiple content holes");r=o}}}return{dom:s,contentDOM:r}}static fromSchema(t){return t.cached.domSerializer||(t.cached.domSerializer=new zl(this.nodesFromSchema(t),this.marksFromSchema(t)))}static nodesFromSchema(t){let e=jl(t.nodes);return e.text||(e.text=t=>t.text),e}static marksFromSchema(t){return jl(t.marks)}}function jl(t){let e={};for(let n in t){let r=t[n].spec.toDOM;r&&(e[n]=r)}return e}function Fl(t){return t.document||window.document}const Ll=Math.pow(2,16);function Bl(t){return 65535&t}class Vl{constructor(t,e,n){this.pos=t,this.delInfo=e,this.recover=n}get deleted(){return(8&this.delInfo)>0}get deletedBefore(){return(5&this.delInfo)>0}get deletedAfter(){return(6&this.delInfo)>0}get deletedAcross(){return(4&this.delInfo)>0}}class ql{constructor(t,e=!1){if(this.ranges=t,this.inverted=e,!t.length&&ql.empty)return ql.empty}recover(t){let e=0,n=Bl(t);if(!this.inverted)for(let r=0;rt)break;let l=this.ranges[s+i],c=this.ranges[s+o],u=a+l;if(t<=u){let i=a+r+((l?t==a?-1:t==u?1:e:e)<0?0:c);if(n)return i;let o=t==(e<0?a:u)?null:s/3+(t-a)*Ll,d=t==a?2:t==u?1:4;return(e<0?t!=a:t!=u)&&(d|=8),new Vl(i,d,o)}r+=c-l}return n?t+r:new Vl(t+r,0,null)}touches(t,e){let n=0,r=Bl(e),i=this.inverted?2:1,o=this.inverted?1:2;for(let s=0;st)break;let a=this.ranges[s+i];if(t<=e+a&&s==3*r)return!0;n+=this.ranges[s+o]-a}return!1}forEach(t){let e=this.inverted?2:1,n=this.inverted?1:2;for(let r=0,i=0;r=0;e--){let r=t.getMirror(e);this.appendMap(t.maps[e].invert(),null!=r&&r>e?n-r-1:void 0)}}invert(){let t=new Jl;return t.appendMappingInverted(this),t}map(t,e=1){if(this.mirror)return this._map(t,e,!0);for(let n=this.from;ni&&et.isAtom&&e.type.allowsMarkType(this.mark.type)?t.mark(this.mark.addToSet(t.marks)):t),r),e.openStart,e.openEnd);return Kl.fromReplace(t,this.from,this.to,i)}invert(){return new Gl(this.from,this.to,this.mark)}map(t){let e=t.mapResult(this.from,1),n=t.mapResult(this.to,-1);return e.deleted&&n.deleted||e.pos>=n.pos?null:new Yl(e.pos,n.pos,this.mark)}merge(t){return t instanceof Yl&&t.mark.eq(this.mark)&&this.from<=t.to&&this.to>=t.from?new Yl(Math.min(this.from,t.from),Math.max(this.to,t.to),this.mark):null}toJSON(){return{stepType:"addMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(t,e){if("number"!=typeof e.from||"number"!=typeof e.to)throw new RangeError("Invalid input for AddMarkStep.fromJSON");return new Yl(e.from,e.to,t.markFromJSON(e.mark))}}Hl.jsonID("addMark",Yl);class Gl extends Hl{constructor(t,e,n){super(),this.from=t,this.to=e,this.mark=n}apply(t){let e=t.slice(this.from,this.to),n=new qa(Ul(e.content,(t=>t.mark(this.mark.removeFromSet(t.marks))),t),e.openStart,e.openEnd);return Kl.fromReplace(t,this.from,this.to,n)}invert(){return new Yl(this.from,this.to,this.mark)}map(t){let e=t.mapResult(this.from,1),n=t.mapResult(this.to,-1);return e.deleted&&n.deleted||e.pos>=n.pos?null:new Gl(e.pos,n.pos,this.mark)}merge(t){return t instanceof Gl&&t.mark.eq(this.mark)&&this.from<=t.to&&this.to>=t.from?new Gl(Math.min(this.from,t.from),Math.max(this.to,t.to),this.mark):null}toJSON(){return{stepType:"removeMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(t,e){if("number"!=typeof e.from||"number"!=typeof e.to)throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");return new Gl(e.from,e.to,t.markFromJSON(e.mark))}}Hl.jsonID("removeMark",Gl);class Zl extends Hl{constructor(t,e){super(),this.pos=t,this.mark=e}apply(t){let e=t.nodeAt(this.pos);if(!e)return Kl.fail("No node at mark step's position");let n=e.type.create(e.attrs,null,this.mark.addToSet(e.marks));return Kl.fromReplace(t,this.pos,this.pos+1,new qa(za.from(n),0,e.isLeaf?0:1))}invert(t){let e=t.nodeAt(this.pos);if(e){let t=this.mark.addToSet(e.marks);if(t.length==e.marks.length){for(let n=0;nn.pos?null:new tc(e.pos,n.pos,r,i,this.slice,this.insert,this.structure)}toJSON(){let t={stepType:"replaceAround",from:this.from,to:this.to,gapFrom:this.gapFrom,gapTo:this.gapTo,insert:this.insert};return this.slice.size&&(t.slice=this.slice.toJSON()),this.structure&&(t.structure=!0),t}static fromJSON(t,e){if("number"!=typeof e.from||"number"!=typeof e.to||"number"!=typeof e.gapFrom||"number"!=typeof e.gapTo||"number"!=typeof e.insert)throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");return new tc(e.from,e.to,e.gapFrom,e.gapTo,qa.fromJSON(t,e.slice),e.insert,!!e.structure)}}function ec(t,e,n){let r=t.resolve(e),i=n-e,o=r.depth;for(;i>0&&o>0&&r.indexAfter(o)==r.node(o).childCount;)o--,i--;if(i>0){let t=r.node(o).maybeChild(r.indexAfter(o));for(;i>0;){if(!t||t.isLeaf)return!0;t=t.firstChild,i--}}return!1}function nc(t,e,n){return(0==e||t.canReplace(e,t.childCount))&&(n==t.childCount||t.canReplace(0,n))}function rc(t){let e=t.parent.content.cutByIndex(t.startIndex,t.endIndex);for(let n=t.depth;;--n){let r=t.$from.node(n),i=t.$from.index(n),o=t.$to.indexAfter(n);if(no;c--,u--){let t=i.node(c),e=i.index(c);if(t.type.spec.isolating)return!1;let n=t.content.cutByIndex(e,t.childCount),o=r&&r[u]||t;if(o!=t&&(n=n.replaceChild(0,o.type.create(o.attrs))),!t.canReplace(e+1,t.childCount)||!o.type.validContent(n))return!1}let a=i.indexAfter(o),l=r&&r[0];return i.node(o).canReplaceWith(a,a,l?l.type:i.node(o+1).type)}function ac(t,e){let n=t.resolve(e),r=n.index();return i=n.nodeBefore,o=n.nodeAfter,!(!i||!o||i.isLeaf||!i.canAppend(o))&&n.parent.canReplace(r,r+1);var i,o}function lc(t,e,n=e,r=qa.empty){if(e==n&&!r.size)return null;let i=t.resolve(e),o=t.resolve(n);return cc(i,o,r)?new Ql(e,n,r):new uc(i,o,r).fit()}function cc(t,e,n){return!n.openStart&&!n.openEnd&&t.start()==e.start()&&t.parent.canReplace(t.index(),e.index(),n.content)}Hl.jsonID("replaceAround",tc);class uc{constructor(t,e,n){this.$from=t,this.$to=e,this.unplaced=n,this.frontier=[],this.placed=za.empty;for(let r=0;r<=t.depth;r++){let e=t.node(r);this.frontier.push({type:e.type,match:e.contentMatchAt(t.indexAfter(r))})}for(let r=t.depth;r>0;r--)this.placed=za.from(t.node(r).copy(this.placed))}get depth(){return this.frontier.length-1}fit(){for(;this.unplaced.size;){let t=this.findFittable();t?this.placeNodes(t):this.openMore()||this.dropNode()}let t=this.mustMoveInline(),e=this.placed.size-this.depth-this.$from.depth,n=this.$from,r=this.close(t<0?this.$to:n.doc.resolve(t));if(!r)return null;let i=this.placed,o=n.depth,s=r.depth;for(;o&&s&&1==i.childCount;)i=i.firstChild.content,o--,s--;let a=new qa(i,o,s);return t>-1?new tc(n.pos,t,this.$to.pos,this.$to.end(),a,e):a.size||n.pos!=this.$to.pos?new Ql(n.pos,r.pos,a):null}findFittable(){for(let t=1;t<=2;t++)for(let e=this.unplaced.openStart;e>=0;e--){let n,r=null;e?(r=hc(this.unplaced.content,e-1).firstChild,n=r.content):n=this.unplaced.content;let i=n.firstChild;for(let o=this.depth;o>=0;o--){let n,{type:s,match:a}=this.frontier[o],l=null;if(1==t&&(i?a.matchType(i.type)||(l=a.fillBefore(za.from(i),!1)):r&&s.compatibleContent(r.type)))return{sliceDepth:e,frontierDepth:o,parent:r,inject:l};if(2==t&&i&&(n=a.findWrapping(i.type)))return{sliceDepth:e,frontierDepth:o,parent:r,wrap:n};if(r&&a.matchType(r.type))break}}}openMore(){let{content:t,openStart:e,openEnd:n}=this.unplaced,r=hc(t,e);return!(!r.childCount||r.firstChild.isLeaf)&&(this.unplaced=new qa(t,e+1,Math.max(n,r.size+e>=t.size-n?e+1:0)),!0)}dropNode(){let{content:t,openStart:e,openEnd:n}=this.unplaced,r=hc(t,e);if(r.childCount<=1&&e>0){let i=t.size-e<=e+r.size;this.unplaced=new qa(dc(t,e-1,1),e-1,i?e-1:n)}else this.unplaced=new qa(dc(t,e,1),e,n)}placeNodes({sliceDepth:t,frontierDepth:e,parent:n,inject:r,wrap:i}){for(;this.depth>e;)this.closeFrontierNode();if(i)for(let p=0;p1||0==a||t.content.size)&&(u=e,c.push(pc(t.mark(d.allowedMarks(t.marks)),1==l?a:0,l==s.childCount?f:-1)))}let h=l==s.childCount;h||(f=-1),this.placed=fc(this.placed,e,za.from(c)),this.frontier[e].match=u,h&&f<0&&n&&n.type==this.frontier[this.depth].type&&this.frontier.length>1&&this.closeFrontierNode();for(let p=0,m=s;p1&&r==this.$to.end(--n);)++r;return r}findCloseLevel(t){t:for(let e=Math.min(this.depth,t.depth);e>=0;e--){let{match:n,type:r}=this.frontier[e],i=e=0;n--){let{match:e,type:r}=this.frontier[n],i=mc(t,n,r,e,!0);if(!i||i.childCount)continue t}return{depth:e,fit:o,move:i?t.doc.resolve(t.after(e+1)):t}}}}close(t){let e=this.findCloseLevel(t);if(!e)return null;for(;this.depth>e.depth;)this.closeFrontierNode();e.fit.childCount&&(this.placed=fc(this.placed,e.depth,e.fit)),t=e.move;for(let n=e.depth+1;n<=t.depth;n++){let e=t.node(n),r=e.type.contentMatch.fillBefore(e.content,!0,t.index(n));this.openFrontierNode(e.type,e.attrs,r)}return t}openFrontierNode(t,e=null,n){let r=this.frontier[this.depth];r.match=r.match.matchType(t),this.placed=fc(this.placed,this.depth,za.from(t.create(e,n))),this.frontier.push({type:t,match:t.contentMatch})}closeFrontierNode(){let t=this.frontier.pop().match.fillBefore(za.empty,!0);t.childCount&&(this.placed=fc(this.placed,this.frontier.length,t))}}function dc(t,e,n){return 0==e?t.cutByIndex(n,t.childCount):t.replaceChild(0,t.firstChild.copy(dc(t.firstChild.content,e-1,n)))}function fc(t,e,n){return 0==e?t.append(n):t.replaceChild(t.childCount-1,t.lastChild.copy(fc(t.lastChild.content,e-1,n)))}function hc(t,e){for(let n=0;n1&&(r=r.replaceChild(0,pc(r.firstChild,e-1,1==r.childCount?n-1:0))),e>0&&(r=t.type.contentMatch.fillBefore(r).append(r),n<=0&&(r=r.append(t.type.contentMatch.matchFragment(r).fillBefore(za.empty,!0)))),t.copy(r)}function mc(t,e,n,r,i){let o=t.node(e),s=i?t.indexAfter(e):t.index(e);if(s==o.childCount&&!n.compatibleContent(o.type))return null;let a=r.fillBefore(o.content,!0,s);return a&&!function(t,e,n){for(let r=n;rr){let e=i.contentMatchAt(0),n=e.fillBefore(t).append(t);t=n.append(e.matchFragment(n).fillBefore(za.empty,!0))}return t}function yc(t,e){let n=[];for(let r=Math.min(t.depth,e.depth);r>=0;r--){let i=t.start(r);if(ie.pos+(e.depth-r)||t.node(r).type.spec.isolating||e.node(r).type.spec.isolating)break;(i==e.start(r)||r==t.depth&&r==e.depth&&t.parent.inlineContent&&e.parent.inlineContent&&r&&e.start(r-1)==i-1)&&n.push(r)}return n}class bc extends Hl{constructor(t,e,n){super(),this.pos=t,this.attr=e,this.value=n}apply(t){let e=t.nodeAt(this.pos);if(!e)return Kl.fail("No node at attribute step's position");let n=Object.create(null);for(let i in e.attrs)n[i]=e.attrs[i];n[this.attr]=this.value;let r=e.type.create(n,null,e.marks);return Kl.fromReplace(t,this.pos,this.pos+1,new qa(za.from(r),0,e.isLeaf?0:1))}getMap(){return ql.empty}invert(t){return new bc(this.pos,this.attr,t.nodeAt(this.pos).attrs[this.attr])}map(t){let e=t.mapResult(this.pos,1);return e.deletedAfter?null:new bc(e.pos,this.attr,this.value)}toJSON(){return{stepType:"attr",pos:this.pos,attr:this.attr,value:this.value}}static fromJSON(t,e){if("number"!=typeof e.pos||"string"!=typeof e.attr)throw new RangeError("Invalid input for AttrStep.fromJSON");return new bc(e.pos,e.attr,e.value)}}Hl.jsonID("attr",bc);let wc=class extends Error{};wc=function t(e){let n=Error.call(this,e);return n.__proto__=t.prototype,n},(wc.prototype=Object.create(Error.prototype)).constructor=wc,wc.prototype.name="TransformError";class xc{constructor(t){this.doc=t,this.steps=[],this.docs=[],this.mapping=new Jl}get before(){return this.docs.length?this.docs[0]:this.doc}step(t){let e=this.maybeStep(t);if(e.failed)throw new wc(e.failed);return this}maybeStep(t){let e=t.apply(this.doc);return e.failed||this.addStep(t,e.doc),e}get docChanged(){return this.steps.length>0}addStep(t,e){this.docs.push(this.doc),this.steps.push(t),this.mapping.appendMap(t.getMap()),this.doc=e}replace(t,e=t,n=qa.empty){let r=lc(this.doc,t,e,n);return r&&this.step(r),this}replaceWith(t,e,n){return this.replace(t,e,new qa(za.from(n),0,0))}delete(t,e){return this.replace(t,e,qa.empty)}insert(t,e){return this.replaceWith(t,t,e)}replaceRange(t,e,n){return function(t,e,n,r){if(!r.size)return t.deleteRange(e,n);let i=t.doc.resolve(e),o=t.doc.resolve(n);if(cc(i,o,r))return t.step(new Ql(e,n,r));let s=yc(i,t.doc.resolve(n));0==s[s.length-1]&&s.pop();let a=-(i.depth+1);s.unshift(a);for(let f=i.depth,h=i.pos-1;f>0;f--,h--){let t=i.node(f).type.spec;if(t.defining||t.definingAsContext||t.isolating)break;s.indexOf(f)>-1?a=f:i.before(f)==h&&s.splice(1,0,-f)}let l=s.indexOf(a),c=[],u=r.openStart;for(let f=r.content,h=0;;h++){let t=f.firstChild;if(c.push(t),h==r.openStart)break;f=t.content}for(let f=u-1;f>=0;f--){let t=c[f].type,e=gc(t);if(e&&i.node(l).type!=t)u=f;else if(e||!t.isTextblock)break}for(let f=r.openStart;f>=0;f--){let e=(f+u+1)%(r.openStart+1),a=c[e];if(a)for(let c=0;c=0&&(t.replace(e,n,r),!(t.steps.length>d));f--){let t=s[f];t<0||(e=i.before(t),n=o.after(t))}}(this,t,e,n),this}replaceRangeWith(t,e,n){return function(t,e,n,r){if(!r.isInline&&e==n&&t.doc.resolve(e).parent.content.size){let i=function(t,e,n){let r=t.resolve(e);if(r.parent.canReplaceWith(r.index(),r.index(),n))return e;if(0==r.parentOffset)for(let i=r.depth-1;i>=0;i--){let t=r.index(i);if(r.node(i).canReplaceWith(t,t,n))return r.before(i+1);if(t>0)return null}if(r.parentOffset==r.parent.content.size)for(let i=r.depth-1;i>=0;i--){let t=r.indexAfter(i);if(r.node(i).canReplaceWith(t,t,n))return r.after(i+1);if(t0&&(n||r.node(e-1).canReplace(r.index(e-1),i.indexAfter(e-1))))return t.delete(r.before(e),i.after(e))}for(let s=1;s<=r.depth&&s<=i.depth;s++)if(e-r.start(s)==r.depth-s&&n>r.end(s)&&i.end(s)-n!=i.depth-s)return t.delete(r.before(s),n);t.delete(e,n)}(this,t,e),this}lift(t,e){return function(t,e,n){let{$from:r,$to:i,depth:o}=e,s=r.before(o+1),a=i.after(o+1),l=s,c=a,u=za.empty,d=0;for(let p=o,m=!1;p>n;p--)m||r.index(p)>0?(m=!0,u=za.from(r.node(p).copy(u)),d++):l--;let f=za.empty,h=0;for(let p=o,m=!1;p>n;p--)m||i.after(p+1)=0;s--){if(r.size){let t=n[s].type.contentMatch.matchFragment(r);if(!t||!t.validEnd)throw new RangeError("Wrapper type given to Transform.wrap does not form valid content of its parent wrapper")}r=za.from(n[s].type.create(n[s].attrs,r))}let i=e.start,o=e.end;t.step(new tc(i,o,i,o,new qa(r,0,0),n.length,!0))}(this,t,e),this}setBlockType(t,e=t,n,r=null){return function(t,e,n,r,i){if(!r.isTextblock)throw new RangeError("Type given to setBlockType should be a textblock");let o=t.steps.length;t.doc.nodesBetween(e,n,((e,n)=>{if(e.isTextblock&&!e.hasMarkup(r,i)&&function(t,e,n){let r=t.resolve(e),i=r.index();return r.parent.canReplaceWith(i,i+1,n)}(t.doc,t.mapping.slice(o).map(n),r)){t.clearIncompatible(t.mapping.slice(o).map(n,1),r);let s=t.mapping.slice(o),a=s.map(n,1),l=s.map(n+e.nodeSize,1);return t.step(new tc(a,l,a+1,l-1,new qa(za.from(r.create(i,null,e.marks)),0,0),1,!0)),!1}}))}(this,t,e,n,r),this}setNodeMarkup(t,e,n=null,r=[]){return function(t,e,n,r,i){let o=t.doc.nodeAt(e);if(!o)throw new RangeError("No node at given position");n||(n=o.type);let s=n.create(r,null,i||o.marks);if(o.isLeaf)return t.replaceWith(e,e+o.nodeSize,s);if(!n.validContent(o.content))throw new RangeError("Invalid content for node type "+n.name);t.step(new tc(e,e+o.nodeSize,e+1,e+o.nodeSize-1,new qa(za.from(s),0,0),1,!0))}(this,t,e,n,r),this}setNodeAttribute(t,e,n){return this.step(new bc(t,e,n)),this}addNodeMark(t,e){return this.step(new Zl(t,e)),this}removeNodeMark(t,e){if(!(e instanceof Ba)){let n=this.doc.nodeAt(t);if(!n)throw new RangeError("No node at position "+t);if(!(e=e.isInSet(n.marks)))return this}return this.step(new Xl(t,e)),this}split(t,e=1,n){return function(t,e,n=1,r){let i=t.doc.resolve(e),o=za.empty,s=za.empty;for(let a=i.depth,l=i.depth-n,c=n-1;a>l;a--,c--){o=za.from(i.node(a).copy(o));let t=r&&r[c];s=za.from(t?t.type.create(t.attrs,s):i.node(a).copy(s))}t.step(new Ql(e,e,new qa(o.append(s),n,n),!0))}(this,t,e,n),this}addMark(t,e,n){return function(t,e,n,r){let i,o,s=[],a=[];t.doc.nodesBetween(e,n,((t,l,c)=>{if(!t.isInline)return;let u=t.marks;if(!r.isInSet(u)&&c.type.allowsMarkType(r.type)){let c=Math.max(l,e),d=Math.min(l+t.nodeSize,n),f=r.addToSet(u);for(let t=0;tt.step(e))),a.forEach((e=>t.step(e)))}(this,t,e,n),this}removeMark(t,e,n){return function(t,e,n,r){let i=[],o=0;t.doc.nodesBetween(e,n,((t,s)=>{if(!t.isInline)return;o++;let a=null;if(r instanceof Ol){let e,n=t.marks;for(;e=r.isInSet(n);)(a||(a=[])).push(e),n=e.removeFromSet(n)}else r?r.isInSet(t.marks)&&(a=[r]):a=t.marks;if(a&&a.length){let r=Math.min(s+t.nodeSize,n);for(let t=0;tt.step(new Gl(e.from,e.to,e.style))))}(this,t,e,n),this}clearIncompatible(t,e,n){return function(t,e,n,r=n.contentMatch){let i=t.doc.nodeAt(e),o=[],s=e+1;for(let a=0;a=0;a--)t.step(o[a])}(this,t,e,n),this}}const kc=Object.create(null);class Sc{constructor(t,e,n){this.$anchor=t,this.$head=e,this.ranges=n||[new Oc(t.min(e),t.max(e))]}get anchor(){return this.$anchor.pos}get head(){return this.$head.pos}get from(){return this.$from.pos}get to(){return this.$to.pos}get $from(){return this.ranges[0].$from}get $to(){return this.ranges[0].$to}get empty(){let t=this.ranges;for(let e=0;e=0;i--){let r=e<0?Ec(t.node(0),t.node(i),t.before(i+1),t.index(i),e,n):Ec(t.node(0),t.node(i),t.after(i+1),t.index(i)+1,e,n);if(r)return r}return null}static near(t,e=1){return this.findFrom(t,e)||this.findFrom(t,-e)||new Dc(t.node(0))}static atStart(t){return Ec(t,t,0,0,1)||new Dc(t)}static atEnd(t){return Ec(t,t,t.content.size,t.childCount,-1)||new Dc(t)}static fromJSON(t,e){if(!e||!e.type)throw new RangeError("Invalid input for Selection.fromJSON");let n=kc[e.type];if(!n)throw new RangeError(`No selection type ${e.type} defined`);return n.fromJSON(t,e)}static jsonID(t,e){if(t in kc)throw new RangeError("Duplicate use of selection JSON ID "+t);return kc[t]=e,e.prototype.jsonID=t,e}getBookmark(){return Cc.between(this.$anchor,this.$head).getBookmark()}}Sc.prototype.visible=!0;class Oc{constructor(t,e){this.$from=t,this.$to=e}}let _c=!1;function Mc(t){_c||t.parent.inlineContent||(_c=!0,console.warn("TextSelection endpoint not pointing into a node with inline content ("+t.parent.type.name+")"))}class Cc extends Sc{constructor(t,e=t){Mc(t),Mc(e),super(t,e)}get $cursor(){return this.$anchor.pos==this.$head.pos?this.$head:null}map(t,e){let n=t.resolve(e.map(this.head));if(!n.parent.inlineContent)return Sc.near(n);let r=t.resolve(e.map(this.anchor));return new Cc(r.parent.inlineContent?r:n,n)}replace(t,e=qa.empty){if(super.replace(t,e),e==qa.empty){let e=this.$from.marksAcross(this.$to);e&&t.ensureMarks(e)}}eq(t){return t instanceof Cc&&t.anchor==this.anchor&&t.head==this.head}getBookmark(){return new $c(this.anchor,this.head)}toJSON(){return{type:"text",anchor:this.anchor,head:this.head}}static fromJSON(t,e){if("number"!=typeof e.anchor||"number"!=typeof e.head)throw new RangeError("Invalid input for TextSelection.fromJSON");return new Cc(t.resolve(e.anchor),t.resolve(e.head))}static create(t,e,n=e){let r=t.resolve(e);return new this(r,n==e?r:t.resolve(n))}static between(t,e,n){let r=t.pos-e.pos;if(n&&!r||(n=r>=0?1:-1),!e.parent.inlineContent){let t=Sc.findFrom(e,n,!0)||Sc.findFrom(e,-n,!0);if(!t)return Sc.near(e,n);e=t.$head}return t.parent.inlineContent||(0==r||(t=(Sc.findFrom(t,-n,!0)||Sc.findFrom(t,n,!0)).$anchor).posnew Dc(t)};function Ec(t,e,n,r,i,o=!1){if(e.inlineContent)return Cc.create(t,n);for(let s=r-(i>0?0:1);i>0?s=0;s+=i){let r=e.child(s);if(r.isAtom){if(!o&&Nc.isSelectable(r))return Nc.create(t,n-(i<0?r.nodeSize:0))}else{let e=Ec(t,r,n+i,i<0?r.childCount:0,i,o);if(e)return e}n+=r.nodeSize*i}return null}function Pc(t,e,n){let r=t.steps.length-1;if(r{null==i&&(i=r)})),t.setSelection(Sc.near(t.doc.resolve(i),n)))}class Ic extends xc{constructor(t){super(t.doc),this.curSelectionFor=0,this.updated=0,this.meta=Object.create(null),this.time=Date.now(),this.curSelection=t.selection,this.storedMarks=t.storedMarks}get selection(){return this.curSelectionFor0}setStoredMarks(t){return this.storedMarks=t,this.updated|=2,this}ensureMarks(t){return Ba.sameSet(this.storedMarks||this.selection.$from.marks(),t)||this.setStoredMarks(t),this}addStoredMark(t){return this.ensureMarks(t.addToSet(this.storedMarks||this.selection.$head.marks()))}removeStoredMark(t){return this.ensureMarks(t.removeFromSet(this.storedMarks||this.selection.$head.marks()))}get storedMarksSet(){return(2&this.updated)>0}addStep(t,e){super.addStep(t,e),this.updated=-3&this.updated,this.storedMarks=null}setTime(t){return this.time=t,this}replaceSelection(t){return this.selection.replace(this,t),this}replaceSelectionWith(t,e=!0){let n=this.selection;return e&&(t=t.mark(this.storedMarks||(n.empty?n.$from.marks():n.$from.marksAcross(n.$to)||Ba.none))),n.replaceWith(this,t),this}deleteSelection(){return this.selection.replace(this),this}insertText(t,e,n){let r=this.doc.type.schema;if(null==e)return t?this.replaceSelectionWith(r.text(t),!0):this.deleteSelection();{if(null==n&&(n=e),n=null==n?e:n,!t)return this.deleteRange(e,n);let i=this.storedMarks;if(!i){let t=this.doc.resolve(e);i=n==e?t.marks():t.marksAcross(this.doc.resolve(n))}return this.replaceRangeWith(e,n,r.text(t,i)),this.selection.empty||this.setSelection(Sc.near(this.selection.$to)),this}}setMeta(t,e){return this.meta["string"==typeof t?t:t.key]=e,this}getMeta(t){return this.meta["string"==typeof t?t:t.key]}get isGeneric(){for(let t in this.meta)return!1;return!0}scrollIntoView(){return this.updated|=4,this}get scrolledIntoView(){return(4&this.updated)>0}}function Rc(t,e){return e&&t?t.bind(e):t}class zc{constructor(t,e,n){this.name=t,this.init=Rc(e.init,n),this.apply=Rc(e.apply,n)}}const jc=[new zc("doc",{init:t=>t.doc||t.schema.topNodeType.createAndFill(),apply:t=>t.doc}),new zc("selection",{init:(t,e)=>t.selection||Sc.atStart(e.doc),apply:t=>t.selection}),new zc("storedMarks",{init:t=>t.storedMarks||null,apply:(t,e,n,r)=>r.selection.$cursor?t.storedMarks:null}),new zc("scrollToSelection",{init:()=>0,apply:(t,e)=>t.scrolledIntoView?e+1:e})];class Fc{constructor(t,e){this.schema=t,this.plugins=[],this.pluginsByKey=Object.create(null),this.fields=jc.slice(),e&&e.forEach((t=>{if(this.pluginsByKey[t.key])throw new RangeError("Adding different instances of a keyed plugin ("+t.key+")");this.plugins.push(t),this.pluginsByKey[t.key]=t,t.spec.state&&this.fields.push(new zc(t.key,t.spec.state,t))}))}}class Lc{constructor(t){this.config=t}get schema(){return this.config.schema}get plugins(){return this.config.plugins}apply(t){return this.applyTransaction(t).state}filterTransaction(t,e=-1){for(let n=0;nt.toJSON()))),t&&"object"==typeof t)for(let n in t){if("doc"==n||"selection"==n)throw new RangeError("The JSON fields `doc` and `selection` are reserved");let r=t[n],i=r.spec.state;i&&i.toJSON&&(e[n]=i.toJSON.call(r,this[r.key]))}return e}static fromJSON(t,e,n){if(!e)throw new RangeError("Invalid input for EditorState.fromJSON");if(!t.schema)throw new RangeError("Required config field 'schema' missing");let r=new Fc(t.schema,t.plugins),i=new Lc(r);return r.fields.forEach((r=>{if("doc"==r.name)i.doc=al.fromJSON(t.schema,e.doc);else if("selection"==r.name)i.selection=Sc.fromJSON(i.doc,e.selection);else if("storedMarks"==r.name)e.storedMarks&&(i.storedMarks=e.storedMarks.map(t.schema.markFromJSON));else{if(n)for(let o in n){let s=n[o],a=s.spec.state;if(s.key==r.name&&a&&a.fromJSON&&Object.prototype.hasOwnProperty.call(e,o))return void(i[r.name]=a.fromJSON.call(s,t,e[o],i))}i[r.name]=r.init(t,i)}})),i}}function Bc(t,e,n){for(let r in t){let i=t[r];i instanceof Function?i=i.bind(e):"handleDOMEvents"==r&&(i=Bc(i,e,{})),n[r]=i}return n}class Vc{constructor(t){this.spec=t,this.props={},t.props&&Bc(t.props,this,this.props),this.key=t.key?t.key.key:Jc("plugin")}getState(t){return t[this.key]}}const qc=Object.create(null);function Jc(t){return t in qc?t+"$"+ ++qc[t]:(qc[t]=0,t+"$")}class Wc{constructor(t="key"){this.key=Jc(t)}get(t){return t.config.pluginsByKey[this.key]}getState(t){return t[this.key]}}const Hc=function(t){for(var e=0;;e++)if(!(t=t.previousSibling))return e},Kc=function(t){let e=t.assignedSlot||t.parentNode;return e&&11==e.nodeType?e.host:e};let Uc=null;const Yc=function(t,e,n){let r=Uc||(Uc=document.createRange());return r.setEnd(t,null==n?t.nodeValue.length:n),r.setStart(t,e||0),r},Gc=function(t,e,n,r){return n&&(Xc(t,e,n,r,-1)||Xc(t,e,n,r,1))},Zc=/^(img|br|input|textarea|hr)$/i;function Xc(t,e,n,r,i){for(;;){if(t==n&&e==r)return!0;if(e==(i<0?0:Qc(t))){let n=t.parentNode;if(!n||1!=n.nodeType||tu(t)||Zc.test(t.nodeName)||"false"==t.contentEditable)return!1;e=Hc(t)+(i<0?0:1),t=n}else{if(1!=t.nodeType)return!1;if("false"==(t=t.childNodes[e+(i<0?-1:0)]).contentEditable)return!1;e=i<0?Qc(t):0}}}function Qc(t){return 3==t.nodeType?t.nodeValue.length:t.childNodes.length}function tu(t){let e;for(let n=t;n&&!(e=n.pmViewDesc);n=n.parentNode);return e&&e.node&&e.node.isBlock&&(e.dom==t||e.contentDOM==t)}const eu=function(t){return t.focusNode&&Gc(t.focusNode,t.focusOffset,t.anchorNode,t.anchorOffset)};function nu(t,e){let n=document.createEvent("Event");return n.initEvent("keydown",!0,!0),n.keyCode=t,n.key=n.code=e,n}const ru="undefined"!=typeof navigator?navigator:null,iu="undefined"!=typeof document?document:null,ou=ru&&ru.userAgent||"",su=/Edge\/(\d+)/.exec(ou),au=/MSIE \d/.exec(ou),lu=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(ou),cu=!!(au||lu||su),uu=au?document.documentMode:lu?+lu[1]:su?+su[1]:0,du=!cu&&/gecko\/(\d+)/i.test(ou);du&&(/Firefox\/(\d+)/.exec(ou)||[0,0])[1];const fu=!cu&&/Chrome\/(\d+)/.exec(ou),hu=!!fu,pu=fu?+fu[1]:0,mu=!cu&&!!ru&&/Apple Computer/.test(ru.vendor),gu=mu&&(/Mobile\/\w+/.test(ou)||!!ru&&ru.maxTouchPoints>2),vu=gu||!!ru&&/Mac/.test(ru.platform),yu=/Android \d/.test(ou),bu=!!iu&&"webkitFontSmoothing"in iu.documentElement.style,wu=bu?+(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent)||[0,0])[1]:0;function xu(t){return{left:0,right:t.documentElement.clientWidth,top:0,bottom:t.documentElement.clientHeight}}function ku(t,e){return"number"==typeof t?t:t[e]}function Su(t){let e=t.getBoundingClientRect(),n=e.width/t.offsetWidth||1,r=e.height/t.offsetHeight||1;return{left:e.left,right:e.left+t.clientWidth*n,top:e.top,bottom:e.top+t.clientHeight*r}}function Ou(t,e,n){let r=t.someProp("scrollThreshold")||0,i=t.someProp("scrollMargin")||5,o=t.dom.ownerDocument;for(let s=n||t.dom;s;s=Kc(s)){if(1!=s.nodeType)continue;let t=s,n=t==o.body,a=n?xu(o):Su(t),l=0,c=0;if(e.topa.bottom-ku(r,"bottom")&&(c=e.bottom-a.bottom+ku(i,"bottom")),e.lefta.right-ku(r,"right")&&(l=e.right-a.right+ku(i,"right")),l||c)if(n)o.defaultView.scrollBy(l,c);else{let n=t.scrollLeft,r=t.scrollTop;c&&(t.scrollTop+=c),l&&(t.scrollLeft+=l);let i=t.scrollLeft-n,o=t.scrollTop-r;e={left:e.left-i,top:e.top-o,right:e.right-i,bottom:e.bottom-o}}if(n)break}}function _u(t){let e=[],n=t.ownerDocument;for(let r=t;r&&(e.push({dom:r,top:r.scrollTop,left:r.scrollLeft}),t!=n);r=Kc(r));return e}function Mu(t,e){for(let n=0;n=a){s=Math.max(d.bottom,s),a=Math.min(d.top,a);let t=d.left>e.left?d.left-e.left:d.right=(d.left+d.right)/2?1:0));continue}}!n&&(e.left>=d.right&&e.top>=d.top||e.left>=d.left&&e.top>=d.bottom)&&(o=c+1)}}return n&&3==n.nodeType?function(t,e){let n=t.nodeValue.length,r=document.createRange();for(let i=0;i=(n.left+n.right)/2?1:0)}}return{node:t,offset:0}}(n,r):!n||i&&1==n.nodeType?{node:t,offset:o}:$u(n,r)}function Nu(t,e){return t.left>=e.left-1&&t.left<=e.right+1&&t.top>=e.top-1&&t.top<=e.bottom+1}function Tu(t,e,n){let r=t.childNodes.length;if(r&&n.tope.top&&i++}n==t.dom&&i==n.childNodes.length-1&&1==n.lastChild.nodeType&&e.top>n.lastChild.getBoundingClientRect().bottom?o=t.state.doc.content.size:0!=i&&1==n.nodeType&&"BR"==n.childNodes[i-1].nodeName||(o=function(t,e,n,r){let i=-1;for(let o=e;o!=t.dom;){let e=t.docView.nearestDesc(o,!0);if(!e)return null;if(e.node.isBlock&&e.parent){let t=e.dom.getBoundingClientRect();if(t.left>r.left||t.top>r.top)i=e.posBefore;else{if(!(t.right-1?i:t.docView.posFromDOM(e,n,1)}(t,n,i,e))}null==o&&(o=function(t,e,n){let{node:r,offset:i}=$u(e,n),o=-1;if(1==r.nodeType&&!r.firstChild){let t=r.getBoundingClientRect();o=t.left!=t.right&&n.left>(t.left+t.right)/2?1:-1}return t.docView.posFromDOM(r,i,o)}(t,s,e));let a=t.docView.nearestDesc(s,!0);return{pos:o,inside:a?a.posAtStart-a.border:-1}}function Au(t,e){let n=t.getClientRects();return n.length?n[e<0?0:n.length-1]:t.getBoundingClientRect()}const Eu=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;function Pu(t,e,n){let{node:r,offset:i,atom:o}=t.docView.domFromPos(e,n<0?-1:1),s=bu||du;if(3==r.nodeType){if(!s||!Eu.test(r.nodeValue)&&(n<0?i:i!=r.nodeValue.length)){let t=i,e=i,o=n<0?1:-1;return n<0&&!i?(e++,o=-1):n>=0&&i==r.nodeValue.length?(t--,o=1):n<0?t--:e++,Iu(Au(Yc(r,t,e),1),o<0)}{let t=Au(Yc(r,i,i),n);if(du&&i&&/\s/.test(r.nodeValue[i-1])&&i=0)}if(null==o&&i&&(n<0||i==Qc(r))){let t=r.childNodes[i-1],e=3==t.nodeType?Yc(t,Qc(t)-(s?0:1)):1!=t.nodeType||"BR"==t.nodeName&&t.nextSibling?null:t;if(e)return Iu(Au(e,1),!1)}if(null==o&&i=0)}function Iu(t,e){if(0==t.width)return t;let n=e?t.left:t.right;return{top:t.top,bottom:t.bottom,left:n,right:n}}function Ru(t,e){if(0==t.height)return t;let n=e?t.top:t.bottom;return{top:n,bottom:n,left:t.left,right:t.right}}function zu(t,e,n){let r=t.state,i=t.root.activeElement;r!=e&&t.updateState(e),i!=t.dom&&t.focus();try{return n()}finally{r!=e&&t.updateState(r),i!=t.dom&&i&&i.focus()}}const ju=/[\u0590-\u08ac]/;let Fu=null,Lu=null,Bu=!1;function Vu(t,e,n){return Fu==e&&Lu==n?Bu:(Fu=e,Lu=n,Bu="up"==n||"down"==n?function(t,e,n){let r=e.selection,i="up"==n?r.$from:r.$to;return zu(t,e,(()=>{let{node:e}=t.docView.domFromPos(i.pos,"up"==n?-1:1);for(;;){let n=t.docView.nearestDesc(e,!0);if(!n)break;if(n.node.isBlock){e=n.dom;break}e=n.dom.parentNode}let r=Pu(t,i.pos,1);for(let t=e.firstChild;t;t=t.nextSibling){let e;if(1==t.nodeType)e=t.getClientRects();else{if(3!=t.nodeType)continue;e=Yc(t,0,t.nodeValue.length).getClientRects()}for(let t=0;ti.top+1&&("up"==n?r.top-i.top>2*(i.bottom-r.top):i.bottom-r.bottom>2*(r.bottom-i.top)))return!1}}return!0}))}(t,e,n):function(t,e,n){let{$head:r}=e.selection;if(!r.parent.isTextblock)return!1;let i=r.parentOffset,o=!i,s=i==r.parent.content.size,a=t.domSelection();return ju.test(r.parent.textContent)&&a.modify?zu(t,e,(()=>{let{focusNode:e,focusOffset:i,anchorNode:o,anchorOffset:s}=t.domSelectionRange(),l=a.caretBidiLevel;a.modify("move",n,"character");let c=r.depth?t.docView.domAfterPos(r.before()):t.dom,{focusNode:u,focusOffset:d}=t.domSelectionRange(),f=u&&!c.contains(1==u.nodeType?u:u.parentNode)||e==u&&i==d;try{a.collapse(o,s),e&&(e!=o||i!=s)&&a.extend&&a.extend(e,i)}catch(h){}return null!=l&&(a.caretBidiLevel=l),f})):"left"==n||"backward"==n?o:s}(t,e,n))}class qu{constructor(t,e,n,r){this.parent=t,this.children=e,this.dom=n,this.contentDOM=r,this.dirty=0,n.pmViewDesc=this}matchesWidget(t){return!1}matchesMark(t){return!1}matchesNode(t,e,n){return!1}matchesHack(t){return!1}parseRule(){return null}stopEvent(t){return!1}get size(){let t=0;for(let e=0;eHc(this.contentDOM);else if(this.contentDOM&&this.contentDOM!=this.dom&&this.dom.contains(this.contentDOM))r=2&t.compareDocumentPosition(this.contentDOM);else if(this.dom.firstChild){if(0==e)for(let e=t;;e=e.parentNode){if(e==this.dom){r=!1;break}if(e.previousSibling)break}if(null==r&&e==t.childNodes.length)for(let e=t;;e=e.parentNode){if(e==this.dom){r=!0;break}if(e.nextSibling)break}}return(null==r?n>0:r)?this.posAtEnd:this.posAtStart}nearestDesc(t,e=!1){for(let n=!0,r=t;r;r=r.parentNode){let i,o=this.getDesc(r);if(o&&(!e||o.node)){if(!n||!(i=o.nodeDOM)||(1==i.nodeType?i.contains(1==t.nodeType?t:t.parentNode):i==t))return o;n=!1}}}getDesc(t){let e=t.pmViewDesc;for(let n=e;n;n=n.parent)if(n==this)return e}posFromDOM(t,e,n){for(let r=t;r;r=r.parentNode){let i=this.getDesc(r);if(i)return i.localPosFromDOM(t,e,n)}return-1}descAt(t){for(let e=0,n=0;et||e instanceof Gu){i=t-o;break}o=n}if(i)return this.children[r].domFromPos(i-this.children[r].border,e);for(;r&&!(n=this.children[r-1]).size&&n instanceof Ju&&n.side>=0;r--);if(e<=0){let t,n=!0;for(;t=r?this.children[r-1]:null,t&&t.dom.parentNode!=this.contentDOM;r--,n=!1);return t&&e&&n&&!t.border&&!t.domAtom?t.domFromPos(t.size,e):{node:this.contentDOM,offset:t?Hc(t.dom)+1:0}}{let t,n=!0;for(;t=r=i&&e<=a-n.border&&n.node&&n.contentDOM&&this.contentDOM.contains(n.contentDOM))return n.parseRange(t,e,i);t=o;for(let e=s;e>0;e--){let n=this.children[e-1];if(n.size&&n.dom.parentNode==this.contentDOM&&!n.emptyChildAt(1)){r=Hc(n.dom)+1;break}t-=n.size}-1==r&&(r=0)}if(r>-1&&(a>e||s==this.children.length-1)){e=a;for(let t=s+1;th&&oe){let t=s;s=a,a=t}let n=document.createRange();n.setEnd(a.node,a.offset),n.setStart(s.node,s.offset),l.removeAllRanges(),l.addRange(n)}}ignoreMutation(t){return!this.contentDOM&&"selection"!=t.type}get contentLost(){return this.contentDOM&&this.contentDOM!=this.dom&&!this.dom.contains(this.contentDOM)}markDirty(t,e){for(let n=0,r=0;r=n:tn){let r=n+i.border,s=o-i.border;if(t>=r&&e<=s)return this.dirty=t==n||e==o?2:1,void(t!=r||e!=s||!i.contentLost&&i.dom.parentNode==this.contentDOM?i.markDirty(t-r,e-r):i.dirty=3);i.dirty=i.dom!=i.contentDOM||i.dom.parentNode!=this.contentDOM||i.children.length?3:2}n=o}this.dirty=2}markParentsDirty(){let t=1;for(let e=this.parent;e;e=e.parent,t++){let n=1==t?2:1;e.dirtyi?i.parent?i.parent.posBeforeChild(i):void 0:r))),!e.type.spec.raw){if(1!=o.nodeType){let t=document.createElement("span");t.appendChild(o),o=t}o.contentEditable="false",o.classList.add("ProseMirror-widget")}super(t,[],o,null),this.widget=e,this.widget=e,i=this}matchesWidget(t){return 0==this.dirty&&t.type.eq(this.widget.type)}parseRule(){return{ignore:!0}}stopEvent(t){let e=this.widget.spec.stopEvent;return!!e&&e(t)}ignoreMutation(t){return"selection"!=t.type||this.widget.spec.ignoreSelection}destroy(){this.widget.type.destroy(this.dom),super.destroy()}get domAtom(){return!0}get side(){return this.widget.type.side}}class Wu extends qu{constructor(t,e,n,r){super(t,[],e,null),this.textDOM=n,this.text=r}get size(){return this.text.length}localPosFromDOM(t,e){return t!=this.textDOM?this.posAtStart+(e?this.size:0):this.posAtStart+e}domFromPos(t){return{node:this.textDOM,offset:t}}ignoreMutation(t){return"characterData"===t.type&&t.target.nodeValue==t.oldValue}}class Hu extends qu{constructor(t,e,n,r){super(t,[],n,r),this.mark=e}static create(t,e,n,r){let i=r.nodeViews[e.type.name],o=i&&i(e,r,n);return o&&o.dom||(o=zl.renderSpec(document,e.type.spec.toDOM(e,n))),new Hu(t,e,o.dom,o.contentDOM||o.dom)}parseRule(){return 3&this.dirty||this.mark.type.spec.reparseInView?null:{mark:this.mark.type.name,attrs:this.mark.attrs,contentElement:this.contentDOM||void 0}}matchesMark(t){return 3!=this.dirty&&this.mark.eq(t)}markDirty(t,e){if(super.markDirty(t,e),0!=this.dirty){let t=this.parent;for(;!t.node;)t=t.parent;t.dirty0&&(i=cd(i,0,t,n));for(let s=0;ss?s.parent?s.parent.posBeforeChild(s):void 0:o),n,r),c=l&&l.dom,u=l&&l.contentDOM;if(e.isText)if(c){if(3!=c.nodeType)throw new RangeError("Text must be rendered as a DOM text node")}else c=document.createTextNode(e.text);else c||({dom:c,contentDOM:u}=zl.renderSpec(document,e.type.spec.toDOM(e)));u||e.isText||"BR"==c.nodeName||(c.hasAttribute("contenteditable")||(c.contentEditable="false"),e.type.spec.draggable&&(c.draggable=!0));let d=c;return c=id(c,n,e),l?s=new Zu(t,e,n,r,c,u||null,d,l,i,o+1):e.isText?new Yu(t,e,n,r,c,d,i):new Ku(t,e,n,r,c,u||null,d,i,o+1)}parseRule(){if(this.node.type.spec.reparseInView)return null;let t={node:this.node.type.name,attrs:this.node.attrs};if("pre"==this.node.type.whitespace&&(t.preserveWhitespace="full"),this.contentDOM)if(this.contentLost){for(let e=this.children.length-1;e>=0;e--){let n=this.children[e];if(this.dom.contains(n.dom.parentNode)){t.contentElement=n.dom.parentNode;break}}t.contentElement||(t.getContent=()=>za.empty)}else t.contentElement=this.contentDOM;else t.getContent=()=>this.node.content;return t}matchesNode(t,e,n){return 0==this.dirty&&t.eq(this.node)&&od(e,this.outerDeco)&&n.eq(this.innerDeco)}get size(){return this.node.nodeSize}get border(){return this.node.isLeaf?0:1}updateChildren(t,e){let n=this.node.inlineContent,r=e,i=t.composing?this.localCompositionInfo(t,e):null,o=i&&i.pos>-1?i:null,s=i&&i.pos<0,a=new ad(this,o&&o.node,t);!function(t,e,n,r){let i=e.locals(t),o=0;if(0==i.length){for(let n=0;no;)a.push(i[s++]);let f=o+u.nodeSize;if(u.isText){let t=f;s!t.inline)):a.slice(),e.forChild(o,u),d),o=f}}(this.node,this.innerDeco,((e,i,o)=>{e.spec.marks?a.syncToMarks(e.spec.marks,n,t):e.type.side>=0&&!o&&a.syncToMarks(i==this.node.childCount?Ba.none:this.node.child(i).marks,n,t),a.placeWidget(e,t,r)}),((e,o,l,c)=>{let u;a.syncToMarks(e.marks,n,t),a.findNodeMatch(e,o,l,c)||s&&t.state.selection.from>r&&t.state.selection.to-1&&a.updateNodeAt(e,o,l,u,t)||a.updateNextNode(e,o,l,t,c)||a.addNode(e,o,l,t,r),r+=e.nodeSize})),a.syncToMarks([],n,t),this.node.isTextblock&&a.addTextblockHacks(),a.destroyRest(),(a.changed||2==this.dirty)&&(o&&this.protectLocalComposition(t,o),Xu(this.contentDOM,this.children,t),gu&&function(t){if("UL"==t.nodeName||"OL"==t.nodeName){let e=t.style.cssText;t.style.cssText=e+"; list-style: square !important",window.getComputedStyle(t).listStyle,t.style.cssText=e}}(this.dom))}localCompositionInfo(t,e){let{from:n,to:r}=t.state.selection;if(!(t.state.selection instanceof Cc)||ne+this.node.content.size)return null;let i=t.domSelectionRange(),o=function(t,e){for(;;){if(3==t.nodeType)return t;if(1==t.nodeType&&e>0){if(t.childNodes.length>e&&3==t.childNodes[e].nodeType)return t.childNodes[e];e=Qc(t=t.childNodes[e-1])}else{if(!(1==t.nodeType&&e=n){let t=a=0&&t+e.length+a>=n)return a+t;if(n==r&&l.length>=r+e.length-a&&l.slice(r-a,r-a+e.length)==e)return r}}return-1}(this.node.content,t,n-e,r-e);return i<0?null:{node:o,pos:i,text:t}}return{node:o,pos:-1,text:""}}protectLocalComposition(t,{node:e,pos:n,text:r}){if(this.getDesc(e))return;let i=e;for(;i.parentNode!=this.contentDOM;i=i.parentNode){for(;i.previousSibling;)i.parentNode.removeChild(i.previousSibling);for(;i.nextSibling;)i.parentNode.removeChild(i.nextSibling);i.pmViewDesc&&(i.pmViewDesc=void 0)}let o=new Wu(this,i,e,r);t.input.compositionNodes.push(o),this.children=cd(this.children,n,n+r.length,t,o)}update(t,e,n,r){return!(3==this.dirty||!t.sameMarkup(this.node))&&(this.updateInner(t,e,n,r),!0)}updateInner(t,e,n,r){this.updateOuterDeco(e),this.node=t,this.innerDeco=n,this.contentDOM&&this.updateChildren(r,this.posAtStart),this.dirty=0}updateOuterDeco(t){if(od(t,this.outerDeco))return;let e=1!=this.nodeDOM.nodeType,n=this.dom;this.dom=nd(this.dom,this.nodeDOM,ed(this.outerDeco,this.node,e),ed(t,this.node,e)),this.dom!=n&&(n.pmViewDesc=void 0,this.dom.pmViewDesc=this),this.outerDeco=t}selectNode(){1==this.nodeDOM.nodeType&&this.nodeDOM.classList.add("ProseMirror-selectednode"),!this.contentDOM&&this.node.type.spec.draggable||(this.dom.draggable=!0)}deselectNode(){1==this.nodeDOM.nodeType&&this.nodeDOM.classList.remove("ProseMirror-selectednode"),!this.contentDOM&&this.node.type.spec.draggable||this.dom.removeAttribute("draggable")}get domAtom(){return this.node.isAtom}}function Uu(t,e,n,r,i){return id(r,e,t),new Ku(void 0,t,e,n,r,r,r,i,0)}class Yu extends Ku{constructor(t,e,n,r,i,o,s){super(t,e,n,r,i,null,o,s,0)}parseRule(){let t=this.nodeDOM.parentNode;for(;t&&t!=this.dom&&!t.pmIsDeco;)t=t.parentNode;return{skip:t||!0}}update(t,e,n,r){return!(3==this.dirty||0!=this.dirty&&!this.inParent()||!t.sameMarkup(this.node))&&(this.updateOuterDeco(e),0==this.dirty&&t.text==this.node.text||t.text==this.nodeDOM.nodeValue||(this.nodeDOM.nodeValue=t.text,r.trackWrites==this.nodeDOM&&(r.trackWrites=null)),this.node=t,this.dirty=0,!0)}inParent(){let t=this.parent.contentDOM;for(let e=this.nodeDOM;e;e=e.parentNode)if(e==t)return!0;return!1}domFromPos(t){return{node:this.nodeDOM,offset:t}}localPosFromDOM(t,e,n){return t==this.nodeDOM?this.posAtStart+Math.min(e,this.node.text.length):super.localPosFromDOM(t,e,n)}ignoreMutation(t){return"characterData"!=t.type&&"selection"!=t.type}slice(t,e,n){let r=this.node.cut(t,e),i=document.createTextNode(r.text);return new Yu(this.parent,r,this.outerDeco,this.innerDeco,i,i,n)}markDirty(t,e){super.markDirty(t,e),this.dom==this.nodeDOM||0!=t&&e!=this.nodeDOM.nodeValue.length||(this.dirty=3)}get domAtom(){return!1}}class Gu extends qu{parseRule(){return{ignore:!0}}matchesHack(t){return 0==this.dirty&&this.dom.nodeName==t}get domAtom(){return!0}get ignoreForCoords(){return"IMG"==this.dom.nodeName}}class Zu extends Ku{constructor(t,e,n,r,i,o,s,a,l,c){super(t,e,n,r,i,o,s,l,c),this.spec=a}update(t,e,n,r){if(3==this.dirty)return!1;if(this.spec.update){let i=this.spec.update(t,e,n);return i&&this.updateInner(t,e,n,r),i}return!(!this.contentDOM&&!t.isLeaf)&&super.update(t,e,n,r)}selectNode(){this.spec.selectNode?this.spec.selectNode():super.selectNode()}deselectNode(){this.spec.deselectNode?this.spec.deselectNode():super.deselectNode()}setSelection(t,e,n,r){this.spec.setSelection?this.spec.setSelection(t,e,n):super.setSelection(t,e,n,r)}destroy(){this.spec.destroy&&this.spec.destroy(),super.destroy()}stopEvent(t){return!!this.spec.stopEvent&&this.spec.stopEvent(t)}ignoreMutation(t){return this.spec.ignoreMutation?this.spec.ignoreMutation(t):super.ignoreMutation(t)}}function Xu(t,e,n){let r=t.firstChild,i=!1;for(let o=0;o0;){let a;for(;;)if(r){let t=n.children[r-1];if(!(t instanceof Hu)){a=t,r--;break}n=t,r=t.children.length}else{if(n==e)break t;r=n.parent.children.indexOf(n),n=n.parent}let l=a.node;if(l){if(l!=t.child(i-1))break;--i,o.set(a,i),s.push(a)}}return{index:i,matched:o,matches:s.reverse()}}(t.node.content,t)}destroyBetween(t,e){if(t!=e){for(let n=t;n>1,o=Math.min(i,t.length);for(;r-1)r>this.index&&(this.changed=!0,this.destroyBetween(this.index,r)),this.top=this.top.children[this.index];else{let r=Hu.create(this.top,t[i],e,n);this.top.children.splice(this.index,0,r),this.top=r,this.changed=!0}this.index=0,i++}}findNodeMatch(t,e,n,r){let i,o=-1;if(r>=this.preMatch.index&&(i=this.preMatch.matches[r-this.preMatch.index]).parent==this.top&&i.matchesNode(t,e,n))o=this.top.children.indexOf(i,this.index);else for(let s=this.index,a=Math.min(this.top.children.length,s+5);s=n||u<=e?o.push(l):(cn&&o.push(l.slice(n-c,l.size,r)))}return o}function ud(t,e=null){let n=t.domSelectionRange(),r=t.state.doc;if(!n.focusNode)return null;let i=t.docView.nearestDesc(n.focusNode),o=i&&0==i.size,s=t.docView.posFromDOM(n.focusNode,n.focusOffset,1);if(s<0)return null;let a,l,c=r.resolve(s);if(eu(n)){for(a=c;i&&!i.node;)i=i.parent;let t=i.node;if(i&&t.isAtom&&Nc.isSelectable(t)&&i.parent&&(!t.isInline||!function(t,e,n){for(let r=0==e,i=e==Qc(t);r||i;){if(t==n)return!0;let e=Hc(t);if(!(t=t.parentNode))return!1;r=r&&0==e,i=i&&e==Qc(t)}}(n.focusNode,n.focusOffset,i.dom))){let t=i.posBefore;l=new Nc(s==t?c:r.resolve(t))}}else{let e=t.docView.posFromDOM(n.anchorNode,n.anchorOffset,1);if(e<0)return null;a=r.resolve(e)}if(!l){l=bd(t,a,c,"pointer"==e||t.state.selection.head{n.anchorNode==r&&n.anchorOffset==i||(e.removeEventListener("selectionchange",t.input.hideSelectionGuard),setTimeout((()=>{dd(t)&&!t.state.selection.visible||t.dom.classList.remove("ProseMirror-hideselection")}),20))})}(t))}t.domObserver.setCurSelection(),t.domObserver.connectSelection()}}const hd=mu||hu&&pu<63;function pd(t,e){let{node:n,offset:r}=t.docView.domFromPos(e,0),i=rr(t,e,n)))||Cc.between(e,n,r)}function wd(t){return!(t.editable&&!t.hasFocus())&&xd(t)}function xd(t){let e=t.domSelectionRange();if(!e.anchorNode)return!1;try{return t.dom.contains(3==e.anchorNode.nodeType?e.anchorNode.parentNode:e.anchorNode)&&(t.editable||t.dom.contains(3==e.focusNode.nodeType?e.focusNode.parentNode:e.focusNode))}catch(n){return!1}}function kd(t,e){let{$anchor:n,$head:r}=t.selection,i=e>0?n.max(r):n.min(r),o=i.parent.inlineContent?i.depth?t.doc.resolve(e>0?i.after():i.before()):null:i;return o&&Sc.findFrom(o,e)}function Sd(t,e){return t.dispatch(t.state.tr.setSelection(e).scrollIntoView()),!0}function Od(t,e,n){let r=t.state.selection;if(!(r instanceof Cc)){if(r instanceof Nc&&r.node.isInline)return Sd(t,new Cc(e>0?r.$to:r.$from));{let n=kd(t.state,e);return!!n&&Sd(t,n)}}if(!r.empty||n.indexOf("s")>-1)return!1;if(t.endOfTextblock(e>0?"right":"left")){let n=kd(t.state,e);return!!(n&&n instanceof Nc)&&Sd(t,n)}if(!(vu&&n.indexOf("m")>-1)){let n,i=r.$head,o=i.textOffset?null:e<0?i.nodeBefore:i.nodeAfter;if(!o||o.isText)return!1;let s=e<0?i.pos-o.nodeSize:i.pos;return!!(o.isAtom||(n=t.docView.descAt(s))&&!n.contentDOM)&&(Nc.isSelectable(o)?Sd(t,new Nc(e<0?t.state.doc.resolve(i.pos-o.nodeSize):i)):!!bu&&Sd(t,new Cc(t.state.doc.resolve(e<0?s:s+o.nodeSize))))}}function _d(t){return 3==t.nodeType?t.nodeValue.length:t.childNodes.length}function Md(t){let e=t.pmViewDesc;return e&&0==e.size&&(t.nextSibling||"BR"!=t.nodeName)}function Cd(t){let e=t.domSelectionRange(),n=e.focusNode,r=e.focusOffset;if(!n)return;let i,o,s=!1;for(du&&1==n.nodeType&&r<_d(n)&&Md(n.childNodes[r])&&(s=!0);;)if(r>0){if(1!=n.nodeType)break;{let t=n.childNodes[r-1];if(Md(t))i=n,o=--r;else{if(3!=t.nodeType)break;n=t,r=n.nodeValue.length}}}else{if(Nd(n))break;{let e=n.previousSibling;for(;e&&Md(e);)i=n.parentNode,o=Hc(e),e=e.previousSibling;if(e)n=e,r=_d(n);else{if(n=n.parentNode,n==t.dom)break;r=0}}}s?Td(t,n,r):i&&Td(t,i,o)}function $d(t){let e=t.domSelectionRange(),n=e.focusNode,r=e.focusOffset;if(!n)return;let i,o,s=_d(n);for(;;)if(r{t.state==i&&fd(t)}),50)}function Dd(t,e,n){let r=t.state.selection;if(r instanceof Cc&&!r.empty||n.indexOf("s")>-1)return!1;if(vu&&n.indexOf("m")>-1)return!1;let{$from:i,$to:o}=r;if(!i.parent.inlineContent||t.endOfTextblock(e<0?"up":"down")){let n=kd(t.state,e);if(n&&n instanceof Nc)return Sd(t,n)}if(!i.parent.inlineContent){let n=e<0?i:o,s=r instanceof Dc?Sc.near(n,e):Sc.findFrom(n,e);return!!s&&Sd(t,s)}return!1}function Ad(t,e){if(!(t.state.selection instanceof Cc))return!0;let{$head:n,$anchor:r,empty:i}=t.state.selection;if(!n.sameParent(r))return!0;if(!i)return!1;if(t.endOfTextblock(e>0?"forward":"backward"))return!0;let o=!n.textOffset&&(e<0?n.nodeBefore:n.nodeAfter);if(o&&!o.isText){let r=t.state.tr;return e<0?r.delete(n.pos-o.nodeSize,n.pos):r.delete(n.pos,n.pos+o.nodeSize),t.dispatch(r),!0}return!1}function Ed(t,e,n){t.domObserver.stop(),e.contentEditable=n,t.domObserver.start()}function Pd(t,e){let n=e.keyCode,r=function(t){let e="";return t.ctrlKey&&(e+="c"),t.metaKey&&(e+="m"),t.altKey&&(e+="a"),t.shiftKey&&(e+="s"),e}(e);return 8==n||vu&&72==n&&"c"==r?Ad(t,-1)||Cd(t):46==n||vu&&68==n&&"c"==r?Ad(t,1)||$d(t):13==n||27==n||(37==n||vu&&66==n&&"c"==r?Od(t,-1,r)||Cd(t):39==n||vu&&70==n&&"c"==r?Od(t,1,r)||$d(t):38==n||vu&&80==n&&"c"==r?Dd(t,-1,r)||Cd(t):40==n||vu&&78==n&&"c"==r?function(t){if(!mu||t.state.selection.$head.parentOffset>0)return!1;let{focusNode:e,focusOffset:n}=t.domSelectionRange();if(e&&1==e.nodeType&&0==n&&e.firstChild&&"false"==e.firstChild.contentEditable){let n=e.firstChild;Ed(t,n,"true"),setTimeout((()=>Ed(t,n,"false")),20)}return!1}(t)||Dd(t,1,r)||$d(t):r==(vu?"m":"c")&&(66==n||73==n||89==n||90==n))}function Id(t,e){t.someProp("transformCopied",(n=>{e=n(e,t)}));let n=[],{content:r,openStart:i,openEnd:o}=e;for(;i>1&&o>1&&1==r.childCount&&1==r.firstChild.childCount;){i--,o--;let t=r.firstChild;n.push(t.type.name,t.attrs!=t.type.defaultAttrs?t.attrs:null),r=t.content}let s=t.someProp("clipboardSerializer")||zl.fromSchema(t.state.schema),a=Wd(),l=a.createElement("div");l.appendChild(s.serializeFragment(r,{document:a}));let c,u=l.firstChild,d=0;for(;u&&1==u.nodeType&&(c=qd[u.nodeName.toLowerCase()]);){for(let t=c.length-1;t>=0;t--){let e=a.createElement(c[t]);for(;l.firstChild;)e.appendChild(l.firstChild);l.appendChild(e),d++}u=l.firstChild}return u&&1==u.nodeType&&u.setAttribute("data-pm-slice",`${i} ${o}${d?` -${d}`:""} ${JSON.stringify(n)}`),{dom:l,text:t.someProp("clipboardTextSerializer",(n=>n(e,t)))||e.content.textBetween(0,e.content.size,"\n\n")}}function Rd(t,e,n,r,i){let o,s,a=i.parent.type.spec.code;if(!n&&!e)return null;let l=e&&(r||a||!n);if(l){if(t.someProp("transformPastedText",(n=>{e=n(e,a||r,t)})),a)return e?new qa(za.from(t.state.schema.text(e.replace(/\r\n?/g,"\n"))),0,0):qa.empty;let n=t.someProp("clipboardTextParser",(n=>n(e,i,r,t)));if(n)s=n;else{let n=i.marks(),{schema:r}=t.state,s=zl.fromSchema(r);o=document.createElement("div"),e.split(/(?:\r\n?|\n)+/).forEach((t=>{let e=o.appendChild(document.createElement("p"));t&&e.appendChild(s.serializeNode(r.text(t,n)))}))}}else t.someProp("transformPastedHTML",(e=>{n=e(n,t)})),o=function(t){let e=/^(\s*]*>)*/.exec(t);e&&(t=t.slice(e[0].length));let n,r=Wd().createElement("div"),i=/<([a-z][^>\s]+)/i.exec(t);(n=i&&qd[i[1].toLowerCase()])&&(t=n.map((t=>"<"+t+">")).join("")+t+n.map((t=>"")).reverse().join(""));if(r.innerHTML=t,n)for(let o=0;o0;d--){let t=o.firstChild;for(;t&&1!=t.nodeType;)t=t.nextSibling;if(!t)break;o=t}if(!s){let e=t.someProp("clipboardParser")||t.someProp("domParser")||Cl.fromSchema(t.state.schema);s=e.parseSlice(o,{preserveWhitespace:!(!l&&!u),context:i,ruleFromNode:t=>"BR"!=t.nodeName||t.nextSibling||!t.parentNode||zd.test(t.parentNode.nodeName)?null:{ignore:!0}})}if(u)s=function(t,e){if(!t.size)return t;let n,r=t.content.firstChild.type.schema;try{n=JSON.parse(e)}catch(Tg){return t}let{content:i,openStart:o,openEnd:s}=t;for(let a=n.length-2;a>=0;a-=2){let t=r.nodes[n[a]];if(!t||t.hasRequiredAttrs())break;i=za.from(t.create(n[a+1],i)),o++,s++}return new qa(i,o,s)}(Vd(s,+u[1],+u[2]),u[4]);else if(s=qa.maxOpen(function(t,e){if(t.childCount<2)return t;for(let n=e.depth;n>=0;n--){let r,i=e.node(n).contentMatchAt(e.index(n)),o=[];if(t.forEach((t=>{if(!o)return;let e,n=i.findWrapping(t.type);if(!n)return o=null;if(e=o.length&&r.length&&Fd(n,r,t,o[o.length-1],0))o[o.length-1]=e;else{o.length&&(o[o.length-1]=Ld(o[o.length-1],r.length));let e=jd(t,n);o.push(e),i=i.matchType(e.type),r=n}})),o)return za.from(o)}return t}(s.content,i),!0),s.openStart||s.openEnd){let t=0,e=0;for(let n=s.content.firstChild;t{s=e(s,t)})),s}const zd=/^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i;function jd(t,e,n=0){for(let r=e.length-1;r>=n;r--)t=e[r].create(null,za.from(t));return t}function Fd(t,e,n,r,i){if(i=n&&(a=e<0?s.contentMatchAt(0).fillBefore(a,t.childCount>1||o<=i).append(a):a.append(s.contentMatchAt(s.childCount).fillBefore(za.empty,!0))),t.replaceChild(e<0?0:t.childCount-1,s.copy(a))}function Vd(t,e,n){return e{for(let n in e)t.input.eventHandlers[n]||t.dom.addEventListener(n,t.input.eventHandlers[n]=e=>Xd(t,e))}))}function Xd(t,e){return t.someProp("handleDOMEvents",(n=>{let r=n[e.type];return!!r&&(r(t,e)||e.defaultPrevented)}))}function Qd(t,e){if(!e.bubbles)return!0;if(e.defaultPrevented)return!1;for(let n=e.target;n!=t.dom;n=n.parentNode)if(!n||11==n.nodeType||n.pmViewDesc&&n.pmViewDesc.stopEvent(e))return!1;return!0}function tf(t){return{left:t.clientX,top:t.clientY}}function ef(t,e,n,r,i){if(-1==r)return!1;let o=t.state.doc.resolve(r);for(let s=o.depth+1;s>0;s--)if(t.someProp(e,(e=>s>o.depth?e(t,n,o.nodeAfter,o.before(s),i,!0):e(t,n,o.node(s),o.before(s),i,!1))))return!0;return!1}function nf(t,e,n){t.focused||t.focus();let r=t.state.tr.setSelection(e);"pointer"==n&&r.setMeta("pointer",!0),t.dispatch(r)}function rf(t,e,n,r,i){return ef(t,"handleClickOn",e,n,r)||t.someProp("handleClick",(n=>n(t,e,r)))||(i?function(t,e){if(-1==e)return!1;let n,r,i=t.state.selection;i instanceof Nc&&(n=i.node);let o=t.state.doc.resolve(e);for(let s=o.depth+1;s>0;s--){let t=s>o.depth?o.nodeAfter:o.node(s);if(Nc.isSelectable(t)){r=n&&i.$from.depth>0&&s>=i.$from.depth&&o.before(i.$from.depth+1)==i.$from.pos?o.before(i.$from.depth):o.before(s);break}}return null!=r&&(nf(t,Nc.create(t.state.doc,r),"pointer"),!0)}(t,n):function(t,e){if(-1==e)return!1;let n=t.state.doc.resolve(e),r=n.nodeAfter;return!!(r&&r.isAtom&&Nc.isSelectable(r))&&(nf(t,new Nc(n),"pointer"),!0)}(t,n))}function of(t,e,n,r){return ef(t,"handleDoubleClickOn",e,n,r)||t.someProp("handleDoubleClick",(n=>n(t,e,r)))}function sf(t,e,n,r){return ef(t,"handleTripleClickOn",e,n,r)||t.someProp("handleTripleClick",(n=>n(t,e,r)))||function(t,e,n){if(0!=n.button)return!1;let r=t.state.doc;if(-1==e)return!!r.inlineContent&&(nf(t,Cc.create(r,0,r.content.size),"pointer"),!0);let i=r.resolve(e);for(let o=i.depth+1;o>0;o--){let e=o>i.depth?i.nodeAfter:i.node(o),n=i.before(o);if(e.inlineContent)nf(t,Cc.create(r,n+1,n+1+e.content.size),"pointer");else{if(!Nc.isSelectable(e))continue;nf(t,Nc.create(r,n),"pointer")}return!0}}(t,n,r)}function af(t){return pf(t)}Kd.keydown=(t,e)=>{let n=e;if(t.input.shiftKey=16==n.keyCode||n.shiftKey,!uf(t,n)&&(t.input.lastKeyCode=n.keyCode,t.input.lastKeyCodeTime=Date.now(),!yu||!hu||13!=n.keyCode))if(229!=n.keyCode&&t.domObserver.forceFlush(),!gu||13!=n.keyCode||n.ctrlKey||n.altKey||n.metaKey)t.someProp("handleKeyDown",(e=>e(t,n)))||Pd(t,n)?n.preventDefault():Gd(t,"key");else{let e=Date.now();t.input.lastIOSEnter=e,t.input.lastIOSEnterFallbackTimeout=setTimeout((()=>{t.input.lastIOSEnter==e&&(t.someProp("handleKeyDown",(e=>e(t,nu(13,"Enter")))),t.input.lastIOSEnter=0)}),200)}},Kd.keyup=(t,e)=>{16==e.keyCode&&(t.input.shiftKey=!1)},Kd.keypress=(t,e)=>{let n=e;if(uf(t,n)||!n.charCode||n.ctrlKey&&!n.altKey||vu&&n.metaKey)return;if(t.someProp("handleKeyPress",(e=>e(t,n))))return void n.preventDefault();let r=t.state.selection;if(!(r instanceof Cc&&r.$from.sameParent(r.$to))){let e=String.fromCharCode(n.charCode);t.someProp("handleTextInput",(n=>n(t,r.$from.pos,r.$to.pos,e)))||t.dispatch(t.state.tr.insertText(e).scrollIntoView()),n.preventDefault()}};const lf=vu?"metaKey":"ctrlKey";Hd.mousedown=(t,e)=>{let n=e;t.input.shiftKey=n.shiftKey;let r=af(t),i=Date.now(),o="singleClick";i-t.input.lastClick.time<500&&function(t,e){let n=e.x-t.clientX,r=e.y-t.clientY;return n*n+r*r<100}(n,t.input.lastClick)&&!n[lf]&&("singleClick"==t.input.lastClick.type?o="doubleClick":"doubleClick"==t.input.lastClick.type&&(o="tripleClick")),t.input.lastClick={time:i,x:n.clientX,y:n.clientY,type:o};let s=t.posAtCoords(tf(n));s&&("singleClick"==o?(t.input.mouseDown&&t.input.mouseDown.done(),t.input.mouseDown=new cf(t,s,n,!!r)):("doubleClick"==o?of:sf)(t,s.pos,s.inside,n)?n.preventDefault():Gd(t,"pointer"))};class cf{constructor(t,e,n,r){let i,o;if(this.view=t,this.pos=e,this.event=n,this.flushed=r,this.delayedSelectionSync=!1,this.mightDrag=null,this.startDoc=t.state.doc,this.selectNode=!!n[lf],this.allowDefault=n.shiftKey,e.inside>-1)i=t.state.doc.nodeAt(e.inside),o=e.inside;else{let n=t.state.doc.resolve(e.pos);i=n.parent,o=n.depth?n.before():0}const s=r?null:n.target,a=s?t.docView.nearestDesc(s,!0):null;this.target=a?a.dom:null;let{selection:l}=t.state;(0==n.button&&i.type.spec.draggable&&!1!==i.type.spec.selectable||l instanceof Nc&&l.from<=o&&l.to>o)&&(this.mightDrag={node:i,pos:o,addAttr:!(!this.target||this.target.draggable),setUneditable:!(!this.target||!du||this.target.hasAttribute("contentEditable"))}),this.target&&this.mightDrag&&(this.mightDrag.addAttr||this.mightDrag.setUneditable)&&(this.view.domObserver.stop(),this.mightDrag.addAttr&&(this.target.draggable=!0),this.mightDrag.setUneditable&&setTimeout((()=>{this.view.input.mouseDown==this&&this.target.setAttribute("contentEditable","false")}),20),this.view.domObserver.start()),t.root.addEventListener("mouseup",this.up=this.up.bind(this)),t.root.addEventListener("mousemove",this.move=this.move.bind(this)),Gd(t,"pointer")}done(){this.view.root.removeEventListener("mouseup",this.up),this.view.root.removeEventListener("mousemove",this.move),this.mightDrag&&this.target&&(this.view.domObserver.stop(),this.mightDrag.addAttr&&this.target.removeAttribute("draggable"),this.mightDrag.setUneditable&&this.target.removeAttribute("contentEditable"),this.view.domObserver.start()),this.delayedSelectionSync&&setTimeout((()=>fd(this.view))),this.view.input.mouseDown=null}up(t){if(this.done(),!this.view.dom.contains(t.target))return;let e=this.pos;this.view.state.doc!=this.startDoc&&(e=this.view.posAtCoords(tf(t))),this.updateAllowDefault(t),this.allowDefault||!e?Gd(this.view,"pointer"):rf(this.view,e.pos,e.inside,t,this.selectNode)?t.preventDefault():0==t.button&&(this.flushed||mu&&this.mightDrag&&!this.mightDrag.node.isAtom||hu&&!this.view.state.selection.visible&&Math.min(Math.abs(e.pos-this.view.state.selection.from),Math.abs(e.pos-this.view.state.selection.to))<=2)?(nf(this.view,Sc.near(this.view.state.doc.resolve(e.pos)),"pointer"),t.preventDefault()):Gd(this.view,"pointer")}move(t){this.updateAllowDefault(t),Gd(this.view,"pointer"),0==t.buttons&&this.done()}updateAllowDefault(t){!this.allowDefault&&(Math.abs(this.event.x-t.clientX)>4||Math.abs(this.event.y-t.clientY)>4)&&(this.allowDefault=!0)}}function uf(t,e){return!!t.composing||!!(mu&&Math.abs(e.timeStamp-t.input.compositionEndedAt)<500)&&(t.input.compositionEndedAt=-2e8,!0)}Hd.touchstart=t=>{t.input.lastTouch=Date.now(),af(t),Gd(t,"pointer")},Hd.touchmove=t=>{t.input.lastTouch=Date.now(),Gd(t,"pointer")},Hd.contextmenu=t=>af(t);const df=yu?5e3:-1;function ff(t,e){clearTimeout(t.input.composingTimeout),e>-1&&(t.input.composingTimeout=setTimeout((()=>pf(t)),e))}function hf(t){for(t.composing&&(t.input.composing=!1,t.input.compositionEndedAt=function(){let t=document.createEvent("Event");return t.initEvent("event",!0,!0),t.timeStamp}());t.input.compositionNodes.length>0;)t.input.compositionNodes.pop().markParentsDirty()}function pf(t,e=!1){if(!(yu&&t.domObserver.flushingSoon>=0)){if(t.domObserver.forceFlush(),hf(t),e||t.docView&&t.docView.dirty){let e=ud(t);return e&&!e.eq(t.state.selection)?t.dispatch(t.state.tr.setSelection(e)):t.updateState(t.state),!0}return!1}}Kd.compositionstart=Kd.compositionupdate=t=>{if(!t.composing){t.domObserver.flush();let{state:e}=t,n=e.selection.$from;if(e.selection.empty&&(e.storedMarks||!n.textOffset&&n.parentOffset&&n.nodeBefore.marks.some((t=>!1===t.type.spec.inclusive))))t.markCursor=t.state.storedMarks||n.marks(),pf(t,!0),t.markCursor=null;else if(pf(t),du&&e.selection.empty&&n.parentOffset&&!n.textOffset&&n.nodeBefore.marks.length){let e=t.domSelectionRange();for(let n=e.focusNode,r=e.focusOffset;n&&1==n.nodeType&&0!=r;){let e=r<0?n.lastChild:n.childNodes[r-1];if(!e)break;if(3==e.nodeType){t.domSelection().collapse(e,e.nodeValue.length);break}n=e,r=-1}}t.input.composing=!0}ff(t,df)},Kd.compositionend=(t,e)=>{t.composing&&(t.input.composing=!1,t.input.compositionEndedAt=e.timeStamp,ff(t,20))};const mf=cu&&uu<15||gu&&wu<604;function gf(t,e,n,r){let i=Rd(t,e,n,t.input.shiftKey,t.state.selection.$from);if(t.someProp("handlePaste",(e=>e(t,r,i||qa.empty))))return!0;if(!i)return!1;let o=function(t){return 0==t.openStart&&0==t.openEnd&&1==t.content.childCount?t.content.firstChild:null}(i),s=o?t.state.tr.replaceSelectionWith(o,t.input.shiftKey):t.state.tr.replaceSelection(i);return t.dispatch(s.scrollIntoView().setMeta("paste",!0).setMeta("uiEvent","paste")),!0}Hd.copy=Kd.cut=(t,e)=>{let n=e,r=t.state.selection,i="cut"==n.type;if(r.empty)return;let o=mf?null:n.clipboardData,s=r.content(),{dom:a,text:l}=Id(t,s);o?(n.preventDefault(),o.clearData(),o.setData("text/html",a.innerHTML),o.setData("text/plain",l)):function(t,e){if(!t.dom.parentNode)return;let n=t.dom.parentNode.appendChild(document.createElement("div"));n.appendChild(e),n.style.cssText="position: fixed; left: -10000px; top: 10px";let r=getSelection(),i=document.createRange();i.selectNodeContents(e),t.dom.blur(),r.removeAllRanges(),r.addRange(i),setTimeout((()=>{n.parentNode&&n.parentNode.removeChild(n),t.focus()}),50)}(t,a),i&&t.dispatch(t.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent","cut"))},Kd.paste=(t,e)=>{let n=e;if(t.composing&&!yu)return;let r=mf?null:n.clipboardData;r&&gf(t,r.getData("text/plain"),r.getData("text/html"),n)?n.preventDefault():function(t,e){if(!t.dom.parentNode)return;let n=t.input.shiftKey||t.state.selection.$from.parent.type.spec.code,r=t.dom.parentNode.appendChild(document.createElement(n?"textarea":"div"));n||(r.contentEditable="true"),r.style.cssText="position: fixed; left: -10000px; top: 10px",r.focus(),setTimeout((()=>{t.focus(),r.parentNode&&r.parentNode.removeChild(r),n?gf(t,r.value,null,e):gf(t,r.textContent,r.innerHTML,e)}),50)}(t,n)};class vf{constructor(t,e){this.slice=t,this.move=e}}const yf=vu?"altKey":"ctrlKey";Hd.dragstart=(t,e)=>{let n=e,r=t.input.mouseDown;if(r&&r.done(),!n.dataTransfer)return;let i=t.state.selection,o=i.empty?null:t.posAtCoords(tf(n));if(o&&o.pos>=i.from&&o.pos<=(i instanceof Nc?i.to-1:i.to));else if(r&&r.mightDrag)t.dispatch(t.state.tr.setSelection(Nc.create(t.state.doc,r.mightDrag.pos)));else if(n.target&&1==n.target.nodeType){let e=t.docView.nearestDesc(n.target,!0);e&&e.node.type.spec.draggable&&e!=t.docView&&t.dispatch(t.state.tr.setSelection(Nc.create(t.state.doc,e.posBefore)))}let s=t.state.selection.content(),{dom:a,text:l}=Id(t,s);n.dataTransfer.clearData(),n.dataTransfer.setData(mf?"Text":"text/html",a.innerHTML),n.dataTransfer.effectAllowed="copyMove",mf||n.dataTransfer.setData("text/plain",l),t.dragging=new vf(s,!n[yf])},Hd.dragend=t=>{let e=t.dragging;window.setTimeout((()=>{t.dragging==e&&(t.dragging=null)}),50)},Kd.dragover=Kd.dragenter=(t,e)=>e.preventDefault(),Kd.drop=(t,e)=>{let n=e,r=t.dragging;if(t.dragging=null,!n.dataTransfer)return;let i=t.posAtCoords(tf(n));if(!i)return;let o=t.state.doc.resolve(i.pos),s=r&&r.slice;s?t.someProp("transformPasted",(e=>{s=e(s,t)})):s=Rd(t,n.dataTransfer.getData(mf?"Text":"text/plain"),mf?null:n.dataTransfer.getData("text/html"),!1,o);let a=!(!r||n[yf]);if(t.someProp("handleDrop",(e=>e(t,n,s||qa.empty,a))))return void n.preventDefault();if(!s)return;n.preventDefault();let l=s?function(t,e,n){let r=t.resolve(e);if(!n.content.size)return e;let i=n.content;for(let o=0;o=0;t--){let e=t==r.depth?0:r.pos<=(r.start(t+1)+r.end(t+1))/2?-1:1,n=r.index(t)+(e>0?1:0),s=r.node(t),a=!1;if(1==o)a=s.canReplace(n,n,i);else{let t=s.contentMatchAt(n).findWrapping(i.firstChild.type);a=t&&s.canReplaceWith(n,n,t[0])}if(a)return 0==e?r.pos:e<0?r.before(t+1):r.after(t+1)}return null}(t.state.doc,o.pos,s):o.pos;null==l&&(l=o.pos);let c=t.state.tr;a&&c.deleteSelection();let u=c.mapping.map(l),d=0==s.openStart&&0==s.openEnd&&1==s.content.childCount,f=c.doc;if(d?c.replaceRangeWith(u,u,s.content.firstChild):c.replaceRange(u,u,s),c.doc.eq(f))return;let h=c.doc.resolve(u);if(d&&Nc.isSelectable(s.content.firstChild)&&h.nodeAfter&&h.nodeAfter.sameMarkup(s.content.firstChild))c.setSelection(new Nc(h));else{let e=c.mapping.map(l);c.mapping.maps[c.mapping.maps.length-1].forEach(((t,n,r,i)=>e=i)),c.setSelection(bd(t,h,c.doc.resolve(e)))}t.focus(),t.dispatch(c.setMeta("uiEvent","drop"))},Hd.focus=t=>{t.input.lastFocus=Date.now(),t.focused||(t.domObserver.stop(),t.dom.classList.add("ProseMirror-focused"),t.domObserver.start(),t.focused=!0,setTimeout((()=>{t.docView&&t.hasFocus()&&!t.domObserver.currentSelection.eq(t.domSelectionRange())&&fd(t)}),20))},Hd.blur=(t,e)=>{let n=e;t.focused&&(t.domObserver.stop(),t.dom.classList.remove("ProseMirror-focused"),t.domObserver.start(),n.relatedTarget&&t.dom.contains(n.relatedTarget)&&t.domObserver.currentSelection.clear(),t.focused=!1)},Hd.beforeinput=(t,e)=>{if(hu&&yu&&"deleteContentBackward"==e.inputType){t.domObserver.flushSoon();let{domChangeCount:e}=t.input;setTimeout((()=>{if(t.input.domChangeCount!=e)return;if(t.dom.blur(),t.focus(),t.someProp("handleKeyDown",(e=>e(t,nu(8,"Backspace")))))return;let{$cursor:n}=t.state.selection;n&&n.pos>0&&t.dispatch(t.state.tr.delete(n.pos-1,n.pos).scrollIntoView())}),50)}};for(let os in Kd)Hd[os]=Kd[os];function bf(t,e){if(t==e)return!0;for(let n in t)if(t[n]!==e[n])return!1;for(let n in e)if(!(n in t))return!1;return!0}class wf{constructor(t,e){this.toDOM=t,this.spec=e||_f,this.side=this.spec.side||0}map(t,e,n,r){let{pos:i,deleted:o}=t.mapResult(e.from+r,this.side<0?-1:1);return o?null:new Sf(i-n,i-n,this)}valid(){return!0}eq(t){return this==t||t instanceof wf&&(this.spec.key&&this.spec.key==t.spec.key||this.toDOM==t.toDOM&&bf(this.spec,t.spec))}destroy(t){this.spec.destroy&&this.spec.destroy(t)}}class xf{constructor(t,e){this.attrs=t,this.spec=e||_f}map(t,e,n,r){let i=t.map(e.from+r,this.spec.inclusiveStart?-1:1)-n,o=t.map(e.to+r,this.spec.inclusiveEnd?1:-1)-n;return i>=o?null:new Sf(i,o,this)}valid(t,e){return e.from=t&&(!i||i(s.spec))&&n.push(s.copy(s.from+r,s.to+r))}for(let o=0;ot){let s=this.children[o]+1;this.children[o+2].findInner(t-s,e-s,n,r+s,i)}}map(t,e,n){return this==Cf||0==t.maps.length?this:this.mapInner(t,e,0,0,n||_f)}mapInner(t,e,n,r,i){let o;for(let s=0;s{let s=o-r-(n-e);for(let l=0;lo+u-t)continue;let c=a[l]+u-t;n>=c?a[l+1]=e<=c?-2:-1:r>=i&&s&&(a[l]+=s,a[l+1]+=s)}t+=s})),u=n.maps[c].map(u,-1)}let l=!1;for(let c=0;c=r.content.size){l=!0;continue}let d=n.map(t[c+1]+o,-1)-i,{index:f,offset:h}=r.content.findIndex(u),p=r.maybeChild(f);if(p&&h==u&&h+p.nodeSize==d){let r=a[c+2].mapInner(n,p,e+1,t[c]+o+1,s);r!=Cf?(a[c]=u,a[c+1]=d,a[c+2]=r):(a[c+1]=-2,l=!0)}else l=!0}if(l){let l=function(t,e,n,r,i,o,s){function a(t,e){for(let o=0;o{let s,a=o+n;if(s=Tf(e,t,a)){for(r||(r=this.children.slice());io&&e.to=t){this.children[s]==t&&(n=this.children[s+2]);break}let i=t+1,o=i+e.content.size;for(let s=0;si&&t.type instanceof xf){let e=Math.max(i,t.from)-i,n=Math.min(o,t.to)-i;en.map(t,e,_f)));return $f.from(n)}forChild(t,e){if(e.isLeaf)return Mf.empty;let n=[];for(let r=0;rt instanceof Mf))?t:t.reduce(((t,e)=>t.concat(e instanceof Mf?e:e.members)),[]))}}}function Nf(t,e){if(!e||!t.length)return t;let n=[];for(let r=0;rn&&o.to{let a=Tf(t,e,s+n);if(a){o=!0;let t=Af(a,e,n+s+1,r);t!=Cf&&i.push(s,s+e.nodeSize,t)}}));let s=Nf(o?Df(t):t,-n).sort(Ef);for(let a=0;a0;)e++;t.splice(e,0,n)}function Rf(t){let e=[];return t.someProp("decorations",(n=>{let r=n(t.state);r&&r!=Cf&&e.push(r)})),t.cursorWrapper&&e.push(Mf.create(t.state.doc,[t.cursorWrapper.deco])),$f.from(e)}const zf={childList:!0,characterData:!0,characterDataOldValue:!0,attributes:!0,attributeOldValue:!0,subtree:!0},jf=cu&&uu<=11;class Ff{constructor(){this.anchorNode=null,this.anchorOffset=0,this.focusNode=null,this.focusOffset=0}set(t){this.anchorNode=t.anchorNode,this.anchorOffset=t.anchorOffset,this.focusNode=t.focusNode,this.focusOffset=t.focusOffset}clear(){this.anchorNode=this.focusNode=null}eq(t){return t.anchorNode==this.anchorNode&&t.anchorOffset==this.anchorOffset&&t.focusNode==this.focusNode&&t.focusOffset==this.focusOffset}}class Lf{constructor(t,e){this.view=t,this.handleDOMChange=e,this.queue=[],this.flushingSoon=-1,this.observer=null,this.currentSelection=new Ff,this.onCharData=null,this.suppressingSelectionUpdates=!1,this.observer=window.MutationObserver&&new window.MutationObserver((t=>{for(let e=0;e"childList"==t.type&&t.removedNodes.length||"characterData"==t.type&&t.oldValue.length>t.target.nodeValue.length))?this.flushSoon():this.flush()})),jf&&(this.onCharData=t=>{this.queue.push({target:t.target,type:"characterData",oldValue:t.prevValue}),this.flushSoon()}),this.onSelectionChange=this.onSelectionChange.bind(this)}flushSoon(){this.flushingSoon<0&&(this.flushingSoon=window.setTimeout((()=>{this.flushingSoon=-1,this.flush()}),20))}forceFlush(){this.flushingSoon>-1&&(window.clearTimeout(this.flushingSoon),this.flushingSoon=-1,this.flush())}start(){this.observer&&(this.observer.takeRecords(),this.observer.observe(this.view.dom,zf)),this.onCharData&&this.view.dom.addEventListener("DOMCharacterDataModified",this.onCharData),this.connectSelection()}stop(){if(this.observer){let t=this.observer.takeRecords();if(t.length){for(let e=0;ethis.flush()),20)}this.observer.disconnect()}this.onCharData&&this.view.dom.removeEventListener("DOMCharacterDataModified",this.onCharData),this.disconnectSelection()}connectSelection(){this.view.dom.ownerDocument.addEventListener("selectionchange",this.onSelectionChange)}disconnectSelection(){this.view.dom.ownerDocument.removeEventListener("selectionchange",this.onSelectionChange)}suppressSelectionUpdates(){this.suppressingSelectionUpdates=!0,setTimeout((()=>this.suppressingSelectionUpdates=!1),50)}onSelectionChange(){if(wd(this.view)){if(this.suppressingSelectionUpdates)return fd(this.view);if(cu&&uu<=11&&!this.view.state.selection.empty){let t=this.view.domSelectionRange();if(t.focusNode&&Gc(t.focusNode,t.focusOffset,t.anchorNode,t.anchorOffset))return this.flushSoon()}this.flush()}}setCurSelection(){this.currentSelection.set(this.view.domSelectionRange())}ignoreSelectionChange(t){if(!t.focusNode)return!0;let e,n=new Set;for(let i=t.focusNode;i;i=Kc(i))n.add(i);for(let i=t.anchorNode;i;i=Kc(i))if(n.has(i)){e=i;break}let r=e&&this.view.docView.nearestDesc(e);return r&&r.ignoreMutation({type:"selection",target:3==e.nodeType?e.parentNode:e})?(this.setCurSelection(),!0):void 0}flush(){let{view:t}=this;if(!t.docView||this.flushingSoon>-1)return;let e=this.observer?this.observer.takeRecords():[];this.queue.length&&(e=this.queue.concat(e),this.queue.length=0);let n=t.domSelectionRange(),r=!this.suppressingSelectionUpdates&&!this.currentSelection.eq(n)&&wd(t)&&!this.ignoreSelectionChange(n),i=-1,o=-1,s=!1,a=[];if(t.editable)for(let c=0;c1){let t=a.filter((t=>"BR"==t.nodeName));if(2==t.length){let e=t[0],n=t[1];e.parentNode&&e.parentNode.parentNode==n.parentNode?n.remove():e.remove()}}let l=null;i<0&&r&&t.input.lastFocus>Date.now()-200&&t.input.lastTouch-1||r)&&(i>-1&&(t.docView.markDirty(i,o),function(t){if(Bf.has(t))return;if(Bf.set(t,null),-1!==["normal","nowrap","pre-line"].indexOf(getComputedStyle(t.dom).whiteSpace)){if(t.requiresGeckoHackNode=du,Vf)return;console.warn("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package."),Vf=!0}}(t)),this.handleDOMChange(i,o,s,a),t.docView&&t.docView.dirty?t.updateState(t.state):this.currentSelection.eq(n)||fd(t),this.currentSelection.set(n))}registerMutation(t,e){if(e.indexOf(t.target)>-1)return null;let n=this.view.docView.nearestDesc(t.target);if("attributes"==t.type&&(n==this.view.docView||"contenteditable"==t.attributeName||"style"==t.attributeName&&!t.oldValue&&!t.target.getAttribute("style")))return null;if(!n||n.ignoreMutation(t))return null;if("childList"==t.type){for(let n=0;nDate.now()-50?t.input.lastSelectionOrigin:null,n=ud(t,e);if(n&&!t.state.selection.eq(n)){let r=t.state.tr.setSelection(n);"pointer"==e?r.setMeta("pointer",!0):"key"==e&&r.scrollIntoView(),t.dispatch(r)}return}let o=t.state.doc.resolve(e),s=o.sharedDepth(n);e=o.before(s+1),n=t.state.doc.resolve(n).after(s+1);let a,l,c=t.state.selection,u=function(t,e,n){let r,{node:i,fromOffset:o,toOffset:s,from:a,to:l}=t.docView.parseRange(e,n),c=t.domSelectionRange(),u=c.anchorNode;if(u&&t.dom.contains(1==u.nodeType?u:u.parentNode)&&(r=[{node:u,offset:c.anchorOffset}],eu(c)||r.push({node:c.focusNode,offset:c.focusOffset})),hu&&8===t.input.lastKeyCode)for(let g=s;g>o;g--){let t=i.childNodes[g-1],e=t.pmViewDesc;if("BR"==t.nodeName&&!e){s=g;break}if(!e||e.size)break}let d=t.state.doc,f=t.someProp("domParser")||Cl.fromSchema(t.state.schema),h=d.resolve(a),p=null,m=f.parse(i,{topNode:h.parent,topMatch:h.parent.contentMatchAt(h.index()),topOpen:!0,from:o,to:s,preserveWhitespace:"pre"!=h.parent.type.whitespace||"full",findPositions:r,ruleFromNode:qf,context:h});if(r&&null!=r[0].pos){let t=r[0].pos,e=r[1]&&r[1].pos;null==e&&(e=t),p={anchor:t+a,head:e+a}}return{doc:m,sel:p,from:a,to:l}}(t,e,n),d=t.state.doc,f=d.slice(u.from,u.to);8===t.input.lastKeyCode&&Date.now()-100=s?o-r:0,a=o+(a-s),s=o}else if(a=a?o-r:0,s=o+(s-a),a=o}return{start:o,endA:s,endB:a}}(f.content,u.doc.content,u.from,a,l);if((gu&&t.input.lastIOSEnter>Date.now()-225||yu)&&i.some((t=>"DIV"==t.nodeName||"P"==t.nodeName||"LI"==t.nodeName))&&(!h||h.endA>=h.endB)&&t.someProp("handleKeyDown",(e=>e(t,nu(13,"Enter")))))return void(t.input.lastIOSEnter=0);if(!h){if(!(r&&c instanceof Cc&&!c.empty&&c.$head.sameParent(c.$anchor))||t.composing||u.sel&&u.sel.anchor!=u.sel.head){if(u.sel){let e=Wf(t,t.state.doc,u.sel);e&&!e.eq(t.state.selection)&&t.dispatch(t.state.tr.setSelection(e))}return}h={start:c.from,endA:c.to,endB:c.to}}if(hu&&t.cursorWrapper&&u.sel&&u.sel.anchor==t.cursorWrapper.deco.from&&u.sel.head==u.sel.anchor){let t=h.endB-h.start;u.sel={anchor:u.sel.anchor+t,head:u.sel.anchor+t}}t.input.domChangeCount++,t.state.selection.fromt.state.selection.from&&h.start<=t.state.selection.from+2&&t.state.selection.from>=u.from?h.start=t.state.selection.from:h.endA=t.state.selection.to-2&&t.state.selection.to<=u.to&&(h.endB+=t.state.selection.to-h.endA,h.endA=t.state.selection.to)),cu&&uu<=11&&h.endB==h.start+1&&h.endA==h.start&&h.start>u.from&&"  "==u.doc.textBetween(h.start-u.from-1,h.start-u.from+1)&&(h.start--,h.endA--,h.endB--);let p,m=u.doc.resolveNoCache(h.start-u.from),g=u.doc.resolveNoCache(h.endB-u.from),v=d.resolve(h.start),y=m.sameParent(g)&&m.parent.inlineContent&&v.end()>=h.endA;if((gu&&t.input.lastIOSEnter>Date.now()-225&&(!y||i.some((t=>"DIV"==t.nodeName||"P"==t.nodeName)))||!y&&m.pose(t,nu(13,"Enter")))))return void(t.input.lastIOSEnter=0);if(t.state.selection.anchor>h.start&&function(t,e,n,r,i){if(!r.parent.isTextblock||n-e<=i.pos-r.pos||Hf(r,!0,!1)n||Hf(s,!0,!1)e(t,nu(8,"Backspace")))))return void(yu&&hu&&t.domObserver.suppressSelectionUpdates());hu&&yu&&h.endB==h.start&&(t.input.lastAndroidDelete=Date.now()),yu&&!y&&m.start()!=g.start()&&0==g.parentOffset&&m.depth==g.depth&&u.sel&&u.sel.anchor==u.sel.head&&u.sel.head==h.endA&&(h.endB-=2,g=u.doc.resolveNoCache(h.endB-u.from),setTimeout((()=>{t.someProp("handleKeyDown",(function(e){return e(t,nu(13,"Enter"))}))}),20));let b,w,x,k=h.start,S=h.endA;if(y)if(m.pos==g.pos)cu&&uu<=11&&0==m.parentOffset&&(t.domObserver.suppressSelectionUpdates(),setTimeout((()=>fd(t)),20)),b=t.state.tr.delete(k,S),w=d.resolve(h.start).marksAcross(d.resolve(h.endA));else if(h.endA==h.endB&&(x=function(t,e){let n,r,i,o=t.firstChild.marks,s=e.firstChild.marks,a=o,l=s;for(let u=0;ut.mark(r.addToSet(t.marks));else{if(0!=a.length||1!=l.length)return null;r=l[0],n="remove",i=t=>t.mark(r.removeFromSet(t.marks))}let c=[];for(let u=0;un(t,k,S,e))))return;b=t.state.tr.insertText(e,k,S)}if(b||(b=t.state.tr.replace(k,S,u.doc.slice(h.start-u.from,h.endB-u.from))),u.sel){let e=Wf(t,b.doc,u.sel);e&&!(hu&&yu&&t.composing&&e.empty&&(h.start!=h.endB||t.input.lastAndroidDeletee.content.size?null:bd(t,e.resolve(n.anchor),e.resolve(n.head))}function Hf(t,e,n){let r=t.depth,i=e?t.end():t.pos;for(;r>0&&(e||t.indexAfter(r)==t.node(r).childCount);)r--,i++,e=!1;if(n){let e=t.node(r).maybeChild(t.indexAfter(r));for(;e&&!e.isLeaf;)e=e.firstChild,i++}return i}class Kf{constructor(t,e){this._root=null,this.focused=!1,this.trackWrites=null,this.mounted=!1,this.markCursor=null,this.cursorWrapper=null,this.lastSelectedViewDesc=void 0,this.input=new Yd,this.prevDirectPlugins=[],this.pluginViews=[],this.requiresGeckoHackNode=!1,this.dragging=null,this._props=e,this.state=e.state,this.directPlugins=e.plugins||[],this.directPlugins.forEach(Xf),this.dispatch=this.dispatch.bind(this),this.dom=t&&t.mount||document.createElement("div"),t&&(t.appendChild?t.appendChild(this.dom):"function"==typeof t?t(this.dom):t.mount&&(this.mounted=!0)),this.editable=Gf(this),Yf(this),this.nodeViews=Zf(this),this.docView=Uu(this.state.doc,Uf(this),Rf(this),this.dom,this),this.domObserver=new Lf(this,((t,e,n,r)=>Jf(this,t,e,n,r))),this.domObserver.start(),function(t){for(let e in Hd){let n=Hd[e];t.dom.addEventListener(e,t.input.eventHandlers[e]=e=>{!Qd(t,e)||Xd(t,e)||!t.editable&&e.type in Kd||n(t,e)},Ud[e]?{passive:!0}:void 0)}mu&&t.dom.addEventListener("input",(()=>null)),Zd(t)}(this),this.updatePluginViews()}get composing(){return this.input.composing}get props(){if(this._props.state!=this.state){let t=this._props;this._props={};for(let e in t)this._props[e]=t[e];this._props.state=this.state}return this._props}update(t){t.handleDOMEvents!=this._props.handleDOMEvents&&Zd(this);let e=this._props;this._props=t,t.plugins&&(t.plugins.forEach(Xf),this.directPlugins=t.plugins),this.updateStateInner(t.state,e)}setProps(t){let e={};for(let n in this._props)e[n]=this._props[n];e.state=this.state;for(let n in t)e[n]=t[n];this.update(e)}updateState(t){this.updateStateInner(t,this._props)}updateStateInner(t,e){let n=this.state,r=!1,i=!1;t.storedMarks&&this.composing&&(hf(this),i=!0),this.state=t;let o=n.plugins!=t.plugins||this._props.plugins!=e.plugins;if(o||this._props.plugins!=e.plugins||this._props.nodeViews!=e.nodeViews){let t=Zf(this);(function(t,e){let n=0,r=0;for(let i in t){if(t[i]!=e[i])return!0;n++}for(let i in e)r++;return n!=r})(t,this.nodeViews)&&(this.nodeViews=t,r=!0)}(o||e.handleDOMEvents!=this._props.handleDOMEvents)&&Zd(this),this.editable=Gf(this),Yf(this);let s=Rf(this),a=Uf(this),l=n.plugins==t.plugins||n.doc.eq(t.doc)?t.scrollToSelection>n.scrollToSelection?"to selection":"preserve":"reset",c=r||!this.docView.matchesNode(t.doc,a,s);!c&&t.selection.eq(n.selection)||(i=!0);let u="preserve"==l&&i&&null==this.dom.style.overflowAnchor&&function(t){let e,n,r=t.dom.getBoundingClientRect(),i=Math.max(0,r.top);for(let o=(r.left+r.right)/2,s=i+1;s=i-20){e=r,n=a.top;break}}return{refDOM:e,refTop:n,stack:_u(t.dom)}}(this);if(i){this.domObserver.stop();let e=c&&(cu||hu)&&!this.composing&&!n.selection.empty&&!t.selection.empty&&function(t,e){let n=Math.min(t.$anchor.sharedDepth(t.head),e.$anchor.sharedDepth(e.head));return t.$anchor.start(n)!=e.$anchor.start(n)}(n.selection,t.selection);if(c){let n=hu?this.trackWrites=this.domSelectionRange().focusNode:null;!r&&this.docView.update(t.doc,a,s,this)||(this.docView.updateOuterDeco([]),this.docView.destroy(),this.docView=Uu(t.doc,a,s,this.dom,this)),n&&!this.trackWrites&&(e=!0)}e||!(this.input.mouseDown&&this.domObserver.currentSelection.eq(this.domSelectionRange())&&function(t){let e=t.docView.domFromPos(t.state.selection.anchor,0),n=t.domSelectionRange();return Gc(e.node,e.offset,n.anchorNode,n.anchorOffset)}(this))?fd(this,e):(vd(this,t.selection),this.domObserver.setCurSelection()),this.domObserver.start()}this.updatePluginViews(n),"reset"==l?this.dom.scrollTop=0:"to selection"==l?this.scrollToSelection():u&&function({refDOM:t,refTop:e,stack:n}){let r=t?t.getBoundingClientRect().top:0;Mu(n,0==r?0:r-e)}(u)}scrollToSelection(){let t=this.domSelectionRange().focusNode;if(this.someProp("handleScrollToSelection",(t=>t(this))));else if(this.state.selection instanceof Nc){let e=this.docView.domAfterPos(this.state.selection.from);1==e.nodeType&&Ou(this,e.getBoundingClientRect(),t)}else Ou(this,this.coordsAtPos(this.state.selection.head,1),t)}destroyPluginViews(){let t;for(;t=this.pluginViews.pop();)t.destroy&&t.destroy()}updatePluginViews(t){if(t&&t.plugins==this.state.plugins&&this.directPlugins==this.prevDirectPlugins)for(let e=0;ee.ownerDocument.getSelection()),this._root=e;return t||document}posAtCoords(t){return Du(this,t)}coordsAtPos(t,e=1){return Pu(this,t,e)}domAtPos(t,e=0){return this.docView.domFromPos(t,e)}nodeDOM(t){let e=this.docView.descAt(t);return e?e.nodeDOM:null}posAtDOM(t,e,n=-1){let r=this.docView.posFromDOM(t,e,n);if(null==r)throw new RangeError("DOM position not inside the editor");return r}endOfTextblock(t,e){return Vu(this,e||this.state,t)}destroy(){this.docView&&(!function(t){t.domObserver.stop();for(let e in t.input.eventHandlers)t.dom.removeEventListener(e,t.input.eventHandlers[e]);clearTimeout(t.input.composingTimeout),clearTimeout(t.input.lastIOSEnterFallbackTimeout)}(this),this.destroyPluginViews(),this.mounted?(this.docView.update(this.state.doc,[],Rf(this),this),this.dom.textContent=""):this.dom.parentNode&&this.dom.parentNode.removeChild(this.dom),this.docView.destroy(),this.docView=null)}get isDestroyed(){return null==this.docView}dispatchEvent(t){return function(t,e){Xd(t,e)||!Hd[e.type]||!t.editable&&e.type in Kd||Hd[e.type](t,e)}(this,t)}dispatch(t){let e=this._props.dispatchTransaction;e?e.call(this,t):this.updateState(this.state.apply(t))}domSelectionRange(){return mu&&11===this.root.nodeType&&function(t){let e=t.activeElement;for(;e&&e.shadowRoot;)e=e.shadowRoot.activeElement;return e}(this.dom.ownerDocument)==this.dom?function(t){let e;function n(t){t.preventDefault(),t.stopImmediatePropagation(),e=t.getTargetRanges()[0]}t.dom.addEventListener("beforeinput",n,!0),document.execCommand("indent"),t.dom.removeEventListener("beforeinput",n,!0);let r=e.startContainer,i=e.startOffset,o=e.endContainer,s=e.endOffset,a=t.domAtPos(t.state.selection.anchor);return Gc(a.node,a.offset,o,s)&&([r,i,o,s]=[o,s,r,i]),{anchorNode:r,anchorOffset:i,focusNode:o,focusOffset:s}}(this):this.domSelection()}domSelection(){return this.root.getSelection()}}function Uf(t){let e=Object.create(null);return e.class="ProseMirror",e.contenteditable=String(t.editable),e.translate="no",t.someProp("attributes",(n=>{if("function"==typeof n&&(n=n(t.state)),n)for(let t in n)"class"==t&&(e.class+=" "+n[t]),"style"==t?e.style=(e.style?e.style+";":"")+n[t]:e[t]||"contenteditable"==t||"nodeName"==t||(e[t]=String(n[t]))})),[Sf.node(0,t.state.doc.content.size,e)]}function Yf(t){if(t.markCursor){let e=document.createElement("img");e.className="ProseMirror-separator",e.setAttribute("mark-placeholder","true"),e.setAttribute("alt",""),t.cursorWrapper={dom:e,deco:Sf.widget(t.state.selection.head,e,{raw:!0,marks:t.markCursor})}}else t.cursorWrapper=null}function Gf(t){return!t.someProp("editable",(e=>!1===e(t.state)))}function Zf(t){let e=Object.create(null);function n(t){for(let n in t)Object.prototype.hasOwnProperty.call(e,n)||(e[n]=t[n])}return t.someProp("nodeViews",n),t.someProp("markViews",n),e}function Xf(t){if(t.spec.state||t.spec.filterTransaction||t.spec.appendTransaction)throw new RangeError("Plugins passed directly to the view must not have a state component")}var Qf={8:"Backspace",9:"Tab",10:"Enter",12:"NumLock",13:"Enter",16:"Shift",17:"Control",18:"Alt",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",44:"PrintScreen",45:"Insert",46:"Delete",59:";",61:"=",91:"Meta",92:"Meta",106:"*",107:"+",108:",",109:"-",110:".",111:"/",144:"NumLock",145:"ScrollLock",160:"Shift",161:"Shift",162:"Control",163:"Control",164:"Alt",165:"Alt",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'"},th={48:")",49:"!",50:"@",51:"#",52:"$",53:"%",54:"^",55:"&",56:"*",57:"(",59:":",61:"+",173:"_",186:":",187:"+",188:"<",189:"_",190:">",191:"?",192:"~",219:"{",220:"|",221:"}",222:'"'},eh="undefined"!=typeof navigator&&/Chrome\/(\d+)/.exec(navigator.userAgent);"undefined"!=typeof navigator&&/Gecko\/\d+/.test(navigator.userAgent);for(var nh="undefined"!=typeof navigator&&/Mac/.test(navigator.platform),rh="undefined"!=typeof navigator&&/MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent),ih=nh||eh&&+eh[1]<57,oh=0;oh<10;oh++)Qf[48+oh]=Qf[96+oh]=String(oh);for(oh=1;oh<=24;oh++)Qf[oh+111]="F"+oh;for(oh=65;oh<=90;oh++)Qf[oh]=String.fromCharCode(oh+32),th[oh]=String.fromCharCode(oh);for(var sh in Qf)th.hasOwnProperty(sh)||(th[sh]=Qf[sh]);const ah="undefined"!=typeof navigator&&/Mac|iP(hone|[oa]d)/.test(navigator.platform);function lh(t){let e,n,r,i,o=t.split(/-(?!$)/),s=o[o.length-1];"Space"==s&&(s=" ");for(let a=0;a127)&&(r=Qf[n.keyCode])&&r!=i){let i=e[ch(r,n,!0)];if(i&&i(t.state,t.dispatch,t))return!0}else if(o&&n.shiftKey){let r=e[ch(i,n,!0)];if(r&&r(t.state,t.dispatch,t))return!0}return!1}}const fh=(t,e)=>!t.selection.empty&&(e&&e(t.tr.deleteSelection().scrollIntoView()),!0);function hh(t,e,n=!1){for(let r=t;r;r="start"==e?r.firstChild:r.lastChild){if(r.isTextblock)return!0;if(n&&1!=r.childCount)return!1}return!1}function ph(t){if(!t.parent.type.spec.isolating)for(let e=t.depth-1;e>=0;e--){if(t.index(e)>0)return t.doc.resolve(t.before(e+1));if(t.node(e).type.spec.isolating)break}return null}function mh(t){if(!t.parent.type.spec.isolating)for(let e=t.depth-1;e>=0;e--){let n=t.node(e);if(t.index(e)+1{let{$head:n,$anchor:r}=t.selection;if(!n.parent.type.spec.code||!n.sameParent(r))return!1;let i=n.node(-1),o=n.indexAfter(-1),s=gh(i.contentMatchAt(o));if(!s||!i.canReplaceWith(o,o,s))return!1;if(e){let r=n.after(),i=t.tr.replaceWith(r,r,s.createAndFill());i.setSelection(Sc.near(i.doc.resolve(r),1)),e(i.scrollIntoView())}return!0};function yh(t,e,n){let r,i,o=e.nodeBefore,s=e.nodeAfter;if(o.type.spec.isolating||s.type.spec.isolating)return!1;if(function(t,e,n){let r=e.nodeBefore,i=e.nodeAfter,o=e.index();return!(!(r&&i&&r.type.compatibleContent(i.type))||(!r.content.size&&e.parent.canReplace(o-1,o)?(n&&n(t.tr.delete(e.pos-r.nodeSize,e.pos).scrollIntoView()),0):!e.parent.canReplace(o,o+1)||!i.isTextblock&&!ac(t.doc,e.pos)||(n&&n(t.tr.clearIncompatible(e.pos,r.type,r.contentMatchAt(r.childCount)).join(e.pos).scrollIntoView()),0)))}(t,e,n))return!0;let a=e.parent.canReplace(e.index(),e.index()+1);if(a&&(r=(i=o.contentMatchAt(o.childCount)).findWrapping(s.type))&&i.matchType(r[0]||s.type).validEnd){if(n){let i=e.pos+s.nodeSize,a=za.empty;for(let t=r.length-1;t>=0;t--)a=za.from(r[t].create(null,a));a=za.from(o.copy(a));let l=t.tr.step(new tc(e.pos-1,i,e.pos,i,new qa(a,1,0),r.length,!0)),c=i+2*r.length;ac(l.doc,c)&&l.join(c),n(l.scrollIntoView())}return!0}let l=Sc.findFrom(e,1),c=l&&l.$from.blockRange(l.$to),u=c&&rc(c);if(null!=u&&u>=e.depth)return n&&n(t.tr.lift(c,u).scrollIntoView()),!0;if(a&&hh(s,"start",!0)&&hh(o,"end")){let r=o,i=[];for(;i.push(r),!r.isTextblock;)r=r.lastChild;let a=s,l=1;for(;!a.isTextblock;a=a.firstChild)l++;if(r.canReplace(r.childCount,r.childCount,a.content)){if(n){let r=za.empty;for(let t=i.length-1;t>=0;t--)r=za.from(i[t].copy(r));n(t.tr.step(new tc(e.pos-i.length,e.pos+s.nodeSize,e.pos+l,e.pos+s.nodeSize-l,new qa(r,i.length,0),0,!0)).scrollIntoView())}return!0}}return!1}function bh(t){return function(e,n){let r=e.selection,i=t<0?r.$from:r.$to,o=i.depth;for(;i.node(o).isInline;){if(!o)return!1;o--}return!!i.node(o).isTextblock&&(n&&n(e.tr.setSelection(Cc.create(e.doc,t<0?i.start(o):i.end(o)))),!0)}}const wh=bh(-1),xh=bh(1);function kh(t,e=null){return function(n,r){let{from:i,to:o}=n.selection,s=!1;return n.doc.nodesBetween(i,o,((r,i)=>{if(s)return!1;if(r.isTextblock&&!r.hasMarkup(t,e))if(r.type==t)s=!0;else{let e=n.doc.resolve(i),r=e.index();s=e.parent.canReplaceWith(r,r+1,t)}})),!!s&&(r&&r(n.tr.setBlockType(i,o,t,e).scrollIntoView()),!0)}}function Sh(t,e=null){return function(n,r){let{empty:i,$cursor:o,ranges:s}=n.selection;if(i&&!o||!function(t,e,n){for(let r=0;r{if(s)return!1;s=t.inlineContent&&t.type.allowsMarkType(n)})),s)return!0}return!1}(n.doc,s,t))return!1;if(r)if(o)t.isInSet(n.storedMarks||o.marks())?r(n.tr.removeStoredMark(t)):r(n.tr.addStoredMark(t.create(e)));else{let i=!1,o=n.tr;for(let e=0;!i&&e{let{$cursor:r}=t.selection;if(!r||(n?!n.endOfTextblock("backward",t):r.parentOffset>0))return!1;let i=ph(r);if(!i){let n=r.blockRange(),i=n&&rc(n);return null!=i&&(e&&e(t.tr.lift(n,i).scrollIntoView()),!0)}let o=i.nodeBefore;if(!o.type.spec.isolating&&yh(t,i,e))return!0;if(0==r.parent.content.size&&(hh(o,"end")||Nc.isSelectable(o))){let n=lc(t.doc,r.before(),r.after(),qa.empty);if(n&&n.slice.size{let{$head:r,empty:i}=t.selection,o=r;if(!i)return!1;if(r.parent.isTextblock){if(n?!n.endOfTextblock("backward",t):r.parentOffset>0)return!1;o=ph(r)}let s=o&&o.nodeBefore;return!(!s||!Nc.isSelectable(s))&&(e&&e(t.tr.setSelection(Nc.create(t.doc,o.pos-s.nodeSize)).scrollIntoView()),!0)})),Mh=Oh(fh,((t,e,n)=>{let{$cursor:r}=t.selection;if(!r||(n?!n.endOfTextblock("forward",t):r.parentOffset{let{$head:r,empty:i}=t.selection,o=r;if(!i)return!1;if(r.parent.isTextblock){if(n?!n.endOfTextblock("forward",t):r.parentOffset{let{$head:n,$anchor:r}=t.selection;return!(!n.parent.type.spec.code||!n.sameParent(r))&&(e&&e(t.tr.insertText("\n").scrollIntoView()),!0)}),((t,e)=>{let n=t.selection,{$from:r,$to:i}=n;if(n instanceof Dc||r.parent.inlineContent||i.parent.inlineContent)return!1;let o=gh(i.parent.contentMatchAt(i.indexAfter()));if(!o||!o.isTextblock)return!1;if(e){let n=(!r.parentOffset&&i.index(){let{$cursor:n}=t.selection;if(!n||n.parent.content.size)return!1;if(n.depth>1&&n.after()!=n.end(-1)){let r=n.before();if(sc(t.doc,r))return e&&e(t.tr.split(r).scrollIntoView()),!0}let r=n.blockRange(),i=r&&rc(r);return null!=i&&(e&&e(t.tr.lift(r,i).scrollIntoView()),!0)}),((t,e)=>{let{$from:n,$to:r}=t.selection;if(t.selection instanceof Nc&&t.selection.node.isBlock)return!(!n.parentOffset||!sc(t.doc,n.pos))&&(e&&e(t.tr.split(n.pos).scrollIntoView()),!0);if(!n.parent.isBlock)return!1;if(e){let i=r.parentOffset==r.parent.content.size,o=t.tr;(t.selection instanceof Cc||t.selection instanceof Dc)&&o.deleteSelection();let s=0==n.depth?null:gh(n.node(-1).contentMatchAt(n.indexAfter(-1))),a=i&&s?[{type:s}]:void 0,l=sc(o.doc,o.mapping.map(n.pos),1,a);if(a||l||!sc(o.doc,o.mapping.map(n.pos),1,s?[{type:s}]:void 0)||(s&&(a=[{type:s}]),l=!0),l&&(o.split(o.mapping.map(n.pos),1,a),!i&&!n.parentOffset&&n.parent.type!=s)){let t=o.mapping.map(n.before()),e=o.doc.resolve(t);s&&n.node(-1).canReplaceWith(e.index(),e.index()+1,s)&&o.setNodeMarkup(o.mapping.map(n.before()),s)}e(o.scrollIntoView())}return!0})),"Mod-Enter":vh,Backspace:_h,"Mod-Backspace":_h,"Shift-Backspace":_h,Delete:Mh,"Mod-Delete":Mh,"Mod-a":(t,e)=>(e&&e(t.tr.setSelection(new Dc(t.doc))),!0)},$h={"Ctrl-h":Ch.Backspace,"Alt-Backspace":Ch["Mod-Backspace"],"Ctrl-d":Ch.Delete,"Ctrl-Alt-Backspace":Ch["Mod-Delete"],"Alt-Delete":Ch["Mod-Delete"],"Alt-d":Ch["Mod-Delete"],"Ctrl-a":wh,"Ctrl-e":xh};for(let os in Ch)$h[os]=Ch[os];const Nh=("undefined"!=typeof navigator?/Mac|iP(hone|[oa]d)/.test(navigator.platform):!("undefined"==typeof os||!os.platform)&&"darwin"==os.platform())?$h:Ch;class Th{constructor(t,e){var n;this.match=t,this.match=t,this.handler="string"==typeof e?(n=e,function(t,e,r,i){let o=n;if(e[1]){let t=e[0].lastIndexOf(e[1]);o+=e[0].slice(t+e[1].length);let n=(r+=t)-i;n>0&&(o=e[0].slice(t-n,t)+o,r=i)}return t.tr.insertText(o,r,i)}):e}}function Dh({rules:t}){let e=new Vc({state:{init:()=>null,apply(t,e){let n=t.getMeta(this);return n||(t.selectionSet||t.docChanged?null:e)}},props:{handleTextInput:(n,r,i,o)=>Ah(n,r,i,o,t,e),handleDOMEvents:{compositionend:n=>{setTimeout((()=>{let{$cursor:r}=n.state.selection;r&&Ah(n,r.pos,r.pos,"",t,e)}))}}},isInputRules:!0});return e}function Ah(t,e,n,r,i,o){if(t.composing)return!1;let s=t.state,a=s.doc.resolve(e);if(a.parent.type.spec.code)return!1;let l=a.parent.textBetween(Math.max(0,a.parentOffset-500),a.parentOffset,null,"")+r;for(let c=0;c{let n=t.plugins;for(let r=0;r=0;t--)n.step(r.steps[t].invert(r.docs[t]));if(i.text){let e=n.doc.resolve(i.from).marks();n.replaceWith(i.from,i.to,t.schema.text(i.text,e))}else n.delete(i.from,i.to);e(n)}return!0}}return!1};function Ph(t,e,n=null,r){return new Th(t,((t,i,o,s)=>{let a=n instanceof Function?n(i):n,l=t.tr.delete(o,s),c=l.doc.resolve(o).blockRange(),u=c&&ic(c,e,a);if(!u)return null;l.wrap(c,u);let d=l.doc.resolve(o-1).nodeBefore;return d&&d.type==e&&ac(l.doc,o-1)&&(!r||r(i,d))&&l.join(o-1),l}))}function Ih(t,e,n=null){return new Th(t,((t,r,i,o)=>{let s=t.doc.resolve(i),a=n instanceof Function?n(r):n;return s.node(-1).canReplaceWith(s.index(-1),s.indexAfter(-1),e)?t.tr.delete(i,o).setBlockType(i,i,e,a):null}))}new Th(/--$/,"—"),new Th(/\.\.\.$/,"…"),new Th(/(?:^|[\s\{\[\(\<'"\u2018\u201C])(")$/,"“"),new Th(/"$/,"”"),new Th(/(?:^|[\s\{\[\(\<'"\u2018\u201C])(')$/,"‘"),new Th(/'$/,"’");const Rh=["ol",0],zh=["ul",0],jh=["li",0],Fh={attrs:{order:{default:1}},parseDOM:[{tag:"ol",getAttrs:t=>({order:t.hasAttribute("start")?+t.getAttribute("start"):1})}],toDOM:t=>1==t.attrs.order?Rh:["ol",{start:t.attrs.order},0]},Lh={parseDOM:[{tag:"ul"}],toDOM:()=>zh},Bh={parseDOM:[{tag:"li"}],toDOM:()=>jh,defining:!0};function Vh(t,e){let n={};for(let r in t)n[r]=t[r];for(let r in e)n[r]=e[r];return n}function qh(t,e,n){return t.append({ordered_list:Vh(Fh,{content:"list_item+",group:n}),bullet_list:Vh(Lh,{content:"list_item+",group:n}),list_item:Vh(Bh,{content:e})})}function Jh(t,e=null){return function(n,r){let{$from:i,$to:o}=n.selection,s=i.blockRange(o),a=!1,l=s;if(!s)return!1;if(s.depth>=2&&i.node(s.depth-1).type.compatibleContent(t)&&0==s.startIndex){if(0==i.index(s.depth-1))return!1;let t=n.doc.resolve(s.start-2);l=new ol(t,t,s.depth),s.endIndex=0;u--)o=za.from(n[u].type.create(n[u].attrs,o));t.step(new tc(e.start-(r?2:0),e.end,e.start,e.end,new qa(o,0,0),n.length,!0));let s=0;for(let u=0;u=r.depth-3;t--)i=za.from(r.node(t).copy(i));let s=r.indexAfter(-1){if(c>-1)return!1;t.isTextblock&&0==t.content.size&&(c=e+1)})),c>-1&&l.setSelection(Sc.near(l.doc.resolve(c))),n(l.scrollIntoView())}return!0}let a=i.pos==r.end()?s.contentMatchAt(0).defaultType:null,l=e.tr.delete(r.pos,i.pos),c=a?[null,{type:a}]:void 0;return!!sc(l.doc,r.pos,2,c)&&(n&&n(l.split(r.pos,2,c).scrollIntoView()),!0)}}function Hh(t){return function(e,n){let{$from:r,$to:i}=e.selection,o=r.blockRange(i,(e=>e.childCount>0&&e.firstChild.type==t));return!!o&&(!n||(r.node(o.depth-1).type==t?function(t,e,n,r){let i=t.tr,o=r.end,s=r.$to.end(r.depth);om;p--)h-=i.child(p).nodeSize,r.delete(h-1,h+1);let o=r.doc.resolve(n.start),s=o.nodeAfter;if(r.mapping.map(n.end)!=n.start+o.nodeAfter.nodeSize)return!1;let a=0==n.startIndex,l=n.endIndex==i.childCount,c=o.node(-1),u=o.index(-1);if(!c.canReplace(u+(a?0:1),u+1,s.content.append(l?za.empty:za.from(i))))return!1;let d=o.pos,f=d+s.nodeSize;return r.step(new tc(d-(a?1:0),f+(l?1:0),d+1,f-1,new qa((a?za.empty:za.from(i.copy(za.empty))).append(l?za.empty:za.from(i.copy(za.empty))),a?0:1,l?0:1),a?0:1)),e(r.scrollIntoView()),!0}(e,n,o)))}}function Kh(t){return function(e,n){let{$from:r,$to:i}=e.selection,o=r.blockRange(i,(e=>e.childCount>0&&e.firstChild.type==t));if(!o)return!1;let s=o.startIndex;if(0==s)return!1;let a=o.parent,l=a.child(s-1);if(l.type!=t)return!1;if(n){let r=l.lastChild&&l.lastChild.type==a.type,i=za.from(r?t.create():null),s=new qa(za.from(t.create(null,za.from(a.type.create(null,i)))),r?3:1,0),c=o.start,u=o.end;n(e.tr.step(new tc(c-(r?3:1),u,c,u,s,1,!0)).scrollIntoView())}return!0}}var Uh=function(){};Uh.prototype.append=function(t){return t.length?(t=Uh.from(t),!this.length&&t||t.length<200&&this.leafAppend(t)||this.length<200&&t.leafPrepend(this)||this.appendInner(t)):this},Uh.prototype.prepend=function(t){return t.length?Uh.from(t).append(this):this},Uh.prototype.appendInner=function(t){return new Gh(this,t)},Uh.prototype.slice=function(t,e){return void 0===t&&(t=0),void 0===e&&(e=this.length),t>=e?Uh.empty:this.sliceInner(Math.max(0,t),Math.min(this.length,e))},Uh.prototype.get=function(t){if(!(t<0||t>=this.length))return this.getInner(t)},Uh.prototype.forEach=function(t,e,n){void 0===e&&(e=0),void 0===n&&(n=this.length),e<=n?this.forEachInner(t,e,n,0):this.forEachInvertedInner(t,e,n,0)},Uh.prototype.map=function(t,e,n){void 0===e&&(e=0),void 0===n&&(n=this.length);var r=[];return this.forEach((function(e,n){return r.push(t(e,n))}),e,n),r},Uh.from=function(t){return t instanceof Uh?t:t&&t.length?new Yh(t):Uh.empty};var Yh=function(t){function e(e){t.call(this),this.values=e}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var n={length:{configurable:!0},depth:{configurable:!0}};return e.prototype.flatten=function(){return this.values},e.prototype.sliceInner=function(t,n){return 0==t&&n==this.length?this:new e(this.values.slice(t,n))},e.prototype.getInner=function(t){return this.values[t]},e.prototype.forEachInner=function(t,e,n,r){for(var i=e;i=n;i--)if(!1===t(this.values[i],r+i))return!1},e.prototype.leafAppend=function(t){if(this.length+t.length<=200)return new e(this.values.concat(t.flatten()))},e.prototype.leafPrepend=function(t){if(this.length+t.length<=200)return new e(t.flatten().concat(this.values))},n.length.get=function(){return this.values.length},n.depth.get=function(){return 0},Object.defineProperties(e.prototype,n),e}(Uh);Uh.empty=new Yh([]);var Gh=function(t){function e(e,n){t.call(this),this.left=e,this.right=n,this.length=e.length+n.length,this.depth=Math.max(e.depth,n.depth)+1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.flatten=function(){return this.left.flatten().concat(this.right.flatten())},e.prototype.getInner=function(t){return ti&&!1===this.right.forEachInner(t,Math.max(e-i,0),Math.min(this.length,n)-i,r+i))&&void 0)},e.prototype.forEachInvertedInner=function(t,e,n,r){var i=this.left.length;return!(e>i&&!1===this.right.forEachInvertedInner(t,e-i,Math.max(n,i)-i,r+i))&&(!(n=n?this.right.slice(t-n,e-n):this.left.slice(t,n).append(this.right.slice(0,e-n))},e.prototype.leafAppend=function(t){var n=this.right.leafAppend(t);if(n)return new e(this.left,n)},e.prototype.leafPrepend=function(t){var n=this.left.leafPrepend(t);if(n)return new e(n,this.right)},e.prototype.appendInner=function(t){return this.left.depth>=Math.max(this.right.depth,t.depth)+1?new e(this.left,new e(this.right,t)):new e(this,t)},e}(Uh),Zh=Uh;class Xh{constructor(t,e){this.items=t,this.eventCount=e}popEvent(t,e){if(0==this.eventCount)return null;let n,r,i=this.items.length;for(;;i--){if(this.items.get(i-1).selection){--i;break}}e&&(n=this.remapping(i,this.items.length),r=n.maps.length);let o,s,a=t.tr,l=[],c=[];return this.items.forEach(((t,e)=>{if(!t.step)return n||(n=this.remapping(i,e+1),r=n.maps.length),r--,void c.push(t);if(n){c.push(new Qh(t.map));let e,i=t.step.map(n.slice(r));i&&a.maybeStep(i).doc&&(e=a.mapping.maps[a.mapping.maps.length-1],l.push(new Qh(e,void 0,void 0,l.length+c.length))),r--,e&&n.appendMap(e,r)}else a.maybeStep(t.step);return t.selection?(o=n?t.selection.map(n.slice(r)):t.selection,s=new Xh(this.items.slice(0,i).append(c.reverse().concat(l)),this.eventCount-1),!1):void 0}),this.items.length,0),{remaining:s,transform:a,selection:o}}addTransform(t,e,n,r){let i=[],o=this.eventCount,s=this.items,a=!r&&s.length?s.get(s.length-1):null;for(let c=0;cep&&(s=function(t,e){let n;return t.forEach(((t,r)=>{if(t.selection&&0==e--)return n=r,!1})),t.slice(n)}(s,l),o-=l),new Xh(s.append(i),o)}remapping(t,e){let n=new Jl;return this.items.forEach(((e,r)=>{let i=null!=e.mirrorOffset&&r-e.mirrorOffset>=t?n.maps.length-e.mirrorOffset:void 0;n.appendMap(e.map,i)}),t,e),n}addMaps(t){return 0==this.eventCount?this:new Xh(this.items.append(t.map((t=>new Qh(t)))),this.eventCount)}rebased(t,e){if(!this.eventCount)return this;let n=[],r=Math.max(0,this.items.length-e),i=t.mapping,o=t.steps.length,s=this.eventCount;this.items.forEach((t=>{t.selection&&s--}),r);let a=e;this.items.forEach((e=>{let r=i.getMirror(--a);if(null==r)return;o=Math.min(o,r);let l=i.maps[r];if(e.step){let o=t.steps[r].invert(t.docs[r]),c=e.selection&&e.selection.map(i.slice(a+1,r));c&&s++,n.push(new Qh(l,o,c))}else n.push(new Qh(l))}),r);let l=[];for(let d=e;d500&&(u=u.compress(this.items.length-n.length)),u}emptyItemCount(){let t=0;return this.items.forEach((e=>{e.step||t++})),t}compress(t=this.items.length){let e=this.remapping(0,t),n=e.maps.length,r=[],i=0;return this.items.forEach(((o,s)=>{if(s>=t)r.push(o),o.selection&&i++;else if(o.step){let t=o.step.map(e.slice(n)),s=t&&t.getMap();if(n--,s&&e.appendMap(s,n),t){let a=o.selection&&o.selection.map(e.slice(n));a&&i++;let l,c=new Qh(s.invert(),t,a),u=r.length-1;(l=r.length&&r[u].merge(c))?r[u]=l:r.push(c)}}else o.map&&n--}),this.items.length,0),new Xh(Zh.from(r.reverse()),i)}}Xh.empty=new Xh(Zh.empty,0);class Qh{constructor(t,e,n,r){this.map=t,this.step=e,this.selection=n,this.mirrorOffset=r}merge(t){if(this.step&&t.step&&!t.selection){let e=t.step.merge(this.step);if(e)return new Qh(e.getMap().invert(),e,this.selection)}}}class tp{constructor(t,e,n,r){this.done=t,this.undone=e,this.prevRanges=n,this.prevTime=r}}const ep=20;function np(t){let e=[];return t.forEach(((t,n,r,i)=>e.push(r,i))),e}function rp(t,e){if(!t)return null;let n=[];for(let r=0;rnew tp(Xh.empty,Xh.empty,null,0),apply:(e,n,r)=>function(t,e,n,r){let i,o=n.getMeta(lp);if(o)return o.historyState;n.getMeta(cp)&&(t=new tp(t.done,t.undone,null,0));let s=n.getMeta("appendedTransaction");if(0==n.steps.length)return t;if(s&&s.getMeta(lp))return s.getMeta(lp).redo?new tp(t.done.addTransform(n,void 0,r,ap(e)),t.undone,np(n.mapping.maps[n.steps.length-1]),t.prevTime):new tp(t.done,t.undone.addTransform(n,void 0,r,ap(e)),null,t.prevTime);if(!1===n.getMeta("addToHistory")||s&&!1===s.getMeta("addToHistory"))return(i=n.getMeta("rebased"))?new tp(t.done.rebased(n,i),t.undone.rebased(n,i),rp(t.prevRanges,n.mapping),t.prevTime):new tp(t.done.addMaps(n.mapping.maps),t.undone.addMaps(n.mapping.maps),rp(t.prevRanges,n.mapping),t.prevTime);{let i=0==t.prevTime||!s&&(t.prevTime<(n.time||0)-r.newGroupDelay||!function(t,e){if(!e)return!1;if(!t.docChanged)return!0;let n=!1;return t.mapping.maps[0].forEach(((t,r)=>{for(let i=0;i=e[i]&&(n=!0)})),n}(n,t.prevRanges)),o=s?rp(t.prevRanges,n.mapping):np(n.mapping.maps[n.steps.length-1]);return new tp(t.done.addTransform(n,i?e.selection.getBookmark():void 0,r,ap(e)),Xh.empty,o,n.time)}}(n,r,e,t)},config:t,props:{handleDOMEvents:{beforeinput(t,e){let n=e.inputType,r="historyUndo"==n?dp:"historyRedo"==n?fp:null;return!!r&&(e.preventDefault(),r(t.state,t.dispatch))}}}})}const dp=(t,e)=>{let n=lp.getState(t);return!(!n||0==n.done.eventCount)&&(e&&ip(n,t,e,!1),!0)},fp=(t,e)=>{let n=lp.getState(t);return!(!n||0==n.undone.eventCount)&&(e&&ip(n,t,e,!0),!0)};function hp(t){let e=lp.getState(t);return e?e.done.eventCount:0}function pp(t){let e=lp.getState(t);return e?e.undone.eventCount:0}"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function mp(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}var gp={},vp={},yp={},bp={},wp={};function xp(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function kp(t){for(var e=1;e=+n}))};var Fp={};Object.defineProperty(Fp,"__esModule",{value:!0}),Fp.default=void 0;var Lp=(0,yp.regex)("email",/^(?:[A-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]{2,}(?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/i);Fp.default=Lp;var Bp={};Object.defineProperty(Bp,"__esModule",{value:!0}),Bp.default=void 0;var Vp=yp,qp=(0,Vp.withParams)({type:"ipAddress"},(function(t){if(!(0,Vp.req)(t))return!0;if("string"!=typeof t)return!1;var e=t.split(".");return 4===e.length&&e.every(Jp)}));Bp.default=qp;var Jp=function(t){if(t.length>3||0===t.length)return!1;if("0"===t[0]&&"0"!==t)return!1;if(!t.match(/^\d+$/))return!1;var e=0|+t;return e>=0&&e<=255},Wp={};Object.defineProperty(Wp,"__esModule",{value:!0}),Wp.default=void 0;var Hp=yp;Wp.default=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:":";return(0,Hp.withParams)({type:"macAddress"},(function(e){if(!(0,Hp.req)(e))return!0;if("string"!=typeof e)return!1;var n="string"==typeof t&&""!==t?e.split(t):12===e.length||16===e.length?e.match(/.{2}/g):null;return null!==n&&(6===n.length||8===n.length)&&n.every(Kp)}))};var Kp=function(t){return t.toLowerCase().match(/^[0-9a-f]{2}$/)},Up={};Object.defineProperty(Up,"__esModule",{value:!0}),Up.default=void 0;var Yp=yp;Up.default=function(t){return(0,Yp.withParams)({type:"maxLength",max:t},(function(e){return!(0,Yp.req)(e)||(0,Yp.len)(e)<=t}))};var Gp={};Object.defineProperty(Gp,"__esModule",{value:!0}),Gp.default=void 0;var Zp=yp;Gp.default=function(t){return(0,Zp.withParams)({type:"minLength",min:t},(function(e){return!(0,Zp.req)(e)||(0,Zp.len)(e)>=t}))};var Xp={};Object.defineProperty(Xp,"__esModule",{value:!0}),Xp.default=void 0;var Qp=yp,tm=(0,Qp.withParams)({type:"required"},(function(t){return(0,Qp.req)("string"==typeof t?t.trim():t)}));Xp.default=tm;var em={};Object.defineProperty(em,"__esModule",{value:!0}),em.default=void 0;var nm=yp;em.default=function(t){return(0,nm.withParams)({type:"requiredIf",prop:t},(function(e,n){return!(0,nm.ref)(t,this,n)||(0,nm.req)(e)}))};var rm={};Object.defineProperty(rm,"__esModule",{value:!0}),rm.default=void 0;var im=yp;rm.default=function(t){return(0,im.withParams)({type:"requiredUnless",prop:t},(function(e,n){return!!(0,im.ref)(t,this,n)||(0,im.req)(e)}))};var om={};Object.defineProperty(om,"__esModule",{value:!0}),om.default=void 0;var sm=yp;om.default=function(t){return(0,sm.withParams)({type:"sameAs",eq:t},(function(e,n){return e===(0,sm.ref)(t,this,n)}))};var am={};Object.defineProperty(am,"__esModule",{value:!0}),am.default=void 0;var lm=(0,yp.regex)("url",/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i);am.default=lm;var cm={};Object.defineProperty(cm,"__esModule",{value:!0}),cm.default=void 0;var um=yp;cm.default=function(){for(var t=arguments.length,e=new Array(t),n=0;n0&&e.reduce((function(e,n){return e||n.apply(t,r)}),!1)}))};var dm={};Object.defineProperty(dm,"__esModule",{value:!0}),dm.default=void 0;var fm=yp;dm.default=function(){for(var t=arguments.length,e=new Array(t),n=0;n0&&e.reduce((function(e,n){return e&&n.apply(t,r)}),!0)}))};var hm={};Object.defineProperty(hm,"__esModule",{value:!0}),hm.default=void 0;var pm=yp;hm.default=function(t){return(0,pm.withParams)({type:"not"},(function(e,n){return!(0,pm.req)(e)||!t.call(this,e,n)}))};var mm={};Object.defineProperty(mm,"__esModule",{value:!0}),mm.default=void 0;var gm=yp;mm.default=function(t){return(0,gm.withParams)({type:"minValue",min:t},(function(e){return!(0,gm.req)(e)||(!/\s/.test(e)||e instanceof Date)&&+e>=+t}))};var vm={};Object.defineProperty(vm,"__esModule",{value:!0}),vm.default=void 0;var ym=yp;vm.default=function(t){return(0,ym.withParams)({type:"maxValue",max:t},(function(e){return!(0,ym.req)(e)||(!/\s/.test(e)||e instanceof Date)&&+e<=+t}))};var bm={};Object.defineProperty(bm,"__esModule",{value:!0}),bm.default=void 0;var wm=(0,yp.regex)("integer",/(^[0-9]*$)|(^-[0-9]+$)/);bm.default=wm;var xm={};Object.defineProperty(xm,"__esModule",{value:!0}),xm.default=void 0;var km=(0,yp.regex)("decimal",/^[-]?\d*(\.\d+)?$/);xm.default=km,function(t){function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"alpha",{enumerable:!0,get:function(){return n.default}}),Object.defineProperty(t,"alphaNum",{enumerable:!0,get:function(){return r.default}}),Object.defineProperty(t,"and",{enumerable:!0,get:function(){return v.default}}),Object.defineProperty(t,"between",{enumerable:!0,get:function(){return o.default}}),Object.defineProperty(t,"decimal",{enumerable:!0,get:function(){return k.default}}),Object.defineProperty(t,"email",{enumerable:!0,get:function(){return s.default}}),t.helpers=void 0,Object.defineProperty(t,"integer",{enumerable:!0,get:function(){return x.default}}),Object.defineProperty(t,"ipAddress",{enumerable:!0,get:function(){return a.default}}),Object.defineProperty(t,"macAddress",{enumerable:!0,get:function(){return l.default}}),Object.defineProperty(t,"maxLength",{enumerable:!0,get:function(){return c.default}}),Object.defineProperty(t,"maxValue",{enumerable:!0,get:function(){return w.default}}),Object.defineProperty(t,"minLength",{enumerable:!0,get:function(){return u.default}}),Object.defineProperty(t,"minValue",{enumerable:!0,get:function(){return b.default}}),Object.defineProperty(t,"not",{enumerable:!0,get:function(){return y.default}}),Object.defineProperty(t,"numeric",{enumerable:!0,get:function(){return i.default}}),Object.defineProperty(t,"or",{enumerable:!0,get:function(){return g.default}}),Object.defineProperty(t,"required",{enumerable:!0,get:function(){return d.default}}),Object.defineProperty(t,"requiredIf",{enumerable:!0,get:function(){return f.default}}),Object.defineProperty(t,"requiredUnless",{enumerable:!0,get:function(){return h.default}}),Object.defineProperty(t,"sameAs",{enumerable:!0,get:function(){return p.default}}),Object.defineProperty(t,"url",{enumerable:!0,get:function(){return m.default}});var n=_(vp),r=_(Ep),i=_(Ip),o=_(zp),s=_(Fp),a=_(Bp),l=_(Wp),c=_(Up),u=_(Gp),d=_(Xp),f=_(em),h=_(rm),p=_(om),m=_(am),g=_(cm),v=_(dm),y=_(hm),b=_(mm),w=_(vm),x=_(bm),k=_(xm),S=function(t,n){if(!n&&t&&t.__esModule)return t;if(null===t||"object"!==e(t)&&"function"!=typeof t)return{default:t};var r=O(n);if(r&&r.has(t))return r.get(t);var i={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var s in t)if("default"!==s&&Object.prototype.hasOwnProperty.call(t,s)){var a=o?Object.getOwnPropertyDescriptor(t,s):null;a&&(a.get||a.set)?Object.defineProperty(i,s,a):i[s]=t[s]}i.default=t,r&&r.set(t,i);return i}(yp);function O(t){if("function"!=typeof WeakMap)return null;var e=new WeakMap,n=new WeakMap;return(O=function(t){return t?n:e})(t)}function _(t){return t&&t.__esModule?t:{default:t}}t.helpers=S}(gp);function Sm(t){return(Sm="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var Om={selector:"vue-portal-target-".concat(((t=21)=>{let e="",n=t;for(;n--;)e+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[64*Math.random()|0];return e})())},_m=function(t){return Om.selector=t},Mm="undefined"!=typeof window&&void 0!==("undefined"==typeof document?"undefined":Sm(document)),Cm=Wn.extend({abstract:!0,name:"PortalOutlet",props:["nodes","tag"],data:function(t){return{updatedNodes:t.nodes}},render:function(t){var e=this.updatedNodes&&this.updatedNodes();return e?1!==e.length||e[0].text?t(this.tag||"DIV",e):e:t()},destroyed:function(){var t=this.$el;t&&t.parentNode.removeChild(t)}}),$m=Wn.extend({name:"VueSimplePortal",props:{disabled:{type:Boolean},prepend:{type:Boolean},selector:{type:String,default:function(){return"#".concat(Om.selector)}},tag:{type:String,default:"DIV"}},render:function(t){if(this.disabled){var e=this.$scopedSlots&&this.$scopedSlots.default();return e?e.length<2&&!e[0].text?e:t(this.tag,e):t()}return t()},created:function(){this.getTargetEl()||this.insertTargetEl()},updated:function(){var t=this;this.$nextTick((function(){t.disabled||t.slotFn===t.$scopedSlots.default||(t.container.updatedNodes=t.$scopedSlots.default),t.slotFn=t.$scopedSlots.default}))},beforeDestroy:function(){this.unmount()},watch:{disabled:{immediate:!0,handler:function(t){t?this.unmount():this.$nextTick(this.mount)}}},methods:{getTargetEl:function(){if(Mm)return document.querySelector(this.selector)},insertTargetEl:function(){if(Mm){var t=document.querySelector("body"),e=document.createElement(this.tag);e.id=this.selector.substring(1),t.appendChild(e)}},mount:function(){if(Mm){var t=this.getTargetEl(),e=document.createElement("DIV");this.prepend&&t.firstChild?t.insertBefore(e,t.firstChild):t.appendChild(e),this.container=new Cm({el:e,parent:this,propsData:{tag:this.tag,nodes:this.$scopedSlots.default}})}},unmount:function(){this.container&&(this.container.$destroy(),delete this.container)}}});function Nm(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t.component(e.name||"portal",$m),e.defaultSelector&&_m(e.defaultSelector)}"undefined"!=typeof window&&window.Vue&&window.Vue===Wn&&Wn.use(Nm) /*! * vuex v3.6.2 * (c) 2021 Evan You * @license MIT - */ -function(t){if(Number(t.version.split(".")[0])>=2)t.mixin({beforeCreate:n});else{var e=t.prototype._init;t.prototype._init=function(t){void 0===t&&(t={}),t.init=t.init?[n].concat(t.init):n,e.call(this,t)}}function n(){var t=this.$options;t.store?this.$store="function"==typeof t.store?t.store():t.store:t.parent&&t.parent.$store&&(this.$store=t.parent.$store)}}(Fa=t)}Wa.state.get=function(){return this._vm._data.$$state},Wa.state.set=function(t){},Va.prototype.commit=function(t,e,n){var r=this,i=Ya(t,e,n),o=i.type,s=i.payload,a={type:o,payload:s},l=this._mutations[o];l&&(this._withCommit((function(){l.forEach((function(t){t(s)}))})),this._subscribers.slice().forEach((function(t){return t(a,r.state)})))},Va.prototype.dispatch=function(t,e){var n=this,r=Ya(t,e),i=r.type,o=r.payload,s={type:i,payload:o},a=this._actions[i];if(a){try{this._actionSubscribers.slice().filter((function(t){return t.before})).forEach((function(t){return t.before(s,n.state)}))}catch(_g){}var l=a.length>1?Promise.all(a.map((function(t){return t(o)}))):a[0](o);return new Promise((function(t,e){l.then((function(e){try{n._actionSubscribers.filter((function(t){return t.after})).forEach((function(t){return t.after(s,n.state)}))}catch(_g){}t(e)}),(function(t){try{n._actionSubscribers.filter((function(t){return t.error})).forEach((function(e){return e.error(s,n.state,t)}))}catch(_g){}e(t)}))}))}},Va.prototype.subscribe=function(t,e){return qa(t,this._subscribers,e)},Va.prototype.subscribeAction=function(t,e){return qa("function"==typeof t?{before:t}:t,this._actionSubscribers,e)},Va.prototype.watch=function(t,e,n){var r=this;return this._watcherVM.$watch((function(){return t(r.state,r.getters)}),e,n)},Va.prototype.replaceState=function(t){var e=this;this._withCommit((function(){e._vm._data.$$state=t}))},Va.prototype.registerModule=function(t,e,n){void 0===n&&(n={}),"string"==typeof t&&(t=[t]),this._modules.register(t,e),Ha(this,this.state,t,this._modules.get(t),n.preserveState),Ka(this,this.state)},Va.prototype.unregisterModule=function(t){var e=this;"string"==typeof t&&(t=[t]),this._modules.unregister(t),this._withCommit((function(){var n=Ua(e.state,t.slice(0,-1));Fa.delete(n,t[t.length-1])})),Ja(this)},Va.prototype.hasModule=function(t){return"string"==typeof t&&(t=[t]),this._modules.isRegistered(t)},Va.prototype.hotUpdate=function(t){this._modules.update(t),Ja(this,!0)},Va.prototype._withCommit=function(t){var e=this._committing;this._committing=!0,t(),this._committing=e},Object.defineProperties(Va.prototype,Wa);var Za=nl((function(t,e){var n={};return el(e).forEach((function(e){var r=e.key,i=e.val;n[r]=function(){var e=this.$store.state,n=this.$store.getters;if(t){var r=rl(this.$store,"mapState",t);if(!r)return;e=r.context.state,n=r.context.getters}return"function"==typeof i?i.call(this,e,n):e[i]},n[r].vuex=!0})),n})),Xa=nl((function(t,e){var n={};return el(e).forEach((function(e){var r=e.key,i=e.val;n[r]=function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];var r=this.$store.commit;if(t){var o=rl(this.$store,"mapMutations",t);if(!o)return;r=o.context.commit}return"function"==typeof i?i.apply(this,[r].concat(e)):r.apply(this.$store,[i].concat(e))}})),n})),Qa=nl((function(t,e){var n={};return el(e).forEach((function(e){var r=e.key,i=e.val;i=t+i,n[r]=function(){if(!t||rl(this.$store,"mapGetters",t))return this.$store.getters[i]},n[r].vuex=!0})),n})),tl=nl((function(t,e){var n={};return el(e).forEach((function(e){var r=e.key,i=e.val;n[r]=function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];var r=this.$store.dispatch;if(t){var o=rl(this.$store,"mapActions",t);if(!o)return;r=o.context.dispatch}return"function"==typeof i?i.apply(this,[r].concat(e)):r.apply(this.$store,[i].concat(e))}})),n}));function el(t){return function(t){return Array.isArray(t)||Ra(t)}(t)?Array.isArray(t)?t.map((function(t){return{key:t,val:t}})):Object.keys(t).map((function(e){return{key:e,val:t[e]}})):[]}function nl(t){return function(e,n){return"string"!=typeof e?(n=e,e=""):"/"!==e.charAt(e.length-1)&&(e+="/"),t(e,n)}}function rl(t,e,n){return t._modulesNamespaceMap[n]}function il(t,e,n){var r=n?t.groupCollapsed:t.group;try{r.call(t,e)}catch(_g){t.log(e)}}function ol(t){try{t.groupEnd()}catch(_g){t.log("—— log end ——")}}function sl(){var t=new Date;return" @ "+al(t.getHours(),2)+":"+al(t.getMinutes(),2)+":"+al(t.getSeconds(),2)+"."+al(t.getMilliseconds(),3)}function al(t,e){return n="0",r=e-t.toString().length,new Array(r+1).join(n)+t;var n,r}const ll={Store:Va,install:Ga,version:"3.6.2",mapState:Za,mapMutations:Xa,mapGetters:Qa,mapActions:tl,createNamespacedHelpers:function(t){return{mapState:Za.bind(null,t),mapGetters:Qa.bind(null,t),mapMutations:Xa.bind(null,t),mapActions:tl.bind(null,t)}},createLogger:function(t){void 0===t&&(t={});var e=t.collapsed;void 0===e&&(e=!0);var n=t.filter;void 0===n&&(n=function(t,e,n){return!0});var r=t.transformer;void 0===r&&(r=function(t){return t});var i=t.mutationTransformer;void 0===i&&(i=function(t){return t});var o=t.actionFilter;void 0===o&&(o=function(t,e){return!0});var s=t.actionTransformer;void 0===s&&(s=function(t){return t});var a=t.logMutations;void 0===a&&(a=!0);var l=t.logActions;void 0===l&&(l=!0);var c=t.logger;return void 0===c&&(c=console),function(t){var u=Pa(t.state);void 0!==c&&(a&&t.subscribe((function(t,o){var s=Pa(o);if(n(t,u,s)){var a=sl(),l=i(t),d="mutation "+t.type+a;il(c,d,e),c.log("%c prev state","color: #9E9E9E; font-weight: bold",r(u)),c.log("%c mutation","color: #03A9F4; font-weight: bold",l),c.log("%c next state","color: #4CAF50; font-weight: bold",r(s)),ol(c)}u=s})),l&&t.subscribeAction((function(t,n){if(o(t,n)){var r=sl(),i=s(t),a="action "+t.type+r;il(c,a,e),c.log("%c action","color: #03A9F4; font-weight: bold",i),ol(c)}})))}}};function cl(t){return{all:t=t||new Map,on:function(e,n){var r=t.get(e);r?r.push(n):t.set(e,[n])},off:function(e,n){var r=t.get(e);r&&(n?r.splice(r.indexOf(n)>>>0,1):t.set(e,[]))},emit:function(e,n){var r=t.get(e);r&&r.slice().map((function(t){t(n)})),(r=t.get("*"))&&r.slice().map((function(t){t(e,n)}))}}}var ul,dl,fl="function"==typeof Map?new Map:(ul=[],dl=[],{has:function(t){return ul.indexOf(t)>-1},get:function(t){return dl[ul.indexOf(t)]},set:function(t,e){-1===ul.indexOf(t)&&(ul.push(t),dl.push(e))},delete:function(t){var e=ul.indexOf(t);e>-1&&(ul.splice(e,1),dl.splice(e,1))}}),hl=function(t){return new Event(t,{bubbles:!0})};try{new Event("test")}catch(_g){hl=function(t){var e=document.createEvent("Event");return e.initEvent(t,!0,!1),e}}function pl(t){var e=fl.get(t);e&&e.destroy()}function ml(t){var e=fl.get(t);e&&e.update()}var gl=null;"undefined"==typeof window||"function"!=typeof window.getComputedStyle?((gl=function(t){return t}).destroy=function(t){return t},gl.update=function(t){return t}):((gl=function(t,e){return t&&Array.prototype.forEach.call(t.length?t:[t],(function(t){return function(t){if(t&&t.nodeName&&"TEXTAREA"===t.nodeName&&!fl.has(t)){var e,n=null,r=null,i=null,o=function(){t.clientWidth!==r&&c()},s=function(e){window.removeEventListener("resize",o,!1),t.removeEventListener("input",c,!1),t.removeEventListener("keyup",c,!1),t.removeEventListener("autosize:destroy",s,!1),t.removeEventListener("autosize:update",c,!1),Object.keys(e).forEach((function(n){t.style[n]=e[n]})),fl.delete(t)}.bind(t,{height:t.style.height,resize:t.style.resize,overflowY:t.style.overflowY,overflowX:t.style.overflowX,wordWrap:t.style.wordWrap});t.addEventListener("autosize:destroy",s,!1),"onpropertychange"in t&&"oninput"in t&&t.addEventListener("keyup",c,!1),window.addEventListener("resize",o,!1),t.addEventListener("input",c,!1),t.addEventListener("autosize:update",c,!1),t.style.overflowX="hidden",t.style.wordWrap="break-word",fl.set(t,{destroy:s,update:c}),"vertical"===(e=window.getComputedStyle(t,null)).resize?t.style.resize="none":"both"===e.resize&&(t.style.resize="horizontal"),n="content-box"===e.boxSizing?-(parseFloat(e.paddingTop)+parseFloat(e.paddingBottom)):parseFloat(e.borderTopWidth)+parseFloat(e.borderBottomWidth),isNaN(n)&&(n=0),c()}function a(e){var n=t.style.width;t.style.width="0px",t.style.width=n,t.style.overflowY=e}function l(){if(0!==t.scrollHeight){var e=function(t){for(var e=[];t&&t.parentNode&&t.parentNode instanceof Element;)t.parentNode.scrollTop&&e.push({node:t.parentNode,scrollTop:t.parentNode.scrollTop}),t=t.parentNode;return e}(t),i=document.documentElement&&document.documentElement.scrollTop;t.style.height="",t.style.height=t.scrollHeight+n+"px",r=t.clientWidth,e.forEach((function(t){t.node.scrollTop=t.scrollTop})),i&&(document.documentElement.scrollTop=i)}}function c(){l();var e=Math.round(parseFloat(t.style.height)),n=window.getComputedStyle(t,null),r="content-box"===n.boxSizing?Math.round(parseFloat(n.height)):t.offsetHeight;if(r=e?t:""+Array(e+1-r.length).join(n)+t},y={s:v,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return(e<=0?"+":"-")+v(r,2,"0")+":"+v(i,2,"0")},m:function t(e,n){if(e.date()1)return t(s[0])}else{var a=e.name;w[a]=e,i=a}return!r&&i&&(b=i),i||!r&&b},k=function(t,e){if(x(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new _(n)},O=y;O.l=S,O.i=x,O.w=function(t,e){return k(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var _=function(){function g(t){this.$L=S(t.locale,null,!0),this.parse(t)}var v=g.prototype;return v.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(O.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match(p);if(r){var i=r[2]-1||0,o=(r[7]||"0").substring(0,3);return n?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,o)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,o)}}return new Date(e)}(t),this.$x=t.x||{},this.init()},v.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},v.$utils=function(){return O},v.isValid=function(){return!(this.$d.toString()===h)},v.isSame=function(t,e){var n=k(t);return this.startOf(e)<=n&&n<=this.endOf(e)},v.isAfter=function(t,e){return k(t)68?1900:2e3)},a=function(t){return function(e){this[t]=+e}},l=[/[+-]\d\d:?(\d\d)?|Z/,function(t){(this.zone||(this.zone={})).offset=function(t){if(!t)return 0;if("Z"===t)return 0;var e=t.match(/([+-]|\d\d)/g),n=60*e[1]+(+e[2]||0);return 0===n?0:"+"===e[0]?-n:n}(t)}],c=function(t){var e=o[t];return e&&(e.indexOf?e:e.s.concat(e.f))},u=function(t,e){var n,r=o.meridiem;if(r){for(var i=1;i<=24;i+=1)if(t.indexOf(r(i,0,e))>-1){n=i>12;break}}else n=t===(e?"pm":"PM");return n},d={A:[i,function(t){this.afternoon=u(t,!1)}],a:[i,function(t){this.afternoon=u(t,!0)}],S:[/\d/,function(t){this.milliseconds=100*+t}],SS:[n,function(t){this.milliseconds=10*+t}],SSS:[/\d{3}/,function(t){this.milliseconds=+t}],s:[r,a("seconds")],ss:[r,a("seconds")],m:[r,a("minutes")],mm:[r,a("minutes")],H:[r,a("hours")],h:[r,a("hours")],HH:[r,a("hours")],hh:[r,a("hours")],D:[r,a("day")],DD:[n,a("day")],Do:[i,function(t){var e=o.ordinal,n=t.match(/\d+/);if(this.day=n[0],e)for(var r=1;r<=31;r+=1)e(r).replace(/\[|\]/g,"")===t&&(this.day=r)}],M:[r,a("month")],MM:[n,a("month")],MMM:[i,function(t){var e=c("months"),n=(c("monthsShort")||e.map((function(t){return t.slice(0,3)}))).indexOf(t)+1;if(n<1)throw new Error;this.month=n%12||n}],MMMM:[i,function(t){var e=c("months").indexOf(t)+1;if(e<1)throw new Error;this.month=e%12||e}],Y:[/[+-]?\d+/,a("year")],YY:[n,function(t){this.year=s(t)}],YYYY:[/\d{4}/,a("year")],Z:l,ZZ:l};function f(n){var r,i;r=n,i=o&&o.formats;for(var s=(n=r.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(e,n,r){var o=r&&r.toUpperCase();return n||i[r]||t[r]||i[o].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(function(t,e,n){return e||n.slice(1)}))}))).match(e),a=s.length,l=0;l-1)return new Date(("X"===e?1e3:1)*t);var r=f(e)(t),i=r.year,o=r.month,s=r.day,a=r.hours,l=r.minutes,c=r.seconds,u=r.milliseconds,d=r.zone,h=new Date,p=s||(i||o?1:h.getDate()),m=i||h.getFullYear(),g=0;i&&!o||(g=o>0?o-1:h.getMonth());var v=a||0,y=l||0,b=c||0,w=u||0;return d?new Date(Date.UTC(m,g,p,v,y,b,w+60*d.offset*1e3)):n?new Date(Date.UTC(m,g,p,v,y,b,w)):new Date(m,g,p,v,y,b,w)}catch(x){return new Date("")}}(e,a,r),this.init(),d&&!0!==d&&(this.$L=this.locale(d).$L),u&&e!=this.format(a)&&(this.$d=new Date("")),o={}}else if(a instanceof Array)for(var h=a.length,p=1;p<=h;p+=1){s[1]=a[p-1];var m=n.apply(this,s);if(m.isValid()){this.$d=m.$d,this.$L=m.$L,this.init();break}p===h&&(this.$d=new Date(""))}else i.call(this,t)}}}();function kl(t){return(kl="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var Ol={selector:"vue-portal-target-".concat(((t=21)=>{let e="",n=t;for(;n--;)e+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[64*Math.random()|0];return e})())},_l=function(t){return Ol.selector=t},Ml="undefined"!=typeof window&&void 0!==("undefined"==typeof document?"undefined":kl(document)),Cl=Wn.extend({abstract:!0,name:"PortalOutlet",props:["nodes","tag"],data:function(t){return{updatedNodes:t.nodes}},render:function(t){var e=this.updatedNodes&&this.updatedNodes();return e?1!==e.length||e[0].text?t(this.tag||"DIV",e):e:t()},destroyed:function(){var t=this.$el;t&&t.parentNode.removeChild(t)}}),$l=Wn.extend({name:"VueSimplePortal",props:{disabled:{type:Boolean},prepend:{type:Boolean},selector:{type:String,default:function(){return"#".concat(Ol.selector)}},tag:{type:String,default:"DIV"}},render:function(t){if(this.disabled){var e=this.$scopedSlots&&this.$scopedSlots.default();return e?e.length<2&&!e[0].text?e:t(this.tag,e):t()}return t()},created:function(){this.getTargetEl()||this.insertTargetEl()},updated:function(){var t=this;this.$nextTick((function(){t.disabled||t.slotFn===t.$scopedSlots.default||(t.container.updatedNodes=t.$scopedSlots.default),t.slotFn=t.$scopedSlots.default}))},beforeDestroy:function(){this.unmount()},watch:{disabled:{immediate:!0,handler:function(t){t?this.unmount():this.$nextTick(this.mount)}}},methods:{getTargetEl:function(){if(Ml)return document.querySelector(this.selector)},insertTargetEl:function(){if(Ml){var t=document.querySelector("body"),e=document.createElement(this.tag);e.id=this.selector.substring(1),t.appendChild(e)}},mount:function(){if(Ml){var t=this.getTargetEl(),e=document.createElement("DIV");this.prepend&&t.firstChild?t.insertBefore(e,t.firstChild):t.appendChild(e),this.container=new Cl({el:e,parent:this,propsData:{tag:this.tag,nodes:this.$scopedSlots.default}})}},unmount:function(){this.container&&(this.container.$destroy(),delete this.container)}}});function Tl(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};t.component(e.name||"portal",$l),e.defaultSelector&&_l(e.defaultSelector)}"undefined"!=typeof window&&window.Vue&&window.Vue===Wn&&Wn.use(Tl);var Dl={},Nl={};function Al(t){return null==t}function El(t){return null!=t}function Pl(t,e){return e.tag===t.tag&&e.key===t.key}function Il(t){var e=t.tag;t.vm=new e({data:t.args})}function Rl(t,e,n){var r,i,o={};for(r=e;r<=n;++r)El(i=t[r].key)&&(o[i]=r);return o}function zl(t,e,n){for(;e<=n;++e)Il(t[e])}function jl(t,e,n){for(;e<=n;++e){var r=t[e];El(r)&&(r.vm.$destroy(),r.vm=null)}}function Fl(t,e){t!==e&&(e.vm=t.vm,function(t){for(var e=Object.keys(t.args),n=0;na?zl(e,s,u):s>u&&jl(t,o,a)}(t,e):El(e)?zl(e,0,e.length-1):El(t)&&jl(t,0,t.length-1)};var Ll={};function Bl(t,e){var n=Object.keys(t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(t);e&&(r=r.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),n.push.apply(n,r)}return n}function Vl(t){for(var e=1;et.length)&&(e=t.length);for(var n=0,r=new Array(e);n1?a:a.$sub[0]:null}}},computed:{run:function(){var t=this,e=this.lazyParentModel();if(Array.isArray(e)&&e.__ob__){var n=e.__ob__.dep;n.depend();var r=n.constructor.target;if(!this._indirectWatcher){var i=r.constructor;this._indirectWatcher=new i(this,(function(){return t.runRule(e)}),null,{lazy:!0})}var o=this.getModel();if(!this._indirectWatcher.dirty&&this._lastModel===o)return this._indirectWatcher.depend(),r.value;this._lastModel=o,this._indirectWatcher.evaluate(),this._indirectWatcher.depend()}else this._indirectWatcher&&(this._indirectWatcher.teardown(),this._indirectWatcher=null);return this._indirectWatcher?this._indirectWatcher.value:this.runRule(e)},$params:function(){return this.run.params},proxy:function(){var t=this.run.output;return t.__isVuelidateAsyncVm?!!t.v:!!t},$pending:function(){var t=this.run.output;return!!t.__isVuelidateAsyncVm&&t.p}},destroyed:function(){this._indirectWatcher&&(this._indirectWatcher.teardown(),this._indirectWatcher=null)}}),a=i.extend({data:function(){return{dirty:!1,validations:null,lazyModel:null,model:null,prop:null,lazyParentModel:null,rootModel:null}},methods:s(s({},g),{},{refProxy:function(t){return this.getRef(t).proxy},getRef:function(t){return this.refs[t]},isNested:function(t){return"function"!=typeof this.validations[t]}}),computed:s(s({},p),{},{nestedKeys:function(){return this.keys.filter(this.isNested)},ruleKeys:function(){var t=this;return this.keys.filter((function(e){return!t.isNested(e)}))},keys:function(){return Object.keys(this.validations).filter((function(t){return"$params"!==t}))},proxy:function(){var t=this,e=u(this.keys,(function(e){return{enumerable:!0,configurable:!0,get:function(){return t.refProxy(e)}}})),n=u(v,(function(e){return{enumerable:!0,configurable:!0,get:function(){return t[e]}}})),r=u(y,(function(e){return{enumerable:!1,configurable:!0,get:function(){return t[e]}}})),i=this.hasIter()?{$iter:{enumerable:!0,value:Object.defineProperties({},s({},e))}}:{};return Object.defineProperties({},s(s(s(s({},e),i),{},{$model:{enumerable:!0,get:function(){var e=t.lazyParentModel();return null!=e?e[t.prop]:null},set:function(e){var n=t.lazyParentModel();null!=n&&(n[t.prop]=e,t.$touch())}}},n),r))},children:function(){var t=this;return[].concat(r(this.nestedKeys.map((function(e){return w(t,e)}))),r(this.ruleKeys.map((function(e){return x(t,e)})))).filter(Boolean)}})}),l=a.extend({methods:{isNested:function(t){return void 0!==this.validations[t]()},getRef:function(t){var e=this;return{get proxy(){return e.validations[t]()||!1}}}}}),m=a.extend({computed:{keys:function(){var t=this.getModel();return f(t)?Object.keys(t):[]},tracker:function(){var t=this,e=this.validations.$trackBy;return e?function(n){return"".concat(h(t.rootModel,t.getModelKey(n),e))}:function(t){return"".concat(t)}},getModelLazy:function(){var t=this;return function(){return t.getModel()}},children:function(){var t=this,n=this.validations,r=this.getModel(),i=s({},n);delete i.$trackBy;var o={};return this.keys.map((function(n){var s=t.tracker(n);return o.hasOwnProperty(s)?null:(o[s]=!0,(0,e.h)(a,s,{validations:i,prop:n,lazyParentModel:t.getModelLazy,model:r[n],rootModel:t.rootModel}))})).filter(Boolean)}},methods:{isNested:function(){return!0},getRef:function(t){return this.refs[this.tracker(t)]},hasIter:function(){return!0}}}),w=function(t,n){if("$each"===n)return(0,e.h)(m,n,{validations:t.validations[n],lazyParentModel:t.lazyParentModel,prop:n,lazyModel:t.getModel,rootModel:t.rootModel});var r=t.validations[n];if(Array.isArray(r)){var i=t.rootModel,o=u(r,(function(t){return function(){return h(i,i.$v,t)}}),(function(t){return Array.isArray(t)?t.join("."):t}));return(0,e.h)(l,n,{validations:o,lazyParentModel:c,prop:n,lazyModel:c,rootModel:i})}return(0,e.h)(a,n,{validations:r,lazyParentModel:t.getModel,prop:n,lazyModel:t.getModelKey,rootModel:t.rootModel})},x=function(t,n){return(0,e.h)(o,n,{rule:t.validations[n],lazyParentModel:t.lazyParentModel,lazyModel:t.getModel,rootModel:t.rootModel})};return b={VBase:i,Validation:a}},x=null;var S=function(t,n){var r=function(t){if(x)return x;for(var e=t.constructor;e.super;)e=e.super;return x=e,e}(t),i=w(r),o=i.Validation;return new(0,i.VBase)({computed:{children:function(){var r="function"==typeof n?n.call(t):n;return[(0,e.h)(o,"$v",{validations:r,lazyParentModel:c,prop:"$v",model:t,rootModel:t})]}}})},k={data:function(){var t=this.$options.validations;return t&&(this._vuelidate=S(this,t)),{}},beforeCreate:function(){var t=this.$options;t.validations&&(t.computed||(t.computed={}),t.computed.$v||(t.computed.$v=function(){return this._vuelidate?this._vuelidate.refs.$v.proxy:null}))},beforeDestroy:function(){this._vuelidate&&(this._vuelidate.$destroy(),this._vuelidate=null)}};function O(t){t.mixin(k)}t.validationMixin=k;var _=O;t.default=_}(Dl);const Zl=yl(Dl);function Xl(t){this.content=t}function Ql(t,e,n){for(let r=0;;r++){if(r==t.childCount||r==e.childCount)return t.childCount==e.childCount?null:n;let i=t.child(r),o=e.child(r);if(i!=o){if(!i.sameMarkup(o))return n;if(i.isText&&i.text!=o.text){for(let t=0;i.text[t]==o.text[t];t++)n++;return n}if(i.content.size||o.content.size){let t=Ql(i.content,o.content,n+1);if(null!=t)return t}n+=i.nodeSize}else n+=i.nodeSize}}function tc(t,e,n,r){for(let i=t.childCount,o=e.childCount;;){if(0==i||0==o)return i==o?null:{a:n,b:r};let s=t.child(--i),a=e.child(--o),l=s.nodeSize;if(s!=a){if(!s.sameMarkup(a))return{a:n,b:r};if(s.isText&&s.text!=a.text){let t=0,e=Math.min(s.text.length,a.text.length);for(;t>1}},Xl.from=function(t){if(t instanceof Xl)return t;var e=[];if(t)for(var n in t)e.push(n,t[n]);return new Xl(e)};class ec{constructor(t,e){if(this.content=t,this.size=e||0,null==e)for(let n=0;nt&&!1!==n(a,r+s,i||null,o)&&a.content.size){let i=s+1;a.nodesBetween(Math.max(0,t-i),Math.min(a.content.size,e-i),n,r+i)}s=l}}descendants(t){this.nodesBetween(0,this.size,t)}textBetween(t,e,n,r){let i="",o=!0;return this.nodesBetween(t,e,((s,a)=>{s.isText?(i+=s.text.slice(Math.max(t,a)-a,e-a),o=!n):s.isLeaf?(r?i+="function"==typeof r?r(s):r:s.type.spec.leafText&&(i+=s.type.spec.leafText(s)),o=!n):!o&&s.isBlock&&(i+=n,o=!0)}),0),i}append(t){if(!t.size)return this;if(!this.size)return t;let e=this.lastChild,n=t.firstChild,r=this.content.slice(),i=0;for(e.isText&&e.sameMarkup(n)&&(r[r.length-1]=e.withText(e.text+n.text),i=1);it)for(let i=0,o=0;ot&&((oe)&&(s=s.isText?s.cut(Math.max(0,t-o),Math.min(s.text.length,e-o)):s.cut(Math.max(0,t-o-1),Math.min(s.content.size,e-o-1))),n.push(s),r+=s.nodeSize),o=a}return new ec(n,r)}cutByIndex(t,e){return t==e?ec.empty:0==t&&e==this.content.length?this:new ec(this.content.slice(t,e))}replaceChild(t,e){let n=this.content[t];if(n==e)return this;let r=this.content.slice(),i=this.size+e.nodeSize-n.nodeSize;return r[t]=e,new ec(r,i)}addToStart(t){return new ec([t].concat(this.content),this.size+t.nodeSize)}addToEnd(t){return new ec(this.content.concat(t),this.size+t.nodeSize)}eq(t){if(this.content.length!=t.content.length)return!1;for(let e=0;ethis.size||t<0)throw new RangeError(`Position ${t} outside of fragment (${this})`);for(let n=0,r=0;;n++){let i=r+this.child(n).nodeSize;if(i>=t)return i==t||e>0?rc(n+1,i):rc(n,r);r=i}}toString(){return"<"+this.toStringInner()+">"}toStringInner(){return this.content.join(", ")}toJSON(){return this.content.length?this.content.map((t=>t.toJSON())):null}static fromJSON(t,e){if(!e)return ec.empty;if(!Array.isArray(e))throw new RangeError("Invalid input for Fragment.fromJSON");return new ec(e.map(t.nodeFromJSON))}static fromArray(t){if(!t.length)return ec.empty;let e,n=0;for(let r=0;rthis.type.rank&&(e||(e=t.slice(0,r)),e.push(this),n=!0),e&&e.push(i)}}return e||(e=t.slice()),n||e.push(this),e}removeFromSet(t){for(let e=0;et.type.rank-e.type.rank)),e}}oc.none=[];class sc extends Error{}class ac{constructor(t,e,n){this.content=t,this.openStart=e,this.openEnd=n}get size(){return this.content.size-this.openStart-this.openEnd}insertAt(t,e){let n=cc(this.content,t+this.openStart,e);return n&&new ac(n,this.openStart,this.openEnd)}removeBetween(t,e){return new ac(lc(this.content,t+this.openStart,e+this.openStart),this.openStart,this.openEnd)}eq(t){return this.content.eq(t.content)&&this.openStart==t.openStart&&this.openEnd==t.openEnd}toString(){return this.content+"("+this.openStart+","+this.openEnd+")"}toJSON(){if(!this.content.size)return null;let t={content:this.content.toJSON()};return this.openStart>0&&(t.openStart=this.openStart),this.openEnd>0&&(t.openEnd=this.openEnd),t}static fromJSON(t,e){if(!e)return ac.empty;let n=e.openStart||0,r=e.openEnd||0;if("number"!=typeof n||"number"!=typeof r)throw new RangeError("Invalid input for Slice.fromJSON");return new ac(ec.fromJSON(t,e.content),n,r)}static maxOpen(t,e=!0){let n=0,r=0;for(let i=t.firstChild;i&&!i.isLeaf&&(e||!i.type.spec.isolating);i=i.firstChild)n++;for(let i=t.lastChild;i&&!i.isLeaf&&(e||!i.type.spec.isolating);i=i.lastChild)r++;return new ac(t,n,r)}}function lc(t,e,n){let{index:r,offset:i}=t.findIndex(e),o=t.maybeChild(r),{index:s,offset:a}=t.findIndex(n);if(i==e||o.isText){if(a!=n&&!t.child(s).isText)throw new RangeError("Removing non-flat range");return t.cut(0,e).append(t.cut(n))}if(r!=s)throw new RangeError("Removing non-flat range");return t.replaceChild(r,o.copy(lc(o.content,e-i-1,n-i-1)))}function cc(t,e,n,r){let{index:i,offset:o}=t.findIndex(e),s=t.maybeChild(i);if(o==e||s.isText)return r&&!r.canReplace(i,i,n)?null:t.cut(0,e).append(n).append(t.cut(e));let a=cc(s.content,e-o-1,n);return a&&t.replaceChild(i,s.copy(a))}function uc(t,e,n){if(n.openStart>t.depth)throw new sc("Inserted content deeper than insertion position");if(t.depth-n.openStart!=e.depth-n.openEnd)throw new sc("Inconsistent open depths");return dc(t,e,n,0)}function dc(t,e,n,r){let i=t.index(r),o=t.node(r);if(i==e.index(r)&&r=0;i--)r=e.node(i).copy(ec.from(r));return{start:r.resolveNoCache(t.openStart+n),end:r.resolveNoCache(r.content.size-t.openEnd-n)}}(n,t);return gc(o,vc(t,i,s,e,r))}{let r=t.parent,i=r.content;return gc(r,i.cut(0,t.parentOffset).append(n.content).append(i.cut(e.parentOffset)))}}return gc(o,yc(t,e,r))}function fc(t,e){if(!e.type.compatibleContent(t.type))throw new sc("Cannot join "+e.type.name+" onto "+t.type.name)}function hc(t,e,n){let r=t.node(n);return fc(r,e.node(n)),r}function pc(t,e){let n=e.length-1;n>=0&&t.isText&&t.sameMarkup(e[n])?e[n]=t.withText(e[n].text+t.text):e.push(t)}function mc(t,e,n,r){let i=(e||t).node(n),o=0,s=e?e.index(n):i.childCount;t&&(o=t.index(n),t.depth>n?o++:t.textOffset&&(pc(t.nodeAfter,r),o++));for(let a=o;ai&&hc(t,e,i+1),s=r.depth>i&&hc(n,r,i+1),a=[];return mc(null,t,i,a),o&&s&&e.index(i)==n.index(i)?(fc(o,s),pc(gc(o,vc(t,e,n,r,i+1)),a)):(o&&pc(gc(o,yc(t,e,i+1)),a),mc(e,n,i,a),s&&pc(gc(s,yc(n,r,i+1)),a)),mc(r,null,i,a),new ec(a)}function yc(t,e,n){let r=[];if(mc(null,t,n,r),t.depth>n){pc(gc(hc(t,e,n+1),yc(t,e,n+1)),r)}return mc(e,null,n,r),new ec(r)}ac.empty=new ac(ec.empty,0,0);class bc{constructor(t,e,n){this.pos=t,this.path=e,this.parentOffset=n,this.depth=e.length/3-1}resolveDepth(t){return null==t?this.depth:t<0?this.depth+t:t}get parent(){return this.node(this.depth)}get doc(){return this.node(0)}node(t){return this.path[3*this.resolveDepth(t)]}index(t){return this.path[3*this.resolveDepth(t)+1]}indexAfter(t){return t=this.resolveDepth(t),this.index(t)+(t!=this.depth||this.textOffset?1:0)}start(t){return 0==(t=this.resolveDepth(t))?0:this.path[3*t-1]+1}end(t){return t=this.resolveDepth(t),this.start(t)+this.node(t).content.size}before(t){if(!(t=this.resolveDepth(t)))throw new RangeError("There is no position before the top-level node");return t==this.depth+1?this.pos:this.path[3*t-1]}after(t){if(!(t=this.resolveDepth(t)))throw new RangeError("There is no position after the top-level node");return t==this.depth+1?this.pos:this.path[3*t-1]+this.path[3*t].nodeSize}get textOffset(){return this.pos-this.path[this.path.length-1]}get nodeAfter(){let t=this.parent,e=this.index(this.depth);if(e==t.childCount)return null;let n=this.pos-this.path[this.path.length-1],r=t.child(e);return n?t.child(e).cut(n):r}get nodeBefore(){let t=this.index(this.depth),e=this.pos-this.path[this.path.length-1];return e?this.parent.child(t).cut(0,e):0==t?null:this.parent.child(t-1)}posAtIndex(t,e){e=this.resolveDepth(e);let n=this.path[3*e],r=0==e?0:this.path[3*e-1]+1;for(let i=0;i0;e--)if(this.start(e)<=t&&this.end(e)>=t)return e;return 0}blockRange(t=this,e){if(t.pos=0;n--)if(t.pos<=this.end(n)&&(!e||e(this.node(n))))return new kc(this,t,n);return null}sameParent(t){return this.pos-this.parentOffset==t.pos-t.parentOffset}max(t){return t.pos>this.pos?t:this}min(t){return t.pos=0&&e<=t.content.size))throw new RangeError("Position "+e+" out of range");let n=[],r=0,i=e;for(let o=t;;){let{index:t,offset:e}=o.content.findIndex(i),s=i-e;if(n.push(o,t,r+e),!s)break;if(o=o.child(t),o.isText)break;i=s-1,r+=e+1}return new bc(e,n,i)}static resolveCached(t,e){for(let r=0;rt&&this.nodesBetween(t,e,(t=>(n.isInSet(t.marks)&&(r=!0),!r))),r}get isBlock(){return this.type.isBlock}get isTextblock(){return this.type.isTextblock}get inlineContent(){return this.type.inlineContent}get isInline(){return this.type.isInline}get isText(){return this.type.isText}get isLeaf(){return this.type.isLeaf}get isAtom(){return this.type.isAtom}toString(){if(this.type.spec.toDebugString)return this.type.spec.toDebugString(this);let t=this.type.name;return this.content.size&&(t+="("+this.content.toStringInner()+")"),Cc(this.marks,t)}contentMatchAt(t){let e=this.type.contentMatch.matchFragment(this.content,0,t);if(!e)throw new Error("Called contentMatchAt on a node with invalid content");return e}canReplace(t,e,n=ec.empty,r=0,i=n.childCount){let o=this.contentMatchAt(t).matchFragment(n,r,i),s=o&&o.matchFragment(this.content,e);if(!s||!s.validEnd)return!1;for(let a=r;at.type.name))}`);this.content.forEach((t=>t.check()))}toJSON(){let t={type:this.type.name};for(let e in this.attrs){t.attrs=this.attrs;break}return this.content.size&&(t.content=this.content.toJSON()),this.marks.length&&(t.marks=this.marks.map((t=>t.toJSON()))),t}static fromJSON(t,e){if(!e)throw new RangeError("Invalid input for Node.fromJSON");let n=null;if(e.marks){if(!Array.isArray(e.marks))throw new RangeError("Invalid mark data for Node.fromJSON");n=e.marks.map(t.markFromJSON)}if("text"==e.type){if("string"!=typeof e.text)throw new RangeError("Invalid text node in JSON");return t.text(e.text,n)}let r=ec.fromJSON(t,e.content);return t.nodeType(e.type).create(e.attrs,r,n)}}_c.prototype.text=void 0;class Mc extends _c{constructor(t,e,n,r){if(super(t,e,null,r),!n)throw new RangeError("Empty text nodes are not allowed");this.text=n}toString(){return this.type.spec.toDebugString?this.type.spec.toDebugString(this):Cc(this.marks,JSON.stringify(this.text))}get textContent(){return this.text}textBetween(t,e){return this.text.slice(t,e)}get nodeSize(){return this.text.length}mark(t){return t==this.marks?this:new Mc(this.type,this.attrs,this.text,t)}withText(t){return t==this.text?this:new Mc(this.type,this.attrs,t,this.marks)}cut(t=0,e=this.text.length){return 0==t&&e==this.text.length?this:this.withText(this.text.slice(t,e))}eq(t){return this.sameMarkup(t)&&this.text==t.text}toJSON(){let t=super.toJSON();return t.text=this.text,t}}function Cc(t,e){for(let n=t.length-1;n>=0;n--)e=t[n].type.name+"("+e+")";return e}class $c{constructor(t){this.validEnd=t,this.next=[],this.wrapCache=[]}static parse(t,e){let n=new Tc(t,e);if(null==n.next)return $c.empty;let r=Dc(n);n.next&&n.err("Unexpected trailing text");let i=function(t){let e=Object.create(null);return n(Rc(t,0));function n(r){let i=[];r.forEach((e=>{t[e].forEach((({term:e,to:n})=>{if(!e)return;let r;for(let t=0;t{r||i.push([e,r=[]]),-1==r.indexOf(t)&&r.push(t)}))}))}));let o=e[r.join(",")]=new $c(r.indexOf(t.length-1)>-1);for(let t=0;tt.to=e))}function o(t,e){if("choice"==t.type)return t.exprs.reduce(((t,n)=>t.concat(o(n,e))),[]);if("seq"!=t.type){if("star"==t.type){let s=n();return r(e,s),i(o(t.expr,s),s),[r(s)]}if("plus"==t.type){let s=n();return i(o(t.expr,e),s),i(o(t.expr,s),s),[r(s)]}if("opt"==t.type)return[r(e)].concat(o(t.expr,e));if("range"==t.type){let s=e;for(let e=0;et.createAndFill())));for(let t=0;t=this.next.length)throw new RangeError(`There's no ${t}th edge in this content match`);return this.next[t]}toString(){let t=[];return function e(n){t.push(n);for(let r=0;r{let r=n+(e.validEnd?"*":" ")+" ";for(let i=0;i"+t.indexOf(e.next[i].next);return r})).join("\n")}}$c.empty=new $c(!0);class Tc{constructor(t,e){this.string=t,this.nodeTypes=e,this.inline=null,this.pos=0,this.tokens=t.split(/\s*(?=\b|\W|$)/),""==this.tokens[this.tokens.length-1]&&this.tokens.pop(),""==this.tokens[0]&&this.tokens.shift()}get next(){return this.tokens[this.pos]}eat(t){return this.next==t&&(this.pos++||!0)}err(t){throw new SyntaxError(t+" (in content expression '"+this.string+"')")}}function Dc(t){let e=[];do{e.push(Nc(t))}while(t.eat("|"));return 1==e.length?e[0]:{type:"choice",exprs:e}}function Nc(t){let e=[];do{e.push(Ac(t))}while(t.next&&")"!=t.next&&"|"!=t.next);return 1==e.length?e[0]:{type:"seq",exprs:e}}function Ac(t){let e=function(t){if(t.eat("(")){let e=Dc(t);return t.eat(")")||t.err("Missing closing paren"),e}if(!/\W/.test(t.next)){let e=function(t,e){let n=t.nodeTypes,r=n[e];if(r)return[r];let i=[];for(let o in n){let t=n[o];t.groups.indexOf(e)>-1&&i.push(t)}0==i.length&&t.err("No node type or group '"+e+"' found");return i}(t,t.next).map((e=>(null==t.inline?t.inline=e.isInline:t.inline!=e.isInline&&t.err("Mixing inline and block content"),{type:"name",value:e})));return t.pos++,1==e.length?e[0]:{type:"choice",exprs:e}}t.err("Unexpected token '"+t.next+"'")}(t);for(;;)if(t.eat("+"))e={type:"plus",expr:e};else if(t.eat("*"))e={type:"star",expr:e};else if(t.eat("?"))e={type:"opt",expr:e};else{if(!t.eat("{"))break;e=Pc(t,e)}return e}function Ec(t){/\D/.test(t.next)&&t.err("Expected number, got '"+t.next+"'");let e=Number(t.next);return t.pos++,e}function Pc(t,e){let n=Ec(t),r=n;return t.eat(",")&&(r="}"!=t.next?Ec(t):-1),t.eat("}")||t.err("Unclosed braced range"),{type:"range",min:n,max:r,expr:e}}function Ic(t,e){return e-t}function Rc(t,e){let n=[];return function e(r){let i=t[r];if(1==i.length&&!i[0].term)return e(i[0].to);n.push(r);for(let t=0;t-1}allowsMarks(t){if(null==this.markSet)return!0;for(let e=0;en[t]=new Lc(t,e,r)));let r=e.spec.topNode||"doc";if(!n[r])throw new RangeError("Schema is missing its top node type ('"+r+"')");if(!n.text)throw new RangeError("Every schema needs a 'text' type");for(let i in n.text.attrs)throw new RangeError("The text node type should not have attributes");return n}}class Bc{constructor(t){this.hasDefault=Object.prototype.hasOwnProperty.call(t,"default"),this.default=t.default}get isRequired(){return!this.hasDefault}}class Vc{constructor(t,e,n,r){this.name=t,this.rank=e,this.schema=n,this.spec=r,this.attrs=Fc(r.attrs),this.excluded=null;let i=zc(this.attrs);this.instance=i?new oc(this,i):null}create(t=null){return!t&&this.instance?this.instance:new oc(this,jc(this.attrs,t))}static compile(t,e){let n=Object.create(null),r=0;return t.forEach(((t,i)=>n[t]=new Vc(t,r++,e,i))),n}removeFromSet(t){for(var e=0;e-1}}class Wc{constructor(t){this.cached=Object.create(null),this.spec={nodes:Xl.from(t.nodes),marks:Xl.from(t.marks||{}),topNode:t.topNode},this.nodes=Lc.compile(this.spec.nodes,this),this.marks=Vc.compile(this.spec.marks,this);let e=Object.create(null);for(let n in this.nodes){if(n in this.marks)throw new RangeError(n+" can not be both a node and a mark");let t=this.nodes[n],r=t.spec.content||"",i=t.spec.marks;t.contentMatch=e[r]||(e[r]=$c.parse(r,this.nodes)),t.inlineContent=t.contentMatch.inlineContent,t.markSet="_"==i?null:i?qc(this,i.split(" ")):""!=i&&t.inlineContent?null:[]}for(let n in this.marks){let t=this.marks[n],e=t.spec.excludes;t.excluded=null==e?[t]:""==e?[]:qc(this,e.split(" "))}this.nodeFromJSON=this.nodeFromJSON.bind(this),this.markFromJSON=this.markFromJSON.bind(this),this.topNodeType=this.nodes[this.spec.topNode||"doc"],this.cached.wrappings=Object.create(null)}node(t,e=null,n,r){if("string"==typeof t)t=this.nodeType(t);else{if(!(t instanceof Lc))throw new RangeError("Invalid node type: "+t);if(t.schema!=this)throw new RangeError("Node type from different schema used ("+t.name+")")}return t.createChecked(e,n,r)}text(t,e){let n=this.nodes.text;return new Mc(n,n.defaultAttrs,t,oc.setFrom(e))}mark(t,e){return"string"==typeof t&&(t=this.marks[t]),t.create(e)}nodeFromJSON(t){return _c.fromJSON(this,t)}markFromJSON(t){return oc.fromJSON(this,t)}nodeType(t){let e=this.nodes[t];if(!e)throw new RangeError("Unknown node type: "+t);return e}}function qc(t,e){let n=[];for(let r=0;r-1)&&n.push(s=r)}if(!s)throw new SyntaxError("Unknown mark type: '"+e[r]+"'")}return n}class Jc{constructor(t,e){this.schema=t,this.rules=e,this.tags=[],this.styles=[],e.forEach((t=>{t.tag?this.tags.push(t):t.style&&this.styles.push(t)})),this.normalizeLists=!this.tags.some((e=>{if(!/^(ul|ol)\b/.test(e.tag)||!e.node)return!1;let n=t.nodes[e.node];return n.contentMatch.matchType(n)}))}parse(t,e={}){let n=new Zc(this,e,!1);return n.addAll(t,e.from,e.to),n.finish()}parseSlice(t,e={}){let n=new Zc(this,e,!0);return n.addAll(t,e.from,e.to),ac.maxOpen(n.finish())}matchTag(t,e,n){for(let r=n?this.tags.indexOf(n)+1:0;rt.length&&(61!=o.charCodeAt(t.length)||o.slice(t.length+1)!=e))){if(r.getAttrs){let t=r.getAttrs(e);if(!1===t)continue;r.attrs=t||void 0}return r}}}static schemaRules(t){let e=[];function n(t){let n=null==t.priority?50:t.priority,r=0;for(;r{n(t=Qc(t)),t.mark=r}))}for(let r in t.nodes){let e=t.nodes[r].spec.parseDOM;e&&e.forEach((t=>{n(t=Qc(t)),t.node=r}))}return e}static fromSchema(t){return t.cached.domParser||(t.cached.domParser=new Jc(t,Jc.schemaRules(t)))}}const Kc={address:!0,article:!0,aside:!0,blockquote:!0,canvas:!0,dd:!0,div:!0,dl:!0,fieldset:!0,figcaption:!0,figure:!0,footer:!0,form:!0,h1:!0,h2:!0,h3:!0,h4:!0,h5:!0,h6:!0,header:!0,hgroup:!0,hr:!0,li:!0,noscript:!0,ol:!0,output:!0,p:!0,pre:!0,section:!0,table:!0,tfoot:!0,ul:!0},Hc={head:!0,noscript:!0,object:!0,script:!0,style:!0,title:!0},Uc={ol:!0,ul:!0};function Yc(t,e,n){return null!=e?(e?1:0)|("full"===e?2:0):t&&"pre"==t.whitespace?3:-5&n}class Gc{constructor(t,e,n,r,i,o,s){this.type=t,this.attrs=e,this.marks=n,this.pendingMarks=r,this.solid=i,this.options=s,this.content=[],this.activeMarks=oc.none,this.stashMarks=[],this.match=o||(4&s?null:t.contentMatch)}findWrapping(t){if(!this.match){if(!this.type)return[];let e=this.type.contentMatch.fillBefore(ec.from(t));if(!e){let e,n=this.type.contentMatch;return(e=n.findWrapping(t.type))?(this.match=n,e):null}this.match=this.type.contentMatch.matchFragment(e)}return this.match.findWrapping(t.type)}finish(t){if(!(1&this.options)){let t,e=this.content[this.content.length-1];if(e&&e.isText&&(t=/[ \t\r\n\u000c]+$/.exec(e.text))){let n=e;e.text.length==t[0].length?this.content.pop():this.content[this.content.length-1]=n.withText(n.text.slice(0,n.text.length-t[0].length))}}let e=ec.from(this.content);return!t&&this.match&&(e=e.append(this.match.fillBefore(ec.empty,!0))),this.type?this.type.create(this.attrs,e,this.marks):e}popFromStashMark(t){for(let e=this.stashMarks.length-1;e>=0;e--)if(t.eq(this.stashMarks[e]))return this.stashMarks.splice(e,1)[0]}applyPending(t){for(let e=0,n=this.pendingMarks;ethis.insertNode(t)));else{let n=t;"string"==typeof e.contentElement?n=t.querySelector(e.contentElement):"function"==typeof e.contentElement?n=e.contentElement(t):e.contentElement&&(n=e.contentElement),this.findAround(t,n,!0),this.addAll(n)}r&&this.sync(s)&&this.open--,o&&this.removePendingMark(o,s)}addAll(t,e,n){let r=e||0;for(let i=e?t.childNodes[e]:t.firstChild,o=null==n?null:t.childNodes[n];i!=o;i=i.nextSibling,++r)this.findAtPoint(t,r),this.addDOM(i);this.findAtPoint(t,r)}findPlace(t){let e,n;for(let r=this.open;r>=0;r--){let i=this.nodes[r],o=i.findWrapping(t);if(o&&(!e||e.length>o.length)&&(e=o,n=i,!o.length))break;if(i.solid)break}if(!e)return!1;this.sync(n);for(let r=0;rthis.open){for(;e>this.open;e--)this.nodes[e-1].content.push(this.nodes[e].finish(t));this.nodes.length=this.open+1}}finish(){return this.open=0,this.closeExtra(this.isOpen),this.nodes[0].finish(this.isOpen||this.options.topOpen)}sync(t){for(let e=this.open;e>=0;e--)if(this.nodes[e]==t)return this.open=e,!0;return!1}get currentPos(){this.closeExtra();let t=0;for(let e=this.open;e>=0;e--){let n=this.nodes[e].content;for(let e=n.length-1;e>=0;e--)t+=n[e].nodeSize;e&&t++}return t}findAtPoint(t,e){if(this.find)for(let n=0;n-1)return t.split(/\s*\|\s*/).some(this.matchesContext,this);let e=t.split("/"),n=this.options.context,r=!(this.isOpen||n&&n.parent.type!=this.nodes[0].type),i=-(n?n.depth+1:0)+(r?0:1),o=(t,s)=>{for(;t>=0;t--){let a=e[t];if(""==a){if(t==e.length-1||0==t)continue;for(;s>=i;s--)if(o(t-1,s))return!0;return!1}{let t=s>0||0==s&&r?this.nodes[s].type:n&&s>=i?n.node(s-i).type:null;if(!t||t.name!=a&&-1==t.groups.indexOf(a))return!1;s--}}return!0};return o(e.length-1,this.open)}textblockFromContext(){let t=this.options.context;if(t)for(let e=t.depth;e>=0;e--){let n=t.node(e).contentMatchAt(t.indexAfter(e)).defaultType;if(n&&n.isTextblock&&n.defaultAttrs)return n}for(let e in this.parser.schema.nodes){let t=this.parser.schema.nodes[e];if(t.isTextblock&&t.defaultAttrs)return t}}addPendingMark(t){let e=function(t,e){for(let n=0;n=0;n--){let r=this.nodes[n];if(r.pendingMarks.lastIndexOf(t)>-1)r.pendingMarks=t.removeFromSet(r.pendingMarks);else{r.activeMarks=t.removeFromSet(r.activeMarks);let e=r.popFromStashMark(t);e&&r.type&&r.type.allowsMarkType(e.type)&&(r.activeMarks=e.addToSet(r.activeMarks))}if(r==e)break}}}function Xc(t,e){return(t.matches||t.msMatchesSelector||t.webkitMatchesSelector||t.mozMatchesSelector).call(t,e)}function Qc(t){let e={};for(let n in t)e[n]=t[n];return e}function tu(t,e){let n=e.schema.nodes;for(let r in n){let i=n[r];if(!i.allowsMarkType(t))continue;let o=[],s=t=>{o.push(t);for(let n=0;n{if(i.length||t.marks.length){let n=0,o=0;for(;n=0;r--){let i=this.serializeMark(t.marks[r],t.isInline,e);i&&((i.contentDOM||i.dom).appendChild(n),n=i.dom)}return n}serializeMark(t,e,n={}){let r=this.marks[t.type.name];return r&&eu.renderSpec(ru(n),r(t,e))}static renderSpec(t,e,n=null){if("string"==typeof e)return{dom:t.createTextNode(e)};if(null!=e.nodeType)return{dom:e};if(e.dom&&null!=e.dom.nodeType)return e;let r,i=e[0],o=i.indexOf(" ");o>0&&(n=i.slice(0,o),i=i.slice(o+1));let s=n?t.createElementNS(n,i):t.createElement(i),a=e[1],l=1;if(a&&"object"==typeof a&&null==a.nodeType&&!Array.isArray(a)){l=2;for(let t in a)if(null!=a[t]){let e=t.indexOf(" ");e>0?s.setAttributeNS(t.slice(0,e),t.slice(e+1),a[t]):s.setAttribute(t,a[t])}}for(let c=l;cl)throw new RangeError("Content hole must be the only child of its parent node");return{dom:s,contentDOM:s}}{let{dom:e,contentDOM:o}=eu.renderSpec(t,i,n);if(s.appendChild(e),o){if(r)throw new RangeError("Multiple content holes");r=o}}}return{dom:s,contentDOM:r}}static fromSchema(t){return t.cached.domSerializer||(t.cached.domSerializer=new eu(this.nodesFromSchema(t),this.marksFromSchema(t)))}static nodesFromSchema(t){let e=nu(t.nodes);return e.text||(e.text=t=>t.text),e}static marksFromSchema(t){return nu(t.marks)}}function nu(t){let e={};for(let n in t){let r=t[n].spec.toDOM;r&&(e[n]=r)}return e}function ru(t){return t.document||window.document}const iu=Math.pow(2,16);function ou(t){return 65535&t}class su{constructor(t,e=!1,n=null){this.pos=t,this.deleted=e,this.recover=n}}class au{constructor(t,e=!1){if(this.ranges=t,this.inverted=e,!t.length&&au.empty)return au.empty}recover(t){let e=0,n=ou(t);if(!this.inverted)for(let r=0;rt)break;let l=this.ranges[s+i],c=this.ranges[s+o],u=a+l;if(t<=u){let i=a+r+((l?t==a?-1:t==u?1:e:e)<0?0:c);if(n)return i;let o=t==(e<0?a:u)?null:s/3+(t-a)*iu;return new su(i,e<0?t!=a:t!=u,o)}r+=c-l}return n?t+r:new su(t+r)}touches(t,e){let n=0,r=ou(e),i=this.inverted?2:1,o=this.inverted?1:2;for(let s=0;st)break;let a=this.ranges[s+i];if(t<=e+a&&s==3*r)return!0;n+=this.ranges[s+o]-a}return!1}forEach(t){let e=this.inverted?2:1,n=this.inverted?1:2;for(let r=0,i=0;r=0;e--){let r=t.getMirror(e);this.appendMap(t.maps[e].invert(),null!=r&&r>e?n-r-1:void 0)}}invert(){let t=new lu;return t.appendMappingInverted(this),t}map(t,e=1){if(this.mirror)return this._map(t,e,!0);for(let n=this.from;ni&&et.isAtom&&e.type.allowsMarkType(this.mark.type)?t.mark(this.mark.addToSet(t.marks)):t),r),e.openStart,e.openEnd);return du.fromReplace(t,this.from,this.to,i)}invert(){return new pu(this.from,this.to,this.mark)}map(t){let e=t.mapResult(this.from,1),n=t.mapResult(this.to,-1);return e.deleted&&n.deleted||e.pos>=n.pos?null:new hu(e.pos,n.pos,this.mark)}merge(t){return t instanceof hu&&t.mark.eq(this.mark)&&this.from<=t.to&&this.to>=t.from?new hu(Math.min(this.from,t.from),Math.max(this.to,t.to),this.mark):null}toJSON(){return{stepType:"addMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(t,e){if("number"!=typeof e.from||"number"!=typeof e.to)throw new RangeError("Invalid input for AddMarkStep.fromJSON");return new hu(e.from,e.to,t.markFromJSON(e.mark))}}uu.jsonID("addMark",hu);class pu extends uu{constructor(t,e,n){super(),this.from=t,this.to=e,this.mark=n}apply(t){let e=t.slice(this.from,this.to),n=new ac(fu(e.content,(t=>t.mark(this.mark.removeFromSet(t.marks))),t),e.openStart,e.openEnd);return du.fromReplace(t,this.from,this.to,n)}invert(){return new hu(this.from,this.to,this.mark)}map(t){let e=t.mapResult(this.from,1),n=t.mapResult(this.to,-1);return e.deleted&&n.deleted||e.pos>=n.pos?null:new pu(e.pos,n.pos,this.mark)}merge(t){return t instanceof pu&&t.mark.eq(this.mark)&&this.from<=t.to&&this.to>=t.from?new pu(Math.min(this.from,t.from),Math.max(this.to,t.to),this.mark):null}toJSON(){return{stepType:"removeMark",mark:this.mark.toJSON(),from:this.from,to:this.to}}static fromJSON(t,e){if("number"!=typeof e.from||"number"!=typeof e.to)throw new RangeError("Invalid input for RemoveMarkStep.fromJSON");return new pu(e.from,e.to,t.markFromJSON(e.mark))}}uu.jsonID("removeMark",pu);class mu extends uu{constructor(t,e,n,r=!1){super(),this.from=t,this.to=e,this.slice=n,this.structure=r}apply(t){return this.structure&&vu(t,this.from,this.to)?du.fail("Structure replace would overwrite content"):du.fromReplace(t,this.from,this.to,this.slice)}getMap(){return new au([this.from,this.to-this.from,this.slice.size])}invert(t){return new mu(this.from,this.from+this.slice.size,t.slice(this.from,this.to))}map(t){let e=t.mapResult(this.from,1),n=t.mapResult(this.to,-1);return e.deleted&&n.deleted?null:new mu(e.pos,Math.max(e.pos,n.pos),this.slice)}merge(t){if(!(t instanceof mu)||t.structure||this.structure)return null;if(this.from+this.slice.size!=t.from||this.slice.openEnd||t.slice.openStart){if(t.to!=this.from||this.slice.openStart||t.slice.openEnd)return null;{let e=this.slice.size+t.slice.size==0?ac.empty:new ac(t.slice.content.append(this.slice.content),t.slice.openStart,this.slice.openEnd);return new mu(t.from,this.to,e,this.structure)}}{let e=this.slice.size+t.slice.size==0?ac.empty:new ac(this.slice.content.append(t.slice.content),this.slice.openStart,t.slice.openEnd);return new mu(this.from,this.to+(t.to-t.from),e,this.structure)}}toJSON(){let t={stepType:"replace",from:this.from,to:this.to};return this.slice.size&&(t.slice=this.slice.toJSON()),this.structure&&(t.structure=!0),t}static fromJSON(t,e){if("number"!=typeof e.from||"number"!=typeof e.to)throw new RangeError("Invalid input for ReplaceStep.fromJSON");return new mu(e.from,e.to,ac.fromJSON(t,e.slice),!!e.structure)}}uu.jsonID("replace",mu);class gu extends uu{constructor(t,e,n,r,i,o,s=!1){super(),this.from=t,this.to=e,this.gapFrom=n,this.gapTo=r,this.slice=i,this.insert=o,this.structure=s}apply(t){if(this.structure&&(vu(t,this.from,this.gapFrom)||vu(t,this.gapTo,this.to)))return du.fail("Structure gap-replace would overwrite content");let e=t.slice(this.gapFrom,this.gapTo);if(e.openStart||e.openEnd)return du.fail("Gap is not a flat range");let n=this.slice.insertAt(this.insert,e.content);return n?du.fromReplace(t,this.from,this.to,n):du.fail("Content does not fit in gap")}getMap(){return new au([this.from,this.gapFrom-this.from,this.insert,this.gapTo,this.to-this.gapTo,this.slice.size-this.insert])}invert(t){let e=this.gapTo-this.gapFrom;return new gu(this.from,this.from+this.slice.size+e,this.from+this.insert,this.from+this.insert+e,t.slice(this.from,this.to).removeBetween(this.gapFrom-this.from,this.gapTo-this.from),this.gapFrom-this.from,this.structure)}map(t){let e=t.mapResult(this.from,1),n=t.mapResult(this.to,-1),r=t.map(this.gapFrom,-1),i=t.map(this.gapTo,1);return e.deleted&&n.deleted||rn.pos?null:new gu(e.pos,n.pos,r,i,this.slice,this.insert,this.structure)}toJSON(){let t={stepType:"replaceAround",from:this.from,to:this.to,gapFrom:this.gapFrom,gapTo:this.gapTo,insert:this.insert};return this.slice.size&&(t.slice=this.slice.toJSON()),this.structure&&(t.structure=!0),t}static fromJSON(t,e){if("number"!=typeof e.from||"number"!=typeof e.to||"number"!=typeof e.gapFrom||"number"!=typeof e.gapTo||"number"!=typeof e.insert)throw new RangeError("Invalid input for ReplaceAroundStep.fromJSON");return new gu(e.from,e.to,e.gapFrom,e.gapTo,ac.fromJSON(t,e.slice),e.insert,!!e.structure)}}function vu(t,e,n){let r=t.resolve(e),i=n-e,o=r.depth;for(;i>0&&o>0&&r.indexAfter(o)==r.node(o).childCount;)o--,i--;if(i>0){let t=r.node(o).maybeChild(r.indexAfter(o));for(;i>0;){if(!t||t.isLeaf)return!0;t=t.firstChild,i--}}return!1}function yu(t,e,n){return(0==e||t.canReplace(e,t.childCount))&&(n==t.childCount||t.canReplace(0,n))}function bu(t){let e=t.parent.content.cutByIndex(t.startIndex,t.endIndex);for(let n=t.depth;;--n){let r=t.$from.node(n),i=t.$from.index(n),o=t.$to.indexAfter(n);if(no;c--,u--){let t=i.node(c),e=i.index(c);if(t.type.spec.isolating)return!1;let n=t.content.cutByIndex(e,t.childCount),o=r&&r[u]||t;if(o!=t&&(n=n.replaceChild(0,o.type.create(o.attrs))),!t.canReplace(e+1,t.childCount)||!o.type.validContent(n))return!1}let a=i.indexAfter(o),l=r&&r[0];return i.node(o).canReplaceWith(a,a,l?l.type:i.node(o+1).type)}function ku(t,e){let n=t.resolve(e),r=n.index();return i=n.nodeBefore,o=n.nodeAfter,!(!i||!o||i.isLeaf||!i.canAppend(o))&&n.parent.canReplace(r,r+1);var i,o}function Ou(t,e,n=e,r=ac.empty){if(e==n&&!r.size)return null;let i=t.resolve(e),o=t.resolve(n);return _u(i,o,r)?new mu(e,n,r):new Mu(i,o,r).fit()}function _u(t,e,n){return!n.openStart&&!n.openEnd&&t.start()==e.start()&&t.parent.canReplace(t.index(),e.index(),n.content)}uu.jsonID("replaceAround",gu);class Mu{constructor(t,e,n){this.$from=t,this.$to=e,this.unplaced=n,this.frontier=[],this.placed=ec.empty;for(let r=0;r<=t.depth;r++){let e=t.node(r);this.frontier.push({type:e.type,match:e.contentMatchAt(t.indexAfter(r))})}for(let r=t.depth;r>0;r--)this.placed=ec.from(t.node(r).copy(this.placed))}get depth(){return this.frontier.length-1}fit(){for(;this.unplaced.size;){let t=this.findFittable();t?this.placeNodes(t):this.openMore()||this.dropNode()}let t=this.mustMoveInline(),e=this.placed.size-this.depth-this.$from.depth,n=this.$from,r=this.close(t<0?this.$to:n.doc.resolve(t));if(!r)return null;let i=this.placed,o=n.depth,s=r.depth;for(;o&&s&&1==i.childCount;)i=i.firstChild.content,o--,s--;let a=new ac(i,o,s);return t>-1?new gu(n.pos,t,this.$to.pos,this.$to.end(),a,e):a.size||n.pos!=this.$to.pos?new mu(n.pos,r.pos,a):null}findFittable(){for(let t=1;t<=2;t++)for(let e=this.unplaced.openStart;e>=0;e--){let n,r=null;e?(r=Tu(this.unplaced.content,e-1).firstChild,n=r.content):n=this.unplaced.content;let i=n.firstChild;for(let o=this.depth;o>=0;o--){let n,{type:s,match:a}=this.frontier[o],l=null;if(1==t&&(i?a.matchType(i.type)||(l=a.fillBefore(ec.from(i),!1)):r&&s.compatibleContent(r.type)))return{sliceDepth:e,frontierDepth:o,parent:r,inject:l};if(2==t&&i&&(n=a.findWrapping(i.type)))return{sliceDepth:e,frontierDepth:o,parent:r,wrap:n};if(r&&a.matchType(r.type))break}}}openMore(){let{content:t,openStart:e,openEnd:n}=this.unplaced,r=Tu(t,e);return!(!r.childCount||r.firstChild.isLeaf)&&(this.unplaced=new ac(t,e+1,Math.max(n,r.size+e>=t.size-n?e+1:0)),!0)}dropNode(){let{content:t,openStart:e,openEnd:n}=this.unplaced,r=Tu(t,e);if(r.childCount<=1&&e>0){let i=t.size-e<=e+r.size;this.unplaced=new ac(Cu(t,e-1,1),e-1,i?e-1:n)}else this.unplaced=new ac(Cu(t,e,1),e,n)}placeNodes({sliceDepth:t,frontierDepth:e,parent:n,inject:r,wrap:i}){for(;this.depth>e;)this.closeFrontierNode();if(i)for(let p=0;p1||0==a||t.content.size)&&(u=e,c.push(Du(t.mark(d.allowedMarks(t.marks)),1==l?a:0,l==s.childCount?f:-1)))}let h=l==s.childCount;h||(f=-1),this.placed=$u(this.placed,e,ec.from(c)),this.frontier[e].match=u,h&&f<0&&n&&n.type==this.frontier[this.depth].type&&this.frontier.length>1&&this.closeFrontierNode();for(let p=0,m=s;p1&&r==this.$to.end(--n);)++r;return r}findCloseLevel(t){t:for(let e=Math.min(this.depth,t.depth);e>=0;e--){let{match:n,type:r}=this.frontier[e],i=e=0;n--){let{match:e,type:r}=this.frontier[n],i=Nu(t,n,r,e,!0);if(!i||i.childCount)continue t}return{depth:e,fit:o,move:i?t.doc.resolve(t.after(e+1)):t}}}}close(t){let e=this.findCloseLevel(t);if(!e)return null;for(;this.depth>e.depth;)this.closeFrontierNode();e.fit.childCount&&(this.placed=$u(this.placed,e.depth,e.fit)),t=e.move;for(let n=e.depth+1;n<=t.depth;n++){let e=t.node(n),r=e.type.contentMatch.fillBefore(e.content,!0,t.index(n));this.openFrontierNode(e.type,e.attrs,r)}return t}openFrontierNode(t,e=null,n){let r=this.frontier[this.depth];r.match=r.match.matchType(t),this.placed=$u(this.placed,this.depth,ec.from(t.create(e,n))),this.frontier.push({type:t,match:t.contentMatch})}closeFrontierNode(){let t=this.frontier.pop().match.fillBefore(ec.empty,!0);t.childCount&&(this.placed=$u(this.placed,this.frontier.length,t))}}function Cu(t,e,n){return 0==e?t.cutByIndex(n,t.childCount):t.replaceChild(0,t.firstChild.copy(Cu(t.firstChild.content,e-1,n)))}function $u(t,e,n){return 0==e?t.append(n):t.replaceChild(t.childCount-1,t.lastChild.copy($u(t.lastChild.content,e-1,n)))}function Tu(t,e){for(let n=0;n1&&(r=r.replaceChild(0,Du(r.firstChild,e-1,1==r.childCount?n-1:0))),e>0&&(r=t.type.contentMatch.fillBefore(r).append(r),n<=0&&(r=r.append(t.type.contentMatch.matchFragment(r).fillBefore(ec.empty,!0)))),t.copy(r)}function Nu(t,e,n,r,i){let o=t.node(e),s=i?t.indexAfter(e):t.index(e);if(s==o.childCount&&!n.compatibleContent(o.type))return null;let a=r.fillBefore(o.content,!0,s);return a&&!function(t,e,n){for(let r=n;rr){let e=i.contentMatchAt(0),n=e.fillBefore(t).append(t);t=n.append(e.matchFragment(n).fillBefore(ec.empty,!0))}return t}function Pu(t,e){let n=[];for(let r=Math.min(t.depth,e.depth);r>=0;r--){let i=t.start(r);if(ie.pos+(e.depth-r)||t.node(r).type.spec.isolating||e.node(r).type.spec.isolating)break;(i==e.start(r)||r==t.depth&&r==e.depth&&t.parent.inlineContent&&e.parent.inlineContent&&r&&e.start(r-1)==i-1)&&n.push(r)}return n}let Iu=class extends Error{};Iu=function t(e){let n=Error.call(this,e);return n.__proto__=t.prototype,n},(Iu.prototype=Object.create(Error.prototype)).constructor=Iu,Iu.prototype.name="TransformError";const Ru=Object.create(null);class zu{constructor(t,e,n){this.$anchor=t,this.$head=e,this.ranges=n||[new ju(t.min(e),t.max(e))]}get anchor(){return this.$anchor.pos}get head(){return this.$head.pos}get from(){return this.$from.pos}get to(){return this.$to.pos}get $from(){return this.ranges[0].$from}get $to(){return this.ranges[0].$to}get empty(){let t=this.ranges;for(let e=0;e=0;i--){let r=e<0?Hu(t.node(0),t.node(i),t.before(i+1),t.index(i),e,n):Hu(t.node(0),t.node(i),t.after(i+1),t.index(i)+1,e,n);if(r)return r}return null}static near(t,e=1){return this.findFrom(t,e)||this.findFrom(t,-e)||new Ju(t.node(0))}static atStart(t){return Hu(t,t,0,0,1)||new Ju(t)}static atEnd(t){return Hu(t,t,t.content.size,t.childCount,-1)||new Ju(t)}static fromJSON(t,e){if(!e||!e.type)throw new RangeError("Invalid input for Selection.fromJSON");let n=Ru[e.type];if(!n)throw new RangeError(`No selection type ${e.type} defined`);return n.fromJSON(t,e)}static jsonID(t,e){if(t in Ru)throw new RangeError("Duplicate use of selection JSON ID "+t);return Ru[t]=e,e.prototype.jsonID=t,e}getBookmark(){return Bu.between(this.$anchor,this.$head).getBookmark()}}zu.prototype.visible=!0;class ju{constructor(t,e){this.$from=t,this.$to=e}}let Fu=!1;function Lu(t){Fu||t.parent.inlineContent||(Fu=!0,console.warn("TextSelection endpoint not pointing into a node with inline content ("+t.parent.type.name+")"))}class Bu extends zu{constructor(t,e=t){Lu(t),Lu(e),super(t,e)}get $cursor(){return this.$anchor.pos==this.$head.pos?this.$head:null}map(t,e){let n=t.resolve(e.map(this.head));if(!n.parent.inlineContent)return zu.near(n);let r=t.resolve(e.map(this.anchor));return new Bu(r.parent.inlineContent?r:n,n)}replace(t,e=ac.empty){if(super.replace(t,e),e==ac.empty){let e=this.$from.marksAcross(this.$to);e&&t.ensureMarks(e)}}eq(t){return t instanceof Bu&&t.anchor==this.anchor&&t.head==this.head}getBookmark(){return new Vu(this.anchor,this.head)}toJSON(){return{type:"text",anchor:this.anchor,head:this.head}}static fromJSON(t,e){if("number"!=typeof e.anchor||"number"!=typeof e.head)throw new RangeError("Invalid input for TextSelection.fromJSON");return new Bu(t.resolve(e.anchor),t.resolve(e.head))}static create(t,e,n=e){let r=t.resolve(e);return new this(r,n==e?r:t.resolve(n))}static between(t,e,n){let r=t.pos-e.pos;if(n&&!r||(n=r>=0?1:-1),!e.parent.inlineContent){let t=zu.findFrom(e,n,!0)||zu.findFrom(e,-n,!0);if(!t)return zu.near(e,n);e=t.$head}return t.parent.inlineContent||(0==r||(t=(zu.findFrom(t,-n,!0)||zu.findFrom(t,n,!0)).$anchor).posnew Ju(t)};function Hu(t,e,n,r,i,o=!1){if(e.inlineContent)return Bu.create(t,n);for(let s=r-(i>0?0:1);i>0?s=0;s+=i){let r=e.child(s);if(r.isAtom){if(!o&&Wu.isSelectable(r))return Wu.create(t,n-(i<0?r.nodeSize:0))}else{let e=Hu(t,r,n+i,i<0?r.childCount:0,i,o);if(e)return e}n+=r.nodeSize*i}return null}function Uu(t,e,n){let r=t.steps.length-1;if(r{null==i&&(i=r)})),t.setSelection(zu.near(t.doc.resolve(i),n)))}class Yu extends class{constructor(t){this.doc=t,this.steps=[],this.docs=[],this.mapping=new lu}get before(){return this.docs.length?this.docs[0]:this.doc}step(t){let e=this.maybeStep(t);if(e.failed)throw new Iu(e.failed);return this}maybeStep(t){let e=t.apply(this.doc);return e.failed||this.addStep(t,e.doc),e}get docChanged(){return this.steps.length>0}addStep(t,e){this.docs.push(this.doc),this.steps.push(t),this.mapping.appendMap(t.getMap()),this.doc=e}replace(t,e=t,n=ac.empty){let r=Ou(this.doc,t,e,n);return r&&this.step(r),this}replaceWith(t,e,n){return this.replace(t,e,new ac(ec.from(n),0,0))}delete(t,e){return this.replace(t,e,ac.empty)}insert(t,e){return this.replaceWith(t,t,e)}replaceRange(t,e,n){return function(t,e,n,r){if(!r.size)return t.deleteRange(e,n);let i=t.doc.resolve(e),o=t.doc.resolve(n);if(_u(i,o,r))return t.step(new mu(e,n,r));let s=Pu(i,t.doc.resolve(n));0==s[s.length-1]&&s.pop();let a=-(i.depth+1);s.unshift(a);for(let f=i.depth,h=i.pos-1;f>0;f--,h--){let t=i.node(f).type.spec;if(t.defining||t.definingAsContext||t.isolating)break;s.indexOf(f)>-1?a=f:i.before(f)==h&&s.splice(1,0,-f)}let l=s.indexOf(a),c=[],u=r.openStart;for(let f=r.content,h=0;;h++){let t=f.firstChild;if(c.push(t),h==r.openStart)break;f=t.content}for(let f=u-1;f>=0;f--){let t=c[f].type,e=Au(t);if(e&&i.node(l).type!=t)u=f;else if(e||!t.isTextblock)break}for(let f=r.openStart;f>=0;f--){let e=(f+u+1)%(r.openStart+1),a=c[e];if(a)for(let c=0;c=0&&(t.replace(e,n,r),!(t.steps.length>d));f--){let t=s[f];t<0||(e=i.before(t),n=o.after(t))}}(this,t,e,n),this}replaceRangeWith(t,e,n){return function(t,e,n,r){if(!r.isInline&&e==n&&t.doc.resolve(e).parent.content.size){let i=function(t,e,n){let r=t.resolve(e);if(r.parent.canReplaceWith(r.index(),r.index(),n))return e;if(0==r.parentOffset)for(let i=r.depth-1;i>=0;i--){let t=r.index(i);if(r.node(i).canReplaceWith(t,t,n))return r.before(i+1);if(t>0)return null}if(r.parentOffset==r.parent.content.size)for(let i=r.depth-1;i>=0;i--){let t=r.indexAfter(i);if(r.node(i).canReplaceWith(t,t,n))return r.after(i+1);if(t0&&(n||r.node(e-1).canReplace(r.index(e-1),i.indexAfter(e-1))))return t.delete(r.before(e),i.after(e))}for(let s=1;s<=r.depth&&s<=i.depth;s++)if(e-r.start(s)==r.depth-s&&n>r.end(s)&&i.end(s)-n!=i.depth-s)return t.delete(r.before(s),n);t.delete(e,n)}(this,t,e),this}lift(t,e){return function(t,e,n){let{$from:r,$to:i,depth:o}=e,s=r.before(o+1),a=i.after(o+1),l=s,c=a,u=ec.empty,d=0;for(let p=o,m=!1;p>n;p--)m||r.index(p)>0?(m=!0,u=ec.from(r.node(p).copy(u)),d++):l--;let f=ec.empty,h=0;for(let p=o,m=!1;p>n;p--)m||i.after(p+1)=0;s--){if(r.size){let t=n[s].type.contentMatch.matchFragment(r);if(!t||!t.validEnd)throw new RangeError("Wrapper type given to Transform.wrap does not form valid content of its parent wrapper")}r=ec.from(n[s].type.create(n[s].attrs,r))}let i=e.start,o=e.end;t.step(new gu(i,o,i,o,new ac(r,0,0),n.length,!0))}(this,t,e),this}setBlockType(t,e=t,n,r=null){return function(t,e,n,r,i){if(!r.isTextblock)throw new RangeError("Type given to setBlockType should be a textblock");let o=t.steps.length;t.doc.nodesBetween(e,n,((e,n)=>{if(e.isTextblock&&!e.hasMarkup(r,i)&&function(t,e,n){let r=t.resolve(e),i=r.index();return r.parent.canReplaceWith(i,i+1,n)}(t.doc,t.mapping.slice(o).map(n),r)){t.clearIncompatible(t.mapping.slice(o).map(n,1),r);let s=t.mapping.slice(o),a=s.map(n,1),l=s.map(n+e.nodeSize,1);return t.step(new gu(a,l,a+1,l-1,new ac(ec.from(r.create(i,null,e.marks)),0,0),1,!0)),!1}}))}(this,t,e,n,r),this}setNodeMarkup(t,e,n=null,r=[]){return function(t,e,n,r,i){let o=t.doc.nodeAt(e);if(!o)throw new RangeError("No node at given position");n||(n=o.type);let s=n.create(r,null,i||o.marks);if(o.isLeaf)return t.replaceWith(e,e+o.nodeSize,s);if(!n.validContent(o.content))throw new RangeError("Invalid content for node type "+n.name);t.step(new gu(e,e+o.nodeSize,e+1,e+o.nodeSize-1,new ac(ec.from(s),0,0),1,!0))}(this,t,e,n,r),this}split(t,e=1,n){return function(t,e,n=1,r){let i=t.doc.resolve(e),o=ec.empty,s=ec.empty;for(let a=i.depth,l=i.depth-n,c=n-1;a>l;a--,c--){o=ec.from(i.node(a).copy(o));let t=r&&r[c];s=ec.from(t?t.type.create(t.attrs,s):i.node(a).copy(s))}t.step(new mu(e,e,new ac(o.append(s),n,n),!0))}(this,t,e,n),this}addMark(t,e,n){return function(t,e,n,r){let i,o,s=[],a=[];t.doc.nodesBetween(e,n,((t,l,c)=>{if(!t.isInline)return;let u=t.marks;if(!r.isInSet(u)&&c.type.allowsMarkType(r.type)){let c=Math.max(l,e),d=Math.min(l+t.nodeSize,n),f=r.addToSet(u);for(let t=0;tt.step(e))),a.forEach((e=>t.step(e)))}(this,t,e,n),this}removeMark(t,e,n){return function(t,e,n,r){let i=[],o=0;t.doc.nodesBetween(e,n,((t,s)=>{if(!t.isInline)return;o++;let a=null;if(r instanceof Vc){let e,n=t.marks;for(;e=r.isInSet(n);)(a||(a=[])).push(e),n=e.removeFromSet(n)}else r?r.isInSet(t.marks)&&(a=[r]):a=t.marks;if(a&&a.length){let r=Math.min(s+t.nodeSize,n);for(let t=0;tt.step(new pu(e.from,e.to,e.style))))}(this,t,e,n),this}clearIncompatible(t,e,n){return function(t,e,n,r=n.contentMatch){let i=t.doc.nodeAt(e),o=[],s=e+1;for(let a=0;a=0;a--)t.step(o[a])}(this,t,e,n),this}}{constructor(t){super(t.doc),this.curSelectionFor=0,this.updated=0,this.meta=Object.create(null),this.time=Date.now(),this.curSelection=t.selection,this.storedMarks=t.storedMarks}get selection(){return this.curSelectionFor0}setStoredMarks(t){return this.storedMarks=t,this.updated|=2,this}ensureMarks(t){return oc.sameSet(this.storedMarks||this.selection.$from.marks(),t)||this.setStoredMarks(t),this}addStoredMark(t){return this.ensureMarks(t.addToSet(this.storedMarks||this.selection.$head.marks()))}removeStoredMark(t){return this.ensureMarks(t.removeFromSet(this.storedMarks||this.selection.$head.marks()))}get storedMarksSet(){return(2&this.updated)>0}addStep(t,e){super.addStep(t,e),this.updated=-3&this.updated,this.storedMarks=null}setTime(t){return this.time=t,this}replaceSelection(t){return this.selection.replace(this,t),this}replaceSelectionWith(t,e=!0){let n=this.selection;return e&&(t=t.mark(this.storedMarks||(n.empty?n.$from.marks():n.$from.marksAcross(n.$to)||oc.none))),n.replaceWith(this,t),this}deleteSelection(){return this.selection.replace(this),this}insertText(t,e,n){let r=this.doc.type.schema;if(null==e)return t?this.replaceSelectionWith(r.text(t),!0):this.deleteSelection();{if(null==n&&(n=e),n=null==n?e:n,!t)return this.deleteRange(e,n);let i=this.storedMarks;if(!i){let t=this.doc.resolve(e);i=n==e?t.marks():t.marksAcross(this.doc.resolve(n))}return this.replaceRangeWith(e,n,r.text(t,i)),this.selection.empty||this.setSelection(zu.near(this.selection.$to)),this}}setMeta(t,e){return this.meta["string"==typeof t?t:t.key]=e,this}getMeta(t){return this.meta["string"==typeof t?t:t.key]}get isGeneric(){for(let t in this.meta)return!1;return!0}scrollIntoView(){return this.updated|=4,this}get scrolledIntoView(){return(4&this.updated)>0}}function Gu(t,e){return e&&t?t.bind(e):t}class Zu{constructor(t,e,n){this.name=t,this.init=Gu(e.init,n),this.apply=Gu(e.apply,n)}}const Xu=[new Zu("doc",{init:t=>t.doc||t.schema.topNodeType.createAndFill(),apply:t=>t.doc}),new Zu("selection",{init:(t,e)=>t.selection||zu.atStart(e.doc),apply:t=>t.selection}),new Zu("storedMarks",{init:t=>t.storedMarks||null,apply:(t,e,n,r)=>r.selection.$cursor?t.storedMarks:null}),new Zu("scrollToSelection",{init:()=>0,apply:(t,e)=>t.scrolledIntoView?e+1:e})];class Qu{constructor(t,e){this.schema=t,this.plugins=[],this.pluginsByKey=Object.create(null),this.fields=Xu.slice(),e&&e.forEach((t=>{if(this.pluginsByKey[t.key])throw new RangeError("Adding different instances of a keyed plugin ("+t.key+")");this.plugins.push(t),this.pluginsByKey[t.key]=t,t.spec.state&&this.fields.push(new Zu(t.key,t.spec.state,t))}))}}class td{constructor(t){this.config=t}get schema(){return this.config.schema}get plugins(){return this.config.plugins}apply(t){return this.applyTransaction(t).state}filterTransaction(t,e=-1){for(let n=0;nt.toJSON()))),t&&"object"==typeof t)for(let n in t){if("doc"==n||"selection"==n)throw new RangeError("The JSON fields `doc` and `selection` are reserved");let r=t[n],i=r.spec.state;i&&i.toJSON&&(e[n]=i.toJSON.call(r,this[r.key]))}return e}static fromJSON(t,e,n){if(!e)throw new RangeError("Invalid input for EditorState.fromJSON");if(!t.schema)throw new RangeError("Required config field 'schema' missing");let r=new Qu(t.schema,t.plugins),i=new td(r);return r.fields.forEach((r=>{if("doc"==r.name)i.doc=_c.fromJSON(t.schema,e.doc);else if("selection"==r.name)i.selection=zu.fromJSON(i.doc,e.selection);else if("storedMarks"==r.name)e.storedMarks&&(i.storedMarks=e.storedMarks.map(t.schema.markFromJSON));else{if(n)for(let o in n){let s=n[o],a=s.spec.state;if(s.key==r.name&&a&&a.fromJSON&&Object.prototype.hasOwnProperty.call(e,o))return void(i[r.name]=a.fromJSON.call(s,t,e[o],i))}i[r.name]=r.init(t,i)}})),i}}function ed(t,e,n){for(let r in t){let i=t[r];i instanceof Function?i=i.bind(e):"handleDOMEvents"==r&&(i=ed(i,e,{})),n[r]=i}return n}class nd{constructor(t){this.spec=t,this.props={},t.props&&ed(t.props,this,this.props),this.key=t.key?t.key.key:id("plugin")}getState(t){return t[this.key]}}const rd=Object.create(null);function id(t){return t in rd?t+"$"+ ++rd[t]:(rd[t]=0,t+"$")}class od{constructor(t="key"){this.key=id(t)}get(t){return t.config.pluginsByKey[this.key]}getState(t){return t[this.key]}}const sd="undefined"!=typeof navigator?navigator:null,ad="undefined"!=typeof document?document:null,ld=sd&&sd.userAgent||"",cd=/Edge\/(\d+)/.exec(ld),ud=/MSIE \d/.exec(ld),dd=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(ld),fd=!!(ud||dd||cd),hd=ud?document.documentMode:dd?+dd[1]:cd?+cd[1]:0,pd=!fd&&/gecko\/(\d+)/i.test(ld);pd&&(/Firefox\/(\d+)/.exec(ld)||[0,0])[1];const md=!fd&&/Chrome\/(\d+)/.exec(ld),gd=!!md,vd=md?+md[1]:0,yd=!fd&&!!sd&&/Apple Computer/.test(sd.vendor),bd=yd&&(/Mobile\/\w+/.test(ld)||!!sd&&sd.maxTouchPoints>2),wd=bd||!!sd&&/Mac/.test(sd.platform),xd=/Android \d/.test(ld),Sd=!!ad&&"webkitFontSmoothing"in ad.documentElement.style,kd=Sd?+(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent)||[0,0])[1]:0,Od=function(t){for(var e=0;;e++)if(!(t=t.previousSibling))return e},_d=function(t){let e=t.assignedSlot||t.parentNode;return e&&11==e.nodeType?e.host:e};let Md=null;const Cd=function(t,e,n){let r=Md||(Md=document.createRange());return r.setEnd(t,null==n?t.nodeValue.length:n),r.setStart(t,e||0),r},$d=function(t,e,n,r){return n&&(Dd(t,e,n,r,-1)||Dd(t,e,n,r,1))},Td=/^(img|br|input|textarea|hr)$/i;function Dd(t,e,n,r,i){for(;;){if(t==n&&e==r)return!0;if(e==(i<0?0:Nd(t))){let n=t.parentNode;if(!n||1!=n.nodeType||Ad(t)||Td.test(t.nodeName)||"false"==t.contentEditable)return!1;e=Od(t)+(i<0?0:1),t=n}else{if(1!=t.nodeType)return!1;if("false"==(t=t.childNodes[e+(i<0?-1:0)]).contentEditable)return!1;e=i<0?Nd(t):0}}}function Nd(t){return 3==t.nodeType?t.nodeValue.length:t.childNodes.length}function Ad(t){let e;for(let n=t;n&&!(e=n.pmViewDesc);n=n.parentNode);return e&&e.node&&e.node.isBlock&&(e.dom==t||e.contentDOM==t)}const Ed=function(t){let e=t.isCollapsed;return e&&gd&&t.rangeCount&&!t.getRangeAt(0).collapsed&&(e=!1),e};function Pd(t,e){let n=document.createEvent("Event");return n.initEvent("keydown",!0,!0),n.keyCode=t,n.key=n.code=e,n}function Id(t){return{left:0,right:t.documentElement.clientWidth,top:0,bottom:t.documentElement.clientHeight}}function Rd(t,e){return"number"==typeof t?t:t[e]}function zd(t){let e=t.getBoundingClientRect(),n=e.width/t.offsetWidth||1,r=e.height/t.offsetHeight||1;return{left:e.left,right:e.left+t.clientWidth*n,top:e.top,bottom:e.top+t.clientHeight*r}}function jd(t,e,n){let r=t.someProp("scrollThreshold")||0,i=t.someProp("scrollMargin")||5,o=t.dom.ownerDocument;for(let s=n||t.dom;s;s=_d(s)){if(1!=s.nodeType)continue;let t=s,n=t==o.body,a=n?Id(o):zd(t),l=0,c=0;if(e.topa.bottom-Rd(r,"bottom")&&(c=e.bottom-a.bottom+Rd(i,"bottom")),e.lefta.right-Rd(r,"right")&&(l=e.right-a.right+Rd(i,"right")),l||c)if(n)o.defaultView.scrollBy(l,c);else{let n=t.scrollLeft,r=t.scrollTop;c&&(t.scrollTop+=c),l&&(t.scrollLeft+=l);let i=t.scrollLeft-n,o=t.scrollTop-r;e={left:e.left-i,top:e.top-o,right:e.right-i,bottom:e.bottom-o}}if(n)break}}function Fd(t){let e=[],n=t.ownerDocument;for(let r=t;r&&(e.push({dom:r,top:r.scrollTop,left:r.scrollLeft}),t!=n);r=_d(r));return e}function Ld(t,e){for(let n=0;n=a){s=Math.max(d.bottom,s),a=Math.min(d.top,a);let t=d.left>e.left?d.left-e.left:d.right=(d.left+d.right)/2?1:0));continue}}!n&&(e.left>=d.right&&e.top>=d.top||e.left>=d.left&&e.top>=d.bottom)&&(o=c+1)}}return n&&3==n.nodeType?function(t,e){let n=t.nodeValue.length,r=document.createRange();for(let i=0;i=(n.left+n.right)/2?1:0)}}return{node:t,offset:0}}(n,r):!n||i&&1==n.nodeType?{node:t,offset:o}:Vd(n,r)}function Wd(t,e){return t.left>=e.left-1&&t.left<=e.right+1&&t.top>=e.top-1&&t.top<=e.bottom+1}function qd(t,e,n){let r=t.childNodes.length;if(r&&n.tope.top&&i++}n==t.dom&&i==n.childNodes.length-1&&1==n.lastChild.nodeType&&e.top>n.lastChild.getBoundingClientRect().bottom?o=t.state.doc.content.size:0!=i&&1==n.nodeType&&"BR"==n.childNodes[i-1].nodeName||(o=function(t,e,n,r){let i=-1;for(let o=e;o!=t.dom;){let e=t.docView.nearestDesc(o,!0);if(!e)return null;if(e.node.isBlock&&e.parent){let t=e.dom.getBoundingClientRect();if(t.left>r.left||t.top>r.top)i=e.posBefore;else{if(!(t.right-1?i:t.docView.posFromDOM(e,n,1)}(t,n,i,e))}null==o&&(o=function(t,e,n){let{node:r,offset:i}=Vd(e,n),o=-1;if(1==r.nodeType&&!r.firstChild){let t=r.getBoundingClientRect();o=t.left!=t.right&&n.left>(t.left+t.right)/2?1:-1}return t.docView.posFromDOM(r,i,o)}(t,s,e));let a=t.docView.nearestDesc(s,!0);return{pos:o,inside:a?a.posAtStart-a.border:-1}}function Kd(t,e){let n=t.getClientRects();return n.length?n[e<0?0:n.length-1]:t.getBoundingClientRect()}const Hd=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;function Ud(t,e,n){let{node:r,offset:i,atom:o}=t.docView.domFromPos(e,n<0?-1:1),s=Sd||pd;if(3==r.nodeType){if(!s||!Hd.test(r.nodeValue)&&(n<0?i:i!=r.nodeValue.length)){let t=i,e=i,o=n<0?1:-1;return n<0&&!i?(e++,o=-1):n>=0&&i==r.nodeValue.length?(t--,o=1):n<0?t--:e++,Yd(Kd(Cd(r,t,e),o),o<0)}{let t=Kd(Cd(r,i,i),n);if(pd&&i&&/\s/.test(r.nodeValue[i-1])&&i=0)}if(null==o&&i&&(n<0||i==Nd(r))){let t=r.childNodes[i-1],e=3==t.nodeType?Cd(t,Nd(t)-(s?0:1)):1!=t.nodeType||"BR"==t.nodeName&&t.nextSibling?null:t;if(e)return Yd(Kd(e,1),!1)}if(null==o&&i=0)}function Yd(t,e){if(0==t.width)return t;let n=e?t.left:t.right;return{top:t.top,bottom:t.bottom,left:n,right:n}}function Gd(t,e){if(0==t.height)return t;let n=e?t.top:t.bottom;return{top:n,bottom:n,left:t.left,right:t.right}}function Zd(t,e,n){let r=t.state,i=t.root.activeElement;r!=e&&t.updateState(e),i!=t.dom&&t.focus();try{return n()}finally{r!=e&&t.updateState(r),i!=t.dom&&i&&i.focus()}}const Xd=/[\u0590-\u08ac]/;let Qd=null,tf=null,ef=!1;function nf(t,e,n){return Qd==e&&tf==n?ef:(Qd=e,tf=n,ef="up"==n||"down"==n?function(t,e,n){let r=e.selection,i="up"==n?r.$from:r.$to;return Zd(t,e,(()=>{let{node:e}=t.docView.domFromPos(i.pos,"up"==n?-1:1);for(;;){let n=t.docView.nearestDesc(e,!0);if(!n)break;if(n.node.isBlock){e=n.dom;break}e=n.dom.parentNode}let r=Ud(t,i.pos,1);for(let t=e.firstChild;t;t=t.nextSibling){let e;if(1==t.nodeType)e=t.getClientRects();else{if(3!=t.nodeType)continue;e=Cd(t,0,t.nodeValue.length).getClientRects()}for(let t=0;ti.top+1&&("up"==n?r.top-i.top>2*(i.bottom-r.top):i.bottom-r.bottom>2*(r.bottom-i.top)))return!1}}return!0}))}(t,e,n):function(t,e,n){let{$head:r}=e.selection;if(!r.parent.isTextblock)return!1;let i=r.parentOffset,o=!i,s=i==r.parent.content.size,a=t.domSelection();return Xd.test(r.parent.textContent)&&a.modify?Zd(t,e,(()=>{let e=a.getRangeAt(0),i=a.focusNode,o=a.focusOffset,s=a.caretBidiLevel;a.modify("move",n,"character");let l=!(r.depth?t.docView.domAfterPos(r.before()):t.dom).contains(1==a.focusNode.nodeType?a.focusNode:a.focusNode.parentNode)||i==a.focusNode&&o==a.focusOffset;return a.removeAllRanges(),a.addRange(e),null!=s&&(a.caretBidiLevel=s),l})):"left"==n||"backward"==n?o:s}(t,e,n))}class rf{constructor(t,e,n,r){this.parent=t,this.children=e,this.dom=n,this.contentDOM=r,this.dirty=0,n.pmViewDesc=this}matchesWidget(t){return!1}matchesMark(t){return!1}matchesNode(t,e,n){return!1}matchesHack(t){return!1}parseRule(){return null}stopEvent(t){return!1}get size(){let t=0;for(let e=0;eOd(this.contentDOM);else if(this.contentDOM&&this.contentDOM!=this.dom&&this.dom.contains(this.contentDOM))r=2&t.compareDocumentPosition(this.contentDOM);else if(this.dom.firstChild){if(0==e)for(let e=t;;e=e.parentNode){if(e==this.dom){r=!1;break}if(e.previousSibling)break}if(null==r&&e==t.childNodes.length)for(let e=t;;e=e.parentNode){if(e==this.dom){r=!0;break}if(e.nextSibling)break}}return(null==r?n>0:r)?this.posAtEnd:this.posAtStart}nearestDesc(t,e=!1){for(let n=!0,r=t;r;r=r.parentNode){let i,o=this.getDesc(r);if(o&&(!e||o.node)){if(!n||!(i=o.nodeDOM)||(1==i.nodeType?i.contains(1==t.nodeType?t:t.parentNode):i==t))return o;n=!1}}}getDesc(t){let e=t.pmViewDesc;for(let n=e;n;n=n.parent)if(n==this)return e}posFromDOM(t,e,n){for(let r=t;r;r=r.parentNode){let i=this.getDesc(r);if(i)return i.localPosFromDOM(t,e,n)}return-1}descAt(t){for(let e=0,n=0;et||e instanceof df){i=t-o;break}o=n}if(i)return this.children[r].domFromPos(i-this.children[r].border,e);for(;r&&!(n=this.children[r-1]).size&&n instanceof of&&n.side>=0;r--);if(e<=0){let t,n=!0;for(;t=r?this.children[r-1]:null,t&&t.dom.parentNode!=this.contentDOM;r--,n=!1);return t&&e&&n&&!t.border&&!t.domAtom?t.domFromPos(t.size,e):{node:this.contentDOM,offset:t?Od(t.dom)+1:0}}{let t,n=!0;for(;t=r=i&&e<=a-n.border&&n.node&&n.contentDOM&&this.contentDOM.contains(n.contentDOM))return n.parseRange(t,e,i);t=o;for(let e=s;e>0;e--){let n=this.children[e-1];if(n.size&&n.dom.parentNode==this.contentDOM&&!n.emptyChildAt(1)){r=Od(n.dom)+1;break}t-=n.size}-1==r&&(r=0)}if(r>-1&&(a>e||s==this.children.length-1)){e=a;for(let t=s+1;th&&oe){let t=s;s=a,a=t}let n=document.createRange();n.setEnd(a.node,a.offset),n.setStart(s.node,s.offset),l.removeAllRanges(),l.addRange(n)}}ignoreMutation(t){return!this.contentDOM&&"selection"!=t.type}get contentLost(){return this.contentDOM&&this.contentDOM!=this.dom&&!this.dom.contains(this.contentDOM)}markDirty(t,e){for(let n=0,r=0;r=n:tn){let r=n+i.border,s=o-i.border;if(t>=r&&e<=s)return this.dirty=t==n||e==o?2:1,void(t!=r||e!=s||!i.contentLost&&i.dom.parentNode==this.contentDOM?i.markDirty(t-r,e-r):i.dirty=3);i.dirty=i.dom!=i.contentDOM||i.dom.parentNode!=this.contentDOM||i.children.length?3:2}n=o}this.dirty=2}markParentsDirty(){let t=1;for(let e=this.parent;e;e=e.parent,t++){let n=1==t?2:1;e.dirtyi?i.parent?i.parent.posBeforeChild(i):void 0:r))),!e.type.spec.raw){if(1!=o.nodeType){let t=document.createElement("span");t.appendChild(o),o=t}o.contentEditable="false",o.classList.add("ProseMirror-widget")}super(t,[],o,null),this.widget=e,this.widget=e,i=this}matchesWidget(t){return 0==this.dirty&&t.type.eq(this.widget.type)}parseRule(){return{ignore:!0}}stopEvent(t){let e=this.widget.spec.stopEvent;return!!e&&e(t)}ignoreMutation(t){return"selection"!=t.type||this.widget.spec.ignoreSelection}destroy(){this.widget.type.destroy(this.dom),super.destroy()}get domAtom(){return!0}get side(){return this.widget.type.side}}class sf extends rf{constructor(t,e,n,r){super(t,[],e,null),this.textDOM=n,this.text=r}get size(){return this.text.length}localPosFromDOM(t,e){return t!=this.textDOM?this.posAtStart+(e?this.size:0):this.posAtStart+e}domFromPos(t){return{node:this.textDOM,offset:t}}ignoreMutation(t){return"characterData"===t.type&&t.target.nodeValue==t.oldValue}}class af extends rf{constructor(t,e,n,r){super(t,[],n,r),this.mark=e}static create(t,e,n,r){let i=r.nodeViews[e.type.name],o=i&&i(e,r,n);return o&&o.dom||(o=eu.renderSpec(document,e.type.spec.toDOM(e,n))),new af(t,e,o.dom,o.contentDOM||o.dom)}parseRule(){return 3&this.dirty||this.mark.type.spec.reparseInView?null:{mark:this.mark.type.name,attrs:this.mark.attrs,contentElement:this.contentDOM||void 0}}matchesMark(t){return 3!=this.dirty&&this.mark.eq(t)}markDirty(t,e){if(super.markDirty(t,e),0!=this.dirty){let t=this.parent;for(;!t.node;)t=t.parent;t.dirty0&&(i=Of(i,0,t,n));for(let s=0;ss?s.parent?s.parent.posBeforeChild(s):void 0:o),n,r),c=l&&l.dom,u=l&&l.contentDOM;if(e.isText)if(c){if(3!=c.nodeType)throw new RangeError("Text must be rendered as a DOM text node")}else c=document.createTextNode(e.text);else c||({dom:c,contentDOM:u}=eu.renderSpec(document,e.type.spec.toDOM(e)));u||e.isText||"BR"==c.nodeName||(c.hasAttribute("contenteditable")||(c.contentEditable="false"),e.type.spec.draggable&&(c.draggable=!0));let d=c;return c=bf(c,n,e),l?s=new ff(t,e,n,r,c,u||null,d,l,i,o+1):e.isText?new uf(t,e,n,r,c,d,i):new lf(t,e,n,r,c,u||null,d,i,o+1)}parseRule(){if(this.node.type.spec.reparseInView)return null;let t={node:this.node.type.name,attrs:this.node.attrs};if("pre"==this.node.type.whitespace&&(t.preserveWhitespace="full"),this.contentDOM)if(this.contentLost){for(let e=this.children.length-1;e>=0;e--){let n=this.children[e];if(this.dom.contains(n.dom.parentNode)){t.contentElement=n.dom.parentNode;break}}t.contentElement||(t.getContent=()=>ec.empty)}else t.contentElement=this.contentDOM;else t.getContent=()=>this.node.content;return t}matchesNode(t,e,n){return 0==this.dirty&&t.eq(this.node)&&wf(e,this.outerDeco)&&n.eq(this.innerDeco)}get size(){return this.node.nodeSize}get border(){return this.node.isLeaf?0:1}updateChildren(t,e){let n=this.node.inlineContent,r=e,i=t.composing?this.localCompositionInfo(t,e):null,o=i&&i.pos>-1?i:null,s=i&&i.pos<0,a=new Sf(this,o&&o.node);!function(t,e,n,r){let i=e.locals(t),o=0;if(0==i.length){for(let n=0;no;)a.push(i[s++]);let f=o+u.nodeSize;if(u.isText){let t=f;s!t.inline)):a.slice(),e.forChild(o,u),d),o=f}}(this.node,this.innerDeco,((e,i,o)=>{e.spec.marks?a.syncToMarks(e.spec.marks,n,t):e.type.side>=0&&!o&&a.syncToMarks(i==this.node.childCount?oc.none:this.node.child(i).marks,n,t),a.placeWidget(e,t,r)}),((e,o,l,c)=>{let u;a.syncToMarks(e.marks,n,t),a.findNodeMatch(e,o,l,c)||s&&t.state.selection.from>r&&t.state.selection.to-1&&a.updateNodeAt(e,o,l,u,t)||a.updateNextNode(e,o,l,t,c)||a.addNode(e,o,l,t,r),r+=e.nodeSize})),a.syncToMarks([],n,t),this.node.isTextblock&&a.addTextblockHacks(),a.destroyRest(),(a.changed||2==this.dirty)&&(o&&this.protectLocalComposition(t,o),hf(this.contentDOM,this.children,t),bd&&function(t){if("UL"==t.nodeName||"OL"==t.nodeName){let e=t.style.cssText;t.style.cssText=e+"; list-style: square !important",window.getComputedStyle(t).listStyle,t.style.cssText=e}}(this.dom))}localCompositionInfo(t,e){let{from:n,to:r}=t.state.selection;if(!(t.state.selection instanceof Bu)||ne+this.node.content.size)return null;let i=t.domSelection(),o=function(t,e){for(;;){if(3==t.nodeType)return t;if(1==t.nodeType&&e>0){if(t.childNodes.length>e&&3==t.childNodes[e].nodeType)return t.childNodes[e];e=Nd(t=t.childNodes[e-1])}else{if(!(1==t.nodeType&&e=n){let t=a=0&&t+e.length+a>=n)return a+t;if(n==r&&l.length>=r+e.length-a&&l.slice(r-a,r-a+e.length)==e)return r}}return-1}(this.node.content,t,n-e,r-e);return i<0?null:{node:o,pos:i,text:t}}return{node:o,pos:-1,text:""}}protectLocalComposition(t,{node:e,pos:n,text:r}){if(this.getDesc(e))return;let i=e;for(;i.parentNode!=this.contentDOM;i=i.parentNode){for(;i.previousSibling;)i.parentNode.removeChild(i.previousSibling);for(;i.nextSibling;)i.parentNode.removeChild(i.nextSibling);i.pmViewDesc&&(i.pmViewDesc=void 0)}let o=new sf(this,i,e,r);t.input.compositionNodes.push(o),this.children=Of(this.children,n,n+r.length,t,o)}update(t,e,n,r){return!(3==this.dirty||!t.sameMarkup(this.node))&&(this.updateInner(t,e,n,r),!0)}updateInner(t,e,n,r){this.updateOuterDeco(e),this.node=t,this.innerDeco=n,this.contentDOM&&this.updateChildren(r,this.posAtStart),this.dirty=0}updateOuterDeco(t){if(wf(t,this.outerDeco))return;let e=1!=this.nodeDOM.nodeType,n=this.dom;this.dom=vf(this.dom,this.nodeDOM,gf(this.outerDeco,this.node,e),gf(t,this.node,e)),this.dom!=n&&(n.pmViewDesc=void 0,this.dom.pmViewDesc=this),this.outerDeco=t}selectNode(){1==this.nodeDOM.nodeType&&this.nodeDOM.classList.add("ProseMirror-selectednode"),!this.contentDOM&&this.node.type.spec.draggable||(this.dom.draggable=!0)}deselectNode(){1==this.nodeDOM.nodeType&&this.nodeDOM.classList.remove("ProseMirror-selectednode"),!this.contentDOM&&this.node.type.spec.draggable||this.dom.removeAttribute("draggable")}get domAtom(){return this.node.isAtom}}function cf(t,e,n,r,i){return bf(r,e,t),new lf(void 0,t,e,n,r,r,r,i,0)}class uf extends lf{constructor(t,e,n,r,i,o,s){super(t,e,n,r,i,null,o,s,0)}parseRule(){let t=this.nodeDOM.parentNode;for(;t&&t!=this.dom&&!t.pmIsDeco;)t=t.parentNode;return{skip:t||!0}}update(t,e,n,r){return!(3==this.dirty||0!=this.dirty&&!this.inParent()||!t.sameMarkup(this.node))&&(this.updateOuterDeco(e),0==this.dirty&&t.text==this.node.text||t.text==this.nodeDOM.nodeValue||(this.nodeDOM.nodeValue=t.text,r.trackWrites==this.nodeDOM&&(r.trackWrites=null)),this.node=t,this.dirty=0,!0)}inParent(){let t=this.parent.contentDOM;for(let e=this.nodeDOM;e;e=e.parentNode)if(e==t)return!0;return!1}domFromPos(t){return{node:this.nodeDOM,offset:t}}localPosFromDOM(t,e,n){return t==this.nodeDOM?this.posAtStart+Math.min(e,this.node.text.length):super.localPosFromDOM(t,e,n)}ignoreMutation(t){return"characterData"!=t.type&&"selection"!=t.type}slice(t,e,n){let r=this.node.cut(t,e),i=document.createTextNode(r.text);return new uf(this.parent,r,this.outerDeco,this.innerDeco,i,i,n)}markDirty(t,e){super.markDirty(t,e),this.dom==this.nodeDOM||0!=t&&e!=this.nodeDOM.nodeValue.length||(this.dirty=3)}get domAtom(){return!1}}class df extends rf{parseRule(){return{ignore:!0}}matchesHack(t){return 0==this.dirty&&this.dom.nodeName==t}get domAtom(){return!0}get ignoreForCoords(){return"IMG"==this.dom.nodeName}}class ff extends lf{constructor(t,e,n,r,i,o,s,a,l,c){super(t,e,n,r,i,o,s,l,c),this.spec=a}update(t,e,n,r){if(3==this.dirty)return!1;if(this.spec.update){let i=this.spec.update(t,e,n);return i&&this.updateInner(t,e,n,r),i}return!(!this.contentDOM&&!t.isLeaf)&&super.update(t,e,n,r)}selectNode(){this.spec.selectNode?this.spec.selectNode():super.selectNode()}deselectNode(){this.spec.deselectNode?this.spec.deselectNode():super.deselectNode()}setSelection(t,e,n,r){this.spec.setSelection?this.spec.setSelection(t,e,n):super.setSelection(t,e,n,r)}destroy(){this.spec.destroy&&this.spec.destroy(),super.destroy()}stopEvent(t){return!!this.spec.stopEvent&&this.spec.stopEvent(t)}ignoreMutation(t){return this.spec.ignoreMutation?this.spec.ignoreMutation(t):super.ignoreMutation(t)}}function hf(t,e,n){let r=t.firstChild,i=!1;for(let o=0;o0;){let a;for(;;)if(r){let t=n.children[r-1];if(!(t instanceof af)){a=t,r--;break}n=t,r=t.children.length}else{if(n==e)break t;r=n.parent.children.indexOf(n),n=n.parent}let l=a.node;if(l){if(l!=t.child(i-1))break;--i,o.set(a,i),s.push(a)}}return{index:i,matched:o,matches:s.reverse()}}(t.node.content,t)}destroyBetween(t,e){if(t!=e){for(let n=t;n>1,o=Math.min(i,t.length);for(;r-1)r>this.index&&(this.changed=!0,this.destroyBetween(this.index,r)),this.top=this.top.children[this.index];else{let r=af.create(this.top,t[i],e,n);this.top.children.splice(this.index,0,r),this.top=r,this.changed=!0}this.index=0,i++}}findNodeMatch(t,e,n,r){let i,o=-1;if(r>=this.preMatch.index&&(i=this.preMatch.matches[r-this.preMatch.index]).parent==this.top&&i.matchesNode(t,e,n))o=this.top.children.indexOf(i,this.index);else for(let s=this.index,a=Math.min(this.top.children.length,s+5);s=n||u<=e?o.push(l):(cn&&o.push(l.slice(n-c,l.size,r)))}return o}function _f(t,e=null){let n=t.domSelection(),r=t.state.doc;if(!n.focusNode)return null;let i=t.docView.nearestDesc(n.focusNode),o=i&&0==i.size,s=t.docView.posFromDOM(n.focusNode,n.focusOffset,1);if(s<0)return null;let a,l,c=r.resolve(s);if(Ed(n)){for(a=c;i&&!i.node;)i=i.parent;let t=i.node;if(i&&t.isAtom&&Wu.isSelectable(t)&&i.parent&&(!t.isInline||!function(t,e,n){for(let r=0==e,i=e==Nd(t);r||i;){if(t==n)return!0;let e=Od(t);if(!(t=t.parentNode))return!1;r=r&&0==e,i=i&&e==Nd(t)}}(n.focusNode,n.focusOffset,i.dom))){let t=i.posBefore;l=new Wu(s==t?c:r.resolve(t))}}else{let e=t.docView.posFromDOM(n.anchorNode,n.anchorOffset,1);if(e<0)return null;a=r.resolve(e)}if(!l){l=Pf(t,a,c,"pointer"==e||t.state.selection.head{n.anchorNode==r&&n.anchorOffset==i||(e.removeEventListener("selectionchange",t.input.hideSelectionGuard),setTimeout((()=>{Mf(t)&&!t.state.selection.visible||t.dom.classList.remove("ProseMirror-hideselection")}),20))})}(t))}t.domObserver.setCurSelection(),t.domObserver.connectSelection()}}const $f=yd||gd&&vd<63;function Tf(t,e){let{node:n,offset:r}=t.docView.domFromPos(e,0),i=rr(t,e,n)))||Bu.between(e,n,r)}function If(t){return(!t.editable||t.root.activeElement==t.dom)&&Rf(t)}function Rf(t){let e=t.domSelection();if(!e.anchorNode)return!1;try{return t.dom.contains(3==e.anchorNode.nodeType?e.anchorNode.parentNode:e.anchorNode)&&(t.editable||t.dom.contains(3==e.focusNode.nodeType?e.focusNode.parentNode:e.focusNode))}catch(n){return!1}}function zf(t,e){let{$anchor:n,$head:r}=t.selection,i=e>0?n.max(r):n.min(r),o=i.parent.inlineContent?i.depth?t.doc.resolve(e>0?i.after():i.before()):null:i;return o&&zu.findFrom(o,e)}function jf(t,e){return t.dispatch(t.state.tr.setSelection(e).scrollIntoView()),!0}function Ff(t,e,n){let r=t.state.selection;if(!(r instanceof Bu)){if(r instanceof Wu&&r.node.isInline)return jf(t,new Bu(e>0?r.$to:r.$from));{let n=zf(t.state,e);return!!n&&jf(t,n)}}if(!r.empty||n.indexOf("s")>-1)return!1;if(t.endOfTextblock(e>0?"right":"left")){let n=zf(t.state,e);return!!(n&&n instanceof Wu)&&jf(t,n)}if(!(wd&&n.indexOf("m")>-1)){let n,i=r.$head,o=i.textOffset?null:e<0?i.nodeBefore:i.nodeAfter;if(!o||o.isText)return!1;let s=e<0?i.pos-o.nodeSize:i.pos;return!!(o.isAtom||(n=t.docView.descAt(s))&&!n.contentDOM)&&(Wu.isSelectable(o)?jf(t,new Wu(e<0?t.state.doc.resolve(i.pos-o.nodeSize):i)):!!Sd&&jf(t,new Bu(t.state.doc.resolve(e<0?s:s+o.nodeSize))))}}function Lf(t){return 3==t.nodeType?t.nodeValue.length:t.childNodes.length}function Bf(t){let e=t.pmViewDesc;return e&&0==e.size&&(t.nextSibling||"BR"!=t.nodeName)}function Vf(t){let e=t.domSelection(),n=e.focusNode,r=e.focusOffset;if(!n)return;let i,o,s=!1;for(pd&&1==n.nodeType&&r0){if(1!=n.nodeType)break;{let t=n.childNodes[r-1];if(Bf(t))i=n,o=--r;else{if(3!=t.nodeType)break;n=t,r=n.nodeValue.length}}}else{if(qf(n))break;{let e=n.previousSibling;for(;e&&Bf(e);)i=n.parentNode,o=Od(e),e=e.previousSibling;if(e)n=e,r=Lf(n);else{if(n=n.parentNode,n==t.dom)break;r=0}}}s?Jf(t,e,n,r):i&&Jf(t,e,i,o)}function Wf(t){let e=t.domSelection(),n=e.focusNode,r=e.focusOffset;if(!n)return;let i,o,s=Lf(n);for(;;)if(r{t.state==i&&Cf(t)}),50)}function Kf(t,e,n){let r=t.state.selection;if(r instanceof Bu&&!r.empty||n.indexOf("s")>-1)return!1;if(wd&&n.indexOf("m")>-1)return!1;let{$from:i,$to:o}=r;if(!i.parent.inlineContent||t.endOfTextblock(e<0?"up":"down")){let n=zf(t.state,e);if(n&&n instanceof Wu)return jf(t,n)}if(!i.parent.inlineContent){let n=e<0?i:o,s=r instanceof Ju?zu.near(n,e):zu.findFrom(n,e);return!!s&&jf(t,s)}return!1}function Hf(t,e){if(!(t.state.selection instanceof Bu))return!0;let{$head:n,$anchor:r,empty:i}=t.state.selection;if(!n.sameParent(r))return!0;if(!i)return!1;if(t.endOfTextblock(e>0?"forward":"backward"))return!0;let o=!n.textOffset&&(e<0?n.nodeBefore:n.nodeAfter);if(o&&!o.isText){let r=t.state.tr;return e<0?r.delete(n.pos-o.nodeSize,n.pos):r.delete(n.pos,n.pos+o.nodeSize),t.dispatch(r),!0}return!1}function Uf(t,e,n){t.domObserver.stop(),e.contentEditable=n,t.domObserver.start()}function Yf(t,e){let n=e.keyCode,r=function(t){let e="";return t.ctrlKey&&(e+="c"),t.metaKey&&(e+="m"),t.altKey&&(e+="a"),t.shiftKey&&(e+="s"),e}(e);return 8==n||wd&&72==n&&"c"==r?Hf(t,-1)||Vf(t):46==n||wd&&68==n&&"c"==r?Hf(t,1)||Wf(t):13==n||27==n||(37==n||wd&&66==n&&"c"==r?Ff(t,-1,r)||Vf(t):39==n||wd&&70==n&&"c"==r?Ff(t,1,r)||Wf(t):38==n||wd&&80==n&&"c"==r?Kf(t,-1,r)||Vf(t):40==n||wd&&78==n&&"c"==r?function(t){if(!yd||t.state.selection.$head.parentOffset>0)return!1;let{focusNode:e,focusOffset:n}=t.domSelection();if(e&&1==e.nodeType&&0==n&&e.firstChild&&"false"==e.firstChild.contentEditable){let n=e.firstChild;Uf(t,n,"true"),setTimeout((()=>Uf(t,n,"false")),20)}return!1}(t)||Kf(t,1,r)||Wf(t):r==(wd?"m":"c")&&(66==n||73==n||89==n||90==n))}function Gf(t,e){let n=[],{content:r,openStart:i,openEnd:o}=e;for(;i>1&&o>1&&1==r.childCount&&1==r.firstChild.childCount;){i--,o--;let t=r.firstChild;n.push(t.type.name,t.attrs!=t.type.defaultAttrs?t.attrs:null),r=t.content}let s=t.someProp("clipboardSerializer")||eu.fromSchema(t.state.schema),a=sh(),l=a.createElement("div");l.appendChild(s.serializeFragment(r,{document:a}));let c,u=l.firstChild,d=0;for(;u&&1==u.nodeType&&(c=ih[u.nodeName.toLowerCase()]);){for(let t=c.length-1;t>=0;t--){let e=a.createElement(c[t]);for(;l.firstChild;)e.appendChild(l.firstChild);l.appendChild(e),d++}u=l.firstChild}return u&&1==u.nodeType&&u.setAttribute("data-pm-slice",`${i} ${o}${d?` -${d}`:""} ${JSON.stringify(n)}`),{dom:l,text:t.someProp("clipboardTextSerializer",(t=>t(e)))||e.content.textBetween(0,e.content.size,"\n\n")}}function Zf(t,e,n,r,i){let o,s,a=i.parent.type.spec.code;if(!n&&!e)return null;let l=e&&(r||a||!n);if(l){if(t.someProp("transformPastedText",(t=>{e=t(e,a||r)})),a)return e?new ac(ec.from(t.state.schema.text(e.replace(/\r\n?/g,"\n"))),0,0):ac.empty;let n=t.someProp("clipboardTextParser",(t=>t(e,i,r)));if(n)s=n;else{let n=i.marks(),{schema:r}=t.state,s=eu.fromSchema(r);o=document.createElement("div"),e.split(/(?:\r\n?|\n)+/).forEach((t=>{let e=o.appendChild(document.createElement("p"));t&&e.appendChild(s.serializeNode(r.text(t,n)))}))}}else t.someProp("transformPastedHTML",(t=>{n=t(n)})),o=function(t){let e=/^(\s*]*>)*/.exec(t);e&&(t=t.slice(e[0].length));let n,r=sh().createElement("div"),i=/<([a-z][^>\s]+)/i.exec(t);(n=i&&ih[i[1].toLowerCase()])&&(t=n.map((t=>"<"+t+">")).join("")+t+n.map((t=>"")).reverse().join(""));if(r.innerHTML=t,n)for(let o=0;o0&&o.firstChild;d--)o=o.firstChild;if(!s){let e=t.someProp("clipboardParser")||t.someProp("domParser")||Jc.fromSchema(t.state.schema);s=e.parseSlice(o,{preserveWhitespace:!(!l&&!u),context:i,ruleFromNode:t=>"BR"!=t.nodeName||t.nextSibling||!t.parentNode||Xf.test(t.parentNode.nodeName)?null:{ignore:!0}})}if(u)s=function(t,e){if(!t.size)return t;let n,r=t.content.firstChild.type.schema;try{n=JSON.parse(e)}catch(_g){return t}let{content:i,openStart:o,openEnd:s}=t;for(let a=n.length-2;a>=0;a-=2){let t=r.nodes[n[a]];if(!t||t.hasRequiredAttrs())break;i=ec.from(t.create(n[a+1],i)),o++,s++}return new ac(i,o,s)}(rh(s,+u[1],+u[2]),u[4]);else if(s=ac.maxOpen(function(t,e){if(t.childCount<2)return t;for(let n=e.depth;n>=0;n--){let r,i=e.node(n).contentMatchAt(e.index(n)),o=[];if(t.forEach((t=>{if(!o)return;let e,n=i.findWrapping(t.type);if(!n)return o=null;if(e=o.length&&r.length&&th(n,r,t,o[o.length-1],0))o[o.length-1]=e;else{o.length&&(o[o.length-1]=eh(o[o.length-1],r.length));let e=Qf(t,n);o.push(e),i=i.matchType(e.type),r=n}})),o)return ec.from(o)}return t}(s.content,i),!0),s.openStart||s.openEnd){let t=0,e=0;for(let n=s.content.firstChild;t{s=t(s)})),s}const Xf=/^(a|abbr|acronym|b|cite|code|del|em|i|ins|kbd|label|output|q|ruby|s|samp|span|strong|sub|sup|time|u|tt|var)$/i;function Qf(t,e,n=0){for(let r=e.length-1;r>=n;r--)t=e[r].create(null,ec.from(t));return t}function th(t,e,n,r,i){if(i=n&&(a=e<0?s.contentMatchAt(0).fillBefore(a,t.childCount>1||o<=i).append(a):a.append(s.contentMatchAt(s.childCount).fillBefore(ec.empty,!0))),t.replaceChild(e<0?0:t.childCount-1,s.copy(a))}function rh(t,e,n){return e{for(let n in e)t.input.eventHandlers[n]||t.dom.addEventListener(n,t.input.eventHandlers[n]=e=>fh(t,e))}))}function fh(t,e){return t.someProp("handleDOMEvents",(n=>{let r=n[e.type];return!!r&&(r(t,e)||e.defaultPrevented)}))}function hh(t,e){if(!e.bubbles)return!0;if(e.defaultPrevented)return!1;for(let n=e.target;n!=t.dom;n=n.parentNode)if(!n||11==n.nodeType||n.pmViewDesc&&n.pmViewDesc.stopEvent(e))return!1;return!0}function ph(t){return{left:t.clientX,top:t.clientY}}function mh(t,e,n,r,i){if(-1==r)return!1;let o=t.state.doc.resolve(r);for(let s=o.depth+1;s>0;s--)if(t.someProp(e,(e=>s>o.depth?e(t,n,o.nodeAfter,o.before(s),i,!0):e(t,n,o.node(s),o.before(s),i,!1))))return!0;return!1}function gh(t,e,n){t.focused||t.focus();let r=t.state.tr.setSelection(e);"pointer"==n&&r.setMeta("pointer",!0),t.dispatch(r)}function vh(t,e,n,r,i){return mh(t,"handleClickOn",e,n,r)||t.someProp("handleClick",(n=>n(t,e,r)))||(i?function(t,e){if(-1==e)return!1;let n,r,i=t.state.selection;i instanceof Wu&&(n=i.node);let o=t.state.doc.resolve(e);for(let s=o.depth+1;s>0;s--){let t=s>o.depth?o.nodeAfter:o.node(s);if(Wu.isSelectable(t)){r=n&&i.$from.depth>0&&s>=i.$from.depth&&o.before(i.$from.depth+1)==i.$from.pos?o.before(i.$from.depth):o.before(s);break}}return null!=r&&(gh(t,Wu.create(t.state.doc,r),"pointer"),!0)}(t,n):function(t,e){if(-1==e)return!1;let n=t.state.doc.resolve(e),r=n.nodeAfter;return!!(r&&r.isAtom&&Wu.isSelectable(r))&&(gh(t,new Wu(n),"pointer"),!0)}(t,n))}function yh(t,e,n,r){return mh(t,"handleDoubleClickOn",e,n,r)||t.someProp("handleDoubleClick",(n=>n(t,e,r)))}function bh(t,e,n,r){return mh(t,"handleTripleClickOn",e,n,r)||t.someProp("handleTripleClick",(n=>n(t,e,r)))||function(t,e,n){if(0!=n.button)return!1;let r=t.state.doc;if(-1==e)return!!r.inlineContent&&(gh(t,Bu.create(r,0,r.content.size),"pointer"),!0);let i=r.resolve(e);for(let o=i.depth+1;o>0;o--){let e=o>i.depth?i.nodeAfter:i.node(o),n=i.before(o);if(e.inlineContent)gh(t,Bu.create(r,n+1,n+1+e.content.size),"pointer");else{if(!Wu.isSelectable(e))continue;gh(t,Wu.create(r,n),"pointer")}return!0}}(t,n,r)}function wh(t){return Ch(t)}lh.keydown=(t,e)=>{let n=e;if(t.input.shiftKey=16==n.keyCode||n.shiftKey,!kh(t,n)&&(t.input.lastKeyCode=n.keyCode,t.input.lastKeyCodeTime=Date.now(),!xd||!gd||13!=n.keyCode))if(229!=n.keyCode&&t.domObserver.forceFlush(),!bd||13!=n.keyCode||n.ctrlKey||n.altKey||n.metaKey)t.someProp("handleKeyDown",(e=>e(t,n)))||Yf(t,n)?n.preventDefault():uh(t,"key");else{let e=Date.now();t.input.lastIOSEnter=e,t.input.lastIOSEnterFallbackTimeout=setTimeout((()=>{t.input.lastIOSEnter==e&&(t.someProp("handleKeyDown",(e=>e(t,Pd(13,"Enter")))),t.input.lastIOSEnter=0)}),200)}},lh.keyup=(t,e)=>{16==e.keyCode&&(t.input.shiftKey=!1)},lh.keypress=(t,e)=>{let n=e;if(kh(t,n)||!n.charCode||n.ctrlKey&&!n.altKey||wd&&n.metaKey)return;if(t.someProp("handleKeyPress",(e=>e(t,n))))return void n.preventDefault();let r=t.state.selection;if(!(r instanceof Bu&&r.$from.sameParent(r.$to))){let e=String.fromCharCode(n.charCode);t.someProp("handleTextInput",(n=>n(t,r.$from.pos,r.$to.pos,e)))||t.dispatch(t.state.tr.insertText(e).scrollIntoView()),n.preventDefault()}};const xh=wd?"metaKey":"ctrlKey";ah.mousedown=(t,e)=>{let n=e;t.input.shiftKey=n.shiftKey;let r=wh(t),i=Date.now(),o="singleClick";i-t.input.lastClick.time<500&&function(t,e){let n=e.x-t.clientX,r=e.y-t.clientY;return n*n+r*r<100}(n,t.input.lastClick)&&!n[xh]&&("singleClick"==t.input.lastClick.type?o="doubleClick":"doubleClick"==t.input.lastClick.type&&(o="tripleClick")),t.input.lastClick={time:i,x:n.clientX,y:n.clientY,type:o};let s=t.posAtCoords(ph(n));s&&("singleClick"==o?(t.input.mouseDown&&t.input.mouseDown.done(),t.input.mouseDown=new Sh(t,s,n,!!r)):("doubleClick"==o?yh:bh)(t,s.pos,s.inside,n)?n.preventDefault():uh(t,"pointer"))};class Sh{constructor(t,e,n,r){let i,o;if(this.view=t,this.pos=e,this.event=n,this.flushed=r,this.delayedSelectionSync=!1,this.mightDrag=null,this.startDoc=t.state.doc,this.selectNode=!!n[xh],this.allowDefault=n.shiftKey,e.inside>-1)i=t.state.doc.nodeAt(e.inside),o=e.inside;else{let n=t.state.doc.resolve(e.pos);i=n.parent,o=n.depth?n.before():0}const s=r?null:n.target,a=s?t.docView.nearestDesc(s,!0):null;this.target=a?a.dom:null;let{selection:l}=t.state;(0==n.button&&i.type.spec.draggable&&!1!==i.type.spec.selectable||l instanceof Wu&&l.from<=o&&l.to>o)&&(this.mightDrag={node:i,pos:o,addAttr:!(!this.target||this.target.draggable),setUneditable:!(!this.target||!pd||this.target.hasAttribute("contentEditable"))}),this.target&&this.mightDrag&&(this.mightDrag.addAttr||this.mightDrag.setUneditable)&&(this.view.domObserver.stop(),this.mightDrag.addAttr&&(this.target.draggable=!0),this.mightDrag.setUneditable&&setTimeout((()=>{this.view.input.mouseDown==this&&this.target.setAttribute("contentEditable","false")}),20),this.view.domObserver.start()),t.root.addEventListener("mouseup",this.up=this.up.bind(this)),t.root.addEventListener("mousemove",this.move=this.move.bind(this)),uh(t,"pointer")}done(){this.view.root.removeEventListener("mouseup",this.up),this.view.root.removeEventListener("mousemove",this.move),this.mightDrag&&this.target&&(this.view.domObserver.stop(),this.mightDrag.addAttr&&this.target.removeAttribute("draggable"),this.mightDrag.setUneditable&&this.target.removeAttribute("contentEditable"),this.view.domObserver.start()),this.delayedSelectionSync&&setTimeout((()=>Cf(this.view))),this.view.input.mouseDown=null}up(t){if(this.done(),!this.view.dom.contains(t.target))return;let e=this.pos;this.view.state.doc!=this.startDoc&&(e=this.view.posAtCoords(ph(t))),this.allowDefault||!e?uh(this.view,"pointer"):vh(this.view,e.pos,e.inside,t,this.selectNode)?t.preventDefault():0==t.button&&(this.flushed||yd&&this.mightDrag&&!this.mightDrag.node.isAtom||gd&&!(this.view.state.selection instanceof Bu)&&Math.min(Math.abs(e.pos-this.view.state.selection.from),Math.abs(e.pos-this.view.state.selection.to))<=2)?(gh(this.view,zu.near(this.view.state.doc.resolve(e.pos)),"pointer"),t.preventDefault()):uh(this.view,"pointer")}move(t){!this.allowDefault&&(Math.abs(this.event.x-t.clientX)>4||Math.abs(this.event.y-t.clientY)>4)&&(this.allowDefault=!0),uh(this.view,"pointer"),0==t.buttons&&this.done()}}function kh(t,e){return!!t.composing||!!(yd&&Math.abs(e.timeStamp-t.input.compositionEndedAt)<500)&&(t.input.compositionEndedAt=-2e8,!0)}ah.touchdown=t=>{wh(t),uh(t,"pointer")},ah.contextmenu=t=>wh(t);const Oh=xd?5e3:-1;function _h(t,e){clearTimeout(t.input.composingTimeout),e>-1&&(t.input.composingTimeout=setTimeout((()=>Ch(t)),e))}function Mh(t){for(t.composing&&(t.input.composing=!1,t.input.compositionEndedAt=function(){let t=document.createEvent("Event");return t.initEvent("event",!0,!0),t.timeStamp}());t.input.compositionNodes.length>0;)t.input.compositionNodes.pop().markParentsDirty()}function Ch(t,e=!1){if(!(xd&&t.domObserver.flushingSoon>=0)){if(t.domObserver.forceFlush(),Mh(t),e||t.docView&&t.docView.dirty){let e=_f(t);return e&&!e.eq(t.state.selection)?t.dispatch(t.state.tr.setSelection(e)):t.updateState(t.state),!0}return!1}}lh.compositionstart=lh.compositionupdate=t=>{if(!t.composing){t.domObserver.flush();let{state:e}=t,n=e.selection.$from;if(e.selection.empty&&(e.storedMarks||!n.textOffset&&n.parentOffset&&n.nodeBefore.marks.some((t=>!1===t.type.spec.inclusive))))t.markCursor=t.state.storedMarks||n.marks(),Ch(t,!0),t.markCursor=null;else if(Ch(t),pd&&e.selection.empty&&n.parentOffset&&!n.textOffset&&n.nodeBefore.marks.length){let e=t.domSelection();for(let t=e.focusNode,n=e.focusOffset;t&&1==t.nodeType&&0!=n;){let r=n<0?t.lastChild:t.childNodes[n-1];if(!r)break;if(3==r.nodeType){e.collapse(r,r.nodeValue.length);break}t=r,n=-1}}t.input.composing=!0}_h(t,Oh)},lh.compositionend=(t,e)=>{t.composing&&(t.input.composing=!1,t.input.compositionEndedAt=e.timeStamp,_h(t,20))};const $h=fd&&hd<15||bd&&kd<604;function Th(t,e,n,r){let i=Zf(t,e,n,t.input.shiftKey,t.state.selection.$from);if(t.someProp("handlePaste",(e=>e(t,r,i||ac.empty))))return!0;if(!i)return!1;let o=function(t){return 0==t.openStart&&0==t.openEnd&&1==t.content.childCount?t.content.firstChild:null}(i),s=o?t.state.tr.replaceSelectionWith(o,t.input.shiftKey):t.state.tr.replaceSelection(i);return t.dispatch(s.scrollIntoView().setMeta("paste",!0).setMeta("uiEvent","paste")),!0}ah.copy=lh.cut=(t,e)=>{let n=e,r=t.state.selection,i="cut"==n.type;if(r.empty)return;let o=$h?null:n.clipboardData,s=r.content(),{dom:a,text:l}=Gf(t,s);o?(n.preventDefault(),o.clearData(),o.setData("text/html",a.innerHTML),o.setData("text/plain",l)):function(t,e){if(!t.dom.parentNode)return;let n=t.dom.parentNode.appendChild(document.createElement("div"));n.appendChild(e),n.style.cssText="position: fixed; left: -10000px; top: 10px";let r=getSelection(),i=document.createRange();i.selectNodeContents(e),t.dom.blur(),r.removeAllRanges(),r.addRange(i),setTimeout((()=>{n.parentNode&&n.parentNode.removeChild(n),t.focus()}),50)}(t,a),i&&t.dispatch(t.state.tr.deleteSelection().scrollIntoView().setMeta("uiEvent","cut"))},lh.paste=(t,e)=>{let n=e;if(t.composing&&!xd)return;let r=$h?null:n.clipboardData;r&&Th(t,r.getData("text/plain"),r.getData("text/html"),n)?n.preventDefault():function(t,e){if(!t.dom.parentNode)return;let n=t.input.shiftKey||t.state.selection.$from.parent.type.spec.code,r=t.dom.parentNode.appendChild(document.createElement(n?"textarea":"div"));n||(r.contentEditable="true"),r.style.cssText="position: fixed; left: -10000px; top: 10px",r.focus(),setTimeout((()=>{t.focus(),r.parentNode&&r.parentNode.removeChild(r),n?Th(t,r.value,null,e):Th(t,r.textContent,r.innerHTML,e)}),50)}(t,n)};class Dh{constructor(t,e){this.slice=t,this.move=e}}const Nh=wd?"altKey":"ctrlKey";ah.dragstart=(t,e)=>{let n=e,r=t.input.mouseDown;if(r&&r.done(),!n.dataTransfer)return;let i=t.state.selection,o=i.empty?null:t.posAtCoords(ph(n));if(o&&o.pos>=i.from&&o.pos<=(i instanceof Wu?i.to-1:i.to));else if(r&&r.mightDrag)t.dispatch(t.state.tr.setSelection(Wu.create(t.state.doc,r.mightDrag.pos)));else if(n.target&&1==n.target.nodeType){let e=t.docView.nearestDesc(n.target,!0);e&&e.node.type.spec.draggable&&e!=t.docView&&t.dispatch(t.state.tr.setSelection(Wu.create(t.state.doc,e.posBefore)))}let s=t.state.selection.content(),{dom:a,text:l}=Gf(t,s);n.dataTransfer.clearData(),n.dataTransfer.setData($h?"Text":"text/html",a.innerHTML),n.dataTransfer.effectAllowed="copyMove",$h||n.dataTransfer.setData("text/plain",l),t.dragging=new Dh(s,!n[Nh])},ah.dragend=t=>{let e=t.dragging;window.setTimeout((()=>{t.dragging==e&&(t.dragging=null)}),50)},lh.dragover=lh.dragenter=(t,e)=>e.preventDefault(),lh.drop=(t,e)=>{let n=e,r=t.dragging;if(t.dragging=null,!n.dataTransfer)return;let i=t.posAtCoords(ph(n));if(!i)return;let o=t.state.doc.resolve(i.pos);if(!o)return;let s=r&&r.slice;s?t.someProp("transformPasted",(t=>{s=t(s)})):s=Zf(t,n.dataTransfer.getData($h?"Text":"text/plain"),$h?null:n.dataTransfer.getData("text/html"),!1,o);let a=!(!r||n[Nh]);if(t.someProp("handleDrop",(e=>e(t,n,s||ac.empty,a))))return void n.preventDefault();if(!s)return;n.preventDefault();let l=s?function(t,e,n){let r=t.resolve(e);if(!n.content.size)return e;let i=n.content;for(let o=0;o=0;t--){let e=t==r.depth?0:r.pos<=(r.start(t+1)+r.end(t+1))/2?-1:1,n=r.index(t)+(e>0?1:0),s=r.node(t),a=!1;if(1==o)a=s.canReplace(n,n,i);else{let t=s.contentMatchAt(n).findWrapping(i.firstChild.type);a=t&&s.canReplaceWith(n,n,t[0])}if(a)return 0==e?r.pos:e<0?r.before(t+1):r.after(t+1)}return null}(t.state.doc,o.pos,s):o.pos;null==l&&(l=o.pos);let c=t.state.tr;a&&c.deleteSelection();let u=c.mapping.map(l),d=0==s.openStart&&0==s.openEnd&&1==s.content.childCount,f=c.doc;if(d?c.replaceRangeWith(u,u,s.content.firstChild):c.replaceRange(u,u,s),c.doc.eq(f))return;let h=c.doc.resolve(u);if(d&&Wu.isSelectable(s.content.firstChild)&&h.nodeAfter&&h.nodeAfter.sameMarkup(s.content.firstChild))c.setSelection(new Wu(h));else{let e=c.mapping.map(l);c.mapping.maps[c.mapping.maps.length-1].forEach(((t,n,r,i)=>e=i)),c.setSelection(Pf(t,h,c.doc.resolve(e)))}t.focus(),t.dispatch(c.setMeta("uiEvent","drop"))},ah.focus=t=>{t.focused||(t.domObserver.stop(),t.dom.classList.add("ProseMirror-focused"),t.domObserver.start(),t.focused=!0,setTimeout((()=>{t.docView&&t.hasFocus()&&!t.domObserver.currentSelection.eq(t.domSelection())&&Cf(t)}),20))},ah.blur=(t,e)=>{let n=e;t.focused&&(t.domObserver.stop(),t.dom.classList.remove("ProseMirror-focused"),t.domObserver.start(),n.relatedTarget&&t.dom.contains(n.relatedTarget)&&t.domObserver.currentSelection.clear(),t.focused=!1)},ah.beforeinput=(t,e)=>{if(gd&&xd&&"deleteContentBackward"==e.inputType){t.domObserver.flushSoon();let{domChangeCount:e}=t.input;setTimeout((()=>{if(t.input.domChangeCount!=e)return;if(t.dom.blur(),t.focus(),t.someProp("handleKeyDown",(e=>e(t,Pd(8,"Backspace")))))return;let{$cursor:n}=t.state.selection;n&&n.pos>0&&t.dispatch(t.state.tr.delete(n.pos-1,n.pos).scrollIntoView())}),50)}};for(let os in lh)ah[os]=lh[os];function Ah(t,e){if(t==e)return!0;for(let n in t)if(t[n]!==e[n])return!1;for(let n in e)if(!(n in t))return!1;return!0}class Eh{constructor(t,e){this.toDOM=t,this.spec=e||jh,this.side=this.spec.side||0}map(t,e,n,r){let{pos:i,deleted:o}=t.mapResult(e.from+r,this.side<0?-1:1);return o?null:new Rh(i-n,i-n,this)}valid(){return!0}eq(t){return this==t||t instanceof Eh&&(this.spec.key&&this.spec.key==t.spec.key||this.toDOM==t.toDOM&&Ah(this.spec,t.spec))}destroy(t){this.spec.destroy&&this.spec.destroy(t)}}class Ph{constructor(t,e){this.attrs=t,this.spec=e||jh}map(t,e,n,r){let i=t.map(e.from+r,this.spec.inclusiveStart?-1:1)-n,o=t.map(e.to+r,this.spec.inclusiveEnd?1:-1)-n;return i>=o?null:new Rh(i,o,this)}valid(t,e){return e.from=t&&(!i||i(s.spec))&&n.push(s.copy(s.from+r,s.to+r))}for(let o=0;ot){let s=this.children[o]+1;this.children[o+2].findInner(t-s,e-s,n,r+s,i)}}map(t,e,n){return this==Lh||0==t.maps.length?this:this.mapInner(t,e,0,0,n||jh)}mapInner(t,e,n,r,i){let o;for(let s=0;s{for(let s=0;sc+o)continue;let u=a[s]+o;e>=u?a[s+1]=t<=u?-2:-1:n>=i&&(l=r-n-(e-t))&&(a[s]+=l,a[s+1]+=l)}};for(let u=0;u=r.content.size){c=!0;continue}let d=n.map(t[u+1]+o,-1)-i,{index:f,offset:h}=r.content.findIndex(l),p=r.maybeChild(f);if(p&&h==l&&h+p.nodeSize==d){let r=a[u+2].mapInner(n,p,e+1,t[u]+o+1,s);r!=Lh?(a[u]=l,a[u+1]=d,a[u+2]=r):(a[u+1]=-2,c=!0)}else c=!0}if(c){let l=function(t,e,n,r,i,o,s){function a(t,e){for(let o=0;o{let s,a=o+n;if(s=Wh(e,t,a)){for(r||(r=this.children.slice());io&&e.to=t){this.children[s]==t&&(n=this.children[s+2]);break}let i=t+1,o=i+e.content.size;for(let s=0;si&&t.type instanceof Ph){let e=Math.max(i,t.from)-i,n=Math.min(o,t.to)-i;en.map(t,e,jh)));return Bh.from(n)}forChild(t,e){if(e.isLeaf)return Fh.empty;let n=[];for(let r=0;rn&&o.to{let a=Wh(t,e,s+n);if(a){o=!0;let t=Jh(a,e,n+s+1,r);t!=Lh&&i.push(s,s+e.nodeSize,t)}}));let s=Vh(o?qh(t):t,-n).sort(Kh);for(let a=0;a0;)e++;t.splice(e,0,n)}function Yh(t){let e=[];return t.someProp("decorations",(n=>{let r=n(t.state);r&&r!=Lh&&e.push(r)})),t.cursorWrapper&&e.push(Fh.create(t.state.doc,[t.cursorWrapper.deco])),Bh.from(e)}const Gh={childList:!0,characterData:!0,characterDataOldValue:!0,attributes:!0,attributeOldValue:!0,subtree:!0},Zh=fd&&hd<=11;class Xh{constructor(){this.anchorNode=null,this.anchorOffset=0,this.focusNode=null,this.focusOffset=0}set(t){this.anchorNode=t.anchorNode,this.anchorOffset=t.anchorOffset,this.focusNode=t.focusNode,this.focusOffset=t.focusOffset}clear(){this.anchorNode=this.focusNode=null}eq(t){return t.anchorNode==this.anchorNode&&t.anchorOffset==this.anchorOffset&&t.focusNode==this.focusNode&&t.focusOffset==this.focusOffset}}class Qh{constructor(t,e){this.view=t,this.handleDOMChange=e,this.queue=[],this.flushingSoon=-1,this.observer=null,this.currentSelection=new Xh,this.onCharData=null,this.suppressingSelectionUpdates=!1,this.observer=window.MutationObserver&&new window.MutationObserver((t=>{for(let e=0;e"childList"==t.type&&t.removedNodes.length||"characterData"==t.type&&t.oldValue.length>t.target.nodeValue.length))?this.flushSoon():this.flush()})),Zh&&(this.onCharData=t=>{this.queue.push({target:t.target,type:"characterData",oldValue:t.prevValue}),this.flushSoon()}),this.onSelectionChange=this.onSelectionChange.bind(this)}flushSoon(){this.flushingSoon<0&&(this.flushingSoon=window.setTimeout((()=>{this.flushingSoon=-1,this.flush()}),20))}forceFlush(){this.flushingSoon>-1&&(window.clearTimeout(this.flushingSoon),this.flushingSoon=-1,this.flush())}start(){this.observer&&(this.observer.takeRecords(),this.observer.observe(this.view.dom,Gh)),this.onCharData&&this.view.dom.addEventListener("DOMCharacterDataModified",this.onCharData),this.connectSelection()}stop(){if(this.observer){let t=this.observer.takeRecords();if(t.length){for(let e=0;ethis.flush()),20)}this.observer.disconnect()}this.onCharData&&this.view.dom.removeEventListener("DOMCharacterDataModified",this.onCharData),this.disconnectSelection()}connectSelection(){this.view.dom.ownerDocument.addEventListener("selectionchange",this.onSelectionChange)}disconnectSelection(){this.view.dom.ownerDocument.removeEventListener("selectionchange",this.onSelectionChange)}suppressSelectionUpdates(){this.suppressingSelectionUpdates=!0,setTimeout((()=>this.suppressingSelectionUpdates=!1),50)}onSelectionChange(){if(If(this.view)){if(this.suppressingSelectionUpdates)return Cf(this.view);if(fd&&hd<=11&&!this.view.state.selection.empty){let t=this.view.domSelection();if(t.focusNode&&$d(t.focusNode,t.focusOffset,t.anchorNode,t.anchorOffset))return this.flushSoon()}this.flush()}}setCurSelection(){this.currentSelection.set(this.view.domSelection())}ignoreSelectionChange(t){if(0==t.rangeCount)return!0;let e=t.getRangeAt(0).commonAncestorContainer,n=this.view.docView.nearestDesc(e);return n&&n.ignoreMutation({type:"selection",target:3==e.nodeType?e.parentNode:e})?(this.setCurSelection(),!0):void 0}flush(){if(!this.view.docView||this.flushingSoon>-1)return;let t=this.observer?this.observer.takeRecords():[];this.queue.length&&(t=this.queue.concat(t),this.queue.length=0);let e=this.view.domSelection(),n=!this.suppressingSelectionUpdates&&!this.currentSelection.eq(e)&&If(this.view)&&!this.ignoreSelectionChange(e),r=-1,i=-1,o=!1,s=[];if(this.view.editable)for(let a=0;a1){let t=s.filter((t=>"BR"==t.nodeName));if(2==t.length){let e=t[0],n=t[1];e.parentNode&&e.parentNode.parentNode==n.parentNode?n.remove():e.remove()}}(r>-1||n)&&(r>-1&&(this.view.docView.markDirty(r,i),function(t){if(tp)return;tp=!0,"normal"==getComputedStyle(t.dom).whiteSpace&&console.warn("ProseMirror expects the CSS white-space property to be set, preferably to 'pre-wrap'. It is recommended to load style/prosemirror.css from the prosemirror-view package.")}(this.view)),this.handleDOMChange(r,i,o,s),this.view.docView&&this.view.docView.dirty?this.view.updateState(this.view.state):this.currentSelection.eq(e)||Cf(this.view),this.currentSelection.set(e))}registerMutation(t,e){if(e.indexOf(t.target)>-1)return null;let n=this.view.docView.nearestDesc(t.target);if("attributes"==t.type&&(n==this.view.docView||"contenteditable"==t.attributeName||"style"==t.attributeName&&!t.oldValue&&!t.target.getAttribute("style")))return null;if(!n||n.ignoreMutation(t))return null;if("childList"==t.type){for(let n=0;nDate.now()-50?t.input.lastSelectionOrigin:null,n=_f(t,e);if(n&&!t.state.selection.eq(n)){let r=t.state.tr.setSelection(n);"pointer"==e?r.setMeta("pointer",!0):"key"==e&&r.scrollIntoView(),t.dispatch(r)}return}let o=t.state.doc.resolve(e),s=o.sharedDepth(n);e=o.before(s+1),n=t.state.doc.resolve(n).after(s+1);let a=t.state.selection,l=function(t,e,n){let r,{node:i,fromOffset:o,toOffset:s,from:a,to:l}=t.docView.parseRange(e,n),c=t.domSelection(),u=c.anchorNode;if(u&&t.dom.contains(1==u.nodeType?u:u.parentNode)&&(r=[{node:u,offset:c.anchorOffset}],Ed(c)||r.push({node:c.focusNode,offset:c.focusOffset})),gd&&8===t.input.lastKeyCode)for(let g=s;g>o;g--){let t=i.childNodes[g-1],e=t.pmViewDesc;if("BR"==t.nodeName&&!e){s=g;break}if(!e||e.size)break}let d=t.state.doc,f=t.someProp("domParser")||Jc.fromSchema(t.state.schema),h=d.resolve(a),p=null,m=f.parse(i,{topNode:h.parent,topMatch:h.parent.contentMatchAt(h.index()),topOpen:!0,from:o,to:s,preserveWhitespace:"pre"!=h.parent.type.whitespace||"full",findPositions:r,ruleFromNode:ep,context:h});if(r&&null!=r[0].pos){let t=r[0].pos,e=r[1]&&r[1].pos;null==e&&(e=t),p={anchor:t+a,head:e+a}}return{doc:m,sel:p,from:a,to:l}}(t,e,n);if(gd&&t.cursorWrapper&&l.sel&&l.sel.anchor==t.cursorWrapper.deco.from&&l.sel.head==l.sel.anchor){let e=t.cursorWrapper.deco.type.toDOM.nextSibling,n=e&&e.nodeValue?e.nodeValue.length:1;l.sel={anchor:l.sel.anchor+n,head:l.sel.anchor+n}}let c,u,d=t.state.doc,f=d.slice(l.from,l.to);8===t.input.lastKeyCode&&Date.now()-100=s?o-r:0,a=o+(a-s),s=o}else if(a=a?o-r:0,s=o+(s-a),a=o}return{start:o,endA:s,endB:a}}(f.content,l.doc.content,l.from,c,u);if((bd&&t.input.lastIOSEnter>Date.now()-225||xd)&&i.some((t=>"DIV"==t.nodeName||"P"==t.nodeName))&&(!h||h.endA>=h.endB)&&t.someProp("handleKeyDown",(e=>e(t,Pd(13,"Enter")))))return void(t.input.lastIOSEnter=0);if(!h){if(!(r&&a instanceof Bu&&!a.empty&&a.$head.sameParent(a.$anchor))||t.composing||l.sel&&l.sel.anchor!=l.sel.head){if(l.sel){let e=rp(t,t.state.doc,l.sel);e&&!e.eq(t.state.selection)&&t.dispatch(t.state.tr.setSelection(e))}return}h={start:a.from,endA:a.to,endB:a.to}}t.input.domChangeCount++,t.state.selection.fromt.state.selection.from&&h.start<=t.state.selection.from+2&&t.state.selection.from>=l.from?h.start=t.state.selection.from:h.endA=t.state.selection.to-2&&t.state.selection.to<=l.to&&(h.endB+=t.state.selection.to-h.endA,h.endA=t.state.selection.to)),fd&&hd<=11&&h.endB==h.start+1&&h.endA==h.start&&h.start>l.from&&"  "==l.doc.textBetween(h.start-l.from-1,h.start-l.from+1)&&(h.start--,h.endA--,h.endB--);let p,m=l.doc.resolveNoCache(h.start-l.from),g=l.doc.resolveNoCache(h.endB-l.from),v=d.resolve(h.start),y=m.sameParent(g)&&m.parent.inlineContent&&v.end()>=h.endA;if((bd&&t.input.lastIOSEnter>Date.now()-225&&(!y||i.some((t=>"DIV"==t.nodeName||"P"==t.nodeName)))||!y&&m.pose(t,Pd(13,"Enter")))))return void(t.input.lastIOSEnter=0);if(t.state.selection.anchor>h.start&&function(t,e,n,r,i){if(!r.parent.isTextblock||n-e<=i.pos-r.pos||ip(r,!0,!1)n||ip(s,!0,!1)e(t,Pd(8,"Backspace")))))return void(xd&&gd&&t.domObserver.suppressSelectionUpdates());gd&&xd&&h.endB==h.start&&(t.input.lastAndroidDelete=Date.now()),xd&&!y&&m.start()!=g.start()&&0==g.parentOffset&&m.depth==g.depth&&l.sel&&l.sel.anchor==l.sel.head&&l.sel.head==h.endA&&(h.endB-=2,g=l.doc.resolveNoCache(h.endB-l.from),setTimeout((()=>{t.someProp("handleKeyDown",(function(e){return e(t,Pd(13,"Enter"))}))}),20));let b,w,x,S=h.start,k=h.endA;if(y)if(m.pos==g.pos)fd&&hd<=11&&0==m.parentOffset&&(t.domObserver.suppressSelectionUpdates(),setTimeout((()=>Cf(t)),20)),b=t.state.tr.delete(S,k),w=d.resolve(h.start).marksAcross(d.resolve(h.endA));else if(h.endA==h.endB&&(x=function(t,e){let n,r,i,o=t.firstChild.marks,s=e.firstChild.marks,a=o,l=s;for(let u=0;ut.mark(r.addToSet(t.marks));else{if(0!=a.length||1!=l.length)return null;r=l[0],n="remove",i=t=>t.mark(r.removeFromSet(t.marks))}let c=[];for(let u=0;un(t,S,k,e))))return;b=t.state.tr.insertText(e,S,k)}if(b||(b=t.state.tr.replace(S,k,l.doc.slice(h.start-l.from,h.endB-l.from))),l.sel){let e=rp(t,b.doc,l.sel);e&&!(gd&&xd&&t.composing&&e.empty&&(h.start!=h.endB||t.input.lastAndroidDeletee.content.size?null:Pf(t,e.resolve(n.anchor),e.resolve(n.head))}function ip(t,e,n){let r=t.depth,i=e?t.end():t.pos;for(;r>0&&(e||t.indexAfter(r)==t.node(r).childCount);)r--,i++,e=!1;if(n){let e=t.node(r).maybeChild(t.indexAfter(r));for(;e&&!e.isLeaf;)e=e.firstChild,i++}return i}class op{constructor(t,e){this._root=null,this.focused=!1,this.trackWrites=null,this.mounted=!1,this.markCursor=null,this.cursorWrapper=null,this.lastSelectedViewDesc=void 0,this.input=new ch,this.prevDirectPlugins=[],this.pluginViews=[],this.dragging=null,this._props=e,this.state=e.state,this.directPlugins=e.plugins||[],this.directPlugins.forEach(up),this.dispatch=this.dispatch.bind(this),this.dom=t&&t.mount||document.createElement("div"),t&&(t.appendChild?t.appendChild(this.dom):"function"==typeof t?t(this.dom):t.mount&&(this.mounted=!0)),this.editable=lp(this),ap(this),this.nodeViews=cp(this),this.docView=cf(this.state.doc,sp(this),Yh(this),this.dom,this),this.domObserver=new Qh(this,((t,e,n,r)=>np(this,t,e,n,r))),this.domObserver.start(),function(t){for(let e in ah){let n=ah[e];t.dom.addEventListener(e,t.input.eventHandlers[e]=e=>{!hh(t,e)||fh(t,e)||!t.editable&&e.type in lh||n(t,e)})}yd&&t.dom.addEventListener("input",(()=>null)),dh(t)}(this),this.updatePluginViews()}get composing(){return this.input.composing}get props(){if(this._props.state!=this.state){let t=this._props;this._props={};for(let e in t)this._props[e]=t[e];this._props.state=this.state}return this._props}update(t){t.handleDOMEvents!=this._props.handleDOMEvents&&dh(this),this._props=t,t.plugins&&(t.plugins.forEach(up),this.directPlugins=t.plugins),this.updateStateInner(t.state,!0)}setProps(t){let e={};for(let n in this._props)e[n]=this._props[n];e.state=this.state;for(let n in t)e[n]=t[n];this.update(e)}updateState(t){this.updateStateInner(t,this.state.plugins!=t.plugins)}updateStateInner(t,e){let n=this.state,r=!1,i=!1;if(t.storedMarks&&this.composing&&(Mh(this),i=!0),this.state=t,e){let t=cp(this);(function(t,e){let n=0,r=0;for(let i in t){if(t[i]!=e[i])return!0;n++}for(let i in e)r++;return n!=r})(t,this.nodeViews)&&(this.nodeViews=t,r=!0),dh(this)}this.editable=lp(this),ap(this);let o=Yh(this),s=sp(this),a=e?"reset":t.scrollToSelection>n.scrollToSelection?"to selection":"preserve",l=r||!this.docView.matchesNode(t.doc,s,o);!l&&t.selection.eq(n.selection)||(i=!0);let c="preserve"==a&&i&&null==this.dom.style.overflowAnchor&&function(t){let e,n,r=t.dom.getBoundingClientRect(),i=Math.max(0,r.top);for(let o=(r.left+r.right)/2,s=i+1;s=i-20){e=r,n=a.top;break}}return{refDOM:e,refTop:n,stack:Fd(t.dom)}}(this);if(i){this.domObserver.stop();let e=l&&(fd||gd)&&!this.composing&&!n.selection.empty&&!t.selection.empty&&function(t,e){let n=Math.min(t.$anchor.sharedDepth(t.head),e.$anchor.sharedDepth(e.head));return t.$anchor.start(n)!=e.$anchor.start(n)}(n.selection,t.selection);if(l){let n=gd?this.trackWrites=this.domSelection().focusNode:null;!r&&this.docView.update(t.doc,s,o,this)||(this.docView.updateOuterDeco([]),this.docView.destroy(),this.docView=cf(t.doc,s,o,this.dom,this)),n&&!this.trackWrites&&(e=!0)}e||!(this.input.mouseDown&&this.domObserver.currentSelection.eq(this.domSelection())&&function(t){let e=t.docView.domFromPos(t.state.selection.anchor,0),n=t.domSelection();return $d(e.node,e.offset,n.anchorNode,n.anchorOffset)}(this))?Cf(this,e):(Af(this,t.selection),this.domObserver.setCurSelection()),this.domObserver.start()}if(this.updatePluginViews(n),"reset"==a)this.dom.scrollTop=0;else if("to selection"==a){let e=this.domSelection().focusNode;if(this.someProp("handleScrollToSelection",(t=>t(this))));else if(t.selection instanceof Wu){let n=this.docView.domAfterPos(t.selection.from);1==n.nodeType&&jd(this,n.getBoundingClientRect(),e)}else jd(this,this.coordsAtPos(t.selection.head,1),e)}else c&&function({refDOM:t,refTop:e,stack:n}){let r=t?t.getBoundingClientRect().top:0;Ld(n,0==r?0:r-e)}(c)}destroyPluginViews(){let t;for(;t=this.pluginViews.pop();)t.destroy&&t.destroy()}updatePluginViews(t){if(t&&t.plugins==this.state.plugins&&this.directPlugins==this.prevDirectPlugins)for(let e=0;ee.ownerDocument.getSelection()),this._root=e;return t||document}posAtCoords(t){return Jd(this,t)}coordsAtPos(t,e=1){return Ud(this,t,e)}domAtPos(t,e=0){return this.docView.domFromPos(t,e)}nodeDOM(t){let e=this.docView.descAt(t);return e?e.nodeDOM:null}posAtDOM(t,e,n=-1){let r=this.docView.posFromDOM(t,e,n);if(null==r)throw new RangeError("DOM position not inside the editor");return r}endOfTextblock(t,e){return nf(this,e||this.state,t)}destroy(){this.docView&&(!function(t){t.domObserver.stop();for(let e in t.input.eventHandlers)t.dom.removeEventListener(e,t.input.eventHandlers[e]);clearTimeout(t.input.composingTimeout),clearTimeout(t.input.lastIOSEnterFallbackTimeout)}(this),this.destroyPluginViews(),this.mounted?(this.docView.update(this.state.doc,[],Yh(this),this),this.dom.textContent=""):this.dom.parentNode&&this.dom.parentNode.removeChild(this.dom),this.docView.destroy(),this.docView=null)}get isDestroyed(){return null==this.docView}dispatchEvent(t){return function(t,e){fh(t,e)||!ah[e.type]||!t.editable&&e.type in lh||ah[e.type](t,e)}(this,t)}dispatch(t){let e=this._props.dispatchTransaction;e?e.call(this,t):this.updateState(this.state.apply(t))}domSelection(){return this.root.getSelection()}}function sp(t){let e=Object.create(null);return e.class="ProseMirror",e.contenteditable=String(t.editable),e.translate="no",t.someProp("attributes",(n=>{if("function"==typeof n&&(n=n(t.state)),n)for(let t in n)"class"==t&&(e.class+=" "+n[t]),"style"==t?e.style=(e.style?e.style+";":"")+n[t]:e[t]||"contenteditable"==t||"nodeName"==t||(e[t]=String(n[t]))})),[Rh.node(0,t.state.doc.content.size,e)]}function ap(t){if(t.markCursor){let e=document.createElement("img");e.className="ProseMirror-separator",e.setAttribute("mark-placeholder","true"),e.setAttribute("alt",""),t.cursorWrapper={dom:e,deco:Rh.widget(t.state.selection.head,e,{raw:!0,marks:t.markCursor})}}else t.cursorWrapper=null}function lp(t){return!t.someProp("editable",(e=>!1===e(t.state)))}function cp(t){let e=Object.create(null);function n(t){for(let n in t)Object.prototype.hasOwnProperty.call(e,n)||(e[n]=t[n])}return t.someProp("nodeViews",n),t.someProp("markViews",n),e}function up(t){if(t.spec.state||t.spec.filterTransaction||t.spec.appendTransaction)throw new RangeError("Plugins passed directly to the view must not have a state component")}for(var dp={8:"Backspace",9:"Tab",10:"Enter",12:"NumLock",13:"Enter",16:"Shift",17:"Control",18:"Alt",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",44:"PrintScreen",45:"Insert",46:"Delete",59:";",61:"=",91:"Meta",92:"Meta",106:"*",107:"+",108:",",109:"-",110:".",111:"/",144:"NumLock",145:"ScrollLock",160:"Shift",161:"Shift",162:"Control",163:"Control",164:"Alt",165:"Alt",173:"-",186:";",187:"=",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",229:"q"},fp={48:")",49:"!",50:"@",51:"#",52:"$",53:"%",54:"^",55:"&",56:"*",57:"(",59:":",61:"+",173:"_",186:":",187:"+",188:"<",189:"_",190:">",191:"?",192:"~",219:"{",220:"|",221:"}",222:'"',229:"Q"},hp="undefined"!=typeof navigator&&/Chrome\/(\d+)/.exec(navigator.userAgent),pp="undefined"!=typeof navigator&&/Apple Computer/.test(navigator.vendor),mp="undefined"!=typeof navigator&&/Gecko\/\d+/.test(navigator.userAgent),gp="undefined"!=typeof navigator&&/Mac/.test(navigator.platform),vp="undefined"!=typeof navigator&&/MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent),yp=hp&&(gp||+hp[1]<57)||mp&&gp,bp=0;bp<10;bp++)dp[48+bp]=dp[96+bp]=String(bp);for(bp=1;bp<=24;bp++)dp[bp+111]="F"+bp;for(bp=65;bp<=90;bp++)dp[bp]=String.fromCharCode(bp+32),fp[bp]=String.fromCharCode(bp);for(var wp in dp)fp.hasOwnProperty(wp)||(fp[wp]=dp[wp]);const xp="undefined"!=typeof navigator&&/Mac|iP(hone|[oa]d)/.test(navigator.platform);function Sp(t){let e,n,r,i,o=t.split(/-(?!$)/),s=o[o.length-1];"Space"==s&&(s=" ");for(let a=0;a127)&&(r=dp[n.keyCode])&&r!=i){let i=e[kp(r,n,!0)];if(i&&i(t.state,t.dispatch,t))return!0}else if(o&&n.shiftKey){let r=e[kp(i,n,!0)];if(r&&r(t.state,t.dispatch,t))return!0}return!1}}const Mp=(t,e)=>!t.selection.empty&&(e&&e(t.tr.deleteSelection().scrollIntoView()),!0);function Cp(t,e,n=!1){for(let r=t;r;r="start"==e?r.firstChild:r.lastChild){if(r.isTextblock)return!0;if(n&&1!=r.childCount)return!1}return!1}function $p(t){if(!t.parent.type.spec.isolating)for(let e=t.depth-1;e>=0;e--){if(t.index(e)>0)return t.doc.resolve(t.before(e+1));if(t.node(e).type.spec.isolating)break}return null}function Tp(t){if(!t.parent.type.spec.isolating)for(let e=t.depth-1;e>=0;e--){let n=t.node(e);if(t.index(e)+1{let{$head:n,$anchor:r}=t.selection;if(!n.parent.type.spec.code||!n.sameParent(r))return!1;let i=n.node(-1),o=n.indexAfter(-1),s=Dp(i.contentMatchAt(o));if(!s||!i.canReplaceWith(o,o,s))return!1;if(e){let r=n.after(),i=t.tr.replaceWith(r,r,s.createAndFill());i.setSelection(zu.near(i.doc.resolve(r),1)),e(i.scrollIntoView())}return!0};function Ap(t,e,n){let r,i,o=e.nodeBefore,s=e.nodeAfter;if(o.type.spec.isolating||s.type.spec.isolating)return!1;if(function(t,e,n){let r=e.nodeBefore,i=e.nodeAfter,o=e.index();return!(!(r&&i&&r.type.compatibleContent(i.type))||(!r.content.size&&e.parent.canReplace(o-1,o)?(n&&n(t.tr.delete(e.pos-r.nodeSize,e.pos).scrollIntoView()),0):!e.parent.canReplace(o,o+1)||!i.isTextblock&&!ku(t.doc,e.pos)||(n&&n(t.tr.clearIncompatible(e.pos,r.type,r.contentMatchAt(r.childCount)).join(e.pos).scrollIntoView()),0)))}(t,e,n))return!0;let a=e.parent.canReplace(e.index(),e.index()+1);if(a&&(r=(i=o.contentMatchAt(o.childCount)).findWrapping(s.type))&&i.matchType(r[0]||s.type).validEnd){if(n){let i=e.pos+s.nodeSize,a=ec.empty;for(let t=r.length-1;t>=0;t--)a=ec.from(r[t].create(null,a));a=ec.from(o.copy(a));let l=t.tr.step(new gu(e.pos-1,i,e.pos,i,new ac(a,1,0),r.length,!0)),c=i+2*r.length;ku(l.doc,c)&&l.join(c),n(l.scrollIntoView())}return!0}let l=zu.findFrom(e,1),c=l&&l.$from.blockRange(l.$to),u=c&&bu(c);if(null!=u&&u>=e.depth)return n&&n(t.tr.lift(c,u).scrollIntoView()),!0;if(a&&Cp(s,"start",!0)&&Cp(o,"end")){let r=o,i=[];for(;i.push(r),!r.isTextblock;)r=r.lastChild;let a=s,l=1;for(;!a.isTextblock;a=a.firstChild)l++;if(r.canReplace(r.childCount,r.childCount,a.content)){if(n){let r=ec.empty;for(let t=i.length-1;t>=0;t--)r=ec.from(i[t].copy(r));n(t.tr.step(new gu(e.pos-i.length,e.pos+s.nodeSize,e.pos+l,e.pos+s.nodeSize-l,new ac(r,i.length,0),0,!0)).scrollIntoView())}return!0}}return!1}function Ep(t){return function(e,n){let r=e.selection,i=t<0?r.$from:r.$to,o=i.depth;for(;i.node(o).isInline;){if(!o)return!1;o--}return!!i.node(o).isTextblock&&(n&&n(e.tr.setSelection(Bu.create(e.doc,t<0?i.start(o):i.end(o)))),!0)}}const Pp=Ep(-1),Ip=Ep(1);function Rp(t,e=null){return function(n,r){let{from:i,to:o}=n.selection,s=!1;return n.doc.nodesBetween(i,o,((r,i)=>{if(s)return!1;if(r.isTextblock&&!r.hasMarkup(t,e))if(r.type==t)s=!0;else{let e=n.doc.resolve(i),r=e.index();s=e.parent.canReplaceWith(r,r+1,t)}})),!!s&&(r&&r(n.tr.setBlockType(i,o,t,e).scrollIntoView()),!0)}}function zp(t,e=null){return function(n,r){let{empty:i,$cursor:o,ranges:s}=n.selection;if(i&&!o||!function(t,e,n){for(let r=0;r{if(s)return!1;s=t.inlineContent&&t.type.allowsMarkType(n)})),s)return!0}return!1}(n.doc,s,t))return!1;if(r)if(o)t.isInSet(n.storedMarks||o.marks())?r(n.tr.removeStoredMark(t)):r(n.tr.addStoredMark(t.create(e)));else{let i=!1,o=n.tr;for(let e=0;!i&&e{let{$cursor:r}=t.selection;if(!r||(n?!n.endOfTextblock("backward",t):r.parentOffset>0))return!1;let i=$p(r);if(!i){let n=r.blockRange(),i=n&&bu(n);return null!=i&&(e&&e(t.tr.lift(n,i).scrollIntoView()),!0)}let o=i.nodeBefore;if(!o.type.spec.isolating&&Ap(t,i,e))return!0;if(0==r.parent.content.size&&(Cp(o,"end")||Wu.isSelectable(o))){let n=Ou(t.doc,r.before(),r.after(),ac.empty);if(n&&n.slice.size{let{$head:r,empty:i}=t.selection,o=r;if(!i)return!1;if(r.parent.isTextblock){if(n?!n.endOfTextblock("backward",t):r.parentOffset>0)return!1;o=$p(r)}let s=o&&o.nodeBefore;return!(!s||!Wu.isSelectable(s))&&(e&&e(t.tr.setSelection(Wu.create(t.doc,o.pos-s.nodeSize)).scrollIntoView()),!0)})),Lp=jp(Mp,((t,e,n)=>{let{$cursor:r}=t.selection;if(!r||(n?!n.endOfTextblock("forward",t):r.parentOffset{let{$head:r,empty:i}=t.selection,o=r;if(!i)return!1;if(r.parent.isTextblock){if(n?!n.endOfTextblock("forward",t):r.parentOffset{let{$head:n,$anchor:r}=t.selection;return!(!n.parent.type.spec.code||!n.sameParent(r))&&(e&&e(t.tr.insertText("\n").scrollIntoView()),!0)}),((t,e)=>{let n=t.selection,{$from:r,$to:i}=n;if(n instanceof Ju||r.parent.inlineContent||i.parent.inlineContent)return!1;let o=Dp(i.parent.contentMatchAt(i.indexAfter()));if(!o||!o.isTextblock)return!1;if(e){let n=(!r.parentOffset&&i.index(){let{$cursor:n}=t.selection;if(!n||n.parent.content.size)return!1;if(n.depth>1&&n.after()!=n.end(-1)){let r=n.before();if(Su(t.doc,r))return e&&e(t.tr.split(r).scrollIntoView()),!0}let r=n.blockRange(),i=r&&bu(r);return null!=i&&(e&&e(t.tr.lift(r,i).scrollIntoView()),!0)}),((t,e)=>{let{$from:n,$to:r}=t.selection;if(t.selection instanceof Wu&&t.selection.node.isBlock)return!(!n.parentOffset||!Su(t.doc,n.pos))&&(e&&e(t.tr.split(n.pos).scrollIntoView()),!0);if(!n.parent.isBlock)return!1;if(e){let i=r.parentOffset==r.parent.content.size,o=t.tr;(t.selection instanceof Bu||t.selection instanceof Ju)&&o.deleteSelection();let s=0==n.depth?null:Dp(n.node(-1).contentMatchAt(n.indexAfter(-1))),a=i&&s?[{type:s}]:void 0,l=Su(o.doc,o.mapping.map(n.pos),1,a);if(a||l||!Su(o.doc,o.mapping.map(n.pos),1,s?[{type:s}]:void 0)||(s&&(a=[{type:s}]),l=!0),l&&(o.split(o.mapping.map(n.pos),1,a),!i&&!n.parentOffset&&n.parent.type!=s)){let t=o.mapping.map(n.before()),e=o.doc.resolve(t);s&&n.node(-1).canReplaceWith(e.index(),e.index()+1,s)&&o.setNodeMarkup(o.mapping.map(n.before()),s)}e(o.scrollIntoView())}return!0})),"Mod-Enter":Np,Backspace:Fp,"Mod-Backspace":Fp,"Shift-Backspace":Fp,Delete:Lp,"Mod-Delete":Lp,"Mod-a":(t,e)=>(e&&e(t.tr.setSelection(new Ju(t.doc))),!0)},Vp={"Ctrl-h":Bp.Backspace,"Alt-Backspace":Bp["Mod-Backspace"],"Ctrl-d":Bp.Delete,"Ctrl-Alt-Backspace":Bp["Mod-Delete"],"Alt-Delete":Bp["Mod-Delete"],"Alt-d":Bp["Mod-Delete"],"Ctrl-a":Pp,"Ctrl-e":Ip};for(let os in Bp)Vp[os]=Bp[os];const Wp=("undefined"!=typeof navigator?/Mac|iP(hone|[oa]d)/.test(navigator.platform):!("undefined"==typeof os||!os.platform)&&"darwin"==os.platform())?Vp:Bp;class qp{constructor(t,e){var n;this.match=t,this.match=t,this.handler="string"==typeof e?(n=e,function(t,e,r,i){let o=n;if(e[1]){let t=e[0].lastIndexOf(e[1]);o+=e[0].slice(t+e[1].length);let n=(r+=t)-i;n>0&&(o=e[0].slice(t-n,t)+o,r=i)}return t.tr.insertText(o,r,i)}):e}}function Jp({rules:t}){let e=new nd({state:{init:()=>null,apply(t,e){let n=t.getMeta(this);return n||(t.selectionSet||t.docChanged?null:e)}},props:{handleTextInput:(n,r,i,o)=>Kp(n,r,i,o,t,e),handleDOMEvents:{compositionend:n=>{setTimeout((()=>{let{$cursor:r}=n.state.selection;r&&Kp(n,r.pos,r.pos,"",t,e)}))}}},isInputRules:!0});return e}function Kp(t,e,n,r,i,o){if(t.composing)return!1;let s=t.state,a=s.doc.resolve(e);if(a.parent.type.spec.code)return!1;let l=a.parent.textBetween(Math.max(0,a.parentOffset-500),a.parentOffset,null,"")+r;for(let c=0;c{let n=t.plugins;for(let r=0;r=0;t--)n.step(r.steps[t].invert(r.docs[t]));if(i.text){let e=n.doc.resolve(i.from).marks();n.replaceWith(i.from,i.to,t.schema.text(i.text,e))}else n.delete(i.from,i.to);e(n)}return!0}}return!1};function Up(t,e,n=null,r){return new qp(t,((t,i,o,s)=>{let a=n instanceof Function?n(i):n,l=t.tr.delete(o,s),c=l.doc.resolve(o).blockRange(),u=c&&wu(c,e,a);if(!u)return null;l.wrap(c,u);let d=l.doc.resolve(o-1).nodeBefore;return d&&d.type==e&&ku(l.doc,o-1)&&(!r||r(i,d))&&l.join(o-1),l}))}function Yp(t,e,n=null){return new qp(t,((t,r,i,o)=>{let s=t.doc.resolve(i),a=n instanceof Function?n(r):n;return s.node(-1).canReplaceWith(s.index(-1),s.indexAfter(-1),e)?t.tr.delete(i,o).setBlockType(i,i,e,a):null}))}new qp(/--$/,"—"),new qp(/\.\.\.$/,"…"),new qp(/(?:^|[\s\{\[\(\<'"\u2018\u201C])(")$/,"“"),new qp(/"$/,"”"),new qp(/(?:^|[\s\{\[\(\<'"\u2018\u201C])(')$/,"‘"),new qp(/'$/,"’");const Gp=["ol",0],Zp=["ul",0],Xp=["li",0],Qp={attrs:{order:{default:1}},parseDOM:[{tag:"ol",getAttrs:t=>({order:t.hasAttribute("start")?+t.getAttribute("start"):1})}],toDOM:t=>1==t.attrs.order?Gp:["ol",{start:t.attrs.order},0]},tm={parseDOM:[{tag:"ul"}],toDOM:()=>Zp},em={parseDOM:[{tag:"li"}],toDOM:()=>Xp,defining:!0};function nm(t,e){let n={};for(let r in t)n[r]=t[r];for(let r in e)n[r]=e[r];return n}function rm(t,e,n){return t.append({ordered_list:nm(Qp,{content:"list_item+",group:n}),bullet_list:nm(tm,{content:"list_item+",group:n}),list_item:nm(em,{content:e})})}function im(t,e=null){return function(n,r){let{$from:i,$to:o}=n.selection,s=i.blockRange(o),a=!1,l=s;if(!s)return!1;if(s.depth>=2&&i.node(s.depth-1).type.compatibleContent(t)&&0==s.startIndex){if(0==i.index(s.depth-1))return!1;let t=n.doc.resolve(s.start-2);l=new kc(t,t,s.depth),s.endIndex=0;u--)o=ec.from(n[u].type.create(n[u].attrs,o));t.step(new gu(e.start-(r?2:0),e.end,e.start,e.end,new ac(o,0,0),n.length,!0));let s=0;for(let u=0;u=r.depth-3;t--)i=ec.from(r.node(t).copy(i));let s=r.indexAfter(-1){if(c>-1)return!1;t.isTextblock&&0==t.content.size&&(c=e+1)})),c>-1&&l.setSelection(zu.near(l.doc.resolve(c))),n(l.scrollIntoView())}return!0}let a=i.pos==r.end()?s.contentMatchAt(0).defaultType:null,l=e.tr.delete(r.pos,i.pos),c=a?[null,{type:a}]:void 0;return!!Su(l.doc,r.pos,2,c)&&(n&&n(l.split(r.pos,2,c).scrollIntoView()),!0)}}function sm(t){return function(e,n){let{$from:r,$to:i}=e.selection,o=r.blockRange(i,(e=>e.childCount>0&&e.firstChild.type==t));return!!o&&(!n||(r.node(o.depth-1).type==t?function(t,e,n,r){let i=t.tr,o=r.end,s=r.$to.end(r.depth);om;p--)h-=i.child(p).nodeSize,r.delete(h-1,h+1);let o=r.doc.resolve(n.start),s=o.nodeAfter;if(r.mapping.map(n.end)!=n.start+o.nodeAfter.nodeSize)return!1;let a=0==n.startIndex,l=n.endIndex==i.childCount,c=o.node(-1),u=o.index(-1);if(!c.canReplace(u+(a?0:1),u+1,s.content.append(l?ec.empty:ec.from(i))))return!1;let d=o.pos,f=d+s.nodeSize;return r.step(new gu(d-(a?1:0),f+(l?1:0),d+1,f-1,new ac((a?ec.empty:ec.from(i.copy(ec.empty))).append(l?ec.empty:ec.from(i.copy(ec.empty))),a?0:1,l?0:1),a?0:1)),e(r.scrollIntoView()),!0}(e,n,o)))}}function am(t){return function(e,n){let{$from:r,$to:i}=e.selection,o=r.blockRange(i,(e=>e.childCount>0&&e.firstChild.type==t));if(!o)return!1;let s=o.startIndex;if(0==s)return!1;let a=o.parent,l=a.child(s-1);if(l.type!=t)return!1;if(n){let r=l.lastChild&&l.lastChild.type==a.type,i=ec.from(r?t.create():null),s=new ac(ec.from(t.create(null,ec.from(a.type.create(null,i)))),r?3:1,0),c=o.start,u=o.end;n(e.tr.step(new gu(c-(r?3:1),u,c,u,s,1,!0)).scrollIntoView())}return!0}}var lm=function(){};lm.prototype.append=function(t){return t.length?(t=lm.from(t),!this.length&&t||t.length<200&&this.leafAppend(t)||this.length<200&&t.leafPrepend(this)||this.appendInner(t)):this},lm.prototype.prepend=function(t){return t.length?lm.from(t).append(this):this},lm.prototype.appendInner=function(t){return new um(this,t)},lm.prototype.slice=function(t,e){return void 0===t&&(t=0),void 0===e&&(e=this.length),t>=e?lm.empty:this.sliceInner(Math.max(0,t),Math.min(this.length,e))},lm.prototype.get=function(t){if(!(t<0||t>=this.length))return this.getInner(t)},lm.prototype.forEach=function(t,e,n){void 0===e&&(e=0),void 0===n&&(n=this.length),e<=n?this.forEachInner(t,e,n,0):this.forEachInvertedInner(t,e,n,0)},lm.prototype.map=function(t,e,n){void 0===e&&(e=0),void 0===n&&(n=this.length);var r=[];return this.forEach((function(e,n){return r.push(t(e,n))}),e,n),r},lm.from=function(t){return t instanceof lm?t:t&&t.length?new cm(t):lm.empty};var cm=function(t){function e(e){t.call(this),this.values=e}t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e;var n={length:{configurable:!0},depth:{configurable:!0}};return e.prototype.flatten=function(){return this.values},e.prototype.sliceInner=function(t,n){return 0==t&&n==this.length?this:new e(this.values.slice(t,n))},e.prototype.getInner=function(t){return this.values[t]},e.prototype.forEachInner=function(t,e,n,r){for(var i=e;i=n;i--)if(!1===t(this.values[i],r+i))return!1},e.prototype.leafAppend=function(t){if(this.length+t.length<=200)return new e(this.values.concat(t.flatten()))},e.prototype.leafPrepend=function(t){if(this.length+t.length<=200)return new e(t.flatten().concat(this.values))},n.length.get=function(){return this.values.length},n.depth.get=function(){return 0},Object.defineProperties(e.prototype,n),e}(lm);lm.empty=new cm([]);var um=function(t){function e(e,n){t.call(this),this.left=e,this.right=n,this.length=e.length+n.length,this.depth=Math.max(e.depth,n.depth)+1}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.flatten=function(){return this.left.flatten().concat(this.right.flatten())},e.prototype.getInner=function(t){return ti&&!1===this.right.forEachInner(t,Math.max(e-i,0),Math.min(this.length,n)-i,r+i))&&void 0)},e.prototype.forEachInvertedInner=function(t,e,n,r){var i=this.left.length;return!(e>i&&!1===this.right.forEachInvertedInner(t,e-i,Math.max(n,i)-i,r+i))&&(!(n=n?this.right.slice(t-n,e-n):this.left.slice(t,n).append(this.right.slice(0,e-n))},e.prototype.leafAppend=function(t){var n=this.right.leafAppend(t);if(n)return new e(this.left,n)},e.prototype.leafPrepend=function(t){var n=this.left.leafPrepend(t);if(n)return new e(n,this.right)},e.prototype.appendInner=function(t){return this.left.depth>=Math.max(this.right.depth,t.depth)+1?new e(this.left,new e(this.right,t)):new e(this,t)},e}(lm),dm=lm;class fm{constructor(t,e){this.items=t,this.eventCount=e}popEvent(t,e){if(0==this.eventCount)return null;let n,r,i=this.items.length;for(;;i--){if(this.items.get(i-1).selection){--i;break}}e&&(n=this.remapping(i,this.items.length),r=n.maps.length);let o,s,a=t.tr,l=[],c=[];return this.items.forEach(((t,e)=>{if(!t.step)return n||(n=this.remapping(i,e+1),r=n.maps.length),r--,void c.push(t);if(n){c.push(new hm(t.map));let e,i=t.step.map(n.slice(r));i&&a.maybeStep(i).doc&&(e=a.mapping.maps[a.mapping.maps.length-1],l.push(new hm(e,void 0,void 0,l.length+c.length))),r--,e&&n.appendMap(e,r)}else a.maybeStep(t.step);return t.selection?(o=n?t.selection.map(n.slice(r)):t.selection,s=new fm(this.items.slice(0,i).append(c.reverse().concat(l)),this.eventCount-1),!1):void 0}),this.items.length,0),{remaining:s,transform:a,selection:o}}addTransform(t,e,n,r){let i=[],o=this.eventCount,s=this.items,a=!r&&s.length?s.get(s.length-1):null;for(let c=0;cmm&&(s=function(t,e){let n;return t.forEach(((t,r)=>{if(t.selection&&0==e--)return n=r,!1})),t.slice(n)}(s,l),o-=l),new fm(s.append(i),o)}remapping(t,e){let n=new lu;return this.items.forEach(((e,r)=>{let i=null!=e.mirrorOffset&&r-e.mirrorOffset>=t?n.maps.length-e.mirrorOffset:void 0;n.appendMap(e.map,i)}),t,e),n}addMaps(t){return 0==this.eventCount?this:new fm(this.items.append(t.map((t=>new hm(t)))),this.eventCount)}rebased(t,e){if(!this.eventCount)return this;let n=[],r=Math.max(0,this.items.length-e),i=t.mapping,o=t.steps.length,s=this.eventCount;this.items.forEach((t=>{t.selection&&s--}),r);let a=e;this.items.forEach((e=>{let r=i.getMirror(--a);if(null==r)return;o=Math.min(o,r);let l=i.maps[r];if(e.step){let o=t.steps[r].invert(t.docs[r]),c=e.selection&&e.selection.map(i.slice(a+1,r));c&&s++,n.push(new hm(l,o,c))}else n.push(new hm(l))}),r);let l=[];for(let d=e;d500&&(u=u.compress(this.items.length-n.length)),u}emptyItemCount(){let t=0;return this.items.forEach((e=>{e.step||t++})),t}compress(t=this.items.length){let e=this.remapping(0,t),n=e.maps.length,r=[],i=0;return this.items.forEach(((o,s)=>{if(s>=t)r.push(o),o.selection&&i++;else if(o.step){let t=o.step.map(e.slice(n)),s=t&&t.getMap();if(n--,s&&e.appendMap(s,n),t){let a=o.selection&&o.selection.map(e.slice(n));a&&i++;let l,c=new hm(s.invert(),t,a),u=r.length-1;(l=r.length&&r[u].merge(c))?r[u]=l:r.push(c)}}else o.map&&n--}),this.items.length,0),new fm(dm.from(r.reverse()),i)}}fm.empty=new fm(dm.empty,0);class hm{constructor(t,e,n,r){this.map=t,this.step=e,this.selection=n,this.mirrorOffset=r}merge(t){if(this.step&&t.step&&!t.selection){let e=t.step.merge(this.step);if(e)return new hm(e.getMap().invert(),e,this.selection)}}}class pm{constructor(t,e,n,r){this.done=t,this.undone=e,this.prevRanges=n,this.prevTime=r}}const mm=20;function gm(t){let e=[];return t.forEach(((t,n,r,i)=>e.push(r,i))),e}function vm(t,e){if(!t)return null;let n=[];for(let r=0;rnew pm(fm.empty,fm.empty,null,0),apply:(e,n,r)=>function(t,e,n,r){let i,o=n.getMeta(Sm);if(o)return o.historyState;n.getMeta(km)&&(t=new pm(t.done,t.undone,null,0));let s=n.getMeta("appendedTransaction");if(0==n.steps.length)return t;if(s&&s.getMeta(Sm))return s.getMeta(Sm).redo?new pm(t.done.addTransform(n,void 0,r,xm(e)),t.undone,gm(n.mapping.maps[n.steps.length-1]),t.prevTime):new pm(t.done,t.undone.addTransform(n,void 0,r,xm(e)),null,t.prevTime);if(!1===n.getMeta("addToHistory")||s&&!1===s.getMeta("addToHistory"))return(i=n.getMeta("rebased"))?new pm(t.done.rebased(n,i),t.undone.rebased(n,i),vm(t.prevRanges,n.mapping),t.prevTime):new pm(t.done.addMaps(n.mapping.maps),t.undone.addMaps(n.mapping.maps),vm(t.prevRanges,n.mapping),t.prevTime);{let i=0==t.prevTime||!s&&(t.prevTime<(n.time||0)-r.newGroupDelay||!function(t,e){if(!e)return!1;if(!t.docChanged)return!0;let n=!1;return t.mapping.maps[0].forEach(((t,r)=>{for(let i=0;i=e[i]&&(n=!0)})),n}(n,t.prevRanges)),o=s?vm(t.prevRanges,n.mapping):gm(n.mapping.maps[n.steps.length-1]);return new pm(t.done.addTransform(n,i?e.selection.getBookmark():void 0,r,xm(e)),fm.empty,o,n.time)}}(n,r,e,t)},config:t,props:{handleDOMEvents:{beforeinput(t,e){let n=e.inputType,r="historyUndo"==n?_m:"historyRedo"==n?Mm:null;return!!r&&(e.preventDefault(),r(t.state,t.dispatch))}}}})}const _m=(t,e)=>{let n=Sm.getState(t);return!(!n||0==n.done.eventCount)&&(e&&ym(n,t,e,!1),!0)},Mm=(t,e)=>{let n=Sm.getState(t);return!(!n||0==n.undone.eventCount)&&(e&&ym(n,t,e,!0),!0)};function Cm(t){let e=Sm.getState(t);return e?e.done.eventCount:0}function $m(t){let e=Sm.getState(t);return e?e.undone.eventCount:0}var Tm={},Dm={},Nm={},Am={};Object.defineProperty(Am,"__esModule",{value:!0}),Am.default=void 0;var Em=Ll.withParams;Am.default=Em,function(t){Object.defineProperty(t,"__esModule",{value:!0}),t.req=t.regex=t.ref=t.len=void 0,Object.defineProperty(t,"withParams",{enumerable:!0,get:function(){return n.default}});var e,n=(e=Am)&&e.__esModule?e:{default:e};function r(t){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}var i=function(t){if(Array.isArray(t))return!!t.length;if(null==t)return!1;if(!1===t)return!0;if(t instanceof Date)return!isNaN(t.getTime());if("object"===r(t)){for(var e in t)return!0;return!1}return!!String(t).length};t.req=i;t.len=function(t){return Array.isArray(t)?t.length:"object"===r(t)?Object.keys(t).length:String(t).length};t.ref=function(t,e,n){return"function"==typeof t?t.call(e,n):n[t]};t.regex=function(t,e){return(0,n.default)({type:t},(function(t){return!i(t)||e.test(t)}))}}(Nm),Object.defineProperty(Dm,"__esModule",{value:!0}),Dm.default=void 0;var Pm=(0,Nm.regex)("alpha",/^[a-zA-Z]*$/);Dm.default=Pm;var Im={};Object.defineProperty(Im,"__esModule",{value:!0}),Im.default=void 0;var Rm=(0,Nm.regex)("alphaNum",/^[a-zA-Z0-9]*$/);Im.default=Rm;var zm={};Object.defineProperty(zm,"__esModule",{value:!0}),zm.default=void 0;var jm=(0,Nm.regex)("numeric",/^[0-9]*$/);zm.default=jm;var Fm={};Object.defineProperty(Fm,"__esModule",{value:!0}),Fm.default=void 0;var Lm=Nm;Fm.default=function(t,e){return(0,Lm.withParams)({type:"between",min:t,max:e},(function(n){return!(0,Lm.req)(n)||(!/\s/.test(n)||n instanceof Date)&&+t<=+n&&+e>=+n}))};var Bm={};Object.defineProperty(Bm,"__esModule",{value:!0}),Bm.default=void 0;var Vm=(0,Nm.regex)("email",/^(?:[A-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9]{2,}(?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])$/i);Bm.default=Vm;var Wm={};Object.defineProperty(Wm,"__esModule",{value:!0}),Wm.default=void 0;var qm=Nm,Jm=(0,qm.withParams)({type:"ipAddress"},(function(t){if(!(0,qm.req)(t))return!0;if("string"!=typeof t)return!1;var e=t.split(".");return 4===e.length&&e.every(Km)}));Wm.default=Jm;var Km=function(t){if(t.length>3||0===t.length)return!1;if("0"===t[0]&&"0"!==t)return!1;if(!t.match(/^\d+$/))return!1;var e=0|+t;return e>=0&&e<=255},Hm={};Object.defineProperty(Hm,"__esModule",{value:!0}),Hm.default=void 0;var Um=Nm;Hm.default=function(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:":";return(0,Um.withParams)({type:"macAddress"},(function(e){if(!(0,Um.req)(e))return!0;if("string"!=typeof e)return!1;var n="string"==typeof t&&""!==t?e.split(t):12===e.length||16===e.length?e.match(/.{2}/g):null;return null!==n&&(6===n.length||8===n.length)&&n.every(Ym)}))};var Ym=function(t){return t.toLowerCase().match(/^[0-9a-f]{2}$/)},Gm={};Object.defineProperty(Gm,"__esModule",{value:!0}),Gm.default=void 0;var Zm=Nm;Gm.default=function(t){return(0,Zm.withParams)({type:"maxLength",max:t},(function(e){return!(0,Zm.req)(e)||(0,Zm.len)(e)<=t}))};var Xm={};Object.defineProperty(Xm,"__esModule",{value:!0}),Xm.default=void 0;var Qm=Nm;Xm.default=function(t){return(0,Qm.withParams)({type:"minLength",min:t},(function(e){return!(0,Qm.req)(e)||(0,Qm.len)(e)>=t}))};var tg={};Object.defineProperty(tg,"__esModule",{value:!0}),tg.default=void 0;var eg=Nm,ng=(0,eg.withParams)({type:"required"},(function(t){return(0,eg.req)("string"==typeof t?t.trim():t)}));tg.default=ng;var rg={};Object.defineProperty(rg,"__esModule",{value:!0}),rg.default=void 0;var ig=Nm;rg.default=function(t){return(0,ig.withParams)({type:"requiredIf",prop:t},(function(e,n){return!(0,ig.ref)(t,this,n)||(0,ig.req)(e)}))};var og={};Object.defineProperty(og,"__esModule",{value:!0}),og.default=void 0;var sg=Nm;og.default=function(t){return(0,sg.withParams)({type:"requiredUnless",prop:t},(function(e,n){return!!(0,sg.ref)(t,this,n)||(0,sg.req)(e)}))};var ag={};Object.defineProperty(ag,"__esModule",{value:!0}),ag.default=void 0;var lg=Nm;ag.default=function(t){return(0,lg.withParams)({type:"sameAs",eq:t},(function(e,n){return e===(0,lg.ref)(t,this,n)}))};var cg={};Object.defineProperty(cg,"__esModule",{value:!0}),cg.default=void 0;var ug=(0,Nm.regex)("url",/^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z0-9\u00a1-\uffff][a-z0-9\u00a1-\uffff_-]{0,62})?[a-z0-9\u00a1-\uffff]\.)+(?:[a-z\u00a1-\uffff]{2,}\.?))(?::\d{2,5})?(?:[/?#]\S*)?$/i);cg.default=ug;var dg={};Object.defineProperty(dg,"__esModule",{value:!0}),dg.default=void 0;var fg=Nm;dg.default=function(){for(var t=arguments.length,e=new Array(t),n=0;n0&&e.reduce((function(e,n){return e||n.apply(t,r)}),!1)}))};var hg={};Object.defineProperty(hg,"__esModule",{value:!0}),hg.default=void 0;var pg=Nm;hg.default=function(){for(var t=arguments.length,e=new Array(t),n=0;n0&&e.reduce((function(e,n){return e&&n.apply(t,r)}),!0)}))};var mg={};Object.defineProperty(mg,"__esModule",{value:!0}),mg.default=void 0;var gg=Nm;mg.default=function(t){return(0,gg.withParams)({type:"not"},(function(e,n){return!(0,gg.req)(e)||!t.call(this,e,n)}))};var vg={};Object.defineProperty(vg,"__esModule",{value:!0}),vg.default=void 0;var yg=Nm;vg.default=function(t){return(0,yg.withParams)({type:"minValue",min:t},(function(e){return!(0,yg.req)(e)||(!/\s/.test(e)||e instanceof Date)&&+e>=+t}))};var bg={};Object.defineProperty(bg,"__esModule",{value:!0}),bg.default=void 0;var wg=Nm;bg.default=function(t){return(0,wg.withParams)({type:"maxValue",max:t},(function(e){return!(0,wg.req)(e)||(!/\s/.test(e)||e instanceof Date)&&+e<=+t}))};var xg={};Object.defineProperty(xg,"__esModule",{value:!0}),xg.default=void 0;var Sg=(0,Nm.regex)("integer",/(^[0-9]*$)|(^-[0-9]+$)/);xg.default=Sg;var kg={};Object.defineProperty(kg,"__esModule",{value:!0}),kg.default=void 0;var Og=(0,Nm.regex)("decimal",/^[-]?\d*(\.\d+)?$/);kg.default=Og,function(t){function e(t){return(e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}Object.defineProperty(t,"__esModule",{value:!0}),Object.defineProperty(t,"alpha",{enumerable:!0,get:function(){return n.default}}),Object.defineProperty(t,"alphaNum",{enumerable:!0,get:function(){return r.default}}),Object.defineProperty(t,"and",{enumerable:!0,get:function(){return v.default}}),Object.defineProperty(t,"between",{enumerable:!0,get:function(){return o.default}}),Object.defineProperty(t,"decimal",{enumerable:!0,get:function(){return S.default}}),Object.defineProperty(t,"email",{enumerable:!0,get:function(){return s.default}}),t.helpers=void 0,Object.defineProperty(t,"integer",{enumerable:!0,get:function(){return x.default}}),Object.defineProperty(t,"ipAddress",{enumerable:!0,get:function(){return a.default}}),Object.defineProperty(t,"macAddress",{enumerable:!0,get:function(){return l.default}}),Object.defineProperty(t,"maxLength",{enumerable:!0,get:function(){return c.default}}),Object.defineProperty(t,"maxValue",{enumerable:!0,get:function(){return w.default}}),Object.defineProperty(t,"minLength",{enumerable:!0,get:function(){return u.default}}),Object.defineProperty(t,"minValue",{enumerable:!0,get:function(){return b.default}}),Object.defineProperty(t,"not",{enumerable:!0,get:function(){return y.default}}),Object.defineProperty(t,"numeric",{enumerable:!0,get:function(){return i.default}}),Object.defineProperty(t,"or",{enumerable:!0,get:function(){return g.default}}),Object.defineProperty(t,"required",{enumerable:!0,get:function(){return d.default}}),Object.defineProperty(t,"requiredIf",{enumerable:!0,get:function(){return f.default}}),Object.defineProperty(t,"requiredUnless",{enumerable:!0,get:function(){return h.default}}),Object.defineProperty(t,"sameAs",{enumerable:!0,get:function(){return p.default}}),Object.defineProperty(t,"url",{enumerable:!0,get:function(){return m.default}});var n=_(Dm),r=_(Im),i=_(zm),o=_(Fm),s=_(Bm),a=_(Wm),l=_(Hm),c=_(Gm),u=_(Xm),d=_(tg),f=_(rg),h=_(og),p=_(ag),m=_(cg),g=_(dg),v=_(hg),y=_(mg),b=_(vg),w=_(bg),x=_(xg),S=_(kg),k=function(t,n){if(!n&&t&&t.__esModule)return t;if(null===t||"object"!==e(t)&&"function"!=typeof t)return{default:t};var r=O(n);if(r&&r.has(t))return r.get(t);var i={},o=Object.defineProperty&&Object.getOwnPropertyDescriptor;for(var s in t)if("default"!==s&&Object.prototype.hasOwnProperty.call(t,s)){var a=o?Object.getOwnPropertyDescriptor(t,s):null;a&&(a.get||a.set)?Object.defineProperty(i,s,a):i[s]=t[s]}i.default=t,r&&r.set(t,i);return i}(Nm);function O(t){if("function"!=typeof WeakMap)return null;var e=new WeakMap,n=new WeakMap;return(O=function(t){return t?n:e})(t)}function _(t){return t&&t.__esModule?t:{default:t}}t.helpers=k}(Tm);export{$m as A,Om as B,Tm as C,Jc as D,td as E,ec as F,Tl as G,Zl as H,qp as I,Wu as N,nd as P,ac as S,Bu as T,Wn as V,ll as a,vl as b,Sl as c,wl as d,jp as e,Np as f,Up as g,Yp as h,rm as i,om as j,am as k,sm as l,cl as m,Op as n,Wc as o,Jp as p,op as q,eu as r,Rp as s,zp as t,Hp as u,Wp as v,im as w,_m as x,Mm as y,Cm as z}; + */;var Tm=("undefined"!=typeof window?window:"undefined"!=typeof global?global:{}).__VUE_DEVTOOLS_GLOBAL_HOOK__;function Dm(t,e){if(void 0===e&&(e=[]),null===t||"object"!=typeof t)return t;var n,r=(n=function(e){return e.original===t},e.filter(n)[0]);if(r)return r.copy;var i=Array.isArray(t)?[]:{};return e.push({original:t,copy:i}),Object.keys(t).forEach((function(n){i[n]=Dm(t[n],e)})),i}function Am(t,e){Object.keys(t).forEach((function(n){return e(t[n],n)}))}function Em(t){return null!==t&&"object"==typeof t}var Pm=function(t,e){this.runtime=e,this._children=Object.create(null),this._rawModule=t;var n=t.state;this.state=("function"==typeof n?n():n)||{}},Im={namespaced:{configurable:!0}};Im.namespaced.get=function(){return!!this._rawModule.namespaced},Pm.prototype.addChild=function(t,e){this._children[t]=e},Pm.prototype.removeChild=function(t){delete this._children[t]},Pm.prototype.getChild=function(t){return this._children[t]},Pm.prototype.hasChild=function(t){return t in this._children},Pm.prototype.update=function(t){this._rawModule.namespaced=t.namespaced,t.actions&&(this._rawModule.actions=t.actions),t.mutations&&(this._rawModule.mutations=t.mutations),t.getters&&(this._rawModule.getters=t.getters)},Pm.prototype.forEachChild=function(t){Am(this._children,t)},Pm.prototype.forEachGetter=function(t){this._rawModule.getters&&Am(this._rawModule.getters,t)},Pm.prototype.forEachAction=function(t){this._rawModule.actions&&Am(this._rawModule.actions,t)},Pm.prototype.forEachMutation=function(t){this._rawModule.mutations&&Am(this._rawModule.mutations,t)},Object.defineProperties(Pm.prototype,Im);var Rm,zm=function(t){this.register([],t,!1)};function jm(t,e,n){if(e.update(n),n.modules)for(var r in n.modules){if(!e.getChild(r))return;jm(t.concat(r),e.getChild(r),n.modules[r])}}zm.prototype.get=function(t){return t.reduce((function(t,e){return t.getChild(e)}),this.root)},zm.prototype.getNamespace=function(t){var e=this.root;return t.reduce((function(t,n){return t+((e=e.getChild(n)).namespaced?n+"/":"")}),"")},zm.prototype.update=function(t){jm([],this.root,t)},zm.prototype.register=function(t,e,n){var r=this;void 0===n&&(n=!0);var i=new Pm(e,n);0===t.length?this.root=i:this.get(t.slice(0,-1)).addChild(t[t.length-1],i);e.modules&&Am(e.modules,(function(e,i){r.register(t.concat(i),e,n)}))},zm.prototype.unregister=function(t){var e=this.get(t.slice(0,-1)),n=t[t.length-1],r=e.getChild(n);r&&r.runtime&&e.removeChild(n)},zm.prototype.isRegistered=function(t){var e=this.get(t.slice(0,-1)),n=t[t.length-1];return!!e&&e.hasChild(n)};var Fm=function(t){var e=this;void 0===t&&(t={}),!Rm&&"undefined"!=typeof window&&window.Vue&&Km(window.Vue);var n=t.plugins;void 0===n&&(n=[]);var r=t.strict;void 0===r&&(r=!1),this._committing=!1,this._actions=Object.create(null),this._actionSubscribers=[],this._mutations=Object.create(null),this._wrappedGetters=Object.create(null),this._modules=new zm(t),this._modulesNamespaceMap=Object.create(null),this._subscribers=[],this._watcherVM=new Rm,this._makeLocalGettersCache=Object.create(null);var i=this,o=this.dispatch,s=this.commit;this.dispatch=function(t,e){return o.call(i,t,e)},this.commit=function(t,e,n){return s.call(i,t,e,n)},this.strict=r;var a=this._modules.root.state;Jm(this,a,[],this._modules.root),qm(this,a),n.forEach((function(t){return t(e)})),(void 0!==t.devtools?t.devtools:Rm.config.devtools)&&function(t){Tm&&(t._devtoolHook=Tm,Tm.emit("vuex:init",t),Tm.on("vuex:travel-to-state",(function(e){t.replaceState(e)})),t.subscribe((function(t,e){Tm.emit("vuex:mutation",t,e)}),{prepend:!0}),t.subscribeAction((function(t,e){Tm.emit("vuex:action",t,e)}),{prepend:!0}))}(this)},Lm={state:{configurable:!0}};function Bm(t,e,n){return e.indexOf(t)<0&&(n&&n.prepend?e.unshift(t):e.push(t)),function(){var n=e.indexOf(t);n>-1&&e.splice(n,1)}}function Vm(t,e){t._actions=Object.create(null),t._mutations=Object.create(null),t._wrappedGetters=Object.create(null),t._modulesNamespaceMap=Object.create(null);var n=t.state;Jm(t,n,[],t._modules.root,!0),qm(t,n,e)}function qm(t,e,n){var r=t._vm;t.getters={},t._makeLocalGettersCache=Object.create(null);var i=t._wrappedGetters,o={};Am(i,(function(e,n){o[n]=function(t,e){return function(){return t(e)}}(e,t),Object.defineProperty(t.getters,n,{get:function(){return t._vm[n]},enumerable:!0})}));var s=Rm.config.silent;Rm.config.silent=!0,t._vm=new Rm({data:{$$state:e},computed:o}),Rm.config.silent=s,t.strict&&function(t){t._vm.$watch((function(){return this._data.$$state}),(function(){}),{deep:!0,sync:!0})}(t),r&&(n&&t._withCommit((function(){r._data.$$state=null})),Rm.nextTick((function(){return r.$destroy()})))}function Jm(t,e,n,r,i){var o=!n.length,s=t._modules.getNamespace(n);if(r.namespaced&&(t._modulesNamespaceMap[s],t._modulesNamespaceMap[s]=r),!o&&!i){var a=Wm(e,n.slice(0,-1)),l=n[n.length-1];t._withCommit((function(){Rm.set(a,l,r.state)}))}var c=r.context=function(t,e,n){var r=""===e,i={dispatch:r?t.dispatch:function(n,r,i){var o=Hm(n,r,i),s=o.payload,a=o.options,l=o.type;return a&&a.root||(l=e+l),t.dispatch(l,s)},commit:r?t.commit:function(n,r,i){var o=Hm(n,r,i),s=o.payload,a=o.options,l=o.type;a&&a.root||(l=e+l),t.commit(l,s,a)}};return Object.defineProperties(i,{getters:{get:r?function(){return t.getters}:function(){return function(t,e){if(!t._makeLocalGettersCache[e]){var n={},r=e.length;Object.keys(t.getters).forEach((function(i){if(i.slice(0,r)===e){var o=i.slice(r);Object.defineProperty(n,o,{get:function(){return t.getters[i]},enumerable:!0})}})),t._makeLocalGettersCache[e]=n}return t._makeLocalGettersCache[e]}(t,e)}},state:{get:function(){return Wm(t.state,n)}}}),i}(t,s,n);r.forEachMutation((function(e,n){!function(t,e,n,r){(t._mutations[e]||(t._mutations[e]=[])).push((function(e){n.call(t,r.state,e)}))}(t,s+n,e,c)})),r.forEachAction((function(e,n){var r=e.root?n:s+n,i=e.handler||e;!function(t,e,n,r){(t._actions[e]||(t._actions[e]=[])).push((function(e){var i,o=n.call(t,{dispatch:r.dispatch,commit:r.commit,getters:r.getters,state:r.state,rootGetters:t.getters,rootState:t.state},e);return(i=o)&&"function"==typeof i.then||(o=Promise.resolve(o)),t._devtoolHook?o.catch((function(e){throw t._devtoolHook.emit("vuex:error",e),e})):o}))}(t,r,i,c)})),r.forEachGetter((function(e,n){!function(t,e,n,r){if(t._wrappedGetters[e])return;t._wrappedGetters[e]=function(t){return n(r.state,r.getters,t.state,t.getters)}}(t,s+n,e,c)})),r.forEachChild((function(r,o){Jm(t,e,n.concat(o),r,i)}))}function Wm(t,e){return e.reduce((function(t,e){return t[e]}),t)}function Hm(t,e,n){return Em(t)&&t.type&&(n=e,e=t,t=t.type),{type:t,payload:e,options:n}}function Km(t){Rm&&t===Rm||function(t){if(Number(t.version.split(".")[0])>=2)t.mixin({beforeCreate:n});else{var e=t.prototype._init;t.prototype._init=function(t){void 0===t&&(t={}),t.init=t.init?[n].concat(t.init):n,e.call(this,t)}}function n(){var t=this.$options;t.store?this.$store="function"==typeof t.store?t.store():t.store:t.parent&&t.parent.$store&&(this.$store=t.parent.$store)}}(Rm=t)}Lm.state.get=function(){return this._vm._data.$$state},Lm.state.set=function(t){},Fm.prototype.commit=function(t,e,n){var r=this,i=Hm(t,e,n),o=i.type,s=i.payload,a={type:o,payload:s},l=this._mutations[o];l&&(this._withCommit((function(){l.forEach((function(t){t(s)}))})),this._subscribers.slice().forEach((function(t){return t(a,r.state)})))},Fm.prototype.dispatch=function(t,e){var n=this,r=Hm(t,e),i=r.type,o=r.payload,s={type:i,payload:o},a=this._actions[i];if(a){try{this._actionSubscribers.slice().filter((function(t){return t.before})).forEach((function(t){return t.before(s,n.state)}))}catch(Tg){}var l=a.length>1?Promise.all(a.map((function(t){return t(o)}))):a[0](o);return new Promise((function(t,e){l.then((function(e){try{n._actionSubscribers.filter((function(t){return t.after})).forEach((function(t){return t.after(s,n.state)}))}catch(Tg){}t(e)}),(function(t){try{n._actionSubscribers.filter((function(t){return t.error})).forEach((function(e){return e.error(s,n.state,t)}))}catch(Tg){}e(t)}))}))}},Fm.prototype.subscribe=function(t,e){return Bm(t,this._subscribers,e)},Fm.prototype.subscribeAction=function(t,e){return Bm("function"==typeof t?{before:t}:t,this._actionSubscribers,e)},Fm.prototype.watch=function(t,e,n){var r=this;return this._watcherVM.$watch((function(){return t(r.state,r.getters)}),e,n)},Fm.prototype.replaceState=function(t){var e=this;this._withCommit((function(){e._vm._data.$$state=t}))},Fm.prototype.registerModule=function(t,e,n){void 0===n&&(n={}),"string"==typeof t&&(t=[t]),this._modules.register(t,e),Jm(this,this.state,t,this._modules.get(t),n.preserveState),qm(this,this.state)},Fm.prototype.unregisterModule=function(t){var e=this;"string"==typeof t&&(t=[t]),this._modules.unregister(t),this._withCommit((function(){var n=Wm(e.state,t.slice(0,-1));Rm.delete(n,t[t.length-1])})),Vm(this)},Fm.prototype.hasModule=function(t){return"string"==typeof t&&(t=[t]),this._modules.isRegistered(t)},Fm.prototype.hotUpdate=function(t){this._modules.update(t),Vm(this,!0)},Fm.prototype._withCommit=function(t){var e=this._committing;this._committing=!0,t(),this._committing=e},Object.defineProperties(Fm.prototype,Lm);var Um=Qm((function(t,e){var n={};return Xm(e).forEach((function(e){var r=e.key,i=e.val;n[r]=function(){var e=this.$store.state,n=this.$store.getters;if(t){var r=tg(this.$store,"mapState",t);if(!r)return;e=r.context.state,n=r.context.getters}return"function"==typeof i?i.call(this,e,n):e[i]},n[r].vuex=!0})),n})),Ym=Qm((function(t,e){var n={};return Xm(e).forEach((function(e){var r=e.key,i=e.val;n[r]=function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];var r=this.$store.commit;if(t){var o=tg(this.$store,"mapMutations",t);if(!o)return;r=o.context.commit}return"function"==typeof i?i.apply(this,[r].concat(e)):r.apply(this.$store,[i].concat(e))}})),n})),Gm=Qm((function(t,e){var n={};return Xm(e).forEach((function(e){var r=e.key,i=e.val;i=t+i,n[r]=function(){if(!t||tg(this.$store,"mapGetters",t))return this.$store.getters[i]},n[r].vuex=!0})),n})),Zm=Qm((function(t,e){var n={};return Xm(e).forEach((function(e){var r=e.key,i=e.val;n[r]=function(){for(var e=[],n=arguments.length;n--;)e[n]=arguments[n];var r=this.$store.dispatch;if(t){var o=tg(this.$store,"mapActions",t);if(!o)return;r=o.context.dispatch}return"function"==typeof i?i.apply(this,[r].concat(e)):r.apply(this.$store,[i].concat(e))}})),n}));function Xm(t){return function(t){return Array.isArray(t)||Em(t)}(t)?Array.isArray(t)?t.map((function(t){return{key:t,val:t}})):Object.keys(t).map((function(e){return{key:e,val:t[e]}})):[]}function Qm(t){return function(e,n){return"string"!=typeof e?(n=e,e=""):"/"!==e.charAt(e.length-1)&&(e+="/"),t(e,n)}}function tg(t,e,n){return t._modulesNamespaceMap[n]}function eg(t,e,n){var r=n?t.groupCollapsed:t.group;try{r.call(t,e)}catch(Tg){t.log(e)}}function ng(t){try{t.groupEnd()}catch(Tg){t.log("—— log end ——")}}function rg(){var t=new Date;return" @ "+ig(t.getHours(),2)+":"+ig(t.getMinutes(),2)+":"+ig(t.getSeconds(),2)+"."+ig(t.getMilliseconds(),3)}function ig(t,e){return n="0",r=e-t.toString().length,new Array(r+1).join(n)+t;var n,r}const og={Store:Fm,install:Km,version:"3.6.2",mapState:Um,mapMutations:Ym,mapGetters:Gm,mapActions:Zm,createNamespacedHelpers:function(t){return{mapState:Um.bind(null,t),mapGetters:Gm.bind(null,t),mapMutations:Ym.bind(null,t),mapActions:Zm.bind(null,t)}},createLogger:function(t){void 0===t&&(t={});var e=t.collapsed;void 0===e&&(e=!0);var n=t.filter;void 0===n&&(n=function(t,e,n){return!0});var r=t.transformer;void 0===r&&(r=function(t){return t});var i=t.mutationTransformer;void 0===i&&(i=function(t){return t});var o=t.actionFilter;void 0===o&&(o=function(t,e){return!0});var s=t.actionTransformer;void 0===s&&(s=function(t){return t});var a=t.logMutations;void 0===a&&(a=!0);var l=t.logActions;void 0===l&&(l=!0);var c=t.logger;return void 0===c&&(c=console),function(t){var u=Dm(t.state);void 0!==c&&(a&&t.subscribe((function(t,o){var s=Dm(o);if(n(t,u,s)){var a=rg(),l=i(t),d="mutation "+t.type+a;eg(c,d,e),c.log("%c prev state","color: #9E9E9E; font-weight: bold",r(u)),c.log("%c mutation","color: #03A9F4; font-weight: bold",l),c.log("%c next state","color: #4CAF50; font-weight: bold",r(s)),ng(c)}u=s})),l&&t.subscribeAction((function(t,n){if(o(t,n)){var r=rg(),i=s(t),a="action "+t.type+r;eg(c,a,e),c.log("%c action","color: #03A9F4; font-weight: bold",i),ng(c)}})))}}};function sg(t){return{all:t=t||new Map,on:function(e,n){var r=t.get(e);r?r.push(n):t.set(e,[n])},off:function(e,n){var r=t.get(e);r&&(n?r.splice(r.indexOf(n)>>>0,1):t.set(e,[]))},emit:function(e,n){var r=t.get(e);r&&r.slice().map((function(t){t(n)})),(r=t.get("*"))&&r.slice().map((function(t){t(e,n)}))}}}var ag,lg,cg="function"==typeof Map?new Map:(ag=[],lg=[],{has:function(t){return ag.indexOf(t)>-1},get:function(t){return lg[ag.indexOf(t)]},set:function(t,e){-1===ag.indexOf(t)&&(ag.push(t),lg.push(e))},delete:function(t){var e=ag.indexOf(t);e>-1&&(ag.splice(e,1),lg.splice(e,1))}}),ug=function(t){return new Event(t,{bubbles:!0})};try{new Event("test")}catch(Tg){ug=function(t){var e=document.createEvent("Event");return e.initEvent(t,!0,!1),e}}function dg(t){var e=cg.get(t);e&&e.destroy()}function fg(t){var e=cg.get(t);e&&e.update()}var hg=null;"undefined"==typeof window||"function"!=typeof window.getComputedStyle?((hg=function(t){return t}).destroy=function(t){return t},hg.update=function(t){return t}):((hg=function(t,e){return t&&Array.prototype.forEach.call(t.length?t:[t],(function(t){return function(t){if(t&&t.nodeName&&"TEXTAREA"===t.nodeName&&!cg.has(t)){var e,n=null,r=null,i=null,o=function(){t.clientWidth!==r&&c()},s=function(e){window.removeEventListener("resize",o,!1),t.removeEventListener("input",c,!1),t.removeEventListener("keyup",c,!1),t.removeEventListener("autosize:destroy",s,!1),t.removeEventListener("autosize:update",c,!1),Object.keys(e).forEach((function(n){t.style[n]=e[n]})),cg.delete(t)}.bind(t,{height:t.style.height,resize:t.style.resize,overflowY:t.style.overflowY,overflowX:t.style.overflowX,wordWrap:t.style.wordWrap});t.addEventListener("autosize:destroy",s,!1),"onpropertychange"in t&&"oninput"in t&&t.addEventListener("keyup",c,!1),window.addEventListener("resize",o,!1),t.addEventListener("input",c,!1),t.addEventListener("autosize:update",c,!1),t.style.overflowX="hidden",t.style.wordWrap="break-word",cg.set(t,{destroy:s,update:c}),"vertical"===(e=window.getComputedStyle(t,null)).resize?t.style.resize="none":"both"===e.resize&&(t.style.resize="horizontal"),n="content-box"===e.boxSizing?-(parseFloat(e.paddingTop)+parseFloat(e.paddingBottom)):parseFloat(e.borderTopWidth)+parseFloat(e.borderBottomWidth),isNaN(n)&&(n=0),c()}function a(e){var n=t.style.width;t.style.width="0px",t.style.width=n,t.style.overflowY=e}function l(){if(0!==t.scrollHeight){var e=function(t){for(var e=[];t&&t.parentNode&&t.parentNode instanceof Element;)t.parentNode.scrollTop&&(t.parentNode.style.scrollBehavior="auto",e.push([t.parentNode,t.parentNode.scrollTop])),t=t.parentNode;return function(){return e.forEach((function(t){var e=t[0];e.scrollTop=t[1],e.style.scrollBehavior=null}))}}(t);t.style.height="",t.style.height=t.scrollHeight+n+"px",r=t.clientWidth,e()}}function c(){l();var e=Math.round(parseFloat(t.style.height)),n=window.getComputedStyle(t,null),r="content-box"===n.boxSizing?Math.round(parseFloat(n.height)):t.offsetHeight;if(r=e?t:""+Array(e+1-r.length).join(n)+t},y={s:v,z:function(t){var e=-t.utcOffset(),n=Math.abs(e),r=Math.floor(n/60),i=n%60;return(e<=0?"+":"-")+v(r,2,"0")+":"+v(i,2,"0")},m:function t(e,n){if(e.date()1)return t(s[0])}else{var a=e.name;w[a]=e,i=a}return!r&&i&&(b=i),i||!r&&b},S=function(t,e){if(x(t))return t.clone();var n="object"==typeof e?e:{};return n.date=t,n.args=arguments,new _(n)},O=y;O.l=k,O.i=x,O.w=function(t,e){return S(t,{locale:e.$L,utc:e.$u,x:e.$x,$offset:e.$offset})};var _=function(){function g(t){this.$L=k(t.locale,null,!0),this.parse(t)}var v=g.prototype;return v.parse=function(t){this.$d=function(t){var e=t.date,n=t.utc;if(null===e)return new Date(NaN);if(O.u(e))return new Date;if(e instanceof Date)return new Date(e);if("string"==typeof e&&!/Z$/i.test(e)){var r=e.match(p);if(r){var i=r[2]-1||0,o=(r[7]||"0").substring(0,3);return n?new Date(Date.UTC(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,o)):new Date(r[1],i,r[3]||1,r[4]||0,r[5]||0,r[6]||0,o)}}return new Date(e)}(t),this.$x=t.x||{},this.init()},v.init=function(){var t=this.$d;this.$y=t.getFullYear(),this.$M=t.getMonth(),this.$D=t.getDate(),this.$W=t.getDay(),this.$H=t.getHours(),this.$m=t.getMinutes(),this.$s=t.getSeconds(),this.$ms=t.getMilliseconds()},v.$utils=function(){return O},v.isValid=function(){return!(this.$d.toString()===h)},v.isSame=function(t,e){var n=S(t);return this.startOf(e)<=n&&n<=this.endOf(e)},v.isAfter=function(t,e){return S(t)68?1900:2e3)},a=function(t){return function(e){this[t]=+e}},l=[/[+-]\d\d:?(\d\d)?|Z/,function(t){(this.zone||(this.zone={})).offset=function(t){if(!t)return 0;if("Z"===t)return 0;var e=t.match(/([+-]|\d\d)/g),n=60*e[1]+(+e[2]||0);return 0===n?0:"+"===e[0]?-n:n}(t)}],c=function(t){var e=o[t];return e&&(e.indexOf?e:e.s.concat(e.f))},u=function(t,e){var n,r=o.meridiem;if(r){for(var i=1;i<=24;i+=1)if(t.indexOf(r(i,0,e))>-1){n=i>12;break}}else n=t===(e?"pm":"PM");return n},d={A:[i,function(t){this.afternoon=u(t,!1)}],a:[i,function(t){this.afternoon=u(t,!0)}],S:[/\d/,function(t){this.milliseconds=100*+t}],SS:[n,function(t){this.milliseconds=10*+t}],SSS:[/\d{3}/,function(t){this.milliseconds=+t}],s:[r,a("seconds")],ss:[r,a("seconds")],m:[r,a("minutes")],mm:[r,a("minutes")],H:[r,a("hours")],h:[r,a("hours")],HH:[r,a("hours")],hh:[r,a("hours")],D:[r,a("day")],DD:[n,a("day")],Do:[i,function(t){var e=o.ordinal,n=t.match(/\d+/);if(this.day=n[0],e)for(var r=1;r<=31;r+=1)e(r).replace(/\[|\]/g,"")===t&&(this.day=r)}],M:[r,a("month")],MM:[n,a("month")],MMM:[i,function(t){var e=c("months"),n=(c("monthsShort")||e.map((function(t){return t.slice(0,3)}))).indexOf(t)+1;if(n<1)throw new Error;this.month=n%12||n}],MMMM:[i,function(t){var e=c("months").indexOf(t)+1;if(e<1)throw new Error;this.month=e%12||e}],Y:[/[+-]?\d+/,a("year")],YY:[n,function(t){this.year=s(t)}],YYYY:[/\d{4}/,a("year")],Z:l,ZZ:l};function f(n){var r,i;r=n,i=o&&o.formats;for(var s=(n=r.replace(/(\[[^\]]+])|(LTS?|l{1,4}|L{1,4})/g,(function(e,n,r){var o=r&&r.toUpperCase();return n||i[r]||t[r]||i[o].replace(/(\[[^\]]+])|(MMMM|MM|DD|dddd)/g,(function(t,e,n){return e||n.slice(1)}))}))).match(e),a=s.length,l=0;l-1)return new Date(("X"===e?1e3:1)*t);var r=f(e)(t),i=r.year,o=r.month,s=r.day,a=r.hours,l=r.minutes,c=r.seconds,u=r.milliseconds,d=r.zone,h=new Date,p=s||(i||o?1:h.getDate()),m=i||h.getFullYear(),g=0;i&&!o||(g=o>0?o-1:h.getMonth());var v=a||0,y=l||0,b=c||0,w=u||0;return d?new Date(Date.UTC(m,g,p,v,y,b,w+60*d.offset*1e3)):n?new Date(Date.UTC(m,g,p,v,y,b,w)):new Date(m,g,p,v,y,b,w)}catch(x){return new Date("")}}(e,a,r),this.init(),d&&!0!==d&&(this.$L=this.locale(d).$L),u&&e!=this.format(a)&&(this.$d=new Date("")),o={}}else if(a instanceof Array)for(var h=a.length,p=1;p<=h;p+=1){s[1]=a[p-1];var m=n.apply(this,s);if(m.isValid()){this.$d=m.$d,this.$L=m.$L,this.init();break}p===h&&(this.$d=new Date(""))}else i.call(this,t)}}}();var bg={},wg={};function xg(t){return null==t}function kg(t){return null!=t}function Sg(t,e){return e.tag===t.tag&&e.key===t.key}function Og(t){var e=t.tag;t.vm=new e({data:t.args})}function _g(t,e,n){var r,i,o={};for(r=e;r<=n;++r)kg(i=t[r].key)&&(o[i]=r);return o}function Mg(t,e,n){for(;e<=n;++e)Og(t[e])}function Cg(t,e,n){for(;e<=n;++e){var r=t[e];kg(r)&&(r.vm.$destroy(),r.vm=null)}}function $g(t,e){t!==e&&(e.vm=t.vm,function(t){for(var e=Object.keys(t.args),n=0;na?Mg(e,s,u):s>u&&Cg(t,o,a)}(t,e):kg(e)?Mg(e,0,e.length-1):kg(t)&&Cg(t,0,t.length-1)},function(t){Object.defineProperty(t,"__esModule",{value:!0}),t.Vuelidate=O,t.validationMixin=t.default=void 0,Object.defineProperty(t,"withParams",{enumerable:!0,get:function(){return n.withParams}});var e=wg,n=wp;function r(t){return function(t){if(Array.isArray(t))return i(t)}(t)||function(t){if("undefined"!=typeof Symbol&&null!=t[Symbol.iterator]||null!=t["@@iterator"])return Array.from(t)}(t)||function(t,e){if(!t)return;if("string"==typeof t)return i(t,e);var n=Object.prototype.toString.call(t).slice(8,-1);"Object"===n&&t.constructor&&(n=t.constructor.name);if("Map"===n||"Set"===n)return Array.from(t);if("Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n))return i(t,e)}(t)||function(){throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function i(t,e){(null==e||e>t.length)&&(e=t.length);for(var n=0,r=new Array(e);n1?a:a.$sub[0]:null}}},computed:{run:function(){var t=this,e=this.lazyParentModel();if(Array.isArray(e)&&e.__ob__){var n=e.__ob__.dep;n.depend();var r=n.constructor.target;if(!this._indirectWatcher){var i=r.constructor;this._indirectWatcher=new i(this,(function(){return t.runRule(e)}),null,{lazy:!0})}var o=this.getModel();if(!this._indirectWatcher.dirty&&this._lastModel===o)return this._indirectWatcher.depend(),r.value;this._lastModel=o,this._indirectWatcher.evaluate(),this._indirectWatcher.depend()}else this._indirectWatcher&&(this._indirectWatcher.teardown(),this._indirectWatcher=null);return this._indirectWatcher?this._indirectWatcher.value:this.runRule(e)},$params:function(){return this.run.params},proxy:function(){var t=this.run.output;return t.__isVuelidateAsyncVm?!!t.v:!!t},$pending:function(){var t=this.run.output;return!!t.__isVuelidateAsyncVm&&t.p}},destroyed:function(){this._indirectWatcher&&(this._indirectWatcher.teardown(),this._indirectWatcher=null)}}),a=i.extend({data:function(){return{dirty:!1,validations:null,lazyModel:null,model:null,prop:null,lazyParentModel:null,rootModel:null}},methods:s(s({},g),{},{refProxy:function(t){return this.getRef(t).proxy},getRef:function(t){return this.refs[t]},isNested:function(t){return"function"!=typeof this.validations[t]}}),computed:s(s({},p),{},{nestedKeys:function(){return this.keys.filter(this.isNested)},ruleKeys:function(){var t=this;return this.keys.filter((function(e){return!t.isNested(e)}))},keys:function(){return Object.keys(this.validations).filter((function(t){return"$params"!==t}))},proxy:function(){var t=this,e=u(this.keys,(function(e){return{enumerable:!0,configurable:!0,get:function(){return t.refProxy(e)}}})),n=u(v,(function(e){return{enumerable:!0,configurable:!0,get:function(){return t[e]}}})),r=u(y,(function(e){return{enumerable:!1,configurable:!0,get:function(){return t[e]}}})),i=this.hasIter()?{$iter:{enumerable:!0,value:Object.defineProperties({},s({},e))}}:{};return Object.defineProperties({},s(s(s(s({},e),i),{},{$model:{enumerable:!0,get:function(){var e=t.lazyParentModel();return null!=e?e[t.prop]:null},set:function(e){var n=t.lazyParentModel();null!=n&&(n[t.prop]=e,t.$touch())}}},n),r))},children:function(){var t=this;return[].concat(r(this.nestedKeys.map((function(e){return w(t,e)}))),r(this.ruleKeys.map((function(e){return x(t,e)})))).filter(Boolean)}})}),l=a.extend({methods:{isNested:function(t){return void 0!==this.validations[t]()},getRef:function(t){var e=this;return{get proxy(){return e.validations[t]()||!1}}}}}),m=a.extend({computed:{keys:function(){var t=this.getModel();return f(t)?Object.keys(t):[]},tracker:function(){var t=this,e=this.validations.$trackBy;return e?function(n){return"".concat(h(t.rootModel,t.getModelKey(n),e))}:function(t){return"".concat(t)}},getModelLazy:function(){var t=this;return function(){return t.getModel()}},children:function(){var t=this,n=this.validations,r=this.getModel(),i=s({},n);delete i.$trackBy;var o={};return this.keys.map((function(n){var s=t.tracker(n);return o.hasOwnProperty(s)?null:(o[s]=!0,(0,e.h)(a,s,{validations:i,prop:n,lazyParentModel:t.getModelLazy,model:r[n],rootModel:t.rootModel}))})).filter(Boolean)}},methods:{isNested:function(){return!0},getRef:function(t){return this.refs[this.tracker(t)]},hasIter:function(){return!0}}}),w=function(t,n){if("$each"===n)return(0,e.h)(m,n,{validations:t.validations[n],lazyParentModel:t.lazyParentModel,prop:n,lazyModel:t.getModel,rootModel:t.rootModel});var r=t.validations[n];if(Array.isArray(r)){var i=t.rootModel,o=u(r,(function(t){return function(){return h(i,i.$v,t)}}),(function(t){return Array.isArray(t)?t.join("."):t}));return(0,e.h)(l,n,{validations:o,lazyParentModel:c,prop:n,lazyModel:c,rootModel:i})}return(0,e.h)(a,n,{validations:r,lazyParentModel:t.getModel,prop:n,lazyModel:t.getModelKey,rootModel:t.rootModel})},x=function(t,n){return(0,e.h)(o,n,{rule:t.validations[n],lazyParentModel:t.lazyParentModel,lazyModel:t.getModel,rootModel:t.rootModel})};return b={VBase:i,Validation:a}},x=null;var k=function(t,n){var r=function(t){if(x)return x;for(var e=t.constructor;e.super;)e=e.super;return x=e,e}(t),i=w(r),o=i.Validation;return new(0,i.VBase)({computed:{children:function(){var r="function"==typeof n?n.call(t):n;return[(0,e.h)(o,"$v",{validations:r,lazyParentModel:c,prop:"$v",model:t,rootModel:t})]}}})},S={data:function(){var t=this.$options.validations;return t&&(this._vuelidate=k(this,t)),{}},beforeCreate:function(){var t=this.$options;t.validations&&(t.computed||(t.computed={}),t.computed.$v||(t.computed.$v=function(){return this._vuelidate?this._vuelidate.refs.$v.proxy:null}))},beforeDestroy:function(){this._vuelidate&&(this._vuelidate.$destroy(),this._vuelidate=null)}};function O(t){t.mixin(S)}t.validationMixin=S;var _=O;t.default=_}(bg);const Ng=mp(bg);export{Nm as A,Tt as B,og as C,Cl as D,Lc as E,za as F,sg as G,gg as H,Th as I,yg as J,pg as K,Ng as L,Nc as N,Vc as P,qa as S,Cc as T,Wn as V,kh as a,Ph as b,Oh as c,Ih as d,vh as e,qh as f,Wh as g,Kh as h,_l as i,Dh as j,uh as k,Hh as l,Kf as m,zl as n,Nh as o,dp as p,hp as q,fp as r,Nt as s,Sh as t,Eh as u,pp as v,Jh as w,up as x,gp as y,Je as z}; diff --git a/kirby/src/Api/Api.php b/kirby/src/Api/Api.php index fa24217..91b5788 100644 --- a/kirby/src/Api/Api.php +++ b/kirby/src/Api/Api.php @@ -4,10 +4,14 @@ namespace Kirby\Api; use Closure; use Exception; +use Kirby\Cms\User; +use Kirby\Exception\Exception as ExceptionException; use Kirby\Exception\NotFoundException; use Kirby\Filesystem\F; use Kirby\Http\Response; +use Kirby\Http\Route; use Kirby\Http\Router; +use Kirby\Toolkit\Collection as BaseCollection; use Kirby\Toolkit\I18n; use Kirby\Toolkit\Pagination; use Kirby\Toolkit\Properties; @@ -32,82 +36,59 @@ class Api /** * Authentication callback - * - * @var \Closure */ - protected $authentication; + protected Closure|null $authentication = null; /** * Debugging flag - * - * @var bool */ - protected $debug = false; + protected bool $debug = false; /** * Collection definition - * - * @var array */ - protected $collections = []; + protected array $collections = []; /** * Injected data/dependencies - * - * @var array */ - protected $data = []; + protected array $data = []; /** * Model definitions - * - * @var array */ - protected $models = []; + protected array $models = []; /** * The current route - * - * @var \Kirby\Http\Route */ - protected $route; + protected Route|null $route = null; /** * The Router instance - * - * @var \Kirby\Http\Router */ - protected $router; + protected Router|null $router = null; /** * Route definition - * - * @var array */ - protected $routes = []; + protected array $routes = []; /** * Request data * [query, body, files] - * - * @var array */ - protected $requestData = []; + protected array $requestData = []; /** * The applied request method * (GET, POST, PATCH, etc.) - * - * @var string */ - protected $requestMethod; + protected string|null $requestMethod = null; /** * Magic accessor for any given data * - * @param string $method - * @param array $args - * @return mixed * @throws \Kirby\Exception\NotFoundException */ public function __call(string $method, array $args = []) @@ -117,8 +98,6 @@ class Api /** * Creates a new API instance - * - * @param array $props */ public function __construct(array $props) { @@ -128,16 +107,10 @@ class Api /** * Runs the authentication method * if set - * - * @return mixed */ public function authenticate() { - if ($auth = $this->authentication()) { - return $auth->call($this); - } - - return true; + return $this->authentication()?->call($this) ?? true; } /** @@ -145,7 +118,7 @@ class Api * * @return \Closure|null */ - public function authentication() + public function authentication(): Closure|null { return $this->authentication; } @@ -154,14 +127,10 @@ class Api * Execute an API call for the given path, * request method and optional request data * - * @param string|null $path - * @param string $method - * @param array $requestData - * @return mixed * @throws \Kirby\Exception\NotFoundException * @throws \Exception */ - public function call(string $path = null, string $method = 'GET', array $requestData = []) + public function call(string|null $path = null, string $method = 'GET', array $requestData = []) { $path = rtrim($path ?? '', '/'); @@ -170,19 +139,18 @@ class Api $this->router = new Router($this->routes()); $this->route = $this->router->find($path, $method); - $auth = $this->route->attributes()['auth'] ?? true; + $auth = $this->route?->attributes()['auth'] ?? true; if ($auth !== false) { $user = $this->authenticate(); // set PHP locales based on *user* language // so that e.g. strftime() gets formatted correctly - if (is_a($user, 'Kirby\Cms\User') === true) { + if ($user instanceof User) { $language = $user->language(); // get the locale from the translation - $translation = $user->kirby()->translation($language); - $locale = ($translation !== null) ? $translation->locale() : $language; + $locale = $user->kirby()->translation($language)->locale(); // provide some variants as fallbacks to be // compatible with as many systems as possible @@ -208,14 +176,17 @@ class Api $validate = Pagination::$validate; Pagination::$validate = false; - $output = $this->route->action()->call($this, ...$this->route->arguments()); + $output = $this->route?->action()->call( + $this, + ...$this->route->arguments() + ); // restore old pagination validation mode Pagination::$validate = $validate; if ( is_object($output) === true && - is_a($output, 'Kirby\\Http\\Response') !== true + $output instanceof Response === false ) { return $this->resolve($output)->toResponse(); } @@ -226,13 +197,10 @@ class Api /** * Setter and getter for an API collection * - * @param string $name - * @param array|null $collection - * @return \Kirby\Api\Collection * @throws \Kirby\Exception\NotFoundException If no collection for `$name` exists * @throws \Exception */ - public function collection(string $name, $collection = null) + public function collection(string $name, array|BaseCollection|null $collection = null): Collection { if (isset($this->collections[$name]) === false) { throw new NotFoundException(sprintf('The collection "%s" does not exist', $name)); @@ -243,8 +211,6 @@ class Api /** * Returns the collections definition - * - * @return array */ public function collections(): array { @@ -255,13 +221,9 @@ class Api * Returns the injected data array * or certain parts of it by key * - * @param string|null $key - * @param mixed ...$args - * @return mixed - * * @throws \Kirby\Exception\NotFoundException If no data for `$key` exists */ - public function data($key = null, ...$args) + public function data(string|null $key = null, ...$args) { if ($key === null) { return $this->data; @@ -272,7 +234,7 @@ class Api } // lazy-load data wrapped in Closures - if (is_a($this->data[$key], 'Closure') === true) { + if ($this->data[$key] instanceof Closure) { return $this->data[$key]->call($this, ...$args); } @@ -281,8 +243,6 @@ class Api /** * Returns the debugging flag - * - * @return bool */ public function debug(): bool { @@ -291,9 +251,6 @@ class Api /** * Checks if injected data exists for the given key - * - * @param string $key - * @return bool */ public function hasData(string $key): bool { @@ -305,39 +262,31 @@ class Api * based on the `type` field * * @param array models or collections - * @param mixed $object - * - * @return string key of match + * @return string|null key of match */ - protected function match(array $array, $object = null) + protected function match(array $array, $object = null): string|null { foreach ($array as $definition => $model) { - if (is_a($object, $model['type']) === true) { + if ($object instanceof $model['type']) { return $definition; } } + + return null; } /** * Returns an API model instance by name * - * @param string|null $name - * @param mixed $object - * @return \Kirby\Api\Model - * * @throws \Kirby\Exception\NotFoundException If no model for `$name` exists */ - public function model(string $name = null, $object = null) + public function model(string|null $name = null, $object = null): Model { // Try to auto-match object with API models - if ($name === null) { - if ($model = $this->match($this->models, $object)) { - $name = $model; - } - } + $name ??= $this->match($this->models, $object); if (isset($this->models[$name]) === false) { - throw new NotFoundException(sprintf('The model "%s" does not exist', $name)); + throw new NotFoundException(sprintf('The model "%s" does not exist', $name ?? 'NULL')); } return new Model($this, $object, $this->models[$name]); @@ -345,8 +294,6 @@ class Api /** * Returns all model definitions - * - * @return array */ public function models(): array { @@ -363,8 +310,11 @@ class Api * @param mixed $default * @return mixed */ - public function requestData(string $type = null, string $key = null, $default = null) - { + public function requestData( + string|null $type = null, + string|null $key = null, + $default = null + ) { if ($type === null) { return $this->requestData; } @@ -381,58 +331,40 @@ class Api /** * Returns the request body if available - * - * @param string|null $key - * @param mixed $default - * @return mixed */ - public function requestBody(string $key = null, $default = null) + public function requestBody(string|null $key = null, $default = null) { return $this->requestData('body', $key, $default); } /** * Returns the files from the request if available - * - * @param string|null $key - * @param mixed $default - * @return mixed */ - public function requestFiles(string $key = null, $default = null) + public function requestFiles(string|null $key = null, $default = null) { return $this->requestData('files', $key, $default); } /** * Returns all headers from the request if available - * - * @param string|null $key - * @param mixed $default - * @return mixed */ - public function requestHeaders(string $key = null, $default = null) + public function requestHeaders(string|null $key = null, $default = null) { return $this->requestData('headers', $key, $default); } /** * Returns the request method - * - * @return string */ - public function requestMethod(): string + public function requestMethod(): string|null { return $this->requestMethod; } /** * Returns the request query if available - * - * @param string|null $key - * @param mixed $default - * @return mixed */ - public function requestQuery(string $key = null, $default = null) + public function requestQuery(string|null $key = null, $default = null) { return $this->requestData('query', $key, $default); } @@ -441,14 +373,14 @@ class Api * Turns a Kirby object into an * API model or collection representation * - * @param mixed $object - * @return \Kirby\Api\Model|\Kirby\Api\Collection - * * @throws \Kirby\Exception\NotFoundException If `$object` cannot be resolved */ - public function resolve($object) + public function resolve($object): Model|Collection { - if (is_a($object, 'Kirby\Api\Model') === true || is_a($object, 'Kirby\Api\Collection') === true) { + if ( + $object instanceof Model || + $object instanceof Collection + ) { return $object; } @@ -465,8 +397,6 @@ class Api /** * Returns all defined routes - * - * @return array */ public function routes(): array { @@ -475,11 +405,9 @@ class Api /** * Setter for the authentication callback - * - * @param \Closure|null $authentication * @return $this */ - protected function setAuthentication(Closure $authentication = null) + protected function setAuthentication(Closure|null $authentication = null): static { $this->authentication = $authentication; return $this; @@ -487,11 +415,9 @@ class Api /** * Setter for the collections definition - * - * @param array|null $collections * @return $this */ - protected function setCollections(array $collections = null) + protected function setCollections(array|null $collections = null): static { if ($collections !== null) { $this->collections = array_change_key_case($collections); @@ -501,11 +427,9 @@ class Api /** * Setter for the injected data - * - * @param array|null $data * @return $this */ - protected function setData(array $data = null) + protected function setData(array|null $data = null): static { $this->data = $data ?? []; return $this; @@ -513,11 +437,9 @@ class Api /** * Setter for the debug flag - * - * @param bool $debug * @return $this */ - protected function setDebug(bool $debug = false) + protected function setDebug(bool $debug = false): static { $this->debug = $debug; return $this; @@ -525,11 +447,9 @@ class Api /** * Setter for the model definitions - * - * @param array|null $models * @return $this */ - protected function setModels(array $models = null) + protected function setModels(array|null $models = null): static { if ($models !== null) { $this->models = array_change_key_case($models); @@ -540,11 +460,9 @@ class Api /** * Setter for the request data - * - * @param array|null $requestData * @return $this */ - protected function setRequestData(array $requestData = null) + protected function setRequestData(array|null $requestData = null): static { $defaults = [ 'query' => [], @@ -558,11 +476,9 @@ class Api /** * Setter for the request method - * - * @param string|null $requestMethod * @return $this */ - protected function setRequestMethod(string $requestMethod = null) + protected function setRequestMethod(string|null $requestMethod = null): static { $this->requestMethod = $requestMethod ?? 'GET'; return $this; @@ -570,11 +486,9 @@ class Api /** * Setter for the route definitions - * - * @param array|null $routes * @return $this */ - protected function setRoutes(array $routes = null) + protected function setRoutes(array|null $routes = null): static { $this->routes = $routes ?? []; return $this; @@ -582,13 +496,8 @@ class Api /** * Renders the API call - * - * @param string $path - * @param string $method - * @param array $requestData - * @return mixed */ - public function render(string $path, $method = 'GET', array $requestData = []) + public function render(string $path, string $method = 'GET', array $requestData = []) { try { $result = $this->call($path, $method, $requestData); @@ -596,13 +505,12 @@ class Api $result = $this->responseForException($e); } - if ($result === null) { - $result = $this->responseFor404(); - } elseif ($result === false) { - $result = $this->responseFor400(); - } elseif ($result === true) { - $result = $this->responseFor200(); - } + $result = match ($result) { + null => $this->responseFor404(), + false => $this->responseFor400(), + true => $this->responseFor200(), + default => $result + }; if (is_array($result) === false) { return $result; @@ -628,8 +536,6 @@ class Api /** * Returns a 200 - ok * response array. - * - * @return array */ public function responseFor200(): array { @@ -643,8 +549,6 @@ class Api /** * Returns a 400 - bad request * response array. - * - * @return array */ public function responseFor400(): array { @@ -658,8 +562,6 @@ class Api /** * Returns a 404 - not found * response array. - * - * @return array */ public function responseFor404(): array { @@ -674,9 +576,6 @@ class Api * Creates the response array for * an exception. Kirby exceptions will * have more information - * - * @param \Throwable $e - * @return array */ public function responseForException(Throwable $e): array { @@ -696,11 +595,11 @@ class Api 'file' => F::relativepath($e->getFile(), $docRoot), 'line' => $e->getLine(), 'details' => [], - 'route' => $this->route ? $this->route->pattern() : null + 'route' => $this->route?->pattern() ]; // extend the information for Kirby Exceptions - if (is_a($e, 'Kirby\Exception\Exception') === true) { + if ($e instanceof ExceptionException) { $result['key'] = $e->getKey(); $result['details'] = $e->getDetails(); $result['code'] = $e->getHttpCode(); @@ -726,14 +625,9 @@ class Api * move_uploaded_file() not working with unit test * Added debug parameter for testing purposes as we did in the Email class * - * @param \Closure $callback - * @param bool $single - * @param bool $debug - * @return array - * * @throws \Exception If request has no files or there was an error with the upload */ - public function upload(Closure $callback, $single = false, $debug = false): array + public function upload(Closure $callback, bool $single = false, bool $debug = false): array { $trials = 0; $uploads = []; @@ -757,13 +651,16 @@ class Api if ($postMaxSize < $uploadMaxFileSize) { throw new Exception(I18n::translate('upload.error.iniPostSize')); - } else { - throw new Exception(I18n::translate('upload.error.noFiles')); } + + throw new Exception(I18n::translate('upload.error.noFiles')); } foreach ($files as $upload) { - if (isset($upload['tmp_name']) === false && is_array($upload)) { + if ( + isset($upload['tmp_name']) === false && + is_array($upload) === true + ) { continue; } @@ -780,7 +677,10 @@ class Api // try to detect the correct mime and add the extension // accordingly. This will avoid .tmp filenames - if (empty($extension) === true || in_array($extension, ['tmp', 'temp'])) { + if ( + empty($extension) === true || + in_array($extension, ['tmp', 'temp']) === true + ) { $mime = F::mime($upload['tmp_name']); $extension = F::mimeToExtension($mime); $filename = F::name($upload['name']) . '.' . $extension; @@ -792,7 +692,10 @@ class Api // move the file to a location including the extension, // for better mime detection - if ($debug === false && move_uploaded_file($upload['tmp_name'], $source) === false) { + if ( + $debug === false && + move_uploaded_file($upload['tmp_name'], $source) === false + ) { throw new Exception(I18n::translate('upload.error.cantMove')); } diff --git a/kirby/src/Api/Collection.php b/kirby/src/Api/Collection.php index 48ddca2..e3f39c9 100644 --- a/kirby/src/Api/Collection.php +++ b/kirby/src/Api/Collection.php @@ -2,6 +2,7 @@ namespace Kirby\Api; +use Closure; use Exception; use Kirby\Toolkit\Str; @@ -19,48 +20,27 @@ use Kirby\Toolkit\Str; */ class Collection { - /** - * @var \Kirby\Api\Api - */ - protected $api; - - /** - * @var mixed|null - */ + protected Api $api; protected $data; - - /** - * @var mixed|null - */ protected $model; - - /** - * @var mixed|null - */ protected $select; - - /** - * @var mixed|null - */ protected $view; /** * Collection constructor * - * @param \Kirby\Api\Api $api - * @param mixed|null $data - * @param array $schema * @throws \Exception */ public function __construct(Api $api, $data, array $schema) { - $this->api = $api; - $this->data = $data; - $this->model = $schema['model'] ?? null; - $this->view = $schema['view'] ?? null; + $this->api = $api; + $this->data = $data; + $this->model = $schema['model'] ?? null; + $this->select = null; + $this->view = $schema['view'] ?? null; if ($data === null) { - if (is_a($schema['default'] ?? null, 'Closure') === false) { + if (($schema['default'] ?? null) instanceof Closure === false) { throw new Exception('Missing collection data'); } @@ -69,18 +49,17 @@ class Collection if ( isset($schema['type']) === true && - is_a($this->data, $schema['type']) === false + $this->data instanceof $schema['type'] === false ) { throw new Exception('Invalid collection type'); } } /** - * @param string|array|null $keys * @return $this * @throws \Exception */ - public function select($keys = null) + public function select($keys = null): static { if ($keys === false) { return $this; @@ -99,7 +78,6 @@ class Collection } /** - * @return array * @throws \Kirby\Exception\NotFoundException * @throws \Exception */ @@ -125,7 +103,6 @@ class Collection } /** - * @return array * @throws \Kirby\Exception\NotFoundException * @throws \Exception */ @@ -167,10 +144,9 @@ class Collection } /** - * @param string $view * @return $this */ - public function view(string $view) + public function view(string $view): static { $this->view = $view; return $this; diff --git a/kirby/src/Api/Model.php b/kirby/src/Api/Model.php index f0189c0..e0fa9ba 100644 --- a/kirby/src/Api/Model.php +++ b/kirby/src/Api/Model.php @@ -2,6 +2,7 @@ namespace Kirby\Api; +use Closure; use Exception; use Kirby\Toolkit\Str; @@ -21,37 +22,15 @@ use Kirby\Toolkit\Str; */ class Model { - /** - * @var \Kirby\Api\Api - */ - protected $api; - - /** - * @var mixed|null - */ + protected Api $api; protected $data; - - /** - * @var array|mixed - */ protected $fields; - - /** - * @var mixed|null - */ protected $select; - - /** - * @var array|mixed - */ protected $views; /** * Model constructor * - * @param \Kirby\Api\Api $api - * @param mixed $data - * @param array $schema * @throws \Exception */ public function __construct(Api $api, $data, array $schema) @@ -62,12 +41,15 @@ class Model $this->select = $schema['select'] ?? null; $this->views = $schema['views'] ?? []; - if ($this->select === null && array_key_exists('default', $this->views)) { + if ( + $this->select === null && + array_key_exists('default', $this->views) + ) { $this->view('default'); } if ($data === null) { - if (is_a($schema['default'] ?? null, 'Closure') === false) { + if (($schema['default'] ?? null) instanceof Closure === false) { throw new Exception('Missing model data'); } @@ -76,18 +58,17 @@ class Model if ( isset($schema['type']) === true && - is_a($this->data, $schema['type']) === false + $this->data instanceof $schema['type'] === false ) { throw new Exception(sprintf('Invalid model type "%s" expected: "%s"', get_class($this->data), $schema['type'])); } } /** - * @param null $keys * @return $this * @throws \Exception */ - public function select($keys = null) + public function select($keys = null): static { if ($keys === false) { return $this; @@ -106,7 +87,6 @@ class Model } /** - * @return array * @throws \Exception */ public function selection(): array @@ -153,7 +133,6 @@ class Model } /** - * @return array * @throws \Kirby\Exception\NotFoundException * @throws \Exception */ @@ -163,7 +142,10 @@ class Model $result = []; foreach ($this->fields as $key => $resolver) { - if (array_key_exists($key, $select) === false || is_a($resolver, 'Closure') === false) { + if ( + array_key_exists($key, $select) === false || + $resolver instanceof Closure === false + ) { continue; } @@ -174,8 +156,8 @@ class Model } if ( - is_a($value, 'Kirby\Api\Collection') === true || - is_a($value, 'Kirby\Api\Model') === true + $value instanceof Collection || + $value instanceof self ) { $selection = $select[$key]; @@ -199,7 +181,6 @@ class Model } /** - * @return array * @throws \Kirby\Exception\NotFoundException * @throws \Exception */ @@ -224,11 +205,10 @@ class Model } /** - * @param string $name * @return $this * @throws \Exception */ - public function view(string $name) + public function view(string $name): static { if ($name === 'any') { return $this->select(null); diff --git a/kirby/src/Blueprint/Collection.php b/kirby/src/Blueprint/Collection.php new file mode 100644 index 0000000..3abadb0 --- /dev/null +++ b/kirby/src/Blueprint/Collection.php @@ -0,0 +1,90 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + * + * // TODO: include in test coverage in 3.9 + * @codeCoverageIgnore + */ +class Collection extends BaseCollection +{ + /** + * The expected object type + */ + public const TYPE = Node::class; + + public function __construct(array $objects = []) + { + foreach ($objects as $object) { + $this->__set($object->id, $object); + } + } + + /** + * The Kirby Collection class only shows the key to + * avoid huge tress with dump, but for the blueprint + * collections this is really not useful + */ + public function __debugInfo(): array + { + return A::map($this->data, fn ($item) => (array)$item); + } + + /** + * Validate the type of every item that is being + * added to the collection. They cneed to have + * the class defined by static::TYPE. + */ + public function __set(string $key, $value): void + { + if ( + is_a($value, static::TYPE) === false + ) { + throw new TypeError('Each value in the collection must be an instance of ' . static::TYPE); + } + + parent::__set($key, $value); + } + + public static function factory(array $items) + { + $collection = new static(); + $className = static::TYPE; + + foreach ($items as $id => $item) { + if (is_array($item) === true) { + $item['id'] ??= $id; + $item = $className::factory($item); + $collection->__set($item->id, $item); + } else { + $collection->__set($id, $className::factory($item)); + } + } + + return $collection; + } + + public function render(ModelWithContent $model) + { + $props = []; + + foreach ($this->data as $key => $item) { + $props[$key] = $item->render($model); + } + + return $props; + } +} diff --git a/kirby/src/Blueprint/Config.php b/kirby/src/Blueprint/Config.php new file mode 100644 index 0000000..abfb1a7 --- /dev/null +++ b/kirby/src/Blueprint/Config.php @@ -0,0 +1,75 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + * + * // TODO: include in test coverage in 3.9 + * @codeCoverageIgnore + */ +class Config +{ + public string $file; + public string $id; + public string|array|Closure|null $plugin; + public string $root; + + public function __construct( + public string $path + ) { + $kirby = App::instance(); + + $this->id = basename($this->path); + $this->root = $kirby->root('blueprints'); + $this->file = $this->root . '/' . $this->path . '.yml'; + $this->plugin = $kirby->extension('blueprints', $this->path); + } + + public function read(): array + { + if (F::exists($this->file, $this->root) === true) { + return $this->unpack($this->file); + } + + return $this->unpack($this->plugin); + } + + public function write(array $props): bool + { + return Yaml::write($this->file, $props); + } + + public function unpack(string|array|Closure|null $extension): array + { + return match (true) { + // extension does not exist + is_null($extension) + => throw new NotFoundException('"' . $this->path . '" could not be found'), + + // extension is stored as a file path + is_string($extension) + => Yaml::read($extension), + + // extension is a callback to be resolved + is_callable($extension) + => $extension(App::instance()), + + // extension is already defined as array + default + => $extension + }; + } +} diff --git a/kirby/src/Blueprint/Extension.php b/kirby/src/Blueprint/Extension.php new file mode 100644 index 0000000..cb15905 --- /dev/null +++ b/kirby/src/Blueprint/Extension.php @@ -0,0 +1,65 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + * + * // TODO: include in test coverage in 3.9 + * @codeCoverageIgnore + */ +class Extension +{ + public function __construct( + public string $path + ) { + } + + public static function apply(array $props): array + { + if (isset($props['extends']) === false) { + return $props; + } + + // already extended + if (is_a($props['extends'], Extension::class) === true) { + return $props; + } + + $extension = new static($props['extends']); + return $extension->extend($props); + } + + public function extend(array $props): array + { + $props = array_replace_recursive( + $this->read(), + $props + ); + + $props['extends'] = $this; + + return $props; + } + + public static function factory(string|array $path): static + { + if (is_string($path) === true) { + return new static(path: $path); + } + + return new static(...$path); + } + + public function read(): array + { + $config = new Config($this->path); + return $config->read(); + } +} diff --git a/kirby/src/Blueprint/Factory.php b/kirby/src/Blueprint/Factory.php new file mode 100644 index 0000000..3ba9600 --- /dev/null +++ b/kirby/src/Blueprint/Factory.php @@ -0,0 +1,119 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + * + * // TODO: include in test coverage in 3.9 + * @codeCoverageIgnore + */ +class Factory +{ + /** + * Resolves the properties by + * applying a map of factories (propName => class) + */ + public static function apply(array $properties, array $factories): array + { + foreach ($factories as $property => $class) { + // skip non-existing properties, empty properties + // or properties that are matching objects + if ( + isset($properties[$property]) === false || + $properties[$property] === null || + is_a($properties[$property], $class) === true + ) { + continue; + } + + $properties[$property] = $class::factory($properties[$property]); + } + + return $properties; + } + + public static function forNamedType(ReflectionNamedType|null $type, $value) + { + // get the class name for the single type + $className = $type->getName(); + + // check if there's a factory for the value + if (method_exists($className, 'factory') === true) { + return $className::factory($value); + } + + // try to assign the value directly and trust + // in PHP's type system. + return $value; + } + + public static function forProperties(string $class, array $properties): array + { + foreach ($properties as $property => $value) { + try { + $properties[$property] = static::forProperty($class, $property, $value); + } catch (ReflectionException $e) { + // the property does not exist + unset($properties[$property]); + } + } + + return $properties; + } + + public static function forProperty(string $class, string $property, $value) + { + if (is_null($value) === true) { + return $value; + } + + // instantly assign objects + // PHP's type system will find issues automatically + if (is_object($value) === true) { + return $value; + } + + // get the type for the property + $reflection = new ReflectionProperty($class, $property); + $propType = $reflection->getType(); + + // no type given + if ($propType === null) { + return $value; + } + + // union types + if (is_a($propType, ReflectionUnionType::class) === true) { + return static::forUnionType($propType, $value); + } + + return static::forNamedType($propType, $value); + } + + /** + * For properties with union types, + * the first named type is used to create + * the factory or pass a built-in value + */ + public static function forUnionType(ReflectionUnionType $type, $value) + { + return static::forNamedType($type->getTypes()[0], $value); + } + + public static function make(string $class, array $properties): object + { + return new $class(...static::forProperties($class, $properties)); + } +} diff --git a/kirby/src/Blueprint/Node.php b/kirby/src/Blueprint/Node.php new file mode 100644 index 0000000..88e7d97 --- /dev/null +++ b/kirby/src/Blueprint/Node.php @@ -0,0 +1,118 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + * + * // TODO: include in test coverage in 3.9 + * @codeCoverageIgnore + */ +class Node +{ + public const TYPE = 'node'; + + public function __construct( + public string $id, + public Extension|null $extends = null, + ) { + } + + /** + * Dynamic getter for properties + */ + public function __call(string $name, array $args) + { + $this->defaults(); + return $this->$name; + } + + /** + * Apply default values + */ + public function defaults(): static + { + return $this; + } + + /** + * Creates an instance by a set of array properties. + */ + public static function factory(array $props): static + { + $props = Extension::apply($props); + $props = static::polyfill($props); + return Factory::make(static::class, $props); + } + + + public static function load(string|array $props): static + { + // load by path + if (is_string($props) === true) { + $props = static::loadProps($props); + } + + return static::factory($props); + } + + public static function loadProps(string $path): array + { + $config = new Config($path); + $props = $config->read(); + + // add the id if it's not set yet + $props['id'] ??= basename($path); + + return $props; + } + + /** + * Optional method that runs before static::factory sends + * its properties to the instance. This is perfect to clean + * up props or keep deprecated props compatible. + */ + public static function polyfill(array $props): array + { + return $props; + } + + public function render(ModelWithContent $model) + { + // apply default values + $this->defaults(); + + $array = []; + + // go through all public properties + foreach (get_object_vars($this) as $key => $value) { + if (is_object($value) === false && is_resource($value) === false) { + $array[$key] = $value; + continue; + } + + if (method_exists($value, 'render') === true) { + $array[$key] = $value->render($model); + } + } + + return $array; + } + + /** + * Universal setter for properties + */ + public function set(string $property, $value): static + { + $this->$property = Factory::forProperty(static::class, $property, $value); + return $this; + } +} diff --git a/kirby/src/Blueprint/NodeI18n.php b/kirby/src/Blueprint/NodeI18n.php new file mode 100644 index 0000000..1eaeb10 --- /dev/null +++ b/kirby/src/Blueprint/NodeI18n.php @@ -0,0 +1,44 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + * + * // TODO: include in test coverage in 3.9 + * @codeCoverageIgnore + */ +class NodeI18n extends NodeProperty +{ + public function __construct( + public array $translations, + ) { + } + + public static function factory($value = null): static|null + { + if ($value === false || $value === null) { + return null; + } + + if (is_array($value) === false) { + $value = ['en' => $value]; + } + + return new static($value); + } + + public function render(ModelWithContent $model): string|null + { + return I18n::translate($this->translations, $this->translations); + } +} diff --git a/kirby/src/Blueprint/NodeIcon.php b/kirby/src/Blueprint/NodeIcon.php new file mode 100644 index 0000000..36abdb5 --- /dev/null +++ b/kirby/src/Blueprint/NodeIcon.php @@ -0,0 +1,27 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + * + * // TODO: include in test coverage in 3.9 + * @codeCoverageIgnore + */ +class NodeIcon extends NodeString +{ + public static function field() + { + $field = parent::field(); + $field->id = 'icon'; + $field->label->translations = ['en' => 'Icon']; + + return $field; + } +} diff --git a/kirby/src/Blueprint/NodeProperty.php b/kirby/src/Blueprint/NodeProperty.php new file mode 100644 index 0000000..e3646ab --- /dev/null +++ b/kirby/src/Blueprint/NodeProperty.php @@ -0,0 +1,27 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + * + * // TODO: include in test coverage in 3.9 + * @codeCoverageIgnore + */ +abstract class NodeProperty +{ + abstract public static function factory($value = null): static|null; + + public function render(ModelWithContent $model) + { + return null; + } +} diff --git a/kirby/src/Blueprint/NodeString.php b/kirby/src/Blueprint/NodeString.php new file mode 100644 index 0000000..1fc1d70 --- /dev/null +++ b/kirby/src/Blueprint/NodeString.php @@ -0,0 +1,39 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + * + * // TODO: include in test coverage in 3.9 + * @codeCoverageIgnore + */ +class NodeString extends NodeProperty +{ + public function __construct( + public string $value, + ) { + } + + public static function factory($value = null): static|null + { + if ($value === null) { + return $value; + } + + return new static($value); + } + + public function render(ModelWithContent $model): string|null + { + return $this->value; + } +} diff --git a/kirby/src/Blueprint/NodeText.php b/kirby/src/Blueprint/NodeText.php new file mode 100644 index 0000000..a72e711 --- /dev/null +++ b/kirby/src/Blueprint/NodeText.php @@ -0,0 +1,30 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + * + * // TODO: include in test coverage in 3.9 + * @codeCoverageIgnore + */ +class NodeText extends NodeI18n +{ + public function render(ModelWithContent $model): ?string + { + if ($text = parent::render($model)) { + return $model->toSafeString($text); + } + + return $text; + } +} diff --git a/kirby/src/Cache/ApcuCache.php b/kirby/src/Cache/ApcuCache.php index fb11eda..ee13215 100644 --- a/kirby/src/Cache/ApcuCache.php +++ b/kirby/src/Cache/ApcuCache.php @@ -15,11 +15,17 @@ use APCUIterator; */ class ApcuCache extends Cache { + /** + * Returns whether the cache is ready to + * store values + */ + public function enabled(): bool + { + return apcu_enabled(); + } + /** * Determines if an item exists in the cache - * - * @param string $key - * @return bool */ public function exists(string $key): bool { @@ -29,24 +35,19 @@ class ApcuCache extends Cache /** * Flushes the entire cache and returns * whether the operation was successful - * - * @return bool */ public function flush(): bool { if (empty($this->options['prefix']) === false) { return apcu_delete(new APCUIterator('!^' . preg_quote($this->options['prefix']) . '!')); - } else { - return apcu_clear_cache(); } + + return apcu_clear_cache(); } /** * Removes an item from the cache and returns * whether the operation was successful - * - * @param string $key - * @return bool */ public function remove(string $key): bool { @@ -56,13 +57,11 @@ class ApcuCache extends Cache /** * Internal method to retrieve the raw cache value; * needs to return a Value object or null if not found - * - * @param string $key - * @return \Kirby\Cache\Value|null */ - public function retrieve(string $key) + public function retrieve(string $key): Value|null { - return Value::fromJson(apcu_fetch($this->key($key))); + $value = apcu_fetch($this->key($key)); + return Value::fromJson($value); } /** @@ -73,14 +72,12 @@ class ApcuCache extends Cache * // put an item in the cache for 15 minutes * $cache->set('value', 'my value', 15); * - * - * @param string $key - * @param mixed $value - * @param int $minutes - * @return bool */ public function set(string $key, $value, int $minutes = 0): bool { - return apcu_store($this->key($key), (new Value($value, $minutes))->toJson(), $this->expiration($minutes)); + $key = $this->key($key); + $value = (new Value($value, $minutes))->toJson(); + $expires = $this->expiration($minutes); + return apcu_store($key, $value, $expires); } } diff --git a/kirby/src/Cache/Cache.php b/kirby/src/Cache/Cache.php index 5eeaec8..5b2a05b 100644 --- a/kirby/src/Cache/Cache.php +++ b/kirby/src/Cache/Cache.php @@ -2,6 +2,8 @@ namespace Kirby\Cache; +use Closure; + /** * Cache foundation * This abstract class is used as @@ -18,14 +20,11 @@ abstract class Cache { /** * Stores all options for the driver - * @var array */ - protected $options = []; + protected array $options = []; /** * Sets all parameters which are needed to connect to the cache storage - * - * @param array $options */ public function __construct(array $options = []) { @@ -33,87 +32,47 @@ abstract class Cache } /** - * Writes an item to the cache for a given number of minutes and - * returns whether the operation was successful; - * this needs to be defined by the driver - * - * - * // put an item in the cache for 15 minutes - * $cache->set('value', 'my value', 15); - * - * - * @param string $key - * @param mixed $value - * @param int $minutes - * @return bool + * Checks when the cache has been created; + * returns the creation timestamp on success + * and false if the item does not exist */ - abstract public function set(string $key, $value, int $minutes = 0): bool; - - /** - * Adds the prefix to the key if given - * - * @param string $key - * @return string - */ - protected function key(string $key): string + public function created(string $key): int|false { - if (empty($this->options['prefix']) === false) { - $key = $this->options['prefix'] . '/' . $key; - } - - return $key; - } - - /** - * Internal method to retrieve the raw cache value; - * needs to return a Value object or null if not found; - * this needs to be defined by the driver - * - * @param string $key - * @return \Kirby\Cache\Value|null - */ - abstract public function retrieve(string $key); - - /** - * Gets an item from the cache - * - * - * // get an item from the cache driver - * $value = $cache->get('value'); - * - * // return a default value if the requested item isn't cached - * $value = $cache->get('value', 'default value'); - * - * - * @param string $key - * @param mixed $default - * @return mixed - */ - public function get(string $key, $default = null) - { - // get the Value + // get the Value object $value = $this->retrieve($key); - // check for a valid cache value - if (!is_a($value, 'Kirby\Cache\Value')) { - return $default; + // check for a valid Value object + if ($value instanceof Value === false) { + return false; } - // remove the item if it is expired - if ($value->expires() > 0 && time() >= $value->expires()) { - $this->remove($key); - return $default; - } - - // return the pure value - return $value->value(); + // return the expires timestamp + return $value->created(); } + /** + * Returns whether the cache is ready to + * store values + */ + public function enabled(): bool + { + // TODO: Make this method abstract in a future + // release to ensure that cache drivers override it; + // until then, we assume that the cache is enabled + return true; + } + + /** + * Determines if an item exists in the cache + */ + public function exists(string $key): bool + { + return $this->expired($key) === false; + } + + /** * Calculates the expiration timestamp - * - * @param int $minutes - * @return int */ protected function expiration(int $minutes = 0): int { @@ -130,17 +89,14 @@ abstract class Cache * Checks when an item in the cache expires; * returns the expiry timestamp on success, null if the * item never expires and false if the item does not exist - * - * @param string $key - * @return int|null|false */ - public function expires(string $key) + public function expires(string $key): int|false|null { // get the Value object $value = $this->retrieve($key); // check for a valid Value object - if (!is_a($value, 'Kirby\Cache\Value')) { + if ($value instanceof Value === false) { return false; } @@ -150,9 +106,6 @@ abstract class Cache /** * Checks if an item in the cache is expired - * - * @param string $key - * @return bool */ public function expired(string $key): bool { @@ -160,83 +113,126 @@ abstract class Cache if ($expires === null) { return false; - } elseif (!is_int($expires)) { - return true; - } else { - return time() >= $expires; } + + if (is_int($expires) === false) { + return true; + } + + return time() >= $expires; } /** - * Checks when the cache has been created; - * returns the creation timestamp on success - * and false if the item does not exist - * - * @param string $key - * @return int|false + * Flushes the entire cache and returns + * whether the operation was successful; + * this needs to be defined by the driver */ - public function created(string $key) + abstract public function flush(): bool; + + /** + * Gets an item from the cache + * + * + * // get an item from the cache driver + * $value = $cache->get('value'); + * + * // return a default value if the requested item isn't cached + * $value = $cache->get('value', 'default value'); + * + */ + public function get(string $key, $default = null) { - // get the Value object + // get the Value $value = $this->retrieve($key); - // check for a valid Value object - if (!is_a($value, 'Kirby\Cache\Value')) { - return false; + // check for a valid cache value + if ($value instanceof Value === false) { + return $default; } - // return the expires timestamp - return $value->created(); + // remove the item if it is expired + if ($value->expires() > 0 && time() >= $value->expires()) { + $this->remove($key); + return $default; + } + + // return the pure value + return $value->value(); + } + + /** + * Returns a value by either getting it from the cache + * or via the callback function which then is stored in + * the cache for future retrieval. This method cannot be + * used for `null` as value to be cached. + * @since 3.8.0 + */ + public function getOrSet( + string $key, + Closure $result, + int $minutes = 0 + ) { + $value = $this->get($key); + $result = $value ?? $result(); + + if ($value === null) { + $this->set($key, $result, $minutes); + } + + return $result; + } + + /** + * Adds the prefix to the key if given + */ + protected function key(string $key): string + { + if (empty($this->options['prefix']) === false) { + $key = $this->options['prefix'] . '/' . $key; + } + + return $key; } /** * Alternate version for Cache::created($key) - * - * @param string $key - * @return int|false */ - public function modified(string $key) + public function modified(string $key): int|false { return static::created($key); } /** - * Determines if an item exists in the cache - * - * @param string $key - * @return bool + * Returns all passed cache options */ - public function exists(string $key): bool + public function options(): array { - return $this->expired($key) === false; + return $this->options; } /** * Removes an item from the cache and returns * whether the operation was successful; * this needs to be defined by the driver - * - * @param string $key - * @return bool */ abstract public function remove(string $key): bool; /** - * Flushes the entire cache and returns - * whether the operation was successful; + * Internal method to retrieve the raw cache value; + * needs to return a Value object or null if not found; * this needs to be defined by the driver - * - * @return bool */ - abstract public function flush(): bool; + abstract public function retrieve(string $key): Value|null; /** - * Returns all passed cache options + * Writes an item to the cache for a given number of minutes and + * returns whether the operation was successful; + * this needs to be defined by the driver * - * @return array + * + * // put an item in the cache for 15 minutes + * $cache->set('value', 'my value', 15); + * */ - public function options(): array - { - return $this->options; - } + abstract public function set(string $key, $value, int $minutes = 0): bool; } diff --git a/kirby/src/Cache/FileCache.php b/kirby/src/Cache/FileCache.php index 4063263..4916dc5 100644 --- a/kirby/src/Cache/FileCache.php +++ b/kirby/src/Cache/FileCache.php @@ -20,10 +20,8 @@ class FileCache extends Cache { /** * Full root including prefix - * - * @var string */ - protected $root; + protected string $root; /** * Sets all parameters which are needed for the file cache @@ -44,6 +42,7 @@ class FileCache extends Cache // build the full root including prefix $this->root = $this->options['root']; + if (empty($this->options['prefix']) === false) { $this->root .= '/' . $this->options['prefix']; } @@ -52,10 +51,17 @@ class FileCache extends Cache Dir::make($this->root, true); } + /** + * Returns whether the cache is ready to + * store values + */ + public function enabled(): bool + { + return is_writable($this->root) === true; + } + /** * Returns the full root including prefix - * - * @return string */ public function root(): string { @@ -64,9 +70,6 @@ class FileCache extends Cache /** * Returns the full path to a file for a given key - * - * @param string $key - * @return string */ protected function file(string $key): string { @@ -108,9 +111,9 @@ class FileCache extends Cache if (isset($this->options['extension'])) { return $file . '.' . $this->options['extension']; - } else { - return $file; } + + return $file; } /** @@ -121,11 +124,6 @@ class FileCache extends Cache * // put an item in the cache for 15 minutes * $cache->set('value', 'my value', 15); * - * - * @param string $key - * @param mixed $value - * @param int $minutes - * @return bool */ public function set(string $key, $value, int $minutes = 0): bool { @@ -137,11 +135,8 @@ class FileCache extends Cache /** * Internal method to retrieve the raw cache value; * needs to return a Value object or null if not found - * - * @param string $key - * @return \Kirby\Cache\Value|null */ - public function retrieve(string $key) + public function retrieve(string $key): Value|null { $file = $this->file($key); $value = F::read($file); @@ -153,11 +148,8 @@ class FileCache extends Cache * Checks when the cache has been created; * returns the creation timestamp on success * and false if the item does not exist - * - * @param string $key - * @return mixed */ - public function created(string $key) + public function created(string $key): int|false { // use the modification timestamp // as indicator when the cache has been created/overwritten @@ -165,15 +157,12 @@ class FileCache extends Cache // get the file for this cache key $file = $this->file($key); - return file_exists($file) ? filemtime($this->file($key)) : false; + return file_exists($file) ? filemtime($file) : false; } /** * Removes an item from the cache and returns * whether the operation was successful - * - * @param string $key - * @return bool */ public function remove(string $key): bool { @@ -190,9 +179,6 @@ class FileCache extends Cache /** * Removes empty directories safely by checking each directory * up to the root directory - * - * @param string $dir - * @return void */ protected function removeEmptyDirectories(string $dir): void { @@ -202,7 +188,13 @@ class FileCache extends Cache // checks all directory segments until reaching the root directory while (Str::startsWith($dir, $this->root()) === true && $dir !== $this->root()) { - $files = array_diff(scandir($dir) ?? [], ['.', '..']); + $files = scandir($dir); + + if ($files === false) { + $files = []; // @codeCoverageIgnore + } + + $files = array_diff($files, ['.', '..']); if (empty($files) === true && Dir::remove($dir) === true) { // continue with the next level up @@ -212,7 +204,7 @@ class FileCache extends Cache break; } } - } catch (Exception $e) { // @codeCoverageIgnore + } catch (Exception) { // @codeCoverageIgnore // silently stops the process } } @@ -220,12 +212,13 @@ class FileCache extends Cache /** * Flushes the entire cache and returns * whether the operation was successful - * - * @return bool */ public function flush(): bool { - if (Dir::remove($this->root) === true && Dir::make($this->root) === true) { + if ( + Dir::remove($this->root) === true && + Dir::make($this->root) === true + ) { return true; } diff --git a/kirby/src/Cache/MemCached.php b/kirby/src/Cache/MemCached.php index 591919f..d6b1f89 100644 --- a/kirby/src/Cache/MemCached.php +++ b/kirby/src/Cache/MemCached.php @@ -16,10 +16,14 @@ use Memcached as MemcachedExt; class MemCached extends Cache { /** - * store for the memcache connection - * @var \Memcached + * Store for the memcache connection */ - protected $connection; + protected MemcachedExt $connection; + + /** + * Stores whether the connection was successful + */ + protected bool $enabled; /** * Sets all parameters which are needed to connect to Memcached @@ -39,7 +43,19 @@ class MemCached extends Cache parent::__construct(array_merge($defaults, $options)); $this->connection = new MemcachedExt(); - $this->connection->addServer($this->options['host'], $this->options['port']); + $this->enabled = $this->connection->addServer( + $this->options['host'], + $this->options['port'] + ); + } + + /** + * Returns whether the cache is ready to + * store values + */ + public function enabled(): bool + { + return $this->enabled; } /** @@ -50,35 +66,28 @@ class MemCached extends Cache * // put an item in the cache for 15 minutes * $cache->set('value', 'my value', 15); * - * - * @param string $key - * @param mixed $value - * @param int $minutes - * @return bool */ public function set(string $key, $value, int $minutes = 0): bool { - return $this->connection->set($this->key($key), (new Value($value, $minutes))->toJson(), $this->expiration($minutes)); + $key = $this->key($key); + $value = (new Value($value, $minutes))->toJson(); + $expires = $this->expiration($minutes); + return $this->connection->set($key, $value, $expires); } /** * Internal method to retrieve the raw cache value; * needs to return a Value object or null if not found - * - * @param string $key - * @return \Kirby\Cache\Value|null */ - public function retrieve(string $key) + public function retrieve(string $key): Value|null { - return Value::fromJson($this->connection->get($this->key($key))); + $value = $this->connection->get($this->key($key)); + return Value::fromJson($value); } /** * Removes an item from the cache and returns * whether the operation was successful - * - * @param string $key - * @return bool */ public function remove(string $key): bool { @@ -89,8 +98,6 @@ class MemCached extends Cache * Flushes the entire cache and returns * whether the operation was successful; * WARNING: Memcached only supports flushing the whole cache at once! - * - * @return bool */ public function flush(): bool { diff --git a/kirby/src/Cache/MemoryCache.php b/kirby/src/Cache/MemoryCache.php index 3ee6636..55fdbc1 100644 --- a/kirby/src/Cache/MemoryCache.php +++ b/kirby/src/Cache/MemoryCache.php @@ -15,9 +15,17 @@ class MemoryCache extends Cache { /** * Cache data - * @var array */ - protected $store = []; + protected array $store = []; + + /** + * Returns whether the cache is ready to + * store values + */ + public function enabled(): bool + { + return true; + } /** * Writes an item to the cache for a given number of minutes and @@ -27,11 +35,6 @@ class MemoryCache extends Cache * // put an item in the cache for 15 minutes * $cache->set('value', 'my value', 15); * - * - * @param string $key - * @param mixed $value - * @param int $minutes - * @return bool */ public function set(string $key, $value, int $minutes = 0): bool { @@ -42,11 +45,8 @@ class MemoryCache extends Cache /** * Internal method to retrieve the raw cache value; * needs to return a Value object or null if not found - * - * @param string $key - * @return \Kirby\Cache\Value|null */ - public function retrieve(string $key) + public function retrieve(string $key): Value|null { return $this->store[$key] ?? null; } @@ -54,25 +54,20 @@ class MemoryCache extends Cache /** * Removes an item from the cache and returns * whether the operation was successful - * - * @param string $key - * @return bool */ public function remove(string $key): bool { if (isset($this->store[$key])) { unset($this->store[$key]); return true; - } else { - return false; } + + return false; } /** * Flushes the entire cache and returns * whether the operation was successful - * - * @return bool */ public function flush(): bool { diff --git a/kirby/src/Cache/NullCache.php b/kirby/src/Cache/NullCache.php index 36b419e..7c2211d 100644 --- a/kirby/src/Cache/NullCache.php +++ b/kirby/src/Cache/NullCache.php @@ -13,6 +13,15 @@ namespace Kirby\Cache; */ class NullCache extends Cache { + /** + * Returns whether the cache is ready to + * store values + */ + public function enabled(): bool + { + return false; + } + /** * Writes an item to the cache for a given number of minutes and * returns whether the operation was successful @@ -21,11 +30,6 @@ class NullCache extends Cache * // put an item in the cache for 15 minutes * $cache->set('value', 'my value', 15); * - * - * @param string $key - * @param mixed $value - * @param int $minutes - * @return bool */ public function set(string $key, $value, int $minutes = 0): bool { @@ -35,11 +39,8 @@ class NullCache extends Cache /** * Internal method to retrieve the raw cache value; * needs to return a Value object or null if not found - * - * @param string $key - * @return \Kirby\Cache\Value|null */ - public function retrieve(string $key) + public function retrieve(string $key): Value|null { return null; } @@ -47,9 +48,6 @@ class NullCache extends Cache /** * Removes an item from the cache and returns * whether the operation was successful - * - * @param string $key - * @return bool */ public function remove(string $key): bool { @@ -59,8 +57,6 @@ class NullCache extends Cache /** * Flushes the entire cache and returns * whether the operation was successful - * - * @return bool */ public function flush(): bool { diff --git a/kirby/src/Cache/Value.php b/kirby/src/Cache/Value.php index 3a1105e..45cfdc7 100644 --- a/kirby/src/Cache/Value.php +++ b/kirby/src/Cache/Value.php @@ -19,7 +19,6 @@ class Value { /** * Cached value - * @var mixed */ protected $value; @@ -27,35 +26,30 @@ class Value * the number of minutes until the value expires * @todo Rename this property to $expiry to reflect * both minutes and absolute timestamps - * @var int */ - protected $minutes; + protected int $minutes; /** * Creation timestamp - * @var int */ - protected $created; + protected int $created; /** * Constructor * - * @param mixed $value * @param int $minutes the number of minutes until the value expires * or an absolute UNIX timestamp * @param int $created the UNIX timestamp when the value has been created */ - public function __construct($value, int $minutes = 0, int $created = null) + public function __construct($value, int $minutes = 0, int|null $created = null) { $this->value = $value; - $this->minutes = $minutes ?? 0; + $this->minutes = $minutes; $this->created = $created ?? time(); } /** * Returns the creation date as UNIX timestamp - * - * @return int */ public function created(): int { @@ -65,10 +59,8 @@ class Value /** * Returns the expiration date as UNIX timestamp or * null if the value never expires - * - * @return int|null */ - public function expires(): ?int + public function expires(): int|null { // 0 = keep forever if ($this->minutes === 0) { @@ -85,41 +77,37 @@ class Value /** * Creates a value object from an array - * - * @param array $array - * @return static */ - public static function fromArray(array $array) + public static function fromArray(array $array): static { - return new static($array['value'] ?? null, $array['minutes'] ?? 0, $array['created'] ?? null); + return new static( + $array['value'] ?? null, + $array['minutes'] ?? 0, + $array['created'] ?? null + ); } /** * Creates a value object from a JSON string; * returns null on error - * - * @param string $json - * @return static|null */ - public static function fromJson(string $json) + public static function fromJson(string $json): static|null { try { $array = json_decode($json, true); - if (is_array($array)) { + if (is_array($array) === true) { return static::fromArray($array); - } else { - return null; } - } catch (Throwable $e) { + + return null; + } catch (Throwable) { return null; } } /** * Converts the object to a JSON string - * - * @return string */ public function toJson(): string { @@ -128,8 +116,6 @@ class Value /** * Converts the object to an array - * - * @return array */ public function toArray(): array { @@ -142,8 +128,6 @@ class Value /** * Returns the pure value - * - * @return mixed */ public function value() { diff --git a/kirby/src/Cms/Api.php b/kirby/src/Cms/Api.php index 30aa140..50046f2 100644 --- a/kirby/src/Cms/Api.php +++ b/kirby/src/Cms/Api.php @@ -5,6 +5,7 @@ namespace Kirby\Cms; use Kirby\Api\Api as BaseApi; use Kirby\Exception\NotFoundException; use Kirby\Form\Form; +use Kirby\Session\Session; /** * Api @@ -25,38 +26,30 @@ class Api extends BaseApi /** * Execute an API call for the given path, * request method and optional request data - * - * @param string|null $path - * @param string $method - * @param array $requestData - * @return mixed */ - public function call(string $path = null, string $method = 'GET', array $requestData = []) - { + public function call( + string|null $path = null, + string $method = 'GET', + array $requestData = [] + ) { $this->setRequestMethod($method); $this->setRequestData($requestData); $this->kirby->setCurrentLanguage($this->language()); $allowImpersonation = $this->kirby()->option('api.allowImpersonation', false); - if ($user = $this->kirby->user(null, $allowImpersonation)) { - $translation = $user->language(); - } else { - $translation = $this->kirby->panelLanguage(); - } + + $translation = $this->kirby->user(null, $allowImpersonation)?->language(); + $translation ??= $this->kirby->panelLanguage(); $this->kirby->setCurrentTranslation($translation); return parent::call($path, $method, $requestData); } /** - * @param mixed $model - * @param string $name - * @param string|null $path - * @return mixed * @throws \Kirby\Exception\NotFoundException if the field type cannot be found or the field cannot be loaded */ - public function fieldApi($model, string $name, string $path = null) + public function fieldApi($model, string $name, string|null $path = null) { $field = Form::for($model)->field($name); @@ -75,11 +68,9 @@ class Api extends BaseApi * parent path and filename * * @param string|null $path Path to file's parent model - * @param string $filename Filename - * @return \Kirby\Cms\File|null * @throws \Kirby\Exception\NotFoundException if the file cannot be found */ - public function file(string $path = null, string $filename) + public function file(string|null $path = null, string $filename): File|null { return Find::file($path, $filename); } @@ -88,31 +79,26 @@ class Api extends BaseApi * Returns the model's object for the given path * * @param string $path Path to parent model - * @return \Kirby\Cms\Model|null * @throws \Kirby\Exception\InvalidArgumentException if the model type is invalid * @throws \Kirby\Exception\NotFoundException if the model cannot be found */ - public function parent(string $path) + public function parent(string $path): Model|null { return Find::parent($path); } /** * Returns the Kirby instance - * - * @return \Kirby\Cms\App */ - public function kirby() + public function kirby(): App { return $this->kirby; } /** * Returns the language request header - * - * @return string|null */ - public function language(): ?string + public function language(): string|null { return $this->requestQuery('language') ?? $this->requestHeaders('x-language'); } @@ -121,10 +107,9 @@ class Api extends BaseApi * Returns the page object for the given id * * @param string $id Page's id - * @return \Kirby\Cms\Page|null * @throws \Kirby\Exception\NotFoundException if the page cannot be found */ - public function page(string $id) + public function page(string $id): Page|null { return Find::page($id); } @@ -133,39 +118,26 @@ class Api extends BaseApi * Returns the subpages for the given * parent. The subpages can be filtered * by status (draft, listed, unlisted, published, all) - * - * @param string|null $parentId - * @param string|null $status - * @return \Kirby\Cms\Pages */ - public function pages(string $parentId = null, string $status = null) + public function pages(string|null $parentId = null, string|null $status = null): Pages { $parent = $parentId === null ? $this->site() : $this->page($parentId); - switch ($status) { - case 'all': - return $parent->childrenAndDrafts(); - case 'draft': - case 'drafts': - return $parent->drafts(); - case 'listed': - return $parent->children()->listed(); - case 'unlisted': - return $parent->children()->unlisted(); - case 'published': - default: - return $parent->children(); - } + return match ($status) { + 'all' => $parent->childrenAndDrafts(), + 'draft', 'drafts' => $parent->drafts(), + 'listed' => $parent->children()->listed(), + 'unlisted' => $parent->children()->unlisted(), + 'published' => $parent->children(), + default => $parent->children() + }; } /** * Search for direct subpages of the * given parent - * - * @param string|null $parent - * @return \Kirby\Cms\Pages */ - public function searchPages(string $parent = null) + public function searchPages(string|null $parent = null): Pages { $pages = $this->pages($parent, $this->requestQuery('status')); @@ -180,9 +152,8 @@ class Api extends BaseApi * Returns the current Session instance * * @param array $options Additional options, see the session component - * @return \Kirby\Session\Session */ - public function session(array $options = []) + public function session(array $options = []): Session { return $this->kirby->session(array_merge([ 'detect' => true @@ -192,10 +163,9 @@ class Api extends BaseApi /** * Setter for the parent Kirby instance * - * @param \Kirby\Cms\App $kirby * @return $this */ - protected function setKirby(App $kirby) + protected function setKirby(App $kirby): static { $this->kirby = $kirby; return $this; @@ -203,10 +173,8 @@ class Api extends BaseApi /** * Returns the site object - * - * @return \Kirby\Cms\Site */ - public function site() + public function site(): Site { return $this->kirby->site(); } @@ -217,10 +185,9 @@ class Api extends BaseApi * id is passed * * @param string|null $id User's id - * @return \Kirby\Cms\User|null * @throws \Kirby\Exception\NotFoundException if the user for the given id cannot be found */ - public function user(string $id = null) + public function user(string|null $id = null): User|null { try { return Find::user($id); @@ -235,10 +202,8 @@ class Api extends BaseApi /** * Returns the users collection - * - * @return \Kirby\Cms\Users */ - public function users() + public function users(): Users { return $this->kirby->users(); } diff --git a/kirby/src/Cms/App.php b/kirby/src/Cms/App.php index 04cb4be..4cd8895 100644 --- a/kirby/src/Cms/App.php +++ b/kirby/src/Cms/App.php @@ -2,8 +2,10 @@ namespace Kirby\Cms; +use Closure; use Kirby\Data\Data; use Kirby\Exception\ErrorPageException; +use Kirby\Exception\Exception; use Kirby\Exception\InvalidArgumentException; use Kirby\Exception\LogicException; use Kirby\Exception\NotFoundException; @@ -23,6 +25,7 @@ use Kirby\Toolkit\Config; use Kirby\Toolkit\Controller; use Kirby\Toolkit\Properties; use Kirby\Toolkit\Str; +use Kirby\Uuid\Uuid; use Throwable; /** @@ -380,7 +383,7 @@ class App */ public function collections() { - return $this->collections = $this->collections ?? new Collections(); + return $this->collections ??= new Collections(); } /** @@ -435,7 +438,7 @@ class App $salt = $this->option('content.salt', $default); - if (is_a($salt, 'Closure') === true) { + if ($salt instanceof Closure) { $salt = $salt($model); } @@ -496,7 +499,11 @@ class App // registry controller if ($controller = $this->extension('controllers', $name)) { - return is_a($controller, 'Kirby\Toolkit\Controller') ? $controller : new Controller($controller); + if ($controller instanceof Controller) { + return $controller; + } + + return new Controller($controller); } return null; @@ -520,7 +527,7 @@ class App * @param string|null $check Pass a token here to compare it to the one in the session * @return string|bool Either the token or a boolean check result */ - public function csrf(?string $check = null) + public function csrf(string|null $check = null) { $session = $this->session(); @@ -557,7 +564,7 @@ class App */ public function defaultLanguage() { - return $this->defaultLanguage = $this->defaultLanguage ?? $this->languages()->default(); + return $this->defaultLanguage ??= $this->languages()->default(); } /** @@ -633,28 +640,26 @@ class App */ public function file(string $path, $parent = null, bool $drafts = true) { + // find by global UUID + if (Uuid::is($path, 'file') === true) { + // prefer files of parent, when parent given + return Uuid::for($path, $parent?->files())->model(); + } + $parent = $parent ?? $this->site(); $id = dirname($path); $filename = basename($path); - if (is_a($parent, 'Kirby\Cms\User') === true) { + if ($parent instanceof User) { return $parent->file($filename); } - if (is_a($parent, 'Kirby\Cms\File') === true) { + if ($parent instanceof File) { $parent = $parent->parent(); } if ($id === '.') { - if ($file = $parent->file($filename)) { - return $file; - } - - if ($file = $this->site()->file($filename)) { - return $file; - } - - return null; + return $parent->file($filename) ?? $this->site()->file($filename); } if ($page = $this->page($id, $parent, $drafts)) { @@ -680,7 +685,7 @@ class App * * @todo merge with App::file() */ - public function image(?string $path = null) + public function image(string|null $path = null) { if ($path === null) { return $this->site()->page()->image(); @@ -693,23 +698,13 @@ class App $uri = null; } - switch ($uri) { - case '/': - $parent = $this->site(); - break; - case null: - $parent = $this->site()->page(); - break; - default: - $parent = $this->site()->page($uri); - break; - } + $parent = match ($uri) { + '/' => $this->site(), + null => $this->site()->page(), + default => $this->site()->page($uri) + }; - if ($parent) { - return $parent->image($filename); - } - - return null; + return $parent?->image($filename); } /** @@ -718,18 +713,19 @@ class App * @param \Kirby\Cms\App|null $instance * @param bool $lazy If `true`, the instance is only returned if already existing * @return static|null + * @psalm-return ($lazy is false ? static : static|null) */ public static function instance(self $instance = null, bool $lazy = false) { - if ($instance === null) { - if ($lazy === true) { - return static::$instance; - } else { - return static::$instance ?? new static(); - } + if ($instance !== null) { + return static::$instance = $instance; } - return static::$instance = $instance; + if ($lazy === true) { + return static::$instance; + } + + return static::$instance ?? new static(); } /** @@ -746,8 +742,8 @@ class App $response = $this->response(); // any direct exception will be turned into an error page - if (is_a($input, 'Throwable') === true) { - if (is_a($input, 'Kirby\Exception\Exception') === true) { + if ($input instanceof Throwable) { + if ($input instanceof Exception) { $code = $input->getHttpCode(); } else { $code = $input->getCode(); @@ -778,7 +774,7 @@ class App } // (Modified) global response configuration, e.g. in routes - if (is_a($input, 'Kirby\Cms\Responder') === true) { + if ($input instanceof Responder) { // return the passed object unmodified (without injecting headers // from the global object) to allow a complete response override // https://github.com/getkirby/kirby/pull/4144#issuecomment-1034766726 @@ -786,37 +782,41 @@ class App } // Responses - if (is_a($input, 'Kirby\Http\Response') === true) { + if ($input instanceof Response) { $data = $input->toArray(); // inject headers from the global response configuration // lazily (only if they are not already set); // the case-insensitive nature of headers will be // handled by PHP's `header()` function - $data['headers'] = array_merge($response->headers(), $data['headers']); + $data['headers'] = array_merge( + $response->headers(), + $data['headers'] + ); return new Response($data); } // Pages - if (is_a($input, 'Kirby\Cms\Page')) { + if ($input instanceof Page) { try { $html = $input->render(); } catch (ErrorPageException $e) { return $this->io($e); } - if ($input->isErrorPage() === true) { - if ($response->code() === null) { - $response->code(404); - } + if ( + $input->isErrorPage() === true && + $response->code() === null + ) { + $response->code(404); } return $response->send($html); } // Files - if (is_a($input, 'Kirby\Cms\File')) { + if ($input instanceof File) { return $response->redirect($input->mediaUrl(), 307)->send(); } @@ -844,7 +844,7 @@ class App * @param array $data * @return string */ - public function kirbytag($type, ?string $value = null, array $attr = [], array $data = []): string + public function kirbytag($type, string|null $value = null, array $attr = [], array $data = []): string { if (is_array($type) === true) { $kirbytag = $type; @@ -895,24 +895,13 @@ class App * @internal * @param string|null $text * @param array $options - * @param bool $inline (deprecated: use $options['markdown']['inline'] instead) * @return string - * @todo remove $inline parameter in in 3.8.0 */ - public function kirbytext(string $text = null, array $options = [], bool $inline = false): string + public function kirbytext(string $text = null, array $options = []): string { - // warning for deprecated fourth parameter - // @codeCoverageIgnoreStart - if (func_num_args() === 3) { - Helpers::deprecated('Cms\App::kirbytext(): the $inline parameter is deprecated and will be removed in Kirby 3.8.0. Use $options[\'markdown\'][\'inline\'] instead.'); - } - // @codeCoverageIgnoreEnd - - $options['markdown']['inline'] ??= $inline; - $text = $this->apply('kirbytext:before', compact('text'), 'text'); $text = $this->kirbytags($text, $options); - $text = $this->markdown($text, $options['markdown']); + $text = $this->markdown($text, $options['markdown'] ?? []); if ($this->option('smartypants', false) !== false) { $text = $this->smartypants($text); @@ -936,14 +925,18 @@ class App } if ($code === 'default') { - return $this->languages()->default(); + return $this->defaultLanguage(); } + // if requesting a non-default language, + // find it but don't cache it if ($code !== null) { return $this->languages()->find($code); } - return $this->language = $this->language ?? $this->languages()->default(); + // otherwise return language set by `AppTranslation::setCurrentLanguage` + // or default language + return $this->language ??= $this->defaultLanguage(); } /** @@ -953,22 +946,15 @@ class App * @param string|null $languageCode * @return string|null */ - public function languageCode(string $languageCode = null): ?string + public function languageCode(string $languageCode = null): string|null { - if ($language = $this->language($languageCode)) { - return $language->code(); - } - - return null; + return $this->language($languageCode)?->code(); } /** * Returns all available site languages - * - * @param bool - * @return \Kirby\Cms\Languages */ - public function languages(bool $clone = true) + public function languages(bool $clone = true): Languages { if ($this->languages !== null) { return $clone === true ? clone $this->languages : $this->languages; @@ -1006,34 +992,18 @@ class App * * @internal * @param string|null $text - * @param bool|array $options Boolean inline value is deprecated, use `['inline' => true]` instead + * @param array $options * @return string - * @todo remove boolean $options in in 3.8.0 */ - public function markdown(string $text = null, $options = null): string + public function markdown(string $text = null, array $options = null): string { - // support for the old syntax to enable inline mode as second argument - // @codeCoverageIgnoreStart - if (is_bool($options) === true) { - Helpers::deprecated('Cms\App::markdown(): Passing a boolean as second parameter has been deprecated and won\'t be supported anymore in Kirby 3.8.0. Instead pass array with the key "inline" set to true or false.'); - - $options = [ - 'inline' => $options - ]; - } - // @codeCoverageIgnoreEnd - // merge global options with local options $options = array_merge( $this->options['markdown'] ?? [], (array)$options ); - // TODO: remove passing the $inline parameter in 3.8.0 - // $options['inline'] is set to `false` to avoid the deprecation - // warning in the component; this can also be removed in 3.8.0 - $inline = $options['inline'] ??= false; - return ($this->component('markdown'))($this, $text, $options, $inline); + return ($this->component('markdown'))($this, $text, $options); } /** @@ -1059,7 +1029,7 @@ class App */ public function nonce(): string { - return $this->nonce = $this->nonce ?? base64_encode(random_bytes(20)); + return $this->nonce ??= base64_encode(random_bytes(20)); } /** @@ -1096,7 +1066,7 @@ class App // load the main config options $root = $this->root('config'); - $options = F::load($root . '/config.php', []); + $options = F::load($root . '/config.php', [], allowOutput: false); // merge into one clean options array return $this->options = array_replace_recursive(Config::$data, $options); @@ -1111,19 +1081,27 @@ class App */ protected function optionsFromEnvironment(array $props = []): array { - $globalUrl = $this->options['url'] ?? null; + $root = $this->root('config'); - // create the environment based on the URL setup + // first load `config/env.php` to access its `url` option + $envOptions = F::load($root . '/env.php', [], allowOutput: false); + + // use the option from the main `config.php`, + // but allow the `env.php` to override it + $globalUrl = $envOptions['url'] ?? $this->options['url'] ?? null; + + // create the URL setup based on hostname and server IP address $this->environment = new Environment([ 'allowed' => $globalUrl, 'cli' => $props['cli'] ?? null, ], $props['server'] ?? null); - // merge into one clean options array - $options = $this->environment()->options($this->root('config')); - $this->options = array_replace_recursive($this->options, $options); + // merge into one clean options array; + // the `env.php` options always override everything else + $hostAddrOptions = $this->environment()->options($root); + $this->options = array_replace_recursive($this->options, $hostAddrOptions, $envOptions); - // reload the environment if the environment config has overridden + // reload the environment if the host/address config has overridden // the `url` option; this ensures that the base URL is correct $envUrl = $this->options['url'] ?? null; if ($envUrl !== $globalUrl) { @@ -1201,12 +1179,17 @@ class App * @param bool $drafts * @return \Kirby\Cms\Page|null */ - public function page(?string $id = null, $parent = null, bool $drafts = true) + public function page(string|null $id = null, $parent = null, bool $drafts = true) { if ($id === null) { return null; } + // find by global UUID + if (Uuid::is($id, 'page') === true) { + return Uuid::for($id, $parent?->childrenAndDrafts())->model(); + } + $parent = $parent ?? $this->site(); if ($page = $parent->find($id)) { @@ -1252,6 +1235,10 @@ class App */ public function render(string $path = null, string $method = null) { + if (($_ENV['KIRBY_RENDER'] ?? true) === false) { + return null; + } + return $this->io($this->call($path, $method)); } @@ -1308,7 +1295,10 @@ class App // search for a draft if the page cannot be found if (!$page && $draft = $site->draft($path)) { - if ($this->user() || $draft->isVerified($this->request()->get('token'))) { + if ( + $this->user() || + $draft->isVerified($this->request()->get('token')) + ) { $page = $draft; } } @@ -1335,7 +1325,7 @@ class App } return $response->body($output); - } catch (NotFoundException $e) { + } catch (NotFoundException) { return null; } } @@ -1359,7 +1349,7 @@ class App */ public function response() { - return $this->response = $this->response ?? new Responder(); + return $this->response ??= new Responder(); } /** @@ -1369,7 +1359,7 @@ class App */ public function roles() { - return $this->roles = $this->roles ?? Roles::load($this->root('roles')); + return $this->roles ??= Roles::load($this->root('roles')); } /** @@ -1378,7 +1368,7 @@ class App * @param string $type * @return string|null */ - public function root(string $type = 'index'): ?string + public function root(string $type = 'index'): string|null { return $this->roots->__get($type); } @@ -1572,12 +1562,16 @@ class App * @deprecated 3.7.0 Use `$kirby->environment()` instead * * @return \Kirby\Http\Environment - * @todo Start throwing deprecation warnings in 3.8.0 + * @deprecated Will be removed in Kirby 3.9.0 * @todo Remove in 3.9.0 * @codeCoverageIgnore */ public function server() { + // @codeCoverageIgnoreStart + Helpers::deprecated('$kirby->server() has been deprecated and will be removed in Kirby 3.9.0. Use $kirby->environment() instead.'); + // @codeCoverageIgnoreEnd + return $this->environment(); } @@ -1588,7 +1582,7 @@ class App */ public function site() { - return $this->site = $this->site ?? new Site([ + return $this->site ??= new Site([ 'errorPageId' => $this->options['error'] ?? 'error', 'homePageId' => $this->options['home'] ?? 'home', 'kirby' => $this, @@ -1609,7 +1603,9 @@ class App if ($options === false) { return $text; - } elseif (is_array($options) === false) { + } + + if (is_array($options) === false) { $options = []; } @@ -1628,13 +1624,13 @@ class App * Uses the snippet component to create * and return a template snippet * - * @internal * @param mixed $name * @param array|object $data Variables or an object that becomes `$item` * @param bool $return On `false`, directly echo the snippet * @return string|null + * @psalm-return ($return is true ? string : null) */ - public function snippet($name, $data = [], bool $return = true): ?string + public function snippet($name, $data = [], bool $return = true): string|null { if (is_object($data) === true) { $data = ['item' => $data]; @@ -1657,7 +1653,7 @@ class App */ public function system() { - return $this->system = $this->system ?? new System($this); + return $this->system ??= new System($this); } /** @@ -1740,6 +1736,7 @@ class App * @param string $type * @param bool $object If set to `true`, the URL is converted to an object * @return string|\Kirby\Http\Uri|null + * @psalm-return ($object is false ? string|null : \Kirby\Http\Uri) */ public function url(string $type = 'index', bool $object = false) { @@ -1777,11 +1774,11 @@ class App * @return string|null * @throws \Kirby\Exception\LogicException if the Kirby version cannot be detected */ - public static function version(): ?string + public static function version(): string|null { try { - return static::$version = static::$version ?? Data::read(dirname(__DIR__, 2) . '/composer.json')['version'] ?? null; - } catch (Throwable $e) { + return static::$version ??= Data::read(dirname(__DIR__, 2) . '/composer.json')['version'] ?? null; + } catch (Throwable) { throw new LogicException('The Kirby version cannot be detected. The composer.json is probably missing or not readable.'); } } @@ -1803,6 +1800,6 @@ class App */ public function visitor() { - return $this->visitor = $this->visitor ?? new Visitor(); + return $this->visitor ??= new Visitor(); } } diff --git a/kirby/src/Cms/AppCaches.php b/kirby/src/Cms/AppCaches.php index 2bea1ed..79ec6b9 100644 --- a/kirby/src/Cms/AppCaches.php +++ b/kirby/src/Cms/AppCaches.php @@ -2,6 +2,7 @@ namespace Kirby\Cms; +use Kirby\Cache\Cache; use Kirby\Cache\NullCache; use Kirby\Exception\InvalidArgumentException; @@ -54,7 +55,7 @@ trait AppCaches $cache = new $className($options); // check if it is a usable cache object - if (is_a($cache, 'Kirby\Cache\Cache') !== true) { + if ($cache instanceof Cache === false) { throw new InvalidArgumentException([ 'key' => 'app.invalid.cacheType', 'data' => ['type' => $type] @@ -72,7 +73,8 @@ trait AppCaches */ protected function cacheOptions(string $key): array { - $options = $this->option($this->cacheOptionsKey($key), false); + $options = $this->option($this->cacheOptionsKey($key), null); + $options ??= $this->core()->caches()[$key] ?? false; if ($options === false) { return [ @@ -94,9 +96,9 @@ trait AppCaches if ($options === true) { return $defaults; - } else { - return array_merge($defaults, $options); } + + return array_merge($defaults, $options); } /** diff --git a/kirby/src/Cms/AppErrors.php b/kirby/src/Cms/AppErrors.php index a1013a5..af7e916 100644 --- a/kirby/src/Cms/AppErrors.php +++ b/kirby/src/Cms/AppErrors.php @@ -2,9 +2,12 @@ namespace Kirby\Cms; +use Closure; +use Kirby\Exception\Exception; use Kirby\Filesystem\F; use Kirby\Http\Response; use Kirby\Toolkit\I18n; +use Throwable; use Whoops\Handler\CallbackHandler; use Whoops\Handler\Handler; use Whoops\Handler\PlainTextHandler; @@ -84,7 +87,7 @@ trait AppErrors $handler = new CallbackHandler(function ($exception, $inspector, $run) { $fatal = $this->option('fatal'); - if (is_a($fatal, 'Closure') === true) { + if ($fatal instanceof Closure) { echo $fatal($this, $exception); } else { include $this->root('kirby') . '/views/fatal.php'; @@ -109,11 +112,11 @@ trait AppErrors protected function handleJsonErrors(): void { $handler = new CallbackHandler(function ($exception, $inspector, $run) { - if (is_a($exception, 'Kirby\Exception\Exception') === true) { + if ($exception instanceof Exception) { $httpCode = $exception->getHttpCode(); $code = $exception->getCode(); $details = $exception->getDetails(); - } elseif (is_a($exception, '\Throwable') === true) { + } elseif ($exception instanceof Throwable) { $httpCode = 500; $code = $exception->getCode(); $details = null; @@ -160,19 +163,19 @@ trait AppErrors $whoops = $this->whoops(); $whoops->clearHandlers(); $whoops->pushHandler($handler); - $whoops->pushHandler($this->getExceptionHookWhoopsHandler()); + $whoops->pushHandler($this->getAdditionalWhoopsHandler()); $whoops->register(); // will only do something if not already registered } /** - * Initializes a callback handler for triggering the `system.exception` hook - * - * @return \Whoops\Handler\CallbackHandler + * Whoops callback handler for additional error handling + * (`system.exception` hook and output to error log) */ - protected function getExceptionHookWhoopsHandler(): CallbackHandler + protected function getAdditionalWhoopsHandler(): CallbackHandler { return new CallbackHandler(function ($exception, $inspector, $run) { $this->trigger('system.exception', compact('exception')); + error_log($exception); return Handler::DONE; }); } diff --git a/kirby/src/Cms/AppPlugins.php b/kirby/src/Cms/AppPlugins.php index 161fb2b..39b03b6 100644 --- a/kirby/src/Cms/AppPlugins.php +++ b/kirby/src/Cms/AppPlugins.php @@ -52,6 +52,7 @@ trait AppPlugins 'blueprints' => [], 'cacheTypes' => [], 'collections' => [], + 'commands' => [], 'components' => [], 'controllers' => [], 'collectionFilters' => [], @@ -120,14 +121,14 @@ trait AppPlugins protected function extendApi($api): array { if (is_array($api) === true) { - if (is_a($api['routes'] ?? [], 'Closure') === true) { + if (($api['routes'] ?? []) instanceof Closure) { $api['routes'] = $api['routes']($this); } return $this->extensions['api'] = A::merge($this->extensions['api'], $api, A::MERGE_APPEND); - } else { - return $this->extensions['api']; } + + return $this->extensions['api']; } /** @@ -139,10 +140,7 @@ trait AppPlugins protected function extendAreas(array $areas): array { foreach ($areas as $id => $area) { - if (isset($this->extensions['areas'][$id]) === false) { - $this->extensions['areas'][$id] = []; - } - + $this->extensions['areas'][$id] ??= []; $this->extensions['areas'][$id][] = $area; } @@ -215,6 +213,17 @@ trait AppPlugins return $this->extensions['cacheTypes'] = array_merge($this->extensions['cacheTypes'], $cacheTypes); } + /** + * Registers additional CLI commands + * + * @param array $commands + * @return array + */ + protected function extendCommands(array $commands): array + { + return $this->extensions['commands'] = array_merge($this->extensions['commands'], $commands); + } + /** * Registers additional collection filters * @@ -376,9 +385,7 @@ trait AppPlugins protected function extendHooks(array $hooks): array { foreach ($hooks as $name => $callbacks) { - if (isset($this->extensions['hooks'][$name]) === false) { - $this->extensions['hooks'][$name] = []; - } + $this->extensions['hooks'][$name] ??= []; if (is_array($callbacks) === false) { $callbacks = [$callbacks]; @@ -520,7 +527,7 @@ trait AppPlugins */ protected function extendRoutes($routes): array { - if (is_a($routes, 'Closure') === true) { + if ($routes instanceof Closure) { $routes = $routes($this); } @@ -705,7 +712,7 @@ trait AppPlugins $class = str_replace(['.', '-', '_'], '', $name) . 'Page'; // load the model class - F::loadOnce($model); + F::loadOnce($model, allowOutput: false); if (class_exists($class) === true) { $models[$name] = $class; @@ -896,7 +903,7 @@ trait AppPlugins $styles = $dir . '/index.css'; if (is_file($entry) === true) { - F::loadOnce($entry); + F::loadOnce($entry, allowOutput: false); } elseif (is_file($script) === true || is_file($styles) === true) { // if no PHP file is present but an index.js or index.css, // register as anonymous plugin (without actual extensions) diff --git a/kirby/src/Cms/AppTranslations.php b/kirby/src/Cms/AppTranslations.php index 86d09c2..74f332c 100644 --- a/kirby/src/Cms/AppTranslations.php +++ b/kirby/src/Cms/AppTranslations.php @@ -27,11 +27,7 @@ trait AppTranslations protected function i18n(): void { I18n::$load = function ($locale): array { - $data = []; - - if ($translation = $this->translation($locale)) { - $data = $translation->data(); - } + $data = $this->translation($locale)?->data() ?? []; // inject translations from the current language if ( @@ -49,9 +45,9 @@ trait AppTranslations I18n::$locale = function (): string { if ($this->multilang() === true) { return $this->defaultLanguage()->code(); - } else { - return 'en'; } + + return 'en'; }; I18n::$fallback = function (): array { @@ -71,9 +67,9 @@ trait AppTranslations $fallback[] = 'en'; return $fallback; - } else { - return ['en']; } + + return ['en']; }; I18n::$translations = []; @@ -127,11 +123,8 @@ trait AppTranslations return $this->language = null; } - if ($language = $this->language($languageCode)) { - $this->language = $language; - } else { - $this->language = $this->defaultLanguage(); - } + $this->language = $this->language($languageCode); + $this->language ??= $this->defaultLanguage(); if ($this->language) { Locale::set($this->language->locale()); @@ -161,13 +154,13 @@ trait AppTranslations * @param string|null $locale Locale name or `null` for the current locale * @return \Kirby\Cms\Translation */ - public function translation(?string $locale = null) + public function translation(string|null $locale = null) { $locale = $locale ?? I18n::locale(); $locale = basename($locale); // prefer loading them from the translations collection - if (is_a($this->translations, 'Kirby\Cms\Translations') === true) { + if ($this->translations instanceof Translations) { if ($translation = $this->translations()->find($locale)) { return $translation; } @@ -192,7 +185,7 @@ trait AppTranslations */ public function translations() { - if (is_a($this->translations, 'Kirby\Cms\Translations') === true) { + if ($this->translations instanceof Translations) { return $this->translations; } diff --git a/kirby/src/Cms/AppUsers.php b/kirby/src/Cms/AppUsers.php index 8eedcce..5a93a16 100644 --- a/kirby/src/Cms/AppUsers.php +++ b/kirby/src/Cms/AppUsers.php @@ -31,7 +31,7 @@ trait AppUsers */ public function auth() { - return $this->auth = $this->auth ?? new Auth($this); + return $this->auth ??= new Auth($this); } /** @@ -48,7 +48,7 @@ trait AppUsers * if called with callback: Return value from the callback * @throws \Throwable */ - public function impersonate(?string $who = null, ?Closure $callback = null) + public function impersonate(string|null $who = null, Closure|null $callback = null) { $auth = $this->auth(); @@ -60,8 +60,10 @@ trait AppUsers } try { - // bind the App object to the callback - return $callback->call($this, $userAfter); + // TODO: switch over in 3.9.0 to + // return $callback($userAfter); + $proxy = new AppUsersImpersonateProxy($this); + return $callback->call($proxy, $userAfter); } catch (Throwable $e) { throw $e; } finally { @@ -110,7 +112,7 @@ trait AppUsers * (when `$id` is passed as `null`) * @return \Kirby\Cms\User|null */ - public function user(?string $id = null, bool $allowImpersonation = true) + public function user(string|null $id = null, bool $allowImpersonation = true) { if ($id !== null) { return $this->users()->find($id); @@ -118,12 +120,12 @@ trait AppUsers if ($allowImpersonation === true && is_string($this->user) === true) { return $this->auth()->impersonate($this->user); - } else { - try { - return $this->auth()->user(null, $allowImpersonation); - } catch (Throwable $e) { - return null; - } + } + + try { + return $this->auth()->user(null, $allowImpersonation); + } catch (Throwable) { + return null; } } @@ -134,7 +136,7 @@ trait AppUsers */ public function users() { - if (is_a($this->users, 'Kirby\Cms\Users') === true) { + if ($this->users instanceof Users) { return $this->users; } diff --git a/kirby/src/Cms/AppUsersImpersonateProxy.php b/kirby/src/Cms/AppUsersImpersonateProxy.php new file mode 100644 index 0000000..2ca8849 --- /dev/null +++ b/kirby/src/Cms/AppUsersImpersonateProxy.php @@ -0,0 +1,32 @@ +impersonate()` + * + * @package Kirby Cms + * @author Nico Hoffmann , + * Lukas Bestle + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://getkirby.com/license + * + * @internal + * @deprecated Will be removed in Kirby 3.9.0 + * @todo remove in 3.9.0 + */ +class AppUsersImpersonateProxy +{ + public function __construct(protected App $app) + { + } + + public function __call($name, $arguments) + { + Helpers::deprecated('Calling $kirby->' . $name . '() as $this->' . $name . '() has been deprecated inside the $kirby->impersonate() callback function. Use a dedicated $kirby object for your call instead of $this. In Kirby 3.9.0 $this will no longer refer to the $kirby object, but the current context of the callback function.'); + + return $this->app->$name(...$arguments); + } +} diff --git a/kirby/src/Cms/Auth.php b/kirby/src/Cms/Auth.php index 6c81392..6b2d984 100644 --- a/kirby/src/Cms/Auth.php +++ b/kirby/src/Cms/Auth.php @@ -2,8 +2,10 @@ namespace Kirby\Cms; +use Kirby\Cms\Auth\Challenge; use Kirby\Cms\Auth\Status; use Kirby\Data\Data; +use Kirby\Exception\Exception; use Kirby\Exception\InvalidArgumentException; use Kirby\Exception\LogicException; use Kirby\Exception\NotFoundException; @@ -11,6 +13,7 @@ use Kirby\Exception\PermissionException; use Kirby\Filesystem\F; use Kirby\Http\Idn; use Kirby\Http\Request\Auth\BasicAuth; +use Kirby\Session\Session; use Kirby\Toolkit\A; use Throwable; @@ -95,26 +98,44 @@ class Auth */ public function createChallenge(string $email, bool $long = false, string $mode = 'login') { - $email = $this->validateEmail($email); - - // rate-limit the number of challenges for DoS/DDoS protection - $this->track($email, false); + $email = Idn::decodeEmail($email); $session = $this->kirby->session([ 'createMode' => 'cookie', 'long' => $long === true ]); - $challenge = null; - if ($user = $this->kirby->users()->find($email)) { - $timeout = $this->kirby->option('auth.challenge.timeout', 10 * 60); + $timeout = $this->kirby->option('auth.challenge.timeout', 10 * 60); + // catch every exception to hide them from attackers + // unless auth debugging is enabled + try { + $this->checkRateLimit($email); + + // rate-limit the number of challenges for DoS/DDoS protection + $this->track($email, false); + + // try to find the provided user + $user = $this->kirby->users()->find($email); + if ($user === null) { + $this->kirby->trigger('user.login:failed', compact('email')); + + throw new NotFoundException([ + 'key' => 'user.notFound', + 'data' => [ + 'name' => $email + ] + ]); + } + + // try to find an enabled challenge that is available for that user + $challenge = null; foreach ($this->enabledChallenges() as $name) { $class = static::$challenges[$name] ?? null; if ( $class && class_exists($class) === true && - is_subclass_of($class, 'Kirby\Cms\Auth\Challenge') === true && + is_subclass_of($class, Challenge::class) === true && $class::isAvailable($user, $mode) === true ) { $challenge = $name; @@ -124,40 +145,30 @@ class Auth if ($code !== null) { $session->set('kirby.challenge.code', password_hash($code, PASSWORD_DEFAULT)); - $session->set('kirby.challenge.timeout', time() + $timeout); } break; } } - // if no suitable challenge was found, `$challenge === null` at this point; - // only leak this in debug mode - if ($challenge === null && $this->kirby->option('debug') === true) { + // if no suitable challenge was found, `$challenge === null` at this point + if ($challenge === null) { throw new LogicException('Could not find a suitable authentication challenge'); } - } else { - $this->kirby->trigger('user.login:failed', compact('email')); - - // only leak the non-existing user in debug mode - if ($this->kirby->option('debug') === true) { - throw new NotFoundException([ - 'key' => 'user.notFound', - 'data' => [ - 'name' => $email - ] - ]); - } + } catch (Throwable $e) { + // only throw the exception in auth debug mode + $this->fail($e); } - // always set the email, even if the challenge won't be - // created to avoid leaking whether the user exists + // always set the email and timeout, even if the challenge + // won't be created; this avoids leaking whether the user exists $session->set('kirby.challenge.email', $email); + $session->set('kirby.challenge.timeout', time() + $timeout); // sleep for a random amount of milliseconds // to make automated attacks harder and to // avoid leaking whether the user exists - usleep(random_int(1000, 300000)); + usleep(random_int(50000, 300000)); // clear the status cache $this->status = null; @@ -303,33 +314,25 @@ class Auth * @return \Kirby\Cms\User|null * @throws \Kirby\Exception\NotFoundException if the given user cannot be found */ - public function impersonate(?string $who = null) + public function impersonate(string|null $who = null) { // clear the status cache $this->status = null; - switch ($who) { - case null: - return $this->impersonate = null; - case 'kirby': - return $this->impersonate = new User([ - 'email' => 'kirby@getkirby.com', - 'id' => 'kirby', - 'role' => 'admin', - ]); - case 'nobody': - return $this->impersonate = new User([ - 'email' => 'nobody@getkirby.com', - 'id' => 'nobody', - 'role' => 'nobody', - ]); - default: - if ($user = $this->kirby->users()->find($who)) { - return $this->impersonate = $user; - } - - throw new NotFoundException('The user "' . $who . '" cannot be found'); - } + return $this->impersonate = match ($who) { + null => null, + 'kirby' => new User([ + 'email' => 'kirby@getkirby.com', + 'id' => 'kirby', + 'role' => 'admin', + ]), + 'nobody' => new User([ + 'email' => 'nobody@getkirby.com', + 'id' => 'nobody', + 'role' => 'nobody', + ]), + default => ($this->kirby->users()->find($who) ?? throw new NotFoundException('The user "' . $who . '" cannot be found')) + }; } /** @@ -492,34 +495,21 @@ class Auth } /** - * Ensures that email addresses with IDN domains are in Unicode format - * and that the rate limit was not exceeded - * - * @param string $email - * @return string The normalized Unicode email address + * Ensures that the rate limit was not exceeded * * @throws \Kirby\Exception\PermissionException If the rate limit was exceeded */ - protected function validateEmail(string $email): string + protected function checkRateLimit(string $email): void { - // ensure that email addresses with IDN domains are in Unicode format - $email = Idn::decodeEmail($email); - // check for blocked ips if ($this->isBlocked($email) === true) { $this->kirby->trigger('user.login:failed', compact('email')); - if ($this->kirby->option('debug') === true) { - $message = 'Rate limit exceeded'; - } else { - // avoid leaking security-relevant information - $message = ['key' => 'access.login']; - } - - throw new PermissionException($message); + throw new PermissionException([ + 'details' => ['reason' => 'rate-limited'], + 'fallback' => 'Rate limit exceeded' + ]); } - - return $email; } /** @@ -536,10 +526,12 @@ class Auth */ public function validatePassword(string $email, string $password) { - $email = $this->validateEmail($email); + $email = Idn::decodeEmail($email); - // validate the user try { + $this->checkRateLimit($email); + + // validate the user and its password if ($user = $this->kirby->users()->find($email)) { if ($user->validatePassword($password) === true) { return $user; @@ -553,20 +545,25 @@ class Auth ] ]); } catch (Throwable $e) { - // log invalid login trial - $this->track($email); + $details = $e instanceof Exception ? $e->getDetails() : []; + + // log invalid login trial unless the rate limit is already active + if (($details['reason'] ?? null) !== 'rate-limited') { + try { + $this->track($email); + } catch (Throwable $e) { + // $e is overwritten with the exception + // from the track method if there's one + } + } // sleep for a random amount of milliseconds // to make automated attacks harder - usleep(random_int(1000, 2000000)); + usleep(random_int(10000, 2000000)); // keep throwing the original error in debug mode, // otherwise hide it to avoid leaking security-relevant information - if ($this->kirby->option('debug') === true) { - throw $e; - } else { - throw new PermissionException(['key' => 'access.login']); - } + $this->fail($e, new PermissionException(['key' => 'access.login'])); } } @@ -590,7 +587,7 @@ class Auth try { $log = Data::read($this->logfile(), 'json'); $read = true; - } catch (Throwable $e) { + } catch (Throwable) { $log = []; $read = false; } @@ -636,9 +633,7 @@ class Auth $this->impersonate = null; // logout the current user if it exists - if ($user = $this->user()) { - $user->logout(); - } + $this->user()?->logout(); // clear the pending challenge $session = $this->kirby->session(); @@ -671,7 +666,7 @@ class Auth * @param bool $triggerHook If `false`, no user.login:failed hook is triggered * @return bool */ - public function track(?string $email, bool $triggerHook = true): bool + public function track(string|null $email, bool $triggerHook = true): bool { if ($triggerHook === true) { $this->kirby->trigger('user.login:failed', compact('email')); @@ -721,15 +716,25 @@ class Auth public function type(bool $allowImpersonation = true): string { $basicAuth = $this->kirby->option('api.basicAuth', false); - $auth = $this->kirby->request()->auth(); + $request = $this->kirby->request(); - if ($basicAuth === true && $auth && $auth->type() === 'basic') { + if ( + $basicAuth === true && + + // only get the auth object if the option is enabled + // to avoid triggering `$responder->usesAuth()` if + // the option is disabled + $request->auth() && + $request->auth()->type() === 'basic' + ) { return 'basic'; - } elseif ($allowImpersonation === true && $this->impersonate !== null) { - return 'impersonate'; - } else { - return 'session'; } + + if ($allowImpersonation === true && $this->impersonate !== null) { + return 'impersonate'; + } + + return 'session'; } /** @@ -756,16 +761,18 @@ class Auth } return null; - } elseif ($this->user !== false) { + } + + if ($this->user !== false) { return $this->user; } try { if ($this->type() === 'basic') { return $this->user = $this->currentUserFromBasicAuth(); - } else { - return $this->user = $this->currentUserFromSession($session); } + + return $this->user = $this->currentUserFromSession($session); } catch (Throwable $e) { $this->user = null; @@ -796,11 +803,35 @@ class Auth try { $session = $this->kirby->session(); - // first check if we have an active challenge at all + // time-limiting; check this early so that we can destroy the session no + // matter if the user exists (avoids leaking user information to attackers) + $timeout = $session->get('kirby.challenge.timeout'); + if ($timeout !== null && time() > $timeout) { + // this challenge can never be completed, + // so delete it immediately + $this->logout(); + + throw new PermissionException([ + 'details' => ['challengeDestroyed' => true], + 'fallback' => 'Authentication challenge timeout' + ]); + } + + // check if we have an active challenge $email = $session->get('kirby.challenge.email'); $challenge = $session->get('kirby.challenge.type'); if (is_string($email) !== true || is_string($challenge) !== true) { - throw new InvalidArgumentException('No authentication challenge is active'); + // if the challenge timed out on the previous request, the + // challenge data was already deleted from the session, so we can + // set `challengeDestroyed` to `true` in this response as well; + // however we must only base this on the email, not the type + // (otherwise "faked" challenges would be leaked) + $challengeDestroyed = is_string($email) !== true; + + throw new InvalidArgumentException([ + 'details' => compact('challengeDestroyed'), + 'fallback' => 'No authentication challenge is active' + ]); } $user = $this->kirby->users()->find($email); @@ -814,21 +845,12 @@ class Auth } // rate-limiting - if ($this->isBlocked($email) === true) { - $this->kirby->trigger('user.login:failed', compact('email')); - throw new PermissionException('Rate limit exceeded'); - } - - // time-limiting - $timeout = $session->get('kirby.challenge.timeout'); - if ($timeout !== null && time() > $timeout) { - throw new PermissionException('Authentication challenge timeout'); - } + $this->checkRateLimit($email); if ( isset(static::$challenges[$challenge]) === true && class_exists(static::$challenges[$challenge]) === true && - is_subclass_of(static::$challenges[$challenge], 'Kirby\Cms\Auth\Challenge') === true + is_subclass_of(static::$challenges[$challenge], Challenge::class) === true ) { $class = static::$challenges[$challenge]; if ($class::verify($user, $code) === true) { @@ -839,29 +861,67 @@ class Auth $this->status = null; return $user; - } else { - throw new PermissionException(['key' => 'access.code']); } + + throw new PermissionException(['key' => 'access.code']); } throw new LogicException('Invalid authentication challenge: ' . $challenge); } catch (Throwable $e) { - if (empty($email) === false && $e->getMessage() !== 'Rate limit exceeded') { + $details = $e instanceof \Kirby\Exception\Exception ? $e->getDetails() : []; + + if ( + empty($email) === false && + ($details['reason'] ?? null) !== 'rate-limited' + ) { $this->track($email); } // sleep for a random amount of milliseconds // to make automated attacks harder and to // avoid leaking whether the user exists - usleep(random_int(1000, 2000000)); + usleep(random_int(10000, 2000000)); + + // specifically copy over the marker for a destroyed challenge + // even in production (used by the Panel to reset to the login form) + $challengeDestroyed = $details['challengeDestroyed'] ?? false; + + $fallback = new PermissionException([ + 'details' => compact('challengeDestroyed'), + 'key' => 'access.code' + ]); // keep throwing the original error in debug mode, // otherwise hide it to avoid leaking security-relevant information - if ($this->kirby->option('debug') === true) { - throw $e; - } else { - throw new PermissionException(['key' => 'access.code']); - } + $this->fail($e, $fallback); + } + } + + /** + * Throws an exception only in debug mode, otherwise falls back + * to a public error without sensitive information + * + * @throws \Throwable Either the passed `$exception` or the `$fallback` + * (no exception if debugging is disabled and no fallback was passed) + */ + protected function fail(Throwable $exception, Throwable $fallback = null): void + { + $debug = $this->kirby->option('auth.debug', 'log'); + + // throw the original exception only in debug mode + if ($debug === true) { + throw $exception; + } + + // otherwise hide the real error and only print it to the error log + // unless disabled by setting `auth.debug` to `false` + if ($debug === 'log') { + error_log($exception); // @codeCoverageIgnore + } + + // only throw an error in production if requested by the calling method + if ($fallback !== null) { + throw $fallback; } } @@ -879,7 +939,7 @@ class Auth } // try session in header or cookie - if (is_a($session, 'Kirby\Session\Session') === false) { + if ($session instanceof Session === false) { return $this->kirby->session(['detect' => true]); } diff --git a/kirby/src/Cms/Auth/Challenge.php b/kirby/src/Cms/Auth/Challenge.php index 69a7574..cf69259 100644 --- a/kirby/src/Cms/Auth/Challenge.php +++ b/kirby/src/Cms/Auth/Challenge.php @@ -37,7 +37,7 @@ abstract class Challenge * @return string|null The generated and sent code or `null` in case * there was no code to generate by this algorithm */ - abstract public static function create(User $user, array $options): ?string; + abstract public static function create(User $user, array $options): string|null; /** * Verifies the provided code against the created one; diff --git a/kirby/src/Cms/Auth/Status.php b/kirby/src/Cms/Auth/Status.php index 43031c7..adf8bb5 100644 --- a/kirby/src/Cms/Auth/Status.php +++ b/kirby/src/Cms/Auth/Status.php @@ -86,7 +86,7 @@ class Status * user to avoid leaking whether the pending user exists * @return string|null */ - public function challenge(bool $automaticFallback = true): ?string + public function challenge(bool $automaticFallback = true): string|null { // never return a challenge type if the status doesn't match if ($this->status() !== 'pending') { @@ -95,9 +95,9 @@ class Status if ($automaticFallback === false) { return $this->challenge; - } else { - return $this->challenge ?? $this->challengeFallback; } + + return $this->challenge ?? $this->challengeFallback; } /** @@ -105,7 +105,7 @@ class Status * * @return string|null */ - public function email(): ?string + public function email(): string|null { return $this->email; } @@ -156,7 +156,7 @@ class Status * @param string|null $challenge * @return $this */ - protected function setChallenge(?string $challenge = null) + protected function setChallenge(string|null $challenge = null) { $this->challenge = $challenge; return $this; @@ -169,7 +169,7 @@ class Status * @param string|null $challengeFallback * @return $this */ - protected function setChallengeFallback(?string $challengeFallback = null) + protected function setChallengeFallback(string|null $challengeFallback = null) { $this->challengeFallback = $challengeFallback; return $this; @@ -181,7 +181,7 @@ class Status * @param string|null $email * @return $this */ - protected function setEmail(?string $email = null) + protected function setEmail(string|null $email = null) { $this->email = $email; return $this; diff --git a/kirby/src/Cms/Block.php b/kirby/src/Cms/Block.php index 97f04a7..2955787 100644 --- a/kirby/src/Cms/Block.php +++ b/kirby/src/Cms/Block.php @@ -22,7 +22,7 @@ class Block extends Item { use HasMethods; - public const ITEMS_CLASS = '\Kirby\Cms\Blocks'; + public const ITEMS_CLASS = Blocks::class; /** * @var \Kirby\Cms\Content @@ -157,7 +157,7 @@ class Block extends Item if (empty($type) === false && $class = (static::$models[$type] ?? null)) { $object = new $class($params); - if (is_a($object, 'Kirby\Cms\Block') === true) { + if ($object instanceof self) { return $object; } } @@ -166,7 +166,7 @@ class Block extends Item if ($class = (static::$models['Kirby\Cms\Block'] ?? null)) { $object = new $class($params); - if (is_a($object, 'Kirby\Cms\Block') === true) { + if ($object instanceof self) { return $object; } } diff --git a/kirby/src/Cms/Blocks.php b/kirby/src/Cms/Blocks.php index 49589ec..0277f27 100644 --- a/kirby/src/Cms/Blocks.php +++ b/kirby/src/Cms/Blocks.php @@ -20,7 +20,7 @@ use Throwable; */ class Blocks extends Items { - public const ITEM_CLASS = '\Kirby\Cms\Block'; + public const ITEM_CLASS = Block::class; /** * Return HTML when the collection is @@ -114,7 +114,7 @@ class Blocks extends Items if (empty($input) === false && is_array($input) === false) { try { $input = Json::decode((string)$input); - } catch (Throwable $e) { + } catch (Throwable) { $parser = new Parsley((string)$input, new BlockSchema()); $input = $parser->blocks(); } diff --git a/kirby/src/Cms/Blueprint.php b/kirby/src/Cms/Blueprint.php index bd257c2..cde33be 100644 --- a/kirby/src/Cms/Blueprint.php +++ b/kirby/src/Cms/Blueprint.php @@ -58,7 +58,7 @@ class Blueprint throw new InvalidArgumentException('A blueprint model is required'); } - if (is_a($props['model'], ModelWithContent::class) === false) { + if ($props['model'] instanceof ModelWithContent === false) { throw new InvalidArgumentException('Invalid blueprint model'); } @@ -208,7 +208,7 @@ class Blueprint $mixin = static::find($extend); $mixin = static::extend($mixin); $props = A::merge($mixin, $props, A::MERGE_REPLACE); - } catch (Exception $e) { + } catch (Exception) { // keep the props unextended if the snippet wasn't found } } @@ -231,7 +231,7 @@ class Blueprint { try { $props = static::load($name); - } catch (Exception $e) { + } catch (Exception) { $props = $fallback !== null ? static::load($fallback) : null; } @@ -251,7 +251,7 @@ class Blueprint * @param string $name * @return array|null */ - public function field(string $name): ?array + public function field(string $name): array|null { return $this->fields[$name] ?? null; } @@ -297,7 +297,8 @@ class Blueprint // now ensure that we always return the data array if (is_string($file) === true && F::exists($file) === true) { return static::$loaded[$name] = Data::read($file); - } elseif (is_array($file) === true) { + } + if (is_array($file) === true) { return static::$loaded[$name] = $file; } @@ -398,9 +399,9 @@ class Blueprint if (empty($columnProps['sections']) === true) { $columnProps['sections'] = [ $tabName . '-info-' . $columnKey => [ - 'headline' => 'Column (' . ($columnProps['width'] ?? '1/1') . ')', - 'type' => 'info', - 'text' => 'No sections yet' + 'label' => 'Column (' . ($columnProps['width'] ?? '1/1') . ')', + 'type' => 'info', + 'text' => 'No sections yet' ] ]; } @@ -620,17 +621,17 @@ class Blueprint if (empty($type) === true || is_string($type) === false) { $sections[$sectionName] = [ - 'name' => $sectionName, - 'headline' => 'Invalid section type for section "' . $sectionName . '"', - 'type' => 'info', - 'text' => 'The following section types are available: ' . $this->helpList(array_keys(Section::$types)) + 'name' => $sectionName, + 'label' => 'Invalid section type for section "' . $sectionName . '"', + 'type' => 'info', + 'text' => 'The following section types are available: ' . $this->helpList(array_keys(Section::$types)) ]; } elseif (isset(Section::$types[$type]) === false) { $sections[$sectionName] = [ - 'name' => $sectionName, - 'headline' => 'Invalid section type ("' . $type . '")', - 'type' => 'info', - 'text' => 'The following section types are available: ' . $this->helpList(array_keys(Section::$types)) + 'name' => $sectionName, + 'label' => 'Invalid section type ("' . $type . '")', + 'type' => 'info', + 'text' => 'The following section types are available: ' . $this->helpList(array_keys(Section::$types)) ]; } @@ -730,7 +731,7 @@ class Blueprint $preset = static::$presets[$props['preset']]; if (is_string($preset) === true) { - $preset = require $preset; + $preset = F::load($preset, allowOutput: false); } return $preset($props); @@ -777,7 +778,7 @@ class Blueprint * @param string|null $name * @return array|null */ - public function tab(?string $name = null): ?array + public function tab(string|null $name = null): array|null { if ($name === null) { return A::first($this->tabs); diff --git a/kirby/src/Cms/Collection.php b/kirby/src/Cms/Collection.php index fb8f5f9..8f92632 100644 --- a/kirby/src/Cms/Collection.php +++ b/kirby/src/Cms/Collection.php @@ -6,6 +6,7 @@ use Closure; use Kirby\Exception\InvalidArgumentException; use Kirby\Toolkit\Collection as BaseCollection; use Kirby\Toolkit\Str; +use Kirby\Uuid\Uuid; /** * The Collection class serves as foundation @@ -87,9 +88,12 @@ class Collection extends BaseCollection */ public function add($object) { - if (is_a($object, self::class) === true) { + if ($object instanceof self) { $this->data = array_merge($this->data, $object->data); - } elseif (is_object($object) === true && method_exists($object, 'id') === true) { + } elseif ( + is_object($object) === true && + method_exists($object, 'id') === true + ) { $this->__set($object->id(), $object); } else { $this->append($object); @@ -110,16 +114,37 @@ class Collection extends BaseCollection { if (count($args) === 1) { // try to determine the key from the provided item - if (is_object($args[0]) === true && is_callable([$args[0], 'id']) === true) { + if ( + is_object($args[0]) === true && + is_callable([$args[0], 'id']) === true + ) { return parent::append($args[0]->id(), $args[0]); - } else { - return parent::append($args[0]); } + + return parent::append($args[0]); } return parent::append(...$args); } + /** + * Find a single element by an attribute and its value + * + * @param string $attribute + * @param mixed $value + * @return mixed|null + */ + public function findBy(string $attribute, $value) + { + // $value: cast UUID object to string to allow uses + // like `$pages->findBy('related', $page->uuid())` + if ($value instanceof Uuid) { + $value = $value->toString(); + } + + return parent::findBy($attribute, $value); + } + /** * Groups the items by a given field or callback. Returns a collection * with an item for each group and a collection for each group. @@ -208,7 +233,9 @@ class Collection extends BaseCollection foreach ($keys as $key) { if (is_array($key) === true) { return $this->not(...$key); - } elseif (is_a($key, 'Kirby\Toolkit\Collection') === true) { + } + + if ($key instanceof BaseCollection) { $collection = $collection->not(...$key->keys()); } elseif (is_object($key) === true) { $key = $key->id(); @@ -256,11 +283,14 @@ class Collection extends BaseCollection { if (count($args) === 1) { // try to determine the key from the provided item - if (is_object($args[0]) === true && is_callable([$args[0], 'id']) === true) { + if ( + is_object($args[0]) === true && + is_callable([$args[0], 'id']) === true + ) { return parent::prepend($args[0]->id(), $args[0]); - } else { - return parent::prepend($args[0]); } + + return parent::prepend($args[0]); } return parent::prepend(...$args); diff --git a/kirby/src/Cms/Collections.php b/kirby/src/Cms/Collections.php index 542ed03..72fe017 100644 --- a/kirby/src/Cms/Collections.php +++ b/kirby/src/Cms/Collections.php @@ -2,6 +2,7 @@ namespace Kirby\Cms; +use Closure; use Kirby\Exception\NotFoundException; use Kirby\Filesystem\F; use Kirby\Toolkit\Controller; @@ -62,9 +63,7 @@ class Collections public function get(string $name, array $data = []) { // if not yet loaded - if (isset($this->collections[$name]) === false) { - $this->collections[$name] = $this->load($name); - } + $this->collections[$name] ??= $this->load($name); // if not yet cached if ( @@ -101,7 +100,7 @@ class Collections try { $this->load($name); return true; - } catch (NotFoundException $e) { + } catch (NotFoundException) { return false; } } @@ -122,9 +121,9 @@ class Collections $file = $kirby->root('collections') . '/' . $name . '.php'; if (is_file($file) === true) { - $collection = F::load($file); + $collection = F::load($file, allowOutput: false); - if (is_a($collection, 'Closure')) { + if ($collection instanceof Closure) { return $collection; } } diff --git a/kirby/src/Cms/Content.php b/kirby/src/Cms/Content.php index d0a6e11..cfe6c0c 100644 --- a/kirby/src/Cms/Content.php +++ b/kirby/src/Cms/Content.php @@ -115,7 +115,7 @@ class Content $oldField = $oldFields->get($name); // field name and type matches with old template - if ($oldField && $oldField->type() === $newField->type()) { + if ($oldField?->type() === $newField->type()) { $data[$name] = $content->get($name)->value(); } else { $data[$name] = $newField->default(); @@ -164,13 +164,11 @@ class Content $key = strtolower($key); - if (isset($this->fields[$key])) { - return $this->fields[$key]; - } - - $value = $this->data()[$key] ?? null; - - return $this->fields[$key] = new Field($this->parent, $key, $value); + return $this->fields[$key] ??= new Field( + $this->parent, + $key, + $this->data()[$key] ?? null + ); } /** diff --git a/kirby/src/Cms/ContentLock.php b/kirby/src/Cms/ContentLock.php index f938116..35cfa0c 100644 --- a/kirby/src/Cms/ContentLock.php +++ b/kirby/src/Cms/ContentLock.php @@ -195,6 +195,33 @@ class ContentLock return $this->kirby()->locks()->set($this->model, $this->data); } + /** + * Returns the state for the + * form buttons in the frontend + */ + public function state(): ?string + { + return match (true) { + $this->isUnlocked() => 'unlock', + $this->isLocked() => 'lock', + default => null + }; + } + + /** + * Returns a usable lock array + * for the frontend + * + * @return array + */ + public function toArray(): array + { + return [ + 'state' => $this->state(), + 'data' => $this->get() + ]; + } + /** * Removes current lock and adds lock user to unlock data * @@ -223,10 +250,7 @@ class ContentLock */ protected function user(): User { - if ($user = $this->kirby()->user()) { - return $user; - } - - throw new PermissionException('No user authenticated.'); + return $this->kirby()->user() ?? + throw new PermissionException('No user authenticated.'); } } diff --git a/kirby/src/Cms/ContentTranslation.php b/kirby/src/Cms/ContentTranslation.php index 5ffa744..4ad78c6 100644 --- a/kirby/src/Cms/ContentTranslation.php +++ b/kirby/src/Cms/ContentTranslation.php @@ -84,23 +84,17 @@ class ContentTranslation */ public function content(): array { - $parent = $this->parent(); - - if ($this->content === null) { - $this->content = $parent->readContent($this->code()); - } - - $content = $this->content; + $parent = $this->parent(); + $content = $this->content ??= $parent->readContent($this->code()); // merge with the default content - if ($this->isDefault() === false && $defaultLanguage = $parent->kirby()->defaultLanguage()) { - $default = []; - - if ($defaultTranslation = $parent->translation($defaultLanguage->code())) { - $default = $defaultTranslation->content(); + if ( + $this->isDefault() === false && + $defaultLanguage = $parent->kirby()->defaultLanguage() + ) { + if ($default = $parent->translation($defaultLanguage->code())?->content()) { + $content = array_merge($default, $content); } - - $content = array_merge($default, $content); } return $content; @@ -118,12 +112,11 @@ class ContentTranslation /** * Checks if the translation file exists - * - * @return bool */ public function exists(): bool { - return file_exists($this->contentFile()) === true; + return empty($this->content) === false || + file_exists($this->contentFile()) === true; } /** @@ -211,7 +204,7 @@ class ContentTranslation * * @return string|null */ - public function slug(): ?string + public function slug(): string|null { return $this->slug ??= ($this->content()['slug'] ?? null); } diff --git a/kirby/src/Cms/Core.php b/kirby/src/Cms/Core.php index 48ce72e..231b422 100644 --- a/kirby/src/Cms/Core.php +++ b/kirby/src/Cms/Core.php @@ -21,24 +21,10 @@ namespace Kirby\Cms; */ class Core { - /** - * @var array - */ - protected $cache = []; + protected array $cache = []; + protected App $kirby; + protected string $root; - /** - * @var \Kirby\Cms\App - */ - protected $kirby; - - /** - * @var string - */ - protected $root; - - /** - * @param \Kirby\Cms\App $kirby - */ public function __construct(App $kirby) { $this->kirby = $kirby; @@ -50,11 +36,8 @@ class Core * * This is a shortcut for `$kirby->core()->load()->area()` * to give faster access to original area code in plugins. - * - * @param string $name - * @return array|null */ - public function area(string $name): ?array + public function area(string $name): array|null { return $this->load()->area($name); } @@ -63,8 +46,6 @@ class Core * Returns a list of all paths to area definition files * * They are located in `/kirby/config/areas` - * - * @return array */ public function areas(): array { @@ -82,8 +63,6 @@ class Core /** * Returns a list of all default auth challenge classes - * - * @return array */ public function authChallenges(): array { @@ -96,8 +75,6 @@ class Core * Returns a list of all paths to blueprint presets * * They are located in `/kirby/config/presets` - * - * @return array */ public function blueprintPresets(): array { @@ -113,8 +90,6 @@ class Core * * They are located in `/kirby/config/blueprints`. * Block blueprints are located in `/kirby/config/blocks` - * - * @return array */ public function blueprints(): array { @@ -143,10 +118,19 @@ class Core ]; } + /** + * Returns a list of all core caches + */ + public function caches(): array + { + return [ + 'updates' => true, + 'uuid' => true, + ]; + } + /** * Returns a list of all cache driver classes - * - * @return array */ public function cacheTypes(): array { @@ -163,8 +147,6 @@ class Core * * The component functions can be found in * `/kirby/config/components.php` - * - * @return array */ public function components(): array { @@ -173,8 +155,6 @@ class Core /** * Returns a map of all field method aliases - * - * @return array */ public function fieldMethodAliases(): array { @@ -199,8 +179,6 @@ class Core * Returns an array of all field method functions * * Field methods are stored in `/kirby/config/methods.php` - * - * @return array */ public function fieldMethods(): array { @@ -211,8 +189,6 @@ class Core * Returns an array of paths for field mixins * * They are located in `/kirby/config/fields/mixins` - * - * @return array */ public function fieldMixins(): array { @@ -236,8 +212,6 @@ class Core * * The more complex field classes can be found in * `/kirby/src/Form/Fields` - * - * @return array */ public function fields(): array { @@ -256,6 +230,7 @@ class Core 'list' => $this->root . '/fields/list.php', 'multiselect' => $this->root . '/fields/multiselect.php', 'number' => $this->root . '/fields/number.php', + 'object' => $this->root . '/fields/object.php', 'pages' => $this->root . '/fields/pages.php', 'radio' => $this->root . '/fields/radio.php', 'range' => $this->root . '/fields/range.php', @@ -277,8 +252,6 @@ class Core /** * Returns a map of all kirbytag aliases - * - * @return array */ public function kirbyTagAliases(): array { @@ -292,8 +265,6 @@ class Core * Returns an array of all kirbytag definitions * * They are located in `/kirby/config/tags.php` - * - * @return array */ public function kirbyTags(): array { @@ -306,10 +277,8 @@ class Core * The loader is set to not include plugins. * This way, you can access original Kirby core code * through this load method. - * - * @return \Kirby\Cms\Loader */ - public function load() + public function load(): Loader { return new Loader($this->kirby, false); } @@ -318,8 +287,6 @@ class Core * Returns all absolute paths to important directories * * Roots are resolved and baked in `\Kirby\Cms\App::bakeRoots()` - * - * @return array */ public function roots(): array { @@ -339,6 +306,7 @@ class Core 'blueprints' => fn (array $roots) => $roots['site'] . '/blueprints', 'cache' => fn (array $roots) => $roots['site'] . '/cache', 'collections' => fn (array $roots) => $roots['site'] . '/collections', + 'commands' => fn (array $roots) => $roots['site'] . '/commands', 'config' => fn (array $roots) => $roots['site'] . '/config', 'controllers' => fn (array $roots) => $roots['site'] . '/controllers', 'languages' => fn (array $roots) => $roots['site'] . '/languages', @@ -359,8 +327,6 @@ class Core * Routes are split into `before` and `after` routes. * * Plugin routes will be injected inbetween. - * - * @return array */ public function routes(): array { @@ -371,8 +337,6 @@ class Core * Returns a list of all paths to core block snippets * * They are located in `/kirby/config/blocks` - * - * @return array */ public function snippets(): array { @@ -395,8 +359,6 @@ class Core * Returns a list of paths to section mixins * * They are located in `/kirby/config/sections/mixins` - * - * @return array */ public function sectionMixins(): array { @@ -419,8 +381,6 @@ class Core * Returns a list of all section definitions * * They are located in `/kirby/config/sections` - * - * @return array */ public function sections(): array { @@ -437,8 +397,6 @@ class Core * Returns a list of paths to all system templates * * They are located in `/kirby/config/templates` - * - * @return array */ public function templates(): array { @@ -452,8 +410,6 @@ class Core * Returns an array with all system URLs * * URLs are resolved and baked in `\Kirby\Cms\App::bakeUrls()` - * - * @return array */ public function urls(): array { @@ -465,9 +421,9 @@ class Core if (empty($path) === true) { return $urls['index']; - } else { - return $urls['base'] . '/' . $path; } + + return $urls['base'] . '/' . $path; }, 'assets' => fn (array $urls) => $urls['base'] . '/assets', 'api' => fn (array $urls) => $urls['base'] . '/' . $this->kirby->option('api.slug', 'api'), diff --git a/kirby/src/Cms/Email.php b/kirby/src/Cms/Email.php index 6009792..7b1be8a 100644 --- a/kirby/src/Cms/Email.php +++ b/kirby/src/Cms/Email.php @@ -49,14 +49,10 @@ class Email $this->props = array_merge($preset, $props); // add transport settings - if (isset($this->props['transport']) === false) { - $this->props['transport'] = $this->options['transport'] ?? []; - } + $this->props['transport'] ??= $this->options['transport'] ?? []; // add predefined beforeSend option - if (isset($this->props['beforeSend']) === false) { - $this->props['beforeSend'] = $this->options['beforeSend'] ?? null; - } + $this->props['beforeSend'] ??= $this->options['beforeSend'] ?? null; // transform model objects to values $this->transformUserSingle('from', 'fromName'); @@ -193,7 +189,7 @@ class Email } else { $result[] = $item; } - } elseif (is_a($item, $class) === true) { + } elseif ($item instanceof $class) { // value is a model object, get value through content method(s) if ($contentKey !== null) { $result[(string)$item->$contentKey()] = (string)$item->$contentValue(); @@ -235,9 +231,7 @@ class Email $this->props[$addressProp] = $address; // only use the name from the user if no custom name was set - if (isset($this->props[$nameProp]) === false || $this->props[$nameProp] === null) { - $this->props[$nameProp] = $name; - } + $this->props[$nameProp] ??= $name; } /** diff --git a/kirby/src/Cms/Event.php b/kirby/src/Cms/Event.php index c6ed0c2..9e57854 100644 --- a/kirby/src/Cms/Event.php +++ b/kirby/src/Cms/Event.php @@ -120,7 +120,7 @@ class Event * * @return string|null */ - public function action(): ?string + public function action(): string|null { return $this->action; } @@ -133,11 +133,7 @@ class Event */ public function argument(string $name) { - if (isset($this->arguments[$name]) === true) { - return $this->arguments[$name]; - } - - return null; + return $this->arguments[$name] ?? null; } /** @@ -158,7 +154,7 @@ class Event * @param \Closure $hook * @return mixed */ - public function call(?object $bind, Closure $hook) + public function call(object|null $bind, Closure $hook) { // collect the list of possible hook arguments $data = $this->arguments(); @@ -204,7 +200,9 @@ class Event '*:' . $this->state, '*' ]; - } elseif ($this->state !== null) { + } + + if ($this->state !== null) { // event without action: $type:$state return [ @@ -212,7 +210,9 @@ class Event '*:' . $this->state, '*' ]; - } elseif ($this->action !== null) { + } + + if ($this->action !== null) { // event without state: $type.$action return [ @@ -220,11 +220,10 @@ class Event '*.' . $this->action, '*' ]; - } else { - // event with a simple name - - return ['*']; } + + // event with a simple name + return ['*']; } /** @@ -232,7 +231,7 @@ class Event * * @return string|null */ - public function state(): ?string + public function state(): string|null { return $this->state; } diff --git a/kirby/src/Cms/Field.php b/kirby/src/Cms/Field.php index d3f97a5..710f36c 100644 --- a/kirby/src/Cms/Field.php +++ b/kirby/src/Cms/Field.php @@ -96,7 +96,7 @@ class Field * @param string $key * @param mixed $value */ - public function __construct(?object $parent, string $key, $value) + public function __construct(object|null $parent, string $key, $value) { $this->key = $key; $this->value = $value; @@ -187,7 +187,7 @@ class Field return $this; } - if (is_a($fallback, 'Kirby\Cms\Field') === true) { + if ($fallback instanceof self) { return $fallback; } diff --git a/kirby/src/Cms/Fieldset.php b/kirby/src/Cms/Fieldset.php index 0b49fd4..ff577f5 100644 --- a/kirby/src/Cms/Fieldset.php +++ b/kirby/src/Cms/Fieldset.php @@ -19,7 +19,7 @@ use Kirby\Toolkit\Str; */ class Fieldset extends Item { - public const ITEMS_CLASS = '\Kirby\Cms\Fieldsets'; + public const ITEMS_CLASS = Fieldsets::class; protected $disabled; protected $editable; @@ -92,7 +92,7 @@ class Fieldset extends Item * @param array|string $name * @return string|null */ - protected function createName($name): ?string + protected function createName($name): string|null { return I18n::translate($name, $name); } @@ -101,7 +101,7 @@ class Fieldset extends Item * @param array|string $label * @return string|null */ - protected function createLabel($label = null): ?string + protected function createLabel($label = null): string|null { return I18n::translate($label, $label); } @@ -195,7 +195,7 @@ class Fieldset extends Item /** * @return string|null */ - public function icon(): ?string + public function icon(): string|null { return $this->icon; } @@ -203,7 +203,7 @@ class Fieldset extends Item /** * @return string|null */ - public function label(): ?string + public function label(): string|null { return $this->label; } diff --git a/kirby/src/Cms/Fieldsets.php b/kirby/src/Cms/Fieldsets.php index 6189b22..cef3703 100644 --- a/kirby/src/Cms/Fieldsets.php +++ b/kirby/src/Cms/Fieldsets.php @@ -19,7 +19,7 @@ use Kirby\Toolkit\Str; */ class Fieldsets extends Items { - public const ITEM_CLASS = '\Kirby\Cms\Fieldset'; + public const ITEM_CLASS = Fieldset::class; protected static function createFieldsets($params) { @@ -93,7 +93,7 @@ class Fieldsets extends Items return $this->options['groups'] ?? []; } - public function toArray(?Closure $map = null): array + public function toArray(Closure|null $map = null): array { return A::map( $this->data, diff --git a/kirby/src/Cms/File.php b/kirby/src/Cms/File.php index bc81c7d..b6b1fac 100644 --- a/kirby/src/Cms/File.php +++ b/kirby/src/Cms/File.php @@ -71,10 +71,8 @@ class File extends ModelWithContent /** * The absolute path to the file - * - * @var string|null */ - protected $root; + protected string|null $root = null; /** * @var string @@ -83,10 +81,8 @@ class File extends ModelWithContent /** * The public file Url - * - * @var string */ - protected $url; + protected string|null $url = null; /** * Magic caller for file methods @@ -164,7 +160,7 @@ class File extends ModelWithContent */ public function blueprint() { - if (is_a($this->blueprint, 'Kirby\Cms\FileBlueprint') === true) { + if ($this->blueprint instanceof FileBlueprint) { return $this->blueprint; } @@ -267,9 +263,10 @@ class File extends ModelWithContent return $this->id; } - if (is_a($this->parent(), 'Kirby\Cms\Page') === true) { - return $this->id = $this->parent()->id() . '/' . $this->filename(); - } elseif (is_a($this->parent(), 'Kirby\Cms\User') === true) { + if ( + $this->parent() instanceof Page || + $this->parent() instanceof User + ) { return $this->id = $this->parent()->id() . '/' . $this->filename(); } @@ -298,11 +295,7 @@ class File extends ModelWithContent $template = $this->template(); - if (isset($readable[$template]) === true) { - return $readable[$template]; - } - - return $readable[$template] = $this->permissions()->can('read'); + return $readable[$template] ??= $this->permissions()->can('read'); } /** @@ -398,7 +391,11 @@ class File extends ModelWithContent */ public function page() { - return is_a($this->parent(), 'Kirby\Cms\Page') === true ? $this->parent() : null; + if ($this->parent() instanceof Page) { + return $this->parent(); + } + + return null; } /** @@ -439,13 +436,22 @@ class File extends ModelWithContent */ public function parents() { - if (is_a($this->parent(), 'Kirby\Cms\Page') === true) { + if ($this->parent() instanceof Page) { return $this->parent()->parents()->prepend($this->parent()->id(), $this->parent()); } return new Pages(); } + /** + * Return the permanent URL to the file using its UUID + * @since 3.8.0 + */ + public function permalink(): string|null + { + return $this->uuid()?->url(); + } + /** * Returns the permissions object for this file * @@ -461,7 +467,7 @@ class File extends ModelWithContent * * @return string|null */ - public function root(): ?string + public function root(): string|null { return $this->root ??= $this->parent()->root() . '/' . $this->filename(); } @@ -570,7 +576,11 @@ class File extends ModelWithContent */ public function site() { - return is_a($this->parent(), 'Kirby\Cms\Site') === true ? $this->parent() : $this->kirby()->site(); + if ($this->parent() instanceof Site) { + return $this->parent(); + } + + return $this->kirby()->site(); } /** @@ -578,7 +588,7 @@ class File extends ModelWithContent * * @return string|null */ - public function template(): ?string + public function template(): string|null { return $this->template ??= $this->content()->get('template')->value(); } @@ -616,98 +626,6 @@ class File extends ModelWithContent return $this->url ??= ($this->kirby()->component('file::url'))($this->kirby(), $this); } - - /** - * Deprecated! - */ - - /** - * Provides a kirbytag or markdown - * tag for the file, which will be - * used in the panel, when the file - * gets dragged onto a textarea - * - * @todo Remove in 3.8.0 - * - * @internal - * @param string|null $type (null|auto|kirbytext|markdown) - * @param bool $absolute - * @return string - * @codeCoverageIgnore - */ - public function dragText(string $type = null, bool $absolute = false): string - { - Helpers::deprecated('Cms\File::dragText() has been deprecated and will be removed in Kirby 3.8.0. Use $file->panel()->dragText() instead.'); - return $this->panel()->dragText($type, $absolute); - } - - /** - * Returns an array of all actions - * that can be performed in the Panel - * - * @todo Remove in 3.8.0 - * - * @since 3.3.0 This also checks for the lock status - * @since 3.5.1 This also checks for matching accept settings - * - * @param array $unlock An array of options that will be force-unlocked - * @return array - * @codeCoverageIgnore - */ - public function panelOptions(array $unlock = []): array - { - Helpers::deprecated('Cms\File::panelOptions() has been deprecated and will be removed in Kirby 3.8.0. Use $file->panel()->options() instead.'); - return $this->panel()->options($unlock); - } - - /** - * Returns the full path without leading slash - * - * @todo Remove in 3.8.0 - * - * @internal - * @return string - * @codeCoverageIgnore - */ - public function panelPath(): string - { - Helpers::deprecated('Cms\File::panelPath() has been deprecated and will be removed in Kirby 3.8.0. Use $file->panel()->path() instead.'); - return $this->panel()->path(); - } - - /** - * Prepares the response data for file pickers - * and file fields - * - * @todo Remove in 3.8.0 - * - * @param array|null $params - * @return array - * @codeCoverageIgnore - */ - public function panelPickerData(array $params = []): array - { - Helpers::deprecated('Cms\File::panelPickerData() has been deprecated and will be removed in Kirby 3.8.0. Use $file->panel()->pickerData() instead.'); - return $this->panel()->pickerData($params); - } - - /** - * Returns the url to the editing view - * in the panel - * - * @todo Remove in 3.8.0 - * - * @internal - * @param bool $relative - * @return string - * @codeCoverageIgnore - */ - public function panelUrl(bool $relative = false): string - { - Helpers::deprecated('Cms\File::panelUrl() has been deprecated and will be removed in Kirby 3.8.0. Use $file->panel()->url() instead.'); - return $this->panel()->url($relative); - } - /** * Simplified File URL that uses the parent * Page URL and the filename as a more stable diff --git a/kirby/src/Cms/FileActions.php b/kirby/src/Cms/FileActions.php index e82171a..b6ce3c0 100644 --- a/kirby/src/Cms/FileActions.php +++ b/kirby/src/Cms/FileActions.php @@ -7,6 +7,8 @@ use Kirby\Exception\InvalidArgumentException; use Kirby\Exception\LogicException; use Kirby\Filesystem\F; use Kirby\Form\Form; +use Kirby\Uuid\Uuid; +use Kirby\Uuid\Uuids; /** * FileActions @@ -44,6 +46,9 @@ trait FileActions 'filename' => $name . '.' . $oldFile->extension(), ]); + // remove all public versions, lock and clear UUID cache + $oldFile->unpublish(); + if ($oldFile->exists() === false) { return $newFile; } @@ -52,14 +57,6 @@ trait FileActions throw new LogicException('The new file exists and cannot be overwritten'); } - // remove the lock of the old file - if ($lock = $oldFile->lock()) { - $lock->remove(); - } - - // remove all public versions - $oldFile->unpublish(); - // rename the main file F::move($oldFile->root(), $newFile->root()); @@ -75,6 +72,7 @@ trait FileActions F::move($oldFile->contentFile(), $newFile->contentFile()); } + // update collections $newFile->parent()->files()->remove($oldFile->id()); $newFile->parent()->files()->set($newFile->id(), $newFile); @@ -122,13 +120,12 @@ trait FileActions $result = $callback(...$argumentValues); - if ($action === 'create') { - $argumentsAfter = ['file' => $result]; - } elseif ($action === 'delete') { - $argumentsAfter = ['status' => $result, 'file' => $old]; - } else { - $argumentsAfter = ['newFile' => $result, 'oldFile' => $old]; - } + $argumentsAfter = match ($action) { + 'create' => ['file' => $result], + 'delete' => ['status' => $result, 'file' => $old], + default => ['newFile' => $result, 'oldFile' => $old] + }; + $kirby->trigger('file.' . $action . ':after', $argumentsAfter); $kirby->cache('pages')->flush(); @@ -155,7 +152,14 @@ trait FileActions F::copy($contentFile, $page->root() . '/' . basename($contentFile)); } - return $page->clone()->file($this->filename()); + $copy = $page->clone()->file($this->filename()); + + // overwrite with new UUID (remove old, add new) + if (Uuids::enabled() === true) { + $copy = $copy->save(['uuid' => Uuid::generate()]); + } + + return $copy; } /** @@ -184,17 +188,24 @@ trait FileActions $file = static::factory($props); $upload = $file->asset($props['source']); + // gather content + $content = $props['content'] ?? []; + + // make sure that a UUID gets generated and + // added to content right away + if (Uuids::enabled() === true) { + $content['uuid'] ??= Uuid::generate(); + } + // create a form for the file - $form = Form::for($file, [ - 'values' => $props['content'] ?? [] - ]); + $form = Form::for($file, ['values' => $content]); // inject the content $file = $file->clone(['content' => $form->strings(true)]); // run the hook return $file->commit('create', compact('file', 'upload'), function ($file, $upload) { - // delete all public versions + // remove all public versions, lock and clear UUID cache $file->unpublish(); // overwrite the original @@ -229,14 +240,9 @@ trait FileActions public function delete(): bool { return $this->commit('delete', ['file' => $this], function ($file) { - // remove all versions in the media folder + // remove all public versions, lock and clear UUID cache $file->unpublish(); - // remove the lock of the old file - if ($lock = $file->lock()) { - $lock->remove(); - } - if ($file->kirby()->multilang() === true) { foreach ($file->translations() as $translation) { F::remove($file->contentFile($translation->code())); @@ -288,7 +294,7 @@ trait FileActions return $this->commit('replace', $arguments, function ($file, $upload) { // delete all public versions - $file->unpublish(); + $file->unpublish(true); // overwrite the original if (F::copy($upload->root(), $file->root(), true) !== true) { @@ -300,14 +306,43 @@ trait FileActions }); } + /** + * Stores the content on disk + * + * @internal + * @param array|null $data + * @param string|null $languageCode + * @param bool $overwrite + * @return static + */ + public function save(array $data = null, string $languageCode = null, bool $overwrite = false) + { + $file = parent::save($data, $languageCode, $overwrite); + + // update model in siblings collection + $file->parent()->files()->set($file->id(), $file); + + return $file; + } + /** * Remove all public versions of this file * * @return $this */ - public function unpublish() + public function unpublish(bool $onlyMedia = false) { + // unpublish media files Media::unpublish($this->parent()->mediaRoot(), $this); + + if ($onlyMedia !== true) { + // remove the lock + $this->lock()?->remove(); + + // clear UUID cache + $this->uuid()?->clear(); + } + return $this; } } diff --git a/kirby/src/Cms/FileBlueprint.php b/kirby/src/Cms/FileBlueprint.php index aee9b8b..9d17e5f 100644 --- a/kirby/src/Cms/FileBlueprint.php +++ b/kirby/src/Cms/FileBlueprint.php @@ -3,6 +3,7 @@ namespace Kirby\Cms; use Kirby\Filesystem\F; +use Kirby\Filesystem\Mime; use Kirby\Toolkit\Str; /** @@ -81,7 +82,10 @@ class FileBlueprint extends Blueprint if (is_array($accept['extension']) === true) { // determine the main MIME type for each extension - $restrictions[] = array_map(['Kirby\Filesystem\Mime', 'fromExtension'], $accept['extension']); + $restrictions[] = array_map( + [Mime::class, 'fromExtension'], + $accept['extension'] + ); } if (is_array($accept['type']) === true) { @@ -89,7 +93,10 @@ class FileBlueprint extends Blueprint $mimes = []; foreach ($accept['type'] as $type) { if ($extensions = F::typeToExtensions($type)) { - $mimes[] = array_map(['Kirby\Filesystem\Mime', 'fromExtension'], $extensions); + $mimes[] = array_map( + [Mime::class, 'fromExtension'], + $extensions + ); } } @@ -119,19 +126,15 @@ class FileBlueprint extends Blueprint */ protected function normalizeAccept($accept = null): array { - if (is_string($accept) === true) { - $accept = [ - 'mime' => $accept - ]; - } elseif ($accept === true) { + $accept = match (true) { + is_string($accept) => ['mime' => $accept], // explicitly no restrictions at all - $accept = [ - 'mime' => null - ]; - } elseif (empty($accept) === true) { + $accept === true => ['mime' => null], // no custom restrictions - $accept = []; - } + empty($accept) === true => [], + // custom restrictions + default => $accept + }; $accept = array_change_key_case($accept); diff --git a/kirby/src/Cms/FileModifications.php b/kirby/src/Cms/FileModifications.php index 9e2ca70..11556ba 100644 --- a/kirby/src/Cms/FileModifications.php +++ b/kirby/src/Cms/FileModifications.php @@ -3,6 +3,7 @@ namespace Kirby\Cms; use Kirby\Exception\InvalidArgumentException; +use Kirby\Filesystem\Asset; /** * Trait for image resizing, blurring etc. @@ -53,7 +54,7 @@ trait FileModifications $quality = $options; } elseif (is_string($options)) { $crop = $options; - } elseif (is_a($options, 'Kirby\Cms\Field') === true) { + } elseif ($options instanceof Field) { $crop = $options->value(); } elseif (is_array($options)) { $quality = $options['quality'] ?? $quality; @@ -127,7 +128,7 @@ trait FileModifications * @param array|string|null $sizes * @return string|null */ - public function srcset($sizes = null): ?string + public function srcset($sizes = null): string|null { if (empty($sizes) === true) { $sizes = $this->kirby()->option('thumbs.srcsets.default', []); @@ -202,9 +203,9 @@ trait FileModifications $result = $component($this->kirby(), $this, $options); if ( - is_a($result, 'Kirby\Cms\FileVersion') === false && - is_a($result, 'Kirby\Cms\File') === false && - is_a($result, 'Kirby\Filesystem\Asset') === false + $result instanceof FileVersion === false && + $result instanceof File === false && + $result instanceof Asset === false ) { throw new InvalidArgumentException('The file::version component must return a File, FileVersion or Asset object'); } diff --git a/kirby/src/Cms/FilePicker.php b/kirby/src/Cms/FilePicker.php index ea30ce1..81899ba 100644 --- a/kirby/src/Cms/FilePicker.php +++ b/kirby/src/Cms/FilePicker.php @@ -41,13 +41,14 @@ class FilePicker extends Picker $model = $this->options['model']; // find the right default query - if (empty($this->options['query']) === false) { - $query = $this->options['query']; - } elseif (is_a($model, 'Kirby\Cms\File') === true) { - $query = 'file.siblings'; - } else { - $query = $model::CLASS_ALIAS . '.files'; - } + $query = match (true) { + empty($this->options['query']) === false + => $this->options['query'], + $model instanceof File + => 'file.siblings', + default + => $model::CLASS_ALIAS . '.files' + }; // fetch all files for the picker $files = $model->query($query); @@ -55,15 +56,14 @@ class FilePicker extends Picker // help mitigate some typical query usage issues // by converting site and page objects to proper // pages by returning their children - if (is_a($files, 'Kirby\Cms\Site') === true) { - $files = $files->files(); - } elseif (is_a($files, 'Kirby\Cms\Page') === true) { - $files = $files->files(); - } elseif (is_a($files, 'Kirby\Cms\User') === true) { - $files = $files->files(); - } elseif (is_a($files, 'Kirby\Cms\Files') === false) { - throw new InvalidArgumentException('Your query must return a set of files'); - } + $files = match (true) { + $files instanceof Site, + $files instanceof Page, + $files instanceof User => $files->files(), + $files instanceof Files => $files, + + default => throw new InvalidArgumentException('Your query must return a set of files') + }; // search $files = $this->search($files); diff --git a/kirby/src/Cms/FileVersion.php b/kirby/src/Cms/FileVersion.php index 8eb47b1..96a497f 100644 --- a/kirby/src/Cms/FileVersion.php +++ b/kirby/src/Cms/FileVersion.php @@ -45,7 +45,7 @@ class FileVersion } // content fields - if (is_a($this->original(), 'Kirby\Cms\File') === true) { + if ($this->original() instanceof File) { return $this->original()->content()->get($method, $arguments); } } diff --git a/kirby/src/Cms/Files.php b/kirby/src/Cms/Files.php index ab5b249..5e30528 100644 --- a/kirby/src/Cms/Files.php +++ b/kirby/src/Cms/Files.php @@ -4,6 +4,7 @@ namespace Kirby\Cms; use Kirby\Exception\InvalidArgumentException; use Kirby\Filesystem\F; +use Kirby\Uuid\HasUuids; /** * The `$files` object extends the general @@ -21,6 +22,8 @@ use Kirby\Filesystem\F; */ class Files extends Collection { + use HasUuids; + /** * All registered files methods * @@ -40,15 +43,18 @@ class Files extends Collection public function add($object) { // add a files collection - if (is_a($object, self::class) === true) { + if ($object instanceof self) { $this->data = array_merge($this->data, $object->data); // add a file by id - } elseif (is_string($object) === true && $file = App::instance()->file($object)) { + } elseif ( + is_string($object) === true && + $file = App::instance()->file($object) + ) { $this->__set($file->id(), $file); // add a file object - } elseif (is_a($object, 'Kirby\Cms\File') === true) { + } elseif ($object instanceof File) { $this->__set($object->id(), $object); // give a useful error message on invalid input; @@ -105,22 +111,6 @@ class Files extends Collection return $collection; } - /** - * Tries to find a file by id/filename - * @deprecated 3.7.0 Use `$files->find()` instead - * @todo 3.8.0 Remove method - * @codeCoverageIgnore - * - * @param string $id - * @return \Kirby\Cms\File|null - */ - public function findById(string $id) - { - Helpers::deprecated('Cms\Files::findById() has been deprecated and will be removed in Kirby 3.8.0. Use $files->find() instead.'); - - return $this->findByKey($id); - } - /** * Finds a file by its filename * @internal Use `$files->find()` instead @@ -130,7 +120,11 @@ class Files extends Collection */ public function findByKey(string $key) { - return $this->get(ltrim($this->parent->id() . '/' . $key, '/')); + if ($file = $this->findByUuid($key, 'file')) { + return $file; + } + + return $this->get(ltrim($this->parent?->id() . '/' . $key, '/')); } /** diff --git a/kirby/src/Cms/Find.php b/kirby/src/Cms/Find.php index 581d3ab..7b57f40 100644 --- a/kirby/src/Cms/Find.php +++ b/kirby/src/Cms/Find.php @@ -33,7 +33,7 @@ class Find $filename = urldecode($filename); $file = static::parent($path)->file($filename); - if ($file && $file->isReadable() === true) { + if ($file?->isReadable() === true) { return $file; } @@ -78,7 +78,7 @@ class Find $id = str_replace(['+', ' '], '/', $id); $page = App::instance()->page($id); - if ($page && $page->isReadable() === true) { + if ($page?->isReadable() === true) { return $page; } @@ -117,31 +117,16 @@ class Find $kirby = App::instance(); - switch ($modelName) { - case 'site': - $model = $kirby->site(); - break; - case 'account': - $model = static::user(); - break; - case 'page': - $model = static::page(basename($path)); - break; - case 'file': - $model = static::file(...explode('/files/', $path)); - break; - case 'user': - $model = $kirby->user(basename($path)); - break; - default: - throw new InvalidArgumentException('Invalid model type: ' . $modelType); - } + $model = match ($modelName) { + 'site' => $kirby->site(), + 'account' => static::user(), + 'page' => static::page(basename($path)), + 'file' => static::file(...explode('/files/', $path)), + 'user' => $kirby->user(basename($path)), + default => throw new InvalidArgumentException('Invalid model type: ' . $modelType) + }; - if ($model) { - return $model; - } - - throw new NotFoundException([ + return $model ?? throw new NotFoundException([ 'key' => $modelName . '.undefined' ]); } @@ -167,21 +152,18 @@ class Find // get the authenticated user if ($id === null) { - if ($user = $kirby->user(null, $kirby->option('api.allowImpersonation', false))) { - return $user; - } + $user = $kirby->user( + null, + $kirby->option('api.allowImpersonation', false) + ); - throw new NotFoundException([ + return $user ?? throw new NotFoundException([ 'key' => 'user.undefined' ]); } // get a specific user by id - if ($user = $kirby->user($id)) { - return $user; - } - - throw new NotFoundException([ + return $kirby->user($id) ?? throw new NotFoundException([ 'key' => 'user.notFound', 'data' => [ 'name' => $id diff --git a/kirby/src/Cms/HasChildren.php b/kirby/src/Cms/HasChildren.php index cb2a75e..a798272 100644 --- a/kirby/src/Cms/HasChildren.php +++ b/kirby/src/Cms/HasChildren.php @@ -45,7 +45,7 @@ trait HasChildren */ public function children() { - if (is_a($this->children, 'Kirby\Cms\Pages') === true) { + if ($this->children instanceof Pages) { return $this->children; } @@ -59,7 +59,7 @@ trait HasChildren */ public function childrenAndDrafts() { - if (is_a($this->childrenAndDrafts, 'Kirby\Cms\Pages') === true) { + if ($this->childrenAndDrafts instanceof Pages) { return $this->childrenAndDrafts; } @@ -118,7 +118,7 @@ trait HasChildren */ public function drafts() { - if (is_a($this->drafts, 'Kirby\Cms\Pages') === true) { + if ($this->drafts instanceof Pages) { return $this->drafts; } @@ -217,9 +217,9 @@ trait HasChildren { if ($drafts === true) { return $this->childrenAndDrafts()->index($drafts); - } else { - return $this->children()->index(); } + + return $this->children()->index(); } /** diff --git a/kirby/src/Cms/HasFiles.php b/kirby/src/Cms/HasFiles.php index cb4102d..9e35fe2 100644 --- a/kirby/src/Cms/HasFiles.php +++ b/kirby/src/Cms/HasFiles.php @@ -2,6 +2,8 @@ namespace Kirby\Cms; +use Kirby\Uuid\Uuid; + /** * HasFiles * @@ -90,6 +92,11 @@ trait HasFiles return $this->$in()->first(); } + // find by global UUID + if (Uuid::is($filename, 'file') === true) { + return Uuid::for($filename, $this->files())->model(); + } + if (strpos($filename, '/') !== false) { $path = dirname($filename); $filename = basename($filename); @@ -111,7 +118,7 @@ trait HasFiles */ public function files() { - if (is_a($this->files, 'Kirby\Cms\Files') === true) { + if ($this->files instanceof Files) { return $this->files; } diff --git a/kirby/src/Cms/HasSiblings.php b/kirby/src/Cms/HasSiblings.php index ad6fa7d..99c334e 100644 --- a/kirby/src/Cms/HasSiblings.php +++ b/kirby/src/Cms/HasSiblings.php @@ -23,10 +23,7 @@ trait HasSiblings */ public function indexOf($collection = null): int { - if ($collection === null) { - $collection = $this->siblingsCollection(); - } - + $collection ??= $this->siblingsCollection(); return $collection->indexOf($this); } @@ -39,10 +36,7 @@ trait HasSiblings */ public function next($collection = null) { - if ($collection === null) { - $collection = $this->siblingsCollection(); - } - + $collection ??= $this->siblingsCollection(); return $collection->nth($this->indexOf($collection) + 1); } @@ -55,10 +49,7 @@ trait HasSiblings */ public function nextAll($collection = null) { - if ($collection === null) { - $collection = $this->siblingsCollection(); - } - + $collection ??= $this->siblingsCollection(); return $collection->slice($this->indexOf($collection) + 1); } @@ -71,10 +62,7 @@ trait HasSiblings */ public function prev($collection = null) { - if ($collection === null) { - $collection = $this->siblingsCollection(); - } - + $collection ??= $this->siblingsCollection(); return $collection->nth($this->indexOf($collection) - 1); } @@ -87,10 +75,7 @@ trait HasSiblings */ public function prevAll($collection = null) { - if ($collection === null) { - $collection = $this->siblingsCollection(); - } - + $collection ??= $this->siblingsCollection(); return $collection->slice(0, $this->indexOf($collection)); } @@ -144,10 +129,7 @@ trait HasSiblings */ public function isFirst($collection = null): bool { - if ($collection === null) { - $collection = $this->siblingsCollection(); - } - + $collection ??= $this->siblingsCollection(); return $collection->first()->is($this); } @@ -160,10 +142,7 @@ trait HasSiblings */ public function isLast($collection = null): bool { - if ($collection === null) { - $collection = $this->siblingsCollection(); - } - + $collection ??= $this->siblingsCollection(); return $collection->last()->is($this); } diff --git a/kirby/src/Cms/Helpers.php b/kirby/src/Cms/Helpers.php index a7c92fa..9ea9b35 100644 --- a/kirby/src/Cms/Helpers.php +++ b/kirby/src/Cms/Helpers.php @@ -44,7 +44,18 @@ class Helpers public static function dump($variable, bool $echo = true): string { $kirby = App::instance(); - return ($kirby->component('dump'))($kirby, $variable, $echo); + + if ($kirby->environment()->cli() === true) { + $output = print_r($variable, true) . PHP_EOL; + } else { + $output = '
' . print_r($variable, true) . '
'; + } + + if ($echo === true) { + echo $output; + } + + return $output; } /** @@ -53,29 +64,38 @@ class Helpers * @since 3.7.4 * * @param \Closure $action Any action that may cause an error or warning - * @param \Closure $handler Custom callback like for `set_error_handler()`; - * the first argument is a return value override passed - * by reference, the additional arguments come from - * `set_error_handler()`; returning `false` activates - * error handling by Whoops and/or PHP - * @return mixed Return value of the `$action` closure, possibly overridden by `$handler` + * @param \Closure $condition Closure that returns bool to determine if to + * suppress an error, receives arguments for + * `set_error_handler()` + * @param mixed $fallback Value to return when error is suppressed + * @return mixed Return value of the `$action` closure, + * possibly overridden by `$fallback` */ - public static function handleErrors(Closure $action, Closure $handler) + public static function handleErrors(Closure $action, Closure $condition, $fallback = null) { - $override = $oldHandler = null; - $oldHandler = set_error_handler(function () use (&$override, &$oldHandler, $handler) { - $handlerResult = $handler($override, ...func_get_args()); + $override = null; - if ($handlerResult === false) { + $handler = set_error_handler(function () use (&$override, &$handler, $condition, $fallback) { + // check if suppress condition is met + $suppress = $condition(...func_get_args()); + + if ($suppress !== true) { // handle other warnings with Whoops if loaded - if (is_callable($oldHandler) === true) { - return $oldHandler(...func_get_args()); + if (is_callable($handler) === true) { + return $handler(...func_get_args()); } // otherwise use the standard error handler return false; // @codeCoverageIgnore } + // use fallback to override return for suppressed errors + $override = $fallback; + + if (is_callable($override) === true) { + $override = $override(); + } + // no additional error handling return true; }); diff --git a/kirby/src/Cms/Html.php b/kirby/src/Cms/Html.php index 1af6087..b7c6774 100644 --- a/kirby/src/Cms/Html.php +++ b/kirby/src/Cms/Html.php @@ -26,7 +26,7 @@ class Html extends \Kirby\Toolkit\Html * @param string|array $options Pass an array of attributes for the link tag or a media attribute string * @return string|null */ - public static function css($url, $options = null): ?string + public static function css($url, $options = null): string|null { if (is_array($url) === true) { $links = A::map($url, fn ($url) => static::css($url, $options)); @@ -83,7 +83,7 @@ class Html extends \Kirby\Toolkit\Html * @param string|array $options * @return string|null */ - public static function js($url, $options = null): ?string + public static function js($url, $options = null): string|null { if (is_array($url) === true) { $scripts = A::map($url, fn ($url) => static::js($url, $options)); @@ -121,7 +121,7 @@ class Html extends \Kirby\Toolkit\Html { // support for Kirby's file objects if ( - is_a($file, 'Kirby\Cms\File') === true && + $file instanceof File && $file->extension() === 'svg' ) { return $file->read(); diff --git a/kirby/src/Cms/Ingredients.php b/kirby/src/Cms/Ingredients.php index 42442b3..ab84861 100644 --- a/kirby/src/Cms/Ingredients.php +++ b/kirby/src/Cms/Ingredients.php @@ -2,6 +2,8 @@ namespace Kirby\Cms; +use Closure; + /** * The Ingredients class is the foundation for * `$kirby->urls()` and `$kirby->roots()` objects. @@ -75,7 +77,7 @@ class Ingredients public static function bake(array $ingredients) { foreach ($ingredients as $name => $ingredient) { - if (is_a($ingredient, 'Closure') === true) { + if ($ingredient instanceof Closure) { $ingredients[$name] = $ingredient($ingredients); } } diff --git a/kirby/src/Cms/Item.php b/kirby/src/Cms/Item.php index 2f6922e..b6886dc 100644 --- a/kirby/src/Cms/Item.php +++ b/kirby/src/Cms/Item.php @@ -24,7 +24,7 @@ class Item { use HasSiblings; - public const ITEMS_CLASS = '\Kirby\Cms\Items'; + public const ITEMS_CLASS = Items::class; /** * @var string diff --git a/kirby/src/Cms/Items.php b/kirby/src/Cms/Items.php index 6bbecb5..da65ab1 100644 --- a/kirby/src/Cms/Items.php +++ b/kirby/src/Cms/Items.php @@ -17,7 +17,7 @@ use Exception; */ class Items extends Collection { - public const ITEM_CLASS = '\Kirby\Cms\Item'; + public const ITEM_CLASS = Item::class; /** * @var array diff --git a/kirby/src/Cms/Language.php b/kirby/src/Cms/Language.php index 04fec9d..42e95c4 100644 --- a/kirby/src/Cms/Language.php +++ b/kirby/src/Cms/Language.php @@ -212,6 +212,15 @@ class Language extends Model $language = new static($props); + // trigger before hook + $kirby->trigger( + 'language.create:before', + [ + 'input' => $props, + 'language' => $language + ] + ); + // validate the new language LanguageRules::create($language); @@ -222,7 +231,16 @@ class Language extends Model } // update the main languages collection in the app instance - App::instance()->languages(false)->append($language->code(), $language); + $kirby->languages(false)->append($language->code(), $language); + + // trigger after hook + $kirby->trigger( + 'language.create:after', + [ + 'input' => $props, + 'language' => $language + ] + ); return $language; } @@ -242,6 +260,11 @@ class Language extends Model $code = $this->code(); $isLast = $languages->count() === 1; + // trigger before hook + $kirby->trigger('language.delete:before', [ + 'language' => $this + ]); + if (F::remove($this->root()) !== true) { throw new Exception('The language could not be deleted'); } @@ -255,6 +278,11 @@ class Language extends Model // get the original language collection and remove the current language $kirby->languages(false)->remove($code); + // trigger after hook + $kirby->trigger('language.delete:after', [ + 'language' => $this + ]); + return true; } @@ -350,7 +378,7 @@ class Language extends Model try { return Data::read($file); - } catch (\Exception $e) { + } catch (\Exception) { return []; } } @@ -365,9 +393,9 @@ class Language extends Model { if ($category !== null) { return $this->locale[$category] ?? $this->locale[LC_ALL] ?? null; - } else { - return $this->locale; } + + return $this->locale; } /** @@ -456,7 +484,7 @@ class Language extends Model { try { $existingData = Data::read($this->root()); - } catch (Throwable $e) { + } catch (Throwable) { $existingData = []; } @@ -660,11 +688,15 @@ class Language extends Model // validate the updated language LanguageRules::update($updated); + // trigger before hook + $kirby->trigger('language.update:before', [ + 'language' => $this, + 'input' => $props + ]); + // convert the current default to a non-default language if ($updated->isDefault() === true) { - if ($oldDefault = $kirby->defaultLanguage()) { - $oldDefault->clone(['default' => false])->save(); - } + $kirby->defaultLanguage()?->clone(['default' => false])->save(); $code = $this->code(); $site = $kirby->site(); @@ -689,6 +721,13 @@ class Language extends Model // make sure the language is also updated in the Kirby language collection App::instance()->languages(false)->set($language->code(), $language); + // trigger after hook + $kirby->trigger('language.update:after', [ + 'newLanguage' => $language, + 'oldLanguage' => $this, + 'input' => $props + ]); + return $language; } } diff --git a/kirby/src/Cms/LanguageRouter.php b/kirby/src/Cms/LanguageRouter.php index 8fafbd7..60d3623 100644 --- a/kirby/src/Cms/LanguageRouter.php +++ b/kirby/src/Cms/LanguageRouter.php @@ -123,11 +123,11 @@ class LanguageRouter if ($page = $route->page()) { return $route->action()->call($route, $language, $page, ...$route->arguments()); - } else { - return $route->action()->call($route, $language, ...$route->arguments()); } + + return $route->action()->call($route, $language, ...$route->arguments()); }); - } catch (Exception $e) { + } catch (Exception) { return $kirby->resolve($path, $language->code()); } } diff --git a/kirby/src/Cms/LanguageRoutes.php b/kirby/src/Cms/LanguageRoutes.php index 6d15957..cfce0ca 100644 --- a/kirby/src/Cms/LanguageRoutes.php +++ b/kirby/src/Cms/LanguageRoutes.php @@ -33,7 +33,11 @@ class LanguageRoutes 'method' => 'ALL', 'env' => 'site', 'action' => function ($path = null) use ($language) { - if ($result = $language->router()->call($path)) { + $result = $language->router()->call($path); + + // explicitly test for null as $result can + // contain falsy values that should still be returned + if ($result !== null) { return $result; } diff --git a/kirby/src/Cms/Languages.php b/kirby/src/Cms/Languages.php index d746977..5c423f5 100644 --- a/kirby/src/Cms/Languages.php +++ b/kirby/src/Cms/Languages.php @@ -66,11 +66,7 @@ class Languages extends Collection */ public function default() { - if ($language = $this->findBy('isDefault', true)) { - return $language; - } else { - return $this->first(); - } + return $this->findBy('isDefault', true) ?? $this->first(); } /** @@ -85,7 +81,7 @@ class Languages extends Collection $files = glob(App::instance()->root('languages') . '/*.php'); foreach ($files as $file) { - $props = F::load($file); + $props = F::load($file, allowOutput: false); if (is_array($props) === true) { // inject the language code from the filename diff --git a/kirby/src/Cms/Layout.php b/kirby/src/Cms/Layout.php index 9a27fbf..57fd613 100644 --- a/kirby/src/Cms/Layout.php +++ b/kirby/src/Cms/Layout.php @@ -17,7 +17,7 @@ class Layout extends Item { use HasMethods; - public const ITEMS_CLASS = '\Kirby\Cms\Layouts'; + public const ITEMS_CLASS = Layouts::class; /** * @var \Kirby\Cms\Content diff --git a/kirby/src/Cms/LayoutColumn.php b/kirby/src/Cms/LayoutColumn.php index 2f652d1..5d1d9d8 100644 --- a/kirby/src/Cms/LayoutColumn.php +++ b/kirby/src/Cms/LayoutColumn.php @@ -19,7 +19,7 @@ class LayoutColumn extends Item { use HasMethods; - public const ITEMS_CLASS = '\Kirby\Cms\LayoutColumns'; + public const ITEMS_CLASS = LayoutColumns::class; /** * @var \Kirby\Cms\Blocks diff --git a/kirby/src/Cms/LayoutColumns.php b/kirby/src/Cms/LayoutColumns.php index 449678b..533e504 100644 --- a/kirby/src/Cms/LayoutColumns.php +++ b/kirby/src/Cms/LayoutColumns.php @@ -14,5 +14,5 @@ namespace Kirby\Cms; */ class LayoutColumns extends Items { - public const ITEM_CLASS = '\Kirby\Cms\LayoutColumn'; + public const ITEM_CLASS = LayoutColumn::class; } diff --git a/kirby/src/Cms/Layouts.php b/kirby/src/Cms/Layouts.php index b9f4c90..34b02bd 100644 --- a/kirby/src/Cms/Layouts.php +++ b/kirby/src/Cms/Layouts.php @@ -18,7 +18,7 @@ use Throwable; */ class Layouts extends Items { - public const ITEM_CLASS = '\Kirby\Cms\Layout'; + public const ITEM_CLASS = Layout::class; public static function factory(array $items = null, array $params = []) { @@ -65,7 +65,7 @@ class Layouts extends Items if (empty($input) === false && is_array($input) === false) { try { $input = Data::decode($input, 'json'); - } catch (Throwable $e) { + } catch (Throwable) { return []; } } diff --git a/kirby/src/Cms/Loader.php b/kirby/src/Cms/Loader.php index 0f0cbc4..d0a5488 100644 --- a/kirby/src/Cms/Loader.php +++ b/kirby/src/Cms/Loader.php @@ -54,7 +54,7 @@ class Loader * @param string $name * @return array|null */ - public function area(string $name): ?array + public function area(string $name): array|null { return $this->areas()[$name] ?? null; } @@ -102,7 +102,7 @@ class Loader * @param string $name * @return \Closure|null */ - public function component(string $name): ?Closure + public function component(string $name): Closure|null { return $this->extension('components', $name); } @@ -159,14 +159,13 @@ class Loader public function resolve($item) { if (is_string($item) === true) { - if (F::extension($item) !== 'php') { - $item = Data::read($item); - } else { - $item = require $item; - } + $item = match (F::extension($item)) { + 'php' => F::load($item, allowOutput: false), + default => Data::read($item) + }; } - if (is_callable($item)) { + if (is_callable($item) === true) { $item = $item($this->kirby); } @@ -206,7 +205,7 @@ class Loader // convert closure dropdowns to an array definition // otherwise they cannot be merged properly later foreach ($dropdowns as $key => $dropdown) { - if (is_a($dropdown, 'Closure') === true) { + if ($dropdown instanceof Closure) { $area['dropdowns'][$key] = [ 'options' => $dropdown ]; @@ -222,7 +221,7 @@ class Loader * @param string $name * @return array|null */ - public function section(string $name): ?array + public function section(string $name): array|null { return $this->resolve($this->extension('sections', $name)); } diff --git a/kirby/src/Cms/Media.php b/kirby/src/Cms/Media.php index 32da5af..777ab9a 100644 --- a/kirby/src/Cms/Media.php +++ b/kirby/src/Cms/Media.php @@ -46,10 +46,10 @@ class Media // if at least the token was correct, redirect if (Str::startsWith($hash, $file->mediaToken() . '-') === true) { return Response::redirect($file->mediaUrl(), 307); - } else { - // don't leak the correct token, render the error page - return false; } + + // don't leak the correct token, render the error page + return false; } // send the file to the browser @@ -97,16 +97,17 @@ class Media { $kirby = App::instance(); - // assets - if (is_string($model) === true) { - $root = $kirby->root('media') . '/assets/' . $model . '/' . $hash; - // parent files for file model that already included hash - } elseif (is_a($model, '\Kirby\Cms\File')) { - $root = dirname($model->mediaRoot()); - // model files - } else { - $root = $model->mediaRoot() . '/' . $hash; - } + $root = match (true) { + // assets + is_string($model) + => $kirby->root('media') . '/assets/' . $model . '/' . $hash, + // parent files for file model that already included hash + $model instanceof File + => dirname($model->mediaRoot()), + // model files + default + => $model->mediaRoot() . '/' . $hash + }; try { $thumb = $root . '/' . $filename; @@ -117,21 +118,22 @@ class Media return false; } - if (is_string($model) === true) { - $source = $kirby->root('index') . '/' . $model . '/' . $options['filename']; - } else { - $source = $model->file($options['filename'])->root(); - } + $source = match (true) { + is_string($model) === true + => $kirby->root('index') . '/' . $model . '/' . $options['filename'], + default + => $model->file($options['filename'])->root() + }; try { $kirby->thumb($source, $thumb, $options); F::remove($job); return Response::file($thumb); - } catch (Throwable $e) { + } catch (Throwable) { F::remove($thumb); return Response::file($source); } - } catch (Throwable $e) { + } catch (Throwable) { return false; } } diff --git a/kirby/src/Cms/Model.php b/kirby/src/Cms/Model.php index 94c0317..7acf7c6 100644 --- a/kirby/src/Cms/Model.php +++ b/kirby/src/Cms/Model.php @@ -53,7 +53,7 @@ abstract class Model /** * Each model must return a unique id * - * @return string|int + * @return string|null */ public function id() { diff --git a/kirby/src/Cms/ModelPermissions.php b/kirby/src/Cms/ModelPermissions.php index 5212c4f..916c0d8 100644 --- a/kirby/src/Cms/ModelPermissions.php +++ b/kirby/src/Cms/ModelPermissions.php @@ -67,7 +67,10 @@ abstract class ModelPermissions } // check for a custom overall can method - if (method_exists($this, 'can' . $action) === true && $this->{'can' . $action}() === false) { + if ( + method_exists($this, 'can' . $action) === true && + $this->{'can' . $action}() === false + ) { return false; } @@ -83,7 +86,10 @@ abstract class ModelPermissions return true; } - if (is_array($options) === true && A::isAssociative($options) === true) { + if ( + is_array($options) === true && + A::isAssociative($options) === true + ) { return $options[$role] ?? $options['*'] ?? false; } } diff --git a/kirby/src/Cms/ModelWithContent.php b/kirby/src/Cms/ModelWithContent.php index 2596ea1..71c7501 100644 --- a/kirby/src/Cms/ModelWithContent.php +++ b/kirby/src/Cms/ModelWithContent.php @@ -7,6 +7,9 @@ use Kirby\Data\Data; use Kirby\Exception\InvalidArgumentException; use Kirby\Form\Form; use Kirby\Toolkit\Str; +use Kirby\Uuid\Identifiable; +use Kirby\Uuid\Uuid; +use Kirby\Uuid\Uuids; use Throwable; /** @@ -18,7 +21,7 @@ use Throwable; * @copyright Bastian Allgeier * @license https://getkirby.com/license */ -abstract class ModelWithContent extends Model +abstract class ModelWithContent extends Model implements Identifiable { /** * The content @@ -85,35 +88,39 @@ abstract class ModelWithContent extends Model { // single language support if ($this->kirby()->multilang() === false) { - if (is_a($this->content, 'Kirby\Cms\Content') === true) { + if ($this->content instanceof Content) { return $this->content; } // don't normalize field keys (already handled by the `Data` class) return $this->content = new Content($this->readContent(), $this, false); - - // multi language support - } else { - // only fetch from cache for the default language - if ($languageCode === null && is_a($this->content, 'Kirby\Cms\Content') === true) { - return $this->content; - } - - // get the translation by code - if ($translation = $this->translation($languageCode)) { - // don't normalize field keys (already handled by the `ContentTranslation` class) - $content = new Content($translation->content(), $this, false); - } else { - throw new InvalidArgumentException('Invalid language: ' . $languageCode); - } - - // only store the content for the current language - if ($languageCode === null) { - $this->content = $content; - } - - return $content; } + + // get the targeted language + $language = $this->kirby()->language($languageCode); + + // stop if the language does not exist + if ($language === null) { + throw new InvalidArgumentException('Invalid language: ' . $languageCode); + } + + // only fetch from cache for the current language + if ($languageCode === null && $this->content instanceof Content) { + return $this->content; + } + + // get the translation by code + $translation = $this->translation($language->code()); + + // don't normalize field keys (already handled by the `ContentTranslation` class) + $content = new Content($translation->content(), $this, false); + + // only store the content for the current language + if ($languageCode === null) { + $this->content = $content; + } + + return $content; } /** @@ -135,21 +142,21 @@ abstract class ModelWithContent extends Model if ($force === true) { if (empty($languageCode) === false) { return $directory . '/' . $filename . '.' . $languageCode . '.' . $extension; - } else { - return $directory . '/' . $filename . '.' . $extension; } + + return $directory . '/' . $filename . '.' . $extension; } // add and validate the language code in multi language mode if ($this->kirby()->multilang() === true) { if ($language = $this->kirby()->languageCode($languageCode)) { return $directory . '/' . $filename . '.' . $language . '.' . $extension; - } else { - throw new InvalidArgumentException('Invalid language: ' . $languageCode); } - } else { - return $directory . '/' . $filename . '.' . $extension; + + throw new InvalidArgumentException('Invalid language: ' . $languageCode); } + + return $directory . '/' . $filename . '.' . $extension; } /** @@ -165,11 +172,11 @@ abstract class ModelWithContent extends Model $files[] = $this->contentFile($code); } return $files; - } else { - return [ - $this->contentFile() - ]; } + + return [ + $this->contentFile() + ]; } /** @@ -194,7 +201,7 @@ abstract class ModelWithContent extends Model * @internal * @return string|null */ - public function contentFileDirectory(): ?string + public function contentFileDirectory(): string|null { return $this->root(); } @@ -346,15 +353,15 @@ abstract class ModelWithContent extends Model try { $result = Str::query($query, [ 'kirby' => $this->kirby(), - 'site' => is_a($this, 'Kirby\Cms\Site') ? $this : $this->site(), + 'site' => $this instanceof Site ? $this : $this->site(), 'model' => $this, static::CLASS_ALIAS => $this ]); - } catch (Throwable $e) { + } catch (Throwable) { return null; } - if ($expect !== null && is_a($result, $expect) !== true) { + if ($expect !== null && $result instanceof $expect === false) { return null; } @@ -370,11 +377,16 @@ abstract class ModelWithContent extends Model */ public function readContent(string $languageCode = null): array { - try { - return Data::read($this->contentFile($languageCode)); - } catch (Throwable $e) { + $file = $this->contentFile($languageCode); + + // only if the content file really does not exist, it's ok + // to return empty content. Otherwise this could lead to + // content loss in case of file reading issues + if (file_exists($file) === false) { return []; } + + return Data::read($file); } /** @@ -382,7 +394,7 @@ abstract class ModelWithContent extends Model * * @return string|null */ - abstract public function root(): ?string; + abstract public function root(): string|null; /** * Stores the content on disk @@ -397,9 +409,9 @@ abstract class ModelWithContent extends Model { if ($this->kirby()->multilang() === true) { return $this->saveTranslation($data, $languageCode, $overwrite); - } else { - return $this->saveContent($data, $overwrite); } + + return $this->saveContent($data, $overwrite); } /** @@ -457,6 +469,11 @@ abstract class ModelWithContent extends Model } } + // remove UUID for non-default languages + if (Uuids::enabled() === true && isset($content['uuid']) === true) { + $content['uuid'] = null; + } + // merge the translation with the new data $translation->update($content, true); } @@ -514,10 +531,11 @@ abstract class ModelWithContent extends Model * * @param string|null $template Template string or `null` to use the model ID * @param array $data - * @param string $fallback Fallback for tokens in the template that cannot be replaced + * @param string|null $fallback Fallback for tokens in the template that cannot be replaced + * (`null` to keep the original token) * @return string */ - public function toSafeString(string $template = null, array $data = [], string $fallback = ''): string + public function toSafeString(string $template = null, array $data = [], string|null $fallback = ''): string { return $this->toString($template, $data, $fallback, 'safeTemplate'); } @@ -527,11 +545,12 @@ abstract class ModelWithContent extends Model * * @param string|null $template Template string or `null` to use the model ID * @param array $data - * @param string $fallback Fallback for tokens in the template that cannot be replaced + * @param string|null $fallback Fallback for tokens in the template that cannot be replaced + * (`null` to keep the original token) * @param string $handler For internal use * @return string */ - public function toString(string $template = null, array $data = [], string $fallback = '', string $handler = 'template'): string + public function toString(string $template = null, array $data = [], string|null $fallback = '', string $handler = 'template'): string { if ($template === null) { return $this->id() ?? ''; @@ -543,7 +562,7 @@ abstract class ModelWithContent extends Model $result = Str::$handler($template, array_replace([ 'kirby' => $this->kirby(), - 'site' => is_a($this, 'Kirby\Cms\Site') ? $this : $this->site(), + 'site' => $this instanceof Site ? $this : $this->site(), 'model' => $this, static::CLASS_ALIAS => $this, ], $data), ['fallback' => $fallback]); @@ -560,7 +579,11 @@ abstract class ModelWithContent extends Model */ public function translation(string $languageCode = null) { - return $this->translations()->find($languageCode ?? $this->kirby()->language()->code()); + if ($language = $this->kirby()->language($languageCode)) { + return $this->translations()->find($language->code()); + } + + return null; } /** @@ -617,16 +640,19 @@ abstract class ModelWithContent extends Model $arguments = [static::CLASS_ALIAS => $this, 'values' => $form->data(), 'strings' => $form->strings(), 'languageCode' => $languageCode]; return $this->commit('update', $arguments, function ($model, $values, $strings, $languageCode) { - // save updated values - $model = $model->save($strings, $languageCode, true); - - // update model in siblings collection - $model->siblings()->add($model); - - return $model; + return $model->save($strings, $languageCode, true); }); } + /** + * Returns the model's UUID + * @since 3.8.0 + */ + public function uuid(): Uuid|null + { + return Uuid::for($this); + } + /** * Low level data writer method * to store the given data on disk or anywhere else @@ -643,59 +669,4 @@ abstract class ModelWithContent extends Model $this->contentFileData($data, $languageCode) ); } - - - /** - * Deprecated! - */ - - /** - * Returns the panel icon definition - * - * @deprecated 3.6.0 Use `->panel()->image()` instead - * @todo Remove in 3.8.0 - * - * @internal - * @param array|null $params - * @return array|null - * @codeCoverageIgnore - */ - public function panelIcon(array $params = null): ?array - { - Helpers::deprecated('Cms\ModelWithContent::panelIcon() has been deprecated and will be removed in Kirby 3.8.0. Use $model->panel()->image() instead.'); - return $this->panel()->image($params); - } - - /** - * @deprecated 3.6.0 Use `->panel()->image()` instead - * @todo Remove in 3.8.0 - * - * @internal - * @param string|array|false|null $settings - * @return array|null - * @codeCoverageIgnore - */ - public function panelImage($settings = null): ?array - { - Helpers::deprecated('Cms\ModelWithContent::panelImage() has been deprecated and will be removed in Kirby 3.8.0. Use $model->panel()->image() instead.'); - return $this->panel()->image($settings); - } - - /** - * Returns an array of all actions - * that can be performed in the Panel - * This also checks for the lock status - * - * @deprecated 3.6.0 Use `->panel()->options()` instead - * @todo Remove in 3.8.0 - * - * @param array $unlock An array of options that will be force-unlocked - * @return array - * @codeCoverageIgnore - */ - public function panelOptions(array $unlock = []): array - { - Helpers::deprecated('Cms\ModelWithContent::panelOptions() has been deprecated and will be removed in Kirby 3.8.0. Use $model->panel()->options() instead.'); - return $this->panel()->options($unlock); - } } diff --git a/kirby/src/Cms/Nest.php b/kirby/src/Cms/Nest.php index 56455b3..cde1b29 100644 --- a/kirby/src/Cms/Nest.php +++ b/kirby/src/Cms/Nest.php @@ -18,13 +18,10 @@ namespace Kirby\Cms; */ class Nest { - /** - * @param $data - * @param null $parent - * @return mixed - */ - public static function create($data, $parent = null) - { + public static function create( + $data, + object|null $parent = null + ): NestCollection|NestObject|Field { if (is_scalar($data) === true) { return new Field($parent, $data, $data); } @@ -39,10 +36,12 @@ class Nest } } - if (is_int(key($data))) { + $key = key($data); + + if ($key === null || is_int($key) === true) { return new NestCollection($result); - } else { - return new NestObject($result); } + + return new NestObject($result); } } diff --git a/kirby/src/Cms/NestCollection.php b/kirby/src/Cms/NestCollection.php index b5b1a7b..129668d 100644 --- a/kirby/src/Cms/NestCollection.php +++ b/kirby/src/Cms/NestCollection.php @@ -20,9 +20,6 @@ class NestCollection extends BaseCollection * Converts all objects in the collection * to an array. This can also take a callback * function to further modify the array result. - * - * @param \Closure|null $map - * @return array */ public function toArray(Closure $map = null): array { diff --git a/kirby/src/Cms/NestObject.php b/kirby/src/Cms/NestObject.php index 4744539..2dc9176 100644 --- a/kirby/src/Cms/NestObject.php +++ b/kirby/src/Cms/NestObject.php @@ -17,20 +17,21 @@ class NestObject extends Obj { /** * Converts the object to an array - * - * @return array */ public function toArray(): array { $result = []; foreach ((array)$this as $key => $value) { - if (is_a($value, 'Kirby\Cms\Field') === true) { + if ($value instanceof Field) { $result[$key] = $value->value(); continue; } - if (is_object($value) === true && method_exists($value, 'toArray')) { + if ( + is_object($value) === true && + method_exists($value, 'toArray') + ) { $result[$key] = $value->toArray(); continue; } diff --git a/kirby/src/Cms/Page.php b/kirby/src/Cms/Page.php index 88c95cd..53eeac9 100644 --- a/kirby/src/Cms/Page.php +++ b/kirby/src/Cms/Page.php @@ -2,6 +2,7 @@ namespace Kirby\Cms; +use Closure; use Kirby\Exception\Exception; use Kirby\Exception\InvalidArgumentException; use Kirby\Exception\NotFoundException; @@ -217,9 +218,9 @@ class Page extends ModelWithContent { if ($relative === true) { return 'pages/' . $this->panel()->id(); - } else { - return $this->kirby()->url('api') . '/pages/' . $this->panel()->id(); } + + return $this->kirby()->url('api') . '/pages/' . $this->panel()->id(); } /** @@ -229,7 +230,7 @@ class Page extends ModelWithContent */ public function blueprint() { - if (is_a($this->blueprint, 'Kirby\Cms\PageBlueprint') === true) { + if ($this->blueprint instanceof PageBlueprint) { return $this->blueprint; } @@ -242,7 +243,7 @@ class Page extends ModelWithContent * @param string|null $inSection * @return array */ - public function blueprints(?string $inSection = null): array + public function blueprints(string|null $inSection = null): array { if ($inSection !== null) { return $this->blueprint()->section($inSection)->blueprints(); @@ -272,7 +273,7 @@ class Page extends ModelWithContent 'name' => basename($props['name']), 'title' => $props['title'], ]; - } catch (Exception $e) { + } catch (Exception) { // skip invalid blueprints } } @@ -307,7 +308,7 @@ class Page extends ModelWithContent * @param string|null $languageCode * @return array */ - public function contentFileData(array $data, ?string $languageCode = null): array + public function contentFileData(array $data, string|null $languageCode = null): array { return A::prepend($data, [ 'title' => $data['title'] ?? null, @@ -323,7 +324,7 @@ class Page extends ModelWithContent * @param string|null $languageCode * @return string */ - public function contentFileName(?string $languageCode = null): string + public function contentFileName(string|null $languageCode = null): string { return $this->intendedTemplate()->name(); } @@ -361,7 +362,7 @@ class Page extends ModelWithContent foreach ($controllerData as $key => $value) { if (array_key_exists($key, $classes) === true) { - if (is_a($value, $classes[$key]) === true) { + if ($value instanceof $classes[$key]) { $data[$key] = $value; } else { throw new InvalidArgumentException('The returned variable "' . $key . '" from the controller "' . $this->template()->name() . '" is not of the required type "' . $classes[$key] . '"'); @@ -399,9 +400,9 @@ class Page extends ModelWithContent if ($this->num() !== null) { return $this->dirname = $this->num() . Dir::$numSeparator . $this->uid(); - } else { - return $this->dirname = $this->uid(); } + + return $this->dirname = $this->uid(); } /** @@ -423,9 +424,9 @@ class Page extends ModelWithContent if ($parent = $this->parent()) { return $this->diruri = $parent->diruri() . '/' . $dirname; - } else { - return $this->diruri = $dirname; } + + return $this->diruri = $dirname; } /** @@ -545,7 +546,7 @@ class Page extends ModelWithContent */ public function is($page): bool { - if (is_a($page, 'Kirby\Cms\Page') === false) { + if ($page instanceof self === false) { if (is_string($page) === false) { return false; } @@ -553,7 +554,7 @@ class Page extends ModelWithContent $page = $this->kirby()->page($page); } - if (is_a($page, 'Kirby\Cms\Page') === false) { + if ($page instanceof self === false) { return false; } @@ -567,10 +568,8 @@ class Page extends ModelWithContent */ public function isActive(): bool { - if ($page = $this->site()->page()) { - if ($page->is($this) === true) { - return true; - } + if ($this->site()->page()?->is($this) === true) { + return true; } return false; @@ -625,7 +624,7 @@ class Page extends ModelWithContent } // check for a custom ignore rule - if (is_a($ignore, 'Closure') === true) { + if ($ignore instanceof Closure) { if ($ignore($this) === true) { return false; } @@ -649,11 +648,7 @@ class Page extends ModelWithContent */ public function isChildOf($parent): bool { - if ($parentObj = $this->parent()) { - return $parentObj->is($parent); - } - - return false; + return $this->parent()?->is($parent) ?? false; } /** @@ -754,10 +749,8 @@ class Page extends ModelWithContent return true; } - if ($page = $this->site()->page()) { - if ($page->parents()->has($this->id()) === true) { - return true; - } + if ($this->site()->page()?->parents()->has($this->id()) === true) { + return true; } return false; @@ -784,11 +777,7 @@ class Page extends ModelWithContent $template = $this->intendedTemplate()->name(); - if (isset($readable[$template]) === true) { - return $readable[$template]; - } - - return $readable[$template] = $this->permissions()->can('read'); + return $readable[$template] ??= $this->permissions()->can('read'); } /** @@ -870,7 +859,7 @@ class Page extends ModelWithContent if ($class = (static::$models[$name] ?? null)) { $object = new $class($props); - if (is_a($object, 'Kirby\Cms\Page') === true) { + if ($object instanceof self) { return $object; } } @@ -900,7 +889,7 @@ class Page extends ModelWithContent * * @return int|null */ - public function num(): ?int + public function num(): int|null { return $this->num; } @@ -931,13 +920,9 @@ class Page extends ModelWithContent * @internal * @return string|null */ - public function parentId(): ?string + public function parentId(): string|null { - if ($parent = $this->parent()) { - return $parent->id(); - } - - return null; + return $this->parent()?->id(); } /** @@ -971,6 +956,15 @@ class Page extends ModelWithContent return $parents; } + /** + * Return the permanent URL to the page using its UUID + * @since 3.8.0 + */ + public function permalink(): string|null + { + return $this->uuid()?->url(); + } + /** * Returns the permissions object for this page * @@ -987,7 +981,7 @@ class Page extends ModelWithContent * @internal * @return string|null */ - public function previewUrl(): ?string + public function previewUrl(): string|null { $preview = $this->blueprint()->preview(); @@ -1066,9 +1060,24 @@ class Page extends ModelWithContent $kirby->data = $this->controller($data, $contentType); + // trigger before hook and apply for `data` + $kirby->data = $kirby->apply('page.render:before', [ + 'contentType' => $contentType, + 'data' => $kirby->data, + 'page' => $this + ], 'data'); + // render the page $html = $template->render($kirby->data); + // trigger after hook and apply for `html` + $html = $kirby->apply('page.render:after', [ + 'contentType' => $contentType, + 'data' => $kirby->data, + 'html' => $html, + 'page' => $this + ], 'html'); + // cache the result $response = $kirby->response(); if ($cache !== null && $response->cache() === true) { @@ -1411,9 +1420,9 @@ class Page extends ModelWithContent if ($this->kirby()->multilang() === true) { if (is_string($options) === true) { return $this->urlForLanguage($options); - } else { - return $this->urlForLanguage(null, $options); } + + return $this->urlForLanguage(null, $options); } if ($options !== null) { @@ -1431,9 +1440,9 @@ class Page extends ModelWithContent if ($parent = $this->parent()) { if ($parent->isHomePage() === true) { return $this->url = $this->kirby()->url('base') . '/' . $parent->uid() . '/' . $this->uid(); - } else { - return $this->url = $this->parent()->url() . '/' . $this->uid(); } + + return $this->url = $this->parent()->url() . '/' . $this->uid(); } return $this->url = $this->kirby()->url('base') . '/' . $this->uid(); @@ -1460,104 +1469,11 @@ class Page extends ModelWithContent if ($parent = $this->parent()) { if ($parent->isHomePage() === true) { return $this->url = $this->site()->urlForLanguage($language) . '/' . $parent->slug($language) . '/' . $this->slug($language); - } else { - return $this->url = $this->parent()->urlForLanguage($language) . '/' . $this->slug($language); } + + return $this->url = $this->parent()->urlForLanguage($language) . '/' . $this->slug($language); } return $this->url = $this->site()->urlForLanguage($language) . '/' . $this->slug($language); } - - - /** - * Deprecated! - */ - - /** - * Provides a kirbytag or markdown - * tag for the page, which will be - * used in the panel, when the page - * gets dragged onto a textarea - * - * @deprecated 3.6.0 Use `->panel()->dragText()` instead - * @todo Remove in 3.8.0 - * - * @internal - * @param string|null $type (null|auto|kirbytext|markdown) - * @return string - * @codeCoverageIgnore - */ - public function dragText(string $type = null): string - { - Helpers::deprecated('Cms\Page::dragText() has been deprecated and will be removed in Kirby 3.8.0. Use $page->panel()->dragText() instead.'); - return $this->panel()->dragText($type); - } - - /** - * Returns the escaped Id, which is - * used in the panel to make routing work properly - * - * @deprecated 3.6.0 Use `->panel()->id()` instead - * @todo Remove in 3.8.0 - * - * @internal - * @return string - * @codeCoverageIgnore - */ - public function panelId(): string - { - Helpers::deprecated('Cms\Page::panelId() has been deprecated and will be removed in Kirby 3.8.0. Use $page->panel()->id() instead.'); - return $this->panel()->id(); - } - - /** - * Returns the full path without leading slash - * - * @deprecated 3.6.0 Use `->panel()->path()` instead - * @todo Remove in 3.8.0 - * - * @internal - * @return string - * @codeCoverageIgnore - */ - public function panelPath(): string - { - Helpers::deprecated('Cms\Page::panelPath() has been deprecated and will be removed in Kirby 3.8.0. Use $page->panel()->path() instead.'); - return $this->panel()->path(); - } - - /** - * Prepares the response data for page pickers - * and page fields - * - * @deprecated 3.6.0 Use `->panel()->pickerData()` instead - * @todo Remove in 3.8.0 - * - * @param array|null $params - * @return array - * @codeCoverageIgnore - */ - public function panelPickerData(array $params = []): array - { - Helpers::deprecated('Cms\Page::panelPickerData() has been deprecated and will be removed in Kirby 3.8.0. Use $page->panel()->pickerData() instead.'); - return $this->panel()->pickerData($params); - } - - /** - * Returns the url to the editing view - * in the panel - * - * @deprecated 3.6.0 Use `->panel()->url()` instead - * @todo Remove in 3.8.0 - * - * @internal - * @param bool $relative - * @return string - * @codeCoverageIgnore - */ - public function panelUrl(bool $relative = false): string - { - Helpers::deprecated('Cms\Page::panelUrl() has been deprecated and will be removed in Kirby 3.8.0. Use $page->panel()->url() instead.'); - return $this->panel()->url($relative); - } } diff --git a/kirby/src/Cms/PageActions.php b/kirby/src/Cms/PageActions.php index ec9115c..5cda48b 100644 --- a/kirby/src/Cms/PageActions.php +++ b/kirby/src/Cms/PageActions.php @@ -13,6 +13,8 @@ use Kirby\Form\Form; use Kirby\Toolkit\A; use Kirby\Toolkit\I18n; use Kirby\Toolkit\Str; +use Kirby\Uuid\Uuid; +use Kirby\Uuid\Uuids; /** * PageActions @@ -25,6 +27,75 @@ use Kirby\Toolkit\Str; */ trait PageActions { + /** + * Adapts necessary modifications which page uuid, page slug and files uuid + * of copy objects for single or multilang environments + */ + protected function adaptCopy(Page $copy, bool $files = false, bool $children = false): Page + { + if ($this->kirby()->multilang() === true) { + foreach ($this->kirby()->languages() as $language) { + // overwrite with new UUID for the page and files + // for default language (remove old, add new) + if ( + Uuids::enabled() === true && + $language->isDefault() === true + ) { + $copy = $copy->save(['uuid' => Uuid::generate()], $language->code()); + + // regenerate UUIDs of page files + if ($files !== false) { + foreach ($copy->files() as $file) { + $file->save(['uuid' => Uuid::generate()], $language->code()); + } + } + + // regenerate UUIDs of all page children + if ($children !== false) { + foreach ($copy->index(true) as $child) { + // always adapt files of subpages as they are currently always copied; + // but don't adapt children because we already operate on the index + $this->adaptCopy($child, true); + } + } + } + + // remove all translated slugs + if ( + $language->isDefault() === false && + $copy->translation($language)->exists() === true + ) { + $copy = $copy->save(['slug' => null], $language->code()); + } + } + + return $copy; + } + + // overwrite with new UUID for the page and files (remove old, add new) + if (Uuids::enabled() === true) { + $copy = $copy->save(['uuid' => Uuid::generate()]); + + // regenerate UUIDs of page files + if ($files !== false) { + foreach ($copy->files() as $file) { + $file->save(['uuid' => Uuid::generate()]); + } + } + + // regenerate UUIDs of all page children + if ($children !== false) { + foreach ($copy->index(true) as $child) { + // always adapt files of subpages as they are currently always copied; + // but don't adapt children because we already operate on the index + $this->adaptCopy($child, true); + } + } + } + + return $copy; + } + /** * Changes the sorting number. * The sorting number must already be correct @@ -88,10 +159,8 @@ trait PageActions // in multi-language installations the slug for the non-default // languages is stored in the text file. The changeSlugForLanguage // method takes care of that. - if ($language = $this->kirby()->language($languageCode)) { - if ($language->isDefault() === false) { - return $this->changeSlugForLanguage($slug, $languageCode); - } + if ($this->kirby()->language($languageCode)?->isDefault() === false) { + return $this->changeSlugForLanguage($slug, $languageCode); } // if the slug stays exactly the same, @@ -108,11 +177,12 @@ trait PageActions 'root' => null ]); + // clear UUID cache recursively (for children and files as well) + $oldPage->uuid()?->clear(true); + if ($oldPage->exists() === true) { // remove the lock of the old page - if ($lock = $oldPage->lock()) { - $lock->remove(); - } + $oldPage->lock()?->remove(); // actually move stuff on disk if (Dir::move($oldPage->root(), $newPage->root()) !== true) { @@ -182,16 +252,12 @@ trait PageActions */ public function changeStatus(string $status, int $position = null) { - switch ($status) { - case 'draft': - return $this->changeStatusToDraft(); - case 'listed': - return $this->changeStatusToListed($position); - case 'unlisted': - return $this->changeStatusToUnlisted(); - default: - throw new InvalidArgumentException('Invalid status: ' . $status); - } + return match ($status) { + 'draft' => $this->changeStatusToDraft(), + 'listed' => $this->changeStatusToListed($position), + 'unlisted' => $this->changeStatusToUnlisted(), + default => throw new InvalidArgumentException('Invalid status: ' . $status) + }; } /** @@ -437,14 +503,8 @@ trait PageActions $copy = $parentModel->clone()->findPageOrDraft($slug); - // remove all translated slugs - if ($this->kirby()->multilang() === true) { - foreach ($this->kirby()->languages() as $language) { - if ($language->isDefault() === false && $copy->translation($language)->exists() === true) { - $copy = $copy->save(['slug' => null], $language->code()); - } - } - } + // normalize copy object + $copy = $this->adaptCopy($copy, $files, $children); // add copy to siblings static::updateParentCollections($copy, 'append', $parentModel); @@ -465,13 +525,19 @@ trait PageActions $props['template'] = $props['model'] = strtolower($props['template'] ?? 'default'); $props['isDraft'] = ($props['draft'] ?? true); + // make sure that a UUID gets generated and + // added to content right away + $props['content'] ??= []; + + if (Uuids::enabled() === true) { + $props['content']['uuid'] ??= Uuid::generate(); + } + // create a temporary page object $page = Page::factory($props); // create a form for the page - $form = Form::for($page, [ - 'values' => $props['content'] ?? [] - ]); + $form = Form::for($page, ['values' => $props['content']]); // inject the content $page = $page->clone(['content' => $form->strings(true)]); @@ -593,6 +659,9 @@ trait PageActions public function delete(bool $force = false): bool { return $this->commit('delete', ['page' => $this, 'force' => $force], function ($page, $force) { + // clear UUID cache + $page->uuid()?->clear(); + // delete all files individually foreach ($page->files() as $file) { $file->delete(); @@ -765,9 +834,9 @@ trait PageActions foreach ($sorted as $key => $id) { if ($id === $this->id()) { continue; - } elseif ($sibling = $siblings->get($id)) { - $sibling->changeNum($key + 1); } + + $siblings->get($id)?->changeNum($key + 1); } $parent = $this->parentModel(); @@ -803,6 +872,25 @@ trait PageActions return true; } + /** + * Stores the content on disk + * + * @internal + * @param array|null $data + * @param string|null $languageCode + * @param bool $overwrite + * @return static + */ + public function save(array $data = null, string $languageCode = null, bool $overwrite = false) + { + $page = parent::save($data, $languageCode, $overwrite); + + // overwrite the updated page in the parent collection + static::updateParentCollections($page, 'set'); + + return $page; + } + /** * Convert a page from listed or * unlisted to draft. @@ -862,7 +950,10 @@ trait PageActions $page = parent::update($input, $languageCode, $validate); // if num is created from page content, update num on content update - if ($page->isListed() === true && in_array($page->blueprint()->num(), ['zero', 'default']) === false) { + if ( + $page->isListed() === true && + in_array($page->blueprint()->num(), ['zero', 'default']) === false + ) { $page = $page->changeNum($page->createNum()); } diff --git a/kirby/src/Cms/PageBlueprint.php b/kirby/src/Cms/PageBlueprint.php index 87e4937..12843d3 100644 --- a/kirby/src/Cms/PageBlueprint.php +++ b/kirby/src/Cms/PageBlueprint.php @@ -79,11 +79,7 @@ class PageBlueprint extends Blueprint 'sort' => 'default', ]; - if (isset($aliases[$num]) === true) { - return $aliases[$num]; - } - - return $num; + return $aliases[$num] ?? $num; } /** @@ -144,9 +140,7 @@ class PageBlueprint extends Blueprint } // also make sure to have the text field set - if (isset($status[$key]['text']) === false) { - $status[$key]['text'] = null; - } + $status[$key]['text'] ??= null; // translate text and label if necessary $status[$key]['label'] = $this->i18n($status[$key]['label'], $status[$key]['label']); diff --git a/kirby/src/Cms/PagePermissions.php b/kirby/src/Cms/PagePermissions.php index 53fcb84..fbc69a9 100644 --- a/kirby/src/Cms/PagePermissions.php +++ b/kirby/src/Cms/PagePermissions.php @@ -39,7 +39,7 @@ class PagePermissions extends ModelPermissions */ protected function canChangeTemplate(): bool { - if ($this->model->isHomeOrErrorPage() === true) { + if ($this->model->isErrorPage() === true) { return false; } diff --git a/kirby/src/Cms/PagePicker.php b/kirby/src/Cms/PagePicker.php index 802e7e8..a8e38de 100644 --- a/kirby/src/Cms/PagePicker.php +++ b/kirby/src/Cms/PagePicker.php @@ -86,11 +86,7 @@ class PagePicker extends Picker return $this->parent(); } - if ($items = $this->items()) { - return $items->parent(); - } - - return null; + return $this->items()?->parent(); } /** @@ -101,14 +97,14 @@ class PagePicker extends Picker * @param \Kirby\Cms\Site|\Kirby\Cms\Page|null * @return array|null */ - public function modelToArray($model = null): ?array + public function modelToArray($model = null): array|null { if ($model === null) { return null; } // the selected model is the site. there's nothing above - if (is_a($model, 'Kirby\Cms\Site') === true) { + if ($model instanceof Site) { return [ 'id' => null, 'parent' => null, @@ -200,13 +196,13 @@ class PagePicker extends Picker // help mitigate some typical query usage issues // by converting site and page objects to proper // pages by returning their children - if (is_a($items, 'Kirby\Cms\Site') === true) { - $items = $items->children(); - } elseif (is_a($items, 'Kirby\Cms\Page') === true) { - $items = $items->children(); - } elseif (is_a($items, 'Kirby\Cms\Pages') === false) { - throw new InvalidArgumentException('Your query must return a set of pages'); - } + $items = match (true) { + $items instanceof Site, + $items instanceof Page => $items->children(), + $items instanceof Pages => $items, + + default => throw new InvalidArgumentException('Your query must return a set of pages') + }; return $this->itemsForQuery = $items; } @@ -238,11 +234,7 @@ class PagePicker extends Picker public function start() { if (empty($this->options['query']) === false) { - if ($items = $this->itemsForQuery()) { - return $items->parent(); - } - - return $this->site; + return $this->itemsForQuery()?->parent() ?? $this->site; } return $this->site; diff --git a/kirby/src/Cms/PageRules.php b/kirby/src/Cms/PageRules.php index 68cc711..9e0b36d 100644 --- a/kirby/src/Cms/PageRules.php +++ b/kirby/src/Cms/PageRules.php @@ -61,26 +61,22 @@ class PageRules $siblings = $page->parentModel()->children(); $drafts = $page->parentModel()->drafts(); - if ($duplicate = $siblings->find($slug)) { - if ($duplicate->is($page) === false) { - throw new DuplicateException([ - 'key' => 'page.duplicate', - 'data' => [ - 'slug' => $slug - ] - ]); - } + if ($siblings->find($slug)?->is($page) === false) { + throw new DuplicateException([ + 'key' => 'page.duplicate', + 'data' => [ + 'slug' => $slug + ] + ]); } - if ($duplicate = $drafts->find($slug)) { - if ($duplicate->is($page) === false) { - throw new DuplicateException([ - 'key' => 'page.draft.duplicate', - 'data' => [ - 'slug' => $slug - ] - ]); - } + if ($drafts->find($slug)?->is($page) === false) { + throw new DuplicateException([ + 'key' => 'page.draft.duplicate', + 'data' => [ + 'slug' => $slug + ] + ]); } return true; @@ -101,16 +97,12 @@ class PageRules throw new InvalidArgumentException(['key' => 'page.status.invalid']); } - switch ($status) { - case 'draft': - return static::changeStatusToDraft($page); - case 'listed': - return static::changeStatusToListed($page, $position); - case 'unlisted': - return static::changeStatusToUnlisted($page); - default: - throw new InvalidArgumentException(['key' => 'page.status.invalid']); - } + return match ($status) { + 'draft' => static::changeStatusToDraft($page), + 'listed' => static::changeStatusToListed($page, $position), + 'unlisted' => static::changeStatusToUnlisted($page), + default => throw new InvalidArgumentException(['key' => 'page.status.invalid']) + }; } /** diff --git a/kirby/src/Cms/PageSiblings.php b/kirby/src/Cms/PageSiblings.php index 2507a1d..22014d2 100644 --- a/kirby/src/Cms/PageSiblings.php +++ b/kirby/src/Cms/PageSiblings.php @@ -122,9 +122,9 @@ trait PageSiblings { if ($this->isDraft() === true) { return $this->parentModel()->drafts(); - } else { - return $this->parentModel()->children(); } + + return $this->parentModel()->children(); } /** diff --git a/kirby/src/Cms/Pages.php b/kirby/src/Cms/Pages.php index 5aa3959..b3f6620 100644 --- a/kirby/src/Cms/Pages.php +++ b/kirby/src/Cms/Pages.php @@ -3,6 +3,7 @@ namespace Kirby\Cms; use Kirby\Exception\InvalidArgumentException; +use Kirby\Uuid\HasUuids; /** * The `$pages` object refers to a @@ -22,6 +23,8 @@ use Kirby\Exception\InvalidArgumentException; */ class Pages extends Collection { + use HasUuids; + /** * Cache for the index only listed and unlisted pages * @@ -57,15 +60,18 @@ class Pages extends Collection $site = App::instance()->site(); // add a pages collection - if (is_a($object, self::class) === true) { + if ($object instanceof self) { $this->data = array_merge($this->data, $object->data); // add a page by id - } elseif (is_string($object) === true && $page = $site->find($object)) { + } elseif ( + is_string($object) === true && + $page = $site->find($object) + ) { $this->__set($page->id(), $page); // add a page object - } elseif (is_a($object, 'Kirby\Cms\Page') === true) { + } elseif ($object instanceof Page) { $this->__set($object->id(), $object); // give a useful error message on invalid input; @@ -157,7 +163,7 @@ class Pages extends Collection $children = new static([], $model); $kirby = $model->kirby(); - if (is_a($model, 'Kirby\Cms\Page') === true) { + if ($model instanceof Page) { $parent = $model; $site = $model->site(); } else { @@ -198,41 +204,67 @@ class Pages extends Collection } /** - * Finds a page in the collection by id. - * This works recursively for children and - * children of children, etc. - * @deprecated 3.7.0 Use `$pages->get()` or `$pages->find()` instead - * @todo 3.8.0 Remove method - * @codeCoverageIgnore + * Finds a page by its ID or URI + * @internal Use `$pages->find()` instead * - * @param string|null $id - * @return mixed + * @param string|null $key + * @return \Kirby\Cms\Page|null */ - public function findById(string $id = null) + public function findByKey(string|null $key = null) { - Helpers::deprecated('Cms\Pages::findById() has been deprecated and will be removed in Kirby 3.8.0. Use $pages->get() or $pages->find() instead.'); + if ($key === null) { + return null; + } - return $this->findByKey($id); + if ($page = $this->findByUuid($key, 'page')) { + return $page; + } + + // remove trailing or leading slashes + $key = trim($key, '/'); + + // strip extensions from the id + if (strpos($key, '.') !== false) { + $info = pathinfo($key); + + if ($info['dirname'] !== '.') { + $key = $info['dirname'] . '/' . $info['filename']; + } else { + $key = $info['filename']; + } + } + + // try the obvious way + if ($page = $this->get($key)) { + return $page; + } + + // try to find the page by its (translated) URI by stepping through the page tree + $start = $this->parent instanceof Page ? $this->parent->id() : ''; + if ($page = $this->findByKeyRecursive($key, $start, App::instance()->multilang())) { + return $page; + } + + // for secondary languages, try the full translated URI + // (for collections without parent that won't have a result above) + if ( + App::instance()->multilang() === true && + App::instance()->language()->isDefault() === false && + $page = $this->findBy('uri', $key) + ) { + return $page; + } + + return null; } /** - * Finds a child or child of a child recursively. - * @deprecated 3.7.0 Use `$pages->find()` instead - * @todo 3.8.0 Integrate code into `findByKey()` and remove this method + * Finds a child or child of a child recursively * - * @param string $id - * @param string|null $startAt - * @param bool $multiLang * @return mixed */ - public function findByIdRecursive(string $id, string $startAt = null, bool $multiLang = false, bool $silenceWarning = false) + protected function findByKeyRecursive(string $id, string $startAt = null, bool $multiLang = false) { - // @codeCoverageIgnoreStart - if ($silenceWarning !== true) { - Helpers::deprecated('Cms\Pages::findByIdRecursive() has been deprecated and will be removed in Kirby 3.8.0. Use $pages->find() instead.'); - } - // @codeCoverageIgnoreEnd - $path = explode('/', $id); $item = null; $query = $startAt; @@ -260,73 +292,6 @@ class Pages extends Collection return $item; } - /** - * Finds a page by its ID or URI - * @internal Use `$pages->find()` instead - * - * @param string|null $key - * @return \Kirby\Cms\Page|null - */ - public function findByKey(?string $key = null) - { - if ($key === null) { - return null; - } - - // remove trailing or leading slashes - $key = trim($key, '/'); - - // strip extensions from the id - if (strpos($key, '.') !== false) { - $info = pathinfo($key); - - if ($info['dirname'] !== '.') { - $key = $info['dirname'] . '/' . $info['filename']; - } else { - $key = $info['filename']; - } - } - - // try the obvious way - if ($page = $this->get($key)) { - return $page; - } - - // try to find the page by its (translated) URI by stepping through the page tree - $start = is_a($this->parent, 'Kirby\Cms\Page') === true ? $this->parent->id() : ''; - if ($page = $this->findByIdRecursive($key, $start, App::instance()->multilang(), true)) { - return $page; - } - - // for secondary languages, try the full translated URI - // (for collections without parent that won't have a result above) - if ( - App::instance()->multilang() === true && - App::instance()->language()->isDefault() === false && - $page = $this->findBy('uri', $key) - ) { - return $page; - } - - return null; - } - - /** - * Alias for `$pages->find()` - * @deprecated 3.7.0 Use `$pages->find()` instead - * @todo 3.8.0 Remove method - * @codeCoverageIgnore - * - * @param string $id - * @return \Kirby\Cms\Page|null - */ - public function findByUri(string $id) - { - Helpers::deprecated('Cms\Pages::findByUri() has been deprecated and will be removed in Kirby 3.8.0. Use $pages->find() instead.'); - - return $this->findByKey($id); - } - /** * Finds the currently open page * @@ -380,7 +345,7 @@ class Pages extends Collection // get object property by cache mode $index = $drafts === true ? $this->indexWithDrafts : $this->index; - if (is_a($index, 'Kirby\Cms\Pages') === true) { + if ($index instanceof self) { return $index; } @@ -451,14 +416,14 @@ class Pages extends Collection } // merge an entire collection - if (is_a($args[0], self::class) === true) { + if ($args[0] instanceof self) { $collection = clone $this; $collection->data = array_merge($collection->data, $args[0]->data); return $collection; } // append a single page - if (is_a($args[0], 'Kirby\Cms\Page') === true) { + if ($args[0] instanceof Page) { $collection = clone $this; return $collection->set($args[0]->id(), $args[0]); } diff --git a/kirby/src/Cms/Pagination.php b/kirby/src/Cms/Pagination.php index 13f6ef2..c88f749 100644 --- a/kirby/src/Cms/Pagination.php +++ b/kirby/src/Cms/Pagination.php @@ -98,7 +98,7 @@ class Pagination extends BasePagination * * @return string|null */ - public function firstPageUrl(): ?string + public function firstPageUrl(): string|null { return $this->pageUrl(1); } @@ -108,7 +108,7 @@ class Pagination extends BasePagination * * @return string|null */ - public function lastPageUrl(): ?string + public function lastPageUrl(): string|null { return $this->pageUrl($this->lastPage()); } @@ -119,7 +119,7 @@ class Pagination extends BasePagination * * @return string|null */ - public function nextPageUrl(): ?string + public function nextPageUrl(): string|null { if ($page = $this->nextPage()) { return $this->pageUrl($page); @@ -136,7 +136,7 @@ class Pagination extends BasePagination * @param int|null $page * @return string|null */ - public function pageUrl(int $page = null): ?string + public function pageUrl(int $page = null): string|null { if ($page === null) { return $this->pageUrl($this->page()); @@ -168,7 +168,7 @@ class Pagination extends BasePagination * * @return string|null */ - public function prevPageUrl(): ?string + public function prevPageUrl(): string|null { if ($page = $this->prevPage()) { return $this->pageUrl($page); diff --git a/kirby/src/Cms/Permissions.php b/kirby/src/Cms/Permissions.php index caaa284..2780a84 100644 --- a/kirby/src/Cms/Permissions.php +++ b/kirby/src/Cms/Permissions.php @@ -159,12 +159,6 @@ class Permissions */ protected function setAction(string $category, string $action, $setting) { - // deprecated fallback for the settings/system view - // TODO: remove in 3.8.0 - if ($category === 'access' && $action === 'settings') { - $action = 'system'; - } - // wildcard to overwrite the entire category if ($action === '*') { return $this->setCategory($category, $setting); diff --git a/kirby/src/Cms/Plugin.php b/kirby/src/Cms/Plugin.php index ae5e07f..33dadeb 100644 --- a/kirby/src/Cms/Plugin.php +++ b/kirby/src/Cms/Plugin.php @@ -2,10 +2,15 @@ namespace Kirby\Cms; +use Composer\InstalledVersions; use Exception; +use Kirby\Cms\System\UpdateStatus; use Kirby\Data\Data; use Kirby\Exception\InvalidArgumentException; +use Kirby\Toolkit\A; +use Kirby\Toolkit\Str; use Kirby\Toolkit\V; +use Throwable; /** * Represents a Plugin and handles parsing of @@ -20,15 +25,16 @@ use Kirby\Toolkit\V; */ class Plugin extends Model { - protected $extends; - protected $info; - protected $name; - protected $root; + protected array $extends; + protected string $name; + protected string $root; + + // caches + protected array|null $info = null; + protected UpdateStatus|null $updateStatus = null; /** - * @param string $key - * @param array|null $arguments - * @return mixed|null + * Allows access to any composer.json field by method call */ public function __call(string $key, array $arguments = null) { @@ -36,10 +42,8 @@ class Plugin extends Model } /** - * Plugin constructor - * - * @param string $name - * @param array $extends + * @param string $name Plugin name within Kirby (`vendor/plugin`) + * @param array $extends Associative array of plugin extensions */ public function __construct(string $name, array $extends = []) { @@ -53,9 +57,7 @@ class Plugin extends Model /** * Returns the array with author information - * from the composer file - * - * @return array + * from the composer.json file */ public function authors(): array { @@ -64,8 +66,6 @@ class Plugin extends Model /** * Returns a comma-separated list with all author names - * - * @return string */ public function authorsNames(): string { @@ -79,7 +79,7 @@ class Plugin extends Model } /** - * @return array + * Returns the associative array of extensions the plugin bundles */ public function extends(): array { @@ -87,9 +87,8 @@ class Plugin extends Model } /** - * Returns the unique id for the plugin - * - * @return string + * Returns the unique ID for the plugin + * (alias for the plugin name) */ public function id(): string { @@ -97,7 +96,7 @@ class Plugin extends Model } /** - * @return array + * Returns the raw data from composer.json */ public function info(): array { @@ -107,7 +106,7 @@ class Plugin extends Model try { $info = Data::read($this->manifest()); - } catch (Exception $e) { + } catch (Exception) { // there is no manifest file or it is invalid $info = []; } @@ -117,10 +116,8 @@ class Plugin extends Model /** * Returns the link to the plugin homepage - * - * @return string|null */ - public function link(): ?string + public function link(): string|null { $info = $this->info(); $homepage = $info['homepage'] ?? null; @@ -133,7 +130,7 @@ class Plugin extends Model } /** - * @return string + * Returns the path to the plugin's composer.json */ public function manifest(): string { @@ -141,7 +138,7 @@ class Plugin extends Model } /** - * @return string + * Returns the root where plugin assets are copied to */ public function mediaRoot(): string { @@ -149,7 +146,7 @@ class Plugin extends Model } /** - * @return string + * Returns the base URL for plugin assets */ public function mediaUrl(): string { @@ -157,7 +154,7 @@ class Plugin extends Model } /** - * @return string + * Returns the plugin name (`vendor/plugin`) */ public function name(): string { @@ -165,8 +162,7 @@ class Plugin extends Model } /** - * @param string $key - * @return mixed + * Returns a Kirby option value for this plugin */ public function option(string $key) { @@ -174,7 +170,7 @@ class Plugin extends Model } /** - * @return string + * Returns the option prefix (`vendor.plugin`) */ public function prefix(): string { @@ -182,7 +178,7 @@ class Plugin extends Model } /** - * @return string + * Returns the root where the plugin files are stored */ public function root(): string { @@ -190,11 +186,13 @@ class Plugin extends Model } /** - * @param string $name + * Validates and sets the plugin name + * * @return $this - * @throws \Kirby\Exception\InvalidArgumentException + * + * @throws \Kirby\Exception\InvalidArgumentException If the plugin name has an invalid format */ - protected function setName(string $name) + protected function setName(string $name): static { if (preg_match('!^[a-z0-9-]+\/[a-z0-9-]+$!i', $name) !== 1) { throw new InvalidArgumentException('The plugin name must follow the format "a-z0-9-/a-z0-9-"'); @@ -205,7 +203,7 @@ class Plugin extends Model } /** - * @return array + * Returns all available plugin metadata */ public function toArray(): array { @@ -219,4 +217,88 @@ class Plugin extends Model 'version' => $this->version() ]; } + + /** + * Returns the update status object unless the + * update check has been disabled for the plugin + * @since 3.8.0 + * + * @param array|null $data Custom override for the getkirby.com update data + */ + public function updateStatus(array|null $data = null): UpdateStatus|null + { + if ($this->updateStatus !== null) { + return $this->updateStatus; + } + + $kirby = $this->kirby(); + $option = $kirby->option('updates.plugins'); + + // specific configuration per plugin + if (is_array($option) === true) { + // filter all option values by glob match + $option = A::filter( + $option, + fn ($value, $key) => fnmatch($key, $this->name()) === true + ); + + // sort the matches by key length (with longest key first) + $keys = array_map('strlen', array_keys($option)); + array_multisort($keys, SORT_DESC, $option); + + if (count($option) > 0) { + // use the first and therefore longest key (= most specific match) + $option = reset($option); + } else { + // fallback to the default option value + $option = true; + } + } + + if ($option === null) { + $option = $kirby->option('updates') ?? true; + } + + if ($option !== true) { + return null; + } + + return $this->updateStatus = new UpdateStatus($this, false, $data); + } + + /** + * Returns the normalized version number + * from the composer.json file + */ + public function version(): string|null + { + $composerName = $this->info()['name'] ?? null; + $version = $this->info()['version'] ?? null; + + try { + // if plugin doesn't have version key in composer.json file + // try to get version from "vendor/composer/installed.php" + $version ??= InstalledVersions::getPrettyVersion($composerName); + } catch (Throwable) { + return null; + } + + if ( + is_string($version) !== true || + $version === '' || + Str::endsWith($version, '+no-version-set') + ) { + return null; + } + + // normalize the version number to be without leading `v` + $version = ltrim($version, 'vV'); + + // ensure that the version number now starts with a digit + if (preg_match('/^[0-9]/', $version) !== 1) { + return null; + } + + return $version; + } } diff --git a/kirby/src/Cms/Responder.php b/kirby/src/Cms/Responder.php index 7f3d38e..49640fd 100644 --- a/kirby/src/Cms/Responder.php +++ b/kirby/src/Cms/Responder.php @@ -113,7 +113,7 @@ class Responder * @param bool|null $cache * @return bool|$this */ - public function cache(?bool $cache = null) + public function cache(bool|null $cache = null) { if ($cache === null) { // never ever cache private responses @@ -137,7 +137,7 @@ class Responder * @param bool|null $usesAuth * @return bool|$this */ - public function usesAuth(?bool $usesAuth = null) + public function usesAuth(bool|null $usesAuth = null) { if ($usesAuth === null) { return $this->usesAuth; @@ -171,7 +171,7 @@ class Responder * @param array|null $usesCookies * @return array|$this */ - public function usesCookies(?array $usesCookies = null) + public function usesCookies(array|null $usesCookies = null) { if ($usesCookies === null) { return $this->usesCookies; @@ -352,7 +352,7 @@ class Responder * @param int|null $code * @return $this */ - public function redirect(?string $location = null, ?int $code = null) + public function redirect(string|null $location = null, int|null $code = null) { $location = Url::to($location ?? '/'); $location = Url::unIdn($location); diff --git a/kirby/src/Cms/Response.php b/kirby/src/Cms/Response.php index 9674440..804ec43 100644 --- a/kirby/src/Cms/Response.php +++ b/kirby/src/Cms/Response.php @@ -18,12 +18,8 @@ class Response extends \Kirby\Http\Response * Adjusted redirect creation which * parses locations with the Url::to method * first. - * - * @param string $location - * @param int $code - * @return static */ - public static function redirect(string $location = '/', int $code = 302) + public static function redirect(string $location = '/', int $code = 302): static { return parent::redirect(Url::to($location), $code); } diff --git a/kirby/src/Cms/Role.php b/kirby/src/Cms/Role.php index aa22264..1860690 100644 --- a/kirby/src/Cms/Role.php +++ b/kirby/src/Cms/Role.php @@ -55,7 +55,7 @@ class Role extends Model { try { return static::load('admin'); - } catch (Exception $e) { + } catch (Exception) { return static::factory(static::defaults()['admin'], $inject); } } @@ -152,7 +152,7 @@ class Role extends Model { try { return static::load('nobody'); - } catch (Exception $e) { + } catch (Exception) { return static::factory(static::defaults()['nobody'], $inject); } } diff --git a/kirby/src/Cms/Section.php b/kirby/src/Cms/Section.php index d68b3c2..51ea070 100644 --- a/kirby/src/Cms/Section.php +++ b/kirby/src/Cms/Section.php @@ -44,7 +44,7 @@ class Section extends Component throw new InvalidArgumentException('Undefined section model'); } - if (is_a($attrs['model'], 'Kirby\Cms\Model') === false) { + if ($attrs['model'] instanceof Model === false) { throw new InvalidArgumentException('Invalid section model'); } diff --git a/kirby/src/Cms/Site.php b/kirby/src/Cms/Site.php index 2343ed7..b27bdc3 100644 --- a/kirby/src/Cms/Site.php +++ b/kirby/src/Cms/Site.php @@ -164,9 +164,9 @@ class Site extends ModelWithContent { if ($relative === true) { return 'site'; - } else { - return $this->kirby()->url('api') . '/site'; } + + return $this->kirby()->url('api') . '/site'; } /** @@ -176,7 +176,7 @@ class Site extends ModelWithContent */ public function blueprint() { - if (is_a($this->blueprint, 'Kirby\Cms\SiteBlueprint') === true) { + if ($this->blueprint instanceof SiteBlueprint) { return $this->blueprint; } @@ -210,7 +210,7 @@ class Site extends ModelWithContent * @param string|null $languageCode * @return array */ - public function contentFileData(array $data, ?string $languageCode = null): array + public function contentFileData(array $data, string|null $languageCode = null): array { return A::prepend($data, [ 'title' => $data['title'] ?? null, @@ -235,7 +235,7 @@ class Site extends ModelWithContent */ public function errorPage() { - if (is_a($this->errorPage, 'Kirby\Cms\Page') === true) { + if ($this->errorPage instanceof Page) { return $this->errorPage; } @@ -274,7 +274,7 @@ class Site extends ModelWithContent */ public function homePage() { - if (is_a($this->homePage, 'Kirby\Cms\Page') === true) { + if ($this->homePage instanceof Page) { return $this->homePage; } @@ -327,7 +327,7 @@ class Site extends ModelWithContent */ public function is($site): bool { - if (is_a($site, 'Kirby\Cms\Site') === false) { + if ($site instanceof self === false) { return false; } @@ -364,7 +364,7 @@ class Site extends ModelWithContent * @param string|null $handler * @return int|string */ - public function modified(?string $format = null, ?string $handler = null) + public function modified(string|null $format = null, string|null $handler = null) { return Dir::modified( $this->root(), @@ -386,19 +386,19 @@ class Site extends ModelWithContent * otherwise e.g. `notes/across-the-ocean` * @return \Kirby\Cms\Page|null */ - public function page(?string $path = null) + public function page(string|null $path = null) { if ($path !== null) { return $this->find($path); } - if (is_a($this->page, 'Kirby\Cms\Page') === true) { + if ($this->page instanceof Page) { return $this->page; } try { return $this->page = $this->homePage(); - } catch (LogicException $e) { + } catch (LogicException) { return $this->page = null; } } @@ -439,7 +439,7 @@ class Site extends ModelWithContent * @internal * @return string|null */ - public function previewUrl(): ?string + public function previewUrl(): string|null { $preview = $this->blueprint()->preview(); @@ -485,7 +485,7 @@ class Site extends ModelWithContent * @param array $params * @return \Kirby\Cms\Pages */ - public function search(?string $query = null, $params = []) + public function search(string|null $query = null, $params = []) { return $this->index()->search($query, $params); } @@ -496,7 +496,7 @@ class Site extends ModelWithContent * @param array|null $blueprint * @return $this */ - protected function setBlueprint(?array $blueprint = null) + protected function setBlueprint(array|null $blueprint = null) { if ($blueprint !== null) { $blueprint['model'] = $this; @@ -555,7 +555,7 @@ class Site extends ModelWithContent * @param string|null $url * @return $this */ - protected function setUrl(?string $url = null) + protected function setUrl(string|null $url = null) { $this->url = $url; return $this; @@ -587,7 +587,7 @@ class Site extends ModelWithContent * @param string|null $language * @return string */ - public function url(?string $language = null): string + public function url(string|null $language = null): string { if ($language !== null || $this->kirby()->multilang() === true) { return $this->urlForLanguage($language); @@ -604,7 +604,7 @@ class Site extends ModelWithContent * @param array|null $options * @return string */ - public function urlForLanguage(?string $languageCode = null, ?array $options = null): string + public function urlForLanguage(string|null $languageCode = null, array|null $options = null): string { if ($language = $this->kirby()->language($languageCode)) { return $language->url(); @@ -623,7 +623,7 @@ class Site extends ModelWithContent * @param string|null $languageCode * @return \Kirby\Cms\Page */ - public function visit($page, ?string $languageCode = null) + public function visit($page, string|null $languageCode = null) { if ($languageCode !== null) { $this->kirby()->setCurrentTranslation($languageCode); @@ -636,7 +636,7 @@ class Site extends ModelWithContent } // handle invalid pages - if (is_a($page, 'Kirby\Cms\Page') === false) { + if ($page instanceof Page === false) { throw new InvalidArgumentException('Invalid page object'); } @@ -659,41 +659,4 @@ class Site extends ModelWithContent { return Dir::wasModifiedAfter($this->root(), $time); } - - - /** - * Deprecated! - */ - - /** - * Returns the full path without leading slash - * - * @todo Remove in 3.8.0 - * - * @internal - * @return string - * @codeCoverageIgnore - */ - public function panelPath(): string - { - Helpers::deprecated('Cms\Site::panelPath() has been deprecated and will be removed in Kirby 3.8.0. Use $site->panel()->path() instead.'); - return $this->panel()->path(); - } - - /** - * Returns the url to the editing view - * in the panel - * - * @todo Remove in 3.8.0 - * - * @internal - * @param bool $relative - * @return string - * @codeCoverageIgnore - */ - public function panelUrl(bool $relative = false): string - { - Helpers::deprecated('Cms\Site::panelUrl() has been deprecated and will be removed in Kirby 3.8.0. Use $site->panel()->url() instead.'); - return $this->panel()->url($relative); - } } diff --git a/kirby/src/Cms/Structure.php b/kirby/src/Cms/Structure.php index d86e611..8f6b68e 100644 --- a/kirby/src/Cms/Structure.php +++ b/kirby/src/Cms/Structure.php @@ -46,7 +46,7 @@ class Structure extends Collection */ public function __set(string $id, $props): void { - if (is_a($props, 'Kirby\Cms\StructureObject') === true) { + if ($props instanceof StructureObject) { $object = $props; } else { if (is_array($props) === false) { diff --git a/kirby/src/Cms/StructureObject.php b/kirby/src/Cms/StructureObject.php index 2b0bddd..0805707 100644 --- a/kirby/src/Cms/StructureObject.php +++ b/kirby/src/Cms/StructureObject.php @@ -81,7 +81,7 @@ class StructureObject extends Model */ public function content() { - if (is_a($this->content, 'Kirby\Cms\Content') === true) { + if ($this->content instanceof Content) { return $this->content; } @@ -110,7 +110,7 @@ class StructureObject extends Model */ public function is($structure): bool { - if (is_a($structure, 'Kirby\Cms\StructureObject') === false) { + if ($structure instanceof self === false) { return false; } diff --git a/kirby/src/Cms/System.php b/kirby/src/Cms/System.php index bf19418..3266cd0 100644 --- a/kirby/src/Cms/System.php +++ b/kirby/src/Cms/System.php @@ -2,6 +2,7 @@ namespace Kirby\Cms; +use Kirby\Cms\System\UpdateStatus; use Kirby\Data\Json; use Kirby\Exception\Exception; use Kirby\Exception\InvalidArgumentException; @@ -35,6 +36,9 @@ class System */ protected $app; + // cache + protected UpdateStatus|null $updateStatus = null; + /** * @param \Kirby\Cms\App $app */ @@ -94,7 +98,7 @@ class System * @param string $folder 'git', 'content', 'site', 'kirby' * @return string|null */ - public function exposedFileUrl(string $folder): ?string + public function exposedFileUrl(string $folder): string|null { if (!$url = $this->folderUrl($folder)) { return null; @@ -140,7 +144,7 @@ class System * @param string $folder 'git', 'content', 'site', 'kirby' * @return string|null */ - public function folderUrl(string $folder): ?string + public function folderUrl(string $folder): string|null { $index = $this->app->root('index'); @@ -196,28 +200,28 @@ class System // init /site/accounts try { Dir::make($this->app->root('accounts')); - } catch (Throwable $e) { + } catch (Throwable) { throw new PermissionException('The accounts directory could not be created'); } // init /site/sessions try { Dir::make($this->app->root('sessions')); - } catch (Throwable $e) { + } catch (Throwable) { throw new PermissionException('The sessions directory could not be created'); } // init /content try { Dir::make($this->app->root('content')); - } catch (Throwable $e) { + } catch (Throwable) { throw new PermissionException('The content directory could not be created'); } // init /media try { Dir::make($this->app->root('media')); - } catch (Throwable $e) { + } catch (Throwable) { throw new PermissionException('The media directory could not be created'); } } @@ -277,7 +281,7 @@ class System { try { $license = Json::read($this->app->root('license')); - } catch (Throwable $e) { + } catch (Throwable) { return false; } @@ -318,12 +322,11 @@ class System // only return the actual license key if the // current user has appropriate permissions - $user = $this->app->user(); - if ($user && $user->isAdmin() === true) { + if ($this->app->user()?->isAdmin() === true) { return $license['license']; - } else { - return true; } + + return true; } /** @@ -454,7 +457,7 @@ class System public function php(): bool { return - version_compare(PHP_VERSION, '7.4.0', '>=') === true && + version_compare(PHP_VERSION, '8.0.0', '>=') === true && version_compare(PHP_VERSION, '8.2.0', '<') === true; } @@ -544,23 +547,19 @@ class System * * @return string|null */ - public function serverSoftware(): ?string + public function serverSoftware(): string|null { - if ($servers = $this->app->option('servers')) { - $servers = A::wrap($servers); - } else { - $servers = [ - 'apache', - 'caddy', - 'litespeed', - 'nginx', - 'php' - ]; - } + $servers = $this->app->option('servers', [ + 'apache', + 'caddy', + 'litespeed', + 'nginx', + 'php' + ]); $software = $this->app->environment()->get('SERVER_SOFTWARE', ''); - preg_match('!(' . implode('|', $servers) . ')!i', $software, $matches); + preg_match('!(' . implode('|', A::wrap($servers)) . ')!i', $software, $matches); return $matches[0] ?? null; } @@ -620,6 +619,33 @@ class System return $this->status(); } + /** + * Returns the update status object unless + * the update check for Kirby has been disabled + * @since 3.8.0 + * + * @param array|null $data Custom override for the getkirby.com update data + */ + public function updateStatus(array|null $data = null): UpdateStatus|null + { + if ($this->updateStatus !== null) { + return $this->updateStatus; + } + + $kirby = $this->app; + $option = $kirby->option('updates.kirby') ?? $kirby->option('updates') ?? true; + + if ($option === false) { + return null; + } + + return $this->updateStatus = new UpdateStatus( + $kirby, + $option === 'security', + $data + ); + } + /** * Upgrade to the new folder separator * diff --git a/kirby/src/Cms/System/UpdateStatus.php b/kirby/src/Cms/System/UpdateStatus.php new file mode 100644 index 0000000..7bdf3af --- /dev/null +++ b/kirby/src/Cms/System/UpdateStatus.php @@ -0,0 +1,771 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://getkirby.com/license + */ +class UpdateStatus +{ + /** + * Host to request the update data from + */ + public static string $host = 'https://assets.getkirby.com'; + + /** + * Marker that stores whether a previous remote + * request timed out + */ + protected static bool $timedOut = false; + + // props set in constructor + protected App $app; + protected string|null $currentVersion; + protected array|null $data; + protected string|null $pluginName; + protected bool $securityOnly; + + // props updated throughout the class + protected array $exceptions = []; + protected bool|null $noVulns = null; + + // caches + protected array $messages; + protected array $targetData; + protected array|bool $versionEntry; + protected array $vulnerabilities; + + /** + * @param array|null $data Custom override for the getkirby.com update data + */ + public function __construct( + App|Plugin $package, + bool $securityOnly = false, + array|null $data = null + ) { + if ($package instanceof App) { + $this->app = $package; + $this->pluginName = null; + } else { + $this->app = $package->kirby(); + $this->pluginName = $package->name(); + } + + $this->securityOnly = $securityOnly; + $this->currentVersion = $package->version(); + + $this->data = $data ?? $this->loadData(); + } + + /** + * Returns the currently installed version + */ + public function currentVersion(): string|null + { + return $this->currentVersion; + } + + /** + * Returns the list of exception objects that were + * collected during data fetching and processing + */ + public function exceptions(): array + { + return $this->exceptions; + } + + /** + * Returns the list of exception message strings that + * were collected during data fetching and processing + */ + public function exceptionMessages(): array + { + return array_map(fn ($e) => $e->getMessage(), $this->exceptions()); + } + + /** + * Returns the Panel icon for the status value + * + * @return string 'check'|'alert'|'info' + */ + public function icon(): string + { + return match ($this->status()) { + 'up-to-date', 'not-vulnerable' => 'check', + 'security-update', 'security-upgrade' => 'alert', + 'update', 'upgrade' => 'info', + default => 'question' + }; + } + + /** + * Returns the human-readable and translated label + * for the update status + */ + public function label(): string + { + return I18n::template( + 'system.updateStatus.' . $this->status(), + '?', + ['version' => $this->targetVersion() ?? '?'] + ); + } + + /** + * Returns the latest available version + */ + public function latestVersion(): string|null + { + return $this->data['latest'] ?? null; + } + + /** + * Returns all security messages unless no data + * is available + */ + public function messages(): array|null + { + if (isset($this->messages) === true) { + return $this->messages; + } + + if ( + $this->data === null || + $this->currentVersion === null || + $this->currentVersion === '' + ) { + return null; + } + + $type = $this->pluginName ? 'plugin' : 'kirby'; + + // collect all matching custom messages + $filters = [ + 'kirby' => $this->app->version(), + 'php' => phpversion() + ]; + + if ($type === 'plugin') { + $filters['plugin'] = $this->currentVersion; + } + + $messages = $this->filterArrayByVersion( + $this->data['messages'] ?? [], + $filters, + 'while filtering messages' + ); + + // add a message for each vulnerability + // the current version is affected by + foreach ($this->vulnerabilities() as $vulnerability) { + if ($type === 'plugin') { + $vulnerability['plugin'] = $this->pluginName; + } + + $messages[] = [ + 'text' => I18n::template( + 'system.issues.vulnerability.' . $type, + null, + $vulnerability + ), + 'link' => $vulnerability['link'] ?? null, + 'icon' => 'bug' + ]; + } + + // add special message for end-of-life versions + $versionEntry = $this->versionEntry(); + if (($versionEntry['status'] ?? null) === 'end-of-life') { + $messages[] = [ + 'text' => match ($type) { + 'plugin' => I18n::template( + 'system.issues.eol.plugin', + null, + ['plugin' => $this->pluginName] + ), + default => I18n::translate('system.issues.eol.kirby') + }, + 'link' => $versionEntry['status-link'] ?? 'https://getkirby.com/security/end-of-life', + 'icon' => 'bell' + ]; + } + + return $this->messages = $messages; + } + + /** + * Returns the raw status value + * + * @return string 'up-to-date'|'not-vulnerable'|'security-update'| + * 'security-upgrade'|'update'|'upgrade'|'unreleased'|'error' + */ + public function status(): string + { + return $this->targetData()['status']; + } + + /** + * Version that is suggested for the update/upgrade + */ + public function targetVersion(): string|null + { + return $this->targetData()['version']; + } + + /** + * Returns the Panel theme for the status value + * + * @return string 'positive'|'negative'|'info'|'notice' + */ + public function theme(): string + { + return match ($this->status()) { + 'up-to-date', 'not-vulnerable' => 'positive', + 'security-update', 'security-upgrade' => 'negative', + 'update', 'upgrade' => 'info', + default => 'notice' + }; + } + + /** + * Returns the most important human-readable + * status information as array + */ + public function toArray(): array + { + return [ + 'currentVersion' => $this->currentVersion() ?? '?', + 'icon' => $this->icon(), + 'label' => $this->label(), + 'latestVersion' => $this->latestVersion() ?? '?', + 'pluginName' => $this->pluginName, + 'theme' => $this->theme(), + 'url' => $this->url(), + ]; + } + + /** + * URL of the target version with fallback + * to the URL of the current version; + * `null` is returned if no URL is known + */ + public function url(): string|null + { + return $this->targetData()['url']; + } + + /** + * Returns all vulnerabilities the current version + * is affected by unless no data is available + */ + public function vulnerabilities(): array|null + { + if (isset($this->vulnerabilities) === true) { + return $this->vulnerabilities; + } + + if ( + $this->data === null || + $this->currentVersion === null || + $this->currentVersion === '' + ) { + return null; + } + + // shortcut for versions without vulnerabilities + $this->versionEntry(); + if ($this->noVulns === true) { + return $this->vulnerabilities = []; + } + + // unstable releases are released before their respective + // stable release and would not be matched by the constraints, + // but they will likely also contain the same vulnerabilities; + // so we strip off any non-numeric version modifiers from the end + preg_match('/^([0-9.]+)/', $this->currentVersion, $matches); + $currentVersion = $matches[1]; + + $vulnerabilities = $this->filterArrayByVersion( + $this->data['incidents'] ?? [], + ['affected' => $currentVersion], + 'while filtering incidents' + ); + + // sort the vulnerabilities by severity (with critical first) + $severities = array_map( + fn ($vulnerability) => match ($vulnerability['severity'] ?? null) { + 'critical' => 4, + 'high' => 3, + 'medium' => 2, + 'low' => 1, + default => 0 + }, + $vulnerabilities + ); + array_multisort($severities, SORT_DESC, $vulnerabilities); + + return $this->vulnerabilities = $vulnerabilities; + } + + /** + * Compares a version against a Composer version constraint + * and returns whether the constraint is satisfied + * + * @param string $reason Suffix for error messages + */ + protected function checkConstraint(string $version, string $constraint, string $reason): bool + { + try { + return Semver::satisfies($version, $constraint); + } catch (Exception $e) { + $package = $this->packageName(); + $message = 'Error comparing version constraint for ' . $package . ' ' . $reason . ': ' . $e->getMessage(); + + $exception = new KirbyException([ + 'fallback' => $message, + 'previous' => $e + ]); + $this->exceptions[] = $exception; + + return false; + } + } + + /** + * Filters a two-level array with one or multiple version constraints + * for each value by one or multiple version filters; + * values that don't contain the filter keys are removed + * + * @param array $array Array that contains associative arrays + * @param array $filters Associative array `field => version` + * @param string $reason Suffix for error messages + */ + protected function filterArrayByVersion(array $array, array $filters, string $reason): array + { + return array_filter($array, function ($item) use ($filters, $reason): bool { + foreach ($filters as $key => $version) { + if (isset($item[$key]) !== true) { + $package = $this->packageName(); + $this->exceptions[] = new KirbyException('Missing constraint ' . $key . ' for ' . $package . ' ' . $reason); + + return false; + } + + if ($this->checkConstraint($version, $item[$key], $reason) !== true) { + return false; + } + } + + return true; + }); + } + + /** + * Finds the minimum possible security update + * to fix all known vulnerabilities + * + * @return string|null Version number of the update or + * `null` if no free update is possible + */ + protected function findMinimumSecurityUpdate(): string|null + { + $versionEntry = $this->versionEntry(); + if ($versionEntry === null || isset($versionEntry['latest']) !== true) { + return null; // @codeCoverageIgnore + } + + $affected = $this->vulnerabilities(); + $incidents = $this->data['incidents'] ?? []; + $maxVersion = $versionEntry['latest']; + + // increase the target version number until there are no vulnerabilities + $version = $this->currentVersion; + $iterations = 0; + while (empty($affected) === false) { + // protect against infinite loops if the + // input data is contradicting itself + $iterations++; + if ($iterations > 10) { + return null; + } + + // if we arrived at the `$maxVersion` but still haven't found + // a version without vulnerabilities, we cannot suggest a version + if ($version === $maxVersion) { + return null; + } + + // find the minimum version that fixes all affected vulnerabilities + foreach ($affected as $incident) { + $incidentVersion = null; + foreach (Str::split($incident['fixed'], ',') as $fixed) { + // skip versions of other major releases + if ( + version_compare($fixed, $this->currentVersion, '<') === true || + version_compare($fixed, $maxVersion, '>') === true + ) { + continue; + } + + // find the minimum version that fixes this specific vulnerability + if ( + $incidentVersion === null || + version_compare($fixed, $incidentVersion, '<') === true + ) { + $incidentVersion = $fixed; + } + } + + // verify that we found at least one possible version; + // otherwise try the `$maxVersion` as a last chance before + // concluding at the top that we cannot solve the task + if ($incidentVersion === null) { + $incidentVersion = $maxVersion; + } + + // we need a version that fixes all vulnerabilities, so use the + // "largest of the smallest" fixed versions + if (version_compare($incidentVersion, $version, '>') === true) { + $version = $incidentVersion; + } + } + + // run another loop to verify that the suggested version + // doesn't have any known vulnerabilities on its own + $affected = $this->filterArrayByVersion( + $incidents, + ['affected' => $version], + 'while filtering incidents' + ); + } + + return $version; + } + + /** + * Loads the getkirby.com update data + * from cache or via HTTP + */ + protected function loadData(): array|null + { + // try to get the data from cache + $cache = $this->app->cache('updates'); + $key = ( + $this->pluginName ? + 'plugins/' . $this->pluginName : + 'security' + ); + + // try to return from cache; + // invalidate the cache after updates + $data = $cache->get($key); + if ( + is_array($data) === true && + $data['_version'] === $this->currentVersion + ) { + return $data; + } + + // exception message (on previous request error) + if (is_string($data) === true) { + // restore the exception to make it visible when debugging + $this->exceptions[] = new KirbyException($data); + + return null; + } + + // before we request the data, ensure we have a writable cache; + // this reduces strain on the CDN from repeated requests + if ($cache->enabled() === false) { + $this->exceptions[] = new KirbyException('Cannot check for updates without a working "updates" cache'); + + return null; + } + + // first catch every exception; + // we collect it below for debugging + try { + if (static::$timedOut === true) { + throw new Exception('Previous remote request timed out'); // @codeCoverageIgnore + } + + $response = Remote::get( + static::$host . '/' . $key . '.json', + ['timeout' => 2] + ); + + // allow status code HTTP 200 or 0 (e.g. for the file:// protocol) + if (in_array($response->code(), [0, 200], true) !== true) { + throw new Exception('HTTP error ' . $response->code()); // @codeCoverageIgnore + } + + $data = $response->json(); + + if (is_array($data) !== true) { + throw new Exception('Invalid JSON data'); + } + } catch (Exception $e) { + $package = $this->packageName(); + $message = 'Could not load update data for ' . $package . ': ' . $e->getMessage(); + + $exception = new KirbyException([ + 'fallback' => $message, + 'previous' => $e + ]); + $this->exceptions[] = $exception; + + // if the request timed out, prevent additional + // requests for other packages (e.g. plugins) + // to avoid long Panel hangs + if ($e->getCode() === 28) { + static::$timedOut = true; // @codeCoverageIgnore + } elseif (static::$timedOut === false) { + // different error than timeout; + // prevent additional requests in the + // next three days (e.g. if a plugin + // does not have a page on getkirby.com) + // by caching the exception message + // instead of the data array + $cache->set($key, $exception->getMessage(), 3 * 24 * 60); + } + + return null; + } + + // also cache the current version to + // invalidate the cache after updates + // (ensures that the update status is + // fresh directly after the update to + // avoid confusion with outdated info) + $data['_version'] = $this->currentVersion; + + // cache the retrieved data for three days + $cache->set($key, $data, 3 * 24 * 60); + + return $data; + } + + /** + * Returns the human-readable package name for error messages + */ + protected function packageName(): string + { + return $this->pluginName ? 'plugin ' . $this->pluginName : 'Kirby'; + } + + /** + * Performs the update check and returns data for the + * target version (with fallback and error handling) + */ + protected function targetData(): array + { + if (isset($this->targetData) === true) { + return $this->targetData; + } + + // check if we have valid data to compare to + $versionEntry = $this->versionEntry(); + if ($versionEntry === null) { + $version = $this->currentVersion ?? $this->data['latest'] ?? null; + + return $this->targetData = [ + 'status' => 'error', + 'url' => $version ? $this->urlFor($version, 'changes') : null, + 'version' => null + ]; + } + + // check if the current version is the latest available + if (($versionEntry['status'] ?? null) === 'latest') { + return $this->targetData = [ + 'status' => 'up-to-date', + 'url' => $this->urlFor($this->currentVersion, 'changes'), + 'version' => null + ]; + } + + // check if the current version is unreleased + if (($versionEntry['status'] ?? null) === 'unreleased') { + return $this->targetData = [ + 'status' => 'unreleased', + 'url' => null, + 'version' => null + ]; + } + + // check if the installation is vulnerable; + // minimum possible security fixes are preferred + // over all other updates and upgrades + if (count($this->vulnerabilities()) > 0) { + $update = $this->findMinimumSecurityUpdate(); + + if ($update !== null) { + // a free security update was found + return $this->targetData = [ + 'status' => 'security-update', + 'url' => $this->urlFor($update, 'changes'), + 'version' => $update + ]; + } + + // only a paid security upgrade is possible + return $this->targetData = [ + 'status' => 'security-upgrade', + 'url' => $this->urlFor($this->currentVersion, 'upgrade'), + 'version' => $this->data['latest'] ?? null + ]; + } + + // check if the user limited update checking to security updates + if ($this->securityOnly === true) { + return $this->targetData = [ + 'status' => 'not-vulnerable', + 'url' => $this->urlFor($this->currentVersion, 'changes'), + 'version' => null + ]; + } + + // check if free updates are possible from the current version + $latest = $versionEntry['latest'] ?? null; + if (is_string($latest) === true && $latest !== $this->currentVersion) { + return $this->targetData = [ + 'status' => 'update', + 'url' => $this->urlFor($latest, 'changes'), + 'version' => $latest + ]; + } + + // no free update is possible, but we are not on the latest version, + // so the overall latest version must be an upgrade + return $this->targetData = [ + 'status' => 'upgrade', + 'url' => $this->urlFor($this->currentVersion, 'upgrade'), + 'version' => $this->data['latest'] ?? null + ]; + } + + /** + * Returns the URL for a specific version and purpose + */ + protected function urlFor(string $version, string $purpose): string|null + { + if ($this->data === null) { + return null; + } + + // find the first matching entry + $url = null; + foreach ($this->data['urls'] ?? [] as $constraint => $entry) { + // filter out every entry that does not match the version + if ($this->checkConstraint($version, $constraint, 'while finding URL') !== true) { + continue; + } + + // we found a result + $url = $entry[$purpose] ?? null; + if ($url !== null) { + break; + } + } + + if ($url === null) { + $package = $this->packageName(); + $message = 'No matching URL found for ' . $package . '@' . $version; + + $this->exceptions[] = new KirbyException($message); + + return null; + } + + // insert the URL template placeholders + return Str::template($url, [ + 'current' => $this->currentVersion, + 'version' => $version + ]); + } + + /** + * Extracts the first matching version entry from + * the data array unless no data is available + */ + protected function versionEntry(): array|null + { + if (isset($this->versionEntry) === true) { + // no version entry found on last call + if ($this->versionEntry === false) { + return null; + } + + return $this->versionEntry; + } + + if ( + $this->data === null || + $this->currentVersion === null || + $this->currentVersion === '' + ) { + return null; + } + + // special check for unreleased versions + $latest = $this->data['latest'] ?? null; + if ( + $latest !== null && + version_compare($this->currentVersion, $latest, '>') === true + ) { + return [ + 'status' => 'unreleased' + ]; + } + + $versionEntry = null; + foreach ($this->data['versions'] ?? [] as $constraint => $entry) { + // filter out every entry that does not match the current version + if ($this->checkConstraint($this->currentVersion, $constraint, 'while finding version entry') !== true) { + continue; + } + + if (($entry['status'] ?? null) === 'no-vulnerabilities') { + $this->noVulns = true; + + // use the next matching version entry with + // more specific update information + continue; + } + + if (($entry['status'] ?? null) === 'latest') { + $this->noVulns = true; + } + + // we found a result + $versionEntry = $entry; + break; + } + + if ($versionEntry === null) { + $package = $this->packageName(); + $message = 'No matching version entry found for ' . $package . '@' . $this->currentVersion; + + $this->exceptions[] = new KirbyException($message); + } + + $this->versionEntry = $versionEntry ?? false; + return $versionEntry; + } +} diff --git a/kirby/src/Cms/Template.php b/kirby/src/Cms/Template.php index e3e7e07..ee61cf4 100644 --- a/kirby/src/Cms/Template.php +++ b/kirby/src/Cms/Template.php @@ -122,13 +122,13 @@ class Template * * @return string|null */ - public function file(): ?string + public function file(): string|null { if ($this->hasDefaultType() === true) { try { // Try the default template in the default template directory. return F::realpath($this->root() . '/' . $this->name() . '.' . $this->extension(), $this->root()); - } catch (Exception $e) { + } catch (Exception) { // ignore errors, continue searching } @@ -145,7 +145,7 @@ class Template try { // Try the template with type extension in the default template directory. return F::realpath($this->root() . '/' . $name . '.' . $this->extension(), $this->root()); - } catch (Exception $e) { + } catch (Exception) { // Look for the template with type extension provided by an extension. // This might be null if the template does not exist. return App::instance()->extension($this->store(), $name); diff --git a/kirby/src/Cms/Translation.php b/kirby/src/Cms/Translation.php index b297ba4..783bcfb 100644 --- a/kirby/src/Cms/Translation.php +++ b/kirby/src/Cms/Translation.php @@ -116,7 +116,7 @@ class Translation * @param string|null $default * @return string|null */ - public function get(string $key, string $default = null): ?string + public function get(string $key, string $default = null): string|null { return $this->data[$key] ?? $default; } @@ -145,7 +145,7 @@ class Translation { try { $data = array_merge(Data::read($root), $inject); - } catch (Exception $e) { + } catch (Exception) { $data = []; } diff --git a/kirby/src/Cms/Url.php b/kirby/src/Cms/Url.php index 9111b09..f10604f 100644 --- a/kirby/src/Cms/Url.php +++ b/kirby/src/Cms/Url.php @@ -21,12 +21,10 @@ use Kirby\Http\Url as BaseUrl; */ class Url extends BaseUrl { - public static $home = null; + public static string|null $home = null; /** * Returns the Url to the homepage - * - * @return string */ public static function home(): string { @@ -34,13 +32,10 @@ class Url extends BaseUrl } /** - * Creates an absolute Url to a template asset if it exists. This is used in the `css()` and `js()` helpers - * - * @param string $assetPath - * @param string $extension - * @return string|null + * Creates an absolute Url to a template asset if it exists. + * This is used in the `css()` and `js()` helpers */ - public static function toTemplateAsset(string $assetPath, string $extension) + public static function toTemplateAsset(string $assetPath, string $extension): string|null { $kirby = App::instance(); $page = $kirby->site()->page(); @@ -54,11 +49,9 @@ class Url extends BaseUrl /** * Smart resolver for internal and external urls * - * @param string|null $path * @param array|string|null $options Either an array of options for the Uri class or a language string - * @return string */ - public static function to(string $path = null, $options = null): string + public static function to(string|null $path = null, array|string|null $options = null): string { $kirby = App::instance(); return ($kirby->component('url'))($kirby, $path, $options); diff --git a/kirby/src/Cms/User.php b/kirby/src/Cms/User.php index 67b138c..b94e643 100644 --- a/kirby/src/Cms/User.php +++ b/kirby/src/Cms/User.php @@ -8,6 +8,7 @@ use Kirby\Exception\NotFoundException; use Kirby\Filesystem\Dir; use Kirby\Filesystem\F; use Kirby\Panel\User as Panel; +use Kirby\Session\Session; use Kirby\Toolkit\Str; /** @@ -156,9 +157,9 @@ class User extends ModelWithContent { if ($relative === true) { return 'users/' . $this->id(); - } else { - return $this->kirby()->url('api') . '/users/' . $this->id(); } + + return $this->kirby()->url('api') . '/users/' . $this->id(); } /** @@ -178,13 +179,13 @@ class User extends ModelWithContent */ public function blueprint() { - if (is_a($this->blueprint, 'Kirby\Cms\Blueprint') === true) { + if ($this->blueprint instanceof Blueprint) { return $this->blueprint; } try { return $this->blueprint = UserBlueprint::factory('users/' . $this->role(), 'users/default', $this); - } catch (Exception $e) { + } catch (Exception) { return $this->blueprint = new UserBlueprint([ 'model' => $this, 'name' => 'default', @@ -236,7 +237,7 @@ class User extends ModelWithContent * * @return string */ - public function email(): ?string + public function email(): string|null { return $this->email ??= $this->credentials()['email'] ?? null; } @@ -276,7 +277,7 @@ class User extends ModelWithContent * @param string|null $password * @return string|null */ - public static function hashPassword($password): ?string + public static function hashPassword($password): string|null { if ($password !== null) { $password = password_hash($password, PASSWORD_DEFAULT); @@ -509,7 +510,7 @@ class User extends ModelWithContent if ($class = (static::$models[$name] ?? null)) { $object = new $class($props); - if (is_a($object, 'Kirby\Cms\User') === true) { + if ($object instanceof self) { return $object; } } @@ -594,7 +595,7 @@ class User extends ModelWithContent * * @return string|null */ - public function password(): ?string + public function password(): string|null { if ($this->password !== null) { return $this->password; @@ -618,17 +619,13 @@ class User extends ModelWithContent */ public function role() { - if (is_a($this->role, 'Kirby\Cms\Role') === true) { + if ($this->role instanceof Role) { return $this->role; } - $roleName = $this->role ?? $this->credentials()['role'] ?? 'visitor'; + $name = $this->role ?? $this->credentials()['role'] ?? 'visitor'; - if ($role = $this->kirby()->roles()->find($roleName)) { - return $this->role = $role; - } - - return $this->role = Role::nobody(); + return $this->role = $this->kirby()->roles()->find($name) ?? Role::nobody(); } /** @@ -647,18 +644,16 @@ class User extends ModelWithContent $myRole = $roles->filter('id', $this->role()->id()); // if there's an authenticated user … - if ($user = $kirby->user()) { - // admin users can select pretty much any role - if ($user->isAdmin() === true) { - // except if the user is the last admin - if ($this->isLastAdmin() === true) { - // in which case they have to stay admin - return $myRole; - } - - // return all roles for mighty admins - return $roles; + // admin users can select pretty much any role + if ($kirby->user()?->isAdmin() === true) { + // except if the user is the last admin + if ($this->isLastAdmin() === true) { + // in which case they have to stay admin + return $myRole; } + + // return all roles for mighty admins + return $roles; } // any other user can only keep their role @@ -787,7 +782,7 @@ class User extends ModelWithContent // use passed session options or session object if set if (is_array($session) === true) { $session = $this->kirby()->session($session); - } elseif (is_a($session, 'Kirby\Session\Session') === false) { + } elseif ($session instanceof Session === false) { $session = $this->kirby()->session(['detect' => true]); } @@ -828,15 +823,13 @@ class User extends ModelWithContent * * @param string|null $template * @param array|null $data - * @param string $fallback Fallback for tokens in the template that cannot be replaced + * @param string|null $fallback Fallback for tokens in the template that cannot be replaced + * (`null` to keep the original token) * @return string */ - public function toString(string $template = null, array $data = [], string $fallback = '', string $handler = 'template'): string + public function toString(string $template = null, array $data = [], string|null $fallback = '', string $handler = 'template'): string { - if ($template === null) { - $template = $this->email(); - } - + $template ??= $this->email(); return parent::toString($template, $data, $fallback, $handler); } @@ -847,7 +840,7 @@ class User extends ModelWithContent * * @return string|null */ - public function username(): ?string + public function username(): string|null { return $this->name()->or($this->email())->value(); } @@ -878,56 +871,4 @@ class User extends ModelWithContent return true; } - - - /** - * Deprecated! - */ - - /** - * Returns the full path without leading slash - * - * @todo Remove in 3.8.0 - * - * @internal - * @return string - * @codeCoverageIgnore - */ - public function panelPath(): string - { - Helpers::deprecated('Cms\User::panelPath() has been deprecated and will be removed in Kirby 3.8.0. Use $user->panel()->path() instead.'); - return $this->panel()->path(); - } - - /** - * Returns prepared data for the panel user picker - * - * @todo Remove in 3.8.0 - * - * @param array|null $params - * @return array - * @codeCoverageIgnore - */ - public function panelPickerData(array $params = null): array - { - Helpers::deprecated('Cms\User::panelPickerData() has been deprecated and will be removed in Kirby 3.8.0. Use $user->panel()->pickerData() instead.'); - return $this->panel()->pickerData($params); - } - - /** - * Returns the url to the editing view - * in the panel - * - * @todo Remove in 3.8.0 - * - * @internal - * @param bool $relative - * @return string - * @codeCoverageIgnore - */ - public function panelUrl(bool $relative = false): string - { - Helpers::deprecated('Cms\User::panelUrl() has been deprecated and will be removed in Kirby 3.8.0. Use $user->panel()->url() instead.'); - return $this->panel()->url($relative); - } } diff --git a/kirby/src/Cms/UserActions.php b/kirby/src/Cms/UserActions.php index 4547844..15b0769 100644 --- a/kirby/src/Cms/UserActions.php +++ b/kirby/src/Cms/UserActions.php @@ -263,7 +263,7 @@ trait UserActions // we can't really test for a random match // @codeCoverageIgnoreStart - } catch (Throwable $e) { + } catch (Throwable) { $length++; } } while (true); @@ -308,12 +308,12 @@ trait UserActions $path = $this->root() . '/index.php'; if (is_file($path) === true) { - $credentials = F::load($path); + $credentials = F::load($path, allowOutput: false); return is_array($credentials) === false ? [] : $credentials; - } else { - return []; } + + return []; } /** diff --git a/kirby/src/Cms/UserPicker.php b/kirby/src/Cms/UserPicker.php index 46da3dc..0861bc8 100644 --- a/kirby/src/Cms/UserPicker.php +++ b/kirby/src/Cms/UserPicker.php @@ -43,7 +43,7 @@ class UserPicker extends Picker // find the right default query if (empty($this->options['query']) === false) { $query = $this->options['query']; - } elseif (is_a($model, 'Kirby\Cms\User') === true) { + } elseif ($model instanceof User) { $query = 'user.siblings'; } else { $query = 'kirby.users'; @@ -53,7 +53,7 @@ class UserPicker extends Picker $users = $model->query($query); // catch invalid data - if (is_a($users, 'Kirby\Cms\Users') === false) { + if ($users instanceof Users === false) { throw new InvalidArgumentException('Your query must return a set of users'); } diff --git a/kirby/src/Cms/UserRules.php b/kirby/src/Cms/UserRules.php index fa740fa..bf469d4 100644 --- a/kirby/src/Cms/UserRules.php +++ b/kirby/src/Cms/UserRules.php @@ -179,14 +179,14 @@ class UserRules $currentUser = $user->kirby()->user(); // admins are allowed everything - if ($currentUser && $currentUser->isAdmin() === true) { + if ($currentUser?->isAdmin() === true) { return true; } // only admins are allowed to add admins $role = $props['role'] ?? null; - if ($role === 'admin' && $currentUser && $currentUser->isAdmin() === false) { + if ($role === 'admin' && $currentUser?->isAdmin() === false) { throw new PermissionException([ 'key' => 'user.create.permission' ]); @@ -358,7 +358,7 @@ class UserRules */ public static function validRole(User $user, string $role): bool { - if (is_a($user->kirby()->roles()->find($role), 'Kirby\Cms\Role') === true) { + if ($user->kirby()->roles()->find($role) instanceof Role) { return true; } diff --git a/kirby/src/Cms/Users.php b/kirby/src/Cms/Users.php index 055863c..b9e51fb 100644 --- a/kirby/src/Cms/Users.php +++ b/kirby/src/Cms/Users.php @@ -6,6 +6,7 @@ use Kirby\Exception\InvalidArgumentException; use Kirby\Filesystem\Dir; use Kirby\Filesystem\F; use Kirby\Toolkit\Str; +use Kirby\Uuid\HasUuids; /** * The `$users` object refers to a collection @@ -21,6 +22,8 @@ use Kirby\Toolkit\Str; */ class Users extends Collection { + use HasUuids; + /** * All registered users methods * @@ -45,15 +48,18 @@ class Users extends Collection public function add($object) { // add a users collection - if (is_a($object, self::class) === true) { + if ($object instanceof self) { $this->data = array_merge($this->data, $object->data); // add a user by id - } elseif (is_string($object) === true && $user = App::instance()->user($object)) { + } elseif ( + is_string($object) === true && + $user = App::instance()->user($object) + ) { $this->__set($user->id(), $user); // add a user object - } elseif (is_a($object, 'Kirby\Cms\User') === true) { + } elseif ($object instanceof User) { $this->__set($object->id(), $object); // give a useful error message on invalid input; @@ -85,6 +91,24 @@ class Users extends Collection return $collection; } + /** + * Returns all files of all users + * + * @return \Kirby\Cms\Files + */ + public function files() + { + $files = new Files([], $this->parent); + + foreach ($this->data as $user) { + foreach ($user->files() as $fileKey => $file) { + $files->data[$fileKey] = $file; + } + } + + return $files; + } + /** * Finds a user in the collection by ID or email address * @internal Use `$users->find()` instead @@ -94,6 +118,10 @@ class Users extends Collection */ public function findByKey(string $key) { + if ($user = $this->findByUuid($key, 'user')) { + return $user; + } + if (Str::contains($key, '@') === true) { return parent::findBy('email', Str::lower($key)); } @@ -120,7 +148,7 @@ class Users extends Collection // get role information $path = $root . '/' . $userDirectory . '/index.php'; if (is_file($path) === true) { - $credentials = F::load($path); + $credentials = F::load($path, allowOutput: false); } // create user model based on role diff --git a/kirby/src/Data/Data.php b/kirby/src/Data/Data.php index 3c69e32..00e1194 100644 --- a/kirby/src/Data/Data.php +++ b/kirby/src/Data/Data.php @@ -26,10 +26,8 @@ class Data { /** * Handler Type Aliases - * - * @var array */ - public static $aliases = [ + public static array $aliases = [ 'md' => 'txt', 'mdown' => 'txt', 'rss' => 'xml', @@ -38,10 +36,8 @@ class Data /** * All registered handlers - * - * @var array */ - public static $handlers = [ + public static array $handlers = [ 'json' => 'Kirby\Data\Json', 'php' => 'Kirby\Data\PHP', 'txt' => 'Kirby\Data\Txt', @@ -51,33 +47,32 @@ class Data /** * Handler getter - * - * @param string $type - * @return \Kirby\Data\Handler */ - public static function handler(string $type) + public static function handler(string $type): Handler { // normalize the type $type = strtolower($type); // find a handler or alias + $alias = static::$aliases[$type] ?? null; $handler = static::$handlers[$type] ?? - static::$handlers[static::$aliases[$type] ?? null] ?? - null; + ($alias ? static::$handlers[$alias] ?? null : null); - if ($handler !== null && class_exists($handler)) { - return new $handler(); + if ($handler === null || class_exists($handler) === false) { + throw new Exception('Missing handler for type: "' . $type . '"'); } - throw new Exception('Missing handler for type: "' . $type . '"'); + $handler = new $handler(); + + if ($handler instanceof Handler === false) { + throw new Exception('Handler for type: "' . $type . '" needs to extend Kirby\\Data\\Handler'); + } + + return $handler; } /** * Decodes data with the specified handler - * - * @param mixed $string - * @param string $type - * @return array */ public static function decode($string, string $type): array { @@ -86,10 +81,6 @@ class Data /** * Encodes data with the specified handler - * - * @param mixed $data - * @param string $type - * @return string */ public static function encode($data, string $type): string { @@ -100,12 +91,8 @@ class Data * Reads data from a file; * the data handler is automatically chosen by * the extension if not specified - * - * @param string $file - * @param string $type - * @return array */ - public static function read(string $file, string $type = null): array + public static function read(string $file, string|null $type = null): array { return static::handler($type ?? F::extension($file))->read($file); } @@ -114,14 +101,12 @@ class Data * Writes data to a file; * the data handler is automatically chosen by * the extension if not specified - * - * @param string $file - * @param mixed $data - * @param string $type - * @return bool */ - public static function write(string $file = null, $data = [], string $type = null): bool - { + public static function write( + string $file, + $data = [], + string|null $type = null + ): bool { return static::handler($type ?? F::extension($file))->write($file, $data); } } diff --git a/kirby/src/Data/Handler.php b/kirby/src/Data/Handler.php index 9c511f8..95dbad3 100644 --- a/kirby/src/Data/Handler.php +++ b/kirby/src/Data/Handler.php @@ -21,32 +21,24 @@ abstract class Handler /** * Parses an encoded string and returns a multi-dimensional array * - * Needs to throw an Exception if the file can't be parsed. - * - * @param mixed $string - * @return array + * @throws \Exception if the file can't be parsed */ abstract public static function decode($string): array; /** * Converts an array to an encoded string - * - * @param mixed $data - * @return string */ abstract public static function encode($data): string; /** * Reads data from a file - * - * @param string $file - * @return array */ public static function read(string $file): array { $contents = F::read($file); + if ($contents === false) { - throw new Exception('The file "' . $file . '" does not exist'); + throw new Exception('The file "' . $file . '" does not exist or cannot be read'); } return static::decode($contents); @@ -54,12 +46,8 @@ abstract class Handler /** * Writes data to a file - * - * @param string $file - * @param mixed $data - * @return bool */ - public static function write(string $file = null, $data = []): bool + public static function write(string $file, $data = []): bool { return F::write($file, static::encode($data)); } diff --git a/kirby/src/Data/Json.php b/kirby/src/Data/Json.php index 622636b..35fa867 100644 --- a/kirby/src/Data/Json.php +++ b/kirby/src/Data/Json.php @@ -17,20 +17,17 @@ class Json extends Handler { /** * Converts an array to an encoded JSON string - * - * @param mixed $data - * @return string */ public static function encode($data): string { - return json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + return json_encode( + $data, + JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE + ); } /** * Parses an encoded JSON string and returns a multi-dimensional array - * - * @param mixed $string - * @return array */ public static function decode($string): array { @@ -50,8 +47,8 @@ class Json extends Handler if (is_array($result) === true) { return $result; - } else { - throw new InvalidArgumentException('JSON string is invalid'); } + + throw new InvalidArgumentException('JSON string is invalid'); } } diff --git a/kirby/src/Data/PHP.php b/kirby/src/Data/PHP.php index ff3106c..b22d38a 100644 --- a/kirby/src/Data/PHP.php +++ b/kirby/src/Data/PHP.php @@ -20,9 +20,7 @@ class PHP extends Handler /** * Converts an array to PHP file content * - * @param mixed $data * @param string $indent For internal use only - * @return string */ public static function encode($data, string $indent = ''): string { @@ -40,7 +38,7 @@ class PHP extends Handler return $data ? 'true' : 'false'; case 'integer': case 'double': - return $data; + return (string)$data; default: return var_export($data, true); } @@ -48,9 +46,6 @@ class PHP extends Handler /** * PHP strings shouldn't be decoded manually - * - * @param mixed $string - * @return array */ public static function decode($string): array { @@ -59,9 +54,6 @@ class PHP extends Handler /** * Reads data from a file - * - * @param string $file - * @return array */ public static function read(string $file): array { @@ -69,17 +61,13 @@ class PHP extends Handler throw new Exception('The file "' . $file . '" does not exist'); } - return (array)F::load($file, []); + return (array)F::load($file, [], allowOutput: false); } /** * Creates a PHP file with the given data - * - * @param string $file - * @param mixed $data - * @return bool */ - public static function write(string $file = null, $data = []): bool + public static function write(string $file, $data = []): bool { $php = static::encode($data); $php = " null, @@ -227,10 +186,8 @@ class Database /** * Returns the currently active connection - * - * @return \PDO|null */ - public function connection(): ?PDO + public function connection(): PDO|null { return $this->connection; } @@ -238,10 +195,9 @@ class Database /** * Sets the exception mode * - * @param bool $fail - * @return \Kirby\Database\Database + * @return $this */ - public function fail(bool $fail = true) + public function fail(bool $fail = true): static { $this->fail = $fail; return $this; @@ -249,8 +205,6 @@ class Database /** * Returns the used database type - * - * @return string */ public function type(): string { @@ -259,10 +213,8 @@ class Database /** * Returns the used table name prefix - * - * @return string|null */ - public function prefix(): ?string + public function prefix(): string|null { return $this->prefix; } @@ -270,9 +222,6 @@ class Database /** * Escapes a value to be used for a safe query * NOTE: Prepared statements using bound parameters are more secure and solid - * - * @param string $value - * @return string */ public function escape(string $value): string { @@ -280,12 +229,10 @@ class Database } /** - * Adds a value to the db trace and also returns the entire trace if nothing is specified - * - * @param array|null $data - * @return array + * Adds a value to the db trace and also + * returns the entire trace if nothing is specified */ - public function trace(array $data = null): array + public function trace(array|null $data = null): array { // return the full trace if ($data === null) { @@ -300,38 +247,30 @@ class Database /** * Returns the number of affected rows for the last query - * - * @return int|null */ - public function affected(): ?int + public function affected(): int|null { return $this->affected; } /** * Returns the last id if available - * - * @return int|null */ - public function lastId(): ?int + public function lastId(): int|null { return $this->lastId; } /** * Returns the last query - * - * @return string|null */ - public function lastQuery(): ?string + public function lastQuery(): string|null { return $this->lastQuery; } /** * Returns the last set of results - * - * @return mixed */ public function lastResult() { @@ -340,20 +279,16 @@ class Database /** * Returns the last db error - * - * @return \Throwable */ - public function lastError() + public function lastError(): Throwable { return $this->lastError; } /** * Returns the name of the database - * - * @return string|null */ - public function name(): ?string + public function name(): string|null { return $this->database; } @@ -361,10 +296,6 @@ class Database /** * Private method to execute database queries. * This is used by the query() and execute() methods - * - * @param string $query - * @param array $bindings - * @return bool */ protected function hit(string $query, array $bindings = []): bool { @@ -405,11 +336,6 @@ class Database /** * Executes a sql query, which is expected to return a set of results - * - * @param string $query - * @param array $bindings - * @param array $params - * @return mixed */ public function query(string $query, array $bindings = [], array $params = []) { @@ -427,7 +353,10 @@ class Database } // define the default flag for the fetch method - if ($options['fetch'] instanceof Closure || $options['fetch'] === 'array') { + if ( + $options['fetch'] instanceof Closure || + $options['fetch'] === 'array' + ) { $flags = PDO::FETCH_ASSOC; } else { $flags = PDO::FETCH_CLASS|PDO::FETCH_PROPS_LATE; @@ -463,11 +392,8 @@ class Database } /** - * Executes a sql query, which is expected to not return a set of results - * - * @param string $query - * @param array $bindings - * @return bool + * Executes a sql query, which is expected + * to not return a set of results */ public function execute(string $query, array $bindings = []): bool { @@ -477,10 +403,8 @@ class Database /** * Returns the correct Sql generator instance * for the type of database - * - * @return \Kirby\Database\Sql */ - public function sql() + public function sql(): Sql { $className = static::$types[$this->type]['sql'] ?? 'Sql'; return new $className($this); @@ -490,20 +414,14 @@ class Database * Sets the current table, which should be queried. Returns a * Query object, which can be used to build a full query * for that table - * - * @param string $table - * @return \Kirby\Database\Query */ - public function table(string $table) + public function table(string $table): Query { return new Query($this, $this->prefix() . $table); } /** * Checks if a table exists in the current database - * - * @param string $table - * @return bool */ public function validateTable(string $table): bool { @@ -524,10 +442,6 @@ class Database /** * Checks if a column exists in a specified table - * - * @param string $table - * @param string $column - * @return bool */ public function validateColumn(string $table, string $column): bool { @@ -553,12 +467,8 @@ class Database /** * Creates a new table - * - * @param string $table - * @param array $columns - * @return bool */ - public function createTable($table, $columns = []): bool + public function createTable(string $table, array $columns = []): bool { $sql = $this->sql()->createTable($table, $columns); $queries = Str::split($sql['query'], ';'); @@ -581,9 +491,6 @@ class Database /** * Drops a table - * - * @param string $table - * @return bool */ public function dropTable(string $table): bool { @@ -605,12 +512,8 @@ class Database * Magic way to start queries for tables by * using a method named like the table. * I.e. $db->users()->all() - * - * @param mixed $method - * @param mixed $arguments - * @return \Kirby\Database\Query */ - public function __call($method, $arguments = null) + public function __call(string $method, mixed $arguments = null): Query { return $this->table($method); } @@ -621,7 +524,7 @@ class Database */ Database::$types['mysql'] = [ 'sql' => 'Kirby\Database\Sql\Mysql', - 'dsn' => function (array $params) { + 'dsn' => function (array $params): string { if (isset($params['host']) === false && isset($params['socket']) === false) { throw new InvalidArgumentException('The mysql connection requires either a "host" or a "socket" parameter'); } @@ -659,7 +562,7 @@ Database::$types['mysql'] = [ */ Database::$types['sqlite'] = [ 'sql' => 'Kirby\Database\Sql\Sqlite', - 'dsn' => function (array $params) { + 'dsn' => function (array $params): string { if (isset($params['database']) === false) { throw new InvalidArgumentException('The sqlite connection requires a "database" parameter'); } diff --git a/kirby/src/Database/Db.php b/kirby/src/Database/Db.php index e57562f..01c3f22 100644 --- a/kirby/src/Database/Db.php +++ b/kirby/src/Database/Db.php @@ -18,26 +18,21 @@ class Db { /** * Query shortcuts - * - * @var array */ - public static $queries = []; + public static array $queries = []; /** * The singleton Database object - * - * @var \Kirby\Database\Database */ - public static $connection = null; + public static Database|null $connection = null; /** * (Re)connect the database * * @param array|null $params Pass `[]` to use the default params from the config, * don't pass any argument to get the current connection - * @return \Kirby\Database\Database */ - public static function connect(?array $params = null) + public static function connect(array|null $params = null): Database { if ($params === null && static::$connection !== null) { return static::$connection; @@ -60,10 +55,8 @@ class Db /** * Returns the current database connection - * - * @return \Kirby\Database\Database|null */ - public static function connection() + public static function connection(): Database|null { return static::$connection; } @@ -72,11 +65,8 @@ class Db * Sets the current table which should be queried. Returns a * Query object, which can be used to build a full query for * that table. - * - * @param string $table - * @return \Kirby\Database\Query */ - public static function table(string $table) + public static function table(string $table): Query { $db = static::connect(); return $db->table($table); @@ -84,11 +74,6 @@ class Db /** * Executes a raw SQL query which expects a set of results - * - * @param string $query - * @param array $bindings - * @param array $params - * @return mixed */ public static function query(string $query, array $bindings = [], array $params = []) { @@ -97,11 +82,8 @@ class Db } /** - * Executes a raw SQL query which expects no set of results (i.e. update, insert, delete) - * - * @param string $query - * @param array $bindings - * @return bool + * Executes a raw SQL query which expects + * no set of results (i.e. update, insert, delete) */ public static function execute(string $query, array $bindings = []): bool { @@ -114,9 +96,6 @@ class Db * redirected to either a predefined query or * the respective method of the Database object * - * @param string $method - * @param mixed $arguments - * @return mixed * @throws \Kirby\Exception\InvalidArgumentException */ public static function __callStatic(string $method, $arguments) @@ -125,7 +104,10 @@ class Db return (static::$queries[$method])(...$arguments); } - if (static::$connection !== null && method_exists(static::$connection, $method) === true) { + if ( + static::$connection !== null && + method_exists(static::$connection, $method) === true + ) { return call_user_func_array([static::$connection, $method], $arguments); } @@ -141,13 +123,22 @@ class Db * @param string $table The name of the table which should be queried * @param mixed $columns Either a string with columns or an array of column names * @param mixed $where The WHERE clause; can be a string or an array - * @param string $order - * @param int $offset - * @param int $limit - * @return mixed */ -Db::$queries['select'] = function (string $table, $columns = '*', $where = null, string $order = null, int $offset = 0, int $limit = null) { - return Db::table($table)->select($columns)->where($where)->order($order)->offset($offset)->limit($limit)->all(); +Db::$queries['select'] = function ( + string $table, + $columns = '*', + $where = null, + string|null $order = null, + int $offset = 0, + int|null $limit = null +) { + return Db::table($table) + ->select($columns) + ->where($where) + ->order($order) + ->offset($offset) + ->limit($limit) + ->all(); }; /** @@ -156,13 +147,18 @@ Db::$queries['select'] = function (string $table, $columns = '*', $where = null, * @param string $table The name of the table which should be queried * @param mixed $columns Either a string with columns or an array of column names * @param mixed $where The WHERE clause; can be a string or an array - * @param string $order - * @param int $offset - * @param int $limit - * @return mixed */ -Db::$queries['first'] = Db::$queries['row'] = Db::$queries['one'] = function (string $table, $columns = '*', $where = null, string $order = null) { - return Db::table($table)->select($columns)->where($where)->order($order)->first(); +Db::$queries['first'] = Db::$queries['row'] = Db::$queries['one'] = function ( + string $table, + $columns = '*', + $where = null, + string|null $order = null +) { + return Db::table($table) + ->select($columns) + ->where($where) + ->order($order) + ->first(); }; /** @@ -171,13 +167,21 @@ Db::$queries['first'] = Db::$queries['row'] = Db::$queries['one'] = function (st * @param string $table The name of the table which should be queried * @param string $column The name of the column to select from * @param mixed $where The WHERE clause; can be a string or an array - * @param string $order - * @param int $offset - * @param int $limit - * @return mixed */ -Db::$queries['column'] = function (string $table, string $column, $where = null, string $order = null, int $offset = 0, int $limit = null) { - return Db::table($table)->where($where)->order($order)->offset($offset)->limit($limit)->column($column); +Db::$queries['column'] = function ( + string $table, + string $column, + $where = null, + string|null $order = null, + int $offset = 0, + int|null $limit = null +) { + return Db::table($table) + ->where($where) + ->order($order) + ->offset($offset) + ->limit($limit) + ->column($column); }; /** @@ -197,9 +201,12 @@ Db::$queries['insert'] = function (string $table, array $values) { * @param string $table The name of the table which should be queried * @param array $values An array of values which should be inserted * @param mixed $where An optional WHERE clause - * @return bool */ -Db::$queries['update'] = function (string $table, array $values, $where = null): bool { +Db::$queries['update'] = function ( + string $table, + array $values, + $where = null +): bool { return Db::table($table)->where($where)->update($values); }; @@ -208,7 +215,6 @@ Db::$queries['update'] = function (string $table, array $values, $where = null): * * @param string $table The name of the table which should be queried * @param mixed $where An optional WHERE clause - * @return bool */ Db::$queries['delete'] = function (string $table, $where = null): bool { return Db::table($table)->where($where)->delete(); @@ -231,9 +237,12 @@ Db::$queries['count'] = function (string $table, $where = null): int { * @param string $table The name of the table which should be queried * @param string $column The name of the column of which the minimum should be calculated * @param mixed $where An optional WHERE clause - * @return float */ -Db::$queries['min'] = function (string $table, string $column, $where = null): float { +Db::$queries['min'] = function ( + string $table, + string $column, + $where = null +): float { return Db::table($table)->where($where)->min($column); }; @@ -243,9 +252,12 @@ Db::$queries['min'] = function (string $table, string $column, $where = null): f * @param string $table The name of the table which should be queried * @param string $column The name of the column of which the maximum should be calculated * @param mixed $where An optional WHERE clause - * @return float */ -Db::$queries['max'] = function (string $table, string $column, $where = null): float { +Db::$queries['max'] = function ( + string $table, + string $column, + $where = null +): float { return Db::table($table)->where($where)->max($column); }; @@ -255,9 +267,12 @@ Db::$queries['max'] = function (string $table, string $column, $where = null): f * @param string $table The name of the table which should be queried * @param string $column The name of the column of which the average should be calculated * @param mixed $where An optional WHERE clause - * @return float */ -Db::$queries['avg'] = function (string $table, string $column, $where = null): float { +Db::$queries['avg'] = function ( + string $table, + string $column, + $where = null +): float { return Db::table($table)->where($where)->avg($column); }; @@ -267,9 +282,12 @@ Db::$queries['avg'] = function (string $table, string $column, $where = null): f * @param string $table The name of the table which should be queried * @param string $column The name of the column of which the sum should be calculated * @param mixed $where An optional WHERE clause - * @return float */ -Db::$queries['sum'] = function (string $table, string $column, $where = null): float { +Db::$queries['sum'] = function ( + string $table, + string $column, + $where = null +): float { return Db::table($table)->where($where)->sum($column); }; diff --git a/kirby/src/Database/Query.php b/kirby/src/Database/Query.php index 9354892..5312004 100644 --- a/kirby/src/Database/Query.php +++ b/kirby/src/Database/Query.php @@ -2,8 +2,10 @@ namespace Kirby\Database; +use Closure; use InvalidArgumentException; -use Kirby\Toolkit\A; +use Kirby\Toolkit\Collection; +use Kirby\Toolkit\Obj; use Kirby\Toolkit\Pagination; use Kirby\Toolkit\Str; @@ -23,130 +25,94 @@ class Query /** * Parent Database object - * - * @var \Kirby\Database\Database */ - protected $database = null; + protected Database|null $database = null; /** * The object which should be fetched for each row * or function to call for each row - * - * @var string|\Closure */ - protected $fetch = 'Kirby\Toolkit\Obj'; + protected string|Closure $fetch = Obj::class; /** * The iterator class, which should be used for result sets - * - * @var string */ - protected $iterator = 'Kirby\Toolkit\Collection'; + protected string $iterator = Collection::class; /** * An array of bindings for the final query - * - * @var array */ - protected $bindings = []; + protected array $bindings = []; /** * The table name - * - * @var string */ - protected $table; + protected string $table; /** * The name of the primary key column - * - * @var string */ - protected $primaryKeyName = 'id'; + protected string $primaryKeyName = 'id'; /** * An array with additional join parameters - * - * @var array */ - protected $join; + protected array|null $join = null; /** * A list of columns, which should be selected - * - * @var array|string */ - protected $select; + protected array|string|null $select = null; /** * Boolean for distinct select clauses - * - * @var bool */ - protected $distinct; + protected bool|null $distinct = null; /** * Boolean for if exceptions should be thrown on failing queries - * - * @var bool */ - protected $fail = false; + protected bool $fail = false; /** * A list of values for update and insert clauses - * - * @var array */ - protected $values; + protected array|null $values = null; /** * WHERE clause - * - * @var mixed */ - protected $where; + protected $where = null; /** * GROUP BY clause - * - * @var mixed */ - protected $group; + protected string|null $group = null; /** * HAVING clause - * - * @var mixed */ - protected $having; + protected $having = null; /** * ORDER BY clause - * - * @var mixed */ - protected $order; + protected $order = null; /** * The offset, which should be applied to the select query - * - * @var int */ - protected $offset = 0; + protected int $offset = 0; /** * The limit, which should be applied to the select query - * - * @var int */ - protected $limit; + protected int|null $limit = null; /** * Boolean to enable query debugging - * - * @var bool */ - protected $debug = false; + protected bool $debug = false; /** * Constructor @@ -163,7 +129,7 @@ class Query /** * Reset the query class after each db hit */ - protected function reset() + protected function reset(): void { $this->bindings = []; $this->join = null; @@ -185,10 +151,9 @@ class Query * If enabled, the query will return an array with all important info about * the query instead of actually executing the query and returning results * - * @param bool $debug - * @return \Kirby\Database\Query + * @return $this */ - public function debug(bool $debug = true) + public function debug(bool $debug = true): static { $this->debug = $debug; return $this; @@ -197,10 +162,9 @@ class Query /** * Enables distinct select clauses. * - * @param bool $distinct - * @return \Kirby\Database\Query + * @return $this */ - public function distinct(bool $distinct = true) + public function distinct(bool $distinct = true): static { $this->distinct = $distinct; return $this; @@ -210,10 +174,9 @@ class Query * Enables failing queries. * If enabled queries will no longer fail silently but throw an exception * - * @param bool $fail - * @return \Kirby\Database\Query + * @return $this */ - public function fail(bool $fail = true) + public function fail(bool $fail = true): static { $this->fail = $fail; return $this; @@ -224,10 +187,9 @@ class Query * set this to `'array'` to get a simple array instead of an object; * pass a function that receives the `$data` and the `$key` to generate arbitrary data structures * - * @param string|\Closure $fetch - * @return \Kirby\Database\Query + * @return $this */ - public function fetch($fetch) + public function fetch(string|Closure $fetch): static { $this->fetch = $fetch; return $this; @@ -237,10 +199,9 @@ class Query * Sets the iterator class, which should be used for multiple results * Set this to array to get a simple array instead of an iterator object * - * @param string $iterator - * @return \Kirby\Database\Query + * @return $this */ - public function iterator(string $iterator) + public function iterator(string $iterator): static { $this->iterator = $iterator; return $this; @@ -249,11 +210,10 @@ class Query /** * Sets the name of the table, which should be queried * - * @param string $table - * @return \Kirby\Database\Query + * @return $this * @throws \Kirby\Exception\InvalidArgumentException if the table does not exist */ - public function table(string $table) + public function table(string $table): static { if ($this->database->validateTable($table) === false) { throw new InvalidArgumentException('Invalid table: ' . $table); @@ -266,10 +226,9 @@ class Query /** * Sets the name of the primary key column * - * @param string $primaryKeyName - * @return \Kirby\Database\Query + * @return $this */ - public function primaryKeyName(string $primaryKeyName) + public function primaryKeyName(string $primaryKeyName): static { $this->primaryKeyName = $primaryKeyName; return $this; @@ -279,10 +238,10 @@ class Query * Sets the columns, which should be selected from the table * By default all columns will be selected * - * @param mixed $select Pass either a string of columns or an array - * @return \Kirby\Database\Query + * @param array|string|null $select Pass either a string of columns or an array + * @return $this */ - public function select($select) + public function select(array|string|null $select): static { $this->select = $select; return $this; @@ -296,7 +255,7 @@ class Query * @param string $type The join type. Uses an inner join by default * @return $this */ - public function join(string $table, string $on, string $type = 'JOIN') + public function join(string $table, string $on, string $type = 'JOIN'): static { $join = [ 'table' => $table, @@ -313,11 +272,11 @@ class Query * * @param string $table Name of the table, which should be joined * @param string $on The on clause for this join - * @return \Kirby\Database\Query + * @return $this */ - public function leftJoin(string $table, string $on) + public function leftJoin(string $table, string $on): static { - return $this->join($table, $on, 'left'); + return $this->join($table, $on, 'left join'); } /** @@ -325,11 +284,11 @@ class Query * * @param string $table Name of the table, which should be joined * @param string $on The on clause for this join - * @return \Kirby\Database\Query + * @return $this */ - public function rightJoin(string $table, string $on) + public function rightJoin(string $table, string $on): static { - return $this->join($table, $on, 'right'); + return $this->join($table, $on, 'right join'); } /** @@ -337,9 +296,9 @@ class Query * * @param string $table Name of the table, which should be joined * @param string $on The on clause for this join - * @return \Kirby\Database\Query + * @return $this */ - public function innerJoin($table, $on) + public function innerJoin($table, $on): static { return $this->join($table, $on, 'inner join'); } @@ -348,9 +307,9 @@ class Query * Sets the values which should be used for the update or insert clause * * @param mixed $values Can either be a string or an array of values - * @return \Kirby\Database\Query + * @return $this */ - public function values($values = []) + public function values($values = []): static { if ($values !== null) { $this->values = $values; @@ -360,12 +319,13 @@ class Query /** * Attaches additional bindings to the query. - * Also can be used as getter for all attached bindings by not passing an argument. + * Also can be used as getter for all attached bindings + * by not passing an argument. * - * @param mixed $bindings Array of bindings or null to use this method as getter - * @return array|\Kirby\Database\Query + * @return array|$this + * @psalm-return ($bindings is array ? $this : array) */ - public function bindings(array $bindings = null) + public function bindings(array|null $bindings = null): array|static { if (is_array($bindings) === true) { $this->bindings = array_merge($this->bindings, $bindings); @@ -386,10 +346,9 @@ class Query * ->where('username like ?', 'myuser') (args: 2) * ->where('username', 'like', 'myuser'); (args: 3) * - * @param mixed ...$args - * @return \Kirby\Database\Query + * @return $this */ - public function where(...$args) + public function where(...$args): static { $this->where = $this->filterQuery($args, $this->where); return $this; @@ -399,23 +358,11 @@ class Query * Shortcut to attach a where clause with an OR operator. * Check out the where() method docs for additional info. * - * @param mixed ...$args - * @return \Kirby\Database\Query + * @return $this */ - public function orWhere(...$args) + public function orWhere(...$args): static { - $mode = A::last($args); - - // if there's a where clause mode attribute attached… - if (in_array($mode, ['AND', 'OR'], true) === true) { - // remove that from the list of arguments - array_pop($args); - } - - // make sure to always attach the OR mode indicator - $args[] = 'OR'; - - $this->where(...$args); + $this->where = $this->filterQuery($args, $this->where, 'OR'); return $this; } @@ -423,33 +370,20 @@ class Query * Shortcut to attach a where clause with an AND operator. * Check out the where() method docs for additional info. * - * @param mixed ...$args - * @return \Kirby\Database\Query + * @return $this */ - public function andWhere(...$args) + public function andWhere(...$args): static { - $mode = A::last($args); - - // if there's a where clause mode attribute attached… - if (in_array($mode, ['AND', 'OR'], true) === true) { - // remove that from the list of arguments - array_pop($args); - } - - // make sure to always attach the AND mode indicator - $args[] = 'AND'; - - $this->where(...$args); + $this->where = $this->filterQuery($args, $this->where, 'AND'); return $this; } /** * Attaches a group by clause * - * @param string|null $group - * @return \Kirby\Database\Query + * @return $this */ - public function group(string $group = null) + public function group(string|null $group = null): static { $this->group = $group; return $this; @@ -466,10 +400,9 @@ class Query * ->having('username like ?', 'myuser') (args: 2) * ->having('username', 'like', 'myuser'); (args: 3) * - * @param mixed ...$args - * @return \Kirby\Database\Query + * @return $this */ - public function having(...$args) + public function having(...$args): static { $this->having = $this->filterQuery($args, $this->having); return $this; @@ -479,7 +412,7 @@ class Query * Attaches an order clause * * @param string|null $order - * @return \Kirby\Database\Query + * @return $this */ public function order(string $order = null) { @@ -490,10 +423,9 @@ class Query /** * Sets the offset for select clauses * - * @param int|null $offset - * @return \Kirby\Database\Query + * @return $this */ - public function offset(int $offset = null) + public function offset(int $offset): static { $this->offset = $offset; return $this; @@ -502,10 +434,9 @@ class Query /** * Sets the limit for select clauses * - * @param int|null $limit - * @return \Kirby\Database\Query + * @return $this */ - public function limit(int $limit = null) + public function limit(int|null $limit = null): static { $this->limit = $limit; return $this; @@ -518,51 +449,46 @@ class Query * @param string $type (select, update, insert) * @return array The final query */ - public function build(string $type) + public function build(string $type): array { $sql = $this->database->sql(); - switch ($type) { - case 'select': - return $sql->select([ - 'table' => $this->table, - 'columns' => $this->select, - 'join' => $this->join, - 'distinct' => $this->distinct, - 'where' => $this->where, - 'group' => $this->group, - 'having' => $this->having, - 'order' => $this->order, - 'offset' => $this->offset, - 'limit' => $this->limit, - 'bindings' => $this->bindings - ]); - case 'update': - return $sql->update([ - 'table' => $this->table, - 'where' => $this->where, - 'values' => $this->values, - 'bindings' => $this->bindings - ]); - case 'insert': - return $sql->insert([ - 'table' => $this->table, - 'values' => $this->values, - 'bindings' => $this->bindings - ]); - case 'delete': - return $sql->delete([ - 'table' => $this->table, - 'where' => $this->where, - 'bindings' => $this->bindings - ]); - } + return match ($type) { + 'select' => $sql->select([ + 'table' => $this->table, + 'columns' => $this->select, + 'join' => $this->join, + 'distinct' => $this->distinct, + 'where' => $this->where, + 'group' => $this->group, + 'having' => $this->having, + 'order' => $this->order, + 'offset' => $this->offset, + 'limit' => $this->limit, + 'bindings' => $this->bindings + ]), + 'update' => $sql->update([ + 'table' => $this->table, + 'where' => $this->where, + 'values' => $this->values, + 'bindings' => $this->bindings + ]), + 'insert' => $sql->insert([ + 'table' => $this->table, + 'values' => $this->values, + 'bindings' => $this->bindings + ]), + 'delete' => $sql->delete([ + 'table' => $this->table, + 'where' => $this->where, + 'bindings' => $this->bindings + ]), + default => null + }; } /** * Builds a count query - * - * @return int */ public function count(): int { @@ -571,9 +497,6 @@ class Query /** * Builds a max query - * - * @param string $column - * @return float */ public function max(string $column): float { @@ -582,9 +505,6 @@ class Query /** * Builds a min query - * - * @param string $column - * @return float */ public function min(string $column): float { @@ -593,9 +513,6 @@ class Query /** * Builds a sum query - * - * @param string $column - * @return float */ public function sum(string $column): float { @@ -604,9 +521,6 @@ class Query /** * Builds an average query - * - * @param string $column - * @return float */ public function avg(string $column): float { @@ -617,12 +531,9 @@ class Query * Builds an aggregation query. * This is used by all the aggregation methods above * - * @param string $method - * @param string $column * @param int $default An optional default value, which should be returned if the query fails - * @return mixed */ - public function aggregate(string $method, string $column = '*', $default = 0) + public function aggregate(string $method, string $column = '*', int $default = 0) { // reset the sorting to avoid counting issues $this->order = null; @@ -634,13 +545,13 @@ class Query } $fetch = $this->fetch; - $row = $this->select($method . '(' . $column . ') as aggregation')->fetch('Obj')->first(); + $row = $this->select($method . '(' . $column . ') as aggregation')->fetch(Obj::class)->first(); if ($this->debug === true) { return $row; } - $result = $row ? $row->get('aggregation') : $default; + $result = $row?->get('aggregation') ?? $default; $this->fetch($fetch); @@ -649,12 +560,8 @@ class Query /** * Used as an internal shortcut for firing a db query - * - * @param string|array $sql - * @param array $params - * @return mixed */ - protected function query($sql, array $params = []) + protected function query(string|array $sql, array $params = []) { if (is_string($sql) === true) { $sql = [ @@ -684,12 +591,8 @@ class Query /** * Used as an internal shortcut for executing a db query - * - * @param string|array $sql - * @param array $params - * @return mixed */ - protected function execute($sql, array $params = []) + protected function execute(string|array $sql, array $params = []) { if (is_string($sql) === true) { $sql = [ @@ -719,10 +622,8 @@ class Query /** * Selects only one row from a table - * - * @return object */ - public function first() + public function first(): object|array|false { return $this->query($this->offset(0)->limit(1)->build('select'), [ 'fetch' => $this->fetch, @@ -733,20 +634,16 @@ class Query /** * Selects only one row from a table - * - * @return object */ - public function row() + public function row(): object|array|false { return $this->first(); } /** * Selects only one row from a table - * - * @return object */ - public function one() + public function one(): object|array|false { return $this->first(); } @@ -754,11 +651,10 @@ class Query /** * Automatically adds pagination to a query * - * @param int $page * @param int $limit The number of rows, which should be returned for each page * @return object Collection iterator with attached pagination object */ - public function page(int $page, int $limit) + public function page(int $page, int $limit): object { // clone this to create a counter query $counter = clone $this; @@ -800,8 +696,6 @@ class Query /** * Returns all matching rows from a table - * - * @return mixed */ public function all() { @@ -813,9 +707,6 @@ class Query /** * Returns only values from a single column - * - * @param string $column - * @return mixed */ public function column(string $column) { @@ -850,10 +741,6 @@ class Query /** * Find a single row by column and value - * - * @param string $column - * @param mixed $value - * @return mixed */ public function findBy(string $column, $value) { @@ -862,9 +749,6 @@ class Query /** * Find a single row by its primary key - * - * @param mixed $id - * @return mixed */ public function find($id) { @@ -893,9 +777,8 @@ class Query * * @param mixed $values You can pass values here or set them with ->values() before * @param mixed $where You can pass a where clause here or set it with ->where() before - * @return bool */ - public function update($values = null, $where = null) + public function update($values = null, $where = null): bool { return $this->execute($this->values($values)->where($where)->build('update')); } @@ -904,28 +787,22 @@ class Query * Fires a delete query * * @param mixed $where You can pass a where clause here or set it with ->where() before - * @return bool */ - public function delete($where = null) + public function delete($where = null): bool { return $this->execute($this->where($where)->build('delete')); } /** * Enables magic queries like findByUsername or findByEmail - * - * @param string $method - * @param array $arguments - * @return mixed */ public function __call(string $method, array $arguments = []) { if (preg_match('!^findBy([a-z]+)!i', $method, $match)) { $column = Str::lower($match[1]); return $this->findBy($column, $arguments[0]); - } else { - throw new InvalidArgumentException('Invalid query method: ' . $method, static::ERROR_INVALID_QUERY_METHOD); } + throw new InvalidArgumentException('Invalid query method: ' . $method, static::ERROR_INVALID_QUERY_METHOD); } /** @@ -933,21 +810,11 @@ class Query * * @param array $args Arguments, see where() description * @param mixed $current Current value (like $this->where) - * @return string */ - protected function filterQuery(array $args, $current) + protected function filterQuery(array $args, $current, string $mode = 'AND') { - $mode = A::last($args); $result = ''; - // if there's a where clause mode attribute attached… - if (in_array($mode, ['AND', 'OR'], true) === true) { - // remove that from the list of arguments - array_pop($args); - } else { - $mode = 'AND'; - } - switch (count($args)) { case 1: @@ -1061,8 +928,8 @@ class Query // attach the where clause if (empty($current) === false) { return $current . ' ' . $mode . ' ' . $result; - } else { - return $result; } + + return $result; } } diff --git a/kirby/src/Database/Sql.php b/kirby/src/Database/Sql.php index e3cff62..e5ec88e 100644 --- a/kirby/src/Database/Sql.php +++ b/kirby/src/Database/Sql.php @@ -19,33 +19,25 @@ abstract class Sql { /** * List of literals which should not be escaped in queries - * - * @var array */ - public static $literals = ['NOW()', null]; + public static array $literals = ['NOW()', null]; /** * The parent database connection - * - * @var \Kirby\Database\Database */ - protected $database; + protected Database $database; /** * List of used bindings; used to avoid * duplicate binding names - * - * @var array */ - protected $bindings = []; + protected array $bindings = []; /** * Constructor * @codeCoverageIgnore - * - * @param \Kirby\Database\Database $database */ - public function __construct($database) + public function __construct(Database $database) { $this->database = $database; } @@ -80,7 +72,6 @@ abstract class Sql * the query needs to return rows with a column `name` * * @param string $table Table name - * @return array */ abstract public function columns(string $table): array; @@ -118,7 +109,7 @@ abstract class Sql * @param bool $enforceQualified If true, a qualified identifier is returned in all cases * @return string|null Identifier or null if the table or column is invalid */ - public function columnName(string $table, string $column, bool $enforceQualified = false): ?string + public function columnName(string $table, string $column, bool $enforceQualified = false): string|null { // ensure we have clean $table and $column values without qualified identifiers list($table, $column) = $this->splitIdentifier($table, $column); @@ -136,8 +127,6 @@ abstract class Sql * Abstracted column types to simplify table * creation for multiple database drivers * @codeCoverageIgnore - * - * @return array */ public function columnTypes(): array { @@ -154,11 +143,8 @@ abstract class Sql /** * Combines an identifier (table and column) * - * @param $table string - * @param $column string * @param $values bool Whether the identifier is going to be used for a VALUES clause; * only relevant for SQLite - * @return string */ public function combineIdentifier(string $table, string $column, bool $values = false): string { @@ -316,7 +302,6 @@ abstract class Sql * Builds a DELETE clause * * @param array $params List of parameters for the DELETE clause. See defaults for more info. - * @return array */ public function delete(array $params = []): array { @@ -344,9 +329,6 @@ abstract class Sql /** * Creates the sql for dropping a single table - * - * @param string $table - * @return array */ public function dropTable(string $table): array { @@ -359,13 +341,8 @@ abstract class Sql /** * Extends a given query and bindings * by reference - * - * @param array $query - * @param array $bindings - * @param array $input - * @return void */ - public function extend(&$query, array &$bindings, $input) + public function extend(array &$query, array &$bindings, array $input): void { if (empty($input['query']) === false) { $query[] = $input['query']; @@ -375,9 +352,6 @@ abstract class Sql /** * Creates the from syntax - * - * @param string $table - * @return array */ public function from(string $table): array { @@ -389,51 +363,36 @@ abstract class Sql /** * Creates the group by syntax - * - * @param string $group - * @return array */ - public function group(string $group = null): array + public function group(string|null $group = null): array { - if (empty($group) === true) { - return [ - 'query' => null, - 'bindings' => [] - ]; + if (empty($group) === false) { + $query = 'GROUP BY ' . $group; } return [ - 'query' => 'GROUP BY ' . $group, + 'query' => $query ?? null, 'bindings' => [] ]; } /** * Creates the having syntax - * - * @param string|null $having - * @return array */ - public function having(string $having = null): array + public function having(string|null $having = null): array { - if (empty($having) === true) { - return [ - 'query' => null, - 'bindings' => [] - ]; + if (empty($having) === false) { + $query = 'HAVING ' . $having; } return [ - 'query' => 'HAVING ' . $having, + 'query' => $query ?? null, 'bindings' => [] ]; } /** * Creates an insert query - * - * @param array $params - * @return array */ public function insert(array $params = []): array { @@ -454,10 +413,6 @@ abstract class Sql /** * Creates a join query * - * @param string $table - * @param string $type - * @param string $on - * @return array * @throws \Kirby\Exception\InvalidArgumentException if an invalid join type is given */ public function join(string $type, string $table, string $on): array @@ -492,11 +447,8 @@ abstract class Sql /** * Create the syntax for multiple joins - * - * @param array|null $joins - * @return array */ - public function joins(array $joins = null): array + public function joins(array|null $joins = null): array { $query = []; $bindings = []; @@ -513,12 +465,8 @@ abstract class Sql /** * Creates a limit and offset query instruction - * - * @param int $offset - * @param int|null $limit - * @return array */ - public function limit(int $offset = 0, int $limit = null): array + public function limit(int $offset = 0, int|null $limit = null): array { // no need to add it to the query if ($offset === 0 && $limit === null) { @@ -544,42 +492,29 @@ abstract class Sql /** * Creates the order by syntax - * - * @param string $order - * @return array */ - public function order(string $order = null): array + public function order(string|null $order = null): array { - if (empty($order) === true) { - return [ - 'query' => null, - 'bindings' => [] - ]; + if (empty($order) === false) { + $query = 'ORDER BY ' . $order; } return [ - 'query' => 'ORDER BY ' . $order, + 'query' => $query ?? null, 'bindings' => [] ]; } /** * Converts a query array into a final string - * - * @param array $query - * @param string $separator - * @return string */ - public function query(array $query, string $separator = ' ') + public function query(array $query, string $separator = ' '): string { return implode($separator, array_filter($query)); } /** * Quotes an identifier (table *or* column) - * - * @param $identifier string - * @return string */ public function quoteIdentifier(string $identifier): string { @@ -658,12 +593,8 @@ abstract class Sql /** * Creates a columns definition from string or array - * - * @param string $table - * @param array|string|null $columns - * @return string */ - public function selected($table, $columns = null): string + public function selected(string $table, array|string|null $columns = null): string { // all columns if (empty($columns) === true) { @@ -684,52 +615,46 @@ abstract class Sql } return implode(', ', $result); - } else { - return $columns; } + + return $columns; } /** * Splits a (qualified) identifier into table and column * - * @param $table string Default table if the identifier is not qualified - * @param $identifier string - * @return array + * @param string $table Default table if the identifier is not qualified * @throws \Kirby\Exception\InvalidArgumentException if an invalid identifier is given */ - public function splitIdentifier($table, $identifier): array + public function splitIdentifier(string $table, string $identifier): array { // split by dot, but only outside of quotes $parts = preg_split('/(?:`[^`]*`|"[^"]*")(*SKIP)(*F)|\./', $identifier); - switch (count($parts)) { - case 1: - // non-qualified identifier - return [$table, $this->unquoteIdentifier($parts[0])]; + return match (count($parts)) { + // non-qualified identifier + 1 => [$table, $this->unquoteIdentifier($parts[0])], - case 2: - // qualified identifier - return [$this->unquoteIdentifier($parts[0]), $this->unquoteIdentifier($parts[1])]; + // qualified identifier + 2 => [ + $this->unquoteIdentifier($parts[0]), + $this->unquoteIdentifier($parts[1]) + ], - default: - // every other number is an error - throw new InvalidArgumentException('Invalid identifier ' . $identifier); - } + // every other number is an error + default => throw new InvalidArgumentException('Invalid identifier ' . $identifier) + }; } /** * Returns a query to list the tables of the current database; * the query needs to return rows with a column `name` - * - * @return array */ abstract public function tables(): array; /** * Validates and quotes a table name * - * @param string $table - * @return string * @throws \Kirby\Exception\InvalidArgumentException if an invalid table name is given */ public function tableName(string $table): string @@ -744,9 +669,6 @@ abstract class Sql /** * Unquotes an identifier (table *or* column) - * - * @param $identifier string - * @return string */ public function unquoteIdentifier(string $identifier): string { @@ -767,7 +689,6 @@ abstract class Sql * Builds an update clause * * @param array $params List of parameters for the update clause. See defaults for more info. - * @return array */ public function update(array $params = []): array { @@ -799,9 +720,6 @@ abstract class Sql /** * Validates a given column name in a table * - * @param string $table - * @param string $column - * @return bool * @throws \Kirby\Exception\InvalidArgumentException If the column is invalid */ public function validateColumn(string $table, string $column): bool @@ -822,8 +740,13 @@ abstract class Sql * @param bool $set If true builds a set list of values for update clauses * @param bool $enforceQualified Always use fully qualified column names */ - public function values(string $table, $values, string $separator = ', ', bool $set = true, bool $enforceQualified = false): array - { + public function values( + string $table, + $values, + string $separator = ', ', + bool $set = true, + bool $enforceQualified = false + ): array { if (is_array($values) === false) { return [ 'query' => $values, @@ -833,22 +756,20 @@ abstract class Sql if ($set === true) { return $this->valueSet($table, $values, $separator, $enforceQualified); - } else { - return $this->valueList($table, $values, $separator, $enforceQualified); } + + return $this->valueList($table, $values, $separator, $enforceQualified); } /** * Creates a list of fields and values - * - * @param string $table - * @param string|array $values - * @param string $separator - * @param bool $enforceQualified - * @param array */ - public function valueList(string $table, $values, string $separator = ',', bool $enforceQualified = false): array - { + public function valueList( + string $table, + string|array $values, + string $separator = ',', + bool $enforceQualified = false + ): array { $fields = []; $query = []; $bindings = []; @@ -886,16 +807,13 @@ abstract class Sql /** * Creates a set of values - * - * @param string $table - * @param string|array $values - * @param string $separator - * @param bool $enforceQualified - * @param array - * @return array */ - public function valueSet(string $table, $values, string $separator = ',', bool $enforceQualified = false): array - { + public function valueSet( + string $table, + string|array $values, + string $separator = ',', + bool $enforceQualified = false + ): array { $query = []; $bindings = []; @@ -928,12 +846,7 @@ abstract class Sql ]; } - /** - * @param string|array|null $where - * @param array $bindings - * @return array - */ - public function where($where, array $bindings = []): array + public function where(string|array|null $where, array $bindings = []): array { if (empty($where) === true) { return [ diff --git a/kirby/src/Database/Sql/Mysql.php b/kirby/src/Database/Sql/Mysql.php index f8fc9d3..02c3939 100644 --- a/kirby/src/Database/Sql/Mysql.php +++ b/kirby/src/Database/Sql/Mysql.php @@ -20,7 +20,6 @@ class Mysql extends Sql * the query needs to return rows with a column `name` * * @param string $table Table name - * @return array */ public function columns(string $table): array { @@ -42,8 +41,6 @@ class Mysql extends Sql /** * Returns a query to list the tables of the current database; * the query needs to return rows with a column `name` - * - * @return array */ public function tables(): array { diff --git a/kirby/src/Database/Sql/Sqlite.php b/kirby/src/Database/Sql/Sqlite.php index c064522..05097a5 100644 --- a/kirby/src/Database/Sql/Sqlite.php +++ b/kirby/src/Database/Sql/Sqlite.php @@ -20,7 +20,6 @@ class Sqlite extends Sql * the query needs to return rows with a column `name` * * @param string $table Table name - * @return array */ public function columns(string $table): array { @@ -34,8 +33,6 @@ class Sqlite extends Sql * Abstracted column types to simplify table * creation for multiple database drivers * @codeCoverageIgnore - * - * @return array */ public function columnTypes(): array { @@ -52,11 +49,9 @@ class Sqlite extends Sql /** * Combines an identifier (table and column) * - * @param $table string - * @param $column string - * @param $values bool Whether the identifier is going to be used for a VALUES clause; - * only relevant for SQLite - * @return string + * @param bool $values Whether the identifier is going to be + * used for a VALUES clause; only relevant + * for SQLite */ public function combineIdentifier(string $table, string $column, bool $values = false): string { @@ -111,9 +106,6 @@ class Sqlite extends Sql /** * Quotes an identifier (table *or* column) - * - * @param $identifier string - * @return string */ public function quoteIdentifier(string $identifier): string { @@ -132,8 +124,6 @@ class Sqlite extends Sql /** * Returns a query to list the tables of the current database; * the query needs to return rows with a column `name` - * - * @return string */ public function tables(): array { diff --git a/kirby/src/Email/Body.php b/kirby/src/Email/Body.php index 716dfd5..8fc0a0b 100644 --- a/kirby/src/Email/Body.php +++ b/kirby/src/Email/Body.php @@ -19,20 +19,11 @@ class Body { use Properties; - /** - * @var string - */ - protected $html; - - /** - * @var string - */ - protected $text; + protected string|null $html = null; + protected string|null $text = null; /** * Email body constructor - * - * @param array $props */ public function __construct(array $props = []) { @@ -41,20 +32,16 @@ class Body /** * Returns the HTML content of the email body - * - * @return string */ - public function html() + public function html(): string { return $this->html ?? ''; } /** * Returns the plain text content of the email body - * - * @return string */ - public function text() + public function text(): string { return $this->text ?? ''; } @@ -62,10 +49,9 @@ class Body /** * Sets the HTML content for the email body * - * @param string|null $html * @return $this */ - protected function setHtml(string $html = null) + protected function setHtml(string|null $html = null): static { $this->html = $html; return $this; @@ -74,10 +60,9 @@ class Body /** * Sets the plain text content for the email body * - * @param string|null $text * @return $this */ - protected function setText(string $text = null) + protected function setText(string|null $text = null): static { $this->text = $text; return $this; diff --git a/kirby/src/Email/Email.php b/kirby/src/Email/Email.php index 5cacbb7..73fb883 100644 --- a/kirby/src/Email/Email.php +++ b/kirby/src/Email/Email.php @@ -24,89 +24,61 @@ class Email /** * If set to `true`, the debug mode is enabled * for all emails - * - * @var bool */ - public static $debug = false; + public static bool $debug = false; /** * Store for sent emails when `Email::$debug` * is set to `true` - * + */ + public static array $emails = []; + + /** * @var array */ - public static $emails = []; + protected array|null $attachments = null; + + protected Body|null $body = null; /** - * @var array|null + * @var array */ - protected $attachments; + protected array|null $bcc = null; + + protected Closure|null $beforeSend = null; /** - * @var \Kirby\Email\Body|null + * @var array */ - protected $body; + protected array|null $cc = null; /** - * @var array|null + * @var string */ - protected $bcc; + protected string|null $from = null; + protected string|null $fromName = null; + + protected bool $isSent = false; /** - * @var \Closure|null + * @var string */ - protected $beforeSend; + protected string|null $replyTo = null; + protected string|null $replyToName = null; /** - * @var array|null + * @var string */ - protected $cc; + protected string|null $subject = null; /** - * @var string|null + * @var array */ - protected $from; - - /** - * @var string|null - */ - protected $fromName; - - /** - * @var string|null - */ - protected $replyTo; - - /** - * @var string|null - */ - protected $replyToName; - - /** - * @var bool - */ - protected $isSent = false; - - /** - * @var string|null - */ - protected $subject; - - /** - * @var array|null - */ - protected $to; - - /** - * @var array|null - */ - protected $transport; + protected array|null $to = null; + protected array|null $transport = null; /** * Email constructor - * - * @param array $props - * @param bool $debug */ public function __construct(array $props = [], bool $debug = false) { @@ -123,8 +95,6 @@ class Email /** * Returns the email attachments - * - * @return array */ public function attachments(): array { @@ -133,18 +103,14 @@ class Email /** * Returns the email body - * - * @return \Kirby\Email\Body|null */ - public function body() + public function body(): Body|null { return $this->body; } /** * Returns "bcc" recipients - * - * @return array */ public function bcc(): array { @@ -154,18 +120,14 @@ class Email /** * Returns the beforeSend callback closure, * which has access to the PHPMailer instance - * - * @return \Closure|null */ - public function beforeSend(): ?Closure + public function beforeSend(): Closure|null { return $this->beforeSend; } /** * Returns "cc" recipients - * - * @return array */ public function cc(): array { @@ -174,8 +136,6 @@ class Email /** * Returns default transport settings - * - * @return array */ protected function defaultTransport(): array { @@ -186,8 +146,6 @@ class Email /** * Returns the "from" email address - * - * @return string */ public function from(): string { @@ -196,28 +154,22 @@ class Email /** * Returns the "from" name - * - * @return string|null */ - public function fromName(): ?string + public function fromName(): string|null { return $this->fromName; } /** * Checks if the email has an HTML body - * - * @return bool */ - public function isHtml() + public function isHtml(): bool { return empty($this->body()->html()) === false; } /** * Checks if the email has been sent successfully - * - * @return bool */ public function isSent(): bool { @@ -226,8 +178,6 @@ class Email /** * Returns the "reply to" email address - * - * @return string */ public function replyTo(): string { @@ -236,10 +186,8 @@ class Email /** * Returns the "reply to" name - * - * @return string|null */ - public function replyToName(): ?string + public function replyToName(): string|null { return $this->replyToName; } @@ -247,13 +195,12 @@ class Email /** * Converts single or multiple email addresses to a sanitized format * - * @param string|array|null $email - * @param bool $multiple - * @return array|mixed|string * @throws \Exception */ - protected function resolveEmail($email = null, bool $multiple = true) - { + protected function resolveEmail( + string|array|null $email = null, + bool $multiple = true + ): array|string { if ($email === null) { return $multiple === true ? [] : ''; } @@ -284,8 +231,6 @@ class Email /** * Sends the email - * - * @return bool */ public function send(): bool { @@ -295,10 +240,9 @@ class Email /** * Sets the email attachments * - * @param array|null $attachments * @return $this */ - protected function setAttachments($attachments = null) + protected function setAttachments(array|null $attachments = null): static { $this->attachments = $attachments ?? []; return $this; @@ -307,10 +251,9 @@ class Email /** * Sets the email body * - * @param string|array $body * @return $this */ - protected function setBody($body) + protected function setBody(string|array $body): static { if (is_string($body) === true) { $body = ['text' => $body]; @@ -323,10 +266,9 @@ class Email /** * Sets "bcc" recipients * - * @param string|array|null $bcc * @return $this */ - protected function setBcc($bcc = null) + protected function setBcc(string|array|null $bcc = null): static { $this->bcc = $this->resolveEmail($bcc); return $this; @@ -335,10 +277,9 @@ class Email /** * Sets the "beforeSend" callback * - * @param \Closure|null $beforeSend * @return $this */ - protected function setBeforeSend(?Closure $beforeSend = null) + protected function setBeforeSend(Closure|null $beforeSend = null): static { $this->beforeSend = $beforeSend; return $this; @@ -347,10 +288,9 @@ class Email /** * Sets "cc" recipients * - * @param string|array|null $cc * @return $this */ - protected function setCc($cc = null) + protected function setCc(string|array|null $cc = null): static { $this->cc = $this->resolveEmail($cc); return $this; @@ -359,10 +299,9 @@ class Email /** * Sets the "from" email address * - * @param string $from * @return $this */ - protected function setFrom(string $from) + protected function setFrom(string $from): static { $this->from = $this->resolveEmail($from, false); return $this; @@ -371,10 +310,9 @@ class Email /** * Sets the "from" name * - * @param string|null $fromName * @return $this */ - protected function setFromName(string $fromName = null) + protected function setFromName(string|null $fromName = null): static { $this->fromName = $fromName; return $this; @@ -383,10 +321,9 @@ class Email /** * Sets the "reply to" email address * - * @param string|null $replyTo * @return $this */ - protected function setReplyTo(string $replyTo = null) + protected function setReplyTo(string|null $replyTo = null): static { $this->replyTo = $this->resolveEmail($replyTo, false); return $this; @@ -395,10 +332,9 @@ class Email /** * Sets the "reply to" name * - * @param string|null $replyToName * @return $this */ - protected function setReplyToName(string $replyToName = null) + protected function setReplyToName(string|null $replyToName = null): static { $this->replyToName = $replyToName; return $this; @@ -407,10 +343,9 @@ class Email /** * Sets the email subject * - * @param string $subject * @return $this */ - protected function setSubject(string $subject) + protected function setSubject(string $subject): static { $this->subject = $subject; return $this; @@ -419,10 +354,9 @@ class Email /** * Sets the recipients of the email * - * @param string|array $to * @return $this */ - protected function setTo($to) + protected function setTo(string|array $to): static { $this->to = $this->resolveEmail($to); return $this; @@ -431,10 +365,9 @@ class Email /** * Sets the email transport settings * - * @param array|null $transport * @return $this */ - protected function setTransport($transport = null) + protected function setTransport(array|null $transport = null): static { $this->transport = $transport; return $this; @@ -442,8 +375,6 @@ class Email /** * Returns the email subject - * - * @return string */ public function subject(): string { @@ -452,8 +383,6 @@ class Email /** * Returns the email recipients - * - * @return array */ public function to(): array { @@ -462,8 +391,6 @@ class Email /** * Returns the email transports settings - * - * @return array */ public function transport(): array { diff --git a/kirby/src/Email/PHPMailer.php b/kirby/src/Email/PHPMailer.php index 17f89cf..ee84a40 100644 --- a/kirby/src/Email/PHPMailer.php +++ b/kirby/src/Email/PHPMailer.php @@ -2,6 +2,7 @@ namespace Kirby\Email; +use Closure; use Kirby\Exception\InvalidArgumentException; use PHPMailer\PHPMailer\PHPMailer as Mailer; @@ -20,8 +21,6 @@ class PHPMailer extends Email /** * Sends email via PHPMailer library * - * @param bool $debug - * @return bool * @throws \Kirby\Exception\InvalidArgumentException */ public function send(bool $debug = false): bool @@ -96,10 +95,10 @@ class PHPMailer extends Email // accessible phpMailer instance $beforeSend = $this->beforeSend(); - if (empty($beforeSend) === false && is_a($beforeSend, 'Closure') === true) { + if ($beforeSend instanceof Closure) { $mailer = $beforeSend->call($this, $mailer) ?? $mailer; - if (is_a($mailer, 'PHPMailer\PHPMailer\PHPMailer') === false) { + if ($mailer instanceof Mailer === false) { throw new InvalidArgumentException('"beforeSend" option return should be instance of PHPMailer\PHPMailer\PHPMailer class'); } } diff --git a/kirby/src/Field/FieldOptions.php b/kirby/src/Field/FieldOptions.php new file mode 100644 index 0000000..feef4c4 --- /dev/null +++ b/kirby/src/Field/FieldOptions.php @@ -0,0 +1,93 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + */ +class FieldOptions extends Node +{ + public function __construct( + public Options|OptionsApi|OptionsQuery|null $options = null + ) { + } + + public function defaults(): static + { + $this->options ??= new Options(); + + return parent::defaults(); + } + + public static function factory(array $props): static + { + $options = match ($props['type']) { + 'api' => OptionsApi::factory($props), + 'query' => OptionsQuery::factory($props), + default => Options::factory($props['options'] ?? []) + }; + + return new static($options); + } + + public static function polyfill(array $props = []): array + { + if (is_string($props['options'] ?? null) === true) { + $props['options'] = match ($props['options']) { + 'api' => ['type' => 'api'] + + OptionsApi::polyfill($props['api'] ?? null), + + 'query' => ['type' => 'query'] + + OptionsQuery::polyfill($props['query'] ?? null), + + default => [ 'type' => 'query', 'query' => $props['options']] + }; + } + + unset($props['api'], $props['query']); + + if (($props['options']['type'] ?? null) !== null) { + return $props; + } + + if (($props['options'] ?? null) !== null) { + $props['options'] = [ + 'type' => 'array', + 'options' => $props['options'] + ]; + } + + return $props; + } + + public function resolve(ModelWithContent $model): Options + { + // apply default values + $this->defaults(); + + // already Options, return + if (is_a($this->options, Options::class) === true) { + return $this->options; + } + + // resolve OptionsApi or OptionsQuery to Options + return $this->options = $this->options->resolve($model); + } + + public function render(ModelWithContent $model): array + { + return $this->resolve($model)->render($model); + } +} diff --git a/kirby/src/Filesystem/Asset.php b/kirby/src/Filesystem/Asset.php index cd6488b..cd1e699 100644 --- a/kirby/src/Filesystem/Asset.php +++ b/kirby/src/Filesystem/Asset.php @@ -23,15 +23,11 @@ class Asset /** * Relative file path - * - * @var string */ - protected $path; + protected string|null $path = null; /** * Creates a new Asset object for the given path. - * - * @param string $path */ public function __construct(string $path) { @@ -44,8 +40,6 @@ class Asset /** * Returns a unique id for the asset - * - * @return string */ public function id(): string { @@ -54,8 +48,6 @@ class Asset /** * Create a unique media hash - * - * @return string */ public function mediaHash(): string { @@ -64,8 +56,6 @@ class Asset /** * Returns the relative path starting at the media folder - * - * @return string */ public function mediaPath(): string { @@ -74,8 +64,6 @@ class Asset /** * Returns the absolute path to the file in the public media folder - * - * @return string */ public function mediaRoot(): string { @@ -84,8 +72,6 @@ class Asset /** * Returns the absolute Url to the file in the public media folder - * - * @return string */ public function mediaUrl(): string { @@ -95,8 +81,6 @@ class Asset /** * Returns the path of the file from the web root, * excluding the filename - * - * @return string */ public function path(): string { @@ -106,10 +90,9 @@ class Asset /** * Setter for the path * - * @param string $path * @return $this */ - protected function setPath(string $path) + protected function setPath(string $path): static { $this->path = $path === '.' ? '' : $path; return $this; diff --git a/kirby/src/Filesystem/Dir.php b/kirby/src/Filesystem/Dir.php index 8207efc..5938153 100644 --- a/kirby/src/Filesystem/Dir.php +++ b/kirby/src/Filesystem/Dir.php @@ -4,6 +4,7 @@ namespace Kirby\Filesystem; use Exception; use Kirby\Cms\App; +use Kirby\Cms\Helpers; use Kirby\Cms\Page; use Kirby\Toolkit\Str; use Throwable; @@ -30,10 +31,8 @@ class Dir { /** * Ignore when scanning directories - * - * @var array */ - public static $ignore = [ + public static array $ignore = [ '.', '..', '.DS_Store', @@ -45,19 +44,17 @@ class Dir '@eaDir' ]; - public static $numSeparator = '_'; + public static string $numSeparator = '_'; /** * Copy the directory to a new destination - * - * @param string $dir - * @param string $target - * @param bool $recursive - * @param array $ignore - * @return bool */ - public static function copy(string $dir, string $target, bool $recursive = true, array $ignore = []): bool - { + public static function copy( + string $dir, + string $target, + bool $recursive = true, + array $ignore = [] + ): bool { if (is_dir($dir) === false) { throw new Exception('The directory "' . $dir . '" does not exist'); } @@ -91,15 +88,14 @@ class Dir /** * Get all subdirectories - * - * @param string $dir - * @param array $ignore - * @param bool $absolute - * @return array */ - public static function dirs(string $dir, array $ignore = null, bool $absolute = false): array - { - $result = array_values(array_filter(static::read($dir, $ignore, true), 'is_dir')); + public static function dirs( + string $dir, + array|null $ignore = null, + bool $absolute = false + ): array { + $scan = static::read($dir, $ignore, true); + $result = array_values(array_filter($scan, 'is_dir')); if ($absolute !== true) { $result = array_map('basename', $result); @@ -110,9 +106,6 @@ class Dir /** * Checks if the directory exists on disk - * - * @param string $dir - * @return bool */ public static function exists(string $dir): bool { @@ -121,15 +114,14 @@ class Dir /** * Get all files - * - * @param string $dir - * @param array $ignore - * @param bool $absolute - * @return array */ - public static function files(string $dir, array $ignore = null, bool $absolute = false): array - { - $result = array_values(array_filter(static::read($dir, $ignore, true), 'is_file')); + public static function files( + string $dir, + array|null $ignore = null, + bool $absolute = false + ): array { + $scan = static::read($dir, $ignore, true); + $result = array_values(array_filter($scan, 'is_file')); if ($absolute !== true) { $result = array_map('basename', $result); @@ -140,15 +132,13 @@ class Dir /** * Read the directory and all subdirectories - * - * @param string $dir - * @param bool $recursive - * @param array $ignore - * @param string $path - * @return array */ - public static function index(string $dir, bool $recursive = false, array $ignore = null, string $path = null) - { + public static function index( + string $dir, + bool $recursive = false, + array|null $ignore = null, + string $path = null + ): array { $result = []; $dir = realpath($dir); $items = static::read($dir); @@ -168,9 +158,6 @@ class Dir /** * Checks if the folder has any contents - * - * @param string $dir - * @return bool */ public static function isEmpty(string $dir): bool { @@ -179,9 +166,6 @@ class Dir /** * Checks if the directory is readable - * - * @param string $dir - * @return bool */ public static function isReadable(string $dir): bool { @@ -190,9 +174,6 @@ class Dir /** * Checks if the directory is writable - * - * @param string $dir - * @return bool */ public static function isWritable(string $dir): bool { @@ -209,15 +190,13 @@ class Dir * Don't use outside the Cms context. * * @internal - * - * @param string $dir - * @param string $contentExtension - * @param array|null $contentIgnore - * @param bool $multilang - * @return array */ - public static function inventory(string $dir, string $contentExtension = 'txt', array $contentIgnore = null, bool $multilang = false): array - { + public static function inventory( + string $dir, + string $contentExtension = 'txt', + array|null $contentIgnore = null, + bool $multilang = false + ): array { $dir = realpath($dir); $inventory = [ @@ -304,10 +283,6 @@ class Dir * Take all content files, * remove those who are meta files and * detect the main content file - * - * @param array $inventory - * @param array $content - * @return array */ protected static function inventoryContent(array $inventory, array $content): array { @@ -333,16 +308,17 @@ class Dir /** * Go through all inventory children * and inject a model for each - * - * @param array $inventory - * @param string $contentExtension - * @param bool $multilang - * @return array */ - protected static function inventoryModels(array $inventory, string $contentExtension, bool $multilang = false): array - { + protected static function inventoryModels( + array $inventory, + string $contentExtension, + bool $multilang = false + ): array { // inject models - if (empty($inventory['children']) === false && empty(Page::$models) === false) { + if ( + empty($inventory['children']) === false && + empty(Page::$models) === false + ) { if ($multilang === true) { $contentExtension = App::instance()->defaultLanguage()->code() . '.' . $contentExtension; } @@ -362,10 +338,6 @@ class Dir /** * Create a (symbolic) link to a directory - * - * @param string $source - * @param string $link - * @return bool */ public static function link(string $source, string $link): bool { @@ -381,7 +353,7 @@ class Dir try { return symlink($source, $link) === true; - } catch (Throwable $e) { + } catch (Throwable) { return false; } } @@ -420,7 +392,13 @@ class Dir throw new Exception(sprintf('The directory "%s" cannot be created', $dir)); } - return mkdir($dir); + return Helpers::handleErrors( + fn (): bool => mkdir($dir), + // if the dir was already created (race condition), + fn (int $errno, string $errstr): bool => Str::endsWith($errstr, 'File exists'), + // consider it a success + true + ); } /** @@ -428,11 +406,8 @@ class Dir * subfolders have been modified for the last time. * * @param string $dir The path of the directory - * @param string $format - * @param string $handler - * @return int|string */ - public static function modified(string $dir, string $format = null, string $handler = 'date') + public static function modified(string $dir, string $format = null, string $handler = 'date'): int|string { $modified = filemtime($dir); $items = static::read($dir); @@ -478,13 +453,14 @@ class Dir * Returns a nicely formatted size of all the contents of the folder * * @param string $dir The path of the directory - * @param string|null|false $locale Locale for number formatting, + * @param string|false|null $locale Locale for number formatting, * `null` for the current locale, * `false` to disable number formatting - * @return mixed */ - public static function niceSize(string $dir, $locale = null) - { + public static function niceSize( + string $dir, + string|false|null $locale = null + ): string { return F::niceSize(static::size($dir), $locale); } @@ -497,8 +473,11 @@ class Dir * @param bool $absolute If true, the full path for each item will be returned * @return array An array of filenames */ - public static function read(string $dir, array $ignore = null, bool $absolute = false): array - { + public static function read( + string $dir, + array|null $ignore = null, + bool $absolute = false + ): array { if (is_dir($dir) === false) { return []; } @@ -520,9 +499,6 @@ class Dir /** * Removes a folder including all containing files and folders - * - * @param string $dir - * @return bool */ public static function remove(string $dir): bool { @@ -558,9 +534,8 @@ class Dir * * @param string $dir The path of the directory * @param bool $recursive Include all subfolders and their files - * @return mixed */ - public static function size(string $dir, bool $recursive = true) + public static function size(string $dir, bool $recursive = true): int|false { if (is_dir($dir) === false) { return false; @@ -582,10 +557,6 @@ class Dir /** * Checks if the directory or any subdirectory has been * modified after the given timestamp - * - * @param string $dir - * @param int $time - * @return bool */ public static function wasModifiedAfter(string $dir, int $time): bool { diff --git a/kirby/src/Filesystem/F.php b/kirby/src/Filesystem/F.php index 5481242..5cc5bb3 100644 --- a/kirby/src/Filesystem/F.php +++ b/kirby/src/Filesystem/F.php @@ -3,7 +3,9 @@ namespace Kirby\Filesystem; use Exception; +use IntlDateFormatter; use Kirby\Cms\Helpers; +use Kirby\Http\Response; use Kirby\Toolkit\I18n; use Kirby\Toolkit\Str; use Throwable; @@ -23,10 +25,7 @@ use ZipArchive; */ class F { - /** - * @var array - */ - public static $types = [ + public static array $types = [ 'archive' => [ 'gz', 'gzip', @@ -111,17 +110,23 @@ class F ], ]; - /** - * @var array - */ - public static $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB']; + public static array $units = [ + 'B', + 'KB', + 'MB', + 'GB', + 'TB', + 'PB', + 'EB', + 'ZB', + 'YB' + ]; /** * Appends new content to an existing file * * @param string $file The path for the file * @param mixed $content Either a string or an array. Arrays will be converted to JSON. - * @return bool */ public static function append(string $file, $content): bool { @@ -132,7 +137,6 @@ class F * Returns the file content as base64 encoded string * * @param string $file The path for the file - * @return string */ public static function base64(string $file): string { @@ -141,11 +145,6 @@ class F /** * Copy a file to a new location. - * - * @param string $source - * @param string $target - * @param bool $force - * @return bool */ public static function copy(string $source, string $target, bool $force = false): bool { @@ -174,7 +173,6 @@ class F * * * @param string $file The path - * @return string */ public static function dirname(string $file): string { @@ -183,17 +181,13 @@ class F /** * Checks if the file exists on disk - * - * @param string $file - * @param string $in - * @return bool */ - public static function exists(string $file, string $in = null): bool + public static function exists(string $file, string|null $in = null): bool { try { static::realpath($file, $in); return true; - } catch (Exception $e) { + } catch (Exception) { return false; } } @@ -201,12 +195,13 @@ class F /** * Gets the extension of a file * - * @param string $file The filename or path - * @param string $extension Set an optional extension to overwrite the current one - * @return string + * @param string|null $file The filename or path + * @param string|null $extension Set an optional extension to overwrite the current one */ - public static function extension(string $file = null, string $extension = null): string - { + public static function extension( + string|null $file = null, + string|null $extension = null + ): string { // overwrite the current extension if ($extension !== null) { return static::name($file) . '.' . $extension; @@ -218,22 +213,16 @@ class F /** * Converts a file extension to a mime type - * - * @param string $extension - * @return string|false */ - public static function extensionToMime(string $extension) + public static function extensionToMime(string $extension): string|null { return Mime::fromExtension($extension); } /** * Returns the file type for a passed extension - * - * @param string $extension - * @return string|false */ - public static function extensionToType(string $extension) + public static function extensionToType(string $extension): string|false { foreach (static::$types as $type => $extensions) { if (in_array($extension, $extensions) === true) { @@ -246,11 +235,8 @@ class F /** * Returns all extensions for a certain file type - * - * @param string $type - * @return array */ - public static function extensions(string $type = null) + public static function extensions(string|null $type = null): array { if ($type === null) { return array_keys(Mime::types()); @@ -270,7 +256,6 @@ class F * * * @param string $name The path - * @return string */ public static function filename(string $name): string { @@ -281,15 +266,17 @@ class F * Invalidate opcode cache for file. * * @param string $file The path of the file - * @return bool */ public static function invalidateOpcodeCache(string $file): bool { - if (function_exists('opcache_invalidate') && strlen(ini_get('opcache.restrict_api')) === 0) { + if ( + function_exists('opcache_invalidate') && + strlen(ini_get('opcache.restrict_api')) === 0 + ) { return opcache_invalidate($file, true); - } else { - return false; } + + return false; } /** @@ -297,7 +284,6 @@ class F * * @param string $file Full path to the file * @param string $value An extension or mime type - * @return bool */ public static function is(string $file, string $value): bool { @@ -316,9 +302,6 @@ class F /** * Checks if the file is readable - * - * @param string $file - * @return bool */ public static function isReadable(string $file): bool { @@ -327,9 +310,6 @@ class F /** * Checks if the file is writable - * - * @param string $file - * @return bool */ public static function isWritable(string $file): bool { @@ -342,11 +322,6 @@ class F /** * Create a (symbolic) link to a file - * - * @param string $source - * @param string $link - * @param string $method - * @return bool */ public static function link(string $source, string $link, string $method = 'link'): bool { @@ -362,7 +337,7 @@ class F try { return $method($source, $link) === true; - } catch (Throwable $e) { + } catch (Throwable) { return false; } } @@ -371,13 +346,14 @@ class F * Loads a file and returns the result or `false` if the * file to load does not exist * - * @param string $file - * @param mixed $fallback * @param array $data Optional array of variables to extract in the variable scope - * @return mixed */ - public static function load(string $file, $fallback = null, array $data = []) - { + public static function load( + string $file, + mixed $fallback = null, + array $data = [], + bool $allowOutput = true + ) { if (is_file($file) === false) { return $fallback; } @@ -385,9 +361,21 @@ class F // we use the loadIsolated() method here to prevent the included // file from overwriting our $fallback in this variable scope; see // https://www.php.net/manual/en/function.include.php#example-124 - $result = static::loadIsolated($file, $data); + $callback = fn () => static::loadIsolated($file, $data); - if ($fallback !== null && gettype($result) !== gettype($fallback)) { + // if the loaded file should not produce any output, + // call the loaidIsolated method from the Response class + // which checks for unintended ouput and throws an error if detected + if ($allowOutput === false) { + $result = Response::guardAgainstOutput($callback); + } else { + $result = $callback(); + } + + if ( + $fallback !== null && + gettype($result) !== gettype($fallback) + ) { return $fallback; } @@ -397,37 +385,35 @@ class F /** * A super simple class autoloader * @since 3.7.0 - * - * @param array $classmap - * @param string|null $base - * @return void */ - public static function loadClasses(array $classmap, ?string $base = null): void - { + public static function loadClasses( + array $classmap, + string|null $base = null + ): void { // convert all classnames to lowercase $classmap = array_change_key_case($classmap); - spl_autoload_register(function ($class) use ($classmap, $base) { - $class = strtolower($class); + spl_autoload_register( + fn ($class) => Response::guardAgainstOutput(function () use ($class, $classmap, $base) { + $class = strtolower($class); - if (!isset($classmap[$class])) { - return false; - } + if (isset($classmap[$class]) === false) { + return false; + } - if ($base) { - include $base . '/' . $classmap[$class]; - } else { - include $classmap[$class]; - } - }); + if ($base) { + include $base . '/' . $classmap[$class]; + } else { + include $classmap[$class]; + } + }) + ); } /** * Loads a file with as little as possible in the variable scope * - * @param string $file * @param array $data Optional array of variables to extract in the variable scope - * @return mixed */ protected static function loadIsolated(string $file, array $data = []) { @@ -440,50 +426,48 @@ class F } /** - * Loads a file using `include_once()` and returns whether loading was successful - * - * @param string $file - * @return bool + * Loads a file using `include_once()` and + * returns whether loading was successful */ - public static function loadOnce(string $file): bool - { + public static function loadOnce( + string $file, + bool $allowOutput = true + ): bool { if (is_file($file) === false) { return false; } - include_once $file; + $callback = fn () => include_once $file; + + if ($allowOutput === false) { + Response::guardAgainstOutput($callback); + } else { + $callback(); + } + return true; } /** * Returns the mime type of a file - * - * @param string $file - * @return string|false */ - public static function mime(string $file) + public static function mime(string $file): string|null { return Mime::type($file); } /** * Converts a mime type to a file extension - * - * @param string $mime - * @return string|false */ - public static function mimeToExtension(string $mime = null) + public static function mimeToExtension(string|null $mime = null): string|false { return Mime::toExtension($mime); } /** * Returns the type for a given mime - * - * @param string $mime - * @return string|false */ - public static function mimeToType(string $mime) + public static function mimeToType(string $mime): string|false { return static::extensionToType(Mime::toExtension($mime)); } @@ -491,13 +475,13 @@ class F /** * Get the file's last modification time. * - * @param string $file - * @param string|\IntlDateFormatter|null $format * @param string $handler date, intl or strftime - * @return mixed */ - public static function modified(string $file, $format = null, string $handler = 'date') - { + public static function modified( + string $file, + string|IntlDateFormatter|null $format = null, + string $handler = 'date' + ): string|int|false { if (file_exists($file) !== true) { return false; } @@ -513,7 +497,6 @@ class F * @param string $oldRoot The current path for the file * @param string $newRoot The path to the new location * @param bool $force Force move if the target file exists - * @return bool */ public static function move(string $oldRoot, string $newRoot, bool $force = false): bool { @@ -543,7 +526,6 @@ class F * Extracts the name from a file path or filename without extension * * @param string $name The path or filename - * @return string */ public static function name(string $name): string { @@ -553,14 +535,15 @@ class F /** * Converts an integer size into a human readable format * - * @param mixed $size The file size, a file path or array of paths - * @param string|null|false $locale Locale for number formatting, + * @param int|string|array $size The file size, a file path or array of paths + * @param string|false|null $locale Locale for number formatting, * `null` for the current locale, * `false` to disable number formatting - * @return string */ - public static function niceSize($size, $locale = null): string - { + public static function niceSize( + int|string|array $size, + string|false|null $locale = null + ): string { // file mode if (is_string($size) === true || is_array($size) === true) { $size = static::size($size); @@ -590,31 +573,27 @@ class F * contents of a remote HTTP or HTTPS URL * * @param string $file The path for the file or an absolute URL - * @return string|false */ - public static function read(string $file) + public static function read(string $file): string|false { if ( - is_file($file) !== true && + is_readable($file) !== true && Str::startsWith($file, 'https://') !== true && Str::startsWith($file, 'http://') !== true ) { return false; } - return @file_get_contents($file); + return file_get_contents($file); } /** * Changes the name of the file without * touching the extension * - * @param string $file - * @param string $newName * @param bool $overwrite Force overwrite existing files - * @return string|false */ - public static function rename(string $file, string $newName, bool $overwrite = false) + public static function rename(string $file, string $newName, bool $overwrite = false): string|false { // create the new name $name = static::safeName(basename($newName)); @@ -636,12 +615,8 @@ class F /** * Returns the absolute path to the file if the file can be found. - * - * @param string $file - * @param string $in - * @return string|null */ - public static function realpath(string $file, string $in = null) + public static function realpath(string $file, string|null $in = null): string { $realpath = realpath($file); @@ -669,12 +644,8 @@ class F * starting after $in * * @SuppressWarnings(PHPMD.CountInLoopExpression) - * - * @param string $file - * @param string $in - * @return string */ - public static function relativepath(string $file, string $in = null): string + public static function relativepath(string $file, string|null $in = null): string { if (empty($in) === true) { return basename($file); @@ -715,7 +686,6 @@ class F * * * @param string $file The path for the file - * @return bool */ public static function remove(string $file): bool { @@ -746,7 +716,6 @@ class F * * * @param string $string The file name - * @return string */ public static function safeName(string $string): string { @@ -761,10 +730,6 @@ class F /** * Tries to find similar or the same file by * building a glob based on the path - * - * @param string $path - * @param string $pattern - * @return array */ public static function similar(string $path, string $pattern = '*'): array { @@ -779,9 +744,8 @@ class F * Returns the size of a file or an array of files. * * @param string|array $file file path or array of paths - * @return int */ - public static function size($file): int + public static function size(string|array $file): int { if (is_array($file) === true) { return array_reduce( @@ -793,7 +757,7 @@ class F try { return filesize($file); - } catch (Throwable $e) { + } catch (Throwable) { return 0; } } @@ -802,9 +766,8 @@ class F * Categorize the file * * @param string $file Either the file path or extension - * @return string|null */ - public static function type(string $file) + public static function type(string $file): string|null { $length = strlen($file); @@ -837,11 +800,8 @@ class F /** * Returns all extensions of a given file type * or `null` if the file type is unknown - * - * @param string $type - * @return array|null */ - public static function typeToExtensions(string $type): ?array + public static function typeToExtensions(string $type): array|null { return static::$types[$type] ?? null; } @@ -854,28 +814,15 @@ class F { return Helpers::handleErrors( fn (): bool => unlink($file), - function (&$override, int $errno, string $errstr): bool { - // if the file or link was already deleted (race condition), - // consider it a success - if (Str::endsWith($errstr, 'No such file or directory') === true) { - $override = true; - - // drop the warning - return true; - } - - // handle every other warning normally - return false; - } + // if the file or link was already deleted (race condition), + fn (int $errno, string $errstr): bool => Str::endsWith($errstr, 'No such file or directory'), + // consider it a success + true ); } /** * Unzips a zip file - * - * @param string $file - * @param string $to - * @return bool */ public static function unzip(string $file, string $to): bool { @@ -898,9 +845,8 @@ class F * Returns the file as data uri * * @param string $file The path for the file - * @return string|false */ - public static function uri(string $file) + public static function uri(string $file): string|false { if ($mime = static::mime($file)) { return 'data:' . $mime . ';base64,' . static::base64($file); @@ -915,7 +861,6 @@ class F * @param string $file The path for the new file * @param mixed $content Either a string, an object or an array. Arrays and objects will be serialized. * @param bool $append true: append the content to an existing file if available. false: overwrite. - * @return bool */ public static function write(string $file, $content, bool $append = false): bool { diff --git a/kirby/src/Filesystem/File.php b/kirby/src/Filesystem/File.php index 89cffbb..6c23a6e 100644 --- a/kirby/src/Filesystem/File.php +++ b/kirby/src/Filesystem/File.php @@ -2,8 +2,10 @@ namespace Kirby\Filesystem; +use IntlDateFormatter; use Kirby\Cms\App; use Kirby\Exception\Exception; +use Kirby\Exception\InvalidArgumentException; use Kirby\Http\Response; use Kirby\Sane\Sane; use Kirby\Toolkit\Escape; @@ -28,25 +30,25 @@ class File use Properties; /** - * Absolute file path - * - * @var string + * Parent file model + * The model object must use the `\Kirby\Filesystem\IsFile` trait */ - protected $root; + protected object|null $model = null; + + /** + * Absolute file path + */ + protected string|null $root = null; /** * Absolute file URL - * - * @var string|null */ - protected $url; + protected string|null $url = null; /** * Validation rules to be used for `::match()` - * - * @var array */ - public static $validations = [ + public static array $validations = [ 'maxsize' => ['size', 'max'], 'minsize' => ['size', 'min'] ]; @@ -57,8 +59,10 @@ class File * @param array|string|null $props Properties or deprecated `$root` string * @param string|null $url Deprecated argument, use `$props['url']` instead */ - public function __construct($props = null, string $url = null) - { + public function __construct( + array|string|null $props = null, + string|null $url = null + ) { // Legacy support for old constructor of // the `Kirby\Image\Image` class // @todo 4.0.0 remove @@ -74,8 +78,6 @@ class File /** * Improved `var_dump` output - * - * @return array */ public function __debugInfo(): array { @@ -84,8 +86,6 @@ class File /** * Returns the URL for the file object - * - * @return string */ public function __toString(): string { @@ -94,8 +94,6 @@ class File /** * Returns the file content as base64 encoded string - * - * @return string */ public function base64(): string { @@ -104,15 +102,11 @@ class File /** * Copy a file to a new location. - * - * @param string $target - * @param bool $force - * @return static */ - public function copy(string $target, bool $force = false) + public function copy(string $target, bool $force = false): static { - if (F::copy($this->root, $target, $force) !== true) { - throw new Exception('The file "' . $this->root . '" could not be copied'); + if (F::copy($this->root(), $target, $force) !== true) { + throw new Exception('The file "' . $this->root() . '" could not be copied'); } return new static($target); @@ -122,7 +116,6 @@ class File * Returns the file as data uri * * @param bool $base64 Whether the data should be base64 encoded or not - * @return string */ public function dataUri(bool $base64 = true): string { @@ -135,77 +128,64 @@ class File /** * Deletes the file - * - * @return bool */ public function delete(): bool { - if (F::remove($this->root) !== true) { - throw new Exception('The file "' . $this->root . '" could not be deleted'); + if (F::remove($this->root()) !== true) { + throw new Exception('The file "' . $this->root() . '" could not be deleted'); } return true; } /* - * Automatically sends all needed headers for the file to be downloaded - * and echos the file's content + * Automatically sends all needed headers + * for the file to be downloaded and + * echos the file's content * * @param string|null $filename Optional filename for the download - * @return string */ - public function download($filename = null): string + public function download(string|null $filename = null): string { - return Response::download($this->root, $filename ?? $this->filename()); + return Response::download($this->root(), $filename ?? $this->filename()); } /** * Checks if the file actually exists - * - * @return bool */ public function exists(): bool { - return file_exists($this->root) === true; + return file_exists($this->root()) === true; } /** * Returns the current lowercase extension (without .) - * - * @return string */ public function extension(): string { - return F::extension($this->root); + return F::extension($this->root()); } /** * Returns the filename - * - * @return string */ public function filename(): string { - return basename($this->root); + return basename($this->root()); } /** * Returns a md5 hash of the root - * - * @return string */ public function hash(): string { - return md5($this->root); + return md5($this->root()); } /** * Sends an appropriate header for the asset - * - * @param bool $send - * @return \Kirby\Http\Response|void */ - public function header(bool $send = true) + public function header(bool $send = true): Response|null { $response = new Response('', $this->mime()); @@ -214,13 +194,11 @@ class File } $response->send(); + return null; } /** * Converts the file to html - * - * @param array $attr - * @return string */ public function html(array $attr = []): string { @@ -231,27 +209,22 @@ class File * Checks if a file is of a certain type * * @param string $value An extension or mime type - * @return bool */ public function is(string $value): bool { - return F::is($this->root, $value); + return F::is($this->root(), $value); } /** * Checks if the file is readable - * - * @return bool */ public function isReadable(): bool { - return is_readable($this->root) === true; + return is_readable($this->root()) === true; } /** * Checks if the file is a resizable image - * - * @return bool */ public function isResizable(): bool { @@ -261,8 +234,6 @@ class File /** * Checks if a preview can be displayed for the file * in the panel or in the frontend - * - * @return bool */ public function isViewable(): bool { @@ -271,20 +242,16 @@ class File /** * Checks if the file is writable - * - * @return bool */ public function isWritable(): bool { - return F::isWritable($this->root); + return F::isWritable($this->root()); } /** * Returns the app instance if it exists - * - * @return \Kirby\Cms\App|null */ - public function kirby() + public function kirby(): App|null { return App::instance(null, true); } @@ -293,8 +260,6 @@ class File * Runs a set of validations on the file object * (mainly for images). * - * @param array $rules - * @return bool * @throws \Kirby\Exception\Exception */ public function match(array $rules): bool @@ -361,27 +326,33 @@ class File /** * Detects the mime type of the file - * - * @return string|null */ - public function mime() + public function mime(): string|null { - return Mime::type($this->root); + return Mime::type($this->root()); + } + + /** + * Returns the parent file model, which uses this instance as proxied file asset + */ + public function model(): object|null + { + return $this->model; } /** * Returns the file's last modification time * - * @param string|\IntlDateFormatter|null $format * @param string|null $handler date, intl or strftime - * @return mixed */ - public function modified($format = null, ?string $handler = null) - { + public function modified( + string|IntlDateFormatter|null $format = null, + string|null $handler = null + ): string|int|false { $kirby = $this->kirby(); return F::modified( - $this->root, + $this->root(), $format, $handler ?? ($kirby ? $kirby->option('date.handler', 'date') : 'date') ); @@ -390,14 +361,12 @@ class File /** * Move the file to a new location * - * @param string $newRoot * @param bool $overwrite Force overwriting any existing files - * @return static */ - public function move(string $newRoot, bool $overwrite = false) + public function move(string $newRoot, bool $overwrite = false): static { - if (F::move($this->root, $newRoot, $overwrite) !== true) { - throw new Exception('The file: "' . $this->root . '" could not be moved to: "' . $newRoot . '"'); + if (F::move($this->root(), $newRoot, $overwrite) !== true) { + throw new Exception('The file: "' . $this->root() . '" could not be moved to: "' . $newRoot . '"'); } return new static($newRoot); @@ -406,62 +375,53 @@ class File /** * Getter for the name of the file * without the extension - * - * @return string */ public function name(): string { - return pathinfo($this->root, PATHINFO_FILENAME); + return pathinfo($this->root(), PATHINFO_FILENAME); } /** * Returns the file size in a * human-readable format * - * @param string|null|false $locale Locale for number formatting, + * @param string|false|null $locale Locale for number formatting, * `null` for the current locale, * `false` to disable number formatting - * @return string */ - public function niceSize($locale = null): string + public function niceSize(string|false|null $locale = null): string { - return F::niceSize($this->root, $locale); + return F::niceSize($this->root(), $locale); } /** * Reads the file content and returns it. - * - * @return string|false */ - public function read() + public function read(): string|false { - return F::read($this->root); + return F::read($this->root()); } /** * Returns the absolute path to the file - * - * @return string */ public function realpath(): string { - return realpath($this->root); + return realpath($this->root()); } /** * Changes the name of the file without * touching the extension * - * @param string $newName * @param bool $overwrite Force overwrite existing files - * @return static */ - public function rename(string $newName, bool $overwrite = false) + public function rename(string $newName, bool $overwrite = false): static { - $newRoot = F::rename($this->root, $newName, $overwrite); + $newRoot = F::rename($this->root(), $newName, $overwrite); if ($newRoot === false) { - throw new Exception('The file: "' . $this->root . '" could not be renamed to: "' . $newName . '"'); + throw new Exception('The file: "' . $this->root() . '" could not be renamed to: "' . $newName . '"'); } return new static($newRoot); @@ -469,21 +429,35 @@ class File /** * Returns the given file path - * - * @return string|null */ - public function root(): ?string + public function root(): string|null { - return $this->root; + return $this->root ??= $this->model?->root(); + } + + /** + * Setter for the parent file model, which uses this instance as proxied file asset + * + * @return $this + * + * @throws \Kirby\Exception\InvalidArgumentException When the model does not use the `Kirby\Filesystem\IsFile` trait + */ + protected function setModel(object|null $model = null): static + { + if ($model !== null && method_exists($model, 'hasIsFileTrait') !== true) { + throw new InvalidArgumentException('The model object must use the "Kirby\Filesystem\IsFile" trait'); + } + + $this->model = $model; + return $this; } /** * Setter for the root * - * @param string|null $root * @return $this */ - protected function setRoot(?string $root = null) + protected function setRoot(string|null $root = null): static { $this->root = $root; return $this; @@ -492,10 +466,9 @@ class File /** * Setter for the file url * - * @param string|null $url * @return $this */ - protected function setUrl(?string $url = null) + protected function setUrl(string|null $url = null): static { $this->url = $url; return $this; @@ -503,12 +476,13 @@ class File /** * Returns the absolute url for the file - * - * @return string|null */ - public function url(): ?string + public function url(): string|null { - return $this->url; + // lazily determine the URL from the model object + // only if it's needed to avoid breaking custom file::url + // components that rely on `$cmsFile->asset()` methods + return $this->url ??= $this->model?->url(); } /** @@ -519,14 +493,13 @@ class File * @param string|bool $typeLazy Explicit sane handler type string, * `true` for lazy autodetection or * `false` for normal autodetection - * @return void * * @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation * @throws \Kirby\Exception\LogicException If more than one handler applies * @throws \Kirby\Exception\NotFoundException If the handler was not found * @throws \Kirby\Exception\Exception On other errors */ - public function sanitizeContents($typeLazy = false): void + public function sanitizeContents(string|bool $typeLazy = false): void { Sane::sanitizeFile($this->root(), $typeLazy); } @@ -534,29 +507,23 @@ class File /** * Returns the sha1 hash of the file * @since 3.6.0 - * - * @return string */ public function sha1(): string { - return sha1_file($this->root); + return sha1_file($this->root()); } /** * Returns the raw size of the file - * - * @return int */ public function size(): int { - return F::size($this->root); + return F::size($this->root()); } /** * Converts the media object to a * plain PHP array - * - * @return array */ public function toArray(): array { @@ -582,8 +549,6 @@ class File /** * Converts the entire file array into * a json string - * - * @return string */ public function toJson(): string { @@ -592,12 +557,10 @@ class File /** * Returns the file type. - * - * @return string|null */ - public function type(): ?string + public function type(): string|null { - return F::type($this->root); + return F::type($this->root()); } /** @@ -606,27 +569,23 @@ class File * @param string|bool $typeLazy Explicit sane handler type string, * `true` for lazy autodetection or * `false` for normal autodetection - * @return void * * @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation * @throws \Kirby\Exception\NotFoundException If the handler was not found * @throws \Kirby\Exception\Exception On other errors */ - public function validateContents($typeLazy = false): void + public function validateContents(string|bool $typeLazy = false): void { Sane::validateFile($this->root(), $typeLazy); } /** * Writes content to the file - * - * @param string $content - * @return bool */ - public function write($content): bool + public function write(string $content): bool { - if (F::write($this->root, $content) !== true) { - throw new Exception('The file "' . $this->root . '" could not be written'); + if (F::write($this->root(), $content) !== true) { + throw new Exception('The file "' . $this->root() . '" could not be written'); } return true; diff --git a/kirby/src/Filesystem/Filename.php b/kirby/src/Filesystem/Filename.php index f97de71..ba817c1 100644 --- a/kirby/src/Filesystem/Filename.php +++ b/kirby/src/Filesystem/Filename.php @@ -30,45 +30,31 @@ class Filename { /** * List of all applicable attributes - * - * @var array */ - protected $attributes; + protected array $attributes; /** * The sanitized file extension - * - * @var string */ - protected $extension; + protected string $extension; /** * The source original filename - * - * @var string */ - protected $filename; + protected string $filename; /** * The sanitized file name - * - * @var string */ - protected $name; + protected string $name; /** * The template for the final name - * - * @var string */ - protected $template; + protected string $template; /** * Creates a new Filename object - * - * @param string $filename - * @param string $template - * @param array $attributes */ public function __construct(string $filename, string $template, array $attributes = []) { @@ -84,8 +70,6 @@ class Filename /** * Converts the entire object to a string - * - * @return string */ public function __toString(): string { @@ -96,8 +80,6 @@ class Filename * Converts all processed attributes * to an array. The array keys are already * the shortened versions for the filename - * - * @return array */ public function attributesToArray(): array { @@ -123,9 +105,8 @@ class Filename * new filename * * @param string|null $prefix The prefix will be used in the filename creation - * @return string */ - public function attributesToString(string $prefix = null): string + public function attributesToString(string|null $prefix = null): string { $array = $this->attributesToArray(); $result = []; @@ -135,16 +116,11 @@ class Filename $value = ''; } - switch ($key) { - case 'dimensions': - $result[] = $value; - break; - case 'crop': - $result[] = ($value === 'center') ? 'crop' : $key . '-' . $value; - break; - default: - $result[] = $key . $value; - } + $result[] = match ($key) { + 'dimensions' => $value, + 'crop' => ($value === 'center') ? 'crop' : $key . '-' . $value, + default => $key . $value + }; } $result = array_filter($result); @@ -159,10 +135,8 @@ class Filename /** * Normalizes the blur option value - * - * @return false|int */ - public function blur() + public function blur(): int|false { $value = $this->attributes['blur'] ?? false; @@ -175,10 +149,8 @@ class Filename /** * Normalizes the crop option value - * - * @return false|string */ - public function crop() + public function crop(): string|false { // get the crop value $crop = $this->attributes['crop'] ?? false; @@ -194,10 +166,8 @@ class Filename * Returns a normalized array * with width and height values * if available - * - * @return array */ - public function dimensions() + public function dimensions(): array { if (empty($this->attributes['width']) === true && empty($this->attributes['height']) === true) { return []; @@ -211,8 +181,6 @@ class Filename /** * Returns the sanitized extension - * - * @return string */ public function extension(): string { @@ -225,8 +193,6 @@ class Filename * the option. You can use `grayscale`, * `greyscale` or simply `bw`. The function * will always return `grayscale` - * - * @return bool */ public function grayscale(): bool { @@ -239,8 +205,6 @@ class Filename /** * Returns the filename without extension - * - * @return string */ public function name(): string { @@ -249,10 +213,8 @@ class Filename /** * Normalizes the quality option value - * - * @return false|int */ - public function quality() + public function quality(): int|false { $value = $this->attributes['quality'] ?? false; @@ -268,9 +230,6 @@ class Filename * The extension will be converted * to lowercase and `jpeg` will be * replaced with `jpg` - * - * @param string $extension - * @return string */ protected function sanitizeExtension(string $extension): string { @@ -282,9 +241,6 @@ class Filename /** * Sanitizes the name with Kirby's * Str::slug function - * - * @param string $name - * @return string */ protected function sanitizeName(string $name): string { @@ -293,8 +249,6 @@ class Filename /** * Returns the converted filename as string - * - * @return string */ public function toString(): string { diff --git a/kirby/src/Filesystem/IsFile.php b/kirby/src/Filesystem/IsFile.php index 7e69799..6093238 100644 --- a/kirby/src/Filesystem/IsFile.php +++ b/kirby/src/Filesystem/IsFile.php @@ -26,29 +26,21 @@ trait IsFile /** * File asset object - * - * @var \Kirby\Filesystem\File */ - protected $asset; + protected File|null $asset = null; /** * Absolute file path - * - * @var string|null */ - protected $root; + protected string|null $root = null; /** * Absolute file URL - * - * @var string|null */ - protected $url; + protected string|null $url = null; /** * Constructor sets all file properties - * - * @param array $props */ public function __construct(array $props) { @@ -58,9 +50,6 @@ trait IsFile /** * Magic caller for asset methods * - * @param string $method - * @param array $arguments - * @return mixed * @throws \Kirby\Exception\BadMethodCallException */ public function __call(string $method, array $arguments = []) @@ -80,8 +69,6 @@ trait IsFile /** * Converts the asset to a string - * - * @return string */ public function __toString(): string { @@ -90,33 +77,29 @@ trait IsFile /** * Returns the file asset object - * - * @param array|string|null $props - * @return \Kirby\Filesystem\File */ - public function asset($props = null) + public function asset(array|string|null $props = null): File { if ($this->asset !== null) { return $this->asset; } - $props = $props ?? [ - 'root' => $this->root(), - 'url' => $this->url() - ]; + $props ??= []; - switch ($this->type()) { - case 'image': - return $this->asset = new Image($props); - default: - return $this->asset = new File($props); + if (is_string($props) === true) { + $props = ['root' => $props]; } + + $props['model'] ??= $this; + + return $this->asset = match ($this->type()) { + 'image' => new Image($props), + default => new File($props) + }; } /** * Checks if the file exists on disk - * - * @return bool */ public function exists(): bool { @@ -126,23 +109,29 @@ trait IsFile return file_exists($this->root()) === true; } + /** + * To check the existence of the IsFile trait + * + * @todo Switch to class constant in traits when min PHP version 8.2 required + * @codeCoverageIgnore + */ + protected function hasIsFileTrait(): bool + { + return true; + } /** * Returns the app instance - * - * @return \Kirby\Cms\App */ - public function kirby() + public function kirby(): App { return App::instance(); } /** * Returns the given file path - * - * @return string|null */ - public function root(): ?string + public function root(): string|null { return $this->root; } @@ -150,10 +139,9 @@ trait IsFile /** * Setter for the root * - * @param string|null $root * @return $this */ - protected function setRoot(?string $root = null) + protected function setRoot(string|null $root = null): static { $this->root = $root; return $this; @@ -162,10 +150,9 @@ trait IsFile /** * Setter for the file url * - * @param string|null $url * @return $this */ - protected function setUrl(?string $url = null) + protected function setUrl(string|null $url = null): static { $this->url = $url; return $this; @@ -173,10 +160,8 @@ trait IsFile /** * Returns the file type - * - * @return string|null */ - public function type(): ?string + public function type(): string|null { // Important to include this in the trait // to avoid infinite loops when trying @@ -186,10 +171,8 @@ trait IsFile /** * Returns the absolute url for the file - * - * @return string|null */ - public function url(): ?string + public function url(): string|null { return $this->url; } diff --git a/kirby/src/Filesystem/Mime.php b/kirby/src/Filesystem/Mime.php index ca8b63f..1279101 100644 --- a/kirby/src/Filesystem/Mime.php +++ b/kirby/src/Filesystem/Mime.php @@ -170,7 +170,7 @@ class Mime * @param string $extension * @return string|null */ - public static function fromExtension(string $extension): ?string + public static function fromExtension(string $extension): string|null { $mime = static::$types[$extension] ?? null; return is_array($mime) === true ? array_shift($mime) : $mime; @@ -312,12 +312,8 @@ class Mime /** * Returns the MIME type of a file - * - * @param string $file - * @param string $extension - * @return string|false */ - public static function type(string $file, string $extension = null) + public static function type(string $file, string|null $extension = null): string|null { // use the standard finfo extension $mime = static::fromFileInfo($file); diff --git a/kirby/src/Form/Field.php b/kirby/src/Form/Field.php index 34f4a62..2d1055f 100644 --- a/kirby/src/Form/Field.php +++ b/kirby/src/Form/Field.php @@ -2,6 +2,7 @@ namespace Kirby\Form; +use Closure; use Exception; use Kirby\Exception\InvalidArgumentException; use Kirby\Toolkit\A; @@ -86,7 +87,7 @@ class Field extends Component { if ( isset($this->options['api']) === true && - is_a($this->options['api'], 'Closure') === true + $this->options['api'] instanceof Closure ) { return $this->options['api']->call($this); } @@ -112,7 +113,7 @@ class Field extends Component return null; } - if (is_a($save, 'Closure') === true) { + if ($save instanceof Closure) { return $save->call($this, $value); } @@ -472,7 +473,7 @@ class Field extends Component continue; } - if (is_a($validation, 'Closure') === true) { + if ($validation instanceof Closure) { try { $validation->call($this, $this->value()); } catch (Exception $e) { diff --git a/kirby/src/Form/Field/BlocksField.php b/kirby/src/Form/Field/BlocksField.php index 6479b8a..d058171 100644 --- a/kirby/src/Form/Field/BlocksField.php +++ b/kirby/src/Form/Field/BlocksField.php @@ -57,7 +57,7 @@ class BlocksField extends FieldClass $block['content'] = $this->form($fields[$type], $block['content'])->$to(); $result[] = $block; - } catch (Throwable $e) { + } catch (Throwable) { $result[] = $block; // skip invalid blocks @@ -87,7 +87,7 @@ class BlocksField extends FieldClass return $this->fieldsets; } - public function fieldsetGroups(): ?array + public function fieldsetGroups(): array|null { $fieldsetGroups = $this->fieldsets()->groups(); return empty($fieldsetGroups) === true ? null : $fieldsetGroups; @@ -253,8 +253,9 @@ class BlocksField extends FieldClass $blockType = $block['type']; try { - $blockFields = $fields[$blockType] ?? $this->fields($blockType) ?? []; - } catch (Throwable $e) { + $fieldset = $this->fieldset($blockType); + $blockFields = $fields[$blockType] ?? $fieldset->fields() ?? []; + } catch (Throwable) { // skip invalid blocks continue; } @@ -271,7 +272,9 @@ class BlocksField extends FieldClass throw new InvalidArgumentException([ 'key' => 'blocks.validation', 'data' => [ - 'index' => $index, + 'field' => $field->label(), + 'fieldset' => $fieldset->name(), + 'index' => $index ] ]); } diff --git a/kirby/src/Form/Field/LayoutField.php b/kirby/src/Form/Field/LayoutField.php index 640d095..461f32a 100644 --- a/kirby/src/Form/Field/LayoutField.php +++ b/kirby/src/Form/Field/LayoutField.php @@ -56,7 +56,7 @@ class LayoutField extends BlocksField ]); } - public function layouts(): ?array + public function layouts(): array|null { return $this->layouts; } @@ -200,8 +200,9 @@ class LayoutField extends BlocksField $blockType = $block['type']; try { + $fieldset = $this->fieldset($blockType); $blockFields = $fields[$blockType] ?? $this->fields($blockType) ?? []; - } catch (Throwable $e) { + } catch (Throwable) { // skip invalid blocks continue; } @@ -219,6 +220,8 @@ class LayoutField extends BlocksField 'key' => 'layout.validation.block', 'data' => [ 'blockIndex' => $blockIndex, + 'field' => $field->label(), + 'fieldset' => $fieldset->name(), 'layoutIndex' => $layoutIndex ] ]); diff --git a/kirby/src/Form/FieldClass.php b/kirby/src/Form/FieldClass.php index ed3804b..ebd76c6 100644 --- a/kirby/src/Form/FieldClass.php +++ b/kirby/src/Form/FieldClass.php @@ -2,6 +2,7 @@ namespace Kirby\Form; +use Closure; use Exception; use Kirby\Cms\App; use Kirby\Cms\HasSiblings; @@ -162,7 +163,7 @@ abstract class FieldClass /** * @return string|null */ - public function after(): ?string + public function after(): string|null { return $this->stringTemplate($this->after); } @@ -186,7 +187,7 @@ abstract class FieldClass /** * @return string|null */ - public function before(): ?string + public function before(): string|null { return $this->stringTemplate($this->before); } @@ -259,7 +260,7 @@ abstract class FieldClass * * @return string|null */ - public function help(): ?string + public function help(): string|null { if (empty($this->help) === false) { $help = $this->stringTemplate($this->help); @@ -274,7 +275,7 @@ abstract class FieldClass * @param string|array|null $param * @return string|null */ - protected function i18n($param = null): ?string + protected function i18n($param = null): string|null { return empty($param) === false ? I18n::translate($param, $param) : null; } @@ -284,7 +285,7 @@ abstract class FieldClass * * @return string|null */ - public function icon(): ?string + public function icon(): string|null { return $this->icon; } @@ -457,7 +458,7 @@ abstract class FieldClass * * @return string|null */ - public function placeholder(): ?string + public function placeholder(): string|null { return $this->stringTemplate($this->placeholder); } @@ -578,7 +579,7 @@ abstract class FieldClass * @param string|null $icon * @return void */ - protected function setIcon(?string $icon = null) + protected function setIcon(string|null $icon = null) { $this->icon = $icon; } @@ -684,7 +685,7 @@ abstract class FieldClass * @param string|null $string * @return string|null */ - protected function stringTemplate(?string $string = null): ?string + protected function stringTemplate(string|null $string = null): string|null { if ($string !== null) { return $this->model->toString($string); @@ -767,7 +768,7 @@ abstract class FieldClass continue; } - if (is_a($validation, 'Closure') === true) { + if ($validation instanceof Closure) { try { $validation->call($this, $value); } catch (Exception $e) { @@ -816,7 +817,7 @@ abstract class FieldClass { try { return Data::decode($value, 'json'); - } catch (Throwable $e) { + } catch (Throwable) { return []; } } @@ -858,7 +859,7 @@ abstract class FieldClass * * @return array|null */ - public function when(): ?array + public function when(): array|null { return $this->when; } diff --git a/kirby/src/Form/Form.php b/kirby/src/Form/Form.php index 5935ced..68f698d 100644 --- a/kirby/src/Form/Form.php +++ b/kirby/src/Form/Form.php @@ -2,6 +2,7 @@ namespace Kirby\Form; +use Closure; use Kirby\Cms\App; use Kirby\Cms\Model; use Kirby\Data\Data; @@ -108,9 +109,7 @@ class Form $input = array_merge($values, $input); foreach ($input as $key => $value) { - if (isset($this->values[$key]) === false) { - $this->values[$key] = $value; - } + $this->values[$key] ??= $value; } } } @@ -260,7 +259,7 @@ class Form // convert closures to values foreach ($values as $key => $value) { - if (is_a($value, 'Closure') === true) { + if ($value instanceof Closure) { $values[$key] = $value($original[$key] ?? null); } } @@ -316,7 +315,7 @@ class Form * @param string|null $language * @return array */ - protected static function prepareFieldsForLanguage(array $fields, ?string $language = null): array + protected static function prepareFieldsForLanguage(array $fields, string|null $language = null): array { $kirby = App::instance(null, true); diff --git a/kirby/src/Form/Mixin/EmptyState.php b/kirby/src/Form/Mixin/EmptyState.php index 782acaa..9ea8b0c 100644 --- a/kirby/src/Form/Mixin/EmptyState.php +++ b/kirby/src/Form/Mixin/EmptyState.php @@ -11,7 +11,7 @@ trait EmptyState $this->empty = $this->i18n($empty); } - public function empty(): ?string + public function empty(): string|null { return $this->stringTemplate($this->empty); } diff --git a/kirby/src/Form/Mixin/Max.php b/kirby/src/Form/Mixin/Max.php index b02825e..501ba2d 100644 --- a/kirby/src/Form/Mixin/Max.php +++ b/kirby/src/Form/Mixin/Max.php @@ -6,7 +6,7 @@ trait Max { protected $max; - public function max(): ?int + public function max(): int|null { return $this->max; } diff --git a/kirby/src/Form/Mixin/Min.php b/kirby/src/Form/Mixin/Min.php index 46a8d87..b177a08 100644 --- a/kirby/src/Form/Mixin/Min.php +++ b/kirby/src/Form/Mixin/Min.php @@ -6,7 +6,7 @@ trait Min { protected $min; - public function min(): ?int + public function min(): int|null { return $this->min; } diff --git a/kirby/src/Form/Options.php b/kirby/src/Form/Options.php index 4873b88..3b5da34 100644 --- a/kirby/src/Form/Options.php +++ b/kirby/src/Form/Options.php @@ -16,6 +16,8 @@ use Kirby\Toolkit\I18n; * @link https://getkirby.com * @copyright Bastian Allgeier * @license https://opensource.org/licenses/MIT + * + * @deprecated 3.8.0 Use `Kirby\Option\Options` instead */ class Options { @@ -87,7 +89,7 @@ class Options // add the model by the proper alias foreach (static::aliases() as $className => $alias) { - if (is_a($model, $className) === true) { + if ($model instanceof $className) { $data[$alias] = $model; } } @@ -105,30 +107,23 @@ class Options */ public static function factory($options, array $props = [], $model = null): array { - switch ($options) { - case 'api': - $options = static::api($props['api'], $model); - break; - case 'query': - $options = static::query($props['query'], $model); - break; - case 'children': - case 'grandChildren': - case 'siblings': - case 'index': - case 'files': - case 'images': - case 'documents': - case 'videos': - case 'audio': - case 'code': - case 'archives': - $options = static::query('page.' . $options, $model); - break; - case 'pages': - $options = static::query('site.index', $model); - break; - } + $options = match ($options) { + 'api' => static::api($props['api'], $model), + 'query' => static::query($props['query'], $model), + 'pages' => static::query('site.index', $model), + 'children', + 'grandChildren', + 'siblings', + 'index', + 'files', + 'images', + 'documents', + 'videos', + 'audio', + 'code', + 'archives' => static::query('page.' . $options, $model), + default => $options + }; if (is_array($options) === false) { return []; diff --git a/kirby/src/Form/OptionsApi.php b/kirby/src/Form/OptionsApi.php index c4df0b4..a568520 100644 --- a/kirby/src/Form/OptionsApi.php +++ b/kirby/src/Form/OptionsApi.php @@ -7,8 +7,8 @@ use Kirby\Exception\Exception; use Kirby\Exception\InvalidArgumentException; use Kirby\Http\Remote; use Kirby\Http\Url; +use Kirby\Query\Query; use Kirby\Toolkit\Properties; -use Kirby\Toolkit\Query; use Kirby\Toolkit\Str; /** @@ -20,6 +20,8 @@ use Kirby\Toolkit\Str; * @link https://getkirby.com * @copyright Bastian Allgeier * @license https://opensource.org/licenses/MIT + * + * @deprecated 3.8.0 Use `Kirby\Option\OptionsApi` instead */ class OptionsApi { @@ -132,7 +134,7 @@ class OptionsApi throw new InvalidArgumentException('Invalid options format'); } - $result = (new Query($this->fetch(), Nest::create($data)))->result(); + $result = (new Query($this->fetch()))->resolve(Nest::create($data)); $options = []; foreach ($result as $item) { @@ -161,7 +163,7 @@ class OptionsApi * @param string|null $fetch * @return $this */ - protected function setFetch(?string $fetch = null) + protected function setFetch(string|null $fetch = null) { $this->fetch = $fetch; return $this; @@ -181,7 +183,7 @@ class OptionsApi * @param string $text * @return $this */ - protected function setText(?string $text = null) + protected function setText(string|null $text = null) { $this->text = $text; return $this; @@ -201,7 +203,7 @@ class OptionsApi * @param string|null $value * @return $this */ - protected function setValue(?string $value = null) + protected function setValue(string|null $value = null) { $this->value = $value; return $this; diff --git a/kirby/src/Form/OptionsQuery.php b/kirby/src/Form/OptionsQuery.php index c91ac64..36ff287 100644 --- a/kirby/src/Form/OptionsQuery.php +++ b/kirby/src/Form/OptionsQuery.php @@ -5,10 +5,10 @@ namespace Kirby\Form; use Kirby\Cms\Field; use Kirby\Exception\InvalidArgumentException; use Kirby\Exception\NotFoundException; +use Kirby\Query\Query; use Kirby\Toolkit\Collection; use Kirby\Toolkit\Obj; use Kirby\Toolkit\Properties; -use Kirby\Toolkit\Query; use Kirby\Toolkit\Str; /** @@ -22,6 +22,8 @@ use Kirby\Toolkit\Str; * @link https://getkirby.com * @copyright Bastian Allgeier * @license https://opensource.org/licenses/MIT + * + * @deprecated 3.8.0 Use `Kirby\Option\OptionsQuery` instead */ class OptionsQuery { @@ -115,8 +117,8 @@ class OptionsQuery } $data = $this->data(); - $query = new Query($this->query(), $data); - $result = $query->result(); + $query = new Query($this->query()); + $result = $query->resolve($data); $result = $this->resultToCollection($result); $options = []; @@ -154,7 +156,7 @@ class OptionsQuery // slow but precise resolving foreach ($this->aliases as $className => $alias) { - if (is_a($object, $className) === true) { + if ($object instanceof $className) { return $alias; } } @@ -181,7 +183,7 @@ class OptionsQuery $result = new Collection($result); } - if (is_a($result, 'Kirby\Toolkit\Collection') === false) { + if ($result instanceof Collection === false) { throw new InvalidArgumentException('Invalid query result data'); } @@ -192,7 +194,7 @@ class OptionsQuery * @param array|null $aliases * @return $this */ - protected function setAliases(?array $aliases = null) + protected function setAliases(array|null $aliases = null) { $this->aliases = $aliases; return $this; diff --git a/kirby/src/Http/Cookie.php b/kirby/src/Http/Cookie.php index b63c606..e461a5a 100644 --- a/kirby/src/Http/Cookie.php +++ b/kirby/src/Http/Cookie.php @@ -19,9 +19,8 @@ class Cookie { /** * Key to use for cookie signing - * @var string */ - public static $key = 'KirbyHttpCookieKey'; + public static string $key = 'KirbyHttpCookieKey'; /** * Set a new cookie @@ -68,19 +67,20 @@ class Cookie * Calculates the lifetime for a cookie * * @param int $minutes Number of minutes or timestamp - * @return int */ public static function lifetime(int $minutes): int { if ($minutes > 1000000000) { // absolute timestamp return $minutes; - } elseif ($minutes > 0) { + } + + if ($minutes > 0) { // minutes from now return time() + ($minutes * 60); - } else { - return 0; } + + return 0; } /** @@ -120,9 +120,9 @@ class Cookie * @param string|null $key The name of the cookie * @param string|null $default The default value, which should be returned * if the cookie has not been found - * @return mixed The found value + * @return string|array|null The found value */ - public static function get(string $key = null, string $default = null) + public static function get(string|null $key = null, string|null $default = null): string|array|null { if ($key === null) { return $_COOKIE; @@ -137,9 +137,6 @@ class Cookie /** * Checks if a cookie exists - * - * @param string $key - * @return bool */ public static function exists(string $key): bool { @@ -149,9 +146,6 @@ class Cookie /** * Creates a HMAC for the cookie value * Used as a cookie signature to prevent easy tampering with cookie data - * - * @param string $value - * @return string */ protected static function hmac(string $value): string { @@ -161,11 +155,8 @@ class Cookie /** * Parses the hashed value from a cookie * and tries to extract the value - * - * @param string $string - * @return mixed */ - protected static function parse(string $string) + protected static function parse(string $string): string|null { // if no hash-value separator is present, we can't parse the value if (strpos($string, '+') === false) { @@ -178,7 +169,7 @@ class Cookie // if the hash or the value is missing at all return null // $value can be an empty string, $hash can't be! - if (!is_string($hash) || $hash === '' || !is_string($value)) { + if ($hash === '') { return null; } @@ -207,7 +198,7 @@ class Cookie */ public static function remove(string $key): bool { - if (isset($_COOKIE[$key])) { + if (isset($_COOKIE[$key]) === true) { unset($_COOKIE[$key]); return setcookie($key, '', 1, '/') && setcookie($key, false); } @@ -221,9 +212,6 @@ class Cookie * this ensures that the response is only cached for visitors who don't * have this cookie set; * https://github.com/getkirby/kirby/issues/4423#issuecomment-1166300526 - * - * @param string $key - * @return void */ protected static function trackUsage(string $key): void { diff --git a/kirby/src/Http/Environment.php b/kirby/src/Http/Environment.php index 68aedd4..9a3e3c5 100644 --- a/kirby/src/Http/Environment.php +++ b/kirby/src/Http/Environment.php @@ -3,7 +3,6 @@ namespace Kirby\Http; use Kirby\Cms\App; -use Kirby\Cms\Helpers; use Kirby\Exception\InvalidArgumentException; use Kirby\Filesystem\F; use Kirby\Toolkit\A; @@ -26,143 +25,108 @@ class Environment { /** * Full base URL object - * - * @var \Kirby\Http\Uri */ - protected $baseUri; + protected Uri $baseUri; /** * Full base URL - * - * @var string */ - protected $baseUrl; + protected string $baseUrl; /** * Whether the request is being served by the CLI - * - * @var bool */ - protected $cli; + protected bool $cli; /** * Current host name - * - * @var string */ - protected $host; + protected string|null $host; /** * Whether the HTTPS protocol is used - * - * @var bool */ - protected $https; + protected bool $https; /** * Sanitized `$_SERVER` data - * - * @var array */ - protected $info; + protected array $info; /** * Current server's IP address - * - * @var string */ - protected $ip; + protected string|null $ip; /** * Whether the site is behind a reverse proxy; * `null` if not known (fixed allowed URL setup) - * - * @var bool|null */ - protected $isBehindProxy; + protected bool|null $isBehindProxy; /** * URI path to the base - * - * @var string */ - protected $path; + protected string $path; /** * Port number in the site URL - * - * @var int|null */ - protected $port; + protected int|null $port; /** * Intermediary value of the port * extracted from the host name - * - * @var int|null */ - protected $portInHost; + protected int|null $portInHost = null; /** * Uri object for the full request URI. * It is a combination of the base URL and `REQUEST_URI` - * - * @var \Kirby\Http\Uri */ - protected $requestUri; + protected Uri $requestUri; /** * Full request URL - * - * @var string */ - protected $requestUrl; + protected string $requestUrl; /** * Path to the php script within the * document root without the * filename of the script - * - * @var string */ - protected $scriptPath; + protected string $scriptPath; /** * Class constructor * - * @param array|null $options * @param array|null $info Optional override for `$_SERVER` */ - public function __construct(?array $options = null, ?array $info = null) + public function __construct(array|null $options = null, array|null $info = null) { $this->detect($options, $info); } /** * Returns the server's IP address - * * @see static::ip - * @return string|null */ - public function address(): ?string + public function address(): string|null { return $this->ip(); } /** * Returns the full base URL object - * - * @return \Kirby\Http\Uri */ - public function baseUri() + public function baseUri(): Uri { return $this->baseUri; } /** * Returns the full base URL - * - * @return string */ public function baseUrl(): string { @@ -171,8 +135,6 @@ class Environment /** * Checks if the request is being served by the CLI - * - * @return bool */ public function cli(): bool { @@ -186,9 +148,7 @@ class Environment * the stored information and re-detect the * environment if necessary. * - * @param array|null $options * @param array|null $info Optional override for `$_SERVER` - * @return array */ public function detect(array $options = null, array $info = null): array { @@ -208,18 +168,6 @@ class Environment $this->path = $this->detectPath($this->scriptPath); $this->port = null; - // keep Server flags compatible for now - // TODO: remove in 3.8.0 - // @codeCoverageIgnoreStart - if (is_int($options['allowed']) === true) { - Helpers::deprecated(' - Using `Server::` constants for the `allowed` option has been deprecated and support will be removed in 3.8.0. Use one of the following instead: a single fixed URL, an array of allowed URLs to match dynamically, `*` wildcard to match dynamically even from insecure headers, or `true` to match automtically from safe server variables. - '); - - $options['allowed'] = $this->detectAllowedFromFlag($options['allowed']); - } - // @codeCoverageIgnoreEnd - // insecure auto-detection if ($options['allowed'] === '*' || $options['allowed'] === ['*']) { $this->detectAuto(true); @@ -246,11 +194,8 @@ class Environment /** * Sets the host name, port, path and protocol from the * fixed list of allowed URLs - * - * @param array|string $allowed - * @return void */ - protected function detectAllowed($allowed): void + protected function detectAllowed(array|string|object $allowed): void { $allowed = A::wrap($allowed); @@ -300,34 +245,10 @@ class Environment throw new InvalidArgumentException('The environment is not allowed'); } - /** - * The URL option receives a set of Server constant flags - * - * Server::HOST_FROM_SERVER - * Server::HOST_FROM_SERVER | Server::HOST_ALLOW_EMPTY - * Server::HOST_FROM_HEADER - * Server::HOST_FROM_HEADER | Server::HOST_ALLOW_EMPTY - * @todo Remove in 3.8.0 - * - * @param int $flags - * @return string|null - */ - protected function detectAllowedFromFlag(int $flags): ?string - { - // allow host detection from host headers - if ($flags & Server::HOST_FROM_HEADER) { - return '*'; - } - - // detect host only from server name - return null; - } - /** * Sets the host name, port and protocol without configuration * * @param bool $insecure Include the `Host`, `Forwarded` and `X-Forwarded-*` headers in the search - * @return void */ protected function detectAuto(bool $insecure = false): void { @@ -364,10 +285,8 @@ class Environment /** * Builds the base URL based on the * given environment params - * - * @return \Kirby\Http\Uri */ - protected function detectBaseUri() + protected function detectBaseUri(): Uri { $this->baseUri = new Uri([ 'host' => $this->host, @@ -385,9 +304,8 @@ class Environment * Detects if the request is served by the CLI * * @param bool|null $override Set to a boolean to override detection (for testing) - * @return bool */ - protected function detectCli(?bool $override = null): bool + protected function detectCli(bool|null $override = null): bool { if (is_bool($override) === true) { return $override; @@ -411,8 +329,6 @@ class Environment /** * Detects the host, protocol, port and client IP * from the `Forwarded` and `X-Forwarded-*` headers - * - * @return array */ protected function detectForwarded(): array { @@ -482,10 +398,8 @@ class Environment /** * Detects the host name of the reverse proxy * from the `X-Forwarded-Host` header - * - * @return string|null */ - protected function detectForwardedHost(): ?string + protected function detectForwardedHost(): string|null { $host = $this->get('HTTP_X_FORWARDED_HOST'); $parts = $this->detectPortInHost($host); @@ -498,8 +412,6 @@ class Environment /** * Detects the protocol of the reverse proxy from the * `X-Forwarded-SSL` or `X-Forwarded-Proto` header - * - * @return bool */ protected function detectForwardedHttps(): bool { @@ -519,9 +431,8 @@ class Environment * `X-Forwarded-Host` or `X-Forwarded-Port` header * * @param bool $https Whether HTTPS was detected - * @return int|null */ - protected function detectForwardedPort(bool $https): ?int + protected function detectForwardedPort(bool $https): int|null { // based on forwarded port $port = $this->get('HTTP_X_FORWARDED_PORT'); @@ -547,10 +458,11 @@ class Environment * Detects the host name from various headers * * @param bool $insecure Include the `Host` header in the search - * @return string|null */ - protected function detectHost(bool $insecure = false): ?string + protected function detectHost(bool $insecure = false): string|null { + $hosts = []; + if ($insecure === true) { $hosts[] = $this->get('HTTP_HOST'); } @@ -571,8 +483,6 @@ class Environment /** * Detects the HTTPS status - * - * @return bool */ protected function detectHttps(): bool { @@ -585,11 +495,8 @@ class Environment /** * Normalizes the HTTPS status into a boolean - * - * @param string|bool|null|int $value - * @return bool */ - protected function detectHttpsOn($value): bool + protected function detectHttpsOn(string|int|bool|null $value): bool { // off can mean many things :) $off = ['off', null, '', 0, '0', false, 'false', -1, '-1']; @@ -599,11 +506,8 @@ class Environment /** * Detects the HTTPS status from a `X-Forwarded-Proto` string - * - * @param string|null $protocol - * @return bool */ - protected function detectHttpsProtocol(?string $protocol = null): bool + protected function detectHttpsProtocol(string|null $protocol = null): bool { if ($protocol === null) { return false; @@ -614,21 +518,16 @@ class Environment /** * Detects the server's IP address - * - * @return string|null */ - protected function detectIp(): ?string + protected function detectIp(): string|null { return $this->get('SERVER_ADDR'); } /** * Detects the URI path unless in CLI mode - * - * @param string|null $path - * @return string */ - protected function detectPath(?string $path = null): string + protected function detectPath(string|null $path = null): string { if ($this->cli === true) { return ''; @@ -639,10 +538,8 @@ class Environment /** * Detects the port from various sources - * - * @return int|null */ - protected function detectPort(): ?int + protected function detectPort(): int|null { // based on server port $port = $this->get('SERVER_PORT'); @@ -666,11 +563,8 @@ class Environment /** * Splits a hostname:port string into its components - * - * @param string|null $host - * @return array */ - protected function detectPortInHost(?string $host = null): array + protected function detectPortInHost(string|null $host = null): array { if (empty($host) === true) { return [ @@ -689,11 +583,8 @@ class Environment /** * Splits any URI into path and query - * - * @param string|null $requestUri - * @return \Kirby\Http\Uri */ - protected function detectRequestUri(?string $requestUri = null) + protected function detectRequestUri(string|null $requestUri = null): Uri { // make sure the URL parser works properly when there's a // colon in the request URI but the URI is relative @@ -720,11 +611,8 @@ class Environment /** * Returns the sanitized script path unless in CLI mode - * - * @param string|null $scriptPath - * @return string */ - protected function detectScriptPath(?string $scriptPath = null): string + protected function detectScriptPath(string|null $scriptPath = null): string { if ($this->cli === true) { return ''; @@ -748,9 +636,8 @@ class Environment * to return the entire server array. * @param mixed $default Optional default value, which should be * returned if no element has been found - * @return mixed */ - public function get($key = null, $default = null) + public function get(string|false|null $key = null, $default = null) { if (is_string($key) === false) { return $this->info; @@ -772,9 +659,8 @@ class Environment * to return the entire server array. * @param mixed $default Optional default value, which should be * returned if no element has been found - * @return mixed */ - public static function getGlobally($key = null, $default = null) + public static function getGlobally(string|false|null $key = null, $default = null) { // first try the global `Environment` object if the CMS is running $app = App::instance(null, true); @@ -795,18 +681,14 @@ class Environment /** * Returns the current host name - * - * @return string|null */ - public function host(): ?string + public function host(): string|null { return $this->host; } /** * Returns whether the HTTPS protocol is used - * - * @return bool */ public function https(): bool { @@ -815,8 +697,6 @@ class Environment /** * Returns the sanitized `$_SERVER` array - * - * @return array */ public function info(): array { @@ -825,10 +705,8 @@ class Environment /** * Returns the server's IP address - * - * @return string|null */ - public function ip(): ?string + public function ip(): string|null { return $this->ip; } @@ -836,10 +714,8 @@ class Environment /** * Returns if the server is behind a * reverse proxy server - * - * @return bool|null */ - public function isBehindProxy(): ?bool + public function isBehindProxy(): bool|null { return $this->isBehindProxy; } @@ -847,8 +723,6 @@ class Environment /** * Checks if this is a local installation; * returns `false` if in doubt - * - * @return bool */ public function isLocal(): bool { @@ -901,7 +775,6 @@ class Environment * PHP files (by host name and server IP address) * * @param string $root Root directory to load configs from - * @return array */ public function options(string $root): array { @@ -913,12 +786,20 @@ class Environment // load the config for the host if (empty($host) === false) { - $configHost = F::load($root . '/config.' . $host . '.php', []); + $configHost = F::load( + file: $root . '/config.' . $host . '.php', + fallback: [], + allowOutput: false + ); } // load the config for the server IP if (empty($addr) === false) { - $configAddr = F::load($root . '/config.' . $addr . '.php', []); + $configAddr = F::load( + file: $root . '/config.' . $addr . '.php', + fallback: [], + allowOutput: false + ); } return array_replace_recursive($configHost, $configAddr); @@ -926,30 +807,24 @@ class Environment /** * Returns the detected path - * - * @return string|null */ - public function path(): ?string + public function path(): string|null { return $this->path; } /** * Returns the correct port number - * - * @return int|null */ - public function port(): ?int + public function port(): int|null { return $this->port; } /** * Returns an URI object for the requested URL - * - * @return \Kirby\Http\Uri */ - public function requestUri() + public function requestUri(): Uri { return $this->requestUri; } @@ -957,8 +832,6 @@ class Environment /** * Returns the current URL, including the request path * and query - * - * @return string */ public function requestUrl(): string { @@ -967,12 +840,8 @@ class Environment /** * Sanitizes some `$_SERVER` keys - * - * @param string|array $key - * @param mixed $value - * @return mixed */ - public static function sanitize($key, $value = null) + public static function sanitize(string|array $key, $value = null) { if (is_array($key) === true) { foreach ($key as $k => $v) { @@ -982,27 +851,23 @@ class Environment return $key; } - switch ($key) { - case 'SERVER_ADDR': - case 'SERVER_NAME': - case 'HTTP_HOST': - case 'HTTP_X_FORWARDED_HOST': - return static::sanitizeHost($value); - case 'SERVER_PORT': - case 'HTTP_X_FORWARDED_PORT': - return static::sanitizePort($value); - default: - return $value; - } + return match ($key) { + 'SERVER_ADDR', + 'SERVER_NAME', + 'HTTP_HOST', + 'HTTP_X_FORWARDED_HOST' => static::sanitizeHost($value), + + 'SERVER_PORT', + 'HTTP_X_FORWARDED_PORT' => static::sanitizePort($value), + + default => $value + }; } /** * Sanitizes the given host name - * - * @param string|null $host - * @return string|null */ - protected static function sanitizeHost(?string $host = null): ?string + protected static function sanitizeHost(string|null $host = null): string|null { if (empty($host) === true) { return null; @@ -1026,11 +891,8 @@ class Environment /** * Sanitizes the given port number - * - * @param string|int|null $port - * @return int|null */ - protected static function sanitizePort($port = null): ?int + protected static function sanitizePort(string|int|false|null $port = null): int|null { // already fine if (is_int($port) === true) { @@ -1043,7 +905,7 @@ class Environment } // remove any character that is not an integer - $port = preg_replace('![^0-9]+!', '', (string)($port ?? '')); + $port = preg_replace('![^0-9]+!', '', $port); // no port if ($port === '') { @@ -1056,11 +918,8 @@ class Environment /** * Sanitizes the given script path - * - * @param string|null $scriptPath - * @return string */ - protected function sanitizeScriptPath(?string $scriptPath = null): string + protected function sanitizeScriptPath(string|null $scriptPath = null): string { $scriptPath ??= ''; $scriptPath = trim($scriptPath); @@ -1097,8 +956,6 @@ class Environment * * This can be used to build the base baseUrl * for subfolder installations - * - * @return string */ public function scriptPath(): string { @@ -1107,8 +964,6 @@ class Environment /** * Returns all environment data as array - * - * @return array */ public function toArray(): array { diff --git a/kirby/src/Http/Header.php b/kirby/src/Http/Header.php index 5f3b5ee..2d9692e 100644 --- a/kirby/src/Http/Header.php +++ b/kirby/src/Http/Header.php @@ -17,7 +17,7 @@ use Kirby\Filesystem\F; class Header { // configuration - public static $codes = [ + public static array $codes = [ // successful '_200' => 'OK', @@ -56,9 +56,6 @@ class Header /** * Sends a content type header * - * @param string $mime - * @param string $charset - * @param bool $send * @return string|void */ public static function contentType(string $mime, string $charset = 'UTF-8', bool $send = true) @@ -82,12 +79,8 @@ class Header /** * Creates headers by key and value - * - * @param string|array $key - * @param string|null $value - * @return string */ - public static function create($key, string $value = null): string + public static function create(string|array $key, string|null $value = null): string { if (is_array($key) === true) { $headers = []; @@ -106,9 +99,6 @@ class Header /** * Shortcut for static::contentType() * - * @param string $mime - * @param string $charset - * @param bool $send * @return string|void */ public static function type(string $mime, string $charset = 'UTF-8', bool $send = true) @@ -123,11 +113,12 @@ class Header * and send a custom status code and message, use a $code string formatted * as 3 digits followed by a space and a message, e.g. '999 Custom Status'. * - * @param int|string $code The HTTP status code + * @param int|string|null $code The HTTP status code * @param bool $send If set to false the header will be returned instead * @return string|void + * @psalm-return ($send is false ? string : void) */ - public static function status($code = null, bool $send = true) + public static function status(int|string|null $code = null, bool $send = true) { $codes = static::$codes; $protocol = Environment::getGlobally('SERVER_PROTOCOL', 'HTTP/1.1'); @@ -154,7 +145,6 @@ class Header /** * Sends a 200 header * - * @param bool $send * @return string|void */ public static function success(bool $send = true) @@ -165,7 +155,6 @@ class Header /** * Sends a 201 header * - * @param bool $send * @return string|void */ public static function created(bool $send = true) @@ -176,7 +165,6 @@ class Header /** * Sends a 202 header * - * @param bool $send * @return string|void */ public static function accepted(bool $send = true) @@ -187,7 +175,6 @@ class Header /** * Sends a 400 header * - * @param bool $send * @return string|void */ public static function error(bool $send = true) @@ -198,7 +185,6 @@ class Header /** * Sends a 403 header * - * @param bool $send * @return string|void */ public static function forbidden(bool $send = true) @@ -209,7 +195,6 @@ class Header /** * Sends a 404 header * - * @param bool $send * @return string|void */ public static function notfound(bool $send = true) @@ -220,7 +205,6 @@ class Header /** * Sends a 404 header * - * @param bool $send * @return string|void */ public static function missing(bool $send = true) @@ -231,7 +215,6 @@ class Header /** * Sends a 410 header * - * @param bool $send * @return string|void */ public static function gone(bool $send = true) @@ -242,7 +225,6 @@ class Header /** * Sends a 500 header * - * @param bool $send * @return string|void */ public static function panic(bool $send = true) @@ -253,7 +235,6 @@ class Header /** * Sends a 503 header * - * @param bool $send * @return string|void */ public static function unavailable(bool $send = true) @@ -264,9 +245,6 @@ class Header /** * Sends a redirect header * - * @param string $url - * @param int $code - * @param bool $send * @return string|void */ public static function redirect(string $url, int $code = 302, bool $send = true) @@ -288,7 +266,7 @@ class Header * * @param array $params Check out the defaults array for available parameters */ - public static function download(array $params = []) + public static function download(array $params = []): void { $defaults = [ 'name' => 'download', diff --git a/kirby/src/Http/Idn.php b/kirby/src/Http/Idn.php index a9a538f..2ede8b3 100644 --- a/kirby/src/Http/Idn.php +++ b/kirby/src/Http/Idn.php @@ -17,31 +17,22 @@ class Idn { /** * Convert domain name from IDNA ASCII to Unicode - * - * @param string $domain - * @return string|false */ - public static function decode(string $domain) + public static function decode(string $domain): string|false { return idn_to_utf8($domain); } /** * Convert domain name to IDNA ASCII form - * - * @param string $domain - * @return string|false */ - public static function encode(string $domain) + public static function encode(string $domain): string|false { return idn_to_ascii($domain); } /** * Decodes a email address to the Unicode format - * - * @param string $email - * @return string */ public static function decodeEmail(string $email): string { @@ -57,9 +48,6 @@ class Idn /** * Encodes a email address to the Punycode format - * - * @param string $email - * @return string */ public static function encodeEmail(string $email): string { diff --git a/kirby/src/Http/Params.php b/kirby/src/Http/Params.php index f9c7e1a..2403cc9 100644 --- a/kirby/src/Http/Params.php +++ b/kirby/src/Http/Params.php @@ -2,6 +2,7 @@ namespace Kirby\Http; +use Kirby\Toolkit\Obj; use Kirby\Toolkit\Str; /** @@ -15,19 +16,14 @@ use Kirby\Toolkit\Str; * @copyright Bastian Allgeier * @license https://opensource.org/licenses/MIT */ -class Params extends Query +class Params extends Obj { - /** - * @var null|string - */ - public static $separator; + public static string|null $separator = null; /** * Creates a new params object - * - * @param array|string $params */ - public function __construct($params) + public function __construct(array|string|null $params) { if (is_string($params) === true) { $params = static::extract($params)['params']; @@ -38,11 +34,8 @@ class Params extends Query /** * Extract the params from a string or array - * - * @param string|array|null $path - * @return array */ - public static function extract($path = null): array + public static function extract(string|array|null $path = null): array { if (empty($path) === true) { return [ @@ -93,14 +86,22 @@ class Params extends Query ]; } + public function isEmpty(): bool + { + return empty((array)$this) === true; + } + + public function isNotEmpty(): bool + { + return empty((array)$this) === false; + } + /** * Returns the param separator according * to the operating system. * * Unix = ':' * Windows = ';' - * - * @return string */ public static function separator(): string { @@ -110,26 +111,16 @@ class Params extends Query if (DIRECTORY_SEPARATOR === '/') { return static::$separator = ':'; - } else { - return static::$separator = ';'; } + + return static::$separator = ';'; } /** * Converts the params object to a params string * which can then be used in the URL builder again - * - * @param bool $leadingSlash - * @param bool $trailingSlash - * @return string|null - * - * @todo The argument $leadingSlash is incompatible with - * Query::toString($questionMark = false); the Query class - * should be extracted into a common parent class for both - * Query and Params - * @psalm-suppress ParamNameMismatch */ - public function toString($leadingSlash = false, $trailingSlash = false): string + public function toString(bool $leadingSlash = false, bool $trailingSlash = false): string { if ($this->isEmpty() === true) { return ''; @@ -155,4 +146,9 @@ class Params extends Query return $leadingSlash . $params . $trailingSlash; } + + public function __toString(): string + { + return $this->toString(); + } } diff --git a/kirby/src/Http/Path.php b/kirby/src/Http/Path.php index ca4a77d..10c5020 100644 --- a/kirby/src/Http/Path.php +++ b/kirby/src/Http/Path.php @@ -17,7 +17,7 @@ use Kirby\Toolkit\Str; */ class Path extends Collection { - public function __construct($items) + public function __construct(string|array|null $items) { if (is_string($items) === true) { $items = Str::split($items, '/'); diff --git a/kirby/src/Http/Query.php b/kirby/src/Http/Query.php index 89e7f50..8cd3de8 100644 --- a/kirby/src/Http/Query.php +++ b/kirby/src/Http/Query.php @@ -17,7 +17,7 @@ use Kirby\Toolkit\Obj; */ class Query extends Obj { - public function __construct($query) + public function __construct(string|array|null $query) { if (is_string($query) === true) { parse_str(ltrim($query, '?'), $query); @@ -36,12 +36,7 @@ class Query extends Obj return empty((array)$this) === false; } - public function __toString(): string - { - return $this->toString(); - } - - public function toString($questionMark = false): string + public function toString(bool $questionMark = false): string { $query = http_build_query($this, '', '&', PHP_QUERY_RFC3986); @@ -55,4 +50,10 @@ class Query extends Obj return $query; } + + + public function __toString(): string + { + return $this->toString(); + } } diff --git a/kirby/src/Http/Remote.php b/kirby/src/Http/Remote.php index 8325e33..01f4c89 100644 --- a/kirby/src/Http/Remote.php +++ b/kirby/src/Http/Remote.php @@ -2,11 +2,13 @@ namespace Kirby\Http; +use CurlHandle; use Exception; use Kirby\Cms\App; use Kirby\Exception\InvalidArgumentException; use Kirby\Filesystem\F; use Kirby\Toolkit\Str; +use stdClass; /** * A handy little class to handle @@ -23,10 +25,7 @@ class Remote public const CA_INTERNAL = 1; public const CA_SYSTEM = 2; - /** - * @var array - */ - public static $defaults = [ + public static array $defaults = [ 'agent' => null, 'basicAuth' => null, 'body' => true, @@ -41,52 +40,17 @@ class Remote 'timeout' => 10, ]; - /** - * @var string - */ - public $content; - - /** - * @var resource - */ - public $curl; - - /** - * @var array - */ - public $curlopt = []; - - /** - * @var int - */ - public $errorCode; - - /** - * @var string - */ - public $errorMessage; - - /** - * @var array - */ - public $headers = []; - - /** - * @var array - */ - public $info = []; - - /** - * @var array - */ - public $options = []; + public string|null $content = null; + public CurlHandle|false $curl; + public array $curlopt = []; + public int $errorCode; + public string $errorMessage; + public array $headers = []; + public array $info = []; + public array $options = []; /** * Magic getter for request info data - * - * @param string $method - * @param array $arguments - * @return mixed */ public function __call(string $method, array $arguments = []) { @@ -96,9 +60,6 @@ class Remote /** * Constructor - * - * @param string $url - * @param array $options */ public function __construct(string $url, array $options = []) { @@ -128,27 +89,23 @@ class Remote $this->fetch(); } - public static function __callStatic(string $method, array $arguments = []) + public static function __callStatic(string $method, array $arguments = []): static { return new static($arguments[0], array_merge(['method' => strtoupper($method)], $arguments[1] ?? [])); } /** * Returns the http status code - * - * @return int|null */ - public function code(): ?int + public function code(): int|null { return $this->info['http_code'] ?? null; } /** * Returns the response content - * - * @return mixed */ - public function content() + public function content(): string|null { return $this->content; } @@ -158,7 +115,7 @@ class Remote * * @return $this */ - public function fetch() + public function fetch(): static { // curl options $this->curlopt = [ @@ -171,7 +128,7 @@ class Remote CURLOPT_FOLLOWLOCATION => true, CURLOPT_MAXREDIRS => 10, CURLOPT_HEADER => false, - CURLOPT_HEADERFUNCTION => function ($curl, $header) { + CURLOPT_HEADERFUNCTION => function ($curl, $header): int { $parts = Str::split($header, ':'); if (empty($parts[0]) === false && empty($parts[1]) === false) { @@ -295,12 +252,8 @@ class Remote /** * Static method to send a GET request - * - * @param string $url - * @param array $params - * @return static */ - public static function get(string $url, array $params = []) + public static function get(string $url, array $params = []): static { $defaults = [ 'method' => 'GET', @@ -322,8 +275,6 @@ class Remote /** * Returns all received headers - * - * @return array */ public function headers(): array { @@ -332,8 +283,6 @@ class Remote /** * Returns the request info - * - * @return array */ public function info(): array { @@ -344,17 +293,14 @@ class Remote * Decode the response content * * @param bool $array decode as array or object - * @return array|\stdClass */ - public function json(bool $array = true) + public function json(bool $array = true): array|stdClass|null { return json_decode($this->content(), $array); } /** * Returns the request method - * - * @return string */ public function method(): string { @@ -364,8 +310,6 @@ class Remote /** * Returns all options which have been * set for the current request - * - * @return array */ public function options(): array { @@ -374,35 +318,26 @@ class Remote /** * Internal method to handle post field data - * - * @param mixed $data - * @return mixed */ protected function postfields($data) { if (is_object($data) || is_array($data)) { return http_build_query($data); - } else { - return $data; } + + return $data; } /** * Static method to init this class and send a request - * - * @param string $url - * @param array $params - * @return static */ - public static function request(string $url, array $params = []) + public static function request(string $url, array $params = []): static { return new static($url, $params); } /** * Returns the request Url - * - * @return string */ public function url(): string { diff --git a/kirby/src/Http/Request.php b/kirby/src/Http/Request.php index 0b6a897..17dc3e6 100644 --- a/kirby/src/Http/Request.php +++ b/kirby/src/Http/Request.php @@ -3,6 +3,7 @@ namespace Kirby\Http; use Kirby\Cms\App; +use Kirby\Http\Request\Auth; use Kirby\Http\Request\Body; use Kirby\Http\Request\Files; use Kirby\Http\Request\Query; @@ -22,7 +23,7 @@ use Kirby\Toolkit\Str; */ class Request { - public static $authTypes = [ + public static array $authTypes = [ 'basic' => 'Kirby\Http\Request\Auth\BasicAuth', 'bearer' => 'Kirby\Http\Request\Auth\BearerAuth', 'session' => 'Kirby\Http\Request\Auth\SessionAuth', @@ -30,10 +31,8 @@ class Request /** * The auth object if available - * - * @var \Kirby\Http\Request\Auth|false|null */ - protected $auth; + protected Auth|false|null $auth = null; /** * The Body object is a wrapper around @@ -44,10 +43,8 @@ class Request * Examples: * * `$request->body()->get('foo')` - * - * @var Body */ - protected $body; + protected Body|null $body = null; /** * The Files object is a wrapper around @@ -59,25 +56,19 @@ class Request * * `$request->files()->get('upload')['size']` * `$request->file('upload')['size']` - * - * @var Files */ - protected $files; + protected Files|null $files = null; /** * The Method type - * - * @var string */ - protected $method; + protected string $method; /** * All options that have been passed to * the request in the constructor - * - * @var array */ - protected $options; + protected array $options; /** * The Query object is a wrapper around @@ -88,25 +79,19 @@ class Request * Examples: * * `$request->query()->get('foo')` - * - * @var Query */ - protected $query; + protected Query $query; /** * Request URL object - * - * @var Uri */ - protected $url; + protected Uri $url; /** * Creates a new Request object * You can either pass your own request * data via the $options array or use * the data from the incoming request. - * - * @param array $options */ public function __construct(array $options = []) { @@ -114,26 +99,24 @@ class Request $this->method = $this->detectRequestMethod($options['method'] ?? null); if (isset($options['body']) === true) { - $this->body = is_a($options['body'], Body::class) ? $options['body'] : new Body($options['body']); + $this->body = $options['body'] instanceof Body ? $options['body'] : new Body($options['body']); } if (isset($options['files']) === true) { - $this->files = is_a($options['files'], Files::class) ? $options['files'] : new Files($options['files']); + $this->files = $options['files'] instanceof Files ? $options['files'] : new Files($options['files']); } if (isset($options['query']) === true) { - $this->query = is_a($options['query'], Query::class) === true ? $options['query'] : new Query($options['query']); + $this->query = $options['query'] instanceof Query ? $options['query'] : new Query($options['query']); } if (isset($options['url']) === true) { - $this->url = is_a($options['url'], Uri::class) === true ? $options['url'] : new Uri($options['url']); + $this->url = $options['url'] instanceof Uri ? $options['url'] : new Uri($options['url']); } } /** * Improved `var_dump` output - * - * @return array */ public function __debugInfo(): array { @@ -148,10 +131,8 @@ class Request /** * Returns the Auth object if authentication is set - * - * @return \Kirby\Http\Request\Auth|null */ - public function auth() + public function auth(): Auth|false|null { if ($this->auth !== null) { return $this->auth; @@ -170,7 +151,7 @@ class Request $kirby->response()->usesAuth(true); } - if ($auth = $this->options['auth'] ?? $this->header('authorization')) { + if ($auth = $this->authString()) { $type = Str::lower(Str::before($auth, ' ')); $data = Str::after($auth, ' '); @@ -189,18 +170,14 @@ class Request /** * Returns the Body object - * - * @return \Kirby\Http\Request\Body */ - public function body() + public function body(): Body { return $this->body ??= new Body(); } /** * Checks if the request has been made from the command line - * - * @return bool */ public function cli(): bool { @@ -209,18 +186,14 @@ class Request /** * Returns a CSRF token if stored in a header or the query - * - * @return string|null */ - public function csrf(): ?string + public function csrf(): string|null { return $this->header('x-csrf') ?? $this->query()->get('csrf'); } /** * Returns the request input as array - * - * @return array */ public function data(): array { @@ -230,11 +203,8 @@ class Request /** * Detect the request method from various * options: given method, query string, server vars - * - * @param string $method - * @return string */ - public function detectRequestMethod(string $method = null): string + public function detectRequestMethod(string|null $method = null): string { // all possible methods $methods = ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'CONNECT', 'OPTIONS', 'TRACE', 'PATCH']; @@ -262,8 +232,6 @@ class Request /** * Returns the domain - * - * @return string */ public function domain(): string { @@ -273,21 +241,16 @@ class Request /** * Fetches a single file array * from the Files object by key - * - * @param string $key - * @return array|null */ - public function file(string $key) + public function file(string $key): array|null { return $this->files()->get($key); } /** * Returns the Files object - * - * @return \Kirby\Cms\Files */ - public function files() + public function files(): Files { return $this->files ??= new Files(); } @@ -295,12 +258,8 @@ class Request /** * Returns any data field from the request * if it exists - * - * @param string|null|array $key - * @param mixed $fallback - * @return mixed */ - public function get($key = null, $fallback = null) + public function get(string|array|null $key = null, $fallback = null) { return A::get($this->data(), $key, $fallback); } @@ -309,22 +268,14 @@ class Request * Returns whether the request contains * the `Authorization` header * @since 3.7.0 - * - * @return bool */ public function hasAuth(): bool { - $header = $this->options['auth'] ?? $this->header('authorization'); - - return $header !== null; + return $this->authString() !== null; } /** * Returns a header by key if it exists - * - * @param string $key - * @param mixed $fallback - * @return mixed */ public function header(string $key, $fallback = null) { @@ -335,8 +286,6 @@ class Request /** * Return all headers with polyfill for * missing getallheaders function - * - * @return array */ public function headers(): array { @@ -371,9 +320,6 @@ class Request /** * Checks if the given method name * matches the name of the request method. - * - * @param string $method - * @return bool */ public function is(string $method): bool { @@ -382,8 +328,6 @@ class Request /** * Returns the request method - * - * @return string */ public function method(): string { @@ -393,7 +337,7 @@ class Request /** * Shortcut to the Params object */ - public function params() + public function params(): Params { return $this->url()->params(); } @@ -401,25 +345,21 @@ class Request /** * Shortcut to the Path object */ - public function path() + public function path(): Path { return $this->url()->path(); } /** * Returns the Query object - * - * @return \Kirby\Http\Request\Query */ - public function query() + public function query(): Query { return $this->query ??= new Query(); } /** * Checks for a valid SSL connection - * - * @return bool */ public function ssl(): bool { @@ -431,11 +371,8 @@ class Request * If you pass props you can safely modify * the Url with new parameters without destroying * the original object. - * - * @param array $props - * @return \Kirby\Http\Uri */ - public function url(array $props = null) + public function url(array|null $props = null): Uri { if ($props !== null) { return $this->url()->clone($props); @@ -443,4 +380,27 @@ class Request return $this->url ??= Uri::current(); } + + /** + * Returns the raw auth string from the `auth` option + * or `Authorization` header unless both are empty + */ + protected function authString(): string|null + { + // both variants need to be checked separately + // because empty strings are treated as invalid + // but the `??` operator wouldn't do the fallback + + $option = $this->options['auth'] ?? null; + if (empty($option) === false) { + return $option; + } + + $header = $this->header('authorization'); + if (empty($header) === false) { + return $header; + } + + return null; + } } diff --git a/kirby/src/Http/Request/Auth.php b/kirby/src/Http/Request/Auth.php index 032ca11..3eb1f23 100644 --- a/kirby/src/Http/Request/Auth.php +++ b/kirby/src/Http/Request/Auth.php @@ -16,15 +16,11 @@ abstract class Auth /** * Raw authentication data after the first space * in the `Authorization` header - * - * @var string */ - protected $data; + protected string $data; /** * Constructor - * - * @param string $data */ public function __construct(string $data) { @@ -33,8 +29,6 @@ abstract class Auth /** * Converts the object to a string - * - * @return string */ public function __toString(): string { @@ -44,8 +38,6 @@ abstract class Auth /** * Returns the raw authentication data after the * first space in the `Authorization` header - * - * @return string */ public function data(): string { @@ -54,8 +46,6 @@ abstract class Auth /** * Returns the name of the auth type (lowercase) - * - * @return string */ abstract public function type(): string; } diff --git a/kirby/src/Http/Request/Auth/BasicAuth.php b/kirby/src/Http/Request/Auth/BasicAuth.php index 3d6e70e..7549a4f 100644 --- a/kirby/src/Http/Request/Auth/BasicAuth.php +++ b/kirby/src/Http/Request/Auth/BasicAuth.php @@ -16,24 +16,10 @@ use Kirby\Toolkit\Str; */ class BasicAuth extends Auth { - /** - * @var string - */ - protected $credentials; + protected string $credentials; + protected string|null $password; + protected string|null $username; - /** - * @var string - */ - protected $password; - - /** - * @var string - */ - protected $username; - - /** - * @param string $token - */ public function __construct(string $data) { parent::__construct($data); @@ -45,8 +31,6 @@ class BasicAuth extends Auth /** * Returns the entire unencoded credentials string - * - * @return string */ public function credentials(): string { @@ -55,18 +39,14 @@ class BasicAuth extends Auth /** * Returns the password - * - * @return string|null */ - public function password(): ?string + public function password(): string|null { return $this->password; } /** * Returns the authentication type - * - * @return string */ public function type(): string { @@ -75,10 +55,8 @@ class BasicAuth extends Auth /** * Returns the username - * - * @return string|null */ - public function username(): ?string + public function username(): string|null { return $this->username; } diff --git a/kirby/src/Http/Request/Auth/BearerAuth.php b/kirby/src/Http/Request/Auth/BearerAuth.php index e287606..81dc9a9 100644 --- a/kirby/src/Http/Request/Auth/BearerAuth.php +++ b/kirby/src/Http/Request/Auth/BearerAuth.php @@ -17,8 +17,6 @@ class BearerAuth extends Auth { /** * Returns the authentication token - * - * @return string */ public function token(): string { @@ -27,8 +25,6 @@ class BearerAuth extends Auth /** * Returns the auth type - * - * @return string */ public function type(): string { diff --git a/kirby/src/Http/Request/Auth/SessionAuth.php b/kirby/src/Http/Request/Auth/SessionAuth.php index 1ce29be..ca10830 100644 --- a/kirby/src/Http/Request/Auth/SessionAuth.php +++ b/kirby/src/Http/Request/Auth/SessionAuth.php @@ -4,6 +4,7 @@ namespace Kirby\Http\Request\Auth; use Kirby\Cms\App; use Kirby\Http\Request\Auth; +use Kirby\Session\Session; /** * Authentication data using Kirby's session @@ -18,18 +19,14 @@ class SessionAuth extends Auth { /** * Tries to return the session object - * - * @return \Kirby\Session\Session */ - public function session() + public function session(): Session { return App::instance()->sessionHandler()->getManually($this->data); } /** * Returns the session token - * - * @return string */ public function token(): string { @@ -38,8 +35,6 @@ class SessionAuth extends Auth /** * Returns the authentication type - * - * @return string */ public function type(): string { diff --git a/kirby/src/Http/Request/Body.php b/kirby/src/Http/Request/Body.php index df6f330..53bcdd0 100644 --- a/kirby/src/Http/Request/Body.php +++ b/kirby/src/Http/Request/Body.php @@ -20,17 +20,13 @@ class Body /** * The raw body content - * - * @var string|array */ - protected $contents; + protected string|array|null $contents; /** * The parsed content as array - * - * @var array */ - protected $data; + protected array|null $data = null; /** * Creates a new request body object. @@ -38,10 +34,8 @@ class Body * If null is being passed, the class will * fetch the body either from the $_POST global * or from php://input. - * - * @param array|string|null $contents */ - public function __construct($contents = null) + public function __construct(array|string|null $contents = null) { $this->contents = $contents; } @@ -49,20 +43,18 @@ class Body /** * Fetches the raw contents for the body * or uses the passed contents. - * - * @return string|array */ - public function contents() + public function contents(): string|array { - if ($this->contents === null) { - if (empty($_POST) === false) { - $this->contents = $_POST; - } else { - $this->contents = file_get_contents('php://input'); - } + if ($this->contents !== null) { + return $this->contents; } - return $this->contents; + if (empty($_POST) === false) { + return $this->contents = $_POST; + } + + return $this->contents = file_get_contents('php://input'); } /** @@ -71,8 +63,6 @@ class Body * the body with the json decoder first and * then run parse_str to get some results * if the json decoder failed. - * - * @return array */ public function data(): array { @@ -109,8 +99,6 @@ class Body /** * Converts the data array back * to a http query string - * - * @return string */ public function toString(): string { @@ -119,8 +107,6 @@ class Body /** * Magic string converter - * - * @return string */ public function __toString(): string { diff --git a/kirby/src/Http/Request/Data.php b/kirby/src/Http/Request/Data.php index 8826c90..58be233 100644 --- a/kirby/src/Http/Request/Data.php +++ b/kirby/src/Http/Request/Data.php @@ -20,8 +20,6 @@ trait Data { /** * Improved `var_dump` output - * - * @return array */ public function __debugInfo(): array { @@ -33,8 +31,6 @@ trait Data * implemented by each class using this Trait * and has to return an associative array * for the get method - * - * @return array */ abstract public function data(): array; @@ -43,12 +39,8 @@ trait Data * Trait. You can use it to fetch a single value * of the data array by key or multiple values by * passing an array of keys. - * - * @param string|array $key - * @param mixed|null $default - * @return mixed */ - public function get($key, $default = null) + public function get(string|array $key, $default = null) { if (is_array($key) === true) { $result = []; @@ -64,8 +56,6 @@ trait Data /** * Returns the data array. * This is basically an alias for Data::data() - * - * @return array */ public function toArray(): array { @@ -74,8 +64,6 @@ trait Data /** * Converts the data array to json - * - * @return string */ public function toJson(): string { diff --git a/kirby/src/Http/Request/Files.php b/kirby/src/Http/Request/Files.php index a23263a..8e7d3a0 100644 --- a/kirby/src/Http/Request/Files.php +++ b/kirby/src/Http/Request/Files.php @@ -21,19 +21,15 @@ class Files /** * Sanitized array of all received files - * - * @var array */ - protected $files; + protected array $files; /** * Creates a new Files object * Pass your own array to mock * uploads. - * - * @param array|null $files */ - public function __construct($files = null) + public function __construct(array|null $files = null) { if ($files === null) { $files = $_FILES; @@ -63,8 +59,6 @@ class Files * array. This is only needed to make * the Data trait work for the Files::get($key) * method. - * - * @return array */ public function data(): array { diff --git a/kirby/src/Http/Request/Query.php b/kirby/src/Http/Request/Query.php index 315a683..b6c4ad1 100644 --- a/kirby/src/Http/Request/Query.php +++ b/kirby/src/Http/Request/Query.php @@ -19,10 +19,8 @@ class Query /** * The Query data array - * - * @var array|null */ - protected $data; + protected array|null $data; /** * Creates a new Query object. @@ -30,14 +28,12 @@ class Query * or a parsable query string. If * null is passed, the current Query * will be taken from $_GET - * - * @param array|string|null $data */ - public function __construct($data = null) + public function __construct(array|string|null $data = null) { if ($data === null) { $this->data = $_GET; - } elseif (is_array($data)) { + } elseif (is_array($data) === true) { $this->data = $data; } else { parse_str($data, $parsed); @@ -47,8 +43,6 @@ class Query /** * Returns the Query data as array - * - * @return array */ public function data(): array { @@ -57,8 +51,6 @@ class Query /** * Returns `true` if the request doesn't contain query variables - * - * @return bool */ public function isEmpty(): bool { @@ -67,8 +59,6 @@ class Query /** * Returns `true` if the request contains query variables - * - * @return bool */ public function isNotEmpty(): bool { @@ -78,8 +68,6 @@ class Query /** * Converts the query data array * back to a query string - * - * @return string */ public function toString(): string { @@ -88,8 +76,6 @@ class Query /** * Magic string converter - * - * @return string */ public function __toString(): string { diff --git a/kirby/src/Http/Response.php b/kirby/src/Http/Response.php index 6b1e487..15bca1f 100644 --- a/kirby/src/Http/Response.php +++ b/kirby/src/Http/Response.php @@ -2,7 +2,9 @@ namespace Kirby\Http; +use Closure; use Exception; +use Kirby\Exception\LogicException; use Kirby\Filesystem\F; use Throwable; @@ -22,49 +24,33 @@ class Response /** * Store for all registered headers, * which will be sent with the response - * - * @var array */ - protected $headers = []; + protected array $headers = []; /** * The response body - * - * @var string */ - protected $body; + protected string $body; /** * The HTTP response code - * - * @var int */ - protected $code; + protected int $code; /** * The content type for the response - * - * @var string */ - protected $type; + protected string $type; /** * The content type charset - * - * @var string */ - protected $charset = 'UTF-8'; + protected string $charset = 'UTF-8'; /** * Creates a new response object - * - * @param string $body - * @param string $type - * @param int $code - * @param array $headers - * @param string $charset */ - public function __construct($body = '', ?string $type = null, ?int $code = null, ?array $headers = null, ?string $charset = null) + public function __construct(string|array $body = '', string|null $type = null, int|null $code = null, array|null $headers = null, string|null $charset = null) { // array construction if (is_array($body) === true) { @@ -91,8 +77,6 @@ class Response /** * Improved `var_dump` output - * - * @return array */ public function __debugInfo(): array { @@ -103,22 +87,18 @@ class Response * Makes it possible to convert the * entire response object to a string * to send the headers and print the body - * - * @return string */ public function __toString(): string { try { return $this->send(); - } catch (Throwable $e) { + } catch (Throwable) { return ''; } } /** * Getter for the body - * - * @return string */ public function body(): string { @@ -127,8 +107,6 @@ class Response /** * Getter for the content type charset - * - * @return string */ public function charset(): string { @@ -137,8 +115,6 @@ class Response /** * Getter for the HTTP status code - * - * @return int */ public function code(): int { @@ -149,12 +125,9 @@ class Response * Creates a response that triggers * a file download for the given file * - * @param string $file - * @param string $filename * @param array $props Custom overrides for response props (e.g. headers) - * @return static */ - public static function download(string $file, string $filename = null, array $props = []) + public static function download(string $file, string|null $filename = null, array $props = []): static { if (file_exists($file) === false) { throw new Exception('The file could not be found'); @@ -186,11 +159,9 @@ class Response * Creates a response for a file and * sends the file content to the browser * - * @param string $file * @param array $props Custom overrides for response props (e.g. headers) - * @return static */ - public static function file(string $file, array $props = []) + public static function file(string $file, array $props = []): static { $props = array_merge([ 'body' => F::read($file), @@ -206,32 +177,42 @@ class Response * Urls can be relative or absolute. * @since 3.7.0 * - * @param string $url - * @param int $code - * @return void - * * @codeCoverageIgnore */ - public static function go(string $url = '/', int $code = 302) + public static function go(string $url = '/', int $code = 302): void { die(static::redirect($url, $code)); } + /** + * Ensures that the callback does not produce the first body output + * (used to show when loading a file creates side effects) + */ + public static function guardAgainstOutput(Closure $callback, ...$args): mixed + { + $before = headers_sent(); + $result = $callback(...$args); + $after = headers_sent($file, $line); + + if ($before === false && $after === true) { + throw new LogicException("Disallowed output from file $file:$line, possible accidental whitespace?"); + } + + return $result; + } + /** * Getter for single headers * * @param string $key Name of the header - * @return string|null */ - public function header(string $key): ?string + public function header(string $key): string|null { return $this->headers[$key] ?? null; } /** * Getter for all headers - * - * @return array */ public function headers(): array { @@ -241,14 +222,8 @@ class Response /** * Creates a json response with appropriate * header and automatic conversion of arrays. - * - * @param string|array $body - * @param int $code - * @param bool $pretty - * @param array $headers - * @return static */ - public static function json($body = '', ?int $code = null, ?bool $pretty = null, array $headers = []) + public static function json(string|array $body = '', int|null $code = null, bool|null $pretty = null, array $headers = []): static { if (is_array($body) === true) { $body = json_encode($body, $pretty === true ? JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES : 0); @@ -266,12 +241,8 @@ class Response * Creates a redirect response, * which will send the visitor to the * given location. - * - * @param string $location - * @param int $code - * @return static */ - public static function redirect(string $location = '/', int $code = 302) + public static function redirect(string $location = '/', int $code = 302): static { return new static([ 'code' => $code, @@ -284,8 +255,6 @@ class Response /** * Sends all registered headers and * returns the response body - * - * @return string */ public function send(): string { @@ -308,8 +277,6 @@ class Response * Converts all relevant response attributes * to an associative array for debugging, * testing or whatever. - * - * @return array */ public function toArray(): array { @@ -324,8 +291,6 @@ class Response /** * Getter for the content type - * - * @return string */ public function type(): string { diff --git a/kirby/src/Http/Route.php b/kirby/src/Http/Route.php index 007e481..3aa1d8c 100644 --- a/kirby/src/Http/Route.php +++ b/kirby/src/Http/Route.php @@ -15,47 +15,35 @@ class Route { /** * The callback action function - * - * @var Closure */ - protected $action; + protected Closure $action; /** * Listed of parsed arguments - * - * @var array */ - protected $arguments = []; + protected array $arguments = []; /** * An array of all passed attributes - * - * @var array */ - protected $attributes = []; + protected array $attributes = []; /** * The registered request method - * - * @var string */ - protected $method; + protected string $method; /** * The registered pattern - * - * @var string */ - protected $pattern; + protected string $pattern; /** * Wildcards, which can be used in * Route patterns to make regular expressions * a little more human - * - * @var array */ - protected $wildcards = [ + protected array $wildcards = [ 'required' => [ '(:num)' => '(-?[0-9]+)', '(:alpha)' => '([a-zA-Z]+)', @@ -74,10 +62,6 @@ class Route /** * Magic getter for route attributes - * - * @param string $key - * @param array $arguments - * @return mixed */ public function __call(string $key, array $arguments = null) { @@ -87,13 +71,8 @@ class Route /** * Creates a new Route object for the given * pattern(s), method(s) and the callback action - * - * @param string|array $pattern - * @param string|array $method - * @param Closure $action - * @param array $attributes */ - public function __construct($pattern, $method, Closure $action, array $attributes = []) + public function __construct(string $pattern, string $method, Closure $action, array $attributes = []) { $this->action = $action; $this->attributes = $attributes; @@ -103,18 +82,14 @@ class Route /** * Getter for the action callback - * - * @return Closure */ - public function action() + public function action(): Closure { return $this->action; } /** * Returns all parsed arguments - * - * @return array */ public function arguments(): array { @@ -123,8 +98,6 @@ class Route /** * Getter for additional attributes - * - * @return array */ public function attributes(): array { @@ -133,8 +106,6 @@ class Route /** * Getter for the method - * - * @return string */ public function method(): string { @@ -143,10 +114,8 @@ class Route /** * Returns the route name if set - * - * @return string|null */ - public function name(): ?string + public function name(): string|null { return $this->attributes['name'] ?? null; } @@ -155,8 +124,6 @@ class Route * Throws a specific exception to tell * the router to jump to the next route * @since 3.0.3 - * - * @return void */ public static function next(): void { @@ -165,8 +132,6 @@ class Route /** * Getter for the pattern - * - * @return string */ public function pattern(): string { @@ -176,9 +141,6 @@ class Route /** * Converts the pattern into a full regular * expression by replacing all the wildcards - * - * @param string $pattern - * @return string */ public function regex(string $pattern): string { @@ -200,12 +162,8 @@ class Route /** * Tries to match the path with the regular expression and * extracts all arguments for the Route action - * - * @param string $pattern - * @param string $path - * @return array|false */ - public function parse(string $pattern, string $path) + public function parse(string $pattern, string $path): array|false { // check for direct matches if ($pattern === $path) { diff --git a/kirby/src/Http/Router.php b/kirby/src/Http/Router.php index aceb2b6..6481a63 100644 --- a/kirby/src/Http/Router.php +++ b/kirby/src/Http/Router.php @@ -18,35 +18,27 @@ class Router { /** * Hook that is called after each route - * - * @var \Closure */ - protected $afterEach; + protected Closure|null $afterEach; /** * Hook that is called before each route - * - * @var \Closure */ - protected $beforeEach; + protected Closure|null $beforeEach; /** * Store for the current route, * if one can be found - * - * @var \Kirby\Http\Route|null */ - protected $route; + protected Route|null $route = null; /** * All registered routes, sorted by * their request method. This makes * it faster to find the right route * later. - * - * @var array */ - protected $routes = [ + protected array $routes = [ 'GET' => [], 'HEAD' => [], 'POST' => [], @@ -62,7 +54,6 @@ class Router * Creates a new router object and * registers all the given routes * - * @param array $routes * @param array $hooks Optional `beforeEach` and `afterEach` hooks */ public function __construct(array $routes = [], array $hooks = []) @@ -104,14 +95,12 @@ class Router * and then call the Route action with * the appropriate arguments and a Result * object. - * - * @param string $path - * @param string $method - * @param Closure|null $callback - * @return mixed */ - public function call(string $path = null, string $method = 'GET', Closure $callback = null) - { + public function call( + string|null $path = null, + string $method = 'GET', + Closure|null $callback = null + ) { $path ??= ''; $ignore = []; $result = null; @@ -120,7 +109,7 @@ class Router while ($loop === true) { $route = $this->find($path, $method, $ignore); - if (is_a($this->beforeEach, 'Closure') === true) { + if ($this->beforeEach instanceof Closure) { ($this->beforeEach)($route, $path, $method); } @@ -128,15 +117,15 @@ class Router if ($callback) { $result = $callback($route); } else { - $result = $route->action()->call($route, ...$route->arguments()); + $result = $route?->action()->call($route, ...$route->arguments()); } $loop = false; - } catch (Exceptions\NextRouteException $e) { + } catch (Exceptions\NextRouteException) { $ignore[] = $route; } - if (is_a($this->afterEach, 'Closure') === true) { + if ($this->afterEach instanceof Closure) { $final = $loop === false; $result = ($this->afterEach)($route, $path, $method, $result, $final); } @@ -149,14 +138,8 @@ class Router * Creates a micro-router and executes * the routing action immediately * @since 3.7.0 - * - * @param string|null $path - * @param string $method - * @param array $routes - * @param \Closure|null $callback - * @return mixed */ - public static function execute(?string $path = null, string $method = 'GET', array $routes = [], ?Closure $callback = null) + public static function execute(string|null $path = null, string $method = 'GET', array $routes = [], Closure|null $callback = null) { return (new static($routes))->call($path, $method, $callback); } @@ -166,13 +149,8 @@ class Router * The Route's arguments method is used to * find matches and return all the found * arguments in the path. - * - * @param string $path - * @param string $method - * @param array $ignore - * @return \Kirby\Http\Route|null */ - public function find(string $path, string $method, array $ignore = null) + public function find(string $path, string $method, array|null $ignore = null): Route|null { if (isset($this->routes[$method]) === false) { throw new InvalidArgumentException('Invalid routing method: ' . $method, 400); @@ -199,10 +177,8 @@ class Router * This will only return something, * once Router::find() has been called * and only if a route was found. - * - * @return \Kirby\Http\Route|null */ - public function route() + public function route(): Route|null { return $this->route; } diff --git a/kirby/src/Http/Server.php b/kirby/src/Http/Server.php deleted file mode 100644 index d16118f..0000000 --- a/kirby/src/Http/Server.php +++ /dev/null @@ -1,38 +0,0 @@ - - * @link https://getkirby.com - * @copyright Bastian Allgeier - * @license https://opensource.org/licenses/MIT - * @deprecated 3.7.0 Use `Kirby\Http\Environment` instead - * @todo Remove in 3.8.0 - */ -class Server extends Facade -{ - public const HOST_FROM_SERVER = 1; - public const HOST_FROM_HEADER = 2; - public const HOST_ALLOW_EMPTY = 4; - - public static $cli; - public static $hosts; - - /** - * @return \Kirby\Http\Environment - */ - public static function instance() - { - return new Environment([ - 'cli' => static::$cli, - 'allowed' => static::$hosts - ]); - } -} diff --git a/kirby/src/Http/Uri.php b/kirby/src/Http/Uri.php index 48f8587..087cc8a 100644 --- a/kirby/src/Http/Uri.php +++ b/kirby/src/Http/Uri.php @@ -22,99 +22,68 @@ class Uri /** * Cache for the current Uri object - * - * @var Uri|null */ - public static $current; + public static Uri|null $current = null; /** * The fragment after the hash - * - * @var string|false */ - protected $fragment; + protected string|false|null $fragment = null; /** * The host address - * - * @var string */ - protected $host; + protected string|null $host = null; /** * The optional password for basic authentication - * - * @var string|false */ - protected $password; + protected string|false|null $password = null; /** * The optional list of params - * - * @var Params */ - protected $params; + protected Params|null $params = null; /** * The optional path - * - * @var Path */ - protected $path; + protected Path|null $path = null; /** * The optional port number - * - * @var int|false */ - protected $port; + protected int|false|null $port = null; /** * All original properties - * - * @var array */ - protected $props; + protected array $props; /** * The optional query string without leading ? - * - * @var Query */ - protected $query; + protected Query|null $query = null; /** * https or http - * - * @var string */ - protected $scheme = 'http'; + protected string|null $scheme = 'http'; /** * Supported schemes - * - * @var array */ - protected static $schemes = ['http', 'https', 'ftp']; + protected static array $schemes = ['http', 'https', 'ftp']; - /** - * @var bool - */ - protected $slash = false; + protected bool $slash = false; /** * The optional username for basic authentication - * - * @var string|false */ - protected $username; + protected string|false|null $username = null; /** * Magic caller to access all properties - * - * @param string $property - * @param array $arguments - * @return mixed */ public function __call(string $property, array $arguments = []) { @@ -124,8 +93,6 @@ class Uri /** * Make sure that cloning also clones * the path and query objects - * - * @return void */ public function __clone() { @@ -137,10 +104,9 @@ class Uri /** * Creates a new URI object * - * @param array|string $props * @param array $inject Additional props to inject if a URL string is passed */ - public function __construct($props = [], array $inject = []) + public function __construct(array|string $props = [], array $inject = []) { if (is_string($props) === true) { $props = parse_url($props); @@ -160,9 +126,6 @@ class Uri /** * Magic getter - * - * @param string $property - * @return mixed */ public function __get(string $property) { @@ -171,10 +134,6 @@ class Uri /** * Magic setter - * - * @param string $property - * @param mixed $value - * @return void */ public function __set(string $property, $value): void { @@ -185,24 +144,20 @@ class Uri /** * Converts the URL object to string - * - * @return string */ public function __toString(): string { try { return $this->toString(); - } catch (Throwable $e) { + } catch (Throwable) { return ''; } } /** * Returns the auth details (username:password) - * - * @return string|null */ - public function auth(): ?string + public function auth(): string|null { $auth = trim($this->username . ':' . $this->password); return $auth !== ':' ? $auth : null; @@ -211,10 +166,8 @@ class Uri /** * Returns the base url (scheme + host) * without trailing slash - * - * @return string|null */ - public function base(): ?string + public function base(): string|null { if ($domain = $this->domain()) { return $this->scheme ? $this->scheme . '://' . $domain : $domain; @@ -226,11 +179,8 @@ class Uri /** * Clones the Uri object and applies optional * new props. - * - * @param array $props - * @return static */ - public function clone(array $props = []) + public function clone(array $props = []): static { $clone = clone $this; @@ -241,11 +191,7 @@ class Uri return $clone; } - /** - * @param array $props - * @return static - */ - public static function current(array $props = []) + public static function current(array $props = []): static { if (static::$current !== null) { return static::$current; @@ -261,11 +207,11 @@ class Uri } /** - * Returns the domain without scheme, path or query - * - * @return string|null + * Returns the domain without scheme, path or query. + * Includes auth part when not empty. + * Includes port number when different from 80 or 443. */ - public function domain(): ?string + public function domain(): string|null { if (empty($this->host) === true || $this->host === '/') { return null; @@ -287,33 +233,21 @@ class Uri return $domain; } - /** - * @return bool - */ public function hasFragment(): bool { return empty($this->fragment) === false; } - /** - * @return bool - */ public function hasPath(): bool { return $this->path()->isNotEmpty(); } - /** - * @return bool - */ public function hasQuery(): bool { return $this->query()->isNotEmpty(); } - /** - * @return bool - */ public function https(): bool { return $this->scheme() === 'https'; @@ -325,7 +259,7 @@ class Uri * * @return $this */ - public function idn() + public function idn(): static { if (empty($this->host) === false) { $this->setHost(Idn::decode($this->host)); @@ -336,11 +270,8 @@ class Uri /** * Creates an Uri object for the URL to the index.php * or any other executed script. - * - * @param array $props - * @return static */ - public static function index(array $props = []) + public static function index(array $props = []): static { if ($app = App::instance(null, true)) { $url = $app->url('index'); @@ -353,8 +284,6 @@ class Uri /** * Checks if the host exists - * - * @return bool */ public function isAbsolute(): bool { @@ -362,30 +291,27 @@ class Uri } /** - * @param string|null $fragment * @return $this */ - public function setFragment(string $fragment = null) + public function setFragment(string|null $fragment = null): static { $this->fragment = $fragment ? ltrim($fragment, '#') : null; return $this; } /** - * @param string $host * @return $this */ - public function setHost(string $host = null) + public function setHost(string|null $host = null): static { $this->host = $host; return $this; } /** - * @param \Kirby\Http\Params|string|array|false|null $params * @return $this */ - public function setParams($params = null) + public function setParams(Params|string|array|false|null $params = null): static { // ensure that the special constructor value of `false` // is never passed through as it's not supported by `Params` @@ -393,35 +319,32 @@ class Uri $params = []; } - $this->params = is_a($params, 'Kirby\Http\Params') === true ? $params : new Params($params); + $this->params = $params instanceof Params ? $params : new Params($params); return $this; } /** - * @param string|null $password * @return $this */ - public function setPassword(string $password = null) + public function setPassword(string|null $password = null): static { $this->password = $password; return $this; } /** - * @param \Kirby\Http\Path|string|array|null $path * @return $this */ - public function setPath($path = null) + public function setPath(Path|string|array|null $path = null): static { - $this->path = is_a($path, 'Kirby\Http\Path') === true ? $path : new Path($path); + $this->path = $path instanceof Path ? $path : new Path($path); return $this; } /** - * @param int|null $port * @return $this */ - public function setPort(int $port = null) + public function setPort(int|null $port = null): static { if ($port === 0) { $port = null; @@ -438,20 +361,18 @@ class Uri } /** - * @param \Kirby\Http\Query|string|array|null $query * @return $this */ - public function setQuery($query = null) + public function setQuery(Query|string|array|null $query = null): static { - $this->query = is_a($query, 'Kirby\Http\Query') === true ? $query : new Query($query); + $this->query = $query instanceof Query ? $query : new Query($query); return $this; } /** - * @param string $scheme * @return $this */ - public function setScheme(string $scheme = null) + public function setScheme(string|null $scheme = null): static { if ($scheme !== null && in_array($scheme, static::$schemes) === false) { throw new InvalidArgumentException('Invalid URL scheme: ' . $scheme); @@ -465,20 +386,18 @@ class Uri * Set if a trailing slash should be added to * the path when the URI is being built * - * @param bool $slash * @return $this */ - public function setSlash(bool $slash = false) + public function setSlash(bool $slash = false): static { $this->slash = $slash; return $this; } /** - * @param string|null $username * @return $this */ - public function setUsername(string $username = null) + public function setUsername(string|null $username = null): static { $this->username = $username; return $this; @@ -486,8 +405,6 @@ class Uri /** * Converts the Url object to an array - * - * @return array */ public function toArray(): array { @@ -513,8 +430,6 @@ class Uri /** * Returns the full URL as string - * - * @return string */ public function toString(): string { @@ -548,7 +463,7 @@ class Uri * * @return $this */ - public function unIdn() + public function unIdn(): static { if (empty($this->host) === false) { $this->setHost(Idn::encode($this->host)); @@ -560,7 +475,6 @@ class Uri * Parses the path inside the props and extracts * the params unless disabled * - * @param array $props * @return array Modified props array */ protected static function parsePath(array $props): array diff --git a/kirby/src/Http/Url.php b/kirby/src/Http/Url.php index e0c3cdf..23e5456 100644 --- a/kirby/src/Http/Url.php +++ b/kirby/src/Http/Url.php @@ -17,26 +17,18 @@ class Url { /** * The base Url to build absolute Urls from - * - * @var string */ - public static $home = '/'; + public static string|null $home = '/'; /** - * The current Uri object - * - * @var Uri + * The current Uri object as string */ - public static $current = null; + public static string|null $current = null; /** * Facade for all Uri object methods - * - * @param string $method - * @param array $arguments - * @return mixed */ - public static function __callStatic(string $method, $arguments) + public static function __callStatic(string $method, array $arguments) { return (new Uri($arguments[0] ?? static::current()))->$method(...array_slice($arguments, 1)); } @@ -44,30 +36,22 @@ class Url /** * Url Builder * Actually just a factory for `new Uri($parts)` - * - * @param array $parts - * @param string|null $url - * @return string */ - public static function build(array $parts = [], string $url = null): string + public static function build(array $parts = [], string|null $url = null): string { return (string)(new Uri($url ?? static::current()))->clone($parts); } /** * Returns the current url with all bells and whistles - * - * @return string */ public static function current(): string { - return static::$current = static::$current ?? static::toObject()->toString(); + return static::$current ??= static::toObject()->toString(); } /** * Returns the url for the current directory - * - * @return string */ public static function currentDir(): string { @@ -76,11 +60,9 @@ class Url /** * Tries to fix a broken url without protocol - * - * @param string|null $url - * @return string + * @psalm-return ($url is null ? string|null : string) */ - public static function fix(string $url = null): string + public static function fix(string|null $url = null): string|null { // make sure to not touch absolute urls return (!preg_match('!^(https|http|ftp)\:\/\/!i', $url ?? '')) ? 'http://' . $url : $url; @@ -88,8 +70,6 @@ class Url /** * Returns the home url if defined - * - * @return string */ public static function home(): string { @@ -98,9 +78,6 @@ class Url /** * Returns the url to the executed script - * - * @param array $props - * @return string */ public static function index(array $props = []): string { @@ -109,11 +86,8 @@ class Url /** * Checks if an URL is absolute - * - * @param string|null $url - * @return bool */ - public static function isAbsolute(string $url = null): bool + public static function isAbsolute(string|null $url = null): bool { // matches the following groups of URLs: // //example.com/uri @@ -124,12 +98,8 @@ class Url /** * Convert a relative path into an absolute URL - * - * @param string|null $path - * @param string|null $home - * @return string */ - public static function makeAbsolute(string $path = null, string $home = null): string + public static function makeAbsolute(string|null $path = null, string|null $home = null): string { if ($path === '' || $path === '/' || $path === null) { return $home ?? static::home(); @@ -156,32 +126,22 @@ class Url /** * Returns the path for the given url - * - * @param string|array|null $url - * @param bool $leadingSlash - * @param bool $trailingSlash - * @return string */ - public static function path($url = null, bool $leadingSlash = false, bool $trailingSlash = false): string + public static function path(string|array|null $url = null, bool $leadingSlash = false, bool $trailingSlash = false): string { return Url::toObject($url)->path()->toString($leadingSlash, $trailingSlash); } /** * Returns the query for the given url - * - * @param string|array|null $url - * @return string */ - public static function query($url = null): string + public static function query(string|array|null $url = null): string { return Url::toObject($url)->query()->toString(); } /** * Return the last url the user has been on if detectable - * - * @return string */ public static function last(): string { @@ -190,14 +150,8 @@ class Url /** * Shortens the Url by removing all unnecessary parts - * - * @param string $url - * @param int $length - * @param bool $base - * @param string $rep - * @return string */ - public static function short($url = null, int $length = 0, bool $base = false, string $rep = '…'): string + public static function short(string|null $url = null, int $length = 0, bool $base = false, string $rep = '…'): string { $uri = static::toObject($url); @@ -219,45 +173,32 @@ class Url /** * Removes the path from the Url - * - * @param string $url - * @return string */ - public static function stripPath($url = null): string + public static function stripPath(string|null $url = null): string { return static::toObject($url)->setPath(null)->toString(); } /** * Removes the query string from the Url - * - * @param string $url - * @return string */ - public static function stripQuery($url = null): string + public static function stripQuery(string|null $url = null): string { return static::toObject($url)->setQuery(null)->toString(); } /** * Removes the fragment (hash) from the Url - * - * @param string $url - * @return string */ - public static function stripFragment($url = null): string + public static function stripFragment(string|null $url = null): string { return static::toObject($url)->setFragment(null)->toString(); } /** * Smart resolver for internal and external urls - * - * @param string $path - * @param mixed $options - * @return string */ - public static function to(string $path = null, $options = null): string + public static function to(string|null $path = null, array $options = null): string { // make sure $path is string $path ??= ''; @@ -278,11 +219,8 @@ class Url /** * Converts the Url to a Uri object - * - * @param string $url - * @return \Kirby\Http\Uri */ - public static function toObject($url = null) + public static function toObject(string|null $url = null): Uri { return $url === null ? Uri::current() : new Uri($url); } diff --git a/kirby/src/Http/Visitor.php b/kirby/src/Http/Visitor.php index 6c1b2ac..bf1d56b 100644 --- a/kirby/src/Http/Visitor.php +++ b/kirby/src/Http/Visitor.php @@ -20,29 +20,10 @@ use Kirby\Toolkit\Str; */ class Visitor { - /** - * IP address - * @var string|null - */ - protected $ip; - - /** - * user agent - * @var string|null - */ - protected $userAgent; - - /** - * accepted language - * @var string|null - */ - protected $acceptedLanguage; - - /** - * accepted mime type - * @var string|null - */ - protected $acceptedMimeType; + protected string|null $ip = null; + protected string|null $userAgent = null; + protected string|null $acceptedLanguage = null; + protected string|null $acceptedMimeType = null; /** * Creates a new visitor object. @@ -50,8 +31,6 @@ class Visitor * modify the information about the visitor. * * By default everything is pulled from $_SERVER - * - * @param array $arguments */ public function __construct(array $arguments = []) { @@ -66,10 +45,9 @@ class Visitor * provided or returns the user's * accepted language otherwise * - * @param string|null $acceptedLanguage - * @return \Kirby\Toolkit\Obj|\Kirby\Http\Visitor|null + * @return $this|\Kirby\Toolkit\Obj|null */ - public function acceptedLanguage(string $acceptedLanguage = null) + public function acceptedLanguage(string|null $acceptedLanguage = null): static|Obj|null { if ($acceptedLanguage === null) { return $this->acceptedLanguages()->first(); @@ -82,10 +60,8 @@ class Visitor /** * Returns an array of all accepted languages * including their quality and locale - * - * @return \Kirby\Toolkit\Collection */ - public function acceptedLanguages() + public function acceptedLanguages(): Collection { $accepted = Str::accepted($this->acceptedLanguage); $languages = []; @@ -111,9 +87,6 @@ class Visitor /** * Checks if the user accepts the given language - * - * @param string $code - * @return bool */ public function acceptsLanguage(string $code): bool { @@ -133,10 +106,9 @@ class Visitor * provided or returns the user's * accepted mime type otherwise * - * @param string|null $acceptedMimeType - * @return \Kirby\Toolkit\Obj|\Kirby\Http\Visitor + * @return $this|\Kirby\Toolkit\Obj|null */ - public function acceptedMimeType(string $acceptedMimeType = null) + public function acceptedMimeType(string|null $acceptedMimeType = null): static|Obj|null { if ($acceptedMimeType === null) { return $this->acceptedMimeTypes()->first(); @@ -148,10 +120,8 @@ class Visitor /** * Returns a collection of all accepted mime types - * - * @return \Kirby\Toolkit\Collection */ - public function acceptedMimeTypes() + public function acceptedMimeTypes(): Collection { $accepted = Str::accepted($this->acceptedMimeType); $mimes = []; @@ -168,9 +138,6 @@ class Visitor /** * Checks if the user accepts the given mime type - * - * @param string $mimeType - * @return bool */ public function acceptsMimeType(string $mimeType): bool { @@ -185,7 +152,7 @@ class Visitor * @param string ...$mimeTypes MIME types to query for * @return string|null Preferred MIME type */ - public function preferredMimeType(string ...$mimeTypes): ?string + public function preferredMimeType(string ...$mimeTypes): string|null { foreach ($this->acceptedMimeTypes() as $acceptedMime) { // look for direct matches @@ -208,8 +175,6 @@ class Visitor * Returns true if the visitor prefers a JSON response over * an HTML response based on the `Accept` request header * @since 3.3.0 - * - * @return bool */ public function prefersJson(): bool { @@ -221,10 +186,9 @@ class Visitor * or returns the ip of the current * visitor otherwise * - * @param string|null $ip - * @return string|Visitor|null + * @return $this|string|null */ - public function ip(string $ip = null) + public function ip(string|null $ip = null): static|string|null { if ($ip === null) { return $this->ip; @@ -238,10 +202,9 @@ class Visitor * or returns the user agent string of * the current visitor otherwise * - * @param string|null $userAgent - * @return string|Visitor|null + * @return $this|string|null */ - public function userAgent(string $userAgent = null) + public function userAgent(string|null $userAgent = null): static|string|null { if ($userAgent === null) { return $this->userAgent; diff --git a/kirby/src/Image/Camera.php b/kirby/src/Image/Camera.php index 3cfb793..8655330 100644 --- a/kirby/src/Image/Camera.php +++ b/kirby/src/Image/Camera.php @@ -15,23 +15,16 @@ class Camera { /** * Make exif data - * - * @var string|null */ - protected $make; + protected string|null $make; /** * Model exif data * - * @var string|null + * @var */ - protected $model; + protected string|null $model; - /** - * Constructor - * - * @param array $exif - */ public function __construct(array $exif) { $this->make = $exif['Make'] ?? null; @@ -40,28 +33,22 @@ class Camera /** * Returns the make of the camera - * - * @return string */ - public function make(): ?string + public function make(): string|null { return $this->make; } /** * Returns the camera model - * - * @return string */ - public function model(): ?string + public function model(): string|null { return $this->model; } /** * Converts the object into a nicely readable array - * - * @return array */ public function toArray(): array { @@ -73,8 +60,6 @@ class Camera /** * Returns the full make + model name - * - * @return string */ public function __toString(): string { @@ -83,8 +68,6 @@ class Camera /** * Improved `var_dump` output - * - * @return array */ public function __debugInfo(): array { diff --git a/kirby/src/Image/Darkroom.php b/kirby/src/Image/Darkroom.php index 642273a..e8277ab 100644 --- a/kirby/src/Image/Darkroom.php +++ b/kirby/src/Image/Darkroom.php @@ -16,20 +16,15 @@ use Exception; */ class Darkroom { - public static $types = [ + public static array $types = [ 'gd' => 'Kirby\Image\Darkroom\GdLib', 'im' => 'Kirby\Image\Darkroom\ImageMagick' ]; - /** - * @var array - */ - protected $settings = []; + protected array $settings = []; /** * Darkroom constructor - * - * @param array $settings */ public function __construct(array $settings = []) { @@ -40,12 +35,9 @@ class Darkroom * Creates a new Darkroom instance for the given * type/driver * - * @param string $type - * @param array $settings - * @return mixed * @throws \Exception */ - public static function factory(string $type, array $settings = []) + public static function factory(string $type, array $settings = []): object { if (isset(static::$types[$type]) === false) { throw new Exception('Invalid Darkroom type'); @@ -57,8 +49,6 @@ class Darkroom /** * Returns the default thumb settings - * - * @return array */ protected function defaults(): array { @@ -78,9 +68,6 @@ class Darkroom /** * Normalizes all thumb options - * - * @param array $options - * @return array */ protected function options(array $options = []): array { @@ -108,9 +95,7 @@ class Darkroom unset($options['bw']); } - if ($options['quality'] === null) { - $options['quality'] = $this->settings['quality']; - } + $options['quality'] ??= $this->settings['quality']; return $options; } @@ -119,12 +104,8 @@ class Darkroom * Calculates the dimensions of the final thumb based * on the given options and returns a full array with * all the final options to be used for the image generator - * - * @param string $file - * @param array $options - * @return array */ - public function preprocess(string $file, array $options = []) + public function preprocess(string $file, array $options = []): array { $options = $this->options($options); $image = new Image($file); @@ -148,10 +129,6 @@ class Darkroom /** * This method must be replaced by the driver to run the * actual image processing job. - * - * @param string $file - * @param array $options - * @return array */ public function process(string $file, array $options = []): array { diff --git a/kirby/src/Image/Darkroom/GdLib.php b/kirby/src/Image/Darkroom/GdLib.php index bc381e6..38efc87 100644 --- a/kirby/src/Image/Darkroom/GdLib.php +++ b/kirby/src/Image/Darkroom/GdLib.php @@ -19,10 +19,6 @@ class GdLib extends Darkroom { /** * Processes the image with the SimpleImage library - * - * @param string $file - * @param array $options - * @return array */ public function process(string $file, array $options = []): array { @@ -45,12 +41,8 @@ class GdLib extends Darkroom /** * Activates the autoOrient option in SimpleImage * unless this is deactivated - * - * @param \claviska\SimpleImage $image - * @param $options - * @return \claviska\SimpleImage */ - protected function autoOrient(SimpleImage $image, $options) + protected function autoOrient(SimpleImage $image, array $options): SimpleImage { if ($options['autoOrient'] === false) { return $image; @@ -61,12 +53,8 @@ class GdLib extends Darkroom /** * Wrapper around SimpleImage's resize and crop methods - * - * @param \claviska\SimpleImage $image - * @param array $options - * @return \claviska\SimpleImage */ - protected function resize(SimpleImage $image, array $options) + protected function resize(SimpleImage $image, array $options): SimpleImage { if ($options['crop'] === false) { return $image->resize($options['width'], $options['height']); @@ -77,12 +65,8 @@ class GdLib extends Darkroom /** * Applies the correct blur settings for SimpleImage - * - * @param \claviska\SimpleImage $image - * @param array $options - * @return \claviska\SimpleImage */ - protected function blur(SimpleImage $image, array $options) + protected function blur(SimpleImage $image, array $options): SimpleImage { if ($options['blur'] === false) { return $image; @@ -93,12 +77,8 @@ class GdLib extends Darkroom /** * Applies grayscale conversion if activated in the options. - * - * @param \claviska\SimpleImage $image - * @param array $options - * @return \claviska\SimpleImage */ - protected function grayscale(SimpleImage $image, array $options) + protected function grayscale(SimpleImage $image, array $options): SimpleImage { if ($options['grayscale'] === false) { return $image; @@ -109,11 +89,8 @@ class GdLib extends Darkroom /** * Returns mime type based on `format` option - * - * @param array $options - * @return string|null */ - protected function mime(array $options): ?string + protected function mime(array $options): string|null { if ($options['format'] === null) { return null; diff --git a/kirby/src/Image/Darkroom/ImageMagick.php b/kirby/src/Image/Darkroom/ImageMagick.php index 33e33aa..cf10cf2 100644 --- a/kirby/src/Image/Darkroom/ImageMagick.php +++ b/kirby/src/Image/Darkroom/ImageMagick.php @@ -20,52 +20,42 @@ class ImageMagick extends Darkroom /** * Activates imagemagick's auto-orient feature unless * it is deactivated via the options - * - * @param string $file - * @param array $options - * @return string */ - protected function autoOrient(string $file, array $options) + protected function autoOrient(string $file, array $options): string|null { if ($options['autoOrient'] === true) { return '-auto-orient'; } + + return null; } /** * Applies the blur settings - * - * @param string $file - * @param array $options - * @return string */ - protected function blur(string $file, array $options) + protected function blur(string $file, array $options): string|null { if ($options['blur'] !== false) { return '-blur ' . escapeshellarg('0x' . $options['blur']); } + + return null; } /** * Keep animated gifs - * - * @param string $file - * @param array $options - * @return string */ - protected function coalesce(string $file, array $options) + protected function coalesce(string $file, array $options): string|null { if (F::extension($file) === 'gif') { return '-coalesce'; } + + return null; } /** * Creates the convert command with the right path to the binary file - * - * @param string $file - * @param array $options - * @return string */ protected function convert(string $file, array $options): string { @@ -88,8 +78,6 @@ class ImageMagick extends Darkroom /** * Returns additional default parameters for imagemagick - * - * @return array */ protected function defaults(): array { @@ -101,40 +89,33 @@ class ImageMagick extends Darkroom /** * Applies the correct settings for grayscale images - * - * @param string $file - * @param array $options - * @return string */ - protected function grayscale(string $file, array $options) + protected function grayscale(string $file, array $options): string|null { if ($options['grayscale'] === true) { return '-colorspace gray'; } + + return null; } /** * Applies the correct settings for interlaced JPEGs if * activated via options - * - * @param string $file - * @param array $options - * @return string */ - protected function interlace(string $file, array $options) + protected function interlace(string $file, array $options): string|null { if ($options['interlace'] === true) { return '-interlace line'; } + + return null; } /** * Creates and runs the full imagemagick command * to process the image * - * @param string $file - * @param array $options - * @return array * @throws \Exception */ public function process(string $file, array $options = []): array @@ -169,10 +150,6 @@ class ImageMagick extends Darkroom /** * Applies the correct JPEG compression quality settings - * - * @param string $file - * @param array $options - * @return string */ protected function quality(string $file, array $options): string { @@ -182,10 +159,6 @@ class ImageMagick extends Darkroom /** * Creates the correct options to crop or resize the image * and translates the crop positions for imagemagick - * - * @param string $file - * @param array $options - * @return string */ protected function resize(string $file, array $options): string { @@ -218,10 +191,6 @@ class ImageMagick extends Darkroom /** * Creates the option for the output file - * - * @param string $file - * @param array $options - * @return string */ protected function save(string $file, array $options): string { @@ -234,10 +203,6 @@ class ImageMagick extends Darkroom /** * Removes all metadata from the image - * - * @param string $file - * @param array $options - * @return string */ protected function strip(string $file, array $options): string { diff --git a/kirby/src/Image/Dimensions.php b/kirby/src/Image/Dimensions.php index 30931c6..f1da3a3 100644 --- a/kirby/src/Image/Dimensions.php +++ b/kirby/src/Image/Dimensions.php @@ -16,36 +16,14 @@ namespace Kirby\Image; */ class Dimensions { - /** - * the height of the parent object - * - * @var int - */ - public $height = 0; - - /** - * the width of the parent object - * - * @var int - */ - public $width = 0; - - /** - * Constructor - * - * @param int $width - * @param int $height - */ - public function __construct(int $width, int $height) - { - $this->width = $width; - $this->height = $height; + public function __construct( + public int $width, + public int $height + ) { } /** * Improved `var_dump` output - * - * @return array */ public function __debugInfo(): array { @@ -54,8 +32,6 @@ class Dimensions /** * Echos the dimensions as width × height - * - * @return string */ public function __toString(): string { @@ -65,11 +41,9 @@ class Dimensions /** * Crops the dimensions by width and height * - * @param int $width - * @param int|null $height * @return $this */ - public function crop(int $width, int $height = null) + public function crop(int $width, int|null $height = null): static { $this->width = $width; $this->height = $width; @@ -83,10 +57,8 @@ class Dimensions /** * Returns the height - * - * @return int */ - public function height() + public function height(): int { return $this->height; } @@ -112,7 +84,7 @@ class Dimensions * upscaled to fit the box if smaller * @return $this object with recalculated dimensions */ - public function fit(int $box, bool $force = false) + public function fit(int $box, bool $force = false): static { if ($this->width === 0 || $this->height === 0) { $this->width = $box; @@ -164,7 +136,7 @@ class Dimensions * upscaled to fit the box if smaller * @return $this object with recalculated dimensions */ - public function fitHeight(int $fit = null, bool $force = false) + public function fitHeight(int|null $fit = null, bool $force = false): static { return $this->fitSize('height', $fit, $force); } @@ -178,7 +150,7 @@ class Dimensions * upscaled to fit the box if smaller * @return $this object with recalculated dimensions */ - protected function fitSize(string $ref, int $fit = null, bool $force = false) + protected function fitSize(string $ref, int|null $fit = null, bool $force = false): static { if ($fit === 0 || $fit === null) { return $this; @@ -217,7 +189,7 @@ class Dimensions * upscaled to fit the box if smaller * @return $this object with recalculated dimensions */ - public function fitWidth(int $fit = null, bool $force = false) + public function fitWidth(int|null $fit = null, bool $force = false): static { return $this->fitSize('width', $fit, $force); } @@ -227,11 +199,13 @@ class Dimensions * * @param int|null $width the max height * @param int|null $height the max width - * @param bool $force * @return $this */ - public function fitWidthAndHeight(int $width = null, int $height = null, bool $force = false) - { + public function fitWidthAndHeight( + int|null $width = null, + int|null $height = null, + bool $force = false + ): static { if ($this->width > $this->height) { $this->fitWidth($width, $force); @@ -253,11 +227,8 @@ class Dimensions /** * Detect the dimensions for an image file - * - * @param string $root - * @return static */ - public static function forImage(string $root) + public static function forImage(string $root): static { if (file_exists($root) === false) { return new static(0, 0); @@ -269,11 +240,8 @@ class Dimensions /** * Detect the dimensions for a svg file - * - * @param string $root - * @return static */ - public static function forSvg(string $root) + public static function forSvg(string $root): static { // avoid xml errors libxml_use_internal_errors(true); @@ -299,8 +267,6 @@ class Dimensions /** * Checks if the dimensions are landscape - * - * @return bool */ public function landscape(): bool { @@ -309,10 +275,8 @@ class Dimensions /** * Returns a string representation of the orientation - * - * @return string|false */ - public function orientation() + public function orientation(): string|false { if (!$this->ratio()) { return false; @@ -331,8 +295,6 @@ class Dimensions /** * Checks if the dimensions are portrait - * - * @return bool */ public function portrait(): bool { @@ -349,8 +311,6 @@ class Dimensions * // output: 1.5625 * * - * - * @return float */ public function ratio(): float { @@ -362,20 +322,19 @@ class Dimensions } /** - * @param int|null $width - * @param int|null $height - * @param bool $force + * Resizes image * @return $this */ - public function resize(int $width = null, int $height = null, bool $force = false) - { + public function resize( + int|null $width = null, + int|null $height = null, + bool $force = false + ): static { return $this->fitWidthAndHeight($width, $height, $force); } /** * Checks if the dimensions are square - * - * @return bool */ public function square(): bool { @@ -385,10 +344,9 @@ class Dimensions /** * Resize and crop * - * @param array $options * @return $this */ - public function thumb(array $options = []) + public function thumb(array $options = []): static { $width = $options['width'] ?? null; $height = $options['height'] ?? null; @@ -405,8 +363,6 @@ class Dimensions /** * Converts the dimensions object * to a plain PHP array - * - * @return array */ public function toArray(): array { @@ -420,8 +376,6 @@ class Dimensions /** * Returns the width - * - * @return int */ public function width(): int { diff --git a/kirby/src/Image/Exif.php b/kirby/src/Image/Exif.php index 9405271..b03573a 100644 --- a/kirby/src/Image/Exif.php +++ b/kirby/src/Image/Exif.php @@ -16,75 +16,55 @@ use Kirby\Toolkit\V; class Exif { /** - * the parent image object - * @var \Kirby\Image\Image + * The parent image object */ - protected $image; + protected Image $image; /** - * the raw exif array - * @var array + * The raw exif array */ - protected $data = []; + protected array $data = []; /** - * the camera object with model and make - * @var Camera + * The camera object with model and make */ - protected $camera; + protected Camera|null $camera = null; /** - * the location object - * @var Location + * The location object */ - protected $location; + protected Location|null $location = null; /** - * the timestamp - * - * @var string + * The timestamp */ - protected $timestamp; + protected string|null $timestamp = null; /** - * the exposure value - * - * @var string + * The exposure value */ - protected $exposure; + protected string|null $exposure = null; /** - * the aperture value - * - * @var string + * The aperture value */ - protected $aperture; + protected string|null $aperture = null; /** - * iso value - * - * @var string + * ISO value */ - protected $iso; + protected string|null $iso = null; /** - * focal length - * - * @var string + * Focal length */ - protected $focalLength; + protected string|null $focalLength = null; /** - * color or black/white - * @var bool + * Color or black/white */ - protected $isColor; + protected bool|null $isColor = null; - /** - * Constructor - * - * @param \Kirby\Image\Image $image - */ public function __construct(Image $image) { $this->image = $image; @@ -94,8 +74,6 @@ class Exif /** * Returns the raw data array from the parser - * - * @return array */ public function data(): array { @@ -104,10 +82,8 @@ class Exif /** * Returns the Camera object - * - * @return \Kirby\Image\Camera|null */ - public function camera() + public function camera(): Camera { if ($this->camera !== null) { return $this->camera; @@ -118,10 +94,8 @@ class Exif /** * Returns the location object - * - * @return \Kirby\Image\Location|null */ - public function location() + public function location(): Location { if ($this->location !== null) { return $this->location; @@ -132,78 +106,62 @@ class Exif /** * Returns the timestamp - * - * @return string|null */ - public function timestamp() + public function timestamp(): string|null { return $this->timestamp; } /** * Returns the exposure - * - * @return string|null */ - public function exposure() + public function exposure(): string|null { return $this->exposure; } /** * Returns the aperture - * - * @return string|null */ - public function aperture() + public function aperture(): string|null { return $this->aperture; } /** * Returns the iso value - * - * @return int|null */ - public function iso() + public function iso(): string|null { return $this->iso; } /** * Checks if this is a color picture - * - * @return bool|null */ - public function isColor() + public function isColor(): bool|null { return $this->isColor; } /** * Checks if this is a bw picture - * - * @return bool|null */ - public function isBW(): ?bool + public function isBW(): bool|null { return ($this->isColor !== null) ? $this->isColor === false : null; } /** * Returns the focal length - * - * @return string|null */ - public function focalLength() + public function focalLength(): string|null { return $this->focalLength; } /** * Read the exif data of the image object if possible - * - * @return mixed */ protected function read(): array { @@ -219,8 +177,6 @@ class Exif /** * Get all computed data - * - * @return array */ protected function computed(): array { @@ -228,9 +184,9 @@ class Exif } /** - * Pareses and stores all relevant exif data + * Parses and stores all relevant exif data */ - protected function parse() + protected function parse(): void { $this->timestamp = $this->parseTimestamp(); $this->exposure = $this->data['ExposureTime'] ?? null; @@ -242,13 +198,13 @@ class Exif /** * Return the timestamp when the picture has been taken - * - * @return string|int */ - protected function parseTimestamp() + protected function parseTimestamp(): string { if (isset($this->data['DateTimeOriginal']) === true) { - return strtotime($this->data['DateTimeOriginal']); + if ($time = strtotime($this->data['DateTimeOriginal'])) { + return (string)$time; + } } return $this->data['FileDateTime'] ?? $this->image->modified(); @@ -256,24 +212,22 @@ class Exif /** * Return the focal length - * - * @return string|null */ - protected function parseFocalLength() + protected function parseFocalLength(): string|null { - return $this->data['FocalLength'] ?? $this->data['FocalLengthIn35mmFilm'] ?? null; + return $this->data['FocalLength'] ?? + $this->data['FocalLengthIn35mmFilm'] ?? + null; } /** * Converts the object into a nicely readable array - * - * @return array */ public function toArray(): array { return [ - 'camera' => $this->camera() ? $this->camera()->toArray() : null, - 'location' => $this->location() ? $this->location()->toArray() : null, + 'camera' => $this->camera()->toArray(), + 'location' => $this->location()->toArray(), 'timestamp' => $this->timestamp(), 'exposure' => $this->exposure(), 'aperture' => $this->aperture(), @@ -285,8 +239,6 @@ class Exif /** * Improved `var_dump` output - * - * @return array */ public function __debugInfo(): array { diff --git a/kirby/src/Image/Image.php b/kirby/src/Image/Image.php index b505a9a..5779eb1 100644 --- a/kirby/src/Image/Image.php +++ b/kirby/src/Image/Image.php @@ -2,6 +2,7 @@ namespace Kirby\Image; +use Kirby\Exception\LogicException; use Kirby\Filesystem\File; use Kirby\Toolkit\Html; @@ -22,20 +23,10 @@ use Kirby\Toolkit\Html; */ class Image extends File { - /** - * @var \Kirby\Image\Exif|null - */ - protected $exif; + protected Exif|null $exif = null; + protected Dimensions|null $dimensions = null; - /** - * @var \Kirby\Image\Dimensions|null - */ - protected $dimensions; - - /** - * @var array - */ - public static $resizableTypes = [ + public static array $resizableTypes = [ 'jpg', 'jpeg', 'gif', @@ -43,10 +34,7 @@ class Image extends File 'webp' ]; - /** - * @var array - */ - public static $viewableTypes = [ + public static array $viewableTypes = [ 'avif', 'jpg', 'jpeg', @@ -58,10 +46,8 @@ class Image extends File /** * Validation rules to be used for `::match()` - * - * @var array */ - public static $validations = [ + public static array $validations = [ 'maxsize' => ['size', 'max'], 'minsize' => ['size', 'min'], 'maxwidth' => ['width', 'max'], @@ -73,8 +59,6 @@ class Image extends File /** * Returns the `` tag for the image object - * - * @return string */ public function __toString(): string { @@ -83,10 +67,8 @@ class Image extends File /** * Returns the dimensions of the file if possible - * - * @return \Kirby\Image\Dimensions */ - public function dimensions() + public function dimensions(): Dimensions { if ($this->dimensions !== null) { return $this->dimensions; @@ -111,18 +93,14 @@ class Image extends File /** * Returns the exif object for this file (if image) - * - * @return \Kirby\Image\Exif */ - public function exif() + public function exif(): Exif { return $this->exif ??= new Exif($this); } /** * Returns the height of the asset - * - * @return int */ public function height(): int { @@ -131,19 +109,18 @@ class Image extends File /** * Converts the file to html - * - * @param array $attr - * @return string */ public function html(array $attr = []): string { - return Html::img($this->url(), $attr); + if ($url = $this->url()) { + return Html::img($url, $attr); + } + + throw new LogicException('Calling Image::html() requires that the URL property is not null'); } /** * Returns the PHP imagesize array - * - * @return array */ public function imagesize(): array { @@ -152,8 +129,6 @@ class Image extends File /** * Checks if the dimensions of the asset are portrait - * - * @return bool */ public function isPortrait(): bool { @@ -162,8 +137,6 @@ class Image extends File /** * Checks if the dimensions of the asset are landscape - * - * @return bool */ public function isLandscape(): bool { @@ -172,8 +145,6 @@ class Image extends File /** * Checks if the dimensions of the asset are square - * - * @return bool */ public function isSquare(): bool { @@ -182,8 +153,6 @@ class Image extends File /** * Checks if the file is a resizable image - * - * @return bool */ public function isResizable(): bool { @@ -193,8 +162,6 @@ class Image extends File /** * Checks if a preview can be displayed for the file * in the Panel or in the frontend - * - * @return bool */ public function isViewable(): bool { @@ -203,8 +170,6 @@ class Image extends File /** * Returns the ratio of the asset - * - * @return float */ public function ratio(): float { @@ -213,19 +178,15 @@ class Image extends File /** * Returns the orientation as string - * landscape | portrait | square - * - * @return string + * `landscape` | `portrait` | `square` */ - public function orientation(): string + public function orientation(): string|false { return $this->dimensions()->orientation(); } /** * Converts the object to an array - * - * @return array */ public function toArray(): array { @@ -241,8 +202,6 @@ class Image extends File /** * Returns the width of the asset - * - * @return int */ public function width(): int { diff --git a/kirby/src/Image/Location.php b/kirby/src/Image/Location.php index 00b65c4..4b60c6a 100644 --- a/kirby/src/Image/Location.php +++ b/kirby/src/Image/Location.php @@ -14,19 +14,8 @@ namespace Kirby\Image; */ class Location { - /** - * latitude - * - * @var float|null - */ - protected $lat; - - /** - * longitude - * - * @var float|null - */ - protected $lng; + protected float|null $lat = null; + protected float|null $lng = null; /** * Constructor @@ -47,32 +36,24 @@ class Location /** * Returns the latitude - * - * @return float|null */ - public function lat() + public function lat(): float|null { return $this->lat; } /** * Returns the longitude - * - * @return float|null */ - public function lng() + public function lng(): float|null { return $this->lng; } /** * Converts the gps coordinates - * - * @param string|array $coord - * @param string $hemi - * @return float */ - protected function gps($coord, string $hemi): float + protected function gps(array $coord, string $hemi): float { $degrees = count($coord) > 0 ? $this->num($coord[0]) : 0; $minutes = count($coord) > 1 ? $this->num($coord[1]) : 0; @@ -86,9 +67,6 @@ class Location /** * Converts coordinates to floats - * - * @param string $part - * @return float */ protected function num(string $part): float { @@ -103,8 +81,6 @@ class Location /** * Converts the object into a nicely readable array - * - * @return array */ public function toArray(): array { @@ -116,8 +92,6 @@ class Location /** * Echos the entire location as lat, lng - * - * @return string */ public function __toString(): string { @@ -126,8 +100,6 @@ class Location /** * Improved `var_dump` output - * - * @return array */ public function __debugInfo(): array { diff --git a/kirby/src/Option/Option.php b/kirby/src/Option/Option.php new file mode 100644 index 0000000..314e7cf --- /dev/null +++ b/kirby/src/Option/Option.php @@ -0,0 +1,64 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + */ +class Option +{ + public function __construct( + public float|int|string|null $value, + public bool $disabled = false, + public NodeIcon|null $icon = null, + public NodeText|null $info = null, + public NodeText|null $text = null + ) { + $this->text ??= new NodeText(['en' => $this->value]); + } + + public static function factory(float|int|string|null|array $props): static + { + if (is_array($props) === false) { + $props = ['value' => $props]; + } + + $props = Factory::apply($props, [ + 'icon' => NodeIcon::class, + 'info' => NodeText::class, + 'text' => NodeText::class + ]); + + return new static(...$props); + } + + public function id(): string|int|float + { + return $this->value ?? ''; + } + + /** + * Renders all data for the option + */ + public function render(ModelWithContent $model): array + { + return [ + 'disabled' => $this->disabled, + 'icon' => $this->icon?->render($model), + 'info' => $this->info?->render($model), + 'text' => $this->text?->render($model), + 'value' => $this->value + ]; + } +} diff --git a/kirby/src/Option/Options.php b/kirby/src/Option/Options.php new file mode 100644 index 0000000..b1b31c6 --- /dev/null +++ b/kirby/src/Option/Options.php @@ -0,0 +1,55 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + */ +class Options extends Collection +{ + public const TYPE = Option::class; + + public function __construct(array $objects = []) + { + foreach ($objects as $object) { + $this->__set($object->value, $object); + } + } + + public static function factory(array $items = []): static + { + $collection = new static(); + + foreach ($items as $key => $option) { + // skip if option is already an array of option props + if ( + is_array($option) === false || + array_key_exists('value', $option) === false + ) { + $option = match (true) { + is_string($key) => ['value' => $key, 'text' => $option], + default => ['value' => $option] + }; + } + + $option = Option::factory($option); + $collection->__set($option->id(), $option); + } + + return $collection; + } + + public function render(ModelWithContent $model): array + { + return array_values(parent::render($model)); + } +} diff --git a/kirby/src/Option/OptionsApi.php b/kirby/src/Option/OptionsApi.php new file mode 100644 index 0000000..59fc145 --- /dev/null +++ b/kirby/src/Option/OptionsApi.php @@ -0,0 +1,127 @@ +, + * Nico Hoffmann + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + */ +class OptionsApi extends OptionsProvider +{ + public function __construct( + public string $url, + public string|null $query = null, + public string|null $text = null, + public string|null $value = null + ) { + } + + public function defaults(): static + { + $this->text ??= '{{ item.value }}'; + $this->value ??= '{{ item.key }}'; + return $this; + } + + public static function factory(string|array $props): static + { + if (is_string($props) === true) { + return new static(url: $props); + } + + return new static( + url: $props['url'], + query: $props['query'] ?? $props['fetch'] ?? null, + text: $props['text'] ?? null, + value: $props['value'] ?? null + ); + } + + /** + * Loads the API content from a remote URL + * or local file (or from cache) + */ + public function load(ModelWithContent $model): array|null + { + // resolve query templates in $this->url string + $url = $model->toSafeString($this->url); + + // URL, request via cURL + if (Url::isAbsolute($url) === true) { + return Remote::get($url)->json(); + } + + // local file + return Json::read($url); + } + + public static function polyfill(array|string $props = []): array + { + if (is_string($props) === true) { + return ['url' => $props]; + } + + if ($query = $props['fetch'] ?? null) { + $props['query'] ??= $query; + unset($props['fetch']); + } + + return $props; + } + + /** + * Creates the actual options by loading + * data from the API and resolving it to + * the correct text-value entries + */ + public function resolve(ModelWithContent $model): Options + { + // use cached options if present + // @codeCoverageIgnoreStart + if ($this->options !== null) { + return $this->options; + } + // @codeCoverageIgnoreEnd + + // apply property defaults + $this->defaults(); + + // load data from URL and narrow down to queried part + $data = $this->load($model); + + if ($data === null) { + throw new NotFoundException('Options could not be loaded from API: ' . $model->toSafeString($this->url)); + } + + // turn data into Nest so that it can be queried + $data = Nest::create($data); + $data = Query::factory($this->query)->resolve($data); + + // create options by resolving text and value query strings + // for each item from the data + $options = $data->toArray(fn ($item) => [ + // value is always a raw string + 'value' => $model->toString($this->value, ['item' => $item]), + // text is only a raw string when using {< >} + 'text' => $model->toSafeString($this->text, ['item' => $item]), + ]); + + // create Options object and render this subsequently + return $this->options = Options::factory($options); + } +} diff --git a/kirby/src/Option/OptionsProvider.php b/kirby/src/Option/OptionsProvider.php new file mode 100644 index 0000000..e36ab09 --- /dev/null +++ b/kirby/src/Option/OptionsProvider.php @@ -0,0 +1,30 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + */ +abstract class OptionsProvider +{ + public Options|null $options = null; + + /** + * Returns options as array + */ + public function render(ModelWithContent $model) + { + return $this->resolve($model)->render($model); + } + + abstract public function resolve(ModelWithContent $model): Options; +} diff --git a/kirby/src/Option/OptionsQuery.php b/kirby/src/Option/OptionsQuery.php new file mode 100644 index 0000000..0179b1f --- /dev/null +++ b/kirby/src/Option/OptionsQuery.php @@ -0,0 +1,179 @@ +, + * Nico Hoffmann + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + */ +class OptionsQuery extends OptionsProvider +{ + public function __construct( + public string $query, + public string|null $text = null, + public string|null $value = null + ) { + } + + protected function collection(array $array): Collection + { + foreach ($array as $key => $value) { + if (is_scalar($value) === true) { + $array[$key] = new Obj([ + 'key' => new Field(null, 'key', $key), + 'value' => new Field(null, 'value', $value), + ]); + } + } + + return new Collection($array); + } + + public static function factory(string|array $props): static + { + if (is_string($props) === true) { + return new static(query: $props); + } + + return new static( + query: $props['query'] ?? $props['fetch'], + text: $props['text'] ?? null, + value: $props['value'] ?? null + ); + } + + /** + * Returns defaults for the following based on item type: + * [query entry alias, default text query, default value query] + */ + protected function itemToDefaults(array|object $item): array + { + return match (true) { + is_array($item), + $item instanceof Obj => [ + 'arrayItem', + '{{ item.value }}', + '{{ item.value }}' + ], + + $item instanceof StructureObject => [ + 'structureItem', + '{{ item.title }}', + '{{ item.id }}' + ], + + $item instanceof Block => [ + 'block', + '{{ block.type }}: {{ block.id }}', + '{{ block.id }}' + ], + + $item instanceof Page => [ + 'page', + '{{ page.title }}', + '{{ page.id }}' + ], + + $item instanceof File => [ + 'file', + '{{ file.filename }}', + '{{ file.id }}' + ], + + $item instanceof User => [ + 'user', + '{{ user.username }}', + '{{ user.email }}' + ], + + default => [ + 'item', + '{{ item.value }}', + '{{ item.value }}' + ] + }; + } + + public static function polyfill(array|string $props = []): array + { + if (is_string($props) === true) { + return ['query' => $props]; + } + + if ($query = $props['fetch'] ?? null) { + $props['query'] ??= $query; + unset($props['fetch']); + } + + return $props; + } + + /** + * Creates the actual options by running + * the query on the model and resolving it to + * the correct text-value entries + */ + public function resolve(ModelWithContent $model): Options + { + // use cached options if present + // @codeCoverageIgnoreStart + if ($this->options !== null) { + return $this->options; + } + // @codeCoverageIgnoreEnd + + // run query + $result = $model->query($this->query); + + // the query already returned an options collection + if ($result instanceof Options) { + return $result; + } + + // convert result to a collection + if (is_array($result) === true) { + $result = $this->collection($result); + } + + if ($result instanceof Collection === false) { + throw new InvalidArgumentException('Invalid query result data: ' . get_class($result)); + } + + // create options array + $options = $result->toArray(function ($item) use ($model) { + // get defaults based on item type + [$alias, $text, $value] = $this->itemToDefaults($item); + $data = ['item' => $item, $alias => $item]; + + // value is always a raw string + $value = $model->toString($this->value ?? $value, $data); + + // text is only a raw string when HTML prop + // is explicitly set to true + $text = $model->toSafeString($this->text ?? $text, $data); + + return compact('text', 'value'); + }); + + return $this->options = Options::factory($options); + } +} diff --git a/kirby/src/Panel/Dialog.php b/kirby/src/Panel/Dialog.php index a7825e9..3f0fc1c 100644 --- a/kirby/src/Panel/Dialog.php +++ b/kirby/src/Panel/Dialog.php @@ -2,6 +2,8 @@ namespace Kirby\Panel; +use Kirby\Http\Response; + /** * The Dialog response class handles Fiber * requests to render the JSON object for @@ -16,16 +18,12 @@ namespace Kirby\Panel; */ class Dialog extends Json { - protected static $key = '$dialog'; + protected static string $key = '$dialog'; /** * Renders dialogs - * - * @param mixed $data - * @param array $options - * @return \Kirby\Http\Response */ - public static function response($data, array $options = []) + public static function response($data, array $options = []): Response { // interpret true as success if ($data === true) { diff --git a/kirby/src/Panel/Document.php b/kirby/src/Panel/Document.php index 68e1f9c..034b1d3 100644 --- a/kirby/src/Panel/Document.php +++ b/kirby/src/Panel/Document.php @@ -3,7 +3,6 @@ namespace Kirby\Panel; use Kirby\Cms\App; -use Kirby\Cms\Helpers; use Kirby\Exception\Exception; use Kirby\Exception\InvalidArgumentException; use Kirby\Filesystem\Asset; @@ -31,8 +30,6 @@ class Document /** * Generates an array with all assets * that need to be loaded for the panel (js, css, icons) - * - * @return array */ public static function assets(): array { @@ -137,9 +134,8 @@ class Document * @since 3.7.0 * * @param string $option asset option name - * @return string|null */ - public static function customAsset(string $option): ?string + public static function customAsset(string $option): string|null { if ($path = App::instance()->option($option)) { $asset = new Asset($path); @@ -153,34 +149,12 @@ class Document } /** - * @deprecated 3.7.0 Use `Document::customAsset('panel.css)` instead - * @todo remove in 3.8.0 - * @codeCoverageIgnore - */ - public static function customCss(): ?string - { - Helpers::deprecated('Panel\Document::customCss() has been deprecated and will be removed in Kirby 3.8.0. Use Panel\Document::customAsset(\'panel.css\') instead.'); - return static::customAsset('panel.css'); - } - - /** - * @deprecated 3.7.0 Use `Document::customAsset('panel.js)` instead - * @todo remove in 3.8.0 - * @codeCoverageIgnore - */ - public static function customJs(): ?string - { - Helpers::deprecated('Panel\Document::customJs() has been deprecated and will be removed in Kirby 3.8.0. Use Panel\Document::customAsset(\'panel.js\') instead.'); - return static::customAsset('panel.js'); - } - - /** - * Returns array of favion icons + * Returns array of favicon icons * based on config option * @since 3.7.0 * * @param string $url URL prefix for default icons - * @return array + * @throws \Kirby\Exception\InvalidArgumentException */ public static function favicon(string $url = ''): array { @@ -190,13 +164,13 @@ class Document 'type' => 'image/png', 'url' => $url . '/apple-touch-icon.png', ], - 'shortcut icon' => [ - 'type' => 'image/svg+xml', - 'url' => $url . '/favicon.svg', - ], 'alternate icon' => [ 'type' => 'image/png', 'url' => $url . '/favicon.png', + ], + 'shortcut icon' => [ + 'type' => 'image/svg+xml', + 'url' => $url . '/favicon.svg', ] ]); @@ -221,8 +195,6 @@ class Document * Load the SVG icon sprite * This will be injected in the * initial HTML document for the Panel - * - * @return string */ public static function icons(): string { @@ -233,7 +205,6 @@ class Document * Links all dist files in the media folder * and returns the link to the requested asset * - * @return bool * @throws \Kirby\Exception\Exception If Panel assets could not be moved to the public directory */ public static function link(): bool @@ -265,11 +236,8 @@ class Document /** * Renders the panel document - * - * @param array $fiber - * @return \Kirby\Http\Response */ - public static function response(array $fiber) + public static function response(array $fiber): Response { $kirby = App::instance(); diff --git a/kirby/src/Panel/Dropdown.php b/kirby/src/Panel/Dropdown.php index 42bdd91..b0e5fda 100644 --- a/kirby/src/Panel/Dropdown.php +++ b/kirby/src/Panel/Dropdown.php @@ -5,6 +5,7 @@ namespace Kirby\Panel; use Kirby\Cms\App; use Kirby\Cms\Find; use Kirby\Exception\LogicException; +use Kirby\Http\Response; use Kirby\Http\Uri; use Kirby\Toolkit\Str; use Throwable; @@ -23,12 +24,10 @@ use Throwable; */ class Dropdown extends Json { - protected static $key = '$dropdown'; + protected static string $key = '$dropdown'; /** * Returns the options for the changes dropdown - * - * @return array */ public static function changes(): array { @@ -54,7 +53,7 @@ class Dropdown extends Json } $options[] = $option; - } catch (Throwable $e) { + } catch (Throwable) { continue; } } @@ -72,12 +71,8 @@ class Dropdown extends Json /** * Renders dropdowns - * - * @param mixed $data - * @param array $options - * @return \Kirby\Http\Response */ - public static function response($data, array $options = []) + public static function response($data, array $options = []): Response { if (is_array($data) === true) { $data = [ diff --git a/kirby/src/Panel/Field.php b/kirby/src/Panel/Field.php index 3d02d21..ab53aa1 100644 --- a/kirby/src/Panel/Field.php +++ b/kirby/src/Panel/Field.php @@ -22,9 +22,6 @@ class Field { /** * A standard email field - * - * @param array $props - * @return array */ public static function email(array $props = []): array { @@ -37,10 +34,6 @@ class Field /** * File position - * - * @param \Kirby\Cms\File - * @param array $props - * @return array */ public static function filePosition(File $file, array $props = []): array { @@ -78,9 +71,6 @@ class Field } - /** - * @return array - */ public static function hidden(): array { return ['type' => 'hidden']; @@ -88,10 +78,6 @@ class Field /** * Page position - * - * @param \Kirby\Cms\Page - * @param array $props - * @return array */ public static function pagePosition(Page $page, array $props = []): array { @@ -137,9 +123,6 @@ class Field /** * A regular password field - * - * @param array $props - * @return array */ public static function password(array $props = []): array { @@ -151,9 +134,6 @@ class Field /** * User role radio buttons - * - * @param array $props - * @return array */ public static function role(array $props = []): array { @@ -183,10 +163,6 @@ class Field ], $props); } - /** - * @param array $props - * @return array - */ public static function slug(array $props = []): array { return array_merge([ @@ -195,12 +171,7 @@ class Field ], $props); } - /** - * @param array $blueprints - * @param array $props - * @return array - */ - public static function template(?array $blueprints = [], ?array $props = []): array + public static function template(array|null $blueprints = [], array|null $props = []): array { $options = []; @@ -221,10 +192,6 @@ class Field ], $props); } - /** - * @param array $props - * @return array - */ public static function title(array $props = []): array { return array_merge([ @@ -236,9 +203,6 @@ class Field /** * Panel translation select box - * - * @param array $props - * @return array */ public static function translation(array $props = []): array { @@ -259,10 +223,6 @@ class Field ], $props); } - /** - * @param array $props - * @return array - */ public static function username(array $props = []): array { return array_merge([ diff --git a/kirby/src/Panel/File.php b/kirby/src/Panel/File.php index c78fa7e..4beb689 100644 --- a/kirby/src/Panel/File.php +++ b/kirby/src/Panel/File.php @@ -2,6 +2,8 @@ namespace Kirby\Panel; +use Kirby\Cms\File as CmsFile; +use Kirby\Filesystem\Asset; use Kirby\Toolkit\I18n; use Throwable; @@ -17,15 +19,8 @@ use Throwable; */ class File extends Model { - /** - * @var \Kirby\Cms\File - */ - protected $model; - /** * Breadcrumb array - * - * @return array */ public function breadcrumb(): array { @@ -34,6 +29,7 @@ class File extends Model switch ($parent::CLASS_ALIAS) { case 'user': + /** @var \Kirby\Cms\User $parent */ // The breadcrumb is not necessary // on the account view if ($parent->isLoggedIn() === false) { @@ -44,6 +40,7 @@ class File extends Model } break; case 'page': + /** @var \Kirby\Cms\Page $parent */ $breadcrumb = $this->model->parents()->flip()->values(fn ($parent) => [ 'label' => $parent->title()->toString(), 'link' => $parent->panel()->url(true), @@ -67,41 +64,43 @@ class File extends Model * * @internal * @param string|null $type (`auto`|`kirbytext`|`markdown`) - * @param bool $absolute - * @return string */ - public function dragText(string $type = null, bool $absolute = false): string + public function dragText(string|null $type = null, bool $absolute = false): string { $type = $this->dragTextType($type); - $url = $absolute ? $this->model->id() : $this->model->filename(); + $url = $this->model->filename(); + $file = $this->model->type(); + + // By default only the filename is added as relative URL. + // If an absolute URL is required, either use the permalink + // for markdown notation or the UUID for Kirbytext (since + // Kirbytags support can resolve UUIDs directly) + if ($absolute === true) { + $url = $type === 'markdown' ? $this->model->permalink() : $this->model->uuid(); + // if UUIDs are disabled, fall back to URL + $url ??= $this->model->url(); + } + if ($dragTextFromCallback = $this->dragTextFromCallback($type, $url)) { return $dragTextFromCallback; } if ($type === 'markdown') { - if ($this->model->type() === 'image') { - return '![' . $this->model->alt() . '](' . $url . ')'; - } - - return '[' . $this->model->filename() . '](' . $url . ')'; + return match ($file) { + 'image' => '![' . $this->model->alt() . '](' . $url . ')', + default => '[' . $this->model->filename() . '](' . $url . ')' + }; } - if ($this->model->type() === 'image') { - return '(image: ' . $url . ')'; - } - if ($this->model->type() === 'video') { - return '(video: ' . $url . ')'; - } - - return '(file: ' . $url . ')'; + return match ($file) { + 'image', 'video' => '(' . $file . ': ' . $url . ')', + default => '(file: ' . $url . ')' + }; } /** * Provides options for the file dropdown - * - * @param array $options - * @return array */ public function dropdown(array $options = []): array { @@ -163,9 +162,7 @@ class File extends Model /** * Returns the setup for a dropdown option * which is used in the changes dropdown - * for example. - * - * @return array + * for example */ public function dropdownOption(): array { @@ -177,8 +174,6 @@ class File extends Model /** * Returns the Panel icon color - * - * @return string */ protected function imageColor(): string { @@ -208,8 +203,6 @@ class File extends Model /** * Default settings for the file's Panel image - * - * @return array */ protected function imageDefaults(): array { @@ -221,8 +214,6 @@ class File extends Model /** * Returns the Panel icon type - * - * @return string */ protected function imageIcon(): string { @@ -253,13 +244,11 @@ class File extends Model /** * Returns the image file object based on provided query - * * @internal - * @param string|null $query - * @return \Kirby\Cms\File|\Kirby\Filesystem\Asset|null */ - protected function imageSource(string $query = null) - { + protected function imageSource( + string|null $query = null + ): CmsFile|Asset|null { if ($query === null && $this->model->isViewable()) { return $this->model; } @@ -272,7 +261,6 @@ class File extends Model * that can be performed in the Panel * * @param array $unlock An array of options that will be force-unlocked - * @return array */ public function options(array $unlock = []): array { @@ -282,7 +270,7 @@ class File extends Model // check if the file type is allowed at all, // otherwise it cannot be replaced $this->model->match($this->model->blueprint()->accept()); - } catch (Throwable $e) { + } catch (Throwable) { $options['replace'] = false; } @@ -291,8 +279,6 @@ class File extends Model /** * Returns the full path without leading slash - * - * @return string */ public function path(): string { @@ -302,18 +288,13 @@ class File extends Model /** * Prepares the response data for file pickers * and file fields - * - * @param array|null $params - * @return array */ public function pickerData(array $params = []): array { - $id = $this->model->id(); $name = $this->model->filename(); if (empty($params['model']) === false) { $parent = $this->model->parent(); - $uuid = $parent === $params['model'] ? $name : $id; $absolute = $parent !== $params['model']; } @@ -323,18 +304,14 @@ class File extends Model 'filename' => $name, 'dragText' => $this->dragText('auto', $absolute ?? false), 'type' => $this->model->type(), - 'url' => $this->model->url(), - 'uuid' => $uuid ?? $id, + 'url' => $this->model->url() ]); } /** * Returns the data array for the * view's component props - * * @internal - * - * @return array */ public function props(): array { @@ -408,10 +385,7 @@ class File extends Model /** * Returns navigation array with * previous and next file - * * @internal - * - * @return array */ public function prevNext(): array { @@ -424,11 +398,11 @@ class File extends Model ); return [ - 'next' => function () use ($file, $siblings): ?array { + 'next' => function () use ($file, $siblings): array|null { $next = $siblings->nth($siblings->indexOf($file) + 1); return $this->toPrevNextLink($next, 'filename'); }, - 'prev' => function () use ($file, $siblings): ?array { + 'prev' => function () use ($file, $siblings): array|null { $prev = $siblings->nth($siblings->indexOf($file) - 1); return $this->toPrevNextLink($prev, 'filename'); } @@ -437,9 +411,6 @@ class File extends Model /** * Returns the url to the editing view * in the panel - * - * @param bool $relative - * @return string */ public function url(bool $relative = false): string { @@ -450,21 +421,16 @@ class File extends Model /** * Returns the data array for * this model's Panel view - * * @internal - * - * @return array */ public function view(): array { - $file = $this->model; - return [ - 'breadcrumb' => fn (): array => $file->panel()->breadcrumb(), + 'breadcrumb' => fn (): array => $this->model->panel()->breadcrumb(), 'component' => 'k-file-view', 'props' => $this->props(), 'search' => 'files', - 'title' => $file->filename(), + 'title' => $this->model->filename(), ]; } } diff --git a/kirby/src/Panel/Home.php b/kirby/src/Panel/Home.php index 434673c..95ba708 100644 --- a/kirby/src/Panel/Home.php +++ b/kirby/src/Panel/Home.php @@ -38,9 +38,6 @@ class Home * It will go through the entire menu and * take the first area which is not disabled * or locked in other ways - * - * @param \Kirby\Cms\User $user - * @return string */ public static function alternative(User $user): string { @@ -85,10 +82,6 @@ class Home * panel path. This is quite tricky, because we * need to call a trimmed down router to check * for available routes and their firewall status. - * - * @param \Kirby\Cms\User - * @param string $path - * @return bool */ public static function hasAccess(User $user, string $path): bool { @@ -124,7 +117,7 @@ class Home // check the firewall return Panel::hasAccess($user, $areaId); }); - } catch (Throwable $e) { + } catch (Throwable) { return false; } } @@ -134,9 +127,6 @@ class Home * as the index URL of the Kirby installation. * This is used to block external URLs to third-party * domains as redirect options. - * - * @param \Kirby\Http\Uri $uri - * @return bool */ public static function hasValidDomain(Uri $uri): bool { @@ -145,10 +135,7 @@ class Home } /** - * Checks if the given URL is a Panel Url. - * - * @param string $url - * @return bool + * Checks if the given URL is a Panel Url */ public static function isPanelUrl(string $url): bool { @@ -158,11 +145,8 @@ class Home /** * Returns the path after /panel/ which can then * be used in the router or to find a matching view - * - * @param string $url - * @return string|null */ - public static function panelPath(string $url): ?string + public static function panelPath(string $url): string|null { $after = Str::after($url, App::instance()->url('panel')); return trim($after, '/'); @@ -173,10 +157,8 @@ class Home * before the last logout. We take this Url if possible * to redirect the user back to the last point where they * left before they got logged out. - * - * @return string|null */ - public static function remembered(): ?string + public static function remembered(): string|null { // check for a stored path after login $remembered = App::instance()->session()->pull('panel.path'); @@ -206,8 +188,6 @@ class Home * Afterwards, we also check for permissions before the redirect happens * to avoid redirects to inaccessible Panel views. In such a case * the next best accessible view is picked from the menu. - * - * @return string */ public static function url(): string { diff --git a/kirby/src/Panel/Json.php b/kirby/src/Panel/Json.php index 926046e..1e67e31 100644 --- a/kirby/src/Panel/Json.php +++ b/kirby/src/Panel/Json.php @@ -2,6 +2,10 @@ namespace Kirby\Panel; +use Kirby\Exception\Exception; +use Kirby\Http\Response; +use Throwable; + /** * The Json abstract response class provides * common framework for Fiber requests @@ -17,16 +21,12 @@ namespace Kirby\Panel; */ abstract class Json { - protected static $key = '$response'; + protected static string $key = '$response'; /** * Renders the error response with the provided message - * - * @param string $message - * @param int $code - * @return array */ - public static function error(string $message, int $code = 404) + public static function error(string $message, int $code = 404): array { return [ 'code' => $code, @@ -36,26 +36,22 @@ abstract class Json /** * Prepares the JSON response for the Panel - * - * @param mixed $data - * @param array $options - * @return mixed */ - public static function response($data, array $options = []) + public static function response($data, array $options = []): Response { // handle redirects - if (is_a($data, 'Kirby\Panel\Redirect') === true) { + if ($data instanceof Redirect) { $data = [ 'redirect' => $data->location(), 'code' => $data->code() ]; // handle Kirby exceptions - } elseif (is_a($data, 'Kirby\Exception\Exception') === true) { + } elseif ($data instanceof Exception) { $data = static::error($data->getMessage(), $data->getHttpCode()); // handle exceptions - } elseif (is_a($data, 'Throwable') === true) { + } elseif ($data instanceof Throwable) { $data = static::error($data->getMessage(), 500); // only expect arrays from here on diff --git a/kirby/src/Panel/Model.php b/kirby/src/Panel/Model.php index 6fc7675..83a1621 100644 --- a/kirby/src/Panel/Model.php +++ b/kirby/src/Panel/Model.php @@ -2,6 +2,10 @@ namespace Kirby\Panel; +use Closure; +use Kirby\Cms\File as CmsFile; +use Kirby\Cms\ModelWithContent; +use Kirby\Filesystem\Asset; use Kirby\Form\Form; use Kirby\Http\Uri; use Kirby\Toolkit\A; @@ -18,23 +22,15 @@ use Kirby\Toolkit\A; */ abstract class Model { - /** - * @var \Kirby\Cms\ModelWithContent - */ - protected $model; + protected ModelWithContent $model; - /** - * @param \Kirby\Cms\ModelWithContent $model - */ - public function __construct($model) + public function __construct(ModelWithContent $model) { $this->model = $model; } /** * Get the content values for the model - * - * @return array */ public function content(): array { @@ -47,20 +43,14 @@ abstract class Model * @internal * * @param string $type markdown or kirbytext - * @param mixed ...$args - * @return string|null */ - public function dragTextFromCallback(string $type, ...$args): ?string + public function dragTextFromCallback(string $type, ...$args): string|null { $option = 'panel.' . $type . '.' . $this->model::CLASS_ALIAS . 'DragText'; $callback = $this->model->kirby()->option($option); - if ( - empty($callback) === false && - is_a($callback, 'Closure') === true && - ($dragText = $callback($this->model, ...$args)) !== null - ) { - return $dragText; + if ($callback instanceof Closure) { + return $callback($this->model, ...$args); } return null; @@ -74,9 +64,8 @@ abstract class Model * @internal * * @param string|null $type (`auto`|`kirbytext`|`markdown`) - * @return string */ - public function dragTextType(string $type = null): string + public function dragTextType(string|null $type = null): string { $type ??= 'auto'; @@ -92,8 +81,6 @@ abstract class Model * Returns the setup for a dropdown option * which is used in the changes dropdown * for example. - * - * @return array */ public function dropdownOption(): array { @@ -106,14 +93,12 @@ abstract class Model /** * Returns the Panel image definition - * * @internal - * - * @param string|array|false|null $settings - * @return array|null */ - public function image($settings = [], string $layout = 'list'): ?array - { + public function image( + string|array|false|null $settings = [], + string $layout = 'list' + ): array|null { // completely switched off if ($settings === false) { return null; @@ -147,20 +132,16 @@ abstract class Model if ($image->isResizable() === true) { $settings['src'] = static::imagePlaceholder(); - switch ($layout) { - case 'cards': - $sizes = [352, 864, 1408]; - break; - case 'cardlets': - $sizes = [96, 192]; - break; - case 'list': - default: - $sizes = [38, 76]; - break; - } + $sizes = match ($layout) { + 'cards' => [352, 864, 1408], + 'cardlets' => [96, 192], + default => [38, 76] + }; - if (($settings['cover'] ?? false) === false || $layout === 'cards') { + if ( + ($settings['cover'] ?? false) === false || + $layout === 'cards' + ) { $settings['srcset'] = $image->srcset($sizes); } else { $settings['srcset'] = $image->srcset([ @@ -181,9 +162,7 @@ abstract class Model } } - if (isset($settings['query']) === true) { - unset($settings['query']); - } + unset($settings['query']); // resolve remaining options defined as query return A::map($settings, function ($option) { @@ -197,8 +176,6 @@ abstract class Model /** * Default settings for Panel image - * - * @return array */ protected function imageDefaults(): array { @@ -213,10 +190,7 @@ abstract class Model /** * Data URI placeholder string for Panel image - * * @internal - * - * @return string */ public static function imagePlaceholder(): string { @@ -225,20 +199,17 @@ abstract class Model /** * Returns the image file object based on provided query - * * @internal - * - * @param string|null $query - * @return \Kirby\Cms\File|\Kirby\Filesystem\Asset|null */ - protected function imageSource(?string $query = null) - { + protected function imageSource( + string|null $query = null + ): CmsFile|Asset|null { $image = $this->model->query($query ?? null); // validate the query result if ( - is_a($image, 'Kirby\Cms\File') === true || - is_a($image, 'Kirby\Filesystem\Asset') === true + $image instanceof CmsFile || + $image instanceof Asset ) { return $image; } @@ -249,11 +220,6 @@ abstract class Model /** * Checks for disabled dropdown options according * to the given permissions - * - * @param string $action - * @param array $options - * @param array $permissions - * @return bool */ public function isDisabledDropdownOption(string $action, array $options, array $permissions): bool { @@ -267,21 +233,10 @@ abstract class Model * @return array|false array with lock info, * false if locking is not supported */ - public function lock() + public function lock(): array|false { if ($lock = $this->model->lock()) { - if ($lock->isUnlocked() === true) { - return ['state' => 'unlock']; - } - - if ($lock->isLocked() === true) { - return [ - 'state' => 'lock', - 'data' => $lock->get() - ]; - } - - return ['state' => null]; + return $lock->toArray(); } return false; @@ -293,7 +248,6 @@ abstract class Model * This also checks for the lock status * * @param array $unlock An array of options that will be force-unlocked - * @return array */ public function options(array $unlock = []): array { @@ -314,17 +268,12 @@ abstract class Model /** * Returns the full path without leading slash - * - * @return string */ abstract public function path(): string; /** * Prepares the response data for page pickers * and page fields - * - * @param array|null $params - * @return array */ public function pickerData(array $params = []): array { @@ -338,16 +287,14 @@ abstract class Model 'link' => $this->url(true), 'sortable' => true, 'text' => $this->model->toSafeString($params['text'] ?? false), + 'uuid' => $this->model->uuid()?->toString() ?? $this->model->id(), ]; } /** * Returns the data array for the * view's component props - * * @internal - * - * @return array */ public function props(): array { @@ -376,11 +323,7 @@ abstract class Model * Returns link url and tooltip * for model (e.g. used for prev/next * navigation) - * * @internal - * - * @param string $tooltip - * @return array */ public function toLink(string $tooltip = 'title'): array { @@ -396,12 +339,8 @@ abstract class Model * preserves tab selection * * @internal - * - * @param \Kirby\Cms\ModelWithContent|null $model - * @param string $tooltip - * @return array */ - protected function toPrevNextLink($model = null, string $tooltip = 'title'): ?array + protected function toPrevNextLink(ModelWithContent|null $model = null, string $tooltip = 'title'): array|null { if ($model === null) { return null; @@ -425,9 +364,6 @@ abstract class Model * in the Panel * * @internal - * - * @param bool $relative - * @return string */ public function url(bool $relative = false): string { @@ -443,8 +379,6 @@ abstract class Model * this model's Panel view * * @internal - * - * @return array */ abstract public function view(): array; } diff --git a/kirby/src/Panel/Page.php b/kirby/src/Panel/Page.php index 9d73016..75fd78d 100644 --- a/kirby/src/Panel/Page.php +++ b/kirby/src/Panel/Page.php @@ -2,6 +2,8 @@ namespace Kirby\Panel; +use Kirby\Cms\File as CmsFile; +use Kirby\Filesystem\Asset; use Kirby\Toolkit\I18n; /** @@ -16,15 +18,8 @@ use Kirby\Toolkit\I18n; */ class Page extends Model { - /** - * @var \Kirby\Cms\Page - */ - protected $model; - /** * Breadcrumb array - * - * @return array */ public function breadcrumb(): array { @@ -43,9 +38,8 @@ class Page extends Model * * @internal * @param string|null $type (`auto`|`kirbytext`|`markdown`) - * @return string */ - public function dragText(string $type = null): string + public function dragText(string|null $type = null): string { $type = $this->dragTextType($type); @@ -53,18 +47,21 @@ class Page extends Model return $callback; } + $title = $this->model->title(); + + // type: markdown if ($type === 'markdown') { - return '[' . $this->model->title() . '](' . $this->model->url() . ')'; + $url = $this->model->permalink() ?? $this->model->url(); + return '[' . $title . '](' . $url . ')'; } - return '(link: ' . $this->model->id() . ' text: ' . $this->model->title() . ')'; + // type: kirbytext + $link = $this->model->uuid() ?? $this->model->uri(); + return '(link: ' . $link . ' text: ' . $title . ')'; } /** * Provides options for the page dropdown - * - * @param array $options - * @return array */ public function dropdown(array $options = []): array { @@ -160,8 +157,6 @@ class Page extends Model * Returns the setup for a dropdown option * which is used in the changes dropdown * for example. - * - * @return array */ public function dropdownOption(): array { @@ -173,8 +168,6 @@ class Page extends Model /** * Returns the escaped Id, which is * used in the panel to make routing work properly - * - * @return string */ public function id(): string { @@ -183,8 +176,6 @@ class Page extends Model /** * Default settings for the page's Panel image - * - * @return array */ protected function imageDefaults(): array { @@ -201,11 +192,10 @@ class Page extends Model * Returns the image file object based on provided query * * @internal - * @param string|null $query - * @return \Kirby\Cms\File|\Kirby\Filesystem\Asset|null */ - protected function imageSource(string $query = null) - { + protected function imageSource( + string|null $query = null + ): CmsFile|Asset|null { if ($query === null) { $query = 'page.image'; } @@ -217,7 +207,6 @@ class Page extends Model * Returns the full path without leading slash * * @internal - * @return string */ public function path(): string { @@ -227,9 +216,6 @@ class Page extends Model /** * Prepares the response data for page pickers * and page fields - * - * @param array|null $params - * @return array */ public function pickerData(array $params = []): array { @@ -245,12 +231,11 @@ class Page extends Model /** * The best applicable position for * the position/status dialog - * - * @return int */ public function position(): int { - return $this->model->num() ?? $this->model->parentModel()->children()->listed()->not($this->model)->count() + 1; + return $this->model->num() ?? + $this->model->parentModel()->children()->listed()->not($this->model)->count() + 1; } /** @@ -259,8 +244,6 @@ class Page extends Model * based on blueprint definition * * @internal - * - * @return array */ public function prevNext(): array { @@ -323,8 +306,6 @@ class Page extends Model * view's component props * * @internal - * - * @return array */ public function props(): array { @@ -334,7 +315,7 @@ class Page extends Model parent::props(), $this->prevNext(), [ - 'blueprint' => $this->model->intendedTemplate()->name(), + 'blueprint' => $page->intendedTemplate()->name(), 'model' => [ 'content' => $this->content(), 'id' => $page->id(), @@ -358,8 +339,6 @@ class Page extends Model * this model's Panel view * * @internal - * - * @return array */ public function view(): array { diff --git a/kirby/src/Panel/Panel.php b/kirby/src/Panel/Panel.php index f237478..0f937b0 100644 --- a/kirby/src/Panel/Panel.php +++ b/kirby/src/Panel/Panel.php @@ -2,6 +2,7 @@ namespace Kirby\Panel; +use Closure; use Kirby\Cms\App; use Kirby\Cms\Url as CmsUrl; use Kirby\Cms\User; @@ -32,12 +33,8 @@ class Panel { /** * Normalize a panel area - * - * @param string $id - * @param array|string $area - * @return array */ - public static function area(string $id, $area): array + public static function area(string $id, array|string $area): array { $area['id'] = $id; $area['label'] ??= $id; @@ -53,8 +50,6 @@ class Panel /** * Collect all registered areas - * - * @return array */ public static function areas(): array { @@ -116,13 +111,11 @@ class Panel /** * Check for access permissions - * - * @param \Kirby\Cms\User|null $user - * @param string|null $areaId - * @return bool */ - public static function firewall(?User $user = null, ?string $areaId = null): bool - { + public static function firewall( + User|null $user = null, + string|null $areaId = null + ): bool { // a user has to be logged in if ($user === null) { throw new PermissionException(['key' => 'access.panel']); @@ -158,13 +151,10 @@ class Panel /** * Redirect to a Panel url * - * @param string|null $path - * @param int $code * @throws \Kirby\Panel\Redirect - * @return void * @codeCoverageIgnore */ - public static function go(?string $url = null, int $code = 302): void + public static function go(string|null $url = null, int $code = 302): void { throw new Redirect(static::url($url), $code); } @@ -172,17 +162,15 @@ class Panel /** * Check if the given user has access to the panel * or to a given area - * - * @param \Kirby\Cms\User|null $user - * @param string|null $area - * @return bool */ - public static function hasAccess(?User $user = null, string $area = null): bool - { + public static function hasAccess( + User|null $user = null, + string|null $area = null + ): bool { try { static::firewall($user, $area); return true; - } catch (Throwable $e) { + } catch (Throwable) { return false; } } @@ -190,8 +178,6 @@ class Panel /** * Checks for a Fiber request * via get parameters or headers - * - * @return bool */ public static function isFiberRequest(): bool { @@ -207,12 +193,8 @@ class Panel /** * Returns a JSON response * for Fiber calls - * - * @param array $data - * @param int $code - * @return \Kirby\Http\Response */ - public static function json(array $data, int $code = 200) + public static function json(array $data, int $code = 200): Response { $request = App::instance()->request(); @@ -224,8 +206,6 @@ class Panel /** * Checks for a multilanguage installation - * - * @return bool */ public static function multilang(): bool { @@ -236,8 +216,6 @@ class Panel /** * Returns the referrer path if present - * - * @return string */ public static function referrer(): string { @@ -253,15 +231,11 @@ class Panel /** * Creates a Response object from the result of * a Panel route call - * - * @params mixed $result - * @params array $options - * @return \Kirby\Http\Response */ - public static function response($result, array $options = []) + public static function response($result, array $options = []): Response { // pass responses directly down to the Kirby router - if (is_a($result, 'Kirby\Http\Response') === true) { + if ($result instanceof Response) { return $result; } @@ -275,25 +249,18 @@ class Panel } // handle different response types (view, dialog, ...) - switch ($options['type'] ?? null) { - case 'dialog': - return Dialog::response($result, $options); - case 'dropdown': - return Dropdown::response($result, $options); - case 'search': - return Search::response($result, $options); - default: - return View::response($result, $options); - } + return match ($options['type'] ?? null) { + 'dialog' => Dialog::response($result, $options), + 'dropdown' => Dropdown::response($result, $options), + 'search' => Search::response($result, $options), + default => View::response($result, $options) + }; } /** * Router for the Panel views - * - * @param string $path - * @return \Kirby\Http\Response|false */ - public static function router(string $path = null) + public static function router(string|null $path = null): Response|null { $kirby = App::instance(); @@ -349,8 +316,6 @@ class Panel /** * Extract the routes from the given array * of active areas. - * - * @return array */ public static function routes(array $areas): array { @@ -404,10 +369,6 @@ class Panel /** * Extract all routes from an area - * - * @param string $areaId - * @param array $area - * @return array */ public static function routesForDialogs(string $areaId, array $area): array { @@ -441,10 +402,6 @@ class Panel /** * Extract all routes for dropdowns - * - * @param string $areaId - * @param array $area - * @return array */ public static function routesForDropdowns(string $areaId, array $area): array { @@ -454,7 +411,7 @@ class Panel foreach ($dropdowns as $name => $dropdown) { // Handle shortcuts for dropdowns. The name is the pattern // and options are defined in a Closure - if (is_a($dropdown, 'Closure') === true) { + if ($dropdown instanceof Closure) { $dropdown = [ 'pattern' => $name, 'action' => $dropdown @@ -479,10 +436,6 @@ class Panel /** * Extract all routes for searches - * - * @param string $areaId - * @param array $area - * @return array */ public static function routesForSearches(string $areaId, array $area): array { @@ -511,10 +464,6 @@ class Panel /** * Extract all views from an area - * - * @param string $areaId - * @param array $area - * @return array */ public static function routesForViews(string $areaId, array $area): array { @@ -534,10 +483,8 @@ class Panel * Set the current language in multi-lang * installations based on the session or the * query language query parameter - * - * @return string|null */ - public static function setLanguage(): ?string + public static function setLanguage(): string|null { $kirby = App::instance(); @@ -570,20 +517,15 @@ class Panel /** * Set the currently active Panel translation * based on the current user or config - * - * @return string */ public static function setTranslation(): string { $kirby = App::instance(); - if ($user = $kirby->user()) { - // use the user language for the default translation - $translation = $user->language(); - } else { - // fall back to the language from the config - $translation = $kirby->panelLanguage(); - } + // use the user language for the default translation or + // fall back to the language from the config + $translation = $kirby->user()?->language() ?? + $kirby->panelLanguage(); $kirby->setCurrentTranslation($translation); @@ -593,11 +535,8 @@ class Panel /** * Creates an absolute Panel URL * independent of the Panel slug config - * - * @param string|null $url - * @return string */ - public static function url(?string $url = null): string + public static function url(string|null $url = null): string { $slug = App::instance()->option('panel.slug', 'panel'); diff --git a/kirby/src/Panel/Plugins.php b/kirby/src/Panel/Plugins.php index daa6ff5..f264f73 100644 --- a/kirby/src/Panel/Plugins.php +++ b/kirby/src/Panel/Plugins.php @@ -23,15 +23,11 @@ class Plugins { /** * Cache of all collected plugin files - * - * @var array */ - public $files; + public array|null $files = null; /** * Collects and returns the plugin files for all plugins - * - * @return array */ public function files(): array { @@ -58,8 +54,6 @@ class Plugins /** * Returns the last modification * of the collected plugin files - * - * @return int */ public function modified(): int { @@ -75,9 +69,6 @@ class Plugins /** * Read the files from all plugins and concatenate them - * - * @param string $type - * @return string */ public function read(string $type): string { @@ -140,9 +131,6 @@ class Plugins /** * Absolute url to the cache file * This is used by the panel to link the plugins - * - * @param string $type - * @return string */ public function url(string $type): string { diff --git a/kirby/src/Panel/Redirect.php b/kirby/src/Panel/Redirect.php index 0c63a2e..d00cd6f 100644 --- a/kirby/src/Panel/Redirect.php +++ b/kirby/src/Panel/Redirect.php @@ -20,8 +20,6 @@ class Redirect extends Exception { /** * Returns the HTTP code for the redirect - * - * @return int */ public function code(): int { @@ -36,8 +34,6 @@ class Redirect extends Exception /** * Returns the URL for the redirect - * - * @return string */ public function location(): string { diff --git a/kirby/src/Panel/Search.php b/kirby/src/Panel/Search.php index 20e75ae..984d38d 100644 --- a/kirby/src/Panel/Search.php +++ b/kirby/src/Panel/Search.php @@ -2,6 +2,8 @@ namespace Kirby\Panel; +use Kirby\Http\Response; + /** * The Search response class handles Fiber * requests to render the JSON object for @@ -16,14 +18,9 @@ namespace Kirby\Panel; */ class Search extends Json { - protected static $key = '$search'; + protected static string $key = '$search'; - /** - * @param mixed $data - * @param array $options - * @return \Kirby\Http\Response - */ - public static function response($data, array $options = []) + public static function response($data, array $options = []): Response { if (is_array($data) === true) { $data = [ diff --git a/kirby/src/Panel/Site.php b/kirby/src/Panel/Site.php index 92f5178..caddd46 100644 --- a/kirby/src/Panel/Site.php +++ b/kirby/src/Panel/Site.php @@ -2,6 +2,9 @@ namespace Kirby\Panel; +use Kirby\Cms\File as CmsFile; +use Kirby\Filesystem\Asset; + /** * Provides information about the site model for the Panel * @since 3.6.0 @@ -14,17 +17,10 @@ namespace Kirby\Panel; */ class Site extends Model { - /** - * @var \Kirby\Cms\Site - */ - protected $model; - /** * Returns the setup for a dropdown option * which is used in the changes dropdown * for example. - * - * @return array */ public function dropdownOption(): array { @@ -38,11 +34,10 @@ class Site extends Model * Returns the image file object based on provided query * * @internal - * @param string|null $query - * @return \Kirby\Cms\File|\Kirby\Filesystem\Asset|null */ - protected function imageSource(string $query = null) - { + protected function imageSource( + string|null $query = null + ): CmsFile|Asset|null { if ($query === null) { $query = 'site.image'; } @@ -52,8 +47,6 @@ class Site extends Model /** * Returns the full path without leading slash - * - * @return string */ public function path(): string { @@ -65,8 +58,6 @@ class Site extends Model * view's component props * * @internal - * - * @return array */ public function props(): array { @@ -86,8 +77,6 @@ class Site extends Model * this model's Panel view * * @internal - * - * @return array */ public function view(): array { diff --git a/kirby/src/Panel/User.php b/kirby/src/Panel/User.php index 69275ef..3b8ae2e 100644 --- a/kirby/src/Panel/User.php +++ b/kirby/src/Panel/User.php @@ -2,7 +2,10 @@ namespace Kirby\Panel; +use Kirby\Cms\File as CmsFile; +use Kirby\Cms\Translation; use Kirby\Cms\Url; +use Kirby\Filesystem\Asset; use Kirby\Toolkit\I18n; /** @@ -17,15 +20,8 @@ use Kirby\Toolkit\I18n; */ class User extends Model { - /** - * @var \Kirby\Cms\User - */ - protected $model; - /** * Breadcrumb array - * - * @return array */ public function breadcrumb(): array { @@ -39,9 +35,6 @@ class User extends Model /** * Provides options for the user dropdown - * - * @param array $options - * @return array */ public function dropdown(array $options = []): array { @@ -104,8 +97,6 @@ class User extends Model * Returns the setup for a dropdown option * which is used in the changes dropdown * for example. - * - * @return array */ public function dropdownOption(): array { @@ -115,10 +106,7 @@ class User extends Model ] + parent::dropdownOption(); } - /** - * @return string|null - */ - public function home(): ?string + public function home(): string|null { if ($home = ($this->model->blueprint()->home() ?? null)) { $url = $this->model->toString($home); @@ -130,8 +118,6 @@ class User extends Model /** * Default settings for the user's Panel image - * - * @return array */ protected function imageDefaults(): array { @@ -144,12 +130,11 @@ class User extends Model /** * Returns the image file object based on provided query - * - * @param string|null $query - * @return \Kirby\Cms\File|\Kirby\Filesystem\Asset|null + * @internal */ - protected function imageSource(string $query = null) - { + protected function imageSource( + string|null $query = null + ): CmsFile|Asset|null { if ($query === null) { return $this->model->avatar(); } @@ -159,8 +144,6 @@ class User extends Model /** * Returns the full path without leading slash - * - * @return string */ public function path(): string { @@ -174,11 +157,8 @@ class User extends Model /** * Returns prepared data for the panel user picker - * - * @param array|null $params - * @return array */ - public function pickerData(array $params = null): array + public function pickerData(array $params = []): array { $params['text'] ??= '{{ user.username }}'; @@ -193,8 +173,6 @@ class User extends Model * previous and next user * * @internal - * - * @return array */ public function prevNext(): array { @@ -211,8 +189,6 @@ class User extends Model * view's component props * * @internal - * - * @return array */ public function props(): array { @@ -244,10 +220,8 @@ class User extends Model /** * Returns the Translation object * for the selected Panel language - * - * @return \Kirby\Cms\Translation */ - public function translation() + public function translation(): Translation { $kirby = $this->model->kirby(); $lang = $this->model->language(); @@ -259,8 +233,6 @@ class User extends Model * this model's Panel view * * @internal - * - * @return array */ public function view(): array { diff --git a/kirby/src/Panel/View.php b/kirby/src/Panel/View.php index 3eb7155..3a2783d 100644 --- a/kirby/src/Panel/View.php +++ b/kirby/src/Panel/View.php @@ -2,11 +2,14 @@ namespace Kirby\Panel; +use Closure; use Kirby\Cms\App; +use Kirby\Exception\Exception; use Kirby\Http\Response; use Kirby\Toolkit\A; use Kirby\Toolkit\I18n; use Kirby\Toolkit\Str; +use Throwable; /** * The View response class handles Fiber @@ -27,9 +30,6 @@ class View * query parameters. Requests can return only * certain data fields that way or globals can * be injected on demand. - * - * @param array $data - * @return array */ public static function apply(array $data): array { @@ -55,12 +55,8 @@ class View * * A global request can be activated with the `X-Fiber-Globals` header or the * `_globals` query parameter. - * - * @param array $data - * @param string|null $globals - * @return array */ - public static function applyGlobals(array $data, ?string $globals = null): array + public static function applyGlobals(array $data, string|null $globals = null): array { // split globals string into an array of fields $globalKeys = Str::split($globals, ','); @@ -89,12 +85,8 @@ class View * * Such requests can fetch shared data or globals. * Globals will be loaded on demand. - * - * @param array $data - * @param string|null $only - * @return array */ - public static function applyOnly(array $data, ?string $only = null): array + public static function applyOnly(array $data, string|null $only = null): array { // split include string into an array of fields $onlyKeys = Str::split($only, ','); @@ -133,10 +125,6 @@ class View * The full shared data is always sent on every JSON and * full document request unless the `X-Fiber-Only` header or * the `_only` query parameter is set. - * - * @param array $view - * @param array $options - * @return array */ public static function data(array $view = [], array $options = []): array { @@ -239,10 +227,6 @@ class View /** * Renders the error view with provided message - * - * @param string $message - * @param int $code - * @return array */ public static function error(string $message, int $code = 404) { @@ -265,8 +249,6 @@ class View * is only requested once on the first page load. * It can be loaded partially later if needed, * but is otherwise not included in Fiber calls. - * - * @return array */ public static function globals(): array { @@ -323,13 +305,8 @@ class View /** * Creates the menu for the topbar - * - * @param array $areas - * @param array $permissions - * @param string|null $current - * @return array */ - public static function menu(?array $areas = [], ?array $permissions = [], ?string $current = null): array + public static function menu(array|null $areas = [], array|null $permissions = [], string|null $current = null): array { $menu = []; @@ -346,7 +323,7 @@ class View $menuSetting = $area['menu'] ?? false; // menu settings can be a callback that can return true, false or disabled - if (is_a($menuSetting, 'Closure') === true) { + if ($menuSetting instanceof Closure) { $menuSetting = $menuSetting($areas, $permissions, $current); } @@ -391,23 +368,19 @@ class View * Renders the main panel view either as * JSON response or full HTML document based * on the request header or query params - * - * @param mixed $data - * @param array $options - * @return \Kirby\Http\Response */ - public static function response($data, array $options = []) + public static function response($data, array $options = []): Response { // handle redirects - if (is_a($data, 'Kirby\Panel\Redirect') === true) { + if ($data instanceof Redirect) { return Response::redirect($data->location(), $data->code()); // handle Kirby exceptions - } elseif (is_a($data, 'Kirby\Exception\Exception') === true) { + } elseif ($data instanceof Exception) { $data = static::error($data->getMessage(), $data->getHttpCode()); // handle regular exceptions - } elseif (is_a($data, 'Throwable') === true) { + } elseif ($data instanceof Throwable) { $data = static::error($data->getMessage(), 500); // only expect arrays from here on @@ -437,7 +410,7 @@ class View return Document::response($fiber); } - public static function searches(array $areas, array $permissions) + public static function searches(array $areas, array $permissions): array { $searches = []; diff --git a/kirby/src/Parsley/Element.php b/kirby/src/Parsley/Element.php index 292a55a..b0bd9de 100644 --- a/kirby/src/Parsley/Element.php +++ b/kirby/src/Parsley/Element.php @@ -21,20 +21,9 @@ use Kirby\Toolkit\Str; */ class Element { - /** - * @var array - */ - protected $marks; + protected array $marks; + protected DOMElement $node; - /** - * @var \DOMElement - */ - protected $node; - - /** - * @param \DOMElement $node - * @param array $marks - */ public function __construct(DOMElement $node, array $marks = []) { $this->marks = $marks; @@ -44,12 +33,8 @@ class Element /** * The returns the attribute value or * the given fallback if the attribute does not exist - * - * @param string $attr - * @param string|null $fallback - * @return string|null */ - public function attr(string $attr, string $fallback = null): ?string + public function attr(string $attr, string|null $fallback = null): string|null { if ($this->node->hasAttribute($attr)) { return $this->node->getAttribute($attr) ?? $fallback; @@ -60,8 +45,6 @@ class Element /** * Returns a list of all child elements - * - * @return \DOMNodeList */ public function children(): DOMNodeList { @@ -70,8 +53,6 @@ class Element /** * Returns an array with all class names - * - * @return array */ public function classList(): array { @@ -80,20 +61,16 @@ class Element /** * Returns the value of the class attribute - * - * @return string|null */ - public function className(): ?string + public function className(): string|null { return $this->attr('class'); } /** * Returns the original dom element - * - * @return \DOMElement */ - public function element() + public function element(): DOMElement { return $this->node; } @@ -101,9 +78,6 @@ class Element /** * Returns an array with all nested elements * that could be found for the given query - * - * @param string $query - * @return array */ public function filter(string $query): array { @@ -121,11 +95,8 @@ class Element /** * Tries to find a single nested element by * query and otherwise returns null - * - * @param string $query - * @return \Kirby\Parsley\Element|null */ - public function find(string $query) + public function find(string $query): Element|null { if ($result = $this->query($query)[0]) { return new static($result); @@ -136,19 +107,14 @@ class Element /** * Returns the inner HTML of the element - * - * @param array|null $marks List of allowed marks - * @return string */ - public function innerHtml(array $marks = null): string + public function innerHtml(array|null $marks = null): string { return (new Inline($this->node, $marks ?? $this->marks))->innerHtml(); } /** * Returns the contents as plain text - * - * @return string */ public function innerText(): string { @@ -157,40 +123,31 @@ class Element /** * Returns the full HTML for the element - * - * @param array|null $marks - * @return string */ - public function outerHtml(array $marks = null): string + public function outerHtml(array|null $marks = null): string { return $this->node->ownerDocument->saveHtml($this->node); } /** * Searches nested elements - * - * @param string $query - * @return DOMNodeList|null */ - public function query(string $query) + public function query(string $query): DOMNodeList|null { - return (new DOMXPath($this->node->ownerDocument))->query($query, $this->node); + $path = new DOMXPath($this->node->ownerDocument); + return $path->query($query, $this->node); } /** * Removes the element from the DOM - * - * @return void */ - public function remove() + public function remove(): void { $this->node->parentNode->removeChild($this->node); } /** * Returns the name of the element - * - * @return string */ public function tagName(): string { diff --git a/kirby/src/Parsley/Inline.php b/kirby/src/Parsley/Inline.php index 97c044f..891adfd 100644 --- a/kirby/src/Parsley/Inline.php +++ b/kirby/src/Parsley/Inline.php @@ -2,8 +2,10 @@ namespace Kirby\Parsley; +use DOMComment; use DOMNode; use DOMNodeList; +use DOMText; use Kirby\Toolkit\Html; /** @@ -20,20 +22,9 @@ use Kirby\Toolkit\Html; */ class Inline { - /** - * @var string - */ - protected $html = ''; + protected string $html = ''; + protected array $marks = []; - /** - * @var array - */ - protected $marks = []; - - /** - * @param \DOMNode $node - * @param array $marks - */ public function __construct(DOMNode $node, array $marks = []) { $this->createMarkRules($marks); @@ -42,11 +33,8 @@ class Inline /** * Loads all mark rules - * - * @param array $marks - * @return array */ - protected function createMarkRules(array $marks) + protected function createMarkRules(array $marks): array { foreach ($marks as $mark) { $this->marks[$mark['tag']] = $mark; @@ -58,10 +46,6 @@ class Inline /** * Get all allowed attributes for a DOMNode * as clean array - * - * @param DOMNode $node - * @param array $marks - * @return array */ public static function parseAttrs(DOMNode $node, array $marks = []): array { @@ -83,10 +67,6 @@ class Inline /** * Parses all children and creates clean HTML * for each of them. - * - * @param \DOMNodeList $children - * @param array $marks - * @return string */ public static function parseChildren(DOMNodeList $children, array $marks): string { @@ -100,11 +80,8 @@ class Inline /** * Go through all child elements and create * clean inner HTML for them - * - * @param DOMNode $node - * @return string|null */ - public static function parseInnerHtml(DOMNode $node, array $marks = []): ?string + public static function parseInnerHtml(DOMNode $node, array $marks = []): string|null { $html = static::parseChildren($node->childNodes, $marks); @@ -123,19 +100,15 @@ class Inline /** * Converts the given node to clean HTML - * - * @param \DOMNode $node - * @param array $marks - * @return string|null */ - public static function parseNode(DOMNode $node, array $marks = []): ?string + public static function parseNode(DOMNode $node, array $marks = []): string|null { - if (is_a($node, 'DOMText') === true) { + if ($node instanceof DOMText) { return Html::encode($node->textContent); } // ignore comments - if (is_a($node, 'DOMComment') === true) { + if ($node instanceof DOMComment) { return null; } @@ -165,8 +138,6 @@ class Inline /** * Returns the HTML contents of the element - * - * @return string */ public function innerHtml(): string { diff --git a/kirby/src/Parsley/Parsley.php b/kirby/src/Parsley/Parsley.php index d99d45e..460ecfb 100644 --- a/kirby/src/Parsley/Parsley.php +++ b/kirby/src/Parsley/Parsley.php @@ -2,7 +2,10 @@ namespace Kirby\Parsley; +use DOMDocument; +use DOMElement; use DOMNode; +use DOMText; use Kirby\Parsley\Schema\Plain; use Kirby\Toolkit\Dom; @@ -20,56 +23,18 @@ use Kirby\Toolkit\Dom; */ class Parsley { - /** - * @var array - */ - protected $blocks = []; + protected array $blocks = []; + protected DOMDocument $doc; + protected Dom $dom; + protected array $inline = []; + protected array $marks = []; + protected array $nodes = []; + protected Schema $schema; + protected array $skip = []; - /** - * @var \DOMDocument - */ - protected $doc; + public static bool $useXmlExtension = true; - /** - * @var \Kirby\Toolkit\Dom - */ - protected $dom; - - /** - * @var array - */ - protected $inline = []; - - /** - * @var array - */ - protected $marks = []; - - /** - * @var array - */ - protected $nodes = []; - - /** - * @var \Kirby\Parsley\Schema - */ - protected $schema; - - /** - * @var array - */ - protected $skip = []; - - /** - * @var bool - */ - public static $useXmlExtension = true; - - /** - * @param string $html - * @param \Kirby\Parsley\Schema|null $schema - */ - public function __construct(string $html, Schema $schema = null) + public function __construct(string $html, Schema|null $schema = null) { // fail gracefully if the XML extension is not installed // or should be skipped @@ -110,8 +75,6 @@ class Parsley /** * Returns all detected blocks - * - * @return array */ public function blocks(): array { @@ -120,9 +83,6 @@ class Parsley /** * Load all node rules from the schema - * - * @param array $nodes - * @return array */ public function createNodeRules(array $nodes): array { @@ -136,9 +96,6 @@ class Parsley /** * Checks if the given element contains * any other block level elements - * - * @param \DOMNode $element - * @return bool */ public function containsBlock(DOMNode $element): bool { @@ -162,10 +119,8 @@ class Parsley * if the type matches, or will be appended. * * The inline cache will be reset afterwards - * - * @return void */ - public function endInlineBlock() + public function endInlineBlock(): void { if (empty($this->inline) === true) { return; @@ -191,11 +146,8 @@ class Parsley * Creates a fallback block type for the given * element. The element can either be a element object * or a simple HTML/plain text string - * - * @param \Kirby\Parsley\Element|string $element - * @return array|null */ - public function fallback($element): ?array + public function fallback(Element|string $element): array|null { if ($fallback = $this->schema->fallback($element)) { return $fallback; @@ -206,13 +158,10 @@ class Parsley /** * Checks if the given DOMNode is a block element - * - * @param DOMNode $element - * @return bool */ public function isBlock(DOMNode $element): bool { - if (is_a($element, 'DOMElement') === false) { + if ($element instanceof DOMElement === false) { return false; } @@ -221,17 +170,14 @@ class Parsley /** * Checks if the given DOMNode is an inline element - * - * @param \DOMNode $element - * @return bool */ public function isInline(DOMNode $element): bool { - if (is_a($element, 'DOMText') === true) { + if ($element instanceof DOMText) { return true; } - if (is_a($element, 'DOMElement') === true) { + if ($element instanceof DOMElement) { // all spans will be treated as inline elements if ($element->tagName === 'span') { return true; @@ -252,11 +198,7 @@ class Parsley return false; } - /** - * @param array $block - * @return void - */ - public function mergeOrAppend(array $block) + public function mergeOrAppend(array $block): void { $lastIndex = count($this->blocks) - 1; $lastItem = $this->blocks[$lastIndex] ?? null; @@ -274,9 +216,6 @@ class Parsley /** * Parses the given DOM node and tries to * convert it to a block or a list of blocks - * - * @param \DOMNode $element - * @return void */ public function parseNode(DOMNode $element): bool { @@ -339,9 +278,6 @@ class Parsley return true; } - /** - * @return bool - */ public function useXmlExtension(): bool { if (static::$useXmlExtension !== true) { diff --git a/kirby/src/Parsley/Schema.php b/kirby/src/Parsley/Schema.php index b9c1232..3cf74f1 100644 --- a/kirby/src/Parsley/Schema.php +++ b/kirby/src/Parsley/Schema.php @@ -18,11 +18,8 @@ class Schema /** * Returns the fallback block when no * other block type can be detected - * - * @param \Kirby\Parsley\Element|string $element - * @return array|null */ - public function fallback($element): ?array + public function fallback(Element|string $element): array|null { return null; } @@ -30,8 +27,6 @@ class Schema /** * Returns a list of allowed inline marks * and their parsing rules - * - * @return array */ public function marks(): array { @@ -41,8 +36,6 @@ class Schema /** * Returns a list of allowed nodes and * their parsing rules - * - * @return array */ public function nodes(): array { @@ -52,8 +45,6 @@ class Schema /** * Returns a list of all elements that should be * skipped and not be parsed at all - * - * @return array */ public function skip(): array { diff --git a/kirby/src/Parsley/Schema/Blocks.php b/kirby/src/Parsley/Schema/Blocks.php index d825a0e..c221dc7 100644 --- a/kirby/src/Parsley/Schema/Blocks.php +++ b/kirby/src/Parsley/Schema/Blocks.php @@ -2,6 +2,8 @@ namespace Kirby\Parsley\Schema; +use DOMElement; +use DOMText; use Kirby\Parsley\Element; use Kirby\Toolkit\Str; @@ -19,10 +21,6 @@ use Kirby\Toolkit\Str; */ class Blocks extends Plain { - /** - * @param \Kirby\Parsley\Element $node - * @return array - */ public function blockquote(Element $node): array { $citation = null; @@ -30,10 +28,14 @@ class Blocks extends Plain // get all the text for the quote foreach ($node->children() as $child) { - if (is_a($child, 'DOMText') === true) { + if ($child instanceof DOMText) { $text[] = trim($child->textContent); } - if (is_a($child, 'DOMElement') === true && $child->tagName !== 'footer') { + + if ( + $child instanceof DOMElement && + $child->tagName !== 'footer' + ) { $text[] = (new Element($child))->innerHTML($this->marks()); } } @@ -58,13 +60,10 @@ class Blocks extends Plain /** * Creates the fallback block type * if no other block can be found - * - * @param \Kirby\Parsley\Element|string $element - * @return array|null */ - public function fallback($element): ?array + public function fallback(Element|string $element): array|null { - if (is_a($element, Element::class) === true) { + if ($element instanceof Element) { $html = $element->innerHtml(); // wrap the inner HTML in a p tag if it doesn't @@ -94,9 +93,6 @@ class Blocks extends Plain /** * Converts a heading element to a heading block - * - * @param \Kirby\Parsley\Element $node - * @return array */ public function heading(Element $node): array { @@ -117,10 +113,6 @@ class Blocks extends Plain ]; } - /** - * @param \Kirby\Parsley\Element $node - * @return array - */ public function iframe(Element $node): array { $caption = null; @@ -163,10 +155,6 @@ class Blocks extends Plain ]; } - /** - * @param \Kirby\Parsley\Element $node - * @return array - */ public function img(Element $node): array { $caption = null; @@ -197,9 +185,6 @@ class Blocks extends Plain /** * Converts a list element to HTML - * - * @param \Kirby\Parsley\Element $node - * @return string */ public function list(Element $node): string { @@ -209,9 +194,9 @@ class Blocks extends Plain $innerHtml = ''; foreach ($li->children() as $child) { - if (is_a($child, 'DOMText') === true) { + if ($child instanceof DOMText) { $innerHtml .= $child->textContent; - } elseif (is_a($child, 'DOMElement') === true) { + } elseif ($child instanceof DOMElement) { $child = new Element($child); if (in_array($child->tagName(), ['ul', 'ol']) === true) { @@ -231,8 +216,6 @@ class Blocks extends Plain /** * Returns a list of allowed inline marks * and their parsing rules - * - * @return array */ public function marks(): array { @@ -291,114 +274,79 @@ class Blocks extends Plain * their parsing rules * * @codeCoverageIgnore - * @return array */ public function nodes(): array { return [ [ 'tag' => 'blockquote', - 'parse' => function (Element $node) { - return $this->blockquote($node); - } + 'parse' => fn (Element $node) => $this->blockquote($node) ], [ 'tag' => 'h1', - 'parse' => function (Element $node) { - return $this->heading($node); - } + 'parse' => fn (Element $node) => $this->heading($node) ], [ 'tag' => 'h2', - 'parse' => function (Element $node) { - return $this->heading($node); - } + 'parse' => fn (Element $node) => $this->heading($node) ], [ 'tag' => 'h3', - 'parse' => function (Element $node) { - return $this->heading($node); - } + 'parse' => fn (Element $node) => $this->heading($node) ], [ 'tag' => 'h4', - 'parse' => function (Element $node) { - return $this->heading($node); - } + 'parse' => fn (Element $node) => $this->heading($node) ], [ 'tag' => 'h5', - 'parse' => function (Element $node) { - return $this->heading($node); - } + 'parse' => fn (Element $node) => $this->heading($node) ], [ 'tag' => 'h6', - 'parse' => function (Element $node) { - return $this->heading($node); - } + 'parse' => fn (Element $node) => $this->heading($node) ], [ 'tag' => 'hr', - 'parse' => function (Element $node) { - return [ - 'type' => 'line' - ]; - } + 'parse' => fn (Element $node) => ['type' => 'line'] ], [ 'tag' => 'iframe', - 'parse' => function (Element $node) { - return $this->iframe($node); - } + 'parse' => fn (Element $node) => $this->iframe($node) ], [ 'tag' => 'img', - 'parse' => function (Element $node) { - return $this->img($node); - } + 'parse' => fn (Element $node) => $this->img($node) ], [ 'tag' => 'ol', - 'parse' => function (Element $node) { - return [ - 'content' => [ - 'text' => $this->list($node) - ], - 'type' => 'list', - ]; - } + 'parse' => fn (Element $node) => [ + 'content' => [ + 'text' => $this->list($node) + ], + 'type' => 'list', + ] ], [ 'tag' => 'pre', - 'parse' => function (Element $node) { - return $this->pre($node); - } + 'parse' => fn (Element $node) => $this->pre($node) ], [ 'tag' => 'table', - 'parse' => function (Element $node) { - return $this->table($node); - } + 'parse' => fn (Element $node) => $this->table($node) ], [ 'tag' => 'ul', - 'parse' => function (Element $node) { - return [ - 'content' => [ - 'text' => $this->list($node) - ], - 'type' => 'list', - ]; - } + 'parse' => fn (Element $node) => [ + 'content' => [ + 'text' => $this->list($node) + ], + 'type' => 'list', + ] ], ]; } - /** - * @param \Kirby\Parsley\Element $node - * @return array - */ public function pre(Element $node): array { $language = 'text'; @@ -421,10 +369,6 @@ class Blocks extends Plain ]; } - /** - * @param \Kirby\Parsley\Element $node - * @return array - */ public function table(Element $node): array { return [ diff --git a/kirby/src/Parsley/Schema/Plain.php b/kirby/src/Parsley/Schema/Plain.php index 96e976a..183556f 100644 --- a/kirby/src/Parsley/Schema/Plain.php +++ b/kirby/src/Parsley/Schema/Plain.php @@ -23,13 +23,10 @@ class Plain extends Schema /** * Creates the fallback block type * if no other block can be found - * - * @param \Kirby\Parsley\Element|string $element - * @return array|null */ - public function fallback($element): ?array + public function fallback(Element|string $element): array|null { - if (is_a($element, Element::class) === true) { + if ($element instanceof Element) { $text = $element->innerText(); } elseif (is_string($element) === true) { $text = trim($element); @@ -52,8 +49,6 @@ class Plain extends Schema /** * Returns a list of all elements that * should be skipped during parsing - * - * @return array */ public function skip(): array { diff --git a/kirby/src/Query/Argument.php b/kirby/src/Query/Argument.php new file mode 100644 index 0000000..579883d --- /dev/null +++ b/kirby/src/Query/Argument.php @@ -0,0 +1,108 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + */ +class Argument +{ + public function __construct( + public mixed $value + ) { + } + + /** + * Sanitizes argument string into actual + * PHP type/object as new Argument instance + */ + public static function factory(string $argument): static + { + $argument = trim($argument); + + // remove grouping parantheses + if ( + Str::startsWith($argument, '(') && + Str::endsWith($argument, ')') + ) { + $argument = trim(substr($argument, 1, -1)); + } + + // string with single or double quotes + if ( + ( + Str::startsWith($argument, '"') && + Str::endsWith($argument, '"') + ) || ( + Str::startsWith($argument, "'") && + Str::endsWith($argument, "'") + ) + ) { + $string = substr($argument, 1, -1); + $string = str_replace(['\"', "\'"], ['"', "'"], $string); + return new static($string); + } + + // array: split and recursive sanitizing + if ( + Str::startsWith($argument, '[') && + Str::endsWith($argument, ']') + ) { + $array = substr($argument, 1, -1); + $array = Arguments::factory($array); + return new static($array); + } + + // numeric + if (is_numeric($argument) === true) { + return new static((float)$argument); + } + + // Closure + if (Str::startsWith($argument, '() =>')) { + $query = Str::after($argument, '() =>'); + $query = trim($query); + return new static(fn () => $query); + } + + return new static(match ($argument) { + 'null' => null, + 'true' => true, + 'false' => false, + + // resolve parameter for objects and methods itself + default => new Query($argument) + }); + } + + /** + * Return the argument value and + * resolves nested objects to scaler types + */ + public function resolve(array|object $data = []): mixed + { + // don't resolve the Closure immediately, instead + // resolve it to the sub-query and create a new Closure + // that resolves the sub-query with the same data set once called + if ($this->value instanceof Closure) { + $query = ($this->value)(); + return fn () => static::factory($query)->resolve($data); + } + + if (is_object($this->value) === true) { + return $this->value->resolve($data); + } + + return $this->value; + } +} diff --git a/kirby/src/Query/Arguments.php b/kirby/src/Query/Arguments.php new file mode 100644 index 0000000..a187e1a --- /dev/null +++ b/kirby/src/Query/Arguments.php @@ -0,0 +1,58 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + */ +class Arguments extends Collection +{ + // skip all matches inside of parantheses + public const NO_PNTH = '\([^)]+\)(*SKIP)(*FAIL)'; + // skip all matches inside of square brackets + public const NO_SQBR = '\[[^]]+\](*SKIP)(*FAIL)'; + // skip all matches inside of double quotes + public const NO_DLQU = '\"(?:[^"\\\\]|\\\\.)*\"(*SKIP)(*FAIL)'; + // skip all matches inside of single quotes + public const NO_SLQU = '\'(?:[^\'\\\\]|\\\\.)*\'(*SKIP)(*FAIL)'; + // skip all matches inside of any of the above skip groups + public const OUTSIDE = self::NO_PNTH . '|' . self::NO_SQBR . '|' . + self::NO_DLQU . '|' . self::NO_SLQU; + + /** + * Splits list of arguments into individual + * Argument instances while respecting skip groups + */ + public static function factory(string $arguments): static + { + $arguments = A::map( + // split by comma, but not inside skip groups + preg_split('!,|' . self::OUTSIDE . '!', $arguments), + fn ($argument) => Argument::factory($argument) + ); + + return new static($arguments); + } + + /** + * Resolve each argument, so that they can + * passed together to the actual method call + */ + public function resolve(array|object $data = []): array + { + return A::map( + $this->data, + fn ($argument) => $argument->resolve($data) + ); + } +} diff --git a/kirby/src/Query/Expression.php b/kirby/src/Query/Expression.php new file mode 100644 index 0000000..cfea6fb --- /dev/null +++ b/kirby/src/Query/Expression.php @@ -0,0 +1,116 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + */ +class Expression +{ + public function __construct( + public array $parts + ) { + } + + public static function factory(string $expression, Query $parent = null): static|Segments + { + // split into different expression parts and operators + $parts = static::parse($expression); + + // shortcut: if expression has only one part, directly + // continue with the segments chain + if (count($parts) === 1) { + return Segments::factory(query: $parts[0], parent: $parent); + } + + // turn all non-operator parts into an Argument + // which takes care of converting string, arrays booleans etc. + // into actual types and treats all other parts as their own queries + $parts = A::map( + $parts, + fn ($part) => + in_array($part, ['?', ':', '?:', '??']) + ? $part + : Argument::factory($part) + ); + + return new static(parts: $parts); + } + + /** + * Splits a comparison string into an array + * of expressions and operators + * @internal + */ + public static function parse(string $string): array + { + // split by multiples of `?` and `:`, but not inside skip groups + // (parantheses, quotes etc.) + return preg_split( + '/\s+([\?\:]+)\s+|' . Arguments::OUTSIDE . '/', + trim($string), + flags: PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY + ); + } + + /** + * Resolves the expression by evaluating + * the supported comparisons and consecutively + * resolving the resulting query/argument + */ + public function resolve(array|object $data = []): mixed + { + $base = null; + + foreach ($this->parts as $index => $part) { + // `a ?? b` + // if the base/previous (e.g. `a`) isn't null, + // stop the expression chain and return `a` + if ($part === '??') { + if ($base !== null) { + return $base; + } + + continue; + } + + // `a ?: b` + // if `a` isn't false, return `a`, otherwise `b` + if ($part === '?:') { + if ($base != false) { + return $base; + } + + return $this->parts[$index + 1]->resolve($data); + } + + // `a ? b : c` + // if `a` isn't false, return `b`, otherwise `c` + if ($part === '?') { + if (($this->parts[$index + 2] ?? null) !== ':') { + throw new LogicException('Query: Incomplete ternary operator (missing matching `? :`)'); + } + + if ($base != false) { + return $this->parts[$index + 1]->resolve($data); + } + + return $this->parts[$index + 3]->resolve($data); + } + + $base = $part->resolve($data); + } + + return $base; + } +} diff --git a/kirby/src/Query/Query.php b/kirby/src/Query/Query.php new file mode 100644 index 0000000..40450bc --- /dev/null +++ b/kirby/src/Query/Query.php @@ -0,0 +1,138 @@ +, + * Nico Hoffmann + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + */ +class Query +{ + /** + * Default data entries + */ + public static array $entries = []; + + /** + * Creates a new Query object + */ + public function __construct( + public string|null $query = null + ) { + if ($query !== null) { + $this->query = trim($query); + } + } + + /** + * Creates a new Query object + */ + public static function factory(string $query): static + { + return new static(query: $query); + } + + /** + * Method to help classes that extend Query + * to intercept a segment's result. + */ + public function intercept(mixed $result): mixed + { + return $result; + } + + /** + * Returns the query result if anything + * can be found, otherwise returns null + * + * @throws \Kirby\Exception\BadMethodCallException If an invalid method is accessed by the query + */ + public function resolve(array|object $data = []): mixed + { + if (empty($this->query) === true) { + return $data; + } + + // merge data with default entries + if (is_array($data) === true) { + $data = array_merge(static::$entries, $data); + } + + // direct data array access via key + if ( + is_array($data) === true && + array_key_exists($this->query, $data) === true + ) { + $value = $data[$this->query]; + + if ($value instanceof Closure) { + $value = $value(); + } + + return $value; + } + + // loop through all segments to resolve query + return Expression::factory($this->query, $this)->resolve($data); + } +} + +/** + * Default entries/functions + */ +Query::$entries['kirby'] = function (): App { + return App::instance(); +}; + +Query::$entries['collection'] = function (string $name): Collection|null { + return App::instance()->collection($name); +}; + +Query::$entries['file'] = function (string $id): File|null { + return App::instance()->file($id); +}; + +Query::$entries['page'] = function (string $id): Page|null { + return App::instance()->site()->find($id); +}; + +Query::$entries['site'] = function (): Site { + return App::instance()->site(); +}; + + +Query::$entries['t'] = function ( + string $key, + string|array $fallback = null, + string $locale = null +): string|null { + return I18n::translate($key, $fallback, $locale); +}; + +Query::$entries['user'] = function (string $id = null): User|null { + return App::instance()->user($id); +}; diff --git a/kirby/src/Query/Segment.php b/kirby/src/Query/Segment.php new file mode 100644 index 0000000..25ed4fc --- /dev/null +++ b/kirby/src/Query/Segment.php @@ -0,0 +1,145 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + */ +class Segment +{ + public function __construct( + public string $method, + public int $position, + public Arguments|null $arguments = null, + ) { + } + + /** + * Throws an exception for an access to an invalid method + * @internal + * + * @param mixed $data Variable on which the access was tried + * @param string $name Name of the method/property that was accessed + * @param string $label Type of the name (`method`, `property` or `method/property`) + * + * @throws \Kirby\Exception\BadMethodCallException + */ + public static function error(mixed $data, string $name, string $label): void + { + $type = strtolower(gettype($data)); + + if ($type === 'double') { + $type = 'float'; + } + + $nonExisting = in_array($type, ['array', 'object']) ? 'non-existing ' : ''; + + $error = 'Access to ' . $nonExisting . $label . ' "' . $name . '" on ' . $type; + + throw new BadMethodCallException($error); + } + + public static function factory( + string $segment, + int $position = 0 + ): static { + if (Str::endsWith($segment, ')') === false) { + return new static(method: $segment, position: $position); + } + + // the args are everything inside the *outer* parentheses + $args = Str::substr($segment, Str::position($segment, '(') + 1, -1); + + return new static( + method: Str::before($segment, '('), + position: $position, + arguments: Arguments::factory($args) + ); + } + + public function resolve(mixed $base = null, array|object $data = []): mixed + { + // resolve arguments to array + $args = $this->arguments?->resolve($data) ?? []; + + // 1st segment, start from $data array + if ($this->position === 0) { + if (is_array($data) == true) { + return $this->resolveArray($data, $args); + } + + return $this->resolveObject($data, $args); + } + + if (is_array($base) === true) { + return $this->resolveArray($base, $args); + } + + if (is_object($base) === true) { + return $this->resolveObject($base, $args); + } + + // trying to access further segments on a scalar/null value + static::error($base, $this->method, 'method/property'); + } + + /** + * Resolves segment by calling the corresponding array key + */ + protected function resolveArray(array $array, array $args): mixed + { + if (array_key_exists($this->method, $array) === false) { + static::error($array, $this->method, 'property'); + } + + $value = $array[$this->method]; + + if ($value instanceof Closure) { + return $value(...$args); + } + + if ($args !== []) { + throw new InvalidArgumentException('Cannot access array element "' . $this->method . '" with arguments'); + } + + return $value; + } + + /** + * Resolves segment by calling the method/accessing the property + * on the base object + */ + protected function resolveObject(object $object, array $args): mixed + { + if ( + method_exists($object, $this->method) === true || + method_exists($object, '__call') === true + ) { + return $object->{$this->method}(...$args); + } + + if ( + $args === [] && ( + property_exists($object, $this->method) === true || + method_exists($object, '__get') === true + ) + ) { + return $object->{$this->method}; + } + + $label = ($args === []) ? 'method/property' : 'method'; + static::error($object, $this->method, $label); + } +} diff --git a/kirby/src/Query/Segments.php b/kirby/src/Query/Segments.php new file mode 100644 index 0000000..e49194d --- /dev/null +++ b/kirby/src/Query/Segments.php @@ -0,0 +1,99 @@ + + * @link https://getkirby.com + * @copyright Bastian Allgeier + * @license https://opensource.org/licenses/MIT + */ +class Segments extends Collection +{ + public function __construct( + array $data = [], + protected Query|null $parent = null, + ) { + parent::__construct($data); + } + + /** + * Split query string into segments by dot + * but not inside (nested) parens + */ + public static function factory(string $query, Query $parent = null): static + { + $segments = static::parse($query); + $position = 0; + + $segments = A::map( + $segments, + function ($segment) use (&$position) { + // leave connectors as they are + if (in_array($segment, ['.', '?.']) === true) { + return $segment; + } + + // turn all other parts into Segment objects + // and pass their position in the chain (ignoring connectors) + $position++; + return Segment::factory($segment, $position - 1); + } + ); + + return new static($segments, $parent); + } + + /** + * Splits the string of a segment chaing into an + * array of segments as well as conenctors (`.` or `?.`) + * @internal + */ + public static function parse(string $string): array + { + return preg_split( + '/(\??\.)|(\(([^()]+|(?2))*+\))(*SKIP)(*FAIL)/', + trim($string), + flags: PREG_SPLIT_DELIM_CAPTURE|PREG_SPLIT_NO_EMPTY + ); + } + + /** + * Resolves the segments chain by looping through + * each segment call to be applied to the value of + * all previous segment calls, returning gracefully at + * `?.` when current value is `null` + */ + public function resolve(array|object $data = []) + { + $value = null; + + foreach ($this->data as $segment) { + // optional chaining: stop if current value is null + if ($segment === '?.' && $value === null) { + return null; + } + + // for regular connectors, just skip + if ($segment === '.') { + continue; + } + + // offer possibility to intercept on objects + if ($value !== null) { + $value = $this->parent?->intercept($value) ?? $value; + } + + $value = $segment->resolve($value, $data); + } + + return $value; + } +} diff --git a/kirby/src/Sane/DomHandler.php b/kirby/src/Sane/DomHandler.php index 810a1ce..960e549 100644 --- a/kirby/src/Sane/DomHandler.php +++ b/kirby/src/Sane/DomHandler.php @@ -22,10 +22,8 @@ class DomHandler extends Handler /** * List of all MIME types that may * be used in data URIs - * - * @var array */ - public static $allowedDataUris = [ + public static array $allowedDataUris = [ 'data:image/png', 'data:image/gif', 'data:image/jpg', @@ -41,31 +39,24 @@ class DomHandler extends Handler /** * Allowed hostnames for HTTP(S) URLs * - * @var array + * @var array|true */ - public static $allowedDomains = []; + public static array|bool $allowedDomains = true; /** * Names of allowed XML processing instructions - * - * @var array */ - public static $allowedPIs = []; + public static array $allowedPIs = []; /** * The document type (`'HTML'` or `'XML'`) * (to be set in child classes) - * - * @var string */ - protected static $type = 'XML'; + protected static string $type = 'XML'; /** * Sanitizes the given string * - * @param string $string - * @return string - * * @throws \Kirby\Exception\InvalidArgumentException If the file couldn't be parsed */ public static function sanitize(string $string): string @@ -78,9 +69,6 @@ class DomHandler extends Handler /** * Validates file contents * - * @param string $string - * @return void - * * @throws \Kirby\Exception\InvalidArgumentException If the file couldn't be parsed * @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation */ @@ -98,7 +86,6 @@ class DomHandler extends Handler * Custom callback for additional attribute sanitization * @internal * - * @param \DOMAttr $attr * @return array Array with exception objects for each modification */ public static function sanitizeAttr(DOMAttr $attr): array @@ -111,7 +98,6 @@ class DomHandler extends Handler * Custom callback for additional element sanitization * @internal * - * @param \DOMElement $element * @return array Array with exception objects for each modification */ public static function sanitizeElement(DOMElement $element): array @@ -123,9 +109,6 @@ class DomHandler extends Handler /** * Custom callback for additional doctype validation * @internal - * - * @param \DOMDocumentType $doctype - * @return void */ public static function validateDoctype(DOMDocumentType $doctype): void { @@ -135,8 +118,6 @@ class DomHandler extends Handler /** * Returns the sanitization options for the handler * (to be extended in child classes) - * - * @return array */ protected static function options(): array { @@ -153,12 +134,9 @@ class DomHandler extends Handler /** * Parses the given string into a `Toolkit\Dom` object * - * @param string $string - * @return \Kirby\Toolkit\Dom - * * @throws \Kirby\Exception\InvalidArgumentException If the file couldn't be parsed */ - protected static function parse(string $string) + protected static function parse(string $string): Dom { return new Dom($string, static::$type); } diff --git a/kirby/src/Sane/Handler.php b/kirby/src/Sane/Handler.php index c66bc98..5b97044 100644 --- a/kirby/src/Sane/Handler.php +++ b/kirby/src/Sane/Handler.php @@ -21,9 +21,6 @@ abstract class Handler { /** * Sanitizes the given string - * - * @param string $string - * @return string */ abstract public static function sanitize(string $string): string; @@ -31,9 +28,6 @@ abstract class Handler * Sanitizes the contents of a file by overwriting * the file with the sanitized version * - * @param string $file - * @return void - * * @throws \Kirby\Exception\Exception If the file does not exist * @throws \Kirby\Exception\Exception On other errors */ @@ -46,9 +40,6 @@ abstract class Handler /** * Validates file contents * - * @param string $string - * @return void - * * @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation * @throws \Kirby\Exception\Exception On other errors */ @@ -57,9 +48,6 @@ abstract class Handler /** * Validates the contents of a file * - * @param string $file - * @return void - * * @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation * @throws \Kirby\Exception\Exception If the file does not exist * @throws \Kirby\Exception\Exception On other errors @@ -73,9 +61,6 @@ abstract class Handler * Reads the contents of a file * for sanitization or validation * - * @param string $file - * @return string - * * @throws \Kirby\Exception\Exception If the file does not exist */ protected static function readFile(string $file): string diff --git a/kirby/src/Sane/Html.php b/kirby/src/Sane/Html.php index 99823e5..c0b00aa 100644 --- a/kirby/src/Sane/Html.php +++ b/kirby/src/Sane/Html.php @@ -17,41 +17,28 @@ class Html extends DomHandler { /** * Global list of allowed attribute prefixes - * - * @var array */ - public static $allowedAttrPrefixes = [ + public static array $allowedAttrPrefixes = [ 'aria-', 'data-', ]; /** * Global list of allowed attributes - * - * @var array */ - public static $allowedAttrs = [ + public static array $allowedAttrs = [ 'class', 'id', ]; - /** - * Allowed hostnames for HTTP(S) URLs - * - * @var array - */ - public static $allowedDomains = true; - /** * Associative array of all allowed tag names with the value * of either an array with the list of all allowed attributes * for this tag, `true` to allow any attribute from the * `allowedAttrs` list or `false` to allow the tag without * any attributes - * - * @var array */ - public static $allowedTags = [ + public static array $allowedTags = [ 'a' => ['href', 'rel', 'title', 'target'], 'abbr' => ['title'], 'b' => true, @@ -95,10 +82,8 @@ class Html extends DomHandler * * IMPORTANT: Use lower-case names here because * of the case-insensitive matching - * - * @var array */ - public static $disallowedTags = [ + public static array $disallowedTags = [ 'iframe', 'meta', 'object', @@ -108,10 +93,8 @@ class Html extends DomHandler /** * List of attributes that may contain URLs - * - * @var array */ - public static $urlAttrs = [ + public static array $urlAttrs = [ 'href', 'src', 'xlink:href', @@ -119,15 +102,11 @@ class Html extends DomHandler /** * The document type (`'HTML'` or `'XML'`) - * - * @var string */ - protected static $type = 'HTML'; + protected static string $type = 'HTML'; /** * Returns the sanitization options for the handler - * - * @return array */ protected static function options(): array { diff --git a/kirby/src/Sane/Sane.php b/kirby/src/Sane/Sane.php index 5a55ae0..15522a0 100644 --- a/kirby/src/Sane/Sane.php +++ b/kirby/src/Sane/Sane.php @@ -23,10 +23,8 @@ class Sane { /** * Handler Type Aliases - * - * @var array */ - public static $aliases = [ + public static array $aliases = [ 'application/xml' => 'xml', 'image/svg' => 'svg', 'image/svg+xml' => 'svg', @@ -36,10 +34,8 @@ class Sane /** * All registered handlers - * - * @var array */ - public static $handlers = [ + public static array $handlers = [ 'html' => 'Kirby\Sane\Html', 'svg' => 'Kirby\Sane\Svg', 'svgz' => 'Kirby\Sane\Svgz', @@ -49,21 +45,19 @@ class Sane /** * Handler getter * - * @param string $type * @param bool $lazy If set to `true`, `null` is returned for undefined handlers - * @return \Kirby\Sane\Handler|null * * @throws \Kirby\Exception\NotFoundException If no handler was found and `$lazy` was set to `false` */ - public static function handler(string $type, bool $lazy = false) + public static function handler(string $type, bool $lazy = false): Handler|null { // normalize the type $type = mb_strtolower($type); // find a handler or alias + $alias = static::$aliases[$type] ?? null; $handler = static::$handlers[$type] ?? - static::$handlers[static::$aliases[$type] ?? null] ?? - null; + ($alias ? static::$handlers[$alias] ?? null : null); if (empty($handler) === false && class_exists($handler) === true) { return new $handler(); @@ -79,10 +73,6 @@ class Sane /** * Sanitizes the given string with the specified handler * @since 3.6.0 - * - * @param string $string - * @param string $type - * @return string */ public static function sanitize(string $string, string $type): string { @@ -96,18 +86,16 @@ class Sane * the extension and MIME type if not specified * @since 3.6.0 * - * @param string $file * @param string|bool $typeLazy Explicit handler type string, * `true` for lazy autodetection or * `false` for normal autodetection - * @return void * * @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation * @throws \Kirby\Exception\LogicException If more than one handler applies * @throws \Kirby\Exception\NotFoundException If the handler was not found * @throws \Kirby\Exception\Exception On other errors */ - public static function sanitizeFile(string $file, $typeLazy = false): void + public static function sanitizeFile(string $file, string|bool $typeLazy = false): void { if (is_string($typeLazy) === true) { static::handler($typeLazy)->sanitizeFile($file); @@ -137,10 +125,6 @@ class Sane /** * Validates file contents with the specified handler * - * @param string $string - * @param string $type - * @return void - * * @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation * @throws \Kirby\Exception\NotFoundException If the handler was not found * @throws \Kirby\Exception\Exception On other errors @@ -155,17 +139,15 @@ class Sane * the sane handlers are automatically chosen by * the extension and MIME type if not specified * - * @param string $file * @param string|bool $typeLazy Explicit handler type string, * `true` for lazy autodetection or * `false` for normal autodetection - * @return void * * @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation * @throws \Kirby\Exception\NotFoundException If the handler was not found * @throws \Kirby\Exception\Exception On other errors */ - public static function validateFile(string $file, $typeLazy = false): void + public static function validateFile(string $file, string|bool $typeLazy = false): void { if (is_string($typeLazy) === true) { static::handler($typeLazy)->validateFile($file); @@ -181,7 +163,6 @@ class Sane * Returns all handler objects that apply to the given file based on * file extension and MIME type * - * @param string $file * @param bool $lazy If set to `true`, undefined handlers are skipped * @return array<\Kirby\Sane\Handler> */ diff --git a/kirby/src/Sane/Svg.php b/kirby/src/Sane/Svg.php index d8d8604..2910272 100644 --- a/kirby/src/Sane/Svg.php +++ b/kirby/src/Sane/Svg.php @@ -33,20 +33,16 @@ class Svg extends Xml /** * Global list of allowed attribute prefixes - * - * @var array */ - public static $allowedAttrPrefixes = [ + public static array $allowedAttrPrefixes = [ 'aria-', 'data-', ]; /** * Global list of allowed attributes - * - * @var array */ - public static $allowedAttrs = [ + public static array $allowedAttrs = [ // core attributes 'id', 'lang', @@ -267,11 +263,16 @@ class Svg extends Xml ]; /** - * Associative array of all allowed namespace URIs + * Allowed hostnames for HTTP(S) URLs * - * @var array + * @var array|true */ - public static $allowedNamespaces = [ + public static array|bool $allowedDomains = []; + + /** + * Associative array of all allowed namespace URIs + */ + public static array $allowedNamespaces = [ '' => 'http://www.w3.org/2000/svg', 'xlink' => 'http://www.w3.org/1999/xlink' ]; @@ -282,10 +283,8 @@ class Svg extends Xml * for this tag, `true` to allow any attribute from the * `allowedAttrs` list or `false` to allow the tag without * any attributes - * - * @var array */ - public static $allowedTags = [ + public static array $allowedTags = [ 'a' => true, 'altGlyph' => true, 'altGlyphDef' => true, @@ -360,10 +359,8 @@ class Svg extends Xml * * IMPORTANT: Use lower-case names here because * of the case-insensitive matching - * - * @var array */ - public static $disallowedTags = [ + public static array $disallowedTags = [ 'animate', 'color-profile', 'cursor', @@ -393,7 +390,6 @@ class Svg extends Xml * Custom callback for additional attribute sanitization * @internal * - * @param \DOMAttr $attr * @return array Array with exception objects for each modification */ public static function sanitizeAttr(DOMAttr $attr): array @@ -415,7 +411,7 @@ class Svg extends Xml // the target must not contain any other elements if ( - is_a($target, 'DOMElement') === true && + $target instanceof DOMElement && $target->getElementsByTagName('use')->count() > 0 ) { $errors[] = new InvalidArgumentException( @@ -433,7 +429,6 @@ class Svg extends Xml * Custom callback for additional element sanitization * @internal * - * @param \DOMElement $element * @return array Array with exception objects for each modification */ public static function sanitizeElement(DOMElement $element): array @@ -459,9 +454,6 @@ class Svg extends Xml /** * Custom callback for additional doctype validation * @internal - * - * @param \DOMDocumentType $doctype - * @return void */ public static function validateDoctype(DOMDocumentType $doctype): void { @@ -472,8 +464,6 @@ class Svg extends Xml /** * Returns the sanitization options for the handler - * - * @return array */ protected static function options(): array { @@ -489,12 +479,9 @@ class Svg extends Xml /** * Parses the given string into a `Toolkit\Dom` object * - * @param string $string - * @return \Kirby\Toolkit\Dom - * * @throws \Kirby\Exception\InvalidArgumentException If the file couldn't be parsed */ - protected static function parse(string $string) + protected static function parse(string $string): Dom { $svg = parent::parse($string); diff --git a/kirby/src/Sane/Svgz.php b/kirby/src/Sane/Svgz.php index fa8f925..a6f2706 100644 --- a/kirby/src/Sane/Svgz.php +++ b/kirby/src/Sane/Svgz.php @@ -19,9 +19,6 @@ class Svgz extends Svg /** * Sanitizes the given string * - * @param string $string - * @return string - * * @throws \Kirby\Exception\InvalidArgumentException If the file couldn't be parsed or recompressed */ public static function sanitize(string $string): string @@ -40,9 +37,6 @@ class Svgz extends Svg /** * Validates file contents * - * @param string $string - * @return void - * * @throws \Kirby\Exception\InvalidArgumentException If the file couldn't be parsed * @throws \Kirby\Exception\InvalidArgumentException If the file didn't pass validation */ @@ -53,9 +47,6 @@ class Svgz extends Svg /** * Uncompresses the SVGZ data - * - * @param string $string - * @return string */ protected static function uncompress(string $string): string { diff --git a/kirby/src/Sane/Xml.php b/kirby/src/Sane/Xml.php index 6a99df2..e012c71 100644 --- a/kirby/src/Sane/Xml.php +++ b/kirby/src/Sane/Xml.php @@ -24,7 +24,6 @@ class Xml extends DomHandler * Custom callback for additional element sanitization * @internal * - * @param \DOMElement $element * @return array Array with exception objects for each modification */ public static function sanitizeElement(DOMElement $element): array @@ -54,9 +53,6 @@ class Xml extends DomHandler /** * Custom callback for additional doctype validation * @internal - * - * @param \DOMDocumentType $doctype - * @return void */ public static function validateDoctype(DOMDocumentType $doctype): void { diff --git a/kirby/src/Session/AutoSession.php b/kirby/src/Session/AutoSession.php index 73453b2..d2d0a6a 100644 --- a/kirby/src/Session/AutoSession.php +++ b/kirby/src/Session/AutoSession.php @@ -75,11 +75,10 @@ class AutoSession } // get the current session - if ($options['detect'] === true) { - $session = $this->sessions->currentDetected(); - } else { - $session = $this->sessions->current(); - } + $session = match ($options['detect']) { + true => $this->sessions->currentDetected(), + default => $this->sessions->current() + }; // create a new session if ($session === null) { diff --git a/kirby/src/Session/FileSessionStore.php b/kirby/src/Session/FileSessionStore.php index 0bcece0..7fdc4fc 100644 --- a/kirby/src/Session/FileSessionStore.php +++ b/kirby/src/Session/FileSessionStore.php @@ -157,7 +157,9 @@ class FileSessionStore extends SessionStore // check if the file is already unlocked or doesn't exist if (!isset($this->isLocked[$name])) { return; - } elseif ($this->exists($expiryTime, $id) === false) { + } + + if ($this->exists($expiryTime, $id) === false) { unset($this->isLocked[$name]); return; } diff --git a/kirby/src/Session/Session.php b/kirby/src/Session/Session.php index 2751081..66f5416 100644 --- a/kirby/src/Session/Session.php +++ b/kirby/src/Session/Session.php @@ -139,12 +139,12 @@ class Session if ($this->tokenExpiry !== null) { if (is_string($this->tokenKey)) { return $this->tokenExpiry . '.' . $this->tokenId . '.' . $this->tokenKey; - } else { - return $this->tokenExpiry . '.' . $this->tokenId; } - } else { - return null; + + return $this->tokenExpiry . '.' . $this->tokenId; } + + return null; } /** @@ -611,12 +611,15 @@ class Session // now make sure that we have a valid timestamp if (is_int($time)) { return $time; - } else { - throw new InvalidArgumentException([ - 'data' => ['method' => 'Session::timeToTimestamp', 'argument' => '$time'], - 'translate' => false - ]); } + + throw new InvalidArgumentException([ + 'data' => [ + 'method' => 'Session::timeToTimestamp', + 'argument' => '$time' + ], + 'translate' => false + ]); } /** @@ -727,7 +730,7 @@ class Session $this->renewable = $data['renewable']; // reload data into existing object to avoid breaking memory references - if (is_a($this->data, 'Kirby\Session\SessionData')) { + if ($this->data instanceof SessionData) { $this->data()->reload($data['data']); } else { $this->data = new SessionData($this, $data['data']); diff --git a/kirby/src/Session/SessionData.php b/kirby/src/Session/SessionData.php index eb9ee14..0ff8752 100644 --- a/kirby/src/Session/SessionData.php +++ b/kirby/src/Session/SessionData.php @@ -177,14 +177,19 @@ class SessionData { if (is_string($key)) { return $this->data[$key] ?? $default; - } elseif ($key === null) { - return $this->data; - } else { - throw new InvalidArgumentException([ - 'data' => ['method' => 'SessionData::get', 'argument' => 'key'], - 'translate' => false - ]); } + + if ($key === null) { + return $this->data; + } + + throw new InvalidArgumentException([ + 'data' => [ + 'method' => 'SessionData::get', + 'argument' => 'key' + ], + 'translate' => false + ]); } /** diff --git a/kirby/src/Session/Sessions.php b/kirby/src/Session/Sessions.php index 86c26b2..221ae73 100644 --- a/kirby/src/Session/Sessions.php +++ b/kirby/src/Session/Sessions.php @@ -40,7 +40,7 @@ class Sessions { if (is_string($store)) { $this->store = new FileSessionStore($store); - } elseif (is_a($store, 'Kirby\Session\SessionStore') === true) { + } elseif ($store instanceof SessionStore) { $this->store = $store; } else { throw new InvalidArgumentException([ @@ -101,9 +101,7 @@ class Sessions public function create(array $options = []) { // fall back to default mode - if (!isset($options['mode'])) { - $options['mode'] = $this->mode; - } + $options['mode'] ??= $this->mode; return new Session($this, null, $options); } @@ -117,11 +115,7 @@ class Sessions */ public function get(string $token, string $mode = null) { - if (isset($this->cache[$token])) { - return $this->cache[$token]; - } - - return $this->cache[$token] = new Session($this, $token, ['mode' => $mode ?? $this->mode]); + return $this->cache[$token] ??= new Session($this, $token, ['mode' => $mode ?? $this->mode]); } /** @@ -131,38 +125,33 @@ class Sessions * - In `manual` mode: Fails and throws an Exception * * @return \Kirby\Session\Session|null Either the current session or null in case there isn't one + * @throws \Kirby\Exception\Exception + * @throws \Kirby\Exception\LogicException */ public function current() { - $token = null; - switch ($this->mode) { - case 'cookie': - $token = $this->tokenFromCookie(); - break; - case 'header': - $token = $this->tokenFromHeader(); - break; - case 'manual': - throw new LogicException([ - 'key' => 'session.sessions.manualMode', - 'fallback' => 'Cannot automatically get current session in manual mode', - 'translate' => false, - 'httpCode' => 500 - ]); - default: - // unexpected error that shouldn't occur - throw new Exception(['translate' => false]); // @codeCoverageIgnore - } + $token = match ($this->mode) { + 'cookie' => $this->tokenFromCookie(), + 'header' => $this->tokenFromHeader(), + 'manual' => throw new LogicException([ + 'key' => 'session.sessions.manualMode', + 'fallback' => 'Cannot automatically get current session in manual mode', + 'translate' => false, + 'httpCode' => 500 + ]), + // unexpected error that shouldn't occur + default => throw new Exception(['translate' => false]) // @codeCoverageIgnore + }; // no token was found, no session - if (!is_string($token)) { + if (is_string($token) === false) { return null; } // token was found, try to get the session try { return $this->get($token); - } catch (Throwable $e) { + } catch (Throwable) { return null; } } @@ -192,7 +181,7 @@ class Sessions try { $mode = (is_string($tokenFromHeader)) ? 'header' : 'cookie'; return $this->get($token, $mode); - } catch (Throwable $e) { + } catch (Throwable) { return null; } } @@ -253,11 +242,11 @@ class Sessions { $value = Cookie::get($this->cookieName()); - if (is_string($value)) { - return $value; - } else { + if (is_string($value) === false) { return null; } + + return $value; } /** @@ -271,7 +260,7 @@ class Sessions $headers = $request->headers(); // check if the header exists at all - if (!isset($headers['Authorization'])) { + if (isset($headers['Authorization']) === false) { return null; } diff --git a/kirby/src/Text/KirbyTag.php b/kirby/src/Text/KirbyTag.php index aea9cab..be11a26 100644 --- a/kirby/src/Text/KirbyTag.php +++ b/kirby/src/Text/KirbyTag.php @@ -2,9 +2,15 @@ namespace Kirby\Text; +use AllowDynamicProperties; +use Closure; use Kirby\Cms\App; +use Kirby\Cms\File; +use Kirby\Cms\Model; use Kirby\Exception\BadMethodCallException; use Kirby\Exception\InvalidArgumentException; +use Kirby\Uuid\Uri as UuidUri; +use Kirby\Uuid\Uuid; /** * Representation and parse of a single KirbyTag. @@ -14,30 +20,30 @@ use Kirby\Exception\InvalidArgumentException; * @link https://getkirby.com * @copyright Bastian Allgeier * @license https://opensource.org/licenses/MIT + * + * @todo remove the following psalm suppress when PHP >= 8.2 required + * @psalm-suppress UndefinedAttributeClass */ +#[AllowDynamicProperties] class KirbyTag { - public static $aliases = []; - public static $types = []; + public static array $aliases = []; + public static array $types = []; - public $attrs = []; - public $data = []; - public $options = []; - public $type = null; - public $value = null; + public array $attrs = []; + public array $data = []; + public array $options = []; + public string $type; + public string|null $value = null; - public function __call(string $name, array $arguments = []) - { - return $this->data[$name] ?? $this->$name; - } - - public static function __callStatic(string $type, array $arguments = []) - { - return (new static($type, ...$arguments))->render(); - } - - public function __construct(string $type, string $value = null, array $attrs = [], array $data = [], array $options = []) - { + public function __construct( + string $type, + string|null $value = null, + array $attrs = [], + array $data = [], + array $options = [] + ) { + // type aliases if (isset(static::$types[$type]) === false) { if (isset(static::$aliases[$type]) === false) { throw new InvalidArgumentException('Undefined tag type: ' . $type); @@ -70,6 +76,22 @@ class KirbyTag $this->value = $value; } + /** + * Magic data and property getter + */ + public function __call(string $name, array $arguments = []) + { + return $this->data[$name] ?? $this->$name; + } + + /** + * Magic call `KirbyTag::myType($parameter1, $parameter2)` + */ + public static function __callStatic(string $type, array $arguments = []): string + { + return (new static($type, ...$arguments))->render(); + } + public function __get(string $attr) { $attr = strtolower($attr); @@ -82,7 +104,7 @@ class KirbyTag return $this->$name ?? $default; } - public static function factory(...$arguments) + public static function factory(...$arguments): string { return (new static(...$arguments))->render(); } @@ -92,14 +114,23 @@ class KirbyTag * The method first searches the file * in the current parent, if it's a page. * Afterwards it uses Kirby's global file finder. - * - * @param string $path - * @return \Kirby\Cms\File|null */ - public function file(string $path) + public function file(string $path): File|null { $parent = $this->parent(); + // check first for UUID + if (Uuid::is($path, 'file') === true) { + if ( + is_object($parent) === true && + method_exists($parent, 'files') === true + ) { + $context = $parent->files(); + } + + return Uuid::for($path, $context ?? null)->model(); + } + if ( is_object($parent) === true && method_exists($parent, 'file') === true && @@ -109,8 +140,8 @@ class KirbyTag } if ( - is_a($parent, 'Kirby\Cms\File') === true && - $file = $parent->page()->file($path) + $parent instanceof File && + $file = $parent->page()?->file($path) ) { return $file; } @@ -119,10 +150,8 @@ class KirbyTag } /** * Returns the current Kirby instance - * - * @return \Kirby\Cms\App */ - public function kirby() + public function kirby(): App { return $this->data['kirby'] ?? App::instance(); } @@ -132,14 +161,11 @@ class KirbyTag return $this->options[$key] ?? $default; } - /** - * @param string $string - * @param array $data - * @param array $options - * @return static - */ - public static function parse(string $string, array $data = [], array $options = []) - { + public static function parse( + string $string, + array $data = [], + array $options = [] + ): static { // remove the brackets, extract the first attribute (the tag type) $tag = trim(ltrim($string, '(')); @@ -149,7 +175,8 @@ class KirbyTag $tag = substr($tag, 0, -1); } - $type = trim(substr($tag, 0, strpos($tag, ':'))); + $pos = strpos($tag, ':'); + $type = trim(substr($tag, 0, $pos ? $pos : null)); $type = strtolower($type); $attr = static::$types[$type]['attr'] ?? []; @@ -157,8 +184,11 @@ class KirbyTag // to the list of possible attributes array_unshift($attr, $type); + // ensure that UUIDs protocols aren't matched as attributes + $uuids = sprintf('(?!(%s):\/\/)', implode('|', UuidUri::$schemes)); + // extract all attributes - $regex = sprintf('/(%s):/i', implode('|', $attr)); + $regex = sprintf('/%s(%s):/i', $uuids, implode('|', $attr)); $search = preg_split($regex, $tag, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY); // $search is now an array with alternating keys and values @@ -185,10 +215,8 @@ class KirbyTag /** * Returns the parent model - * - * @return \Kirby\Cms\Model|null */ - public function parent() + public function parent(): Model|null { return $this->data['parent']; } @@ -197,7 +225,7 @@ class KirbyTag { $callback = static::$types[$this->type]['html'] ?? null; - if (is_a($callback, 'Closure') === true) { + if ($callback instanceof Closure) { return (string)$callback($this); } diff --git a/kirby/src/Text/KirbyTags.php b/kirby/src/Text/KirbyTags.php index 80ad584..6121552 100644 --- a/kirby/src/Text/KirbyTags.php +++ b/kirby/src/Text/KirbyTags.php @@ -20,8 +20,11 @@ use Kirby\Toolkit\Str; */ class KirbyTags { - public static function parse(string $text = null, array $data = [], array $options = []): string - { + public static function parse( + string|null $text = null, + array $data = [], + array $options = [] + ): string { $regex = '! (?=[^\]]) # positive lookahead that matches a group after the main expression without including ] in the result (?=\([a-z0-9_-]+:) # positive lookahead that requires starts with ( and lowercase ASCII letters, digits, underscores or hyphens followed with : immediately to the right of the current location diff --git a/kirby/src/Text/Markdown.php b/kirby/src/Text/Markdown.php index 1a7b3d0..ae49451 100644 --- a/kirby/src/Text/Markdown.php +++ b/kirby/src/Text/Markdown.php @@ -23,16 +23,12 @@ class Markdown /** * Array with all configured options * for the parser - * - * @var array */ - protected $options = []; + protected array $options = []; /** * Returns default values for all * available parser options - * - * @return array */ public function defaults(): array { @@ -46,8 +42,6 @@ class Markdown /** * Creates a new Markdown parser * with the given options - * - * @param array $options */ public function __construct(array $options = []) { @@ -56,12 +50,8 @@ class Markdown /** * Parses the given text and returns the HTML - * - * @param string|null $text - * @param bool $inline - * @return string */ - public function parse(string $text = null, bool $inline = false): string + public function parse(string|null $text = null, bool $inline = false): string { if ($this->options['extra'] === true) { $parser = new ParsedownExtra(); @@ -74,8 +64,8 @@ class Markdown if ($inline === true) { return @$parser->line($text); - } else { - return @$parser->text($text); } + + return @$parser->text($text); } } diff --git a/kirby/src/Text/SmartyPants.php b/kirby/src/Text/SmartyPants.php index c384099..c87761b 100644 --- a/kirby/src/Text/SmartyPants.php +++ b/kirby/src/Text/SmartyPants.php @@ -21,23 +21,17 @@ class SmartyPants /** * Array with all configured options * for the parser - * - * @var array */ - protected $options = []; + protected array $options = []; /** * Michelf's parser object - * - * @var SmartyPantsTypographer */ - protected $parser; + protected SmartyPantsTypographer $parser; /** * Returns default values for all * available parser options - * - * @return array */ public function defaults(): array { @@ -75,8 +69,6 @@ class SmartyPants /** * Creates a new SmartyPants parser * with the given options - * - * @param array $options */ public function __construct(array $options = []) { @@ -114,11 +106,8 @@ class SmartyPants /** * Parses the given text - * - * @param string|null $text - * @return string */ - public function parse(string $text = null): string + public function parse(string|null $text = null): string { // prepare the text $text = str_replace('"', '"', $text ?? ''); diff --git a/kirby/src/Toolkit/A.php b/kirby/src/Toolkit/A.php index 58eab0b..4097804 100644 --- a/kirby/src/Toolkit/A.php +++ b/kirby/src/Toolkit/A.php @@ -2,6 +2,7 @@ namespace Kirby\Toolkit; +use Closure; use Exception; /** @@ -21,14 +22,10 @@ class A { /** * Appends the given array - * - * @param array $array - * @param array $append - * @return array */ public static function append(array $array, array $append): array { - return $array + $append; + return static::merge($array, $append, A::MERGE_APPEND); } /** @@ -37,14 +34,12 @@ class A * applying the passed parameters * @since 3.5.6 * - * @param array $array * @param mixed ...$args Parameters to pass to the closures - * @return array */ public static function apply(array $array, ...$args): array { array_walk_recursive($array, function (&$item) use ($args) { - if (is_a($item, 'Closure')) { + if ($item instanceof Closure) { $item = $item(...$args); } }); @@ -73,13 +68,16 @@ class A * * * @param array $array The source array - * @param mixed $key The key to look for - * @param mixed $default Optional default value, which should be - * returned if no element has been found - * @return mixed + * @param string|int|array|null $key The key to look for + * @param mixed $default Optional default value, which + * should be returned if no element + * has been found */ - public static function get($array, $key, $default = null) - { + public static function get( + $array, + string|int|array|null $key, + $default = null + ) { if (is_array($array) === false) { return $array; } @@ -141,11 +139,9 @@ class A } /** - * @param mixed $value - * @param mixed $separator - * @return string + * Joins the elements of an array to a string */ - public static function join($value, $separator = ', ') + public static function join(array|string $value, string $separator = ', '): string { if (is_string($value) === true) { return $value; @@ -160,43 +156,65 @@ class A /** * Merges arrays recursively * - * @param array $array1 - * @param array $array2 - * @param int $mode Behavior for elements with numeric keys; - * A::MERGE_APPEND: elements are appended, keys are reset; - * A::MERGE_OVERWRITE: elements are overwritten, keys are preserved - * A::MERGE_REPLACE: non-associative arrays are completely replaced - * @return array + * If last argument is an integer, it defines the + * behavior for elements with numeric keys; + * - A::MERGE_OVERWRITE: elements are overwritten, keys are preserved + * - A::MERGE_APPEND: elements are appended, keys are reset; + * - A::MERGE_REPLACE: non-associative arrays are completely replaced */ - public static function merge($array1, $array2, int $mode = A::MERGE_APPEND) + public static function merge(array|int ...$arrays): array { - $merged = $array1; + // get mode from parameters + $last = A::last($arrays); + $mode = is_int($last) ? array_pop($arrays) : A::MERGE_APPEND; - if (static::isAssociative($array1) === false && $mode === static::MERGE_REPLACE) { - return $array2; - } + // get the first two arrays that should be merged + $merged = array_shift($arrays); + $join = array_shift($arrays); - foreach ($array2 as $key => $value) { - // append to the merged array, don't overwrite numeric keys - if (is_int($key) === true && $mode === static::MERGE_APPEND) { - $merged[] = $value; + if ( + static::isAssociative($merged) === false && + $mode === static::MERGE_REPLACE + ) { + $merged = $join; + } else { + foreach ($join as $key => $value) { + // append to the merged array, don't overwrite numeric keys + if ( + is_int($key) === true && + $mode === static::MERGE_APPEND + ) { + $merged[] = $value; - // recursively merge the two array values - } elseif (is_array($value) === true && isset($merged[$key]) === true && is_array($merged[$key]) === true) { - $merged[$key] = static::merge($merged[$key], $value, $mode); + // recursively merge the two array values + } elseif ( + is_array($value) === true && + isset($merged[$key]) === true && + is_array($merged[$key]) === true + ) { + $merged[$key] = static::merge($merged[$key], $value, $mode); - // simply overwrite with the value from the second array - } else { - $merged[$key] = $value; + // simply overwrite with the value from the second array + } else { + $merged[$key] = $value; + } + } + + if ($mode === static::MERGE_APPEND) { + // the keys don't make sense anymore, reset them + // array_merge() is the simplest way to renumber + // arrays that have both numeric and string keys; + // besides the keys, nothing changes here + $merged = array_merge($merged, []); } } - if ($mode === static::MERGE_APPEND) { - // the keys don't make sense anymore, reset them - // array_merge() is the simplest way to renumber - // arrays that have both numeric and string keys; - // besides the keys, nothing changes here - $merged = array_merge($merged, []); + // if more than two arrays need to be merged, add the result + // as first array and the mode to the end and call the method again + if (count($arrays) > 0) { + array_unshift($arrays, $merged); + array_push($arrays, $mode); + return static::merge(...$arrays); } return $merged; @@ -230,7 +248,7 @@ class A * @return array The result array with all values * from that column. */ - public static function pluck(array $array, string $key) + public static function pluck(array $array, string $key): array { $output = []; foreach ($array as $a) { @@ -244,10 +262,6 @@ class A /** * Prepends the given array - * - * @param array $array - * @param array $prepend - * @return array */ public static function prepend(array $array, array $prepend): array { @@ -337,11 +351,6 @@ class A /** * Returns a number of random elements from an array, * either in original or shuffled order - * - * @param array $array - * @param int $count - * @param bool $shuffle - * @return array */ public static function random(array $array, int $count = 1, bool $shuffle = false): array { @@ -400,10 +409,6 @@ class A * A simple wrapper around array_map * with a sane argument order * @since 3.6.0 - * - * @param array $array - * @param callable $map - * @return array */ public static function map(array $array, callable $map): array { @@ -412,11 +417,6 @@ class A /** * Move an array item to a new index - * - * @param array $array - * @param int $from - * @param int $to - * @return array */ public static function move(array $array, int $from, int $to): array { @@ -480,10 +480,8 @@ class A * Normalizes an array into a nested form by converting * dot notation in keys to nested structures * - * @param array $array * @param array $ignore List of keys in dot notation that should * not be converted to a nested structure - * @return array */ public static function nest(array $array, array $ignore = []): array { @@ -523,10 +521,10 @@ class A is_array($result[$key]) === true && is_array($value) === true ) { - $result[$key] = array_replace_recursive($result[$key], $value); - } else { - $result[$key] = $value; + $value = array_replace_recursive($result[$key], $value); } + + $result[$key] = $value; } return $result; @@ -661,8 +659,12 @@ class A * @param int $decimals The number of decimals to return * @return float The average value */ - public static function average(array $array, int $decimals = 0): float + public static function average(array $array, int $decimals = 0): float|null { + if (empty($array) === true) { + return null; + } + return round((array_sum($array) / sizeof($array)), $decimals); } @@ -681,11 +683,8 @@ class A * // 'password' => 'super-secret' * // ]; * - * - * @param array ...$arrays - * @return array */ - public static function extend(...$arrays): array + public static function extend(array ...$arrays): array { return array_merge_recursive(...$arrays); } @@ -713,19 +712,15 @@ class A * } * ]); * - * - * @param array $array - * @param array $update - * @return array */ public static function update(array $array, array $update): array { foreach ($update as $key => $value) { - if (is_a($value, 'Closure') === true) { - $array[$key] = call_user_func($value, static::get($array, $key)); - } else { - $array[$key] = $value; + if ($value instanceof Closure) { + $value = call_user_func($value, static::get($array, $key)); } + + $array[$key] = $value; } return $array; @@ -734,29 +729,24 @@ class A /** * Wraps the given value in an array * if it's not an array yet. - * - * @param mixed|null $array - * @return array */ public static function wrap($array = null): array { if ($array === null) { return []; - } elseif (is_array($array) === false) { - return [$array]; - } else { - return $array; } + + if (is_array($array) === false) { + return [$array]; + } + + return $array; } /** * Filter the array using the given callback * using both value and key * @since 3.6.5 - * - * @param array $array - * @param callable $callback - * @return array */ public static function filter(array $array, callable $callback): array { @@ -766,19 +756,16 @@ class A /** * Remove key(s) from an array * @since 3.6.5 - * - * @param array $array - * @param int|string|array $keys - * @return array */ - public static function without(array $array, $keys): array + public static function without(array $array, int|string|array $keys): array { if (is_int($keys) || is_string($keys)) { $keys = static::wrap($keys); } - return static::filter($array, function ($value, $key) use ($keys) { - return in_array($key, $keys, true) === false; - }); + return static::filter( + $array, + fn ($value, $key) => in_array($key, $keys, true) === false + ); } } diff --git a/kirby/src/Toolkit/Collection.php b/kirby/src/Toolkit/Collection.php index 7bf9b88..6710a4b 100644 --- a/kirby/src/Toolkit/Collection.php +++ b/kirby/src/Toolkit/Collection.php @@ -99,11 +99,11 @@ class Collection extends Iterator implements Countable */ public function __set(string $key, $value): void { - if ($this->caseSensitive === true) { - $this->data[$key] = $value; - } else { - $this->data[strtolower($key)] = $value; + if ($this->caseSensitive !== true) { + $key = strtolower($key); } + + $this->data[$key] = $value; } /** @@ -380,11 +380,11 @@ class Collection extends Iterator implements Countable public function find(...$keys) { if (count($keys) === 1) { - if (is_array($keys[0]) === true) { - $keys = $keys[0]; - } else { + if (is_array($keys[0]) === false) { return $this->findByKey($keys[0]); } + + $keys = $keys[0]; } $result = []; @@ -551,12 +551,14 @@ class Collection extends Iterator implements Countable // make sure we have a proper key for each group if (is_array($value) === true) { throw new Exception('You cannot group by arrays or objects'); - } elseif (is_object($value) === true) { + } + + if (is_object($value) === true) { if (method_exists($value, '__toString') === false) { throw new Exception('You cannot group by arrays or objects'); - } else { - $value = (string)$value; } + + $value = (string)$value; } if (isset($groups[$value]) === false) { @@ -1175,11 +1177,7 @@ class Collection extends Iterator implements Countable return $callback->call($this, $condition); } - if ($fallback !== null) { - return $fallback->call($this, $condition); - } - - return $this; + return $fallback?->call($this, $condition) ?? $this; } /** diff --git a/kirby/src/Toolkit/Component.php b/kirby/src/Toolkit/Component.php index 7ada97c..f4a0dab 100644 --- a/kirby/src/Toolkit/Component.php +++ b/kirby/src/Toolkit/Component.php @@ -2,7 +2,9 @@ namespace Kirby\Toolkit; +use AllowDynamicProperties; use ArgumentCountError; +use Closure; use Kirby\Exception\Exception; use Kirby\Exception\InvalidArgumentException; use Kirby\Filesystem\F; @@ -16,7 +18,11 @@ use TypeError; * @link https://getkirby.com * @copyright Bastian Allgeier * @license https://opensource.org/licenses/MIT + * + * @todo remove the following psalm suppress when PHP >= 8.2 required + * @psalm-suppress UndefinedAttributeClass */ +#[AllowDynamicProperties] class Component { /** @@ -179,17 +185,17 @@ class Component protected function applyProps(array $props): void { foreach ($props as $propName => $propFunction) { - if (is_a($propFunction, 'Closure') === true) { + if ($propFunction instanceof Closure) { if (isset($this->attrs[$propName]) === true) { try { $this->$propName = $this->props[$propName] = $propFunction->call($this, $this->attrs[$propName]); - } catch (TypeError $e) { + } catch (TypeError) { throw new TypeError('Invalid value for "' . $propName . '"'); } } else { try { $this->$propName = $this->props[$propName] = $propFunction->call($this); - } catch (ArgumentCountError $e) { + } catch (ArgumentCountError) { throw new ArgumentCountError('Please provide a value for "' . $propName . '"'); } } @@ -209,7 +215,7 @@ class Component protected function applyComputed(array $computed): void { foreach ($computed as $computedName => $computedFunction) { - if (is_a($computedFunction, 'Closure') === true) { + if ($computedFunction instanceof Closure) { $this->$computedName = $this->computed[$computedName] = $computedFunction->call($this); } } @@ -231,7 +237,7 @@ class Component throw new Exception('Component definition ' . $definition . ' does not exist'); } - static::$types[$type] = $definition = F::load($definition); + static::$types[$type] = $definition = F::load($definition, allowOutput: false); } return $definition; @@ -253,7 +259,11 @@ class Component if (isset($definition['extends']) === true) { // extend other definitions - $options = array_replace_recursive(static::defaults(), static::load($definition['extends']), $definition); + $options = array_replace_recursive( + static::defaults(), + static::load($definition['extends']), + $definition + ); } else { // inject defaults $options = array_replace_recursive(static::defaults(), $definition); @@ -265,10 +275,14 @@ class Component if (isset(static::$mixins[$mixin]) === true) { if (is_string(static::$mixins[$mixin]) === true) { // resolve a path to a mixin on demand - static::$mixins[$mixin] = include static::$mixins[$mixin]; + + static::$mixins[$mixin] = F::load(static::$mixins[$mixin], allowOutput: false); } - $options = array_replace_recursive(static::$mixins[$mixin], $options); + $options = array_replace_recursive( + static::$mixins[$mixin], + $options + ); } } } @@ -283,7 +297,7 @@ class Component */ public function toArray(): array { - if (is_a($this->options['toArray'] ?? null, 'Closure') === true) { + if (($this->options['toArray'] ?? null) instanceof Closure) { return $this->options['toArray']->call($this); } diff --git a/kirby/src/Toolkit/Controller.php b/kirby/src/Toolkit/Controller.php index 259ada5..c20787e 100644 --- a/kirby/src/Toolkit/Controller.php +++ b/kirby/src/Toolkit/Controller.php @@ -58,7 +58,7 @@ class Controller $function = F::load($file); - if (is_a($function, 'Closure') === false) { + if ($function instanceof Closure === false) { return null; } diff --git a/kirby/src/Toolkit/Date.php b/kirby/src/Toolkit/Date.php index 9e0ca81..0f706eb 100644 --- a/kirby/src/Toolkit/Date.php +++ b/kirby/src/Toolkit/Date.php @@ -3,6 +3,7 @@ namespace Kirby\Toolkit; use DateTime; +use DateTimeInterface; use DateTimeZone; use Exception; use Kirby\Exception\InvalidArgumentException; @@ -32,7 +33,7 @@ class Date extends DateTime $datetime = date('r', $datetime); } - if (is_a($datetime, 'DateTimeInterface') === true) { + if ($datetime instanceof DateTimeInterface) { $datetime = $datetime->format('r'); } @@ -84,7 +85,7 @@ class Date extends DateTime * @param int|null $day * @return int */ - public function day(?int $day = null): int + public function day(int|null $day = null): int { if ($day === null) { return (int)$this->format('d'); @@ -126,7 +127,7 @@ class Date extends DateTime * @param int|null $hour * @return int */ - public function hour(?int $hour = null): int + public function hour(int|null $hour = null): int { if ($hour === null) { return (int)$this->format('H'); @@ -234,7 +235,7 @@ class Date extends DateTime * @param int|null $minute * @return int */ - public function minute(?int $minute = null): int + public function minute(int|null $minute = null): int { if ($minute === null) { return (int)$this->format('i'); @@ -250,7 +251,7 @@ class Date extends DateTime * @param int|null $month * @return int */ - public function month(?int $month = null): int + public function month(int|null $month = null): int { if ($month === null) { return (int)$this->format('m'); @@ -305,7 +306,7 @@ class Date extends DateTime * @param \DateTimeZone|null $timezone * @return static|null */ - public static function optional(?string $datetime = null, ?DateTimeZone $timezone = null) + public static function optional(string|null $datetime = null, ?DateTimeZone $timezone = null) { if (empty($datetime) === true) { return null; @@ -313,7 +314,7 @@ class Date extends DateTime try { return new static($datetime, $timezone); - } catch (Exception $e) { + } catch (Exception) { return null; } } @@ -368,7 +369,7 @@ class Date extends DateTime * @param int|array|null $step array of `unit` and `size` to round to nearest * @return int|null */ - public static function roundedTimestamp(?string $date = null, $step = null): ?int + public static function roundedTimestamp(string|null $date = null, $step = null): int|null { if ($date = static::optional($date)) { if ($step !== null) { @@ -391,7 +392,7 @@ class Date extends DateTime * @param int|null $second * @return int */ - public function second(?int $second = null): int + public function second(int|null $second = null): int { if ($second === null) { return (int)$this->format('s'); @@ -421,7 +422,7 @@ class Date extends DateTime * @param array|null $default Default values to use if one or both values are not provided * @return array */ - public static function stepConfig($input = null, ?array $default = null): array + public static function stepConfig($input = null, array|null $default = null): array { $default ??= [ 'size' => 1, @@ -502,19 +503,12 @@ class Date extends DateTime */ public function toString(string $mode = 'datetime', bool $timezone = true): string { - switch ($mode) { - case 'date': - $format = 'Y-m-d'; - break; - case 'time': - $format = 'H:i:s'; - break; - case 'datetime': - $format = 'Y-m-d H:i:s'; - break; - default: - throw new InvalidArgumentException('Invalid mode'); - } + $format = match ($mode) { + 'date' => 'Y-m-d', + 'time' => 'H:i:s', + 'datetime' => 'Y-m-d H:i:s', + default => throw new InvalidArgumentException('Invalid mode') + }; if ($timezone === true) { $format .= 'P'; @@ -529,7 +523,7 @@ class Date extends DateTime * @param int|null $year * @return int */ - public function year(?int $year = null): int + public function year(int|null $year = null): int { if ($year === null) { return (int)$this->format('Y'); diff --git a/kirby/src/Toolkit/Dom.php b/kirby/src/Toolkit/Dom.php index 8f88c0b..fec17f2 100644 --- a/kirby/src/Toolkit/Dom.php +++ b/kirby/src/Toolkit/Dom.php @@ -9,6 +9,7 @@ use DOMDocumentType; use DOMElement; use DOMNode; use DOMProcessingInstruction; +use DOMText; use DOMXPath; use Kirby\Cms\App; use Kirby\Exception\Exception; @@ -68,12 +69,6 @@ class Dom $this->doc = new DOMDocument(); $loaderSetting = null; - if (\PHP_VERSION_ID < 80000) { - // prevent loading external entities to protect against XXE attacks; - // only needed for PHP versions before 8.0 (the function was deprecated - // as the disabled state is the new default in PHP 8.0+) - $loaderSetting = libxml_disable_entity_loader(true); - } // switch to "user error handling" $intErrorsSetting = libxml_use_internal_errors(true); @@ -106,12 +101,6 @@ class Dom $load = $this->doc->loadXML($code); } - if (\PHP_VERSION_ID < 80000) { - // ensure that we don't alter global state by - // resetting the original value - libxml_disable_entity_loader($loaderSetting); - } - // get one error for use below and reset the global state $error = libxml_get_last_error(); libxml_clear_errors(); @@ -442,7 +431,7 @@ class Dom * @param \Closure|null Comparison callback that returns whether the expected and real name match * @return string|false Matched name in the list or `false` */ - public static function listContainsName(array $list, DOMNode $node, array $options, ?Closure $compare = null) + public static function listContainsName(array $list, DOMNode $node, array $options, Closure|null $compare = null) { $allowedNamespaces = $options['allowedNamespaces']; $localName = $node->localName; @@ -589,7 +578,7 @@ class Dom // convert the `DOMNodeList` to an array first, otherwise removing // nodes would shift the list and make subsequent operations fail foreach (iterator_to_array($this->doc->childNodes, false) as $child) { - if (is_a($child, 'DOMDocumentType') === true) { + if ($child instanceof DOMDocumentType) { $this->sanitizeDoctype($child, $options, $errors); } } @@ -646,7 +635,7 @@ class Dom foreach ($node->childNodes as $childNode) { // discard text nodes as they can be unexpected // directly in the parent element - if (is_a($childNode, 'DOMText') === true) { + if ($childNode instanceof DOMText) { continue; } diff --git a/kirby/src/Toolkit/Html.php b/kirby/src/Toolkit/Html.php index c8c30d7..5050958 100644 --- a/kirby/src/Toolkit/Html.php +++ b/kirby/src/Toolkit/Html.php @@ -137,7 +137,7 @@ class Html extends Xml * @param string|null $after An optional string that will be appended if the result is not empty * @return string|null The generated HTML attributes string */ - public static function attr($name, $value = null, ?string $before = null, ?string $after = null): ?string + public static function attr($name, $value = null, string|null $before = null, string|null $after = null): string|null { // HTML supports boolean attributes without values if (is_array($name) === false && is_bool($value) === true) { @@ -219,7 +219,7 @@ class Html extends Xml * * @psalm-suppress ParamNameMismatch */ - public static function encode(?string $string, bool $keepTags = false): string + public static function encode(string|null $string, bool $keepTags = false): string { if ($string === null) { return ''; @@ -279,12 +279,12 @@ class Html extends Xml * @param array $attr Additional attributes for the `