├── public
├── index.html
├── css
│ ├── index.html
│ ├── koot
│ │ ├── _koot.css
│ │ ├── paginator.css
│ │ ├── flash.css
│ │ ├── logo.css
│ │ ├── scaffold.css
│ │ ├── icons.css
│ │ └── admin.css
│ ├── koot.scss
│ ├── kumbia
│ │ ├── paginator.css
│ │ ├── flash.css
│ │ ├── scaffold.css
│ │ ├── icons.css
│ │ └── kumbia.css
│ ├── kumbia.min.css
│ └── koot.min.css
├── files
│ ├── index.html
│ └── upload
│ │ └── index.html
├── img
│ ├── index.html
│ ├── upload
│ │ └── index.html
│ ├── logo.png
│ ├── login.jpg
│ ├── datepicker
│ │ ├── cal.gif
│ │ ├── bullet1.gif
│ │ ├── bullet2.gif
│ │ ├── cal-grey.gif
│ │ ├── bg_header.jpg
│ │ ├── backstripes.gif
│ │ └── gradient-e5e5e5-ffffff.gif
│ ├── welcome
│ │ ├── user_management.avif
│ │ ├── user_management.png
│ │ ├── permission_handling.avif
│ │ ├── permission_handling.png
│ │ ├── resource_management.avif
│ │ ├── resource_management.png
│ │ ├── role_based_access_control.avif
│ │ └── role_based_access_control.png
│ ├── kumbia.svg
│ ├── icons
│ │ ├── edit.svg
│ │ └── delete.svg
│ ├── php7.svg
│ ├── koot.svg
│ └── kumbiaphp.svg
├── temp
│ └── index.html
├── javascript
│ ├── index.html
│ └── jquery
│ │ ├── jquery.kumbiaphp.min.js
│ │ └── jquery.kumbiaphp.js
├── js
│ ├── app.js
│ └── minimal-theme-switcher.js
├── robots.txt
├── favicon.ico
├── .htaccess
├── web.config
├── .user.ini
└── index.php
├── koot
├── temp
│ ├── cache
│ │ └── empty
│ ├── logs
│ │ └── empty
│ └── sqlite
│ │ └── ku_admin.db
├── .htaccess
├── extensions
│ ├── console
│ │ └── empty
│ ├── filters
│ │ └── empty
│ ├── helpers
│ │ └── empty
│ └── scaffolds
│ │ └── empty
├── bin
│ ├── phpserver
│ └── metrics
├── models
│ ├── permissions.php
│ ├── users_roles.php
│ ├── users.php
│ ├── resources.php
│ └── roles.php
├── config
│ ├── mysql
│ │ ├── ku_admin.mwb
│ │ └── ku_admin.sql
│ ├── exception.php
│ ├── databases.php
│ ├── routes.php
│ └── config.php
├── locale
│ └── es_ES
│ │ └── LC_MESSAGES
│ │ ├── default.mo
│ │ └── default.po
├── views
│ ├── _shared
│ │ ├── templates
│ │ │ ├── json.phtml
│ │ │ ├── csv.phtml
│ │ │ ├── xml.phtml
│ │ │ ├── default.phtml
│ │ │ ├── admin.phtml
│ │ │ └── login
│ │ │ │ └── login.phtml
│ │ ├── partials
│ │ │ ├── kumbia
│ │ │ │ └── footer.phtml
│ │ │ └── paginators
│ │ │ │ ├── classic.phtml
│ │ │ │ └── digg.phtml
│ │ ├── scaffolds
│ │ │ ├── kumbia
│ │ │ │ ├── crear.phtml
│ │ │ │ ├── ver.phtml
│ │ │ │ └── index.phtml
│ │ │ └── lite
│ │ │ │ ├── show.phtml
│ │ │ │ └── page.phtml
│ │ └── errors
│ │ │ └── 404.phtml
│ ├── admin
│ │ ├── roles
│ │ │ └── create.phtml
│ │ ├── users
│ │ │ └── create.phtml
│ │ └── resources
│ │ │ └── create.phtml
│ ├── index
│ │ └── index.phtml
│ └── pages
│ │ └── kumbia
│ │ └── status.phtml
├── controllers
│ ├── admin
│ │ ├── roles_controller.php
│ │ ├── users_controller.php
│ │ └── resources_controller.php
│ ├── index_controller.php
│ └── pages_controller.php
├── libs
│ ├── bootstrap.php
│ ├── pages_trait.php
│ ├── view.php
│ ├── active_record.php
│ ├── lite_record.php
│ ├── app_controller.php
│ ├── controller_rest.php
│ ├── controller_admin.php
│ ├── controller_scaffold.php
│ ├── controller_scaffold_lite.php
│ └── httpk.php
├── phpunit.xml.dist
└── tests
│ ├── bootstrap.php
│ ├── KumbiaTestTrait.php
│ └── Controller
│ └── PagesControllerTest.php
├── .gitignore
├── .github
└── FUNDING.yml
├── .travis.yml
├── README.md
├── composer.json
├── phpunit.xml.dist
└── LICENSE
/public/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/koot/temp/cache/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/koot/temp/logs/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/css/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/files/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/img/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/temp/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/img/upload/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/javascript/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/koot/.htaccess:
--------------------------------------------------------------------------------
1 | deny from all
2 |
--------------------------------------------------------------------------------
/koot/extensions/console/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/koot/extensions/filters/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/koot/extensions/helpers/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/koot/extensions/scaffolds/empty:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/files/upload/index.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/js/app.js:
--------------------------------------------------------------------------------
1 | // New KumbiaJS
2 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
3 |
--------------------------------------------------------------------------------
/koot/bin/phpserver:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | php -S 0.0.0.0:8001 -t ../public
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KumbiaPHP/Koot/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/public/img/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/KumbiaPHP/Koot/HEAD/public/img/logo.png
--------------------------------------------------------------------------------
/koot/models/permissions.php:
--------------------------------------------------------------------------------
1 | status = 1;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/koot/models/resources.php:
--------------------------------------------------------------------------------
1 | status = 1;
7 | }
8 | }
9 |
--------------------------------------------------------------------------------
/koot/controllers/admin/resources_controller.php:
--------------------------------------------------------------------------------
1 | []
7 | ];
8 |
--------------------------------------------------------------------------------
/public/css/koot/_koot.css:
--------------------------------------------------------------------------------
1 | /*! Koot 2024 */
2 | @import "pico.css";
3 | /* @import "admin.css"; */
4 | @import "flash.css";
5 | @import "icons.css";
6 | @import "logo.css";
7 | @import "paginator.css";
8 |
--------------------------------------------------------------------------------
/public/img/kumbia.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/koot/models/roles.php:
--------------------------------------------------------------------------------
1 | 'Super Admin',
7 | 2 => 'Editor',
8 | 3 => 'Author'
9 | ];
10 | }
11 |
--------------------------------------------------------------------------------
/koot/libs/bootstrap.php:
--------------------------------------------------------------------------------
1 |
2 | © 2020 - = date('Y'); ?> Koot Team
3 |
= 'Executed in ', round((microtime(1) - $_SERVER['REQUEST_TIME_FLOAT']) * 1000, 4), ' ms. using ', number_format(memory_get_usage() / 1048576, 3), ' MB memory'; ?>
4 |
--------------------------------------------------------------------------------
/public/img/icons/edit.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/css/koot.scss:
--------------------------------------------------------------------------------
1 | // Import Flash
2 | @import "koot/flash";
3 |
4 | // Import Icons
5 | @import "koot/icons";
6 |
7 | // Import Admin
8 | @import "koot/admin";
9 |
10 | // Import Paginator
11 | @import "koot/paginator";
12 |
13 | // Import Pico
14 | @import "koot/pico";
15 |
16 | // Import Scaffold
17 | @import "koot/scaffold";
18 |
19 | // Import Logo
20 | @import "koot/logo";
--------------------------------------------------------------------------------
/koot/libs/active_record.php:
--------------------------------------------------------------------------------
1 |
2 | = ucwords("$model") ?> = _('Create') ?>
3 |
4 | = Form::open() ?>
5 |
8 |
9 | = Form::submit(_('Save')) ?>
10 | = Form::close() ?>
11 |
12 |
--------------------------------------------------------------------------------
/koot/views/_shared/scaffolds/kumbia/crear.phtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
= ucwords("$model"), ": $action_name" ?>
4 |
5 |
6 |
7 |
8 |
9 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/public/img/icons/delete.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/css/kumbia/paginator.css:
--------------------------------------------------------------------------------
1 | .paginator .nextprev {
2 | color: #000;
3 | }
4 |
5 | .paginator a {
6 | border: 1px solid #e8ebf1;
7 | padding: .5em;
8 | text-decoration: none;
9 | margin: .5em .1em;
10 | background: #FFF;
11 | }
12 |
13 | .paginator a:hover {
14 | background: #e8ebf1;
15 | }
16 |
17 | .paginator strong {
18 | background: #e8ebf1;
19 | border: 1px solid #e8ebf1;
20 | padding: .5em;
21 | margin: .5em .1em;
22 | }
--------------------------------------------------------------------------------
/koot/views/_shared/templates/csv.phtml:
--------------------------------------------------------------------------------
1 | getFields());
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/public/css/koot/flash.css:
--------------------------------------------------------------------------------
1 | /* Formatea los mensajes Flash::xxx() de KumbiaPHP */
2 |
3 | .flash {
4 | margin: 5px 0;
5 | min-height: 32px;
6 | padding: 3px 10px 3px 50px;
7 | background-repeat: no-repeat;
8 | background-position: 10px center;
9 | line-height: 32px;
10 | border-radius: 2px;
11 | }
12 |
13 | .error {
14 | color: #D8000C;
15 | background-color: #FFBABA;
16 | }
17 |
18 | .info {
19 | color: #00529B;
20 | background-color: #BDE5F8;
21 | }
22 |
23 | .valid {
24 | color: #4F8A10;
25 | background-color: #DFF2BF;
26 | }
27 |
28 | .warning {
29 | color: #9F6000;
30 | background-color: #FEEFB3;
31 | }
--------------------------------------------------------------------------------
/public/css/kumbia/flash.css:
--------------------------------------------------------------------------------
1 | /* Formatea los mensajes Flash::xxx() de KumbiaPHP */
2 |
3 | .flash {
4 | margin: 5px 0;
5 | min-height: 32px;
6 | padding: 3px 10px 3px 50px;
7 | background-repeat: no-repeat;
8 | background-position: 10px center;
9 | line-height: 32px;
10 | border-radius: 2px;
11 | }
12 |
13 | .error {
14 | color: #D8000C;
15 | background-color: #FFBABA;
16 | }
17 |
18 | .info {
19 | color: #00529B;
20 | background-color: #BDE5F8;
21 | }
22 |
23 | .valid {
24 | color: #4F8A10;
25 | background-color: #DFF2BF;
26 | }
27 |
28 | .warning {
29 | color: #9F6000;
30 | background-color: #FEEFB3;
31 | }
--------------------------------------------------------------------------------
/koot/libs/app_controller.php:
--------------------------------------------------------------------------------
1 |
2 | = _('Users') ?> = _('Create') ?>
3 |
4 | = Form::open() ?>
5 |
6 |
9 |
10 |
13 |
14 |
17 |
18 | = Form::submit(_('Save')) ?>
19 | = Form::close() ?>
20 |
21 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
4 | patreon: # Replace with a single Patreon username
5 | open_collective: kumbiaphp
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
--------------------------------------------------------------------------------
/public/.htaccess:
--------------------------------------------------------------------------------
1 | DirectoryIndex index.php
2 | # Si esta mod_rewrite habilitado
3 |
4 | # Activar modo de reescritura
5 | RewriteEngine On
6 |
7 | # Directorio de instalacion, puede ser necesario si
8 | # la aplicacion se ubica en public_html
9 | #RewriteBase /
10 |
11 | # No permite reescritura si el archivo o directorio existe
12 | RewriteCond %{REQUEST_FILENAME} !-f
13 | RewriteCond %{REQUEST_FILENAME} !-d
14 |
15 | # Para peticiones que no son archivos ni directorios
16 | # Reescribe a index.php/
17 | RewriteRule (.*) index.php/$1 [L]
18 |
19 | # Reescribe a index.php?_url=URL
20 | #RewriteRule ^(.*)$ index.php?_url=/$1 [QSA,L]
21 |
22 |
--------------------------------------------------------------------------------
/public/img/php7.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/koot/bin/metrics:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | PATH=./vendor/bin:../../vendor/bin:~/.config/composer/vendor/bin:~/.composer/vendor/bin:$PATH
4 |
5 | phpmetrics --report-html="./temp/metrics" --exclude="tests,temp,features" .
6 |
7 | if [[ $? > 0 ]]; then
8 | #do log_error;
9 | echo
10 | echo phpmetrics not installed. Install with:
11 | echo composer global require phpmetrics/phpmetrics
12 | echo
13 | exit 1;
14 | fi
15 |
16 | echo
17 | echo Control+click to open:
18 | echo file://$PWD/temp/metrics/index.html
19 | echo
20 | # If you want open it in browser directly
21 | # xdg-open file://$PWD/temp/metrics/index.html
22 | # in Mac
23 | # open file://$PWD/temp/metrics/index.html
24 |
25 | # composer global require 'phpmetrics/phpmetrics'
--------------------------------------------------------------------------------
/public/css/koot/logo.css:
--------------------------------------------------------------------------------
1 | /* Dark color scheme (Auto) */
2 | /* Automatically enabled if user has Dark mode enabled */
3 | @media only screen and (prefers-color-scheme: dark) {
4 | :root:not([data-theme]) {
5 | --koot-logo-wordmark: #bdecee;
6 | }
7 | }
8 |
9 | /* Can be forced with data-theme="light" */
10 | [data-theme="light"],
11 | :root:not([data-theme="dark"]) {
12 | --koot-logo-wordmark: #002741;
13 | }
14 |
15 | [data-theme="dark"],
16 | :root:not([data-theme="light"]) {
17 | --koot-logo-wordmark: #bdecee;
18 | }
19 |
20 | svg.logo {
21 | width: 5rem;
22 | height: auto;
23 | margin: -.5rem;
24 | }
25 |
26 | @media (min-width: 576px) {
27 | svg.logo {
28 | width: 10rem;
29 | margin: -1rem;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/public/css/kumbia/scaffold.css:
--------------------------------------------------------------------------------
1 | #scaffold table a {
2 | color: #333;
3 | font-weight: normal;
4 | }
5 |
6 | #scaffold table a:hover {
7 | color: #0ac;
8 | text-decoration: none;
9 | }
10 |
11 | #scaffold table {
12 | width: 100%
13 | }
14 |
15 | #scaffold th {
16 | text-align: left;
17 | }
18 |
19 | #scaffold caption {
20 | font-size: 2em;
21 | text-align: left;
22 | }
23 |
24 | #scaffold .show {
25 | list-style: none;
26 | padding: 1em
27 | }
28 |
29 | #scaffold .show strong {
30 | width: 30%;
31 | display: inline-block;
32 | }
33 |
34 | #scaffold .show li {
35 | padding: 8px;
36 | line-height: 1.5;
37 | border-top: 1px solid #ddd;
38 | }
39 |
40 | #scaffold .show li:hover {
41 | background-color: #f5f5f5
42 | }
43 |
--------------------------------------------------------------------------------
/public/css/koot/scaffold.css:
--------------------------------------------------------------------------------
1 | /* #scaffold table a {
2 | color: #333;
3 | font-weight: normal;
4 | }
5 |
6 | #scaffold table a:hover {
7 | color: #0ac;
8 | text-decoration: none;
9 | } */
10 |
11 | #scaffold table {
12 | width: 100%
13 | }
14 |
15 | #scaffold th {
16 | text-align: left;
17 | }
18 |
19 | #scaffold caption {
20 | font-size: 2em;
21 | text-align: left;
22 | }
23 |
24 | #scaffold .show {
25 | list-style: none;
26 | padding: 1em
27 | }
28 |
29 | #scaffold .show strong {
30 | width: 30%;
31 | display: inline-block;
32 | }
33 |
34 | #scaffold .show li {
35 | padding: 8px;
36 | line-height: 1.5;
37 | border-top: 1px solid #ddd;
38 | }
39 |
40 | #scaffold .show li:hover {
41 | background-color: #f5f5f5
42 | }
43 |
--------------------------------------------------------------------------------
/koot/config/databases.php:
--------------------------------------------------------------------------------
1 | [
8 | 'dsn' => 'mysql:host=127.0.0.1;dbname=ku_admin;charset=utf8',
9 | 'username' => 'root',
10 | 'password' => '',
11 | 'params' => [
12 | //PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8', //UTF8 en PHP < 5.3.6
13 | \PDO::ATTR_PERSISTENT => \true, //conexión persistente
14 | \PDO::ATTR_ERRMODE => \PDO::ERRMODE_EXCEPTION
15 | ]
16 | ]
17 | ];*/
18 |
19 | /**
20 | * Ejemplo de SQLite
21 | */
22 | return ['default' => [
23 | 'dsn' => 'sqlite:'.APP_PATH.'temp/sqlite/ku_admin.db',
24 | 'pdo' => 'On',
25 | ]
26 | ];
27 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: php
2 | dist: bionic
3 |
4 | php:
5 | - 7.4
6 | - 8.0
7 | - master
8 |
9 | matrix:
10 | allow_failures:
11 | - php: master
12 | # 7.2 and 7.3 for the Mockery class
13 |
14 | notifications:
15 | slack: kumbiaphp:51JaKQTXASwf52D8b32OyWb9
16 | # irc: "irc.freenode.org#kumbiaphp"
17 | # email:
18 | # - xxxxx@gmail.com
19 |
20 |
21 | # env:
22 | # - DB=mysql
23 | # - DB=pgsql
24 | # - DB=sqlite
25 |
26 | install:
27 | - composer install
28 |
29 | script:
30 | - vendor/bin/phpunit --configuration phpunit.xml.dist
31 | # - phpunit --configuration core/phpunit.xml.dist --coverage-text --colors --coverage-clover=coverage.clover
32 | # - wget https://scrutinizer-ci.com/ocular.phar
33 | # - php ocular.phar code-coverage:upload --format=php-clover coverage.clover
--------------------------------------------------------------------------------
/public/css/koot/icons.css:
--------------------------------------------------------------------------------
1 | /* Using https://feathericons.com/ */
2 | .icon {
3 | filter: invert(0.5);
4 | }
5 |
6 | .icon:hover {
7 | filter: none
8 | }
9 |
10 | /* .actions .icon {
11 | border: 1px solid gray;
12 | padding: .5em;
13 | border-radius: 6px;
14 | } */
15 | /* .delete {
16 |
17 | }
18 |
19 | .edit {
20 | /* background-image: url("data:image/svg+xml;utf8,")
21 | background-image: url(/img/edit.svg);
22 | } */
--------------------------------------------------------------------------------
/public/css/kumbia/icons.css:
--------------------------------------------------------------------------------
1 | /* Using https://feathericons.com/ */
2 | .icon {
3 | filter: invert(0.5);
4 | }
5 |
6 | .icon:hover {
7 | filter: none
8 | }
9 |
10 | /* .actions .icon {
11 | border: 1px solid gray;
12 | padding: .5em;
13 | border-radius: 6px;
14 | } */
15 | /* .delete {
16 |
17 | }
18 |
19 | .edit {
20 | /* background-image: url("data:image/svg+xml;utf8,")
21 | background-image: url(/img/edit.svg);
22 | } */
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | ## Koot
4 |
5 | Community backend to avoid repeating ourselves in new applications.
6 |
7 | ### Requirements
8 |
9 | * PHP >= 8.0
10 | * Composer
11 | * Multi language
12 |
13 | ### Install
14 |
15 | 1. Clone or download this repository
16 | 2. Rename folder to `koot`
17 | 3. Open the console and enter the `koot/` folder
18 | 4. Run command `composer install` to get the dependencies
19 |
20 | ### Run
21 |
22 | 1. Open the console and enter the `koot/app/` folder
23 | 2. Run command `bin/phpserver`
24 | 3. Open http://0.0.0.0:8001 in your browser
25 |
26 | ### Support us
27 |
28 | [Donate our collective](https://opencollective.com/kumbiaphp)
29 |
30 | Chat with us
31 |
32 |
--------------------------------------------------------------------------------
/public/css/koot/admin.css:
--------------------------------------------------------------------------------
1 | @media (min-width: 992px) {
2 | #develop {
3 | --block-spacing-horizontal: calc(var(--spacing) * 1.75);
4 | grid-column-gap: calc(var(--block-spacing-horizontal));
5 | display: grid;
6 | grid-template-columns:200px auto;
7 | height: 100vh;
8 | padding: 0
9 | }
10 |
11 | #develop > aside {
12 | border-right: 1px solid var(--muted-border-color)
13 | }
14 |
15 | #doc > nav {
16 | border-bottom: 1px solid var(--muted-border-color)
17 | }
18 |
19 | #menu {
20 | background-color: var();
21 | }
22 |
23 | .settings {
24 | text-decoration: none;
25 | position: absolute;
26 | bottom: 0;
27 | padding-bottom: 1em;
28 | width: 200px;
29 | border-top: 1px solid solid var(--muted-border-color)
30 | }
31 | }
--------------------------------------------------------------------------------
/public/web.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/koot/libs/controller_rest.php:
--------------------------------------------------------------------------------
1 | 'controlador2/accion2/valor_id2'
11 | *
12 | * Ej:
13 | * Enrutar cualquier petición a posts/adicionar a posts/insertar/*
14 | * '/posts/adicionar/*' => 'posts/insertar/*'
15 | *
16 | * Otros ejemplos:
17 | *
18 | * '/prueba/ruta1/*' => 'prueba/ruta2/*',
19 | * '/prueba/ruta2/*' => 'prueba/ruta3/*',
20 | */
21 | return [
22 | 'routes' => [
23 | /**
24 | * Muestra la info relacionado con el framework
25 | */
26 | '/' => 'index/index',
27 | /**
28 | * Status del config.php/config.ini
29 | */
30 | '/status' => 'pages/kumbia/status'
31 |
32 | ],
33 | ];
34 |
--------------------------------------------------------------------------------
/koot/views/_shared/scaffolds/kumbia/ver.phtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
= ucwords("$model"),": $action_name" ?>
5 |
6 | fields as $field) : ?>
7 | - = $data->alias[$field]?> : = h($data->$field) ?>
8 |
9 |
10 |
11 |
17 |
18 |
19 |
No existe
20 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/koot/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | ./tests
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 | ./tests
27 | ../../core
28 | ../../vendor
29 |
30 |
31 |
--------------------------------------------------------------------------------
/koot/libs/controller_admin.php:
--------------------------------------------------------------------------------
1 |
2 | = ucwords("$model") ?> = _('Create') ?>
3 |
4 |
5 | = Form::open(); ?>
6 |
7 | = Form::text('data.name', 'required') ?>
8 |
9 | = Form::text('data.description') ?>
10 |
11 | = Form::text('data.module') ?>
12 |
13 | = Form::text('data.controller', 'required') ?>
14 |
15 | = Form::text('data.action', 'required') ?>
16 |
17 | = Form::text('data.url', 'required') ?>
18 | = Form::submit(_('Save'), 'class="btn btn-primary"') ?>
19 | = Form::close(); ?>
20 |
21 |
22 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "kumbia/koot",
3 | "description": "KumbiaPHP admin",
4 | "keywords": [
5 | "KumbiaPHP",
6 | "admin"
7 | ],
8 | "type": "project",
9 | "homepage": "https://kumbiaphp.com",
10 | "license": "BSD-3-Clause",
11 | "support": {
12 | "issues": "https://github.com/KumbiaPHP/Koot/issues",
13 | "slack": "https://slack.kumbiaphp.com"
14 | },
15 | "authors": [
16 | {
17 | "name": "Kumbia Community",
18 | "homepage": "https://github.com/KumbiaPHP/Koot/graphs/contributors"
19 | }
20 | ],
21 | "require": {
22 | "php": ">=8.0",
23 | "ext-pdo": "*",
24 | "ext-json": "*",
25 | "ext-curl": "*",
26 | "ext-gettext": "*",
27 | "kumbia/framework": "^1",
28 | "kumbia/activerecord": "^0.5"
29 | },
30 | "require-dev": {
31 | "phpunit/phpunit": "^9"
32 | },
33 | "autoload": {
34 | "psr-4": {
35 | "Koot\\": "koot/"
36 | }
37 | },
38 | "config": {
39 | "optimize-autoloader": true,
40 | "sort-packages": true
41 | },
42 | "funding": [
43 | {
44 | "type": "Open Collective",
45 | "url": "https://opencollective.com/kumbiaphp"
46 | }
47 | ]
48 | }
49 |
--------------------------------------------------------------------------------
/koot/views/_shared/scaffolds/kumbia/index.phtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
= ucwords("$model"), ": $action_name" ?>
4 |
5 | = Html::linkAction("crear/", 'Crear registro', 'class="btn btn-primary"')?>
6 |
7 | items) && (count($data->items) > 0)) : ?>
8 |
9 |
10 | items)->fields as $field) : ?>
11 | | = (current($data->items)->get_alias($field))?> |
12 |
13 | Acciones |
14 |
15 |
16 | items as $item) : ?>
17 |
18 | fields as $field) : ?>
19 | | = h($item->$field)?> |
20 |
21 | = Html::linkAction("ver/$item->id", 'Ver')?> |
22 | = Html::linkAction("editar/$item->id", 'Editar')?> |
23 | = Html::linkAction("borrar/$item->id", 'Borrar', 'onclick="return confirm(\'¿Está seguro?\')"') ?>
24 | |
25 |
26 |
27 |
28 |
29 | $data ,'url' => Router::get('controller_path').'/index')) ?>
30 |
31 |
32 |
No hay ningún registro
33 |
34 |
35 |
--------------------------------------------------------------------------------
/koot/views/_shared/scaffolds/lite/show.phtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
_('Record not found')
6 |
10 |
11 | = ucwords("$model") ?> = _('Show') ?>
12 |
13 | getFields() as $key => $field) : ?>
14 | - = $data->getAlias()[$key] ?> = h($data->$field) ?>
15 |
16 |
17 |
18 |
24 |
25 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
11 |
12 |
13 | .
14 |
15 |
16 | app/tests
17 | app/temp
18 | vendor
19 | app/config
20 |
21 |
22 |
23 |
24 | app/tests/
25 |
26 |
27 |
28 |
30 |
31 |
32 |
33 |
34 |
37 |
38 |
--------------------------------------------------------------------------------
/koot/controllers/pages_controller.php:
--------------------------------------------------------------------------------
1 |
26 | * Muestra un enlace que al hacer click irá a dominio.com/pages/aviso
27 | *
28 | */
29 | class PagesController extends AppController
30 | {
31 | protected function before_filter()
32 | {
33 | // If is AJAX, send only the view
34 | if (Input::isAjax()) {
35 | View::template(null);
36 | }
37 | }
38 |
39 | public function __call($name, $params)
40 | {
41 | View::select(implode('/', [$name, ...$params]));
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/koot/config/config.php:
--------------------------------------------------------------------------------
1 | [
8 | /**
9 | * name: es el nombre de la aplicacion
10 | */
11 | 'name' => 'KuAdmin',
12 | /**
13 | * database: base de datos a utilizar
14 | */
15 | 'database' => 'development',
16 | /**
17 | * dbdate: formato de fecha por defecto de la aplicacion
18 | */
19 | 'dbdate' => 'YYYY-MM-DD',
20 | /**
21 | * debug: muestra los errores en pantalla (On/off)
22 | */
23 | 'debug' => 'On',
24 | /**
25 | * log_exceptions: muestra las excepciones en pantalla (On/off)
26 | */
27 | 'log_exceptions' => 'On',
28 | /**
29 | * cache_template: descomentar para habilitar cache de template
30 | */
31 | //'cache_template' => 'On',
32 | /**
33 | * cache_driver: driver para la cache (file, sqlite, memsqlite)
34 | */
35 | 'cache_driver' => 'file',
36 | /**
37 | * metadata_lifetime: tiempo de vida de la metadata en cache
38 | */
39 | 'metadata_lifetime' => '+1 year',
40 | /**
41 | * namespace_auth: espacio de nombres por defecto para Auth
42 | */
43 | 'namespace_auth' => 'default',
44 | /**
45 | * routes: descomentar para activar routes en routes.php
46 | */
47 | //'routes' => '1',
48 | ],
49 | ];
50 |
--------------------------------------------------------------------------------
/koot/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 | assertSame(
29 | $code,
30 | $actual,
31 | "Status code is not $code but $actual."
32 | );
33 | }
34 | /**
35 | * Request to Controller
36 | *
37 | * @param string $method HTTP method
38 | * @param string $url controller/method/arg|uri
39 | * @param array $params POST parameters/Query string
40 | */
41 | protected function request($method, $url, $params = [])
42 | {
43 | $_SERVER['REQUEST_METHOD'] = $method;
44 |
45 | ob_start();
46 | $start_ob_level = ob_get_level();
47 | ob_start();
48 | View::render(Router::execute($url));
49 | while (ob_get_level() > $start_ob_level) {
50 | ob_end_flush();
51 | }
52 |
53 | //$content = $this->getActualOutput();
54 | return ob_get_clean();
55 | }
56 | /**
57 | * GET Request to Controller
58 | *
59 | * @param string $url controller/method/arg|uri
60 | * @param array $params Query string
61 | */
62 | public function get($url, $params = [])
63 | {
64 | return $this->request('GET', $url, $params);
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/koot/views/_shared/errors/404.phtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | ERROR 404
6 |
7 |
8 |
40 |
41 |
42 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/koot/tests/Controller/PagesControllerTest.php:
--------------------------------------------------------------------------------
1 | get('/pages/kumbia/status/');
31 | $this->assertStringContainsString('config.php', $actual);
32 | $this->assertResponseCode(200);
33 | }
34 | /**
35 | * Test no page to show
36 | */
37 | public function testDisplayNoPage(): void
38 | {
39 | $this->expectWarning();
40 | $this->expectWarningMessageMatches('/No such file or directory/');
41 |
42 | $actual = $this->get('/pages/no_page/');
43 |
44 | $this->expectException(KumbiaException::class);
45 | $this->assertResponseCode(404);
46 | $this->assertStringContainsString('Vista "pages/no_page.phtml" no encontrada
', $actual);
47 | }
48 |
49 | /**
50 | * Test for bad people
51 | */
52 | public function testBadPeople(): void
53 | {
54 | $this->expectException(KumbiaException::class);
55 | $actual = $this->get('/pages/../no_page/');
56 |
57 | $this->assertResponseCode(404);
58 | $this->assertStringContainsString("Posible intento de hack en URL: '/pages/../no_page/'", $actual);
59 | }
60 |
61 | public function testObLevel(): void
62 | {
63 | $this->assertEquals(1, ob_get_level());
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/koot/views/_shared/templates/xml.phtml:
--------------------------------------------------------------------------------
1 | $value) {
9 | if (is_numeric($key)) {
10 | $key = $nodeName;
11 | }
12 | $xml .= '<' . $key . '>' . "\n" . generate_xml_from_array($value, $nodeName) . '' . $key . '>' . "\n";
13 | }
14 | } else {
15 | $xml = htmlspecialchars($array, ENT_QUOTES) . "\n";
16 | }
17 | return $xml;
18 | }
19 |
20 | function generate_valid_xml_from_array($array, $nodeBlock = 'nodes', $nodeName = 'node')
21 | {
22 | $xml = '' . "\n";
23 | $xml .= '<' . $nodeBlock . '>' . "\n";
24 | $xml .= generate_xml_from_array($array, $nodeName);
25 | $xml .= '' . $nodeBlock . '>' . "\n";
26 | return $xml;
27 | }
28 |
29 | //First element
30 | $first = is_array($data) ? $data[key($data)] : $data;
31 | $block = $first == $data && is_object($first) ? strtolower(get_class($first)) : 'data';
32 | $node = is_object($first) ? strtolower(get_class($first)) : 'node';
33 |
34 | echo generate_valid_xml_from_array($data, $block, $node);
35 | /*
36 | TODO use Simple XML
37 | function printElem($xml, $elem){
38 | $xml->startElement();
39 | $a = get_object_vars($elem);
40 | foreach($a as $key=>$value) {
41 | $xml->startElement($key);
42 | $xml->text($value);
43 | $xml->endElement();
44 | }
45 | $xml->endElement();
46 | }
47 |
48 | $xml=new XMLWriter();
49 | $xml->openMemory();
50 | $xml->startDocument('1.0','UTF-8');
51 | $xml->startElement('xml');
52 | $xml->setIndent(true);
53 |
54 | if(is_array($data)){
55 | foreach($data as $elem) {
56 | printElem($xml, $elem);
57 | }
58 | }else{
59 | printElem($xml, $data);
60 | }
61 |
62 | $xml->endElement();
63 | echo $xml->outputMemory(true);
64 | */
65 |
--------------------------------------------------------------------------------
/public/js/minimal-theme-switcher.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * Minimal theme switcher
3 | *
4 | * Pico.css - https://picocss.com
5 | * Copyright 2019-2023 - Licensed under MIT
6 | * Copyright 2024 Updated for Koot
7 | */
8 |
9 | const themeSwitcher = {
10 | // Config
11 | buttonsTarget: ".theme-switcher",
12 | rootAttribute: "data-theme",
13 | localStorageKey: "kootPreferredColorScheme",
14 |
15 | // Init
16 | init() {
17 | this.scheme = this.schemeFromLocalStorage ?? this.preferredColorScheme
18 | this.initSwitchers()
19 | },
20 |
21 | // Get color scheme from local storage
22 | get schemeFromLocalStorage() {
23 | return window.localStorage?.getItem(this.localStorageKey)
24 | },
25 |
26 | // Preferred color scheme
27 | get preferredColorScheme() {
28 | return window.matchMedia?.("(prefers-color-scheme: dark)").matches ? "dark" : "light";
29 | },
30 |
31 | // Init switchers
32 | initSwitchers() {
33 | const buttons = document.querySelectorAll(this.buttonsTarget)
34 | buttons.forEach((button) => {
35 | button.addEventListener(
36 | "click",
37 | (event) => {
38 | event.preventDefault()
39 | // Set scheme
40 | this.toogleScheme()
41 | },
42 | false
43 | )
44 | })
45 | },
46 |
47 | // Set scheme
48 | set scheme(scheme) {
49 | if (! scheme in ["dark", "light"]) {
50 | return
51 | }
52 | this._scheme = scheme
53 | this.applyScheme()
54 | this.schemeToLocalStorage()
55 | },
56 |
57 | // Get scheme
58 | get scheme() {
59 | return this._scheme
60 | },
61 |
62 | toogleScheme() {
63 | this.scheme = "dark" == this.scheme ? "light" : "dark"
64 | },
65 | // Apply scheme
66 | applyScheme() {
67 | document.querySelector("html").setAttribute(this.rootAttribute, this.scheme)
68 | },
69 |
70 | // Store scheme to local storage
71 | schemeToLocalStorage() {
72 | window.localStorage?.setItem(this.localStorageKey, this.scheme)
73 | },
74 | }
75 |
76 | // Init
77 | themeSwitcher.init()
78 |
--------------------------------------------------------------------------------
/koot/views/_shared/scaffolds/lite/page.phtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
= ucwords("$model") ?> = _('List') ?>
4 |
5 | = Html::linkAction("create/", _('Create'), 'role="button"') ?>
6 |
7 |
8 |
= _('No records') ?>
9 |
10 |
11 |
12 |
13 |
37 |
38 | $data]) ?>
39 |
40 |
--------------------------------------------------------------------------------
/koot/views/_shared/partials/paginators/classic.phtml:
--------------------------------------------------------------------------------
1 | totalPages();
31 | $prev = $page->prevPage();
32 | $next = $page->nextPage();
33 | $page = $page->page();
34 | // Calculando el inicio de paginador centrado
35 | if ($page <= $half) {
36 | $start = 1;
37 | } elseif (($pagetotal - $page) < $half) {
38 | $start = $pagetotal - $show + 1;
39 | if ($start < 1) {
40 | $start = 1;
41 | }
42 | } else {
43 | $start = $page - $half;
44 | }
45 |
46 | if ($pagetotal > 1) : ?>
47 |
66 |
67 | count(), ' items.' ?>
--------------------------------------------------------------------------------
/koot/views/index/index.phtml:
--------------------------------------------------------------------------------
1 |
2 | Welcome to Koot
3 | Koot is your go-to community backend solution, built on the robust and fast KumbiaPHP framework.
4 |
5 |
6 |
7 | Features
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
User Management
17 |
Handle user registrations, logins, and profiles efficiently.
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
Role-Based Access Control
27 |
Define roles and assign them to users for granular access control.
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
Resource Management
37 |
Manage your application's resources with ease.
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
Permission Handling
47 |
Fine-tune permissions for different user roles.
48 |
49 |
50 |
51 |
52 |
53 | About Koot
54 | Koot is designed to streamline backend development, minimizing repetitive tasks and focusing on unique features of your applications.
55 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/public/img/koot.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/koot/libs/controller_scaffold.php:
--------------------------------------------------------------------------------
1 | data = (new $this->model)->paginate("page: $page", 'order: id desc');
22 | }
23 |
24 | /**
25 | * Crea un Registro
26 | */
27 | public function crear()
28 | {
29 | if (Input::hasPost($this->model)) {
30 |
31 | $obj = new $this->model;
32 | //En caso que falle la operación de guardar
33 | if (!$obj->save(Input::post($this->model))) {
34 | Flash::error('Falló Operación');
35 | //se hacen persistente los datos en el formulario
36 | $this->{$this->model} = $obj;
37 | return;
38 | }
39 | return Redirect::to();
40 | }
41 | // Sólo es necesario para el autoForm
42 | $this->{$this->model} = new $this->model;
43 | }
44 |
45 | /**
46 | * Edita un Registro
47 | */
48 | public function editar($id)
49 | {
50 | View::select('crear');
51 |
52 | //se verifica si se ha enviado via POST los datos
53 | if (Input::hasPost($this->model)) {
54 | $obj = new $this->model;
55 | if (!$obj->update(Input::post($this->model))) {
56 | Flash::error('Falló Operación');
57 | //se hacen persistente los datos en el formulario
58 | $this->{$this->model} = Input::post($this->model);
59 | } else {
60 | return Redirect::to();
61 | }
62 | }
63 |
64 | //Aplicando la autocarga de objeto, para comenzar la edición
65 | $this->{$this->model} = (new $this->model)->find((int) $id);
66 | }
67 |
68 | /**
69 | * Borra un Registro
70 | */
71 | public function borrar($id)
72 | {
73 | if (!(new $this->model)->delete((int) $id)) {
74 | Flash::error('Falló Operación');
75 | }
76 | //enrutando al index para listar los articulos
77 | Redirect::to();
78 | }
79 |
80 | /**
81 | * Ver un Registro
82 | */
83 | public function ver($id)
84 | {
85 | $this->data = (new $this->model)->find_first((int) $id);
86 | }
87 | }
--------------------------------------------------------------------------------
/public/img/kumbiaphp.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/koot/views/pages/kumbia/status.phtml:
--------------------------------------------------------------------------------
1 |
2 | ';
6 | } else {
7 | echo strftime("%e de %B del %Y") , '
';
8 | }
9 |
10 |
11 | /**
12 | * Verificando permisos del dir temp/
13 | */
14 | if (!is_writable(APP_PATH.'temp')) {
15 | $tmp = "Debes darle permiso a: '".basename(APP_PATH)."/temp/'";
16 | } else {
17 | $tmp = 'Directorio temp... ok';
18 | }
19 |
20 | $status = PRODUCTION ? 'Production' : 'Development';
21 |
22 |
23 | /**
24 | * Configuracion del config.ini
25 | */
26 | $config = Config::read('config');
27 |
28 | if (isset($config['application']['cache_driver'])) {
29 | $cahe_driver = $config['application']['cache_driver'];
30 | } else {
31 | $cache_driver = 'No ha seleccionado un driver para la cache';
32 | }
33 |
34 | $locale = str_replace(';', '
', setlocale(LC_ALL, '0'));
35 |
36 | if (! $timezone = date_default_timezone_get()) {
37 | $timezone = 'No se ha especificado un Timezone.';
38 | }
39 | ?>
40 |
config.php de = basename(dirname(APP_PATH)) ?>
41 |
42 |
43 |
Directorio temp/:
44 |
= $tmp ?>
45 |
46 |
Estado Actual del Framework: = $status ?>
47 |
Ver Modos de ejecución
48 |
49 |
Base de Datos: = $config['application']['database'] ?>
50 |
Datos de la conexión a la BD que será utilizada, ver configuración databases.ini.
51 |
52 |
Cache Driver: = $cahe_driver ?>
53 |
Driver que se utilizará para realizar las operaciones de cache.
54 |
55 |
Charset: = APP_CHARSET ?>
56 |
Codificación de caracteres. Recomendado UTF-8
57 |
58 |
Valores del servidor
59 |
Como cambiar estos valores enlace TODO
60 |
61 |
TimeZone: = $timezone ?>
62 |
Zona horaria que usará la aplicación.
63 |
64 |
Locale:
65 |
= $locale ?>
66 |
Localización. Característica que depende de los locale instalados en el servidor.
67 |
68 |
69 |
--------------------------------------------------------------------------------
/public/javascript/jquery/jquery.kumbiaphp.min.js:
--------------------------------------------------------------------------------
1 | /*
2 | http://wiki.kumbiaphp.com/Licencia New BSD License
3 | */
4 | (function(a){a.KumbiaPHP={publicPath:null,plugin:[],cConfirm:function(b){var c=a(this);confirm(c.data("msg"))||b.preventDefault()},cFx:function(b){return function(c){c.preventDefault();c=a(this);a("#"+c.data("to"))[b]()}},cRemote:function(b){var c=a(this),c=a("#"+c.data("to"));b.preventDefault();c.load(this.href)},cRemoteConfirm:function(b){var c=a(this),d=a("#"+c.data("to"));b.preventDefault();confirm(c.data("msg"))&&d.load(this.href)},cFRemote:function(b){b.preventDefault();este=a(this);var c=a("[type=submit]",
5 | este);c.attr("disabled","disabled");b=este.attr("action");var d=este.attr("data-to");a.post(b,este.serialize(),function(b){var e=a("#"+d);e.html(b);e.hide();e.show("slow");c.attr("disabled",null)})},cUpdaterSelect:function(){var b=a(this),c=a("#"+b.data("update"));url=b.data("url");c.empty();a.get(url,{id:b.val()},function(b){for(i in b){var f=a("").text(b[i]).val(i);c.append(f)}},"json")},bind:function(){a("a.js-confirm, input.js-confirm").on("click",this.cConfirm);a("a.js-remote").on("click",
6 | this.cRemote);a("a.js-remote-confirm").on("click",this.cRemoteConfirm);a("a.js-show").on("click",this.cFx("show"));a("a.js-hide").on("click",this.cFx("hide"));a("a.js-toggle").on("click",this.cFx("toggle"));a("a.js-fade-in").on("click",this.cFx("fadeIn"));a("a.js-fade-out").on("click",this.cFx("fadeOut"));a("form.js-remote").on("submit",this.cFRemote);a("select.js-remote").on("change",this.cUpdaterSelect);a.KumbiaPHP.bindDatePicker()},autoload:function(){var b=a("[class*='jp-']");a.each(b,function(b){var d=
7 | a(this).attr("class").split(" ");for(b in d)"jp-"==d[b].substr(0,3)&&-1==a.inArray(d[b].substr(3),a.KumbiaPHP.plugin)&&a.KumbiaPHP.plugin.push(d[b].substr(3))});b=a("head");for(i in a.KumbiaPHP.plugin)a.ajaxSetup({cache:!0}),b.append(''),a.getScript(a.KumbiaPHP.publicPath+"javascript/jquery/jquery."+a.KumbiaPHP.plugin[i]+".js",function(){})},bindDatePicker:function(){var b=a("input.js-datepicker"),
8 | c=function(){b.each(function(){var b={monthSelector:!0,yearSelector:!0},c=a(this);void 0!=c.attr("min")&&(b.dateMin=c.attr("min").split("-"));void 0!=c.attr("max")&&(b.dateMax=c.attr("max").split("-"));c.pickadate(b)})};if("undefined"!=typeof a.pickadate)return c();a("head").append('');jQuery.ajax({dataType:"script",cache:!0,url:this.publicPath+"javascript/jquery/pickadate.js"}).done(function(){c()})},initialize:function(){var b=
9 | a("script:last").attr("src");this.publicPath=b.substr(0,b.length-37);a(function(){a.KumbiaPHP.bind();a.KumbiaPHP.autoload()})}};a.KumbiaPHP.initialize()})(jQuery);
10 |
--------------------------------------------------------------------------------
/koot/libs/controller_scaffold_lite.php:
--------------------------------------------------------------------------------
1 | data = $this->model::paginateQuery('SELECT * FROM ' . strtolower($this->model), 1, $this->perPage);
21 | }
22 |
23 | public function page(int $page = 1)
24 | {
25 | if ($page === 1) {
26 | Redirect::toAction('');
27 | return;
28 | }
29 |
30 | $this->data = $this->model::paginateQuery('SELECT * FROM ' . strtolower($this->model), $page, $this->perPage);
31 | }
32 |
33 | public function create()
34 | {
35 | // It is verified if the data has been sent via POST
36 | if (Input::hasPost('data')) {
37 | $obj = new $this->model;
38 | // Try to save the user
39 | if ($obj->create(Input::post('data'))) {
40 | // Success message and return to the list
41 | Flash::valid(_('Record created '));
42 | Redirect::toAction('');
43 | return;
44 | }
45 | // If it fails the data is persistent in the form
46 | $this->data = Input::post('data');
47 | }
48 | }
49 |
50 | public function edit(int $id)
51 | {
52 | View::select('create');
53 | // Load the data from database
54 | $this->data = $this->model::get($id);
55 | //If not exist
56 | if (!$this->data) {
57 | Flash::warning(_('Record not found'));
58 | Redirect::toAction('');
59 | return;
60 | }
61 | // It is verified if the data has been sent via POST
62 | if (Input::hasPost('data')) {
63 | // Try to save changes
64 | if ($this->data->update(Input::post('data'))) {
65 | // Success message and return to the list
66 | Flash::valid(_('Record updated'));
67 | Redirect::toAction('');
68 | return;
69 | }
70 | // If it fails the data is persistent in the form
71 | $this->data = Input::post('data');
72 | }
73 | }
74 |
75 | public function show(int $id)
76 | {
77 | $this->data = $this->model::get($id);
78 | }
79 |
80 | public function delete(int $id)
81 | {
82 | if (!$this->model::delete($id)) {
83 | Flash::error(_('Something was wrong'));
84 | }
85 |
86 | Redirect::toAction('');
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/koot/views/_shared/partials/paginators/digg.phtml:
--------------------------------------------------------------------------------
1 | page() <= $half) {
34 | $start = 1;
35 | } elseif (($page->totalPages() - $page->page()) < $half) {
36 | $start = $page->totalPages() - $show + 1;
37 | if ($start < 1) {
38 | $start = 1;
39 | }
40 | } else {
41 | $start = $page->page() - $half;
42 | }
43 | $last = false;
44 | if ($start === $page->totalPages()) {
45 | if ($start - 1 > 0) {
46 | $start -= 1;
47 | }
48 |
49 | $last = true;
50 | }
51 | ?>
52 |
53 |
--------------------------------------------------------------------------------
/koot/locale/es_ES/LC_MESSAGES/default.po:
--------------------------------------------------------------------------------
1 | msgid ""
2 | msgstr ""
3 | "Project-Id-Version: \n"
4 | "POT-Creation-Date: 2022-07-02 06:15-0500\n"
5 | "PO-Revision-Date: 2022-07-02 06:15-0500\n"
6 | "Last-Translator: \n"
7 | "Language-Team: \n"
8 | "Language: es_ES\n"
9 | "MIME-Version: 1.0\n"
10 | "Content-Type: text/plain; charset=UTF-8\n"
11 | "Content-Transfer-Encoding: 8bit\n"
12 | "X-Generator: Poedit 3.1\n"
13 | "X-Poedit-Basepath: ../../../..\n"
14 | "X-Poedit-SearchPath-0: .\n"
15 |
16 | #: app/libs/controller_scaffold_lite.php:41
17 | msgid "Record created"
18 | msgstr "Registro creado"
19 |
20 | #: app/libs/controller_scaffold_lite.php:57
21 | msgid "Record not found"
22 | msgstr "Registro no encontrado"
23 |
24 | #: app/libs/controller_scaffold_lite.php:66
25 | msgid "Record updated"
26 | msgstr "Registro actualizado"
27 |
28 | #: app/libs/controller_scaffold_lite.php:83
29 | msgid "Something was wrong"
30 | msgstr "Algo salió mal"
31 |
32 | #: app/views/_shared/partials/paginators/classic.phtml:50
33 | #: app/views/_shared/partials/paginators/classic.phtml:52
34 | #: app/views/_shared/partials/paginators/digg.phtml:55
35 | #: app/views/_shared/partials/paginators/digg.phtml:59
36 | msgid "Prev"
37 | msgstr "Anterior"
38 |
39 | #: app/views/_shared/partials/paginators/classic.phtml:63
40 | #: app/views/_shared/partials/paginators/digg.phtml:90
41 | msgid "Next"
42 | msgstr "Siguiente"
43 |
44 | #: app/views/_shared/scaffolds/lite/page.phtml:3
45 | #: app/views/_shared/scaffolds/lite/show.phtml:12
46 | #: app/views/admin/resources/create.phtml:24
47 | #: app/views/admin/roles/create.phtml:13 app/views/admin/users/create.phtml:22
48 | msgid "List"
49 | msgstr "Lista"
50 |
51 | #: app/views/_shared/scaffolds/lite/page.phtml:5
52 | #: app/views/_shared/scaffolds/lite/show.phtml:13
53 | #: app/views/admin/resources/create.phtml:2
54 | #: app/views/admin/roles/create.phtml:2 app/views/admin/users/create.phtml:2
55 | msgid "Create"
56 | msgstr "Crear"
57 |
58 | #: app/views/_shared/scaffolds/lite/page.phtml:17
59 | msgid "Actions"
60 | msgstr "Acciones"
61 |
62 | #: app/views/_shared/scaffolds/lite/page.phtml:27
63 | #: app/views/_shared/scaffolds/lite/show.phtml:14
64 | msgid "Edit"
65 | msgstr "Editar"
66 |
67 | #: app/views/_shared/scaffolds/lite/page.phtml:28
68 | #: app/views/_shared/scaffolds/lite/show.phtml:15
69 | msgid "Are you sure you want to delete?"
70 | msgstr "¿Está seguro que quiere borrar?"
71 |
72 | #: app/views/_shared/scaffolds/lite/page.phtml:28
73 | #: app/views/_shared/scaffolds/lite/show.phtml:15
74 | msgid "Are you sure?"
75 | msgstr "¿Está seguro?"
76 |
77 | #: app/views/_shared/scaffolds/lite/page.phtml:28
78 | #: app/views/_shared/scaffolds/lite/show.phtml:15
79 | msgid "Delete"
80 | msgstr "Eliminar"
81 |
82 | #: app/views/_shared/scaffolds/lite/page.phtml:39
83 | msgid "No records"
84 | msgstr "No hay registros"
85 |
86 | #: app/views/_shared/scaffolds/lite/show.phtml:4
87 | msgid "Show"
88 | msgstr "Mostrar"
89 |
90 | #: app/views/admin/resources/create.phtml:18
91 | #: app/views/admin/roles/create.phtml:9 app/views/admin/users/create.phtml:18
92 | msgid "Save"
93 | msgstr "Guardar"
94 |
95 | #: app/views/admin/users/create.phtml:2
96 | msgid "Users"
97 | msgstr "Usuarios"
98 |
--------------------------------------------------------------------------------
/public/index.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | >
5 | Koot Fast App
6 |
7 |
8 |
9 |
10 |
11 |
12 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/koot/config/mysql/ku_admin.sql:
--------------------------------------------------------------------------------
1 | -- MySQL Script generated by MySQL Workbench
2 | -- Sun May 10 19:28:53 2020
3 | -- Model: New Model Version: 1.0
4 | -- MySQL Workbench Forward Engineering
5 |
6 | SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
7 | SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
8 | SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION';
9 |
10 | -- -----------------------------------------------------
11 | -- Schema ku_admin
12 | -- -----------------------------------------------------
13 | DROP SCHEMA IF EXISTS `ku_admin` ;
14 |
15 | -- -----------------------------------------------------
16 | -- Schema ku_admin
17 | -- -----------------------------------------------------
18 | CREATE SCHEMA IF NOT EXISTS `ku_admin` DEFAULT CHARACTER SET utf8 ;
19 | USE `ku_admin` ;
20 |
21 | -- -----------------------------------------------------
22 | -- Table `ku_admin`.`permissions`
23 | -- -----------------------------------------------------
24 | CREATE TABLE IF NOT EXISTS `ku_admin`.`permissions` (
25 | `id` INT NOT NULL AUTO_INCREMENT,
26 | `roles_id` INT NOT NULL,
27 | `resources_id` INT NOT NULL,
28 | PRIMARY KEY (`id`),
29 | CONSTRAINT `fk_permissions__roles`
30 | FOREIGN KEY (`roles_id`)
31 | REFERENCES `ku_admin`.`roles` (`id`)
32 | ON DELETE NO ACTION
33 | ON UPDATE NO ACTION,
34 | CONSTRAINT `fk_permissions__resources`
35 | FOREIGN KEY (`resources_id`)
36 | REFERENCES `ku_admin`.`resources` (`id`)
37 | ON DELETE NO ACTION
38 | ON UPDATE NO ACTION)
39 | ENGINE = InnoDB;
40 |
41 | CREATE INDEX `fk_permissions_roles_idx` ON `ku_admin`.`permissions` (`roles_id` ASC);
42 |
43 | CREATE INDEX `fk_permissions_resources_idx` ON `ku_admin`.`permissions` (`resources_id` ASC);
44 |
45 |
46 | -- -----------------------------------------------------
47 | -- Table `ku_admin`.`resources`
48 | -- -----------------------------------------------------
49 | CREATE TABLE IF NOT EXISTS `ku_admin`.`resources` (
50 | `id` INT NOT NULL AUTO_INCREMENT,
51 | `name` VARCHAR(127) NOT NULL,
52 | `description` VARCHAR(255) NULL,
53 | `url` VARCHAR(255) NOT NULL,
54 | `module` VARCHAR(45) NULL,
55 | `controller` VARCHAR(45) NOT NULL,
56 | `action` VARCHAR(45) NOT NULL,
57 | `status` INT NOT NULL,
58 | PRIMARY KEY (`id`))
59 | ENGINE = InnoDB;
60 |
61 | CREATE UNIQUE INDEX `resources_name_UNIQUE` ON `ku_admin`.`resources` (`name` ASC);
62 |
63 | CREATE UNIQUE INDEX `resources_url_UNIQUE` ON `ku_admin`.`resources` (`url` ASC);
64 |
65 |
66 | -- -----------------------------------------------------
67 | -- Table `ku_admin`.`roles`
68 | -- -----------------------------------------------------
69 | CREATE TABLE IF NOT EXISTS `ku_admin`.`roles` (
70 | `id` INT NOT NULL AUTO_INCREMENT,
71 | `name` VARCHAR(45) NULL,
72 | `status` INT NOT NULL,
73 | PRIMARY KEY (`id`))
74 | ENGINE = InnoDB;
75 |
76 |
77 | -- -----------------------------------------------------
78 | -- Table `ku_admin`.`users`
79 | -- -----------------------------------------------------
80 | CREATE TABLE IF NOT EXISTS `ku_admin`.`users` (
81 | `id` INT NOT NULL AUTO_INCREMENT,
82 | `email` VARCHAR(255) NOT NULL,
83 | `username` VARCHAR(45) NULL,
84 | `password` VARCHAR(255) NULL,
85 | `first_name` VARCHAR(255) NULL,
86 | `middle_name` VARCHAR(255) NULL,
87 | `last_name` VARCHAR(255) NULL,
88 | `status` INT NOT NULL,
89 | PRIMARY KEY (`id`))
90 | ENGINE = InnoDB;
91 |
92 | CREATE UNIQUE INDEX `users_email_UNIQUE` ON `ku_admin`.`users` (`email` ASC);
93 |
94 |
95 | -- -----------------------------------------------------
96 | -- Table `ku_admin`.`users_roles`
97 | -- -----------------------------------------------------
98 | CREATE TABLE IF NOT EXISTS `ku_admin`.`users_roles` (
99 | `id` INT NOT NULL AUTO_INCREMENT,
100 | `users_id` INT NOT NULL,
101 | `roles_id` INT NOT NULL,
102 | PRIMARY KEY (`id`),
103 | CONSTRAINT `fk_users_roles__users`
104 | FOREIGN KEY (`users_id`)
105 | REFERENCES `ku_admin`.`users` (`id`)
106 | ON DELETE NO ACTION
107 | ON UPDATE NO ACTION,
108 | CONSTRAINT `fk_users_roles__roles`
109 | FOREIGN KEY (`roles_id`)
110 | REFERENCES `ku_admin`.`roles` (`id`)
111 | ON DELETE NO ACTION
112 | ON UPDATE NO ACTION)
113 | ENGINE = InnoDB;
114 |
115 | CREATE INDEX `fk_users_roles_users_idx` ON `ku_admin`.`users_roles` (`users_id` ASC);
116 |
117 | CREATE INDEX `fk_users_roles_roles_idx` ON `ku_admin`.`users_roles` (`roles_id` ASC);
118 |
119 |
120 | SET SQL_MODE=@OLD_SQL_MODE;
121 | SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
122 | SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
123 |
--------------------------------------------------------------------------------
/koot/views/_shared/templates/admin.phtml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | >
5 | Koot Fast App
6 |
7 |
8 |
9 |
10 |
11 |
12 |
27 |
28 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/koot/libs/httpk.php:
--------------------------------------------------------------------------------
1 | query = '?' . http_build_query($params);
41 | return $this;
42 | }
43 |
44 | public function header(string $header, string $value): self
45 | {
46 | $this->headers[$header] = $value;
47 | return $this;
48 | }
49 |
50 | public function headerArray(array $headers): self
51 | {
52 | $this->headers = array_merge($this->headers, $headers); // mmm review
53 | return $this;
54 | }
55 |
56 | public function body(string $data, string $type = 'application/json')
57 | {
58 | $this->body = $data;
59 | $this->headers['Content-Type'] = $type;
60 | return $this;
61 | }
62 |
63 | public function jsonBody(array $data): self
64 | {
65 | //añadir exception si falla
66 | return $this->body(json_encode($data));
67 | }
68 |
69 | /**
70 | * Create a form urlencoded from an array
71 | *
72 | * @param array $data
73 | * @return self
74 | */
75 | public function formBody(array $data): self
76 | {
77 | return $this->body(http_build_query($data), 'application/x-www-form-urlencoded');
78 | }
79 |
80 | /**
81 | * https://www.php.net/manual/en/function.curl-setopt.php
82 | * https://curl.se/libcurl/c/curl_easy_setopt.html
83 | *
84 | * @param int $key A constant CURLOPT_xxxx
85 | * @param mixed $value
86 | */
87 | public function setopt(int $key, $value): self
88 | {
89 | $this->curlopts[$key] = $value;
90 | return $this;
91 | }
92 |
93 | /**
94 | * https://www.php.net/manual/en/function.curl-setopt.php
95 | * https://curl.se/libcurl/c/curl_easy_setopt.html
96 | *
97 | * @param array $options A list of constants CURLOPT_XXXXXS and values
98 | */
99 | public function setoptArray(array $options): self
100 | {
101 | $this->curlopts = $options + $this->curlopts;
102 | return $this;
103 | }
104 |
105 | protected function joinHeaders(): array
106 | {
107 | $headers = [];
108 | foreach ($this->headers as $key => $value) {
109 | $headers[] = "$key: $value";
110 | }
111 | return $headers;
112 | }
113 |
114 |
115 | protected function getOptions(): array
116 | {
117 | $options = [
118 | CURLOPT_USERAGENT => self::USER_AGENT,
119 | CURLOPT_URL => $this->url . $this->query,
120 | CURLOPT_CUSTOMREQUEST => $this->method,
121 | CURLOPT_HTTPHEADER => $this->joinHeaders(),
122 | CURLOPT_ENCODING => '',
123 | CURLOPT_RETURNTRANSFER => true,
124 | CURLOPT_FOLLOWLOCATION => true,
125 | CURLOPT_MAXREDIRS => 10,
126 | CURLOPT_CONNECTTIMEOUT => 5,
127 | CURLOPT_TIMEOUT => 5
128 | ];
129 |
130 | if (isset($this->body)) {
131 | $options[CURLOPT_POSTFIELDS] = $this->body;
132 | }
133 |
134 | if ($this->curlopts) {
135 | $options = $this->curlopts + $options;
136 | }
137 |
138 | return $options;
139 | }
140 |
141 | public function send(): string
142 | {
143 | $ch = curl_init();
144 | curl_setopt_array($ch, $this->getOptions());
145 |
146 | $result = curl_exec($ch);
147 | if ($result === false) {
148 | $error = curl_error($ch);
149 | $errno = curl_errno($ch);
150 | curl_close($ch);
151 | throw new RuntimeException($error, $errno);
152 | }
153 | curl_close($ch);
154 | return $result;
155 | }
156 |
157 | /**
158 | * @return mixed
159 | */
160 | public function getJson(bool $assoc = true, int $depth = 512, int $flags = 0)
161 | {
162 | $this->headers['Accept'] = 'application/json';
163 | return json_decode($this->send(), $assoc, $depth, JSON_THROW_ON_ERROR|$flags);
164 | }
165 | // Use Kumbia parsers
166 | }
167 |
--------------------------------------------------------------------------------
/public/javascript/jquery/jquery.kumbiaphp.js:
--------------------------------------------------------------------------------
1 | /**
2 | * KumbiaPHP web & app Framework
3 | *
4 | * LICENSE
5 | *
6 | * This source file is subject to the new BSD license that is bundled
7 | * with this package in the file LICENSE.
8 | *
9 | * Plugin para jQuery que incluye los callbacks basicos para los Helpers
10 | *
11 | * @copyright Copyright (c) 2005 - 2019 KumbiaPHP Team (http://www.kumbiaphp.com)
12 | * @license https://github.com/KumbiaPHP/KumbiaPHP/blob/master/LICENSE New BSD License
13 | */
14 |
15 | (function($) {
16 | /**
17 | * Objeto KumbiaPHP
18 | *
19 | */
20 | $.KumbiaPHP = {
21 | /**
22 | * Ruta al directorio public en el servidor
23 | *
24 | * @var String
25 | */
26 | publicPath : null,
27 |
28 | /**
29 | * Plugins cargados
30 | *
31 | * @var Array
32 | */
33 | plugin: [],
34 |
35 | /**
36 | * Muestra mensaje de confirmacion
37 | *
38 | * @param Object event
39 | */
40 | cConfirm: function(event) {
41 | var este=$(this);
42 | if(!confirm(este.data('msg'))) {
43 | event.preventDefault();
44 | }
45 | },
46 |
47 | /**
48 | * Aplica un efecto a un elemento
49 | *
50 | * @param String fx
51 | */
52 | cFx: function(fx) {
53 | return function(event) {
54 | event.preventDefault();
55 | var este=$(this),
56 | rel = $('#'+este.data('to'));
57 | rel[fx]();
58 | }
59 | },
60 |
61 | /**
62 | * Carga con AJAX
63 | *
64 | * @param Object event
65 | */
66 | cRemote: function(event) {
67 | var este=$(this), rel = $('#'+este.data('to'));
68 | event.preventDefault();
69 | rel.load(this.href);
70 | },
71 |
72 | /**
73 | * Carga con AJAX y Confirmacion
74 | *
75 | * @param Object event
76 | */
77 | cRemoteConfirm: function(event) {
78 | var este=$(this), rel = $('#'+este.data('to'));
79 | event.preventDefault();
80 | if(confirm(este.data('msg'))) {
81 | rel.load(this.href);
82 | }
83 | },
84 |
85 | /**
86 | * Enviar formularios de manera asincronica, via POST
87 | * Y los carga en un contenedor
88 | */
89 | cFRemote: function(event){
90 | event.preventDefault();
91 | este = $(this);
92 | var button = $('[type=submit]', este);
93 | button.attr('disabled', 'disabled');
94 | var url = este.attr('action');
95 | var div = este.attr('data-to');
96 | $.post(url, este.serialize(), function(data, status){
97 | var capa = $('#'+div);
98 | capa.html(data);
99 | capa.hide();
100 | capa.show('slow');
101 | button.attr('disabled', null);
102 | });
103 | },
104 |
105 | /**
106 | * Carga con AJAX al cambiar select
107 | *
108 | * @param Object event
109 | */
110 | cUpdaterSelect: function(event) {
111 | var $t = $(this),$u= $('#' + $t.data('update'))
112 | url = $t.data('url');
113 | $u.empty();
114 | $.get(url, {'id':$t.val()}, function(d){
115 | for(i in d){
116 | var a = $('').text(d[i]).val(i);
117 | $u.append(a);
118 | }
119 | }, 'json');
120 | },
121 |
122 | /**
123 | * Enlaza a las clases por defecto
124 | *
125 | */
126 | bind : function() {
127 | // Enlace y boton con confirmacion
128 | $("body").on('click', "a.js-confirm, input.js-confirm",this.cConfirm);
129 |
130 | // Enlace ajax
131 | $("body").on('click', "a.js-remote",this.cRemote);
132 |
133 | // Enlace ajax con confirmacion
134 | $("body").on('click', "a.js-remote-confirm",this.cRemoteConfirm);
135 |
136 | // Efecto show
137 | $("body").on('click', "a.js-show",this.cFx('show'));
138 |
139 | // Efecto hide
140 | $("body").on('click', "a.js-hide",this.cFx('hide'));
141 |
142 | // Efecto toggle
143 | $("body").on('click', "a.js-toggle",this.cFx('toggle'));
144 |
145 | // Efecto fadeIn
146 | $("body").on('click', "a.js-fade-in",this.cFx('fadeIn'));
147 |
148 | // Efecto fadeOut
149 | $("body").on('click', "a.js-fade-out",this.cFx('fadeOut'));
150 |
151 | // Formulario ajax
152 | $("body").on('submit',"form.js-remote", this.cFRemote);
153 |
154 | // Lista desplegable que actualiza con ajax
155 | $("body").on('change',"select.js-remote", this.cUpdaterSelect);
156 |
157 | // Enlazar DatePicker
158 | $.KumbiaPHP.bindDatePicker();
159 |
160 | },
161 |
162 | /**
163 | * Implementa la autocarga de plugins, estos deben seguir
164 | * una convención para que pueda funcionar correctamente
165 | */
166 | autoload: function(){
167 | var elem = $("[class*='jp-']");
168 | $.each(elem, function(i, val){
169 | var este = $(this); //apunta al elemento con clase jp-*
170 | var classes = este.attr('class').split(' ');
171 | for (i in classes){
172 | if(classes[i].substr(0, 3) == 'jp-'){
173 | if($.inArray(classes[i].substr(3),$.KumbiaPHP.plugin) != -1)
174 | continue;
175 | $.KumbiaPHP.plugin.push(classes[i].substr(3))
176 | }
177 | }
178 | });
179 | var head = $('head');
180 | for(i in $.KumbiaPHP.plugin){
181 | $.ajaxSetup({ cache: true});
182 | head.append('');
183 | $.getScript($.KumbiaPHP.publicPath + 'javascript/jquery/jquery.' + $.KumbiaPHP.plugin[i] + '.js', function(data, text){});
184 | }
185 | },
186 |
187 | /**
188 | * Carga y Enlaza Unobstrusive DatePicker en caso de ser necesario
189 | *
190 | */
191 | bindDatePicker: function() {
192 |
193 | // Selecciona los campos input
194 | var inputs = $('input.js-datepicker');
195 | /**
196 | * Funcion encargada de enlazar el DatePicker a los Input
197 | *
198 | */
199 | var bindInputs = function() {
200 | inputs.each(function() {
201 | var opts = {monthSelector: true,yearSelector:true};
202 | var input = $(this);
203 | // Verifica si hay mínimo
204 | if(input.attr('min') != undefined) {
205 | opts.dateMin = input.attr('min').split('-');
206 | }
207 | // Verifica si ha máximo
208 | if(input.attr('max') != undefined) {
209 | opts.dateMax = input.attr('max').split('-');
210 | }
211 |
212 | // Crea el calendario
213 | input.pickadate(opts);
214 | });
215 | }
216 |
217 | // Si ya esta cargado Unobstrusive DatePicker, lo integra de una vez
218 | if(typeof($.pickadate) != "undefined") {
219 | return bindInputs();
220 | }
221 |
222 | // Carga la hoja de estilos
223 | $('head').append('');
224 |
225 | // Carga Unobstrusive DatePicker, para poder usar cache
226 | jQuery.ajax({ dataType: "script",cache: true, url: this.publicPath + 'javascript/jquery/pickadate.js'}).done(function(){
227 | bindInputs();
228 | });
229 | },
230 |
231 | /**
232 | * Inicializa el plugin
233 | *
234 | */
235 | initialize: function() {
236 | // Obtiene el publicPath, restando los caracteres que sobran
237 | // de la ruta, respecto a la ruta de ubicacion del plugin de KumbiaPHP
238 | // "javascript/jquery/jquery.kumbiaphp.js"
239 | var src = $('script:last').attr('src');
240 | this.publicPath = src.substr(0, src.length - 37);
241 |
242 | // Enlaza a las clases por defecto
243 | $(function(){
244 | $.KumbiaPHP.bind();
245 | $.KumbiaPHP.autoload();
246 |
247 | });
248 | }
249 | }
250 |
251 | // Inicializa el plugin
252 | $.KumbiaPHP.initialize();
253 | })(jQuery);
254 |
--------------------------------------------------------------------------------
/koot/views/_shared/templates/login/login.phtml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 | Login KuAdmin
9 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
251 |
252 |
253 |
254 |
--------------------------------------------------------------------------------
/public/css/kumbia.min.css:
--------------------------------------------------------------------------------
1 | .flash{margin:5px 0;min-height:32px;padding:3px 10px 3px 50px;background-repeat:no-repeat;background-position:10px center;line-height:32px;border-radius:2px}.error{color:#d8000c;background-color:#ffbaba}.info{color:#00529b;background-color:#bde5f8}.valid{color:#4f8a10;background-color:#dff2bf}.warning{color:#9f6000;background-color:#feefb3}.icon{filter:invert(.5)}.icon:hover{filter:none}article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}audio,canvas,video{display:inline-block}audio:not([controls]){display:none;height:0}[hidden]{display:none}html{font-family:sans-serif;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%}a:focus{outline:thin dotted}a:active,a:hover{outline:0}mark{background:#ff0;color:#000}code,kbd,pre,samp{font-family:monospace,serif;font-size:1em}pre{white-space:pre-wrap}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:0}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}*,:after,:before{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}body{font-family:Helvetica,Arial,sans-serif;font-size:15px;line-height:1.5;color:#333;background-color:#fff;margin:0}a{color:#0ac;font-weight:700;text-decoration:none}a:focus,a:hover{color:#ff4d4d;text-decoration:underline}a:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}img{vertical-align:middle}.img-rounded{border-radius:9px}.img-circle{border-radius:50%}hr{margin-top:22px;margin-bottom:22px;border:0;border-top:1px solid #eee}p{margin:0 0 11px}small{font-size:85%}cite{font-style:normal}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}h1,h2,h3,h4,h5,h6{font-family:Helvetica,Arial,sans-serif;font-weight:500;line-height:1.1}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small{font-weight:400;line-height:1;color:#999;font-size:60%}h1,h2,h3,h4,h5,h6{margin-top:22px;margin-bottom:11px}h1{font-size:42px}h2{font-size:36px}h3{font-size:29px}h4{font-size:22px}h5{font-size:19px}h6{font-size:16px}header.top{padding-bottom:10px;margin:44px 0 22px;border-bottom:1px solid #eee}ol,ul{margin-top:0;margin-bottom:11px}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}ul.unstyled{padding-left:0;list-style:none}ul.inline{padding-left:0;list-style:none}ul.inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-bottom:22px}dd,dt{line-height:1.5}dt{font-weight:700}dd{margin-left:0}@media (min-width:768px){dl.horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}dl.horizontal dd{margin-left:180px}dl.horizontal dd:after,dl.horizontal dd:before{content:" ";display:table}dl.horizontal dd:after{clear:both}}blockquote{padding:11px 22px;margin:0 0 22px;border-left:5px solid #eee}blockquote p{font-size:18.75px;font-weight:300;line-height:1.25}blockquote p:last-child{margin-bottom:0}blockquote small{display:block;line-height:1.5;color:#999}blockquote small:before{content:'\2014 \00A0'}blockquote:after,blockquote:before,q:after,q:before{content:""}address{display:block;margin-bottom:22px;font-style:normal;line-height:1.5}code,pre{font-family:Monaco,Menlo,Consolas,"Courier New",monospace}code{padding:2px 4px;color:#c7254e;white-space:nowrap;border-radius:6px}pre{display:block;padding:10.5px;margin:0 0 11px;line-height:1.5;word-break:break-all;word-wrap:break-word;color:#333;background-color:#f5f5f5;border-radius:5px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;border:0}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.container:after,.container:before{content:" ";display:table}.container:after{clear:both}.row{margin-left:15px;margin-right:15px}.row:after,.row:before{content:" ";display:table}.row:after{clear:both}.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9{position:relative;min-height:1px;padding-left:15px;padding-right:15px;float:left}.col-1{width:8.333333333333332%}.col-2{width:16.666666666666664%}.col-3{width:25%}.col-4{width:33.33333333333333%}.col-5{width:41.66666666666667%}.col-6{width:50%}.col-7{width:58.333333333333336%}.col-8{width:66.66666666666666%}.col-9{width:75%}.col-10{width:83.33333333333334%}.col-11{width:91.66666666666666%}.col-12{width:100%}.offset-0{margin-left:0}.offset-1{margin-left:8.333333333333332%}.offset-2{margin-left:16.666666666666664%}.offset-3{margin-left:25%}.offset-4{margin-left:33.33333333333333%}.offset-5{margin-left:41.66666666666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333333333336%}.offset-8{margin-left:66.66666666666666%}.offset-9{margin-left:75%}.offset-10{margin-left:83.33333333333334%}.offset-11{margin-left:91.66666666666666%}@media (min-width:992px){.container{max-width:970px}}@media (min-width:1200px){.container{max-width:1170px}}table{max-width:100%;border-collapse:collapse}table{margin:auto;margin-bottom:22px}table tr>td,table tr>th{padding:8px;line-height:1.5;border-top:1px solid #ddd}table thead>tr>th{vertical-align:bottom;border-bottom:2px solid #ddd}table.condensed td,table.condensed th{padding:5px}table.border{border:1px solid #ddd}table.border td,table.border th{border:1px solid #ddd}table.zebra>tbody>tr:nth-child(odd)>td,table.zebra>tbody>tr:nth-child(odd)>th{background-color:#f9f9f9}table.hover>tbody>tr:hover{background-color:#f5f5f5}legend{display:block;width:100%;padding:0;margin-bottom:22px;font-size:22.5px;line-height:inherit;color:#333;border:0;border-bottom:1px solid #e5e5e5}fieldset{border:0}label{display:inline-block;margin-bottom:5px;font-weight:700}.control::-moz-placeholder{color:#999}.control:-ms-input-placeholder{color:#999}.control::-webkit-input-placeholder{color:#999}input.control,select.control,textarea.control{display:block;width:100%;height:36px;padding:6px 12px;line-height:1.5;color:#555;background-color:#fff;border:1px solid #ccc;border-radius:6px;-webkit-transition:all ease-in .4s;transition:all ease-in .4s}input.control:focus,select.control:focus,textarea.control:focus{border-color:#66afe9;outline:0}fieldset[disabled] input.control,fieldset[disabled] select.control,fieldset[disabled] textarea.control,input.control[disabled],input.control[readonly],select.control[disabled],select.control[readonly],textarea.control[disabled],textarea.control[readonly]{cursor:not-allowed;background-color:#eee}textareainput.control,textareaselect.control,textareatextarea.control{height:auto}@media (min-width:768px){form.inline .form-group,form.inline input.control,form.inline select.control,form.inline textarea.control{display:inline-block}form.inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}form.inline .control{display:inline-block}}.form-group{margin-bottom:15px}form.horizontal .form-group{margin-left:-15px;margin-right:-15px}form.horizontal .form-group:after,form.horizontal .form-group:before{content:" ";display:table}form.horizontal .form-group:after{clear:both}.form-horizontal{padding-top:6px}@media (min-width:768px){form.horizontal .control-label{text-align:right}}.btn{display:inline-block;text-decoration:none;color:#fff;border-radius:6px;border-width:1px;line-height:1.5;padding:6px 12px;-webkit-box-shadow:1px 1px 3px #555;box-shadow:1px 1px 3px #555}.btn:hover{text-decoration:none;-webkit-box-shadow:1px 2px 5px #777;box-shadow:1px 2px 5px #777}.btn-default{color:#000;border-color:#ccc;border-bottom-color:#b3b3b3;background-repeat:repeat-x;background-image:-webkit-linear-gradient(45deg,#fff,#e6e6e6);background-image:-moz-linear-gradient(45deg,#fff,#e6e6e6);background-image:linear-gradient(45deg,#fff,#e6e6e6)}.btn-default:hover{background:#ccc}.btn-inverse{border-color:#222;border-bottom-color:#080808;background-repeat:repeat-x;background-image:-webkit-linear-gradient(45deg,#555,#3b3b3b);background-image:-moz-linear-gradient(45deg,#555,#3b3b3b);background-image:linear-gradient(45deg,#555,#3b3b3b)}.btn-inverse:hover{background:#222}.btn-danger{border-color:#a02622;border-bottom-color:#761c19;background-repeat:repeat-x;background-image:-webkit-linear-gradient(45deg,#d9534f,#c9302c);background-image:-moz-linear-gradient(45deg,#d9534f,#c9302c);background-image:linear-gradient(45deg,#d9534f,#c9302c)}.btn-danger:hover{background:#a02622}.btn-info{border-color:#2390b0;border-bottom-color:#1b6d85;background-repeat:repeat-x;background-image:-webkit-linear-gradient(45deg,#5bc0de,#31b0d5);background-image:-moz-linear-gradient(45deg,#5bc0de,#31b0d5);background-image:linear-gradient(45deg,#5bc0de,#31b0d5)}.btn-info:hover{background:#2390b0}.btn-success{border-color:#357935;border-bottom-color:#255625;background-repeat:repeat-x;background-image:-webkit-linear-gradient(45deg,#5cb85c,#449d44);background-image:-moz-linear-gradient(45deg,#5cb85c,#449d44);background-image:linear-gradient(45deg,#5cb85c,#449d44)}.btn-success:hover{background:#357935}.btn-primary{border-color:#245682;border-bottom-color:#193c5a;background-repeat:repeat-x;background-image:-webkit-linear-gradient(45deg,#428bca,#3071a9);background-image:-moz-linear-gradient(45deg,#428bca,#3071a9);background-image:linear-gradient(45deg,#428bca,#3071a9)}.btn-primary:hover{background:#245682}.btn-warning{border-color:#c77c11;border-bottom-color:#985f0d;background-repeat:repeat-x;background-image:-webkit-linear-gradient(45deg,#f0ad4e,#ec971f);background-image:-moz-linear-gradient(45deg,#f0ad4e,#ec971f);background-image:linear-gradient(45deg,#f0ad4e,#ec971f)}.btn-warning:hover{background:#c77c11}.btn-sm{font-size:.7em}.btn-lg{font-size:1.2em}.btn-round{border-radius:20px}.btn-active,.btn-active:hover,.btn-disabled,.btn-disabled:hover,.btn.disabled,.btn[disabled]{opacity:1;background:#d1d1d1;border:1px solid #b3b3b3;text-shadow:0 1px 1px #fff}.btn.disabled,.btn[disabled]{color:#999}.hero{padding:30px;margin-bottom:30px;font-size:22.5px;font-weight:200;line-height:2.25;color:#fff;background-color:#0ac;border-radius:6px}.hero h1{line-height:1;color:inherit}.hero p{line-height:1.4}@media screen and (min-width:768px){.hero{padding-top:50px;padding-bottom:50px}.hero h1{font-size:67.5px}}.actions{border-top:dotted 1px grey;padding-top:1em;margin:.5em 0 0}input,label,select,textarea{display:block}footer{padding-top:1em;margin-top:2em;border-top:1px solid #ccc}.paginator .nextprev{color:#000}.paginator a{border:1px solid #e8ebf1;padding:.5em;text-decoration:none;margin:.5em .1em;background:#fff}.paginator a:hover{background:#e8ebf1}.paginator strong{background:#e8ebf1;border:1px solid #e8ebf1;padding:.5em;margin:.5em .1em}#scaffold table a{color:#333;font-weight:400}#scaffold table a:hover{color:#0ac;text-decoration:none}#scaffold table{width:100%}#scaffold th{text-align:left}#scaffold caption{font-size:2em;text-align:left}#scaffold .show{list-style:none;padding:1em}#scaffold .show strong{width:30%;display:inline-block}#scaffold .show li{padding:8px;line-height:1.5;border-top:1px solid #ddd}#scaffold .show li:hover{background-color:#f5f5f5}
--------------------------------------------------------------------------------
/public/css/kumbia/kumbia.css:
--------------------------------------------------------------------------------
1 | article, aside, details, figcaption, figure, footer, header, hgroup, main, nav, section, summary {
2 | display: block
3 | }
4 |
5 | audio, canvas, video {
6 | display: inline-block
7 | }
8 |
9 | audio:not([controls]) {
10 | display: none;
11 | height: 0
12 | }
13 |
14 | [hidden] {
15 | display: none
16 | }
17 |
18 | html {
19 | font-family: sans-serif;
20 | -webkit-text-size-adjust: 100%;
21 | -ms-text-size-adjust: 100%
22 | }
23 |
24 | a:focus {
25 | outline: thin dotted
26 | }
27 |
28 | a:active, a:hover {
29 | outline: 0
30 | }
31 |
32 | mark {
33 | background: #ff0;
34 | color: #000
35 | }
36 |
37 | code, kbd, pre, samp {
38 | font-family: monospace, serif;
39 | font-size: 1em
40 | }
41 |
42 | pre {
43 | white-space: pre-wrap
44 | }
45 |
46 | sub, sup {
47 | font-size: 75%;
48 | line-height: 0;
49 | position: relative;
50 | vertical-align: baseline
51 | }
52 |
53 | sup {
54 | top: -0.5em
55 | }
56 |
57 | sub {
58 | bottom: -0.25em
59 | }
60 |
61 | img {
62 | border: 0
63 | }
64 |
65 | svg:not(:root) {
66 | overflow: hidden
67 | }
68 |
69 | figure {
70 | margin: 0
71 | }
72 |
73 | input[type="search"]::-webkit-search-cancel-button, input[type="search"]::-webkit-search-decoration {
74 | -webkit-appearance: none
75 | }
76 |
77 | *, *:before, *:after {
78 | -webkit-box-sizing: border-box;
79 | -moz-box-sizing: border-box;
80 | box-sizing: border-box
81 | }
82 |
83 | body {
84 | font-family: Helvetica, Arial, sans-serif;
85 | font-size: 15px;
86 | line-height: 1.5;
87 | color: #333;
88 | background-color: #fff;
89 | margin: 0
90 | }
91 |
92 | a {
93 | color: #0ac;
94 | font-weight: bold;
95 | text-decoration: none
96 | }
97 |
98 | a:hover, a:focus {
99 | color: #ff4d4d;
100 | text-decoration: underline
101 | }
102 |
103 | a:focus {
104 | outline: thin dotted #333;
105 | outline: 5px auto -webkit-focus-ring-color;
106 | outline-offset: -2px
107 | }
108 |
109 | img {
110 | vertical-align: middle
111 | }
112 |
113 | .img-rounded {
114 | border-radius: 9px
115 | }
116 |
117 | .img-circle {
118 | border-radius: 50%
119 | }
120 |
121 | hr {
122 | margin-top: 22px;
123 | margin-bottom: 22px;
124 | border: 0;
125 | border-top: 1px solid #eee
126 | }
127 |
128 | p {
129 | margin: 0 0 11px
130 | }
131 |
132 | small {
133 | font-size: 85%
134 | }
135 |
136 | cite {
137 | font-style: normal
138 | }
139 |
140 | .text-left {
141 | text-align: left
142 | }
143 |
144 | .text-right {
145 | text-align: right
146 | }
147 |
148 | .text-center {
149 | text-align: center
150 | }
151 |
152 | h1, h2, h3, h4, h5, h6 {
153 | font-family: Helvetica, Arial, sans-serif;
154 | font-weight: 500;
155 | line-height: 1.1
156 | }
157 |
158 | h1 small, h2 small, h3 small, h4 small, h5 small, h6 small {
159 | font-weight: normal;
160 | line-height: 1;
161 | color: #999;
162 | font-size: 60%
163 | }
164 |
165 | h1, h2, h3, h4, h5, h6 {
166 | margin-top: 22px;
167 | margin-bottom: 11px
168 | }
169 |
170 | h1 {
171 | font-size: 42px
172 | }
173 |
174 | h2 {
175 | font-size: 36px
176 | }
177 |
178 | h3 {
179 | font-size: 29px
180 | }
181 |
182 | h4 {
183 | font-size: 22px
184 | }
185 |
186 | h5 {
187 | font-size: 19px
188 | }
189 |
190 | h6 {
191 | font-size: 16px
192 | }
193 |
194 | header.top {
195 | padding-bottom: 10px;
196 | margin: 44px 0 22px;
197 | border-bottom: 1px solid #eee
198 | }
199 |
200 | ul, ol {
201 | margin-top: 0;
202 | margin-bottom: 11px
203 | }
204 |
205 | ul ul, ol ul, ul ol, ol ol {
206 | margin-bottom: 0
207 | }
208 |
209 | ul.unstyled {
210 | padding-left: 0;
211 | list-style: none
212 | }
213 |
214 | ul.inline {
215 | padding-left: 0;
216 | list-style: none
217 | }
218 |
219 | ul.inline>li {
220 | display: inline-block;
221 | padding-left: 5px;
222 | padding-right: 5px
223 | }
224 |
225 | dl {
226 | margin-bottom: 22px
227 | }
228 |
229 | dt, dd {
230 | line-height: 1.5
231 | }
232 |
233 | dt {
234 | font-weight: bold
235 | }
236 |
237 | dd {
238 | margin-left: 0
239 | }
240 |
241 | @media (min-width:768px) {
242 | dl.horizontal dt {
243 | float: left;
244 | width: 160px;
245 | clear: left;
246 | text-align: right;
247 | overflow: hidden;
248 | text-overflow: ellipsis;
249 | white-space: nowrap
250 | }
251 | dl.horizontal dd {
252 | margin-left: 180px
253 | }
254 | dl.horizontal dd:before, dl.horizontal dd:after {
255 | content: " ";
256 | display: table;
257 | }
258 | dl.horizontal dd:after {
259 | clear: both
260 | }
261 | }
262 |
263 | blockquote {
264 | padding: 11px 22px;
265 | margin: 0 0 22px;
266 | border-left: 5px solid #eee
267 | }
268 |
269 | blockquote p {
270 | font-size: 18.75px;
271 | font-weight: 300;
272 | line-height: 1.25
273 | }
274 |
275 | blockquote p:last-child {
276 | margin-bottom: 0
277 | }
278 |
279 | blockquote small {
280 | display: block;
281 | line-height: 1.5;
282 | color: #999
283 | }
284 |
285 | blockquote small:before {
286 | content: '\2014 \00A0'
287 | }
288 |
289 | q:before, q:after, blockquote:before, blockquote:after {
290 | content: ""
291 | }
292 |
293 | address {
294 | display: block;
295 | margin-bottom: 22px;
296 | font-style: normal;
297 | line-height: 1.5
298 | }
299 |
300 | code, pre {
301 | font-family: Monaco, Menlo, Consolas, "Courier New", monospace
302 | }
303 |
304 | code {
305 | padding: 2px 4px;
306 | color: #c7254e;
307 | white-space: nowrap;
308 | border-radius: 6px
309 | }
310 |
311 | pre {
312 | display: block;
313 | padding: 10.5px;
314 | margin: 0 0 11px;
315 | line-height: 1.5;
316 | word-break: break-all;
317 | word-wrap: break-word;
318 | color: #333;
319 | background-color: #f5f5f5;
320 | border-radius: 5px;
321 | }
322 |
323 | pre code {
324 | padding: 0;
325 | font-size: inherit;
326 | color: inherit;
327 | white-space: pre-wrap;
328 | border: 0
329 | }
330 |
331 | .container {
332 | margin-right: auto;
333 | margin-left: auto;
334 | padding-left: 15px;
335 | padding-right: 15px
336 | }
337 |
338 | .container:before, .container:after {
339 | content: " ";
340 | display: table;
341 | }
342 |
343 | .container:after {
344 | clear: both
345 | }
346 |
347 | .row {
348 | margin-left: 15px;
349 | margin-right: 15px
350 | }
351 |
352 | .row:before, .row:after {
353 | content: " ";
354 | display: table;
355 | }
356 |
357 | .row:after {
358 | clear: both
359 | }
360 |
361 | .col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12 {
362 | position: relative;
363 | min-height: 1px;
364 | padding-left: 15px;
365 | padding-right: 15px;
366 | float: left
367 | }
368 |
369 | .col-1 {
370 | width: 8.333333333333332%
371 | }
372 |
373 | .col-2 {
374 | width: 16.666666666666664%
375 | }
376 |
377 | .col-3 {
378 | width: 25%
379 | }
380 |
381 | .col-4 {
382 | width: 33.33333333333333%
383 | }
384 |
385 | .col-5 {
386 | width: 41.66666666666667%
387 | }
388 |
389 | .col-6 {
390 | width: 50%
391 | }
392 |
393 | .col-7 {
394 | width: 58.333333333333336%
395 | }
396 |
397 | .col-8 {
398 | width: 66.66666666666666%
399 | }
400 |
401 | .col-9 {
402 | width: 75%
403 | }
404 |
405 | .col-10 {
406 | width: 83.33333333333334%
407 | }
408 |
409 | .col-11 {
410 | width: 91.66666666666666%
411 | }
412 |
413 | .col-12 {
414 | width: 100%
415 | }
416 |
417 | .offset-0 {
418 | margin-left: 0
419 | }
420 |
421 | .offset-1 {
422 | margin-left: 8.333333333333332%
423 | }
424 |
425 | .offset-2 {
426 | margin-left: 16.666666666666664%
427 | }
428 |
429 | .offset-3 {
430 | margin-left: 25%
431 | }
432 |
433 | .offset-4 {
434 | margin-left: 33.33333333333333%
435 | }
436 |
437 | .offset-5 {
438 | margin-left: 41.66666666666667%
439 | }
440 |
441 | .offset-6 {
442 | margin-left: 50%
443 | }
444 |
445 | .offset-7 {
446 | margin-left: 58.333333333333336%
447 | }
448 |
449 | .offset-8 {
450 | margin-left: 66.66666666666666%
451 | }
452 |
453 | .offset-9 {
454 | margin-left: 75%
455 | }
456 |
457 | .offset-10 {
458 | margin-left: 83.33333333333334%
459 | }
460 |
461 | .offset-11 {
462 | margin-left: 91.66666666666666%
463 | }
464 |
465 | @media (min-width:992px) {
466 | .container {
467 | max-width: 970px
468 | }
469 | }
470 |
471 | @media (min-width:1200px) {
472 | .container {
473 | max-width: 1170px
474 | }
475 | }
476 |
477 | table {
478 | max-width: 100%;
479 | border-collapse: collapse
480 | }
481 |
482 | table {
483 | margin: auto;
484 | margin-bottom: 22px
485 | }
486 |
487 | table tr>th, table tr>td {
488 | padding: 8px;
489 | line-height: 1.5;
490 | border-top: 1px solid #ddd
491 | }
492 |
493 | table thead>tr>th {
494 | vertical-align: bottom;
495 | border-bottom: 2px solid #ddd
496 | }
497 |
498 | table.condensed th, table.condensed td {
499 | padding: 5px
500 | }
501 |
502 | table.border {
503 | border: 1px solid #ddd
504 | }
505 |
506 | table.border th, table.border td {
507 | border: 1px solid #ddd
508 | }
509 |
510 | table.zebra>tbody>tr:nth-child(odd)>td, table.zebra>tbody>tr:nth-child(odd)>th {
511 | background-color: #f9f9f9
512 | }
513 |
514 | table.hover>tbody>tr:hover {
515 | background-color: #f5f5f5
516 | }
517 |
518 | legend {
519 | display: block;
520 | width: 100%;
521 | padding: 0;
522 | margin-bottom: 22px;
523 | font-size: 22.5px;
524 | line-height: inherit;
525 | color: #333;
526 | border: 0;
527 | border-bottom: 1px solid #e5e5e5
528 | }
529 |
530 | fieldset {
531 | border: 0
532 | }
533 |
534 | label {
535 | display: inline-block;
536 | margin-bottom: 5px;
537 | font-weight: bold
538 | }
539 |
540 | .control::-moz-placeholder {
541 | color: #999
542 | }
543 |
544 | .control:-ms-input-placeholder {
545 | color: #999
546 | }
547 |
548 | .control::-webkit-input-placeholder {
549 | color: #999
550 | }
551 |
552 | input.control, select.control, textarea.control {
553 | display: block;
554 | width: 100%;
555 | height: 36px;
556 | padding: 6px 12px;
557 | line-height: 1.5;
558 | color: #555;
559 | background-color: #fff;
560 | border: 1px solid #ccc;
561 | border-radius: 6px;
562 | -webkit-transition: all ease-in .4s;
563 | transition: all ease-in .4s
564 | }
565 |
566 | input.control:focus, select.control:focus, textarea.control:focus {
567 | border-color: #66afe9;
568 | outline: 0
569 | }
570 |
571 | input.control[disabled], select.control[disabled], textarea.control[disabled], input.control[readonly], select.control[readonly], textarea.control[readonly], fieldset[disabled] input.control, fieldset[disabled] select.control, fieldset[disabled] textarea.control {
572 | cursor: not-allowed;
573 | background-color: #eee
574 | }
575 |
576 | textareainput.control, textareaselect.control, textareatextarea.control {
577 | height: auto
578 | }
579 |
580 | @media (min-width:768px) {
581 | form.inline input.control, form.inline select.control, form.inline textarea.control, form.inline .form-group {
582 | display: inline-block
583 | }
584 | form.inline .form-group {
585 | display: inline-block;
586 | margin-bottom: 0;
587 | vertical-align: middle
588 | }
589 | form.inline .control {
590 | display: inline-block
591 | }
592 | }
593 |
594 | .form-group {
595 | margin-bottom: 15px
596 | }
597 |
598 | form.horizontal .form-group {
599 | margin-left: -15px;
600 | margin-right: -15px
601 | }
602 |
603 | form.horizontal .form-group:before, form.horizontal .form-group:after {
604 | content: " ";
605 | display: table;
606 | }
607 |
608 | form.horizontal .form-group:after {
609 | clear: both
610 | }
611 |
612 | .form-horizontal {
613 | padding-top: 6px
614 | }
615 |
616 | @media (min-width:768px) {
617 | form.horizontal .control-label {
618 | text-align: right
619 | }
620 | }
621 |
622 | .btn {
623 | display: inline-block;
624 | text-decoration: none;
625 | color: #fff;
626 | border-radius: 6px;
627 | border-width: 1px;
628 | line-height: 1.5;
629 | padding: 6px 12px;
630 | -webkit-box-shadow: 1px 1px 3px #555;
631 | box-shadow: 1px 1px 3px #555
632 | }
633 |
634 | .btn:hover {
635 | text-decoration: none;
636 | -webkit-box-shadow: 1px 2px 5px #777;
637 | box-shadow: 1px 2px 5px #777
638 | }
639 |
640 | .btn-default {
641 | color: #000;
642 | border-color: #ccc;
643 | border-bottom-color: #b3b3b3;
644 | background-repeat: repeat-x;
645 | background-image: -webkit-linear-gradient(45deg, #fff, #e6e6e6);
646 | background-image: -moz-linear-gradient(45deg, #fff, #e6e6e6);
647 | background-image: linear-gradient(45deg, #fff, #e6e6e6)
648 | }
649 |
650 | .btn-default:hover {
651 | background: #ccc
652 | }
653 |
654 | .btn-inverse {
655 | border-color: #222;
656 | border-bottom-color: #080808;
657 | background-repeat: repeat-x;
658 | background-image: -webkit-linear-gradient(45deg, #555, #3b3b3b);
659 | background-image: -moz-linear-gradient(45deg, #555, #3b3b3b);
660 | background-image: linear-gradient(45deg, #555, #3b3b3b)
661 | }
662 |
663 | .btn-inverse:hover {
664 | background: #222
665 | }
666 |
667 | .btn-danger {
668 | border-color: #a02622;
669 | border-bottom-color: #761c19;
670 | background-repeat: repeat-x;
671 | background-image: -webkit-linear-gradient(45deg, #d9534f, #c9302c);
672 | background-image: -moz-linear-gradient(45deg, #d9534f, #c9302c);
673 | background-image: linear-gradient(45deg, #d9534f, #c9302c)
674 | }
675 |
676 | .btn-danger:hover {
677 | background: #a02622
678 | }
679 |
680 | .btn-info {
681 | border-color: #2390b0;
682 | border-bottom-color: #1b6d85;
683 | background-repeat: repeat-x;
684 | background-image: -webkit-linear-gradient(45deg, #5bc0de, #31b0d5);
685 | background-image: -moz-linear-gradient(45deg, #5bc0de, #31b0d5);
686 | background-image: linear-gradient(45deg, #5bc0de, #31b0d5)
687 | }
688 |
689 | .btn-info:hover {
690 | background: #2390b0
691 | }
692 |
693 | .btn-success {
694 | border-color: #357935;
695 | border-bottom-color: #255625;
696 | background-repeat: repeat-x;
697 | background-image: -webkit-linear-gradient(45deg, #5cb85c, #449d44);
698 | background-image: -moz-linear-gradient(45deg, #5cb85c, #449d44);
699 | background-image: linear-gradient(45deg, #5cb85c, #449d44)
700 | }
701 |
702 | .btn-success:hover {
703 | background: #357935
704 | }
705 |
706 | .btn-primary {
707 | border-color: #245682;
708 | border-bottom-color: #193c5a;
709 | background-repeat: repeat-x;
710 | background-image: -webkit-linear-gradient(45deg, #428bca, #3071a9);
711 | background-image: -moz-linear-gradient(45deg, #428bca, #3071a9);
712 | background-image: linear-gradient(45deg, #428bca, #3071a9)
713 | }
714 |
715 | .btn-primary:hover {
716 | background: #245682
717 | }
718 |
719 | .btn-warning {
720 | border-color: #c77c11;
721 | border-bottom-color: #985f0d;
722 | background-repeat: repeat-x;
723 | background-image: -webkit-linear-gradient(45deg, #f0ad4e, #ec971f);
724 | background-image: -moz-linear-gradient(45deg, #f0ad4e, #ec971f);
725 | background-image: linear-gradient(45deg, #f0ad4e, #ec971f)
726 | }
727 |
728 | .btn-warning:hover {
729 | background: #c77c11
730 | }
731 |
732 | .btn-sm {
733 | font-size: .7em
734 | }
735 |
736 | .btn-lg {
737 | font-size: 1.2em
738 | }
739 |
740 | .btn-round {
741 | border-radius: 20px
742 | }
743 |
744 | .btn-active, .btn-active:hover, .btn.disabled, .btn[disabled], .btn-disabled, .btn-disabled:hover {
745 | opacity: 1;
746 | filter: alpha(opacity=100);
747 | background: #d1d1d1;
748 | border: 1px solid #b3b3b3;
749 | text-shadow: 0 1px 1px #fff
750 | }
751 |
752 | .btn.disabled, .btn[disabled] {
753 | color: #999
754 | }
755 |
756 | .hero {
757 | padding: 30px;
758 | margin-bottom: 30px;
759 | font-size: 22.5px;
760 | font-weight: 200;
761 | line-height: 2.25;
762 | color: #fff;
763 | background-color: #0ac;
764 | border-radius: 6px
765 | }
766 |
767 | .hero h1 {
768 | line-height: 1;
769 | color: inherit
770 | }
771 |
772 | .hero p {
773 | line-height: 1.4
774 | }
775 |
776 | @media screen and (min-width:768px) {
777 | .hero {
778 | padding-top: 50px;
779 | padding-bottom: 50px
780 | }
781 | .hero h1 {
782 | font-size: 67.5px
783 | }
784 | }
785 |
786 | .actions {
787 | border-top: dotted 1px grey;
788 | padding-top: 1em;
789 | margin: .5em 0 0;
790 | }
791 |
792 | label, input, textarea, select {
793 | display: block;
794 | }
795 |
796 | footer {
797 | padding-top: 1em;
798 | margin-top: 2em;
799 | border-top: 1px solid #ccc;
800 | }
801 |
802 |
--------------------------------------------------------------------------------
/public/css/koot.min.css:
--------------------------------------------------------------------------------
1 | @charset "UTF-8";
2 | /*! Koot 2024 */
3 | /*!
4 | * Pico CSS v1.5.11 (https://picocss.com)
5 | * Copyright 2019-2023 - Licensed under MIT
6 | */:root{--font-family:system-ui,-apple-system,"Segoe UI","Roboto","Ubuntu","Cantarell","Noto Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--line-height:1.5;--font-weight:400;--font-size:16px;--border-radius:0.25rem;--border-width:1px;--outline-width:3px;--spacing:1rem;--typography-spacing-vertical:1.5rem;--block-spacing-vertical:calc(var(--spacing)*2);--block-spacing-horizontal:var(--spacing);--grid-spacing-vertical:0;--grid-spacing-horizontal:var(--spacing);--form-element-spacing-vertical:0.75rem;--form-element-spacing-horizontal:1rem;--nav-element-spacing-vertical:1rem;--nav-element-spacing-horizontal:0.5rem;--nav-link-spacing-vertical:0.5rem;--nav-link-spacing-horizontal:0.5rem;--form-label-font-weight:var(--font-weight);--transition:0.2s ease-in-out;--modal-overlay-backdrop-filter:blur(0.25rem)}@media (min-width:576px){:root{--font-size:17px}}@media (min-width:768px){:root{--font-size:18px}}@media (min-width:992px){:root{--font-size:19px}}@media (min-width:1200px){:root{--font-size:20px}}@media (min-width:576px){body>footer,body>header,body>main,section{--block-spacing-vertical:calc(var(--spacing)*2.5)}}@media (min-width:768px){body>footer,body>header,body>main,section{--block-spacing-vertical:calc(var(--spacing)*3)}}@media (min-width:992px){body>footer,body>header,body>main,section{--block-spacing-vertical:calc(var(--spacing)*3.5)}}@media (min-width:1200px){body>footer,body>header,body>main,section{--block-spacing-vertical:calc(var(--spacing)*4)}}@media (min-width:576px){article{--block-spacing-horizontal:calc(var(--spacing)*1.25)}}@media (min-width:768px){article{--block-spacing-horizontal:calc(var(--spacing)*1.5)}}@media (min-width:992px){article{--block-spacing-horizontal:calc(var(--spacing)*1.75)}}@media (min-width:1200px){article{--block-spacing-horizontal:calc(var(--spacing)*2)}}dialog>article{--block-spacing-vertical:calc(var(--spacing)*2);--block-spacing-horizontal:var(--spacing)}@media (min-width:576px){dialog>article{--block-spacing-vertical:calc(var(--spacing)*2.5);--block-spacing-horizontal:calc(var(--spacing)*1.25)}}@media (min-width:768px){dialog>article{--block-spacing-vertical:calc(var(--spacing)*3);--block-spacing-horizontal:calc(var(--spacing)*1.5)}}a{--text-decoration:none}a.contrast,a.secondary{--text-decoration:underline}small{--font-size:0.875em}h1,h2,h3,h4,h5,h6{--font-weight:700}h1{--font-size:2rem;--typography-spacing-vertical:3rem}h2{--font-size:1.75rem;--typography-spacing-vertical:2.625rem}h3{--font-size:1.5rem;--typography-spacing-vertical:2.25rem}h4{--font-size:1.25rem;--typography-spacing-vertical:1.874rem}h5{--font-size:1.125rem;--typography-spacing-vertical:1.6875rem}[type=checkbox],[type=radio]{--border-width:2px}[type=checkbox][role=switch],tfoot td,tfoot th,thead td,thead th{--border-width:3px}:not(thead,tfoot)>*>td{--font-size:0.875em}code,kbd,pre,samp{--font-family:"Menlo","Consolas","Roboto Mono","Ubuntu Monospace","Noto Mono","Oxygen Mono","Liberation Mono",monospace,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji"}kbd{--font-weight:bolder}:root:not([data-theme=dark]),[data-theme=light]{--background-color:#fff;--color:#415462;--h1-color:#1b2832;--h2-color:#24333e;--h3-color:#2c3d49;--h4-color:#374956;--h5-color:#415462;--h6-color:#4d606d;--muted-color:#73828c;--muted-border-color:#edf0f3;--primary:#1095c1;--primary-hover:#08769b;--primary-focus:rgba(16,149,193,.125);--primary-inverse:#fff;--secondary:#596b78;--secondary-hover:#415462;--secondary-focus:rgba(89,107,120,.125);--secondary-inverse:#fff;--contrast:#1b2832;--contrast-hover:#000;--contrast-focus:rgba(89,107,120,.125);--contrast-inverse:#fff;--mark-background-color:#fff2ca;--mark-color:#543a26;--ins-color:#388e3c;--del-color:#c62828;--blockquote-border-color:var(--muted-border-color);--blockquote-footer-color:var(--muted-color);--button-box-shadow:0 0 0 transparent;--button-hover-box-shadow:0 0 0 transparent;--form-element-background-color:transparent;--form-element-border-color:#a2afb9;--form-element-color:var(--color);--form-element-placeholder-color:var(--muted-color);--form-element-active-background-color:transparent;--form-element-active-border-color:var(--primary);--form-element-focus-color:var(--primary-focus);--form-element-disabled-background-color:#d5dce2;--form-element-disabled-border-color:#a2afb9;--form-element-disabled-opacity:0.5;--form-element-invalid-border-color:#c62828;--form-element-invalid-active-border-color:#d32f2f;--form-element-invalid-focus-color:rgba(211,47,47,.125);--form-element-valid-border-color:#388e3c;--form-element-valid-active-border-color:#43a047;--form-element-valid-focus-color:rgba(67,160,71,.125);--switch-background-color:#bbc6ce;--switch-color:var(--primary-inverse);--switch-checked-background-color:var(--primary);--range-border-color:#d5dce2;--range-active-border-color:#bbc6ce;--range-thumb-border-color:var(--background-color);--range-thumb-color:var(--secondary);--range-thumb-hover-color:var(--secondary-hover);--range-thumb-active-color:var(--primary);--table-border-color:var(--muted-border-color);--table-row-stripped-background-color:#f6f8f9;--code-background-color:#edf0f3;--code-color:var(--muted-color);--code-kbd-background-color:var(--contrast);--code-kbd-color:var(--contrast-inverse);--code-tag-color:#b34d80;--code-property-color:#3d888f;--code-value-color:#986;--code-comment-color:#a2afb9;--accordion-border-color:var(--muted-border-color);--accordion-close-summary-color:var(--color);--accordion-open-summary-color:var(--muted-color);--card-background-color:var(--background-color);--card-border-color:var(--muted-border-color);--card-box-shadow:0.0145rem 0.029rem 0.174rem rgba(27,40,50,.017),0.0335rem 0.067rem 0.402rem rgba(27,40,50,.024),0.0625rem 0.125rem 0.75rem rgba(27,40,50,.03),0.1125rem 0.225rem 1.35rem rgba(27,40,50,.036),0.2085rem 0.417rem 2.502rem rgba(27,40,50,.043),0.5rem 1rem 6rem rgba(27,40,50,.06),0 0 0 0.0625rem rgba(27,40,50,.015);--card-sectionning-background-color:#fbfbfc;--dropdown-background-color:#fbfbfc;--dropdown-border-color:#e1e6eb;--dropdown-box-shadow:var(--card-box-shadow);--dropdown-color:var(--color);--dropdown-hover-background-color:#edf0f3;--modal-overlay-background-color:rgba(213,220,226,.7);--progress-background-color:#d5dce2;--progress-color:var(--primary);--loading-spinner-opacity:0.5;--tooltip-background-color:var(--contrast);--tooltip-color:var(--contrast-inverse);--icon-checkbox:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23FFF' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");--icon-chevron:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23415462' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");--icon-chevron-button:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23FFF' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");--icon-chevron-button-inverse:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23FFF' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");--icon-close:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%2373828C' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E");--icon-date:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23415462' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'/%3E%3Cpath d='M16 2v4M8 2v4M3 10h18'/%3E%3C/svg%3E");--icon-invalid:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23C62828' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 8v4M12 16h.01'/%3E%3C/svg%3E");--icon-minus:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23FFF' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3C/svg%3E");--icon-search:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23415462' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.35-4.35'/%3E%3C/svg%3E");--icon-time:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23415462' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 6v6l4 2'/%3E%3C/svg%3E");--icon-valid:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23388E3C' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");color-scheme:light}@media only screen and (prefers-color-scheme:dark){:root:not([data-theme]){--background-color:#11191f;--color:#bbc6ce;--h1-color:#edf0f3;--h2-color:#e1e6eb;--h3-color:#d5dce2;--h4-color:#c8d1d8;--h5-color:#bbc6ce;--h6-color:#afbbc4;--muted-color:#73828c;--muted-border-color:#1f2d38;--primary:#1095c1;--primary-hover:#1ab3e6;--primary-focus:rgba(16,149,193,.25);--primary-inverse:#fff;--secondary:#596b78;--secondary-hover:#73828c;--secondary-focus:rgba(115,130,140,.25);--secondary-inverse:#fff;--contrast:#edf0f3;--contrast-hover:#fff;--contrast-focus:rgba(115,130,140,.25);--contrast-inverse:#000;--mark-background-color:#d1c284;--mark-color:#11191f;--ins-color:#388e3c;--del-color:#c62828;--blockquote-border-color:var(--muted-border-color);--blockquote-footer-color:var(--muted-color);--button-box-shadow:0 0 0 transparent;--button-hover-box-shadow:0 0 0 transparent;--form-element-background-color:#11191f;--form-element-border-color:#374956;--form-element-color:var(--color);--form-element-placeholder-color:var(--muted-color);--form-element-active-background-color:var(--form-element-background-color);--form-element-active-border-color:var(--primary);--form-element-focus-color:var(--primary-focus);--form-element-disabled-background-color:#2c3d49;--form-element-disabled-border-color:#415462;--form-element-disabled-opacity:0.5;--form-element-invalid-border-color:#b71c1c;--form-element-invalid-active-border-color:#c62828;--form-element-invalid-focus-color:rgba(198,40,40,.25);--form-element-valid-border-color:#2e7d32;--form-element-valid-active-border-color:#388e3c;--form-element-valid-focus-color:rgba(56,142,60,.25);--switch-background-color:#374956;--switch-color:var(--primary-inverse);--switch-checked-background-color:var(--primary);--range-border-color:#24333e;--range-active-border-color:#2c3d49;--range-thumb-border-color:var(--background-color);--range-thumb-color:var(--secondary);--range-thumb-hover-color:var(--secondary-hover);--range-thumb-active-color:var(--primary);--table-border-color:var(--muted-border-color);--table-row-stripped-background-color:rgba(115,130,140,.05);--code-background-color:#18232c;--code-color:var(--muted-color);--code-kbd-background-color:var(--contrast);--code-kbd-color:var(--contrast-inverse);--code-tag-color:#a65980;--code-property-color:#599fa6;--code-value-color:#8c8473;--code-comment-color:#4d606d;--accordion-border-color:var(--muted-border-color);--accordion-active-summary-color:var(--primary);--accordion-close-summary-color:var(--color);--accordion-open-summary-color:var(--muted-color);--card-background-color:#141e26;--card-border-color:var(--card-background-color);--card-box-shadow:0.0145rem 0.029rem 0.174rem rgba(0,0,0,.017),0.0335rem 0.067rem 0.402rem rgba(0,0,0,.024),0.0625rem 0.125rem 0.75rem rgba(0,0,0,.03),0.1125rem 0.225rem 1.35rem rgba(0,0,0,.036),0.2085rem 0.417rem 2.502rem rgba(0,0,0,.043),0.5rem 1rem 6rem rgba(0,0,0,.06),0 0 0 0.0625rem rgba(0,0,0,.015);--card-sectionning-background-color:#18232c;--dropdown-background-color:#1b2832;--dropdown-border-color:#24333e;--dropdown-box-shadow:var(--card-box-shadow);--dropdown-color:var(--color);--dropdown-hover-background-color:rgba(36,51,62,.75);--modal-overlay-background-color:rgba(36,51,62,.8);--progress-background-color:#24333e;--progress-color:var(--primary);--loading-spinner-opacity:0.5;--tooltip-background-color:var(--contrast);--tooltip-color:var(--contrast-inverse);--icon-checkbox:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23FFF' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");--icon-chevron:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23A2AFB9' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");--icon-chevron-button:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23FFF' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");--icon-chevron-button-inverse:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");--icon-close:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%2373828C' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E");--icon-date:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23A2AFB9' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'/%3E%3Cpath d='M16 2v4M8 2v4M3 10h18'/%3E%3C/svg%3E");--icon-invalid:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23B71C1C' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 8v4M12 16h.01'/%3E%3C/svg%3E");--icon-minus:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23FFF' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3C/svg%3E");--icon-search:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23A2AFB9' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.35-4.35'/%3E%3C/svg%3E");--icon-time:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23A2AFB9' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 6v6l4 2'/%3E%3C/svg%3E");--icon-valid:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%232E7D32' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");color-scheme:dark}}[data-theme=dark]{--background-color:#11191f;--color:#bbc6ce;--h1-color:#edf0f3;--h2-color:#e1e6eb;--h3-color:#d5dce2;--h4-color:#c8d1d8;--h5-color:#bbc6ce;--h6-color:#afbbc4;--muted-color:#73828c;--muted-border-color:#1f2d38;--primary:#1095c1;--primary-hover:#1ab3e6;--primary-focus:rgba(16,149,193,.25);--primary-inverse:#fff;--secondary:#596b78;--secondary-hover:#73828c;--secondary-focus:rgba(115,130,140,.25);--secondary-inverse:#fff;--contrast:#edf0f3;--contrast-hover:#fff;--contrast-focus:rgba(115,130,140,.25);--contrast-inverse:#000;--mark-background-color:#d1c284;--mark-color:#11191f;--ins-color:#388e3c;--del-color:#c62828;--blockquote-border-color:var(--muted-border-color);--blockquote-footer-color:var(--muted-color);--button-box-shadow:0 0 0 transparent;--button-hover-box-shadow:0 0 0 transparent;--form-element-background-color:#11191f;--form-element-border-color:#374956;--form-element-color:var(--color);--form-element-placeholder-color:var(--muted-color);--form-element-active-background-color:var(--form-element-background-color);--form-element-active-border-color:var(--primary);--form-element-focus-color:var(--primary-focus);--form-element-disabled-background-color:#2c3d49;--form-element-disabled-border-color:#415462;--form-element-disabled-opacity:0.5;--form-element-invalid-border-color:#b71c1c;--form-element-invalid-active-border-color:#c62828;--form-element-invalid-focus-color:rgba(198,40,40,.25);--form-element-valid-border-color:#2e7d32;--form-element-valid-active-border-color:#388e3c;--form-element-valid-focus-color:rgba(56,142,60,.25);--switch-background-color:#374956;--switch-color:var(--primary-inverse);--switch-checked-background-color:var(--primary);--range-border-color:#24333e;--range-active-border-color:#2c3d49;--range-thumb-border-color:var(--background-color);--range-thumb-color:var(--secondary);--range-thumb-hover-color:var(--secondary-hover);--range-thumb-active-color:var(--primary);--table-border-color:var(--muted-border-color);--table-row-stripped-background-color:rgba(115,130,140,.05);--code-background-color:#18232c;--code-color:var(--muted-color);--code-kbd-background-color:var(--contrast);--code-kbd-color:var(--contrast-inverse);--code-tag-color:#a65980;--code-property-color:#599fa6;--code-value-color:#8c8473;--code-comment-color:#4d606d;--accordion-border-color:var(--muted-border-color);--accordion-active-summary-color:var(--primary);--accordion-close-summary-color:var(--color);--accordion-open-summary-color:var(--muted-color);--card-background-color:#141e26;--card-border-color:var(--card-background-color);--card-box-shadow:0.0145rem 0.029rem 0.174rem rgba(0,0,0,.017),0.0335rem 0.067rem 0.402rem rgba(0,0,0,.024),0.0625rem 0.125rem 0.75rem rgba(0,0,0,.03),0.1125rem 0.225rem 1.35rem rgba(0,0,0,.036),0.2085rem 0.417rem 2.502rem rgba(0,0,0,.043),0.5rem 1rem 6rem rgba(0,0,0,.06),0 0 0 0.0625rem rgba(0,0,0,.015);--card-sectionning-background-color:#18232c;--dropdown-background-color:#1b2832;--dropdown-border-color:#24333e;--dropdown-box-shadow:var(--card-box-shadow);--dropdown-color:var(--color);--dropdown-hover-background-color:rgba(36,51,62,.75);--modal-overlay-background-color:rgba(36,51,62,.8);--progress-background-color:#24333e;--progress-color:var(--primary);--loading-spinner-opacity:0.5;--tooltip-background-color:var(--contrast);--tooltip-color:var(--contrast-inverse);--icon-checkbox:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23FFF' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");--icon-chevron:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23A2AFB9' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");--icon-chevron-button:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23FFF' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");--icon-chevron-button-inverse:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23000' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");--icon-close:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%2373828C' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M18 6 6 18M6 6l12 12'/%3E%3C/svg%3E");--icon-date:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23A2AFB9' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2' ry='2'/%3E%3Cpath d='M16 2v4M8 2v4M3 10h18'/%3E%3C/svg%3E");--icon-invalid:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23B71C1C' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 8v4M12 16h.01'/%3E%3C/svg%3E");--icon-minus:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23FFF' stroke-width='4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 12h14'/%3E%3C/svg%3E");--icon-search:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23A2AFB9' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='11' cy='11' r='8'/%3E%3Cpath d='m21 21-4.35-4.35'/%3E%3C/svg%3E");--icon-time:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%23A2AFB9' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Ccircle cx='12' cy='12' r='10'/%3E%3Cpath d='M12 6v6l4 2'/%3E%3C/svg%3E");--icon-valid:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' fill='none' stroke='%232E7D32' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");color-scheme:dark}[type=checkbox],[type=radio],[type=range],progress{accent-color:var(--primary)}*,:after,:before{background-repeat:no-repeat;box-sizing:border-box}:after,:before{text-decoration:inherit;vertical-align:inherit}:where(:root){-webkit-tap-highlight-color:transparent;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;text-size-adjust:100%;background-color:var(--background-color);color:var(--color);cursor:default;font-family:var(--font-family);font-size:var(--font-size);font-weight:var(--font-weight);line-height:var(--line-height);overflow-wrap:break-word;-moz-tab-size:4;-o-tab-size:4;tab-size:4;text-rendering:optimizeLegibility}main{display:block}body{margin:0;width:100%}body>footer,body>header,body>main{margin-left:auto;margin-right:auto;padding:var(--block-spacing-vertical) 0;width:100%}.container,.container-fluid{margin-left:auto;margin-right:auto;padding-left:var(--spacing);padding-right:var(--spacing);width:100%}@media (min-width:576px){.container{max-width:510px;padding-left:0;padding-right:0}}@media (min-width:768px){.container{max-width:700px}}@media (min-width:992px){.container{max-width:920px}}@media (min-width:1200px){.container{max-width:1130px}}section{margin-bottom:var(--block-spacing-vertical)}.grid{grid-column-gap:var(--grid-spacing-horizontal);grid-row-gap:var(--grid-spacing-vertical);display:grid;grid-template-columns:1fr;margin:0}@media (min-width:992px){.grid{grid-template-columns:repeat(auto-fit,minmax(0,1fr))}}.grid>*{min-width:0}figure{display:block;margin:0;overflow-x:auto;padding:0}figure figcaption{color:var(--muted-color);padding:calc(var(--spacing)*.5) 0}b,strong{font-weight:bolder}sub,sup{font-size:.75em;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}address,blockquote,dl,figure,form,ol,p,pre,table,ul{color:var(--color);font-size:var(--font-size);font-style:normal;font-weight:var(--font-weight);margin-bottom:var(--typography-spacing-vertical);margin-top:0}[role=link],a{--color:var(--primary);--background-color:transparent;background-color:var(--background-color);color:var(--color);outline:none;-webkit-text-decoration:var(--text-decoration);text-decoration:var(--text-decoration);transition:background-color var(--transition),color var(--transition),box-shadow var(--transition),-webkit-text-decoration var(--transition);transition:background-color var(--transition),color var(--transition),text-decoration var(--transition),box-shadow var(--transition);transition:background-color var(--transition),color var(--transition),text-decoration var(--transition),box-shadow var(--transition),-webkit-text-decoration var(--transition)}[role=link]:is([aria-current],:hover,:active,:focus),a:is([aria-current],:hover,:active,:focus){--color:var(--primary-hover);--text-decoration:underline}[role=link]:focus,a:focus{--background-color:var(--primary-focus)}[role=link].secondary,a.secondary{--color:var(--secondary)}[role=link].secondary:is([aria-current],:hover,:active,:focus),a.secondary:is([aria-current],:hover,:active,:focus){--color:var(--secondary-hover)}[role=link].secondary:focus,a.secondary:focus{--background-color:var(--secondary-focus)}[role=link].contrast,a.contrast{--color:var(--contrast)}[role=link].contrast:is([aria-current],:hover,:active,:focus),a.contrast:is([aria-current],:hover,:active,:focus){--color:var(--contrast-hover)}[role=link].contrast:focus,a.contrast:focus{--background-color:var(--contrast-focus)}h1,h2,h3,h4,h5,h6{color:var(--color);font-family:var(--font-family);font-size:var(--font-size);font-weight:var(--font-weight);margin-bottom:var(--typography-spacing-vertical);margin-top:0}h1{--color:var(--h1-color)}h2{--color:var(--h2-color)}h3{--color:var(--h3-color)}h4{--color:var(--h4-color)}h5{--color:var(--h5-color)}h6{--color:var(--h6-color)}:where(address,blockquote,dl,figure,form,ol,p,pre,table,ul)~:is(h1,h2,h3,h4,h5,h6){margin-top:var(--typography-spacing-vertical)}.headings,hgroup{margin-bottom:var(--typography-spacing-vertical)}.headings>*,hgroup>*{margin-bottom:0}.headings>:last-child,hgroup>:last-child{--color:var(--muted-color);--font-weight:unset;font-family:unset;font-size:1rem}p{margin-bottom:var(--typography-spacing-vertical)}small{font-size:var(--font-size)}:where(dl,ol,ul){padding-left:var(--spacing);padding-right:0;padding-inline-end:0;padding-inline-start:var(--spacing)}:where(dl,ol,ul) li{margin-bottom:calc(var(--typography-spacing-vertical)*.25)}:where(dl,ol,ul) :is(dl,ol,ul){margin:0;margin-top:calc(var(--typography-spacing-vertical)*.25)}ul li{list-style:square}mark{background-color:var(--mark-background-color);color:var(--mark-color);padding:.125rem .25rem;vertical-align:baseline}blockquote{border-inline-end:none;border-inline-start:.25rem solid var(--blockquote-border-color);border-left:.25rem solid var(--blockquote-border-color);border-right:none;display:block;margin:var(--typography-spacing-vertical) 0;padding:var(--spacing)}blockquote footer{color:var(--blockquote-footer-color);margin-top:calc(var(--typography-spacing-vertical)*.5)}abbr[title]{border-bottom:1px dotted;cursor:help}abbr[title],ins{text-decoration:none}ins{color:var(--ins-color)}del{color:var(--del-color)}::-moz-selection{background-color:var(--primary-focus)}::selection{background-color:var(--primary-focus)}:where(audio,canvas,iframe,img,svg,video){vertical-align:middle}audio,video{display:inline-block}audio:not([controls]){display:none;height:0}:where(iframe){border-style:none}img{border-style:none;height:auto;max-width:100%}:where(svg:not([fill])){fill:currentColor}svg:not(:root){overflow:hidden}button{font-family:inherit;margin:0;overflow:visible;text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}button{display:block;margin-bottom:var(--spacing);width:100%}[role=button]{display:inline-block;text-decoration:none}[role=button],button,input[type=button],input[type=reset],input[type=submit]{--background-color:var(--primary);--border-color:var(--primary);--color:var(--primary-inverse);--box-shadow:var(--button-box-shadow,0 0 0 transparent);background-color:var(--background-color);border:var(--border-width) solid var(--border-color);border-radius:var(--border-radius);box-shadow:var(--box-shadow);color:var(--color);cursor:pointer;font-size:1rem;font-weight:var(--font-weight);line-height:var(--line-height);outline:none;padding:var(--form-element-spacing-vertical) var(--form-element-spacing-horizontal);text-align:center;transition:background-color var(--transition),border-color var(--transition),color var(--transition),box-shadow var(--transition)}[role=button]:is([aria-current],:hover,:active,:focus),button:is([aria-current],:hover,:active,:focus),input[type=button]:is([aria-current],:hover,:active,:focus),input[type=reset]:is([aria-current],:hover,:active,:focus),input[type=submit]:is([aria-current],:hover,:active,:focus){--background-color:var(--primary-hover);--border-color:var(--primary-hover);--box-shadow:var(--button-hover-box-shadow,0 0 0 transparent);--color:var(--primary-inverse)}[role=button]:focus,button:focus,input[type=button]:focus,input[type=reset]:focus,input[type=submit]:focus{--box-shadow:var(--button-hover-box-shadow,0 0 0 transparent),0 0 0 var(--outline-width) var(--primary-focus)}:is(button,input[type=submit],input[type=button],[role=button]).secondary,input[type=reset]{--background-color:var(--secondary);--border-color:var(--secondary);--color:var(--secondary-inverse);cursor:pointer}:is(button,input[type=submit],input[type=button],[role=button]).secondary:is([aria-current],:hover,:active,:focus),input[type=reset]:is([aria-current],:hover,:active,:focus){--background-color:var(--secondary-hover);--border-color:var(--secondary-hover);--color:var(--secondary-inverse)}:is(button,input[type=submit],input[type=button],[role=button]).secondary:focus,input[type=reset]:focus{--box-shadow:var(--button-hover-box-shadow,0 0 0 transparent),0 0 0 var(--outline-width) var(--secondary-focus)}:is(button,input[type=submit],input[type=button],[role=button]).contrast{--background-color:var(--contrast);--border-color:var(--contrast);--color:var(--contrast-inverse)}:is(button,input[type=submit],input[type=button],[role=button]).contrast:is([aria-current],:hover,:active,:focus){--background-color:var(--contrast-hover);--border-color:var(--contrast-hover);--color:var(--contrast-inverse)}:is(button,input[type=submit],input[type=button],[role=button]).contrast:focus{--box-shadow:var(--button-hover-box-shadow,0 0 0 transparent),0 0 0 var(--outline-width) var(--contrast-focus)}:is(button,input[type=submit],input[type=button],[role=button]).outline,input[type=reset].outline{--background-color:transparent;--color:var(--primary)}:is(button,input[type=submit],input[type=button],[role=button]).outline:is([aria-current],:hover,:active,:focus),input[type=reset].outline:is([aria-current],:hover,:active,:focus){--background-color:transparent;--color:var(--primary-hover)}:is(button,input[type=submit],input[type=button],[role=button]).outline.secondary,input[type=reset].outline{--color:var(--secondary)}:is(button,input[type=submit],input[type=button],[role=button]).outline.secondary:is([aria-current],:hover,:active,:focus),input[type=reset].outline:is([aria-current],:hover,:active,:focus){--color:var(--secondary-hover)}:is(button,input[type=submit],input[type=button],[role=button]).outline.contrast{--color:var(--contrast)}:is(button,input[type=submit],input[type=button],[role=button]).outline.contrast:is([aria-current],:hover,:active,:focus){--color:var(--contrast-hover)}:where(button,[type=submit],[type=button],[type=reset],[role=button])[disabled],:where(fieldset[disabled]) :is(button,[type=submit],[type=button],[type=reset],[role=button]),a[role=button]:not([href]){opacity:.5;pointer-events:none}input,optgroup,select,textarea{font-family:inherit;font-size:1rem;letter-spacing:inherit;line-height:var(--line-height);margin:0}input{overflow:visible}select{text-transform:none}legend{color:inherit;max-width:100%;padding:0;white-space:normal}textarea{overflow:auto}[type=checkbox],[type=radio]{padding:0}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}::-moz-focus-inner{border-style:none;padding:0}:-moz-focusring{outline:none}:-moz-ui-invalid{box-shadow:none}::-ms-expand{display:none}[type=file],[type=range]{border-width:0;padding:0}input:not([type=checkbox],[type=radio],[type=range]){height:calc(1rem*var(--line-height) + var(--form-element-spacing-vertical)*2 + var(--border-width)*2)}fieldset{border:0;margin:0;margin-bottom:var(--spacing);padding:0}fieldset legend,label{display:block;font-weight:var(--form-label-font-weight,var(--font-weight));margin-bottom:calc(var(--spacing)*.25)}input:not([type=checkbox],[type=radio]),select,textarea{width:100%}input:not([type=checkbox],[type=radio],[type=range],[type=file]),select,textarea{-webkit-appearance:none;-moz-appearance:none;appearance:none;padding:var(--form-element-spacing-vertical) var(--form-element-spacing-horizontal)}input,select,textarea{--background-color:var(--form-element-background-color);--border-color:var(--form-element-border-color);--color:var(--form-element-color);--box-shadow:none;background-color:var(--background-color);border:var(--border-width) solid var(--border-color);border-radius:var(--border-radius);box-shadow:var(--box-shadow);color:var(--color);font-weight:var(--font-weight);outline:none;transition:background-color var(--transition),border-color var(--transition),color var(--transition),box-shadow var(--transition)}:where(select,textarea):is(:active,:focus),input:not([type=submit],[type=button],[type=reset],[type=checkbox],[type=radio],[readonly]):is(:active,:focus){--background-color:var(--form-element-active-background-color)}:where(select,textarea):is(:active,:focus),input:not([type=submit],[type=button],[type=reset],[role=switch],[readonly]):is(:active,:focus){--border-color:var(--form-element-active-border-color)}input:not([type=submit],[type=button],[type=reset],[type=range],[type=file],[readonly]):focus,select:focus,textarea:focus{--box-shadow:0 0 0 var(--outline-width) var(--form-element-focus-color)}:where(fieldset[disabled]) :is(input:not([type=submit],[type=button],[type=reset]),select,textarea),input:not([type=submit],[type=button],[type=reset])[disabled],select[disabled],textarea[disabled]{--background-color:var(--form-element-disabled-background-color);--border-color:var(--form-element-disabled-border-color);opacity:var(--form-element-disabled-opacity);pointer-events:none}:where(input,select,textarea):not([type=checkbox],[type=radio],[type=date],[type=datetime-local],[type=month],[type=time],[type=week])[aria-invalid]{background-position:center right .75rem;background-repeat:no-repeat;background-size:1rem auto;padding-left:var(--form-element-spacing-horizontal);padding-right:calc(var(--form-element-spacing-horizontal) + 1.5rem)!important;padding-inline-end:calc(var(--form-element-spacing-horizontal) + 1.5rem)!important;padding-inline-start:var(--form-element-spacing-horizontal)!important}:where(input,select,textarea):not([type=checkbox],[type=radio],[type=date],[type=datetime-local],[type=month],[type=time],[type=week])[aria-invalid=false]{background-image:var(--icon-valid)}:where(input,select,textarea):not([type=checkbox],[type=radio],[type=date],[type=datetime-local],[type=month],[type=time],[type=week])[aria-invalid=true]{background-image:var(--icon-invalid)}:where(input,select,textarea)[aria-invalid=false]{--border-color:var(--form-element-valid-border-color)}:where(input,select,textarea)[aria-invalid=false]:is(:active,:focus){--border-color:var(--form-element-valid-active-border-color)!important;--box-shadow:0 0 0 var(--outline-width) var(--form-element-valid-focus-color)!important}:where(input,select,textarea)[aria-invalid=true]{--border-color:var(--form-element-invalid-border-color)}:where(input,select,textarea)[aria-invalid=true]:is(:active,:focus){--border-color:var(--form-element-invalid-active-border-color)!important;--box-shadow:0 0 0 var(--outline-width) var(--form-element-invalid-focus-color)!important}[dir=rtl] :where(input,select,textarea):not([type=checkbox],[type=radio]):is([aria-invalid],[aria-invalid=true],[aria-invalid=false]){background-position:center left .75rem}input::-webkit-input-placeholder,input::placeholder,select:invalid,textarea::-webkit-input-placeholder,textarea::placeholder{color:var(--form-element-placeholder-color);opacity:1}input:not([type=checkbox],[type=radio]),select,textarea{margin-bottom:var(--spacing)}select::-ms-expand{background-color:transparent;border:0}select:not([multiple],[size]){background-image:var(--icon-chevron);background-position:center right .75rem;background-repeat:no-repeat;background-size:1rem auto;padding-left:var(--form-element-spacing-horizontal);padding-right:calc(var(--form-element-spacing-horizontal) + 1.5rem);padding-inline-end:calc(var(--form-element-spacing-horizontal) + 1.5rem);padding-inline-start:var(--form-element-spacing-horizontal)}[dir=rtl] select:not([multiple],[size]){background-position:center left .75rem}:where(input,select,textarea,.grid)+small{color:var(--muted-color);display:block;margin-bottom:var(--spacing);margin-top:calc(var(--spacing)*-.75);width:100%}label>:where(input,select,textarea){margin-top:calc(var(--spacing)*.25)}[type=checkbox],[type=radio]{-webkit-appearance:none;-moz-appearance:none;appearance:none;border-width:var(--border-width);cursor:pointer;font-size:inherit;height:1.25em;margin-left:0;margin-right:.375em;margin-top:-.125em;margin-inline-end:.375em;margin-inline-start:0;vertical-align:middle;width:1.25em}[type=checkbox]::-ms-check,[type=radio]::-ms-check{display:none}[type=checkbox]:checked,[type=checkbox]:checked:active,[type=checkbox]:checked:focus,[type=radio]:checked,[type=radio]:checked:active,[type=radio]:checked:focus{--background-color:var(--primary);--border-color:var(--primary);background-image:var(--icon-checkbox);background-position:50%;background-repeat:no-repeat;background-size:.75em auto}[type=checkbox]~label,[type=radio]~label{cursor:pointer;display:inline-block;margin-bottom:0;margin-right:.375em}[type=checkbox]:indeterminate{--background-color:var(--primary);--border-color:var(--primary);background-image:var(--icon-minus);background-position:50%;background-repeat:no-repeat;background-size:.75em auto}[type=radio]{border-radius:50%}[type=radio]:checked,[type=radio]:checked:active,[type=radio]:checked:focus{--background-color:var(--primary-inverse);background-image:none;border-width:.35em}[type=checkbox][role=switch]{--background-color:var(--switch-background-color);--border-color:var(--switch-background-color);--color:var(--switch-color);background-color:var(--background-color);border:var(--border-width) solid var(--border-color);border-radius:1.25em;height:1.25em;line-height:1.25em;width:2.25em}[type=checkbox][role=switch]:focus{--background-color:var(--switch-background-color);--border-color:var(--switch-background-color)}[type=checkbox][role=switch]:checked{--background-color:var(--switch-checked-background-color);--border-color:var(--switch-checked-background-color)}[type=checkbox][role=switch]:before{background-color:var(--color);border-radius:50%;content:"";display:block;height:100%;transition:margin .1s ease-in-out;width:calc(1.25em - var(--border-width)*2)}[type=checkbox][role=switch]:checked{background-image:none}[type=checkbox][role=switch]:checked:before{margin-left:calc(1.125em - var(--border-width));margin-inline-start:calc(1.125em - var(--border-width))}[type=checkbox]:checked[aria-invalid=false],[type=checkbox][aria-invalid=false],[type=checkbox][role=switch]:checked[aria-invalid=false],[type=checkbox][role=switch][aria-invalid=false],[type=radio]:checked[aria-invalid=false],[type=radio][aria-invalid=false]{--border-color:var(--form-element-valid-border-color)}[type=checkbox]:checked[aria-invalid=true],[type=checkbox][aria-invalid=true],[type=checkbox][role=switch]:checked[aria-invalid=true],[type=checkbox][role=switch][aria-invalid=true],[type=radio]:checked[aria-invalid=true],[type=radio][aria-invalid=true]{--border-color:var(--form-element-invalid-border-color)}[type=color]::-webkit-color-swatch-wrapper{padding:0}[type=color]::-moz-focus-inner{padding:0}[type=color]::-webkit-color-swatch{border:0;border-radius:calc(var(--border-radius)*.5)}[type=color]::-moz-color-swatch{border:0;border-radius:calc(var(--border-radius)*.5)}input:not([type=checkbox],[type=radio],[type=range],[type=file]):is([type=date],[type=datetime-local],[type=month],[type=time],[type=week]){--icon-position:0.75rem;--icon-width:1rem;background-image:var(--icon-date);background-position:center right var(--icon-position);background-repeat:no-repeat;background-size:var(--icon-width) auto;padding-right:calc(var(--icon-width) + var(--icon-position))}input:not([type=checkbox],[type=radio],[type=range],[type=file])[type=time]{background-image:var(--icon-time)}[type=date]::-webkit-calendar-picker-indicator,[type=datetime-local]::-webkit-calendar-picker-indicator,[type=month]::-webkit-calendar-picker-indicator,[type=time]::-webkit-calendar-picker-indicator,[type=week]::-webkit-calendar-picker-indicator{margin-left:var(--icon-position);margin-right:calc(var(--icon-width)*-1);opacity:0;width:var(--icon-width)}[dir=rtl] :is([type=date],[type=datetime-local],[type=month],[type=time],[type=week]){text-align:right}@-moz-document url-prefix(){[type=date],[type=datetime-local],[type=month],[type=time],[type=week]{background-image:none!important;padding-right:var(--form-element-spacing-horizontal)!important}}[type=file]{--color:var(--muted-color);background:none;border:0;border-radius:0;padding:calc(var(--form-element-spacing-vertical)*.5) 0}[type=file]::file-selector-button{--background-color:var(--secondary);--border-color:var(--secondary);--color:var(--secondary-inverse);background-color:var(--background-color);border:var(--border-width) solid var(--border-color);border-radius:var(--border-radius);box-shadow:var(--box-shadow);color:var(--color);cursor:pointer;font-size:1rem;font-weight:var(--font-weight);line-height:var(--line-height);margin-left:0;margin-right:calc(var(--spacing)/2);margin-inline-end:calc(var(--spacing)/2);margin-inline-start:0;outline:none;padding:calc(var(--form-element-spacing-vertical)*.5) calc(var(--form-element-spacing-horizontal)*.5);text-align:center;transition:background-color var(--transition),border-color var(--transition),color var(--transition),box-shadow var(--transition)}[type=file]::file-selector-button:is(:hover,:active,:focus){--background-color:var(--secondary-hover);--border-color:var(--secondary-hover)}[type=file]::-webkit-file-upload-button{--background-color:var(--secondary);--border-color:var(--secondary);--color:var(--secondary-inverse);background-color:var(--background-color);border:var(--border-width) solid var(--border-color);border-radius:var(--border-radius);box-shadow:var(--box-shadow);color:var(--color);cursor:pointer;font-size:1rem;font-weight:var(--font-weight);line-height:var(--line-height);margin-left:0;margin-right:calc(var(--spacing)/2);margin-inline-end:calc(var(--spacing)/2);margin-inline-start:0;outline:none;padding:calc(var(--form-element-spacing-vertical)*.5) calc(var(--form-element-spacing-horizontal)*.5);text-align:center;-webkit-transition:background-color var(--transition),border-color var(--transition),color var(--transition),box-shadow var(--transition);transition:background-color var(--transition),border-color var(--transition),color var(--transition),box-shadow var(--transition)}[type=file]::-webkit-file-upload-button:is(:hover,:active,:focus){--background-color:var(--secondary-hover);--border-color:var(--secondary-hover)}[type=file]::-ms-browse{--background-color:var(--secondary);--border-color:var(--secondary);--color:var(--secondary-inverse);background-color:var(--background-color);border:var(--border-width) solid var(--border-color);border-radius:var(--border-radius);box-shadow:var(--box-shadow);color:var(--color);cursor:pointer;font-size:1rem;font-weight:var(--font-weight);line-height:var(--line-height);margin-left:0;margin-right:calc(var(--spacing)/2);margin-inline-end:calc(var(--spacing)/2);margin-inline-start:0;outline:none;padding:calc(var(--form-element-spacing-vertical)*.5) calc(var(--form-element-spacing-horizontal)*.5);text-align:center;-ms-transition:background-color var(--transition),border-color var(--transition),color var(--transition),box-shadow var(--transition);transition:background-color var(--transition),border-color var(--transition),color var(--transition),box-shadow var(--transition)}[type=file]::-ms-browse:is(:hover,:active,:focus){--background-color:var(--secondary-hover);--border-color:var(--secondary-hover)}[type=range]{-webkit-appearance:none;-moz-appearance:none;appearance:none;background:none;height:1.25rem;width:100%}[type=range]::-webkit-slider-runnable-track{background-color:var(--range-border-color);border-radius:var(--border-radius);height:.25rem;-webkit-transition:background-color var(--transition),box-shadow var(--transition);transition:background-color var(--transition),box-shadow var(--transition);width:100%}[type=range]::-moz-range-track{background-color:var(--range-border-color);border-radius:var(--border-radius);height:.25rem;-moz-transition:background-color var(--transition),box-shadow var(--transition);transition:background-color var(--transition),box-shadow var(--transition);width:100%}[type=range]::-ms-track{background-color:var(--range-border-color);border-radius:var(--border-radius);height:.25rem;-ms-transition:background-color var(--transition),box-shadow var(--transition);transition:background-color var(--transition),box-shadow var(--transition);width:100%}[type=range]::-webkit-slider-thumb{-webkit-appearance:none;background-color:var(--range-thumb-color);border:2px solid var(--range-thumb-border-color);border-radius:50%;cursor:pointer;height:1.25rem;margin-top:-.5rem;-webkit-transition:background-color var(--transition),transform var(--transition);transition:background-color var(--transition),transform var(--transition);width:1.25rem}[type=range]::-moz-range-thumb{-webkit-appearance:none;background-color:var(--range-thumb-color);border:2px solid var(--range-thumb-border-color);border-radius:50%;cursor:pointer;height:1.25rem;margin-top:-.5rem;-moz-transition:background-color var(--transition),transform var(--transition);transition:background-color var(--transition),transform var(--transition);width:1.25rem}[type=range]::-ms-thumb{-webkit-appearance:none;background-color:var(--range-thumb-color);border:2px solid var(--range-thumb-border-color);border-radius:50%;cursor:pointer;height:1.25rem;margin-top:-.5rem;-ms-transition:background-color var(--transition),transform var(--transition);transition:background-color var(--transition),transform var(--transition);width:1.25rem}[type=range]:focus,[type=range]:hover{--range-border-color:var(--range-active-border-color);--range-thumb-color:var(--range-thumb-hover-color)}[type=range]:active{--range-thumb-color:var(--range-thumb-active-color)}[type=range]:active::-webkit-slider-thumb{transform:scale(1.25)}[type=range]:active::-moz-range-thumb{transform:scale(1.25)}[type=range]:active::-ms-thumb{transform:scale(1.25)}input:not([type=checkbox],[type=radio],[type=range],[type=file])[type=search]{background-image:var(--icon-search);background-position:center left 1.125rem;background-repeat:no-repeat;background-size:1rem auto;border-radius:5rem;padding-inline-start:calc(var(--form-element-spacing-horizontal) + 1.75rem)}input:not([type=checkbox],[type=radio],[type=range],[type=file])[type=search][aria-invalid]{background-position:center left 1.125rem,center right .75rem;padding-inline-start:calc(var(--form-element-spacing-horizontal) + 1.75rem)!important}input:not([type=checkbox],[type=radio],[type=range],[type=file])[type=search][aria-invalid=false]{background-image:var(--icon-search),var(--icon-valid)}input:not([type=checkbox],[type=radio],[type=range],[type=file])[type=search][aria-invalid=true]{background-image:var(--icon-search),var(--icon-invalid)}[type=search]::-webkit-search-cancel-button{-webkit-appearance:none;display:none}[dir=rtl] :where(input):not([type=checkbox],[type=radio],[type=range],[type=file])[type=search]{background-position:center right 1.125rem}[dir=rtl] :where(input):not([type=checkbox],[type=radio],[type=range],[type=file])[type=search][aria-invalid]{background-position:center right 1.125rem,center left .75rem}:where(table){border-collapse:collapse;border-spacing:0;text-indent:0;width:100%}td,th{border-bottom:var(--border-width) solid var(--table-border-color);color:var(--color);font-size:var(--font-size);font-weight:var(--font-weight);padding:calc(var(--spacing)/2) var(--spacing);text-align:left;text-align:start}tfoot td,tfoot th{border-bottom:0;border-top:var(--border-width) solid var(--table-border-color)}table[role=grid] tbody tr:nth-child(odd){background-color:var(--table-row-stripped-background-color)}code,kbd,pre,samp{font-family:var(--font-family);font-size:.875em}pre{-ms-overflow-style:scrollbar;overflow:auto}code,kbd,pre{background:var(--code-background-color);border-radius:var(--border-radius);color:var(--code-color);font-weight:var(--font-weight);line-height:normal}code,kbd{display:inline-block;padding:.375rem .5rem}pre{margin-bottom:var(--spacing);overflow-x:auto}pre,pre>code{display:block}pre>code{background:none;font-size:14px;line-height:var(--line-height);padding:var(--spacing)}code b{color:var(--code-tag-color);font-weight:var(--font-weight)}code i{color:var(--code-property-color);font-style:normal}code u{color:var(--code-value-color);text-decoration:none}code em{color:var(--code-comment-color);font-style:normal}kbd{background-color:var(--code-kbd-background-color);color:var(--code-kbd-color);vertical-align:baseline}hr{border:0;border-top:1px solid var(--muted-border-color);color:inherit;height:0}[hidden],template{display:none!important}canvas{display:inline-block}details{border-bottom:var(--border-width) solid var(--accordion-border-color);display:block;margin-bottom:var(--spacing);padding-bottom:var(--spacing)}details summary{cursor:pointer;line-height:1rem;list-style-type:none;transition:color var(--transition)}details summary:not([role]){color:var(--accordion-close-summary-color)}details summary::-webkit-details-marker{display:none}details summary::marker{display:none}details summary::-moz-list-bullet{list-style-type:none}details summary:after{background-image:var(--icon-chevron);background-position:100%;background-repeat:no-repeat;background-size:1rem auto;content:"";display:block;float:right;height:1rem;margin-inline-start:calc(var(--spacing, 1rem)*.5);transform:rotate(-90deg);transition:transform var(--transition);width:1rem}details summary:focus{outline:none}details summary:focus:not([role=button]){color:var(--accordion-active-summary-color)}details summary[role=button]{text-align:left;width:100%}details summary[role=button]:after{background-image:var(--icon-chevron-button);height:calc(1rem*var(--line-height, 1.5))}details summary[role=button]:not(.outline).contrast:after{background-image:var(--icon-chevron-button-inverse)}details[open]>summary{margin-bottom:calc(var(--spacing))}details[open]>summary:not([role]):not(:focus){color:var(--accordion-open-summary-color)}details[open]>summary:after{transform:rotate(0)}[dir=rtl] details summary{text-align:right}[dir=rtl] details summary:after{background-position:0;float:left}article{background:var(--card-background-color);border-radius:var(--border-radius);box-shadow:var(--card-box-shadow);margin:var(--block-spacing-vertical) 0;padding:var(--block-spacing-vertical) var(--block-spacing-horizontal)}article>footer,article>header{background-color:var(--card-sectionning-background-color);margin-left:calc(var(--block-spacing-horizontal)*-1);margin-right:calc(var(--block-spacing-horizontal)*-1);padding:calc(var(--block-spacing-vertical)*.66) var(--block-spacing-horizontal)}article>header{border-bottom:var(--border-width) solid var(--card-border-color);border-top-left-radius:var(--border-radius);border-top-right-radius:var(--border-radius);margin-bottom:var(--block-spacing-vertical);margin-top:calc(var(--block-spacing-vertical)*-1)}article>footer{border-bottom-left-radius:var(--border-radius);border-bottom-right-radius:var(--border-radius);border-top:var(--border-width) solid var(--card-border-color);margin-bottom:calc(var(--block-spacing-vertical)*-1);margin-top:var(--block-spacing-vertical)}:root{--scrollbar-width:0px}dialog{align-items:center;-webkit-backdrop-filter:var(--modal-overlay-backdrop-filter);backdrop-filter:var(--modal-overlay-backdrop-filter);background-color:var(--modal-overlay-background-color);border:0;bottom:0;color:var(--color);display:flex;height:inherit;justify-content:center;left:0;min-height:100%;min-width:100%;padding:var(--spacing);position:fixed;right:0;top:0;width:inherit;z-index:999}dialog article{max-height:calc(100vh - var(--spacing)*2);overflow:auto}@media (min-width:576px){dialog article{max-width:510px}}@media (min-width:768px){dialog article{max-width:700px}}dialog article>footer,dialog article>header{padding:calc(var(--block-spacing-vertical)*.5) var(--block-spacing-horizontal)}dialog article>header .close{float:right;margin:0;margin-left:var(--spacing)}dialog article>footer{text-align:right}dialog article>footer [role=button]{margin-bottom:0}dialog article>footer [role=button]:not(:first-of-type){margin-left:calc(var(--spacing)*.5)}dialog article p:last-of-type{margin:0}dialog article .close{background-image:var(--icon-close);background-position:50%;background-repeat:no-repeat;background-size:auto 1rem;display:block;height:1rem;margin-bottom:var(--typography-spacing-vertical);margin-left:auto;margin-top:calc(var(--block-spacing-vertical)*-.5);opacity:.5;transition:opacity var(--transition);width:1rem}dialog article .close:is([aria-current],:hover,:active,:focus){opacity:1}dialog:not([open]),dialog[open=false]{display:none}.modal-is-open{overflow:hidden;padding-right:var(--scrollbar-width,0);pointer-events:none;touch-action:none}.modal-is-open dialog{pointer-events:auto}:where(.modal-is-opening,.modal-is-closing) dialog,:where(.modal-is-opening,.modal-is-closing) dialog>article{animation-duration:.2s;animation-fill-mode:both;animation-timing-function:ease-in-out}:where(.modal-is-opening,.modal-is-closing) dialog{animation-duration:.8s;animation-name:modal-overlay}:where(.modal-is-opening,.modal-is-closing) dialog>article{animation-delay:.2s;animation-name:modal}.modal-is-closing dialog,.modal-is-closing dialog>article{animation-delay:0s;animation-direction:reverse}@keyframes modal-overlay{0%{-webkit-backdrop-filter:none;backdrop-filter:none;background-color:transparent}}@keyframes modal{0%{opacity:0;transform:translateY(-100%)}}:where(nav li):before{content:"";float:left}nav,nav ul{display:flex}nav{justify-content:space-between}nav ol,nav ul{align-items:center;list-style:none;margin-bottom:0;padding:0}nav ol:first-of-type,nav ul:first-of-type{margin-left:calc(var(--nav-element-spacing-horizontal)*-1)}nav ol:last-of-type,nav ul:last-of-type{margin-right:calc(var(--nav-element-spacing-horizontal)*-1)}nav li{display:inline-block;margin:0;padding:var(--nav-element-spacing-vertical) var(--nav-element-spacing-horizontal)}nav li>*{--spacing:0}nav :where(a,[role=link]){border-radius:var(--border-radius);display:inline-block;margin:calc(var(--nav-link-spacing-vertical)*-1) calc(var(--nav-link-spacing-horizontal)*-1);padding:var(--nav-link-spacing-vertical) var(--nav-link-spacing-horizontal);text-decoration:none}nav :where(a,[role=link]):is([aria-current],:hover,:active,:focus){text-decoration:none}nav[aria-label=breadcrumb]{align-items:center;justify-content:start}nav[aria-label=breadcrumb] ul li:not(:first-child){margin-inline-start:var(--nav-link-spacing-horizontal)}nav[aria-label=breadcrumb] ul li:not(:last-child) :after{color:var(--muted-color);content:"/";margin-inline-start:calc(var(--nav-link-spacing-horizontal)/2);position:absolute;text-align:center;width:calc(var(--nav-link-spacing-horizontal)*2)}nav[aria-label=breadcrumb] a[aria-current]{background-color:transparent;color:inherit;pointer-events:none;text-decoration:none}nav [role=button]{margin-left:inherit;margin-right:inherit;padding:var(--nav-link-spacing-vertical) var(--nav-link-spacing-horizontal)}aside li,aside nav,aside ol,aside ul{display:block}aside li{padding:calc(var(--nav-element-spacing-vertical)*.5) var(--nav-element-spacing-horizontal)}aside li a{display:block}aside li [role=button]{margin:inherit}[dir=rtl] nav[aria-label=breadcrumb] ul li:not(:last-child) :after{content:"\\"}progress{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--progress-background-color);border:0;border-radius:var(--border-radius);color:var(--progress-color);display:inline-block;height:.5rem;margin-bottom:calc(var(--spacing)*.5);overflow:hidden;vertical-align:baseline;width:100%}progress::-webkit-progress-bar{background:none;border-radius:var(--border-radius)}progress[value]::-webkit-progress-value{background-color:var(--progress-color)}progress::-moz-progress-bar{background-color:var(--progress-color)}@media (prefers-reduced-motion:no-preference){progress:indeterminate{animation:progress-indeterminate 1s linear infinite;background:var(--progress-background-color) linear-gradient(to right,var(--progress-color) 30%,var(--progress-background-color) 30%) top left/150% 150% no-repeat}progress:indeterminate[value]::-webkit-progress-value{background-color:transparent}progress:indeterminate::-moz-progress-bar{background-color:transparent}}@media (prefers-reduced-motion:no-preference){[dir=rtl] progress:indeterminate{animation-direction:reverse}}@keyframes progress-indeterminate{0%{background-position:200% 0}to{background-position:-200% 0}}details[role=list],li[role=list]{position:relative}details[role=list] summary+ul,li[role=list]>ul{background-color:var(--dropdown-background-color);border:var(--border-width) solid var(--dropdown-border-color);border-radius:var(--border-radius);border-top-left-radius:0;border-top-right-radius:0;box-shadow:var(--card-box-shadow);color:var(--dropdown-color);display:flex;flex-direction:column;left:0;margin:0;padding:0;position:absolute;right:0;top:auto;white-space:nowrap;z-index:99}details[role=list] summary+ul li,li[role=list]>ul li{list-style:none;margin-bottom:0;padding:calc(var(--form-element-spacing-vertical)*.5) var(--form-element-spacing-horizontal);width:100%}details[role=list] summary+ul li:first-of-type,li[role=list]>ul li:first-of-type{margin-top:calc(var(--form-element-spacing-vertical)*.5)}details[role=list] summary+ul li:last-of-type,li[role=list]>ul li:last-of-type{margin-bottom:calc(var(--form-element-spacing-vertical)*.5)}details[role=list] summary+ul li a,li[role=list]>ul li a{color:var(--dropdown-color);display:block;margin:calc(var(--form-element-spacing-vertical)*-.5) calc(var(--form-element-spacing-horizontal)*-1);overflow:hidden;padding:calc(var(--form-element-spacing-vertical)*.5) var(--form-element-spacing-horizontal);text-decoration:none;text-overflow:ellipsis}details[role=list] summary+ul li a:hover,li[role=list]>ul li a:hover{background-color:var(--dropdown-hover-background-color)}details[role=list] summary:after,li[role=list]>a:after{background-image:var(--icon-chevron);background-position:100%;background-repeat:no-repeat;background-size:1rem auto;content:"";display:block;float:right;height:calc(1rem*var(--line-height, 1.5));margin-inline-start:.5rem;transform:rotate(0deg);width:1rem}details[role=list]{border-bottom:none;padding:0}details[role=list] summary{margin-bottom:0}details[role=list] summary:not([role]){background-color:var(--form-element-background-color);border:var(--border-width) solid var(--form-element-border-color);border-radius:var(--border-radius);color:var(--form-element-placeholder-color);cursor:pointer;height:calc(1rem*var(--line-height) + var(--form-element-spacing-vertical)*2 + var(--border-width)*2);line-height:inherit;padding:var(--form-element-spacing-vertical) var(--form-element-spacing-horizontal);transition:background-color var(--transition),border-color var(--transition),color var(--transition),box-shadow var(--transition)}details[role=list] summary:not([role]):active,details[role=list] summary:not([role]):focus{background-color:var(--form-element-active-background-color);border-color:var(--form-element-active-border-color)}details[role=list] summary:not([role]):focus{box-shadow:0 0 0 var(--outline-width) var(--form-element-focus-color)}details[role=list][open] summary{border-bottom-left-radius:0;border-bottom-right-radius:0}details[role=list][open] summary:before{background:none;bottom:0;content:"";cursor:default;display:block;left:0;position:fixed;right:0;top:0;z-index:1}nav details[role=list] summary,nav li[role=list] a{direction:ltr;display:flex}nav details[role=list] summary+ul,nav li[role=list]>ul{border-radius:var(--border-radius);min-width:-moz-fit-content;min-width:fit-content}nav details[role=list] summary+ul li a,nav li[role=list]>ul li a{border-radius:0}nav details[role=list] summary,nav details[role=list] summary:not([role]){height:auto;padding:var(--nav-link-spacing-vertical) var(--nav-link-spacing-horizontal)}nav details[role=list][open] summary{border-radius:var(--border-radius)}nav details[role=list] summary+ul{margin-top:var(--outline-width);margin-inline-start:0}nav details[role=list] summary[role=link]{line-height:var(--line-height);margin-bottom:calc(var(--nav-link-spacing-vertical)*-1)}nav details[role=list] summary[role=link]+ul{margin-top:calc(var(--nav-link-spacing-vertical) + var(--outline-width));margin-inline-start:calc(var(--nav-link-spacing-horizontal)*-1)}li[role=list] a:active~ul,li[role=list] a:focus~ul,li[role=list]:hover>ul{display:flex}li[role=list]>ul{display:none;margin-top:calc(var(--nav-link-spacing-vertical) + var(--outline-width));margin-inline-start:calc(var(--nav-element-spacing-horizontal) - var(--nav-link-spacing-horizontal))}li[role=list]>a:after{background-image:var(--icon-chevron)}label>details[role=list]{margin-bottom:var(--spacing);margin-top:calc(var(--spacing)*.25)}[aria-busy=true]{cursor:progress}[aria-busy=true]:not(input,select,textarea,html):before{animation:spinner .75s linear infinite;border:.1875em solid;border-radius:1em;border-right:.1875em solid transparent;content:"";display:inline-block;height:1em;opacity:var(--loading-spinner-opacity);vertical-align:text-bottom;vertical-align:-.125em;width:1em}[aria-busy=true]:not(input,select,textarea,html):not(:empty):before{margin-left:0;margin-right:calc(var(--spacing)*.5);margin-inline-end:calc(var(--spacing)*.5);margin-inline-start:0}[aria-busy=true]:not(input,select,textarea,html):empty{text-align:center}a[aria-busy=true],button[aria-busy=true],input[type=button][aria-busy=true],input[type=reset][aria-busy=true],input[type=submit][aria-busy=true]{pointer-events:none}@keyframes spinner{to{transform:rotate(1turn)}}[data-tooltip]{position:relative}[data-tooltip]:not(a,button,input){border-bottom:1px dotted;cursor:help;text-decoration:none}[data-tooltip]:after,[data-tooltip]:before,[data-tooltip][data-placement=top]:after,[data-tooltip][data-placement=top]:before{background:var(--tooltip-background-color);border-radius:var(--border-radius);bottom:100%;color:var(--tooltip-color);content:attr(data-tooltip);display:block;font-size:.875rem;font-style:normal;font-weight:var(--font-weight);left:50%;opacity:0;overflow:hidden;padding:.25rem .5rem;pointer-events:none;position:absolute;text-decoration:none;text-overflow:ellipsis;transform:translate(-50%,-.25rem);white-space:nowrap;z-index:99}[data-tooltip]:after,[data-tooltip][data-placement=top]:after{background-color:transparent;border-left:.3rem solid transparent;border-radius:0;border-right:.3rem solid transparent;border-top:.3rem solid;color:var(--tooltip-background-color);content:"";padding:0;transform:translate(-50%)}[data-tooltip][data-placement=bottom]:after,[data-tooltip][data-placement=bottom]:before{bottom:auto;top:100%;transform:translate(-50%,.25rem)}[data-tooltip][data-placement=bottom]:after{border:.3rem solid transparent;border-bottom-color:currentcolor;transform:translate(-50%,-.3rem)}[data-tooltip][data-placement=left]:after,[data-tooltip][data-placement=left]:before{bottom:auto;left:auto;right:100%;top:50%;transform:translate(-.25rem,-50%)}[data-tooltip][data-placement=left]:after{border:.3rem solid transparent;border-left-color:currentcolor;transform:translate(.3rem,-50%)}[data-tooltip][data-placement=right]:after,[data-tooltip][data-placement=right]:before{bottom:auto;left:100%;right:auto;top:50%;transform:translate(.25rem,-50%)}[data-tooltip][data-placement=right]:after{border:.3rem solid transparent;border-right-color:currentcolor;transform:translate(-.3rem,-50%)}[data-tooltip]:focus:after,[data-tooltip]:focus:before,[data-tooltip]:hover:after,[data-tooltip]:hover:before{opacity:1}@media (hover:hover) and (pointer:fine){[data-tooltip]:hover:after,[data-tooltip]:hover:before,[data-tooltip][data-placement=bottom]:focus:after,[data-tooltip][data-placement=bottom]:focus:before,[data-tooltip][data-placement=bottom]:hover [data-tooltip]:focus:after,[data-tooltip][data-placement=bottom]:hover [data-tooltip]:focus:before{animation-duration:.2s;animation-name:tooltip-slide-top}[data-tooltip]:hover:after,[data-tooltip][data-placement=bottom]:focus:after,[data-tooltip][data-placement=bottom]:hover [data-tooltip]:focus:after{animation-name:tooltip-caret-slide-top}[data-tooltip][data-placement=bottom]:focus:after,[data-tooltip][data-placement=bottom]:focus:before,[data-tooltip][data-placement=bottom]:hover:after,[data-tooltip][data-placement=bottom]:hover:before{animation-duration:.2s;animation-name:tooltip-slide-bottom}[data-tooltip][data-placement=bottom]:focus:after,[data-tooltip][data-placement=bottom]:hover:after{animation-name:tooltip-caret-slide-bottom}[data-tooltip][data-placement=left]:focus:after,[data-tooltip][data-placement=left]:focus:before,[data-tooltip][data-placement=left]:hover:after,[data-tooltip][data-placement=left]:hover:before{animation-duration:.2s;animation-name:tooltip-slide-left}[data-tooltip][data-placement=left]:focus:after,[data-tooltip][data-placement=left]:hover:after{animation-name:tooltip-caret-slide-left}[data-tooltip][data-placement=right]:focus:after,[data-tooltip][data-placement=right]:focus:before,[data-tooltip][data-placement=right]:hover:after,[data-tooltip][data-placement=right]:hover:before{animation-duration:.2s;animation-name:tooltip-slide-right}[data-tooltip][data-placement=right]:focus:after,[data-tooltip][data-placement=right]:hover:after{animation-name:tooltip-caret-slide-right}}@keyframes tooltip-slide-top{0%{opacity:0;transform:translate(-50%,.75rem)}to{opacity:1;transform:translate(-50%,-.25rem)}}@keyframes tooltip-caret-slide-top{0%{opacity:0}50%{opacity:0;transform:translate(-50%,-.25rem)}to{opacity:1;transform:translate(-50%)}}@keyframes tooltip-slide-bottom{0%{opacity:0;transform:translate(-50%,-.75rem)}to{opacity:1;transform:translate(-50%,.25rem)}}@keyframes tooltip-caret-slide-bottom{0%{opacity:0}50%{opacity:0;transform:translate(-50%,-.5rem)}to{opacity:1;transform:translate(-50%,-.3rem)}}@keyframes tooltip-slide-left{0%{opacity:0;transform:translate(.75rem,-50%)}to{opacity:1;transform:translate(-.25rem,-50%)}}@keyframes tooltip-caret-slide-left{0%{opacity:0}50%{opacity:0;transform:translate(.05rem,-50%)}to{opacity:1;transform:translate(.3rem,-50%)}}@keyframes tooltip-slide-right{0%{opacity:0;transform:translate(-.75rem,-50%)}to{opacity:1;transform:translate(.25rem,-50%)}}@keyframes tooltip-caret-slide-right{0%{opacity:0}50%{opacity:0;transform:translate(-.05rem,-50%)}to{opacity:1;transform:translate(-.3rem,-50%)}}[aria-controls]{cursor:pointer}[aria-disabled=true],[disabled]{cursor:not-allowed}[aria-hidden=false][hidden]{display:initial}[aria-hidden=false][hidden]:not(:focus){clip:rect(0,0,0,0);position:absolute}[tabindex],a,area,button,input,label,select,summary,textarea{-ms-touch-action:manipulation}[dir=rtl]{direction:rtl}@media (prefers-reduced-motion:reduce){:not([aria-busy=true]),:not([aria-busy=true]):after,:not([aria-busy=true]):before{animation-delay:-1ms!important;animation-duration:1ms!important;animation-iteration-count:1!important;background-attachment:scroll!important;scroll-behavior:auto!important;transition-delay:0s!important;transition-duration:0s!important}}.flash{background-position:10px;background-repeat:no-repeat;border-radius:2px;line-height:32px;margin:5px 0;min-height:32px;padding:3px 10px 3px 50px}.error{background-color:#ffbaba;color:#d8000c}.info{background-color:#bde5f8;color:#00529b}.valid{background-color:#dff2bf;color:#4f8a10}.warning{background-color:#feefb3;color:#9f6000}.icon{filter:invert(.5)}.icon:hover{filter:none}@media only screen and (prefers-color-scheme:dark){:root:not([data-theme]){--koot-logo-wordmark:#bdecee}}:root:not([data-theme=dark]),[data-theme=light]{--koot-logo-wordmark:#002741}:root:not([data-theme=light]),[data-theme=dark]{--koot-logo-wordmark:#bdecee}svg.logo{height:auto;margin:-.5rem;width:5rem}@media (min-width:576px){svg.logo{margin:-1rem;width:10rem}}.paginator{justify-content:flex-start}.paginator .nextprev{color:#000}.paginator a{background:#fff;border:1px solid #e8ebf1;margin:.5em .1em;padding:.5em;text-decoration:none}.paginator a:hover,.paginator strong{background:#e8ebf1}.paginator strong{border:1px solid #e8ebf1;margin:.5em .1em;padding:.5em}
--------------------------------------------------------------------------------