From 7a01793062941d306bfb405bba736d4941455fde Mon Sep 17 00:00:00 2001 From: OniriCorpe Date: Sat, 23 Mar 2024 08:59:52 +0100 Subject: [PATCH] Improve markdown formatting of pages, a lot of them are improperly formatted (#2429) * Revert "Revert "markdown format"" * fix formating * fix readme * add .markdownlint.json * add markdownlint-rules-grav-pages * add markdownlint-rules-grav-pages files * add license for Markdown Lint Rules for Grav Pages * fix [figure] mess * fix [figure] mess 2 * fix [figure] mess 3 * maj .gitignore * various fixes * fix markdownlint-rules-grav-pages * second formater pass * various manual fixes * add .markdownlintignore * markdownlintignore: auto-generated pages * disable proper-names for html_elements * another bunch of various markdown fixes * Update pages/02.administer/10.install/20.dns_config/dns_config.es.md Co-authored-by: tituspijean --------- Co-authored-by: Alexandre Aubin <4533074+alexAubin@users.noreply.github.com> Co-authored-by: tituspijean --- .gitignore | 2 + .markdownlint.json | 64 + .markdownlintignore | 11 + README.md | 14 +- markdownlint-rules-grav-pages/.eslintrc | 10 + markdownlint-rules-grav-pages/.gitignore | 2 + markdownlint-rules-grav-pages/.travis.yml | 9 + markdownlint-rules-grav-pages/CHANGELOG.md | 79 + markdownlint-rules-grav-pages/LICENSE | 24 + markdownlint-rules-grav-pages/README.md | 44 + markdownlint-rules-grav-pages/lib/flat.js | 10 + .../package-lock.json | 15298 ++++++++++++++++ markdownlint-rules-grav-pages/package.json | 42 + .../rules/frontmatter.schema.json | 119 + .../rules/valid-images.js | 31 + .../rules/valid-internal-links.js | 128 + .../rules/valid-metadata-block.js | 69 + markdownlint-rules-grav-pages/tests/.eslintrc | 9 + .../tests/assets/test.image | 0 .../tests/assets/valid-images/test.image | 0 .../tests/assets/valid-images/test.md | 23 + .../tests/assets/valid-internal-links/test.md | 46 + .../invalid-too-long-title.md | 5 + .../invalid-unrecognized-property.md | 6 + .../valid-minimum-block.md | 5 + .../valid-metadata-block/valid-taxonomy.md | 11 + .../tests/valid-images.spec.js | 31 + .../tests/valid-internal-links.spec.js | 89 + .../tests/valid-metadata-block.spec.js | 60 + orphaned/default.es.md | 6 +- orphaned/default.fr.md | 6 +- orphaned/default.it.md | 6 +- orphaned/default.md | 6 +- orphaned/dns.es.md | 1 - orphaned/dns.fr.md | 5 +- orphaned/dns.md | 2 - orphaned/index.ar.md | 10 +- orphaned/index.de.md | 10 +- orphaned/index.es.md | 11 +- orphaned/index.fr.md | 10 +- orphaned/index.it.md | 10 +- orphaned/index.md | 9 +- orphaned/index.oc.md | 10 +- orphaned/registrar.fr.md | 11 +- orphaned/registrar.md | 11 +- pages/00.home/docs.de.md | 2 - pages/00.home/docs.es.md | 1 - pages/00.home/docs.fr.md | 1 - pages/00.home/docs.it.md | 1 - pages/00.home/docs.md | 1 - pages/00.home/docs.ru.md | 1 - .../05.self_hosting/self_hosting.de.md | 2 +- .../05.self_hosting/self_hosting.es.md | 35 +- .../05.self_hosting/self_hosting.it.md | 2 - .../05.self_hosting/self_hosting.ru.md | 6 +- .../what_is_yunohost.ar.md | 8 +- .../what_is_yunohost.de.md | 5 +- .../what_is_yunohost.es.md | 8 +- .../what_is_yunohost.fr.md | 6 +- .../what_is_yunohost.it.md | 13 +- .../10.what_is_yunohost/what_is_yunohost.md | 6 +- .../what_is_yunohost.ru.md | 6 +- .../how_to_host_yourself.de.md | 2 +- .../how_to_host_yourself.md | 4 +- .../how_to_host_yourself.ru.md | 5 +- .../10.install/05.images/docs.fr.md | 4 +- .../10.install/05.images/images.de.md | 4 +- .../10.install/05.images/images.es.md | 5 +- .../10.install/05.images/images.fr.md | 4 +- .../10.install/05.images/images.md | 4 +- .../10.install/05.images/images.ru.md | 4 +- .../finding_the_local_ip.de.md | 8 +- .../finding_the_local_ip.fr.md | 9 +- .../finding_the_local_ip.md | 8 +- .../finding_the_local_ip.ru.md | 12 +- .../15.isp_box_config/isp_box_config.de.md | 10 +- .../15.isp_box_config/isp_box_config.es.md | 15 +- .../15.isp_box_config/isp_box_config.fr.md | 11 +- .../15.isp_box_config/isp_box_config.md | 10 +- .../15.isp_box_config/isp_box_config.ru.md | 11 +- .../10.install/20.dns_config/dns_config.de.md | 18 +- .../10.install/20.dns_config/dns_config.es.md | 12 +- .../10.install/20.dns_config/dns_config.fr.md | 12 +- .../10.install/20.dns_config/dns_config.md | 10 +- .../10.install/20.dns_config/dns_config.ru.md | 10 +- .../25.installing_debian/installing_debian.md | 18 +- pages/02.administer/10.install/install.de.md | 184 +- pages/02.administer/10.install/install.fr.md | 161 +- pages/02.administer/10.install/install.md | 190 +- pages/02.administer/10.install/install.ru.md | 175 +- .../05.guidelines/guidelines.de.md | 4 +- .../05.guidelines/guidelines.fr.md | 8 +- .../05.guidelines/guidelines.it.md | 6 +- .../05.guidelines/guidelines.md | 14 +- .../15.admin_guide/10.admin/admin.de.md | 2 +- .../15.admin_guide/10.admin/admin.es.md | 2 +- .../15.admin_guide/10.admin/admin.fr.md | 3 +- .../15.admin_guide/10.admin/admin.it.md | 3 +- .../15.admin_guide/10.admin/admin.md | 2 +- .../15.command_line/command_line.de.md | 20 +- .../15.command_line/command_line.es.md | 14 +- .../15.command_line/command_line.fr.md | 20 +- .../15.command_line/command_line.it.md | 13 +- .../15.command_line/command_line.md | 31 +- .../groups_and_permissions.fr.md | 76 +- .../groups_and_permissions.md | 67 +- .../15.admin_guide/20.users/users.fr.md | 1 - .../01.certificate/certificate.de.md | 8 +- .../01.certificate/certificate.es.md | 2 +- .../01.certificate/certificate.it.md | 3 +- .../25.domains/01.certificate/certificate.md | 1 - .../15.admin_guide/25.domains/domains.de.md | 10 +- .../15.admin_guide/25.domains/domains.fr.md | 2 +- .../15.admin_guide/25.domains/domains.it.md | 11 +- .../15.admin_guide/25.domains/domains.md | 14 +- .../15.admin_guide/30.apps/apps.fr.md | 7 +- .../15.admin_guide/30.apps/apps.it.md | 19 +- .../15.admin_guide/30.apps/apps.md | 18 +- .../15.admin_guide/35.nginx/nginx.md | 4 +- .../15.admin_guide/40.xmpp/xmpp.es.md | 6 +- .../15.admin_guide/40.xmpp/xmpp.fr.md | 2 +- .../15.admin_guide/40.xmpp/xmpp.md | 2 +- .../15.admin_guide/45.emails/email.de.md | 13 +- .../15.admin_guide/45.emails/email.es.md | 9 +- .../15.admin_guide/45.emails/email.fr.md | 1 + .../15.admin_guide/45.emails/email.md | 4 +- .../15.admin_guide/50.backups/backup.fr.md | 32 +- .../15.admin_guide/50.backups/backup.it.md | 16 +- .../15.admin_guide/50.backups/backup.md | 24 +- .../stretch_buster_migration.fr.md | 16 +- .../stretch_buster_migration.md | 20 +- .../buster_bullseye_migration.fr.md | 48 +- .../buster_bullseye_migration.md | 62 +- .../jessie_stretch_migration.fr.md | 18 +- .../jessie_stretch_migration.md | 20 +- .../15.admin_guide/55.upgrade/upgrade.fr.md | 2 +- .../15.admin_guide/55.upgrade/upgrade.md | 2 +- .../15.admin_guide/admin_guide.de.md | 3 +- .../15.admin_guide/admin_guide.md | 2 - .../20.backups/05.evaluate/evaluate.fr.md | 53 +- .../20.backups/05.evaluate/evaluate.it.md | 54 +- .../20.backups/05.evaluate/evaluate.md | 55 +- .../01.borgbackup/borgbackup.fr.md | 30 +- .../01.borgbackup/borgbackup.it.md | 34 +- .../01.borgbackup/borgbackup.md | 30 +- .../10.backup_methods/02.restic/restic.fr.md | 9 +- .../10.backup_methods/02.restic/restic.it.md | 6 +- .../10.backup_methods/02.restic/restic.md | 8 +- .../03.archivist/archivist.fr.md | 10 +- .../03.archivist/archivist.md | 11 +- .../10.backup_methods/backup_methods.md | 26 +- .../clone_filesystem.fr.md | 61 +- .../clone_filesystem.it.md | 64 +- .../15.clone_filesystem/clone_filesystem.md | 64 +- .../avoid_hardware_failure.fr.md | 28 +- .../avoid_hardware_failure.it.md | 28 +- .../avoid_hardware_failure.md | 28 +- .../include_exclude_files.fr.md | 13 +- .../include_exclude_files.it.md | 12 +- .../include_exclude_files.md | 13 +- .../custom_backup_methods.fr.md | 6 +- .../custom_backup_methods.it.md | 7 +- .../custom_backup_methods.md | 7 +- .../migrate_or_merge_servers.fr.md | 3 +- .../migrate_or_merge_servers.it.md | 1 + .../migrate_or_merge_servers.md | 3 +- .../01.dns_nohost_me/dns_nohost_me.es.md | 4 +- .../01.dns_nohost_me/dns_nohost_me.fr.md | 4 +- .../01.dns_nohost_me/dns_nohost_me.it.md | 8 +- .../01.dns_nohost_me/dns_nohost_me.md | 7 +- .../02.dns_dynamic_ip/dns_dynamicip.fr.md | 39 +- .../02.dns_dynamic_ip/dns_dynamicip.it.md | 69 +- .../02.dns_dynamic_ip/dns_dynamicip.md | 38 +- .../03.dns_subdomains/dns_subdomains.fr.md | 6 +- .../03.dns_subdomains/dns_subdomains.md | 8 +- .../dns_local_network.es.md | 5 +- .../dns_local_network.fr.md | 7 +- .../dns_local_network.it.md | 11 +- .../04.dns_local_network/dns_local_network.md | 5 +- .../45.tutorials/15.filezilla/filezilla.fr.md | 16 +- .../45.tutorials/15.filezilla/filezilla.it.md | 24 +- .../45.tutorials/15.filezilla/filezilla.md | 16 +- .../external_storage.fr.md | 24 +- .../external_storage.it.md | 26 +- .../25.external_storage/external_storage.md | 35 +- .../email_configure_relay.fr.md | 13 +- .../35.email_relay/email_configure_relay.md | 12 +- .../40.tor/torhiddenservice.fr.md | 16 +- .../40.tor/torhiddenservice.it.md | 14 +- .../45.tutorials/40.tor/torhiddenservice.md | 19 +- .../certificate_custom.fr.md | 50 +- .../certificate_custom.md | 51 +- .../moving_app_folder.fr.md | 14 +- .../55.moving_app_folder/moving_app_folder.md | 12 +- .../45.tutorials/60.security/security.fr.md | 4 +- .../45.tutorials/60.security/security.it.md | 17 +- .../45.tutorials/60.security/security.md | 4 +- .../65.sftp_on_apps/sftp_on_apps.it.md | 3 - .../65.sftp_on_apps/sftp_on_apps.md | 2 - .../change_admin_password.fr.md | 7 +- .../change_admin_password.it.md | 2 - .../change_admin_password.md | 2 - .../15.noaccess/noaccess.fr.md | 49 +- .../15.noaccess/noaccess.it.md | 29 +- .../15.noaccess/noaccess.md | 29 +- .../50.troubleshooting/20.ipv6/ipv6.fr.md | 14 +- .../50.troubleshooting/20.ipv6/ipv6.it.md | 8 +- .../50.troubleshooting/20.ipv6/ipv6.md | 10 +- .../25.unblacklisting/blacklist_forms.fr.md | 16 +- .../25.unblacklisting/blacklist_forms.it.md | 12 +- .../25.unblacklisting/blacklist_forms.md | 46 +- .../50.troubleshooting/troubleshooting.fr.md | 4 +- .../50.troubleshooting/troubleshooting.it.md | 6 +- .../50.troubleshooting/troubleshooting.md | 6 +- .../05.registrar/gandi/autodns.it.md | 10 +- .../05.registrar/gandi/autodns.md | 8 +- .../05.registrar/namecheap/autodns.md | 19 +- .../05.registrar/ovh/autodns/autodns.fr.md | 10 +- .../05.registrar/ovh/autodns/autodns.it.md | 13 +- .../05.registrar/ovh/autodns/autodns.md | 10 +- .../ovh/manualdns/manualdns.fr.md | 12 +- .../ovh/manualdns/manualdns.it.md | 13 +- .../05.registrar/ovh/manualdns/manualdns.md | 12 +- .../55.providers/05.registrar/registrar.it.md | 1 - .../55.providers/05.registrar/registrar.md | 1 - .../55.providers/10.isp/free/isp_free.fr.md | 36 +- .../02.administer/55.providers/10.isp/isp.md | 66 +- .../10.isp/orange/isp_orange.fr.md | 15 +- .../55.providers/10.isp/sfr/isp_sfr.fr.md | 10 +- .../15.vpn/01.vpn/vpn_advantage.de.md | 13 +- .../15.vpn/01.vpn/vpn_advantage.es.md | 16 +- .../15.vpn/01.vpn/vpn_advantage.fr.md | 13 +- .../15.vpn/01.vpn/vpn_advantage.it.md | 11 +- .../15.vpn/01.vpn/vpn_advantage.md | 13 +- .../02.administer/55.providers/15.vpn/vpn.md | 17 +- .../55.providers/20.server/server.md | 10 +- .../install_unpackaged_app.md | 7 +- .../60.extend/15.theming/theming.fr.md | 10 +- .../60.extend/15.theming/theming.md | 16 +- .../60.extend/30.api/admin_api.fr.md | 2 +- .../60.extend/30.api/admin_api.md | 14 +- pages/02.administer/admindoc.es.md | 2 +- pages/02.administer/admindoc.it.md | 4 +- .../email_configure_client.de.md | 17 +- .../email_configure_client.es.md | 3 +- .../email_configure_client.fr.md | 15 +- .../email_configure_client.it.md | 18 +- .../05.emailclients/email_configure_client.md | 17 +- .../10.email_migration/email_migration.fr.md | 7 + .../10.email_migration/email_migration.md | 7 + pages/03.user_guide/15.xmpp/xmpp.es.md | 22 +- pages/03.user_guide/15.xmpp/xmpp.fr.md | 3 +- pages/03.user_guide/15.xmpp/xmpp.it.md | 5 +- pages/03.user_guide/15.xmpp/xmpp.md | 3 +- pages/03.user_guide/user_overview.fr.md | 2 +- pages/03.user_guide/user_overview.md | 2 +- .../15.framasoft/apps_framasoft.md | 68 +- .../use_case_non-profit_organisations.ca.md | 144 +- .../use_case_non-profit_organisations.fr.md | 141 +- .../use_case_non-profit_organisations.md | 141 +- .../use_case_non-profit_organisations.oc.md | 141 +- .../20.app_bundle/app_bundle.md | 2 +- .../10.chat_rooms/chat_rooms.es.md | 38 +- .../10.chat_rooms/chat_rooms.fr.md | 34 +- .../05.community/10.chat_rooms/chat_rooms.md | 34 +- pages/05.community/15.help/help.it.md | 1 - pages/05.community/15.help/help.md | 4 +- pages/05.community/20.faq/faq.de.md | 11 - pages/05.community/20.faq/faq.fr.md | 8 - pages/05.community/20.faq/faq.it.md | 13 +- pages/05.community/20.faq/faq.md | 15 +- .../sponsors_partners.fr.md | 4 +- .../30.project_sponsors/sponsors_partners.md | 2 + .../35.project_budget/project_budget.fr.md | 48 +- .../35.project_budget/project_budget.md | 42 +- .../35.security_team/security_team.fr.md | 2 +- .../35.security_team/security_team.md | 2 +- pages/05.community/40.press_kit/press_kit.md | 41 +- .../doc_writing_guide.fr.md | 26 +- .../doc_writing_guide.md | 24 +- .../doc_markdown_guide.fr.md | 55 +- .../02.markdown_guide/doc_markdown_guide.md | 56 +- .../03.git/doc_use_git.fr.md | 26 +- .../03.git/doc_use_git.md | 24 +- .../write_documentation.de.md | 94 +- .../write_documentation.fr.md | 13 +- .../write_documentation.md | 13 +- .../10.packaging_apps/10.manifest/docs.md | 24 +- .../10.packaging_apps/20.scripts/scripts.md | 10 +- .../10.packaging_apps/30.doc/doc.md | 2 +- .../10.packaging_apps/40.testing/testing.md | 14 +- .../50.publishing/publishing.md | 2 +- .../20.config_panels/config_panels.md | 48 +- .../sso_ldap_integration.md | 4 +- .../50.hooks/packaging_apps_hooks.fr.md | 10 +- .../50.hooks/packaging_apps_hooks.md | 258 +- .../advanced_packagers.md | 24 +- .../70.notes_about_new_packaging_v2/docs.md | 55 +- .../03.git/packaging_apps_git.fr.md | 44 +- .../80.resources/03.git/packaging_apps_git.md | 44 +- .../packaging_apps_virtualbox.fr.md | 9 +- .../packaging_apps_virtualbox.md | 5 +- .../11.helpers/packaging_apps_helpers.md | 569 +- .../packaging_apps_resources.md | 53 +- .../20.bash_tips/shell_variables_scope.fr.md | 111 +- .../20.bash_tips/shell_variables_scope.md | 111 +- .../packaging_apps_intro.de.md | 77 +- .../packaging_apps_intro.fr.md | 59 +- .../10.packaging_apps/packaging_apps_intro.md | 61 +- .../15.dev/02.maindomain/maindomain.md | 11 +- pages/06.contribute/15.dev/03.forms/forms.md | 33 +- pages/06.contribute/15.dev/dev.fr.md | 24 +- pages/06.contribute/15.dev/dev.md | 34 +- pages/06.contribute/contribute.de.md | 19 +- pages/06.contribute/contribute.fr.md | 11 +- pages/06.contribute/contribute.md | 11 +- 316 files changed, 19888 insertions(+), 3184 deletions(-) create mode 100644 .markdownlint.json create mode 100644 .markdownlintignore create mode 100644 markdownlint-rules-grav-pages/.eslintrc create mode 100644 markdownlint-rules-grav-pages/.gitignore create mode 100644 markdownlint-rules-grav-pages/.travis.yml create mode 100644 markdownlint-rules-grav-pages/CHANGELOG.md create mode 100644 markdownlint-rules-grav-pages/LICENSE create mode 100644 markdownlint-rules-grav-pages/README.md create mode 100644 markdownlint-rules-grav-pages/lib/flat.js create mode 100644 markdownlint-rules-grav-pages/package-lock.json create mode 100644 markdownlint-rules-grav-pages/package.json create mode 100644 markdownlint-rules-grav-pages/rules/frontmatter.schema.json create mode 100644 markdownlint-rules-grav-pages/rules/valid-images.js create mode 100644 markdownlint-rules-grav-pages/rules/valid-internal-links.js create mode 100644 markdownlint-rules-grav-pages/rules/valid-metadata-block.js create mode 100644 markdownlint-rules-grav-pages/tests/.eslintrc create mode 100644 markdownlint-rules-grav-pages/tests/assets/test.image create mode 100644 markdownlint-rules-grav-pages/tests/assets/valid-images/test.image create mode 100644 markdownlint-rules-grav-pages/tests/assets/valid-images/test.md create mode 100644 markdownlint-rules-grav-pages/tests/assets/valid-internal-links/test.md create mode 100644 markdownlint-rules-grav-pages/tests/assets/valid-metadata-block/invalid-too-long-title.md create mode 100644 markdownlint-rules-grav-pages/tests/assets/valid-metadata-block/invalid-unrecognized-property.md create mode 100644 markdownlint-rules-grav-pages/tests/assets/valid-metadata-block/valid-minimum-block.md create mode 100644 markdownlint-rules-grav-pages/tests/assets/valid-metadata-block/valid-taxonomy.md create mode 100644 markdownlint-rules-grav-pages/tests/valid-images.spec.js create mode 100644 markdownlint-rules-grav-pages/tests/valid-internal-links.spec.js create mode 100644 markdownlint-rules-grav-pages/tests/valid-metadata-block.spec.js diff --git a/.gitignore b/.gitignore index b4839ace..c9b256bc 100755 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,9 @@ /* +!.github !/pages !/images !/themes !/Dockerfile !/docker-compose.yml !/dev/plugins +!/markdownlint-rules-grav-pages diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 00000000..31e8d093 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,64 @@ +{ + "extends": "markdownlint-rules-grav-pages/rules/frontmatter.schema.json", + "default": true, + "code-block-style": { + "style": "fenced" + }, + "code-fence-style": { + "style": "backtick" + }, + "emphasis-style": { + "style": "asterisk" + }, + "strong-style": { + "style": "asterisk" + }, + "ul-style": { + "style": "dash" + }, + "ul-indent": { + "indent": 2 + }, + "heading-style": { + "style": "atx" + }, + "no-duplicate-heading": { + "siblings_only": true + }, + "hr-style": { + "style": "---" + }, + "ol-prefix": { + "style": "ordered" + }, + "no-trailing-punctuation": { + "punctuation": ".,;:" + }, + "no-inline-html": false, + "fenced-code-language": { + "allowed_languages": [ + "bash", + "html", + "css", + "javascript", + "php", + "json", + "yaml", + "toml", + "markdown", + "text" + ], + "language_only": true + }, + "proper-names": { + "code_blocks": false, + "html_elements": false, + "names": [ + "YunoHost", + "GitHub" + ] + }, + "line-length": false, + "no-reversed-links": false, + "no-missing-space-atx": false +} \ No newline at end of file diff --git a/.markdownlintignore b/.markdownlintignore new file mode 100644 index 00000000..a9d04c41 --- /dev/null +++ b/.markdownlintignore @@ -0,0 +1,11 @@ +config +images +tests +themes +.* +Dockerfile +docker-compose.yml + +# auto-generated pages +pages/06.contribute/10.packaging_apps/80.resources/11.helpers/packaging_apps_helpers.md +pages/06.contribute/10.packaging_apps/80.resources/15.appresources/packaging_apps_resources.md \ No newline at end of file diff --git a/README.md b/README.md index 8eb8ccb7..4d67f3d0 100644 --- a/README.md +++ b/README.md @@ -1,20 +1,20 @@ # YunoHost Documentation -* [Web Site](https://yunohost.org) -* Based on [Grav](https://getgrav.org/) +- [Web Site](https://yunohost.org) +- Based on [Grav](https://getgrav.org/) Please report [issues on YunoHost bugtracker](https://github.com/YunoHost/issues/issues). -## Note about package documentation +## Note on package documentation Package documentation should be done in the package repository itself, under the `/doc` folder. You can learn about it here: -# Contributing +## Contributing This repo use a **submodule** to provide the theme. So when you clone use: -```shell +```bash git clone --recursive https://github.com/YunoHost/doc.git ``` @@ -22,11 +22,11 @@ You can refer to the page on [writing documentation](https://yunohost.org/write_ If you know docker, you can run: -``` +```bash docker-compose up ``` -## Regenerate the CSS +### Regenerate the CSS We use scss to manage the CSS. If you want to change it, you must rebuild it. diff --git a/markdownlint-rules-grav-pages/.eslintrc b/markdownlint-rules-grav-pages/.eslintrc new file mode 100644 index 00000000..7126b196 --- /dev/null +++ b/markdownlint-rules-grav-pages/.eslintrc @@ -0,0 +1,10 @@ +{ + "extends": "airbnb-base", + "rules": { + "no-empty": ["error", { "allowEmptyCatch": true }], + "prefer-rest-params": "off", + "prefer-spread": "off", + "strict": "off", + "indent": ["error", 4] + } +} \ No newline at end of file diff --git a/markdownlint-rules-grav-pages/.gitignore b/markdownlint-rules-grav-pages/.gitignore new file mode 100644 index 00000000..aa7c395e --- /dev/null +++ b/markdownlint-rules-grav-pages/.gitignore @@ -0,0 +1,2 @@ +/node_modules/ +/.idea \ No newline at end of file diff --git a/markdownlint-rules-grav-pages/.travis.yml b/markdownlint-rules-grav-pages/.travis.yml new file mode 100644 index 00000000..845eb6ce --- /dev/null +++ b/markdownlint-rules-grav-pages/.travis.yml @@ -0,0 +1,9 @@ +language: node_js +node_js: + - "8" + - "9" + - "10" + - "11" +script: + - npm run lint + - npm run test diff --git a/markdownlint-rules-grav-pages/CHANGELOG.md b/markdownlint-rules-grav-pages/CHANGELOG.md new file mode 100644 index 00000000..01eeffc0 --- /dev/null +++ b/markdownlint-rules-grav-pages/CHANGELOG.md @@ -0,0 +1,79 @@ +# Changelog + +All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. + +### [1.0.19](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.18...v1.0.19) (2022-05-18) + +### [1.0.18](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.17...v1.0.18) (2022-02-08) + +### [1.0.17](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.16...v1.0.17) (2022-02-03) + +### [1.0.16](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.15...v1.0.16) (2020-03-15) + +### [1.0.15](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.14...v1.0.15) (2019-12-30) + +### [1.0.14](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.13...v1.0.14) (2019-07-11) + + + +### [1.0.13](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.12...v1.0.13) (2019-05-10) + + + + +### [1.0.12](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.11...v1.0.12) (2019-02-14) + + + + +### [1.0.11](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.10...v1.0.11) (2018-12-04) + + + + +### [1.0.10](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.9...v1.0.10) (2018-10-23) + + + + +### [1.0.9](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.8...v1.0.9) (2018-10-03) + + + + +### [1.0.8](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.7...v1.0.8) (2018-09-14) + + + + +### [1.0.7](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.6...v1.0.7) (2018-08-28) + + + + +### [1.0.6](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.5...v1.0.6) (2018-08-28) + + + + +### [1.0.5](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.4...v1.0.5) (2018-08-20) + + + + +### [1.0.4](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.3...v1.0.4) (2018-08-09) + + + + +### [1.0.3](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.2...v1.0.3) (2018-08-09) + + + + +### [1.0.2](https://github.com/syseleven/markdownlint-rules-grav-pages/compare/v1.0.1...v1.0.2) (2018-07-30) + + + + +### 1.0.1 (2018-07-19) diff --git a/markdownlint-rules-grav-pages/LICENSE b/markdownlint-rules-grav-pages/LICENSE new file mode 100644 index 00000000..b5259594 --- /dev/null +++ b/markdownlint-rules-grav-pages/LICENSE @@ -0,0 +1,24 @@ +Copyright (c) 2016, SysEleven GmbH +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the SysEleven GmbH nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL SYSELEVEN GMBH BE LIABLE FOR ANY +DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/markdownlint-rules-grav-pages/README.md b/markdownlint-rules-grav-pages/README.md new file mode 100644 index 00000000..3d7f6c77 --- /dev/null +++ b/markdownlint-rules-grav-pages/README.md @@ -0,0 +1,44 @@ +# Markdown Lint Rules for Grav Pages + +[![Build Status](https://travis-ci.org/syseleven/markdownlint-rules-grav-pages.svg?branch=master)](https://travis-ci.org/syseleven/markdownlint-rules-grav-pages) + +This package contains additional linting rules for [markdownlint](https://github.com/DavidAnson/markdownlint) +that check if a Markdown file is a valid [Grav CMS](https://getgrav.org/) page. + +## Rules + +### valid-images + +* Checks if a relatively referenced image is present. + +### valid-internal-links + +* Checks if a link to a another markdown file in the same repo is correct. + +### valid-metadata-block + +* Checks if a Frontmatter metadata block is present and valid. + +## Usage + +See https://github.com/DavidAnson/markdownlint/blob/master/doc/CustomRules.md + +## Development + +To lint all source files run: + +```bash +$ npm run lint +``` + +To run all tests: + +```bash +$ npm run test +``` + +To release a new version, ensure that the checkout is clean, then run: + +```bash +$ npm run release && git push --follow-tags origin master && npm publish +``` diff --git a/markdownlint-rules-grav-pages/lib/flat.js b/markdownlint-rules-grav-pages/lib/flat.js new file mode 100644 index 00000000..01092316 --- /dev/null +++ b/markdownlint-rules-grav-pages/lib/flat.js @@ -0,0 +1,10 @@ +module.exports = function flat(array) { + let result = []; + array.forEach((a) => { + result.push(a); + if (Array.isArray(a.children)) { + result = result.concat(flat(a.children)); + } + }); + return result; +}; diff --git a/markdownlint-rules-grav-pages/package-lock.json b/markdownlint-rules-grav-pages/package-lock.json new file mode 100644 index 00000000..cd496256 --- /dev/null +++ b/markdownlint-rules-grav-pages/package-lock.json @@ -0,0 +1,15298 @@ +{ + "name": "markdownlint-rules-grav-pages", + "version": "1.0.19", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "markdownlint-rules-grav-pages", + "version": "1.0.19", + "license": "BSD-3-Clause", + "dependencies": { + "jsonschema": "^1.2.5", + "markdown-it": "^12.3.2", + "markdownlint": "^0.25.1", + "markdownlint-cli": "^0.31.1", + "transliteration": "^2.1.8", + "yamljs": "^0.3.0" + }, + "devDependencies": { + "eslint": "^6.8.0", + "eslint-config-airbnb-base": "^14.1.0", + "eslint-plugin-import": "^2.20.1", + "husky": "^4.2.3", + "jest": "^28.1.0", + "standard-version": "^9.5.0" + } + }, + "node_modules/@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", + "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.12.tgz", + "integrity": "sha512-44ODe6O1IVz9s2oJE3rZ4trNNKTX9O7KpQpfAP4t8QII/zwrVRHL7i2pxhqtcY7tqMLrrKfMlBKnm1QlrRFs5w==", + "dev": true, + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.12", + "@babel/helper-compilation-targets": "^7.17.10", + "@babel/helper-module-transforms": "^7.17.12", + "@babel/helpers": "^7.17.9", + "@babel/parser": "^7.17.12", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.12", + "@babel/types": "^7.17.12", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.10.tgz", + "integrity": "sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ==", + "dev": true, + "dependencies": { + "@babel/compat-data": "^7.17.10", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.20.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "dependencies": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.12.tgz", + "integrity": "sha512-t5s2BeSWIghhFRPh9XMn6EIGmvn8Lmw5RVASJzkIx1mSemubQQBNIZiQD7WzaFmaHIrjAec4x8z9Yx8SjJ1/LA==", + "dev": true, + "dependencies": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.17.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.12", + "@babel/types": "^7.17.12" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz", + "integrity": "sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", + "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.17.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "dependencies": { + "@babel/types": "^7.22.5" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.9.tgz", + "integrity": "sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q==", + "dev": true, + "dependencies": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.9", + "@babel/types": "^7.17.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/parser": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", + "dev": true, + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.12.tgz", + "integrity": "sha512-TYY0SXFiO31YXtNg3HtFwNJHjLsAyIIhAhNWkQ5whPPS7HWUFlg9z0Ta4qAQNjQbP1wsSt/oKkmZ/4/WWdMUpw==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.17.12" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/types": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", + "dev": true, + "dependencies": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "node_modules/@hutson/parse-repository-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", + "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.0.tgz", + "integrity": "sha512-tscn3dlJFGay47kb4qVruQg/XWlmvU0xp3EJOjzzY+sBaI+YgwKcvAmTcyYU7xEiLLIY5HCdWRooAL8dqkFlDA==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.0", + "jest-util": "^28.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/console/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/console/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/console/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/console/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.0.tgz", + "integrity": "sha512-/2PTt0ywhjZ4NwNO4bUqD9IVJfmFVhVKGlhvSpmEfUCuxYf/3NHcKmRFI+I71lYzbTT3wMuYpETDCTHo81gC/g==", + "dev": true, + "dependencies": { + "@jest/console": "^28.1.0", + "@jest/reporters": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^28.0.2", + "jest-config": "^28.1.0", + "jest-haste-map": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.0", + "jest-resolve-dependencies": "^28.1.0", + "jest-runner": "^28.1.0", + "jest-runtime": "^28.1.0", + "jest-snapshot": "^28.1.0", + "jest-util": "^28.1.0", + "jest-validate": "^28.1.0", + "jest-watcher": "^28.1.0", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/core/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/core/node_modules/ci-info": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", + "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==", + "dev": true + }, + "node_modules/@jest/core/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/core/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/core/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/core/node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@jest/core/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/environment": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.0.tgz", + "integrity": "sha512-S44WGSxkRngzHslhV6RoAExekfF7Qhwa6R5+IYFa81mpcj0YgdBnRSmvHe3SNwOt64yXaE5GG8Y2xM28ii5ssA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "jest-mock": "^28.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/expect": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.0.tgz", + "integrity": "sha512-be9ETznPLaHOmeJqzYNIXv1ADEzENuQonIoobzThOYPuK/6GhrWNIJDVTgBLCrz3Am73PyEU2urQClZp0hLTtA==", + "dev": true, + "dependencies": { + "expect": "^28.1.0", + "jest-snapshot": "^28.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/expect-utils": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.0.tgz", + "integrity": "sha512-5BrG48dpC0sB80wpeIX5FU6kolDJI4K0n5BM9a5V38MGx0pyRvUBSS0u2aNTdDzmOrCjhOg8pGs6a20ivYkdmw==", + "dev": true, + "dependencies": { + "jest-get-type": "^28.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.0.tgz", + "integrity": "sha512-Xqsf/6VLeAAq78+GNPzI7FZQRf5cCHj1qgQxCjws9n8rKw8r1UYoeaALwBvyuzOkpU3c1I6emeMySPa96rxtIg==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.0", + "@sinonjs/fake-timers": "^9.1.1", + "@types/node": "*", + "jest-message-util": "^28.1.0", + "jest-mock": "^28.1.0", + "jest-util": "^28.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.0.tgz", + "integrity": "sha512-3m7sTg52OTQR6dPhsEQSxAvU+LOBbMivZBwOvKEZ+Rb+GyxVnXi9HKgOTYkx/S99T8yvh17U4tNNJPIEQmtwYw==", + "dev": true, + "dependencies": { + "@jest/environment": "^28.1.0", + "@jest/expect": "^28.1.0", + "@jest/types": "^28.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.0.tgz", + "integrity": "sha512-qxbFfqap/5QlSpIizH9c/bFCDKsQlM4uAKSOvZrP+nIdrjqre3FmKzpTtYyhsaVcOSNK7TTt2kjm+4BJIjysFA==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "@jridgewell/trace-mapping": "^0.3.7", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-util": "^28.1.0", + "jest-worker": "^28.1.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^9.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/reporters/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/reporters/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/reporters/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/reporters/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/schemas": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.0.2.tgz", + "integrity": "sha512-YVDJZjd4izeTDkij00vHHAymNXQ6WWsdChFRK86qck6Jpr3DCL5W3Is3vslviRlP+bLuMYRLbdp98amMvqudhA==", + "dev": true, + "dependencies": { + "@sinclair/typebox": "^0.23.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/source-map": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.0.2.tgz", + "integrity": "sha512-Y9dxC8ZpN3kImkk0LkK5XCEneYMAXlZ8m5bflmSL5vrwyeUpJfentacCUg6fOb8NOpOO7hz2+l37MV77T6BFPw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.7", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-result": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.0.tgz", + "integrity": "sha512-sBBFIyoPzrZho3N+80P35A5oAkSKlGfsEFfXFWuPGBsW40UAjCkGakZhn4UQK4iQlW2vgCDMRDOob9FGKV8YoQ==", + "dev": true, + "dependencies": { + "@jest/console": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.0.tgz", + "integrity": "sha512-tZCEiVWlWNTs/2iK9yi6o3AlMfbbYgV4uuZInSVdzZ7ftpHZhCMuhvk2HLYhCZzLgPFQ9MnM1YaxMnh3TILFiQ==", + "dev": true, + "dependencies": { + "@jest/test-result": "^28.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.0.tgz", + "integrity": "sha512-omy2xe5WxlAfqmsTjTPxw+iXRTRnf+NtX0ToG+4S0tABeb4KsKmPUHq5UBuwunHg3tJRwgEQhEp0M/8oiatLEA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/types": "^28.1.0", + "@jridgewell/trace-mapping": "^0.3.7", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.0", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/transform/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/transform/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/transform/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/transform/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/transform/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", + "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.0.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/@jest/types/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/@jest/types/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/@jest/types/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/@jest/types/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/types/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "dependencies": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/set-array": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", + "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "dev": true, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dev": true, + "dependencies": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "node_modules/@sinclair/typebox": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", + "integrity": "sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg==", + "dev": true + }, + "node_modules/@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@types/babel__core": { + "version": "7.1.19", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.17.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.1.tgz", + "integrity": "sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" + }, + "node_modules/@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "node_modules/@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "*" + } + }, + "node_modules/@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "node_modules/@types/node": { + "version": "17.0.34", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.34.tgz", + "integrity": "sha512-XImEz7XwTvDBtzlTnm8YvMqGW/ErMWBsKZ+hMTvnDIjGCKxwK5Xpc+c/oQjOauwq8M4OS11hEkpjX8rrI/eEgA==", + "dev": true + }, + "node_modules/@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "node_modules/@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "node_modules/@types/prettier": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.1.tgz", + "integrity": "sha512-XFjFHmaLVifrAKaZ+EKghFHtHSUonyw8P2Qmy2/+osBnrKbH9UYtlK10zg8/kCt47MFilll/DEDKy3DHfJ0URw==", + "dev": true + }, + "node_modules/@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "node_modules/@types/yargs": { + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", + "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "node_modules/acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-jsx": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", + "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0" + } + }, + "node_modules/add-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", + "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==", + "dev": true + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "dependencies": { + "type-fest": "^0.11.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/babel-jest": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.0.tgz", + "integrity": "sha512-zNKk0yhDZ6QUwfxh9k07GII6siNGMJWVUU49gmFj5gfdqDKLqa2RArXOF2CODp4Dr7dLxN2cvAV+667dGJ4b4w==", + "dev": true, + "dependencies": { + "@jest/transform": "^28.1.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^28.0.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/babel-jest/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/babel-jest/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/babel-jest/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/babel-jest/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-jest/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.0.2.tgz", + "integrity": "sha512-Kizhn/ZL+68ZQHxSnHyuvJv8IchXD62KQxV77TBDV/xoBFBOfgRAk97GNs6hXdTTCiVES9nB2I6+7MXXrk5llQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "dependencies": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.0.2.tgz", + "integrity": "sha512-sYzXIdgIXXroJTFeB3S6sNDWtlJ2dllCdTEsnZ65ACrMojj3hVNFRmnJ1HZtomGi+Be7aqpY/HJ92fr8OhKVkQ==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^28.0.2", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/browserslist": { + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", + "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001332", + "electron-to-chromium": "^1.4.118", + "escalade": "^3.1.1", + "node-releases": "^2.0.3", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001341", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001341.tgz", + "integrity": "sha512-2SodVrFFtvGENGCv0ChVJIDQ0KPaS1cg7/qtfMaICgeMolDdo/Z2OD32F0Aq9yl6F4YFwGPBS5AaPqNYiW4PoA==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "node_modules/cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "node_modules/cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } + }, + "node_modules/collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "node_modules/commander": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.0.0.tgz", + "integrity": "sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw==", + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "dependencies": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "node_modules/compare-versions": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", + "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", + "dev": true + }, + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "engines": [ + "node >= 6.0" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", + "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==", + "dev": true + }, + "node_modules/contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/conventional-changelog": { + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz", + "integrity": "sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==", + "dev": true, + "dependencies": { + "conventional-changelog-angular": "^5.0.12", + "conventional-changelog-atom": "^2.0.8", + "conventional-changelog-codemirror": "^2.0.8", + "conventional-changelog-conventionalcommits": "^4.5.0", + "conventional-changelog-core": "^4.2.1", + "conventional-changelog-ember": "^2.0.9", + "conventional-changelog-eslint": "^3.0.9", + "conventional-changelog-express": "^2.0.6", + "conventional-changelog-jquery": "^3.0.11", + "conventional-changelog-jshint": "^2.0.9", + "conventional-changelog-preset-loader": "^2.3.4" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-angular": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", + "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-atom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz", + "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-codemirror": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz", + "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-config-spec": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", + "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", + "dev": true + }, + "node_modules/conventional-changelog-conventionalcommits": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz", + "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0", + "lodash": "^4.17.15", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz", + "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==", + "dev": true, + "dependencies": { + "add-stream": "^1.0.0", + "conventional-changelog-writer": "^5.0.0", + "conventional-commits-parser": "^3.2.0", + "dateformat": "^3.0.0", + "get-pkg-repo": "^4.0.0", + "git-raw-commits": "^2.0.8", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^4.1.1", + "lodash": "^4.17.15", + "normalize-package-data": "^3.0.0", + "q": "^1.5.1", + "read-pkg": "^3.0.0", + "read-pkg-up": "^3.0.0", + "through2": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-core/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-core/node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-core/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/conventional-changelog-core/node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/conventional-changelog-core/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/conventional-changelog-core/node_modules/read-pkg/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/conventional-changelog-core/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-ember": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz", + "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-eslint": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz", + "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-express": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz", + "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-jquery": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz", + "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==", + "dev": true, + "dependencies": { + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-jshint": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz", + "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==", + "dev": true, + "dependencies": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-preset-loader": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", + "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-writer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz", + "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==", + "dev": true, + "dependencies": { + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + }, + "bin": { + "conventional-changelog-writer": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-changelog-writer/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "dev": true, + "dependencies": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-commits-parser": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", + "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", + "dev": true, + "dependencies": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "conventional-commits-parser": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/conventional-recommended-bump": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz", + "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==", + "dev": true, + "dependencies": { + "concat-stream": "^2.0.0", + "conventional-changelog-preset-loader": "^2.3.4", + "conventional-commits-filter": "^2.0.7", + "conventional-commits-parser": "^3.2.0", + "git-raw-commits": "^2.0.8", + "git-semver-tags": "^4.1.1", + "meow": "^8.0.0", + "q": "^1.5.1" + }, + "bin": { + "conventional-recommended-bump": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "dev": true, + "dependencies": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/cosmiconfig/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cosmiconfig/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "dependencies": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + }, + "engines": { + "node": ">=4.8" + } + }, + "node_modules/dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "deprecated": "Debug versions >=3.2.0 <3.2.7 || >=4 <4.3.1 have a low-severity ReDos regression when used in a Node.js environment. It is recommended you upgrade to 3.2.7 or 4.3.1. (https://github.com/visionmedia/debug/issues/797)", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decamelize-keys/node_modules/map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "node_modules/deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "node_modules/deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "dependencies": { + "object-keys": "^1.0.12" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/diff-sequences": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.0.2.tgz", + "integrity": "sha512-YtEoNynLDFCRznv/XDalsKGSZDoj0U5kLnXvY0JSq3nBboRrZXjD81+eSiwi+nzcZDwedMmcowcxNwwgFW23mQ==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotgitignore": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", + "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", + "dev": true, + "dependencies": { + "find-up": "^3.0.0", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dotgitignore/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dotgitignore/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/dotgitignore/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.137", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz", + "integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==", + "dev": true + }, + "node_modules/emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==", + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "dependencies": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-abstract/node_modules/has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-abstract/node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/eslint": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", + "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.3", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.2", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.3", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-airbnb-base": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.1.0.tgz", + "integrity": "sha512-+XCcfGyCnbzOnktDVhwsCAx+9DmrzEmuwxyHUJpw+kqBVT744OUBrB09khgFKlK1lshVww6qXGsYPZpavoNjJw==", + "dev": true, + "dependencies": { + "confusing-browser-globals": "^1.0.9", + "object.assign": "^4.1.0", + "object.entries": "^1.1.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "eslint": "^5.16.0 || ^6.8.0", + "eslint-plugin-import": "^2.20.1" + } + }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", + "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", + "dev": true, + "dependencies": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-module-utils": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz", + "integrity": "sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==", + "dev": true, + "dependencies": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-module-utils/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-plugin-import": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz", + "integrity": "sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw==", + "dev": true, + "dependencies": { + "array-includes": "^3.0.3", + "array.prototype.flat": "^1.2.1", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.1", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.12.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "2.x - 6.x" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "dependencies": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "dependencies": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/eslint/node_modules/globals": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz", + "integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==", + "dev": true, + "dependencies": { + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/eslint/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/espree": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", + "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", + "dev": true, + "dependencies": { + "acorn": "^7.1.0", + "acorn-jsx": "^5.1.0", + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "dependencies": { + "estraverse": "^4.0.0" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "dependencies": { + "estraverse": "^4.1.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/execa/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/execa/node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expect": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.0.tgz", + "integrity": "sha512-qFXKl8Pmxk8TBGfaFKRtcQjfXEnKAs+dmlxdwvukJZorwrAabT7M3h8oLOG01I2utEhkmUTi17CHaPBovZsKdw==", + "dev": true, + "dependencies": { + "@jest/expect-utils": "^28.1.0", + "jest-get-type": "^28.0.2", + "jest-matcher-utils": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-util": "^28.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "node_modules/fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "node_modules/figures": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", + "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "dependencies": { + "flat-cache": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/find-up/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "engines": { + "node": ">=8" + } + }, + "node_modules/find-versions": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", + "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", + "dev": true, + "dependencies": { + "semver-regex": "^3.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "dependencies": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "hasInstallScript": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "node_modules/gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-pkg-repo": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", + "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", + "dev": true, + "dependencies": { + "@hutson/parse-repository-url": "^3.0.0", + "hosted-git-info": "^4.0.0", + "through2": "^2.0.0", + "yargs": "^16.2.0" + }, + "bin": { + "get-pkg-repo": "src/cli.js" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/get-pkg-repo/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/get-pkg-repo/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/get-pkg-repo/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/get-pkg-repo/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/get-pkg-repo/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/get-pkg-repo/node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "dependencies": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "node_modules/get-pkg-repo/node_modules/string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/get-pkg-repo/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/get-pkg-repo/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/get-pkg-repo/node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/get-pkg-repo/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/get-pkg-repo/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/get-stdin": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/git-raw-commits": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", + "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "dev": true, + "dependencies": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + }, + "bin": { + "git-raw-commits": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", + "dev": true, + "dependencies": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/git-semver-tags": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", + "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", + "dev": true, + "dependencies": { + "meow": "^8.0.0", + "semver": "^6.0.0" + }, + "bin": { + "git-semver-tags": "cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/git-semver-tags/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/gitconfiglocal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", + "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", + "dev": true, + "dependencies": { + "ini": "^1.3.2" + } + }, + "node_modules/gitconfiglocal/node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "node_modules/handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/husky": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", + "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "compare-versions": "^3.6.0", + "cosmiconfig": "^7.0.0", + "find-versions": "^4.0.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^5.0.0", + "please-upgrade-node": "^3.2.0", + "slash": "^3.0.0", + "which-pm-runs": "^1.0.0" + }, + "bin": { + "husky-run": "bin/run.js", + "husky-upgrade": "lib/upgrader/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/husky" + } + }, + "node_modules/husky/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/husky/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/husky/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/husky/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/husky/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/husky/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/husky/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/husky/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/husky/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/husky/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/husky/node_modules/pkg-dir": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "dev": true, + "dependencies": { + "find-up": "^5.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/husky/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-local/node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "dependencies": { + "find-up": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "node_modules/ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/inquirer": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.1.tgz", + "integrity": "sha512-V1FFQ3TIO15det8PijPLFR9M9baSlnRs9nL7zWu1MNVA2T9YVl9ZbrHJhYs7e9X8jeMZ3lr2JH/rdHFgNCBdYw==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^2.4.2", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.2.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/inquirer/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/inquirer/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "node_modules/is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "node_modules/is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "dev": true, + "dependencies": { + "text-extensions": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", + "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", + "dev": true, + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-report/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", + "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.0.tgz", + "integrity": "sha512-TZR+tHxopPhzw3c3560IJXZWLNHgpcz1Zh0w5A65vynLGNcg/5pZ+VildAd7+XGOu6jd58XMY/HNn0IkZIXVXg==", + "dev": true, + "dependencies": { + "@jest/core": "^28.1.0", + "import-local": "^3.0.2", + "jest-cli": "^28.1.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.0.2.tgz", + "integrity": "sha512-QX9u+5I2s54ZnGoMEjiM2WeBvJR2J7w/8ZUmH2um/WLAuGAYFQcsVXY9+1YL6k0H/AGUdH8pXUAv6erDqEsvIA==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "throat": "^6.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-circus": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.0.tgz", + "integrity": "sha512-rNYfqfLC0L0zQKRKsg4n4J+W1A2fbyGH7Ss/kDIocp9KXD9iaL111glsLu7+Z7FHuZxwzInMDXq+N1ZIBkI/TQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^28.1.0", + "@jest/expect": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^28.1.0", + "jest-matcher-utils": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-runtime": "^28.1.0", + "jest-snapshot": "^28.1.0", + "jest-util": "^28.1.0", + "pretty-format": "^28.1.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-circus/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-circus/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-circus/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-circus/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-circus/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.0.tgz", + "integrity": "sha512-fDJRt6WPRriHrBsvvgb93OxgajHHsJbk4jZxiPqmZbMDRcHskfJBBfTyjFko0jjfprP544hOktdSi9HVgl4VUQ==", + "dev": true, + "dependencies": { + "@jest/core": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/types": "^28.1.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^28.1.0", + "jest-util": "^28.1.0", + "jest-validate": "^28.1.0", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-cli/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/jest-cli/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-cli/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-cli/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-cli/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/jest-cli/node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-cli/node_modules/yargs": { + "version": "17.5.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", + "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-cli/node_modules/yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "dev": true, + "engines": { + "node": ">=12" + } + }, + "node_modules/jest-config": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.0.tgz", + "integrity": "sha512-aOV80E9LeWrmflp7hfZNn/zGA4QKv/xsn2w8QCBP0t0+YqObuCWTSgNbHJ0j9YsTuCO08ZR/wsvlxqqHX20iUA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^28.1.0", + "@jest/types": "^28.1.0", + "babel-jest": "^28.1.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^28.1.0", + "jest-environment-node": "^28.1.0", + "jest-get-type": "^28.0.2", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.0", + "jest-runner": "^28.1.0", + "jest-util": "^28.1.0", + "jest-validate": "^28.1.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^28.1.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "peerDependencies": { + "@types/node": "*", + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-config/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-config/node_modules/ci-info": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", + "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==", + "dev": true + }, + "node_modules/jest-config/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-config/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-config/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-config/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-config/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.0.tgz", + "integrity": "sha512-8eFd3U3OkIKRtlasXfiAQfbovgFgRDb0Ngcs2E+FMeBZ4rUezqIaGjuyggJBp+llosQXNEWofk/Sz4Hr5gMUhA==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^28.0.2", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-diff/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-diff/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-diff/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-diff/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-diff/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-docblock": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.0.2.tgz", + "integrity": "sha512-FH10WWw5NxLoeSdQlJwu+MTiv60aXV/t8KEwIRGEv74WARE1cXIqh1vGdy2CraHuWOOrnzTWj/azQKqW4fO7xg==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-each": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.0.tgz", + "integrity": "sha512-a/XX02xF5NTspceMpHujmOexvJ4GftpYXqr6HhhmKmExtMXsyIN/fvanQlt/BcgFoRKN4OCXxLQKth9/n6OPFg==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.0", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "jest-util": "^28.1.0", + "pretty-format": "^28.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-each/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-each/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-each/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-each/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-each/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-environment-node": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.0.tgz", + "integrity": "sha512-gBLZNiyrPw9CSMlTXF1yJhaBgWDPVvH0Pq6bOEwGMXaYNzhzhw2kA/OijNF8egbCgDS0/veRv97249x2CX+udQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^28.1.0", + "@jest/fake-timers": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "jest-mock": "^28.1.0", + "jest-util": "^28.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.0.tgz", + "integrity": "sha512-xyZ9sXV8PtKi6NCrJlmq53PyNVHzxmcfXNVvIRHpHmh1j/HChC4pwKgyjj7Z9us19JMw8PpQTJsFWOsIfT93Dw==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.0", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.0", + "jest-worker": "^28.1.0", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-leak-detector": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.0.tgz", + "integrity": "sha512-uIJDQbxwEL2AMMs2xjhZl2hw8s77c3wrPaQ9v6tXJLGaaQ+4QrNJH5vuw7hA7w/uGT/iJ42a83opAqxGHeyRIA==", + "dev": true, + "dependencies": { + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.0.tgz", + "integrity": "sha512-onnax0n2uTLRQFKAjC7TuaxibrPSvZgKTcSCnNUz/tOjJ9UhxNm7ZmPpoQavmTDUjXvUQ8KesWk2/VdrxIFzTQ==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^28.1.0", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-matcher-utils/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-matcher-utils/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-matcher-utils/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", + "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.0", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-message-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-message-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-message-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-message-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-message-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-mock": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.0.tgz", + "integrity": "sha512-H7BrhggNn77WhdL7O1apG0Q/iwl0Bdd5E1ydhCJzL3oBLh/UYxAwR3EJLsBZ9XA3ZU4PA3UNw4tQjduBTCTmLw==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.0", + "@types/node": "*" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "dev": true, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.0.tgz", + "integrity": "sha512-vvfN7+tPNnnhDvISuzD1P+CRVP8cK0FHXRwPAcdDaQv4zgvwvag2n55/h5VjYcM5UJG7L4TwE5tZlzcI0X2Lhw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^28.1.0", + "jest-validate": "^28.1.0", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.0.tgz", + "integrity": "sha512-Ue1VYoSZquPwEvng7Uefw8RmZR+me/1kr30H2jMINjGeHgeO/JgrR6wxj2ofkJ7KSAA11W3cOrhNCbj5Dqqd9g==", + "dev": true, + "dependencies": { + "jest-regex-util": "^28.0.2", + "jest-snapshot": "^28.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-resolve/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-resolve/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-resolve/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-resolve/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-resolve/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.0.tgz", + "integrity": "sha512-FBpmuh1HB2dsLklAlRdOxNTTHKFR6G1Qmd80pVDvwbZXTriqjWqjei5DKFC1UlM732KjYcE6yuCdiF0WUCOS2w==", + "dev": true, + "dependencies": { + "@jest/console": "^28.1.0", + "@jest/environment": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "graceful-fs": "^4.2.9", + "jest-docblock": "^28.0.2", + "jest-environment-node": "^28.1.0", + "jest-haste-map": "^28.1.0", + "jest-leak-detector": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-resolve": "^28.1.0", + "jest-runtime": "^28.1.0", + "jest-util": "^28.1.0", + "jest-watcher": "^28.1.0", + "jest-worker": "^28.1.0", + "source-map-support": "0.5.13", + "throat": "^6.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-runner/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runner/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runner/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runner/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runner/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.0.tgz", + "integrity": "sha512-wNYDiwhdH/TV3agaIyVF0lsJ33MhyujOe+lNTUiolqKt8pchy1Hq4+tDMGbtD5P/oNLA3zYrpx73T9dMTOCAcg==", + "dev": true, + "dependencies": { + "@jest/environment": "^28.1.0", + "@jest/fake-timers": "^28.1.0", + "@jest/globals": "^28.1.0", + "@jest/source-map": "^28.0.2", + "@jest/test-result": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-mock": "^28.1.0", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.0", + "jest-snapshot": "^28.1.0", + "jest-util": "^28.1.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-runtime/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-runtime/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-runtime/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-runtime/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-runtime/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.0.tgz", + "integrity": "sha512-ex49M2ZrZsUyQLpLGxQtDbahvgBjlLPgklkqGM0hq/F7W/f8DyqZxVHjdy19QKBm4O93eDp+H5S23EiTbbUmHw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^28.1.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^28.1.0", + "jest-get-type": "^28.0.2", + "jest-haste-map": "^28.1.0", + "jest-matcher-utils": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-util": "^28.1.0", + "natural-compare": "^1.4.0", + "pretty-format": "^28.1.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-snapshot/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-snapshot/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-snapshot/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-snapshot/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest-snapshot/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", + "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-util/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-util/node_modules/ci-info": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", + "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==", + "dev": true + }, + "node_modules/jest-util/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-util/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-util/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-util/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.0.tgz", + "integrity": "sha512-Lly7CJYih3vQBfjLeANGgBSBJ7pEa18cxpQfQEq2go2xyEzehnHfQTjoUia8xUv4x4J80XKFIDwJJThXtRFQXQ==", + "dev": true, + "dependencies": { + "@jest/types": "^28.1.0", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "leven": "^3.1.0", + "pretty-format": "^28.1.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-validate/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-validate/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-validate/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-validate/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-validate/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-validate/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.0.tgz", + "integrity": "sha512-tNHMtfLE8Njcr2IRS+5rXYA4BhU90gAOwI9frTGOqd+jX0P/Au/JfRSNqsf5nUTcWdbVYuLxS1KjnzILSoR5hA==", + "dev": true, + "dependencies": { + "@jest/test-result": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.0", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-watcher/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/jest-watcher/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/jest-watcher/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/jest-watcher/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-watcher/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.0.tgz", + "integrity": "sha512-ZHwM6mNwaWBR52Snff8ZvsCTqQsvhCxP/bT1I6T6DAnb6ygkshsyLQIMxFwHpYxht0HOoqt23JlC01viI7T03A==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/jest-worker/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "node_modules/js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true, + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "node_modules/json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "node_modules/json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true, + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonc-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==" + }, + "node_modules/jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true, + "engines": [ + "node >= 0.2.0" + ] + }, + "node_modules/jsonschema": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.5.tgz", + "integrity": "sha512-kVTF+08x25PQ0CjuVc0gRM9EUPb0Fe9Ln/utFOgcdxEIOHuU7ooBk/UPTd7t1M91pP35m0MU1T8M5P7vP1bRRw==", + "engines": { + "node": "*" + } + }, + "node_modules/JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "dependencies": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + }, + "bin": { + "JSONStream": "bin.js" + }, + "engines": { + "node": "*" + } + }, + "node_modules/kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "node_modules/linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "dependencies": { + "uc.micro": "^1.0.1" + } + }, + "node_modules/load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "node_modules/lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=", + "dev": true + }, + "node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "dependencies": { + "tmpl": "1.0.5" + } + }, + "node_modules/map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "dependencies": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "bin": { + "markdown-it": "bin/markdown-it.js" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/markdownlint": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.25.1.tgz", + "integrity": "sha512-AG7UkLzNa1fxiOv5B+owPsPhtM4D6DoODhsJgiaNg1xowXovrYgOnLqAgOOFQpWOlHFVQUzjMY5ypNNTeov92g==", + "dependencies": { + "markdown-it": "12.3.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/markdownlint-cli": { + "version": "0.31.1", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.31.1.tgz", + "integrity": "sha512-keIOMwQn+Ch7MoBwA+TdkyVMuxAeZFEGmIIlvwgV0Z1TGS5MxPnRr29XCLhkNzCHU+uNKGjU+VEjLX+Z9kli6g==", + "dependencies": { + "commander": "~9.0.0", + "get-stdin": "~9.0.0", + "glob": "~7.2.0", + "ignore": "~5.2.0", + "js-yaml": "^4.1.0", + "jsonc-parser": "~3.0.0", + "markdownlint": "~0.25.1", + "markdownlint-rule-helpers": "~0.16.0", + "minimatch": "~3.0.5", + "run-con": "~1.2.10" + }, + "bin": { + "markdownlint": "markdownlint.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/markdownlint-cli/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "node_modules/markdownlint-cli/node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "engines": { + "node": ">= 4" + } + }, + "node_modules/markdownlint-cli/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/markdownlint-cli/node_modules/minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/markdownlint-rule-helpers": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.16.0.tgz", + "integrity": "sha512-oEacRUVeTJ5D5hW1UYd2qExYI0oELdYK72k1TKGvIeYJIbqQWAz476NAc7LNixSySUhcNl++d02DvX0ccDk9/w==" + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, + "node_modules/meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "dependencies": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/read-pkg-up/node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/read-pkg/node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "node_modules/meow/node_modules/read-pkg/node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/meow/node_modules/read-pkg/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/meow/node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/meow/node_modules/semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "node_modules/minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node_modules/node-releases": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz", + "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==", + "dev": true + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "node_modules/normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.entries": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz", + "integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opencollective-postinstall": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", + "dev": true, + "bin": { + "opencollective-postinstall": "index.js" + } + }, + "node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "dependencies": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-try": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "dependencies": { + "error-ex": "^1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "node_modules/path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "dependencies": { + "pify": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "dependencies": { + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pkg-dir/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "dependencies": { + "semver-compare": "^1.0.0" + } + }, + "node_modules/prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/pretty-format": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.0.tgz", + "integrity": "sha512-79Z4wWOYCdvQkEoEuSlBhHJqWeZ8D8YRPiPctJFCtvuaClGpiwiQYSCUOE6IEKUbbFukKOTFIUAXE8N4EQTo1Q==", + "dev": true, + "dependencies": { + "@jest/schemas": "^28.0.2", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0" + } + }, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "dependencies": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true, + "engines": { + "node": ">=0.6.0", + "teleport": ">=0.2.0" + } + }, + "node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/react-is": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", + "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", + "dev": true + }, + "node_modules/read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "dependencies": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/read-pkg-up/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "dependencies": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true, + "engines": { + "node": ">=6.5.0" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "node_modules/resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-cwd/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "dependencies": { + "is-promise": "^2.1.0" + }, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/run-con": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.2.10.tgz", + "integrity": "sha512-n7PZpYmMM26ZO21dd8y3Yw1TRtGABjRtgPSgFS/nhzfvbJMXFtJhJVyEgayMiP+w/23craJjsnfDvx4W4ue/HQ==", + "dependencies": { + "deep-extend": "^0.6.0", + "ini": "~2.0.0", + "minimist": "^1.2.5", + "strip-json-comments": "~3.1.1" + }, + "bin": { + "run-con": "cli.js" + } + }, + "node_modules/rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "node_modules/semver-regex": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz", + "integrity": "sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/spdx-correct": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz", + "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==", + "dev": true, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "node_modules/spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz", + "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==", + "dev": true + }, + "node_modules/split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "dependencies": { + "through": "2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "dependencies": { + "readable-stream": "^3.0.0" + } + }, + "node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "node_modules/stack-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/standard-version": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.5.0.tgz", + "integrity": "sha512-3zWJ/mmZQsOaO+fOlsa0+QK90pwhNd042qEcw6hKFNoLFs7peGyvPffpEBbK/DSGPbyOvli0mUIFv5A4qTjh2Q==", + "dev": true, + "dependencies": { + "chalk": "^2.4.2", + "conventional-changelog": "3.1.25", + "conventional-changelog-config-spec": "2.1.0", + "conventional-changelog-conventionalcommits": "4.6.3", + "conventional-recommended-bump": "6.1.0", + "detect-indent": "^6.0.0", + "detect-newline": "^3.1.0", + "dotgitignore": "^2.1.0", + "figures": "^3.1.0", + "find-up": "^5.0.0", + "git-semver-tags": "^4.0.0", + "semver": "^7.1.1", + "stringify-package": "^1.0.1", + "yargs": "^16.0.0" + }, + "bin": { + "standard-version": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/standard-version/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/standard-version/node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "node_modules/standard-version/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/standard-version/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/standard-version/node_modules/find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/standard-version/node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/standard-version/node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/standard-version/node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/standard-version/node_modules/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/standard-version/node_modules/semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/standard-version/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/standard-version/node_modules/y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/standard-version/node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/standard-version/node_modules/yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.2.0" + } + }, + "node_modules/string_decoder/node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "node_modules/string-width/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "engines": { + "node": ">=8" + } + }, + "node_modules/string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-package": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz", + "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==", + "dev": true + }, + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "dependencies": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/table/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/table/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/table/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "node_modules/to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/transliteration": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/transliteration/-/transliteration-2.1.8.tgz", + "integrity": "sha512-ds3uRxcS0yCxzP4xP30dz+ImEeVhgAwSaewhlApuYYTUuT8+wFFLoFfO1nHvfJzbpoRBp4lS52Ai3wm8IkemIQ==", + "dependencies": { + "yargs": "^15.0.2" + }, + "bin": { + "slugify": "dist/bin/slugify", + "transliterate": "dist/bin/transliterate" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "node_modules/type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "node_modules/uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, + "node_modules/uglify-js": { + "version": "3.15.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.5.tgz", + "integrity": "sha512-hNM5q5GbBRB5xB+PMqVRcgYe4c8jbyZ1pzZhS6jbq54/4F2gFK869ZheiE5A8/t+W5jtTNpWef/5Q9zk639FNQ==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz", + "integrity": "sha512-HcvgY/xaRm7isYmyx+lFKA4uQmfUbN0J4M0nNItvzTvH/iQ9kW5j/t4YSR+Ge323/lrgDAWJoF46tzGQHwBHFw==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.7", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "node_modules/which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "dev": true + }, + "node_modules/word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dependencies": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "node_modules/write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/write-file-atomic": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", + "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16" + } + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "node_modules/y18n": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==" + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/yamljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", + "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", + "dependencies": { + "argparse": "^1.0.7", + "glob": "^7.0.5" + }, + "bin": { + "json2yaml": "bin/json2yaml", + "yaml2json": "bin/yaml2json" + } + }, + "node_modules/yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dependencies": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dependencies": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + } + }, + "dependencies": { + "@ampproject/remapping": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", + "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.1.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@babel/code-frame": { + "version": "7.22.13", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.22.13.tgz", + "integrity": "sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==", + "dev": true, + "requires": { + "@babel/highlight": "^7.22.13", + "chalk": "^2.4.2" + } + }, + "@babel/compat-data": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.17.10.tgz", + "integrity": "sha512-GZt/TCsG70Ms19gfZO1tM4CVnXsPgEPBCpJu+Qz3L0LUDsY5nZqFZglIoPC1kIYOtNBZlrnFT+klg12vFGZXrw==", + "dev": true + }, + "@babel/core": { + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.12.tgz", + "integrity": "sha512-44ODe6O1IVz9s2oJE3rZ4trNNKTX9O7KpQpfAP4t8QII/zwrVRHL7i2pxhqtcY7tqMLrrKfMlBKnm1QlrRFs5w==", + "dev": true, + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.12", + "@babel/helper-compilation-targets": "^7.17.10", + "@babel/helper-module-transforms": "^7.17.12", + "@babel/helpers": "^7.17.9", + "@babel/parser": "^7.17.12", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.12", + "@babel/types": "^7.17.12", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.23.0.tgz", + "integrity": "sha512-lN85QRR+5IbYrMWM6Y4pE/noaQtg4pNiqeNGX60eqOfo6gtEj6uw/JagelB8vVztSd7R6M5n1+PQkDbHbBRU4g==", + "dev": true, + "requires": { + "@babel/types": "^7.23.0", + "@jridgewell/gen-mapping": "^0.3.2", + "@jridgewell/trace-mapping": "^0.3.17", + "jsesc": "^2.5.1" + }, + "dependencies": { + "@jridgewell/gen-mapping": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.3.tgz", + "integrity": "sha512-HLhSWOLRi875zjjMG/r+Nv0oCW8umGb0BgEhyX3dDX3egwZtB8PqLnjz3yedt8R5StBrzcg4aBpnh8UA9D1BoQ==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + } + } + }, + "@babel/helper-compilation-targets": { + "version": "7.17.10", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.17.10.tgz", + "integrity": "sha512-gh3RxjWbauw/dFiU/7whjd0qN9K6nPJMqe6+Er7rOavFh0CQUSwhAE3IcTho2rywPJFxej6TUUHDkWcYI6gGqQ==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.17.10", + "@babel/helper-validator-option": "^7.16.7", + "browserslist": "^4.20.2", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@babel/helper-environment-visitor": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.22.20.tgz", + "integrity": "sha512-zfedSIzFhat/gFhWfHtgWvlec0nqB9YEIVrpuwjruLlXfUSnA8cJB0miHKwqDnQ7d32aKo2xt88/xZptwxbfhA==", + "dev": true + }, + "@babel/helper-function-name": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.23.0.tgz", + "integrity": "sha512-OErEqsrxjZTJciZ4Oo+eoZqeW9UIiOcuYKRJA4ZAgV9myA+pOXhhmpfNCKjEH/auVfEYVFJ6y1Tc4r0eIApqiw==", + "dev": true, + "requires": { + "@babel/template": "^7.22.15", + "@babel/types": "^7.23.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.22.5.tgz", + "integrity": "sha512-wGjk9QZVzvknA6yKIUURb8zY3grXCcOZt+/7Wcy8O2uctxhplmUPkOdlgoNhmdVee2c92JXbf1xpMtVNbfoxRw==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-module-imports": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.16.7.tgz", + "integrity": "sha512-LVtS6TqjJHFc+nYeITRo6VLXve70xmq7wPhWTqDJusJEgGmkAACWwMiTNrvfoQo6hEhFwAIixNkvB0jPXDL8Wg==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + } + }, + "@babel/helper-module-transforms": { + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.17.12.tgz", + "integrity": "sha512-t5s2BeSWIghhFRPh9XMn6EIGmvn8Lmw5RVASJzkIx1mSemubQQBNIZiQD7WzaFmaHIrjAec4x8z9Yx8SjJ1/LA==", + "dev": true, + "requires": { + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-module-imports": "^7.16.7", + "@babel/helper-simple-access": "^7.17.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/helper-validator-identifier": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.12", + "@babel/types": "^7.17.12" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.17.12.tgz", + "integrity": "sha512-JDkf04mqtN3y4iAbO1hv9U2ARpPyPL1zqyWs/2WG1pgSq9llHFjStX5jdxb84himgJm+8Ng+x0oiWF/nw/XQKA==", + "dev": true + }, + "@babel/helper-simple-access": { + "version": "7.17.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.17.7.tgz", + "integrity": "sha512-txyMCGroZ96i+Pxr3Je3lzEJjqwaRC9buMUgtomcrLe5Nd0+fk1h0LLA+ixUF5OW7AhHuQ7Es1WcQJZmZsz2XA==", + "dev": true, + "requires": { + "@babel/types": "^7.17.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.22.6", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.22.6.tgz", + "integrity": "sha512-AsUnxuLhRYsisFiaJwvp1QF+I3KjD5FOxut14q/GzovUe6orHLesW2C7d754kRm53h5gqrz6sFl6sxc4BVtE/g==", + "dev": true, + "requires": { + "@babel/types": "^7.22.5" + } + }, + "@babel/helper-string-parser": { + "version": "7.22.5", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.22.5.tgz", + "integrity": "sha512-mM4COjgZox8U+JcXQwPijIZLElkgEpO5rsERVDJTc2qfCDfERyob6k5WegS14SX18IIjv+XD+GrqNumY5JRCDw==", + "dev": true + }, + "@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true + }, + "@babel/helper-validator-option": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.16.7.tgz", + "integrity": "sha512-TRtenOuRUVo9oIQGPC5G9DgK4743cdxvtOw0weQNpZXaS16SCBi5MNjZF8vba3ETURjZpTbVn7Vvcf2eAwFozQ==", + "dev": true + }, + "@babel/helpers": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.9.tgz", + "integrity": "sha512-cPCt915ShDWUEzEp3+UNRktO2n6v49l5RSnG9M5pS24hA+2FAc5si+Pn1i4VVbQQ+jh+bIZhPFQOJOzbrOYY1Q==", + "dev": true, + "requires": { + "@babel/template": "^7.16.7", + "@babel/traverse": "^7.17.9", + "@babel/types": "^7.17.0" + } + }, + "@babel/highlight": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.22.20.tgz", + "integrity": "sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", + "integrity": "sha512-vvPKKdMemU85V9WE/l5wZEmImpCtLqbnTvqDS2U1fJ96KrxoW7KrXhNsNCblQlg8Ck4b85yxdTyelsMUgFUXiw==", + "dev": true + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-bigint": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", + "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.12.13", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", + "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.12.13" + } + }, + "@babel/plugin-syntax-import-meta": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", + "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-logical-assignment-operators": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", + "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", + "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.4" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.14.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", + "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.14.5" + } + }, + "@babel/plugin-syntax-typescript": { + "version": "7.17.12", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.17.12.tgz", + "integrity": "sha512-TYY0SXFiO31YXtNg3HtFwNJHjLsAyIIhAhNWkQ5whPPS7HWUFlg9z0Ta4qAQNjQbP1wsSt/oKkmZ/4/WWdMUpw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.17.12" + } + }, + "@babel/template": { + "version": "7.22.15", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.22.15.tgz", + "integrity": "sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.13", + "@babel/parser": "^7.22.15", + "@babel/types": "^7.22.15" + } + }, + "@babel/traverse": { + "version": "7.23.2", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.23.2.tgz", + "integrity": "sha512-azpe59SQ48qG6nu2CzcMLbxUudtN+dOM9kDbUqGq3HXUJRlo7i8fvPoxQUzYgLZ4cMVmuZgm8vvBpNeRhd6XSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.22.13", + "@babel/generator": "^7.23.0", + "@babel/helper-environment-visitor": "^7.22.20", + "@babel/helper-function-name": "^7.23.0", + "@babel/helper-hoist-variables": "^7.22.5", + "@babel/helper-split-export-declaration": "^7.22.6", + "@babel/parser": "^7.23.0", + "@babel/types": "^7.23.0", + "debug": "^4.1.0", + "globals": "^11.1.0" + } + }, + "@babel/types": { + "version": "7.23.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.23.0.tgz", + "integrity": "sha512-0oIyUfKoI3mSqMvsxBdclDwxXKXAUA8v/apZbc+iSyARYou1o8ZGDxbUYyLFoW2arqS2jDGqJuZvv1d/io1axg==", + "dev": true, + "requires": { + "@babel/helper-string-parser": "^7.22.5", + "@babel/helper-validator-identifier": "^7.22.20", + "to-fast-properties": "^2.0.0" + } + }, + "@bcoe/v8-coverage": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", + "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", + "dev": true + }, + "@hutson/parse-repository-url": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@hutson/parse-repository-url/-/parse-repository-url-3.0.2.tgz", + "integrity": "sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==", + "dev": true + }, + "@istanbuljs/load-nyc-config": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "find-up": "^4.1.0", + "get-package-type": "^0.1.0", + "js-yaml": "^3.13.1", + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "@istanbuljs/schema": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", + "dev": true + }, + "@jest/console": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-28.1.0.tgz", + "integrity": "sha512-tscn3dlJFGay47kb4qVruQg/XWlmvU0xp3EJOjzzY+sBaI+YgwKcvAmTcyYU7xEiLLIY5HCdWRooAL8dqkFlDA==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^28.1.0", + "jest-util": "^28.1.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/core": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-28.1.0.tgz", + "integrity": "sha512-/2PTt0ywhjZ4NwNO4bUqD9IVJfmFVhVKGlhvSpmEfUCuxYf/3NHcKmRFI+I71lYzbTT3wMuYpETDCTHo81gC/g==", + "dev": true, + "requires": { + "@jest/console": "^28.1.0", + "@jest/reporters": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^28.0.2", + "jest-config": "^28.1.0", + "jest-haste-map": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.0", + "jest-resolve-dependencies": "^28.1.0", + "jest-runner": "^28.1.0", + "jest-runtime": "^28.1.0", + "jest-snapshot": "^28.1.0", + "jest-util": "^28.1.0", + "jest-validate": "^28.1.0", + "jest-watcher": "^28.1.0", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.0", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", + "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/environment": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-28.1.0.tgz", + "integrity": "sha512-S44WGSxkRngzHslhV6RoAExekfF7Qhwa6R5+IYFa81mpcj0YgdBnRSmvHe3SNwOt64yXaE5GG8Y2xM28ii5ssA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "jest-mock": "^28.1.0" + } + }, + "@jest/expect": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-28.1.0.tgz", + "integrity": "sha512-be9ETznPLaHOmeJqzYNIXv1ADEzENuQonIoobzThOYPuK/6GhrWNIJDVTgBLCrz3Am73PyEU2urQClZp0hLTtA==", + "dev": true, + "requires": { + "expect": "^28.1.0", + "jest-snapshot": "^28.1.0" + } + }, + "@jest/expect-utils": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-28.1.0.tgz", + "integrity": "sha512-5BrG48dpC0sB80wpeIX5FU6kolDJI4K0n5BM9a5V38MGx0pyRvUBSS0u2aNTdDzmOrCjhOg8pGs6a20ivYkdmw==", + "dev": true, + "requires": { + "jest-get-type": "^28.0.2" + } + }, + "@jest/fake-timers": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-28.1.0.tgz", + "integrity": "sha512-Xqsf/6VLeAAq78+GNPzI7FZQRf5cCHj1qgQxCjws9n8rKw8r1UYoeaALwBvyuzOkpU3c1I6emeMySPa96rxtIg==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "@sinonjs/fake-timers": "^9.1.1", + "@types/node": "*", + "jest-message-util": "^28.1.0", + "jest-mock": "^28.1.0", + "jest-util": "^28.1.0" + } + }, + "@jest/globals": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-28.1.0.tgz", + "integrity": "sha512-3m7sTg52OTQR6dPhsEQSxAvU+LOBbMivZBwOvKEZ+Rb+GyxVnXi9HKgOTYkx/S99T8yvh17U4tNNJPIEQmtwYw==", + "dev": true, + "requires": { + "@jest/environment": "^28.1.0", + "@jest/expect": "^28.1.0", + "@jest/types": "^28.1.0" + } + }, + "@jest/reporters": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-28.1.0.tgz", + "integrity": "sha512-qxbFfqap/5QlSpIizH9c/bFCDKsQlM4uAKSOvZrP+nIdrjqre3FmKzpTtYyhsaVcOSNK7TTt2kjm+4BJIjysFA==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "@jridgewell/trace-mapping": "^0.3.7", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.1.3", + "jest-util": "^28.1.0", + "jest-worker": "^28.1.0", + "slash": "^3.0.0", + "string-length": "^4.0.1", + "strip-ansi": "^6.0.0", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^9.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/schemas": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-28.0.2.tgz", + "integrity": "sha512-YVDJZjd4izeTDkij00vHHAymNXQ6WWsdChFRK86qck6Jpr3DCL5W3Is3vslviRlP+bLuMYRLbdp98amMvqudhA==", + "dev": true, + "requires": { + "@sinclair/typebox": "^0.23.3" + } + }, + "@jest/source-map": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-28.0.2.tgz", + "integrity": "sha512-Y9dxC8ZpN3kImkk0LkK5XCEneYMAXlZ8m5bflmSL5vrwyeUpJfentacCUg6fOb8NOpOO7hz2+l37MV77T6BFPw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.7", + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9" + } + }, + "@jest/test-result": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-28.1.0.tgz", + "integrity": "sha512-sBBFIyoPzrZho3N+80P35A5oAkSKlGfsEFfXFWuPGBsW40UAjCkGakZhn4UQK4iQlW2vgCDMRDOob9FGKV8YoQ==", + "dev": true, + "requires": { + "@jest/console": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-28.1.0.tgz", + "integrity": "sha512-tZCEiVWlWNTs/2iK9yi6o3AlMfbbYgV4uuZInSVdzZ7ftpHZhCMuhvk2HLYhCZzLgPFQ9MnM1YaxMnh3TILFiQ==", + "dev": true, + "requires": { + "@jest/test-result": "^28.1.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.0", + "slash": "^3.0.0" + } + }, + "@jest/transform": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-28.1.0.tgz", + "integrity": "sha512-omy2xe5WxlAfqmsTjTPxw+iXRTRnf+NtX0ToG+4S0tABeb4KsKmPUHq5UBuwunHg3tJRwgEQhEp0M/8oiatLEA==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/types": "^28.1.0", + "@jridgewell/trace-mapping": "^0.3.7", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.0", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.0", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "write-file-atomic": "^4.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jest/types": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-28.1.0.tgz", + "integrity": "sha512-xmEggMPr317MIOjjDoZ4ejCSr9Lpbt/u34+dvc99t7DS8YirW5rwZEhzKPC2BMUFkUhI48qs6qLUSGw5FuL0GA==", + "dev": true, + "requires": { + "@jest/schemas": "^28.0.2", + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^17.0.8", + "chalk": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "@jridgewell/gen-mapping": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", + "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "dev": true, + "requires": { + "@jridgewell/set-array": "^1.0.0", + "@jridgewell/sourcemap-codec": "^1.4.10" + } + }, + "@jridgewell/resolve-uri": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.1.tgz", + "integrity": "sha512-dSYZh7HhCDtCKm4QakX0xFpsRDqjjtZf/kjI/v3T3Nwt5r8/qz/M19F9ySyOqU94SXBmeG9ttTul+YnR4LOxFA==", + "dev": true + }, + "@jridgewell/set-array": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.1.tgz", + "integrity": "sha512-Ct5MqZkLGEXTVmQYbGtx9SVqD2fqwvdubdps5D3djjAkgkKwT918VNOz65pEHFaYTeWcukmJmH5SwsA9Tn2ObQ==", + "dev": true + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "@jridgewell/trace-mapping": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.20.tgz", + "integrity": "sha512-R8LcPeWZol2zR8mmH3JeKQ6QRCFb7XgUhV9ZlGhHLGyg4wpPiPZNQOOWhFZhxKw8u//yTbNGI42Bx/3paXEQ+Q==", + "dev": true, + "requires": { + "@jridgewell/resolve-uri": "^3.1.0", + "@jridgewell/sourcemap-codec": "^1.4.14" + } + }, + "@sinclair/typebox": { + "version": "0.23.5", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.23.5.tgz", + "integrity": "sha512-AFBVi/iT4g20DHoujvMH1aEDn8fGJh4xsRGCP6d8RpLPMqsNPvW01Jcn0QysXTsg++/xj25NmJsGyH9xug/wKg==", + "dev": true + }, + "@sinonjs/commons": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", + "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", + "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@types/babel__core": { + "version": "7.1.19", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "@types/babel__generator": { + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@types/babel__template": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "dev": true, + "requires": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@types/babel__traverse": { + "version": "7.17.1", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.17.1.tgz", + "integrity": "sha512-kVzjari1s2YVi77D3w1yuvohV2idweYXMCDzqBiVNN63TcDWrIlTVOYpqVrvbbyOE/IyzBoTKF0fdnLPEORFxA==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } + }, + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" + }, + "@types/graceful-fs": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", + "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/istanbul-lib-coverage": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", + "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", + "dev": true + }, + "@types/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "*" + } + }, + "@types/istanbul-reports": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", + "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "dev": true, + "requires": { + "@types/istanbul-lib-report": "*" + } + }, + "@types/minimist": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", + "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", + "dev": true + }, + "@types/node": { + "version": "17.0.34", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.34.tgz", + "integrity": "sha512-XImEz7XwTvDBtzlTnm8YvMqGW/ErMWBsKZ+hMTvnDIjGCKxwK5Xpc+c/oQjOauwq8M4OS11hEkpjX8rrI/eEgA==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", + "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", + "dev": true + }, + "@types/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", + "dev": true + }, + "@types/prettier": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.1.tgz", + "integrity": "sha512-XFjFHmaLVifrAKaZ+EKghFHtHSUonyw8P2Qmy2/+osBnrKbH9UYtlK10zg8/kCt47MFilll/DEDKy3DHfJ0URw==", + "dev": true + }, + "@types/stack-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", + "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", + "dev": true + }, + "@types/yargs": { + "version": "17.0.10", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.10.tgz", + "integrity": "sha512-gmEaFwpj/7f/ROdtIlci1R1VYU1J4j95m8T+Tj3iBgiBFKg1foE/PSl93bBd5T9LDXNPo8UlNN6W0qwD8O5OaA==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + }, + "@types/yargs-parser": { + "version": "21.0.0", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", + "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", + "dev": true + }, + "acorn": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", + "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", + "dev": true + }, + "acorn-jsx": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", + "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", + "dev": true, + "requires": {} + }, + "add-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/add-stream/-/add-stream-1.0.0.tgz", + "integrity": "sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==", + "dev": true + }, + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, + "ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==", + "dev": true + }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + } + }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "babel-jest": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-28.1.0.tgz", + "integrity": "sha512-zNKk0yhDZ6QUwfxh9k07GII6siNGMJWVUU49gmFj5gfdqDKLqa2RArXOF2CODp4Dr7dLxN2cvAV+667dGJ4b4w==", + "dev": true, + "requires": { + "@jest/transform": "^28.1.0", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^28.0.2", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "babel-plugin-istanbul": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", + "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-instrument": "^5.0.4", + "test-exclude": "^6.0.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-28.0.2.tgz", + "integrity": "sha512-Kizhn/ZL+68ZQHxSnHyuvJv8IchXD62KQxV77TBDV/xoBFBOfgRAk97GNs6hXdTTCiVES9nB2I6+7MXXrk5llQ==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.1.14", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-preset-current-node-syntax": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", + "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", + "dev": true, + "requires": { + "@babel/plugin-syntax-async-generators": "^7.8.4", + "@babel/plugin-syntax-bigint": "^7.8.3", + "@babel/plugin-syntax-class-properties": "^7.8.3", + "@babel/plugin-syntax-import-meta": "^7.8.3", + "@babel/plugin-syntax-json-strings": "^7.8.3", + "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", + "@babel/plugin-syntax-numeric-separator": "^7.8.3", + "@babel/plugin-syntax-object-rest-spread": "^7.8.3", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", + "@babel/plugin-syntax-optional-chaining": "^7.8.3", + "@babel/plugin-syntax-top-level-await": "^7.8.3" + } + }, + "babel-preset-jest": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-28.0.2.tgz", + "integrity": "sha512-sYzXIdgIXXroJTFeB3S6sNDWtlJ2dllCdTEsnZ65ACrMojj3hVNFRmnJ1HZtomGi+Be7aqpY/HJ92fr8OhKVkQ==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^28.0.2", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browserslist": { + "version": "4.20.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz", + "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001332", + "electron-to-chromium": "^1.4.118", + "escalade": "^3.1.1", + "node-releases": "^2.0.3", + "picocolors": "^1.0.0" + } + }, + "bser": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", + "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", + "dev": true, + "requires": { + "node-int64": "^0.4.0" + } + }, + "buffer-from": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", + "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", + "dev": true + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } + }, + "caniuse-lite": { + "version": "1.0.30001341", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001341.tgz", + "integrity": "sha512-2SodVrFFtvGENGCv0ChVJIDQ0KPaS1cg7/qtfMaICgeMolDdo/Z2OD32F0Aq9yl6F4YFwGPBS5AaPqNYiW4PoA==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "char-regex": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", + "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", + "dev": true + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "cjs-module-lexer": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", + "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "cliui": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", + "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^6.2.0" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "collect-v8-coverage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", + "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.0.0.tgz", + "integrity": "sha512-JJfP2saEKbQqvW+FI93OYUB4ByV5cizMpFMiiJI8xDbBvQvSkIk0VvQdn1CZ8mqAO8Loq2h0gYTYtDFUZUeERw==" + }, + "compare-func": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz", + "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==", + "dev": true, + "requires": { + "array-ify": "^1.0.0", + "dot-prop": "^5.1.0" + } + }, + "compare-versions": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", + "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + }, + "concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "confusing-browser-globals": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.9.tgz", + "integrity": "sha512-KbS1Y0jMtyPgIxjO7ZzMAuUpAKMt1SzCL9fsrKsX6b0zJPTaT0SiSPmewwVZg9UAO83HVIlEhZF84LIjZ0lmAw==", + "dev": true + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "conventional-changelog": { + "version": "3.1.25", + "resolved": "https://registry.npmjs.org/conventional-changelog/-/conventional-changelog-3.1.25.tgz", + "integrity": "sha512-ryhi3fd1mKf3fSjbLXOfK2D06YwKNic1nC9mWqybBHdObPd8KJ2vjaXZfYj1U23t+V8T8n0d7gwnc9XbIdFbyQ==", + "dev": true, + "requires": { + "conventional-changelog-angular": "^5.0.12", + "conventional-changelog-atom": "^2.0.8", + "conventional-changelog-codemirror": "^2.0.8", + "conventional-changelog-conventionalcommits": "^4.5.0", + "conventional-changelog-core": "^4.2.1", + "conventional-changelog-ember": "^2.0.9", + "conventional-changelog-eslint": "^3.0.9", + "conventional-changelog-express": "^2.0.6", + "conventional-changelog-jquery": "^3.0.11", + "conventional-changelog-jshint": "^2.0.9", + "conventional-changelog-preset-loader": "^2.3.4" + } + }, + "conventional-changelog-angular": { + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.13.tgz", + "integrity": "sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + } + }, + "conventional-changelog-atom": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-atom/-/conventional-changelog-atom-2.0.8.tgz", + "integrity": "sha512-xo6v46icsFTK3bb7dY/8m2qvc8sZemRgdqLb/bjpBsH2UyOS8rKNTgcb5025Hri6IpANPApbXMg15QLb1LJpBw==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-codemirror": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/conventional-changelog-codemirror/-/conventional-changelog-codemirror-2.0.8.tgz", + "integrity": "sha512-z5DAsn3uj1Vfp7po3gpt2Boc+Bdwmw2++ZHa5Ak9k0UKsYAO5mH1UBTN0qSCuJZREIhX6WU4E1p3IW2oRCNzQw==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-config-spec": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/conventional-changelog-config-spec/-/conventional-changelog-config-spec-2.1.0.tgz", + "integrity": "sha512-IpVePh16EbbB02V+UA+HQnnPIohgXvJRxHcS5+Uwk4AT5LjzCZJm5sp/yqs5C6KZJ1jMsV4paEV13BN1pvDuxQ==", + "dev": true + }, + "conventional-changelog-conventionalcommits": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-4.6.3.tgz", + "integrity": "sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "lodash": "^4.17.15", + "q": "^1.5.1" + } + }, + "conventional-changelog-core": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-4.2.4.tgz", + "integrity": "sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==", + "dev": true, + "requires": { + "add-stream": "^1.0.0", + "conventional-changelog-writer": "^5.0.0", + "conventional-commits-parser": "^3.2.0", + "dateformat": "^3.0.0", + "get-pkg-repo": "^4.0.0", + "git-raw-commits": "^2.0.8", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^4.1.1", + "lodash": "^4.17.15", + "normalize-package-data": "^3.0.0", + "q": "^1.5.1", + "read-pkg": "^3.0.0", + "read-pkg-up": "^3.0.0", + "through2": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "conventional-changelog-ember": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-ember/-/conventional-changelog-ember-2.0.9.tgz", + "integrity": "sha512-ulzIReoZEvZCBDhcNYfDIsLTHzYHc7awh+eI44ZtV5cx6LVxLlVtEmcO+2/kGIHGtw+qVabJYjdI5cJOQgXh1A==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-eslint": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-eslint/-/conventional-changelog-eslint-3.0.9.tgz", + "integrity": "sha512-6NpUCMgU8qmWmyAMSZO5NrRd7rTgErjrm4VASam2u5jrZS0n38V7Y9CzTtLT2qwz5xEChDR4BduoWIr8TfwvXA==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-express": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/conventional-changelog-express/-/conventional-changelog-express-2.0.6.tgz", + "integrity": "sha512-SDez2f3iVJw6V563O3pRtNwXtQaSmEfTCaTBPCqn0oG0mfkq0rX4hHBq5P7De2MncoRixrALj3u3oQsNK+Q0pQ==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-jquery": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/conventional-changelog-jquery/-/conventional-changelog-jquery-3.0.11.tgz", + "integrity": "sha512-x8AWz5/Td55F7+o/9LQ6cQIPwrCjfJQ5Zmfqi8thwUEKHstEn4kTIofXub7plf1xvFA2TqhZlq7fy5OmV6BOMw==", + "dev": true, + "requires": { + "q": "^1.5.1" + } + }, + "conventional-changelog-jshint": { + "version": "2.0.9", + "resolved": "https://registry.npmjs.org/conventional-changelog-jshint/-/conventional-changelog-jshint-2.0.9.tgz", + "integrity": "sha512-wMLdaIzq6TNnMHMy31hql02OEQ8nCQfExw1SE0hYL5KvU+JCTuPaDO+7JiogGT2gJAxiUGATdtYYfh+nT+6riA==", + "dev": true, + "requires": { + "compare-func": "^2.0.0", + "q": "^1.5.1" + } + }, + "conventional-changelog-preset-loader": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.3.4.tgz", + "integrity": "sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==", + "dev": true + }, + "conventional-changelog-writer": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-5.0.1.tgz", + "integrity": "sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==", + "dev": true, + "requires": { + "conventional-commits-filter": "^2.0.7", + "dateformat": "^3.0.0", + "handlebars": "^4.7.7", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "semver": "^6.0.0", + "split": "^1.0.0", + "through2": "^4.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "conventional-commits-filter": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.7.tgz", + "integrity": "sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==", + "dev": true, + "requires": { + "lodash.ismatch": "^4.4.0", + "modify-values": "^1.0.0" + } + }, + "conventional-commits-parser": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.2.4.tgz", + "integrity": "sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==", + "dev": true, + "requires": { + "is-text-path": "^1.0.1", + "JSONStream": "^1.0.4", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + } + }, + "conventional-recommended-bump": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-6.1.0.tgz", + "integrity": "sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==", + "dev": true, + "requires": { + "concat-stream": "^2.0.0", + "conventional-changelog-preset-loader": "^2.3.4", + "conventional-commits-filter": "^2.0.7", + "conventional-commits-parser": "^3.2.0", + "git-raw-commits": "^2.0.8", + "git-semver-tags": "^4.1.1", + "meow": "^8.0.0", + "q": "^1.5.1" + } + }, + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "core-util-is": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", + "dev": true + }, + "cosmiconfig": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "dev": true, + "requires": { + "@types/parse-json": "^4.0.0", + "import-fresh": "^3.2.1", + "parse-json": "^5.0.0", + "path-type": "^4.0.0", + "yaml": "^1.10.0" + }, + "dependencies": { + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + } + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "dargs": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-7.0.0.tgz", + "integrity": "sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==", + "dev": true + }, + "dateformat": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz", + "integrity": "sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + } + } + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "deep-extend": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", + "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==" + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "detect-indent": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.0.0.tgz", + "integrity": "sha512-oSyFlqaTHCItVRGK5RmrmjB+CmaMOW7IaNA/kdxqhoa6d17j/5ce9O9eWXmV/KEdRwqpQA+Vqe8a8Bsybu4YnA==", + "dev": true + }, + "detect-newline": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", + "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", + "dev": true + }, + "diff-sequences": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-28.0.2.tgz", + "integrity": "sha512-YtEoNynLDFCRznv/XDalsKGSZDoj0U5kLnXvY0JSq3nBboRrZXjD81+eSiwi+nzcZDwedMmcowcxNwwgFW23mQ==", + "dev": true + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "dotgitignore": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/dotgitignore/-/dotgitignore-2.1.0.tgz", + "integrity": "sha512-sCm11ak2oY6DglEPpCB8TixLjWAxd3kJTs6UIcSasNYxXdFPV+YKlye92c8H4kKFqV5qYMIh7d+cYecEg0dIkA==", + "dev": true, + "requires": { + "find-up": "^3.0.0", + "minimatch": "^3.0.4" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + } + } + }, + "electron-to-chromium": { + "version": "1.4.137", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.137.tgz", + "integrity": "sha512-0Rcpald12O11BUogJagX3HsCN3FE83DSqWjgXoHo5a72KUKMSfI39XBgJpgNNxS9fuGzytaFjE06kZkiVFy2qA==", + "dev": true + }, + "emittery": { + "version": "0.10.2", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", + "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "entities": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", + "integrity": "sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w==" + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + }, + "dependencies": { + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", + "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.3", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.2", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.3", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "globals": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz", + "integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "eslint-config-airbnb-base": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.1.0.tgz", + "integrity": "sha512-+XCcfGyCnbzOnktDVhwsCAx+9DmrzEmuwxyHUJpw+kqBVT744OUBrB09khgFKlK1lshVww6qXGsYPZpavoNjJw==", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.9", + "object.assign": "^4.1.0", + "object.entries": "^1.1.1" + } + }, + "eslint-import-resolver-node": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", + "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz", + "integrity": "sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-plugin-import": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz", + "integrity": "sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "array.prototype.flat": "^1.2.1", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.1", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + }, + "espree": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", + "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", + "dev": true, + "requires": { + "acorn": "^7.1.0", + "acorn-jsx": "^5.1.0", + "eslint-visitor-keys": "^1.1.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expect": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-28.1.0.tgz", + "integrity": "sha512-qFXKl8Pmxk8TBGfaFKRtcQjfXEnKAs+dmlxdwvukJZorwrAabT7M3h8oLOG01I2utEhkmUTi17CHaPBovZsKdw==", + "dev": true, + "requires": { + "@jest/expect-utils": "^28.1.0", + "jest-get-type": "^28.0.2", + "jest-matcher-utils": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-util": "^28.1.0" + } + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "requires": { + "bser": "2.1.1" + } + }, + "figures": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", + "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "dependencies": { + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" + } + } + }, + "find-versions": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-4.0.0.tgz", + "integrity": "sha512-wgpWy002tA+wgmO27buH/9KzyEOQnKsG/R0yrcjPT9BOFm0zRBVQbZ95nRGXWMywS8YR5knRbpohio0bcJABxQ==", + "dev": true, + "requires": { + "semver-regex": "^3.1.2" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.2", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", + "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==" + }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, + "get-pkg-repo": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-4.2.1.tgz", + "integrity": "sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==", + "dev": true, + "requires": { + "@hutson/parse-repository-url": "^3.0.0", + "hosted-git-info": "^4.0.0", + "through2": "^2.0.0", + "yargs": "^16.2.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + } + } + }, + "get-stdin": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==" + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "git-raw-commits": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.11.tgz", + "integrity": "sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==", + "dev": true, + "requires": { + "dargs": "^7.0.0", + "lodash": "^4.17.15", + "meow": "^8.0.0", + "split2": "^3.0.0", + "through2": "^4.0.0" + } + }, + "git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", + "dev": true, + "requires": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + } + }, + "git-semver-tags": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-4.1.1.tgz", + "integrity": "sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==", + "dev": true, + "requires": { + "meow": "^8.0.0", + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "gitconfiglocal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", + "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", + "dev": true, + "requires": { + "ini": "^1.3.2" + }, + "dependencies": { + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + } + } + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", + "dev": true + }, + "handlebars": { + "version": "4.7.7", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz", + "integrity": "sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.0", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + } + }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "husky": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/husky/-/husky-4.3.8.tgz", + "integrity": "sha512-LCqqsB0PzJQ/AlCgfrfzRe3e3+NvmefAdKQhRYpxS4u6clblBoDdzzvHi8fmxKRzvMxPY/1WZWzomPZww0Anow==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "compare-versions": "^3.6.0", + "cosmiconfig": "^7.0.0", + "find-versions": "^4.0.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^5.0.0", + "please-upgrade-node": "^3.2.0", + "slash": "^3.0.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz", + "integrity": "sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA==", + "dev": true, + "requires": { + "find-up": "^5.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "requires": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "dependencies": { + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ini/-/ini-2.0.0.tgz", + "integrity": "sha512-7PnF4oN3CvZF23ADhA5wRaYEQpJ8qygSkbtTXWBeXWXmEVRXK+1ITciHWwHhsjv1TmW0MgacIv6hEi5pX5NQdA==" + }, + "inquirer": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.1.tgz", + "integrity": "sha512-V1FFQ3TIO15det8PijPLFR9M9baSlnRs9nL7zWu1MNVA2T9YVl9ZbrHJhYs7e9X8jeMZ3lr2JH/rdHFgNCBdYw==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^2.4.2", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.2.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-core-module": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz", + "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "dev": true, + "requires": { + "text-extensions": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "istanbul-lib-coverage": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", + "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", + "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", + "dev": true, + "requires": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", + "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + } + }, + "istanbul-reports": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", + "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jest": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-28.1.0.tgz", + "integrity": "sha512-TZR+tHxopPhzw3c3560IJXZWLNHgpcz1Zh0w5A65vynLGNcg/5pZ+VildAd7+XGOu6jd58XMY/HNn0IkZIXVXg==", + "dev": true, + "requires": { + "@jest/core": "^28.1.0", + "import-local": "^3.0.2", + "jest-cli": "^28.1.0" + } + }, + "jest-changed-files": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-28.0.2.tgz", + "integrity": "sha512-QX9u+5I2s54ZnGoMEjiM2WeBvJR2J7w/8ZUmH2um/WLAuGAYFQcsVXY9+1YL6k0H/AGUdH8pXUAv6erDqEsvIA==", + "dev": true, + "requires": { + "execa": "^5.0.0", + "throat": "^6.0.1" + } + }, + "jest-circus": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-28.1.0.tgz", + "integrity": "sha512-rNYfqfLC0L0zQKRKsg4n4J+W1A2fbyGH7Ss/kDIocp9KXD9iaL111glsLu7+Z7FHuZxwzInMDXq+N1ZIBkI/TQ==", + "dev": true, + "requires": { + "@jest/environment": "^28.1.0", + "@jest/expect": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "is-generator-fn": "^2.0.0", + "jest-each": "^28.1.0", + "jest-matcher-utils": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-runtime": "^28.1.0", + "jest-snapshot": "^28.1.0", + "jest-util": "^28.1.0", + "pretty-format": "^28.1.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-cli": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-28.1.0.tgz", + "integrity": "sha512-fDJRt6WPRriHrBsvvgb93OxgajHHsJbk4jZxiPqmZbMDRcHskfJBBfTyjFko0jjfprP544hOktdSi9HVgl4VUQ==", + "dev": true, + "requires": { + "@jest/core": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/types": "^28.1.0", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^28.1.0", + "jest-util": "^28.1.0", + "jest-validate": "^28.1.0", + "prompts": "^2.0.1", + "yargs": "^17.3.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "17.5.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", + "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.0.0" + } + }, + "yargs-parser": { + "version": "21.0.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.0.1.tgz", + "integrity": "sha512-9BK1jFpLzJROCI5TzwZL/TU4gqjK5xiHV/RfWLOahrjAko/e4DJkRDZQXfvqAsiZzzYhgAzbgz6lg48jcm4GLg==", + "dev": true + } + } + }, + "jest-config": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-28.1.0.tgz", + "integrity": "sha512-aOV80E9LeWrmflp7hfZNn/zGA4QKv/xsn2w8QCBP0t0+YqObuCWTSgNbHJ0j9YsTuCO08ZR/wsvlxqqHX20iUA==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@jest/test-sequencer": "^28.1.0", + "@jest/types": "^28.1.0", + "babel-jest": "^28.1.0", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-circus": "^28.1.0", + "jest-environment-node": "^28.1.0", + "jest-get-type": "^28.0.2", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.0", + "jest-runner": "^28.1.0", + "jest-util": "^28.1.0", + "jest-validate": "^28.1.0", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^28.1.0", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", + "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-diff": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-28.1.0.tgz", + "integrity": "sha512-8eFd3U3OkIKRtlasXfiAQfbovgFgRDb0Ngcs2E+FMeBZ4rUezqIaGjuyggJBp+llosQXNEWofk/Sz4Hr5gMUhA==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^28.0.2", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-docblock": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-28.0.2.tgz", + "integrity": "sha512-FH10WWw5NxLoeSdQlJwu+MTiv60aXV/t8KEwIRGEv74WARE1cXIqh1vGdy2CraHuWOOrnzTWj/azQKqW4fO7xg==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-28.1.0.tgz", + "integrity": "sha512-a/XX02xF5NTspceMpHujmOexvJ4GftpYXqr6HhhmKmExtMXsyIN/fvanQlt/BcgFoRKN4OCXxLQKth9/n6OPFg==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "jest-util": "^28.1.0", + "pretty-format": "^28.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-environment-node": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-28.1.0.tgz", + "integrity": "sha512-gBLZNiyrPw9CSMlTXF1yJhaBgWDPVvH0Pq6bOEwGMXaYNzhzhw2kA/OijNF8egbCgDS0/veRv97249x2CX+udQ==", + "dev": true, + "requires": { + "@jest/environment": "^28.1.0", + "@jest/fake-timers": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "jest-mock": "^28.1.0", + "jest-util": "^28.1.0" + } + }, + "jest-get-type": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-28.0.2.tgz", + "integrity": "sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA==", + "dev": true + }, + "jest-haste-map": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-28.1.0.tgz", + "integrity": "sha512-xyZ9sXV8PtKi6NCrJlmq53PyNVHzxmcfXNVvIRHpHmh1j/HChC4pwKgyjj7Z9us19JMw8PpQTJsFWOsIfT93Dw==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "@types/graceful-fs": "^4.1.3", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^28.0.2", + "jest-util": "^28.1.0", + "jest-worker": "^28.1.0", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + } + }, + "jest-leak-detector": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-28.1.0.tgz", + "integrity": "sha512-uIJDQbxwEL2AMMs2xjhZl2hw8s77c3wrPaQ9v6tXJLGaaQ+4QrNJH5vuw7hA7w/uGT/iJ42a83opAqxGHeyRIA==", + "dev": true, + "requires": { + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.0" + } + }, + "jest-matcher-utils": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-28.1.0.tgz", + "integrity": "sha512-onnax0n2uTLRQFKAjC7TuaxibrPSvZgKTcSCnNUz/tOjJ9UhxNm7ZmPpoQavmTDUjXvUQ8KesWk2/VdrxIFzTQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^28.1.0", + "jest-get-type": "^28.0.2", + "pretty-format": "^28.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-message-util": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-28.1.0.tgz", + "integrity": "sha512-RpA8mpaJ/B2HphDMiDlrAZdDytkmwFqgjDZovM21F35lHGeUeCvYmm6W+sbQ0ydaLpg5bFAUuWG1cjqOl8vqrw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^28.1.0", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^28.1.0", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-mock": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-28.1.0.tgz", + "integrity": "sha512-H7BrhggNn77WhdL7O1apG0Q/iwl0Bdd5E1ydhCJzL3oBLh/UYxAwR3EJLsBZ9XA3ZU4PA3UNw4tQjduBTCTmLw==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "@types/node": "*" + } + }, + "jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "requires": {} + }, + "jest-regex-util": { + "version": "28.0.2", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-28.0.2.tgz", + "integrity": "sha512-4s0IgyNIy0y9FK+cjoVYoxamT7Zeo7MhzqRGx7YDYmaQn1wucY9rotiGkBzzcMXTtjrCAP/f7f+E0F7+fxPNdw==", + "dev": true + }, + "jest-resolve": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-28.1.0.tgz", + "integrity": "sha512-vvfN7+tPNnnhDvISuzD1P+CRVP8cK0FHXRwPAcdDaQv4zgvwvag2n55/h5VjYcM5UJG7L4TwE5tZlzcI0X2Lhw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.0", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^28.1.0", + "jest-validate": "^28.1.0", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-resolve-dependencies": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-28.1.0.tgz", + "integrity": "sha512-Ue1VYoSZquPwEvng7Uefw8RmZR+me/1kr30H2jMINjGeHgeO/JgrR6wxj2ofkJ7KSAA11W3cOrhNCbj5Dqqd9g==", + "dev": true, + "requires": { + "jest-regex-util": "^28.0.2", + "jest-snapshot": "^28.1.0" + } + }, + "jest-runner": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-28.1.0.tgz", + "integrity": "sha512-FBpmuh1HB2dsLklAlRdOxNTTHKFR6G1Qmd80pVDvwbZXTriqjWqjei5DKFC1UlM732KjYcE6yuCdiF0WUCOS2w==", + "dev": true, + "requires": { + "@jest/console": "^28.1.0", + "@jest/environment": "^28.1.0", + "@jest/test-result": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "graceful-fs": "^4.2.9", + "jest-docblock": "^28.0.2", + "jest-environment-node": "^28.1.0", + "jest-haste-map": "^28.1.0", + "jest-leak-detector": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-resolve": "^28.1.0", + "jest-runtime": "^28.1.0", + "jest-util": "^28.1.0", + "jest-watcher": "^28.1.0", + "jest-worker": "^28.1.0", + "source-map-support": "0.5.13", + "throat": "^6.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-runtime": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-28.1.0.tgz", + "integrity": "sha512-wNYDiwhdH/TV3agaIyVF0lsJ33MhyujOe+lNTUiolqKt8pchy1Hq4+tDMGbtD5P/oNLA3zYrpx73T9dMTOCAcg==", + "dev": true, + "requires": { + "@jest/environment": "^28.1.0", + "@jest/fake-timers": "^28.1.0", + "@jest/globals": "^28.1.0", + "@jest/source-map": "^28.0.2", + "@jest/test-result": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-mock": "^28.1.0", + "jest-regex-util": "^28.0.2", + "jest-resolve": "^28.1.0", + "jest-snapshot": "^28.1.0", + "jest-util": "^28.1.0", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-snapshot": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-28.1.0.tgz", + "integrity": "sha512-ex49M2ZrZsUyQLpLGxQtDbahvgBjlLPgklkqGM0hq/F7W/f8DyqZxVHjdy19QKBm4O93eDp+H5S23EiTbbUmHw==", + "dev": true, + "requires": { + "@babel/core": "^7.11.6", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.3.3", + "@jest/expect-utils": "^28.1.0", + "@jest/transform": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/babel__traverse": "^7.0.6", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^28.1.0", + "graceful-fs": "^4.2.9", + "jest-diff": "^28.1.0", + "jest-get-type": "^28.0.2", + "jest-haste-map": "^28.1.0", + "jest-matcher-utils": "^28.1.0", + "jest-message-util": "^28.1.0", + "jest-util": "^28.1.0", + "natural-compare": "^1.4.0", + "pretty-format": "^28.1.0", + "semver": "^7.3.5" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-util": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-28.1.0.tgz", + "integrity": "sha512-qYdCKD77k4Hwkose2YBEqQk7PzUf/NSE+rutzceduFveQREeH6b+89Dc9+wjX9dAwHcgdx4yedGA3FQlU/qCTA==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "ci-info": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.1.tgz", + "integrity": "sha512-SXgeMX9VwDe7iFFaEWkA5AstuER9YKqy4EhHqr4DVqkwmD9rpVimkMKWHdjn30Ja45txyjhSn63lVX69eVCckg==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-validate": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-28.1.0.tgz", + "integrity": "sha512-Lly7CJYih3vQBfjLeANGgBSBJ7pEa18cxpQfQEq2go2xyEzehnHfQTjoUia8xUv4x4J80XKFIDwJJThXtRFQXQ==", + "dev": true, + "requires": { + "@jest/types": "^28.1.0", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^28.0.2", + "leven": "^3.1.0", + "pretty-format": "^28.1.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", + "dev": true + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-watcher": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-28.1.0.tgz", + "integrity": "sha512-tNHMtfLE8Njcr2IRS+5rXYA4BhU90gAOwI9frTGOqd+jX0P/Au/JfRSNqsf5nUTcWdbVYuLxS1KjnzILSoR5hA==", + "dev": true, + "requires": { + "@jest/test-result": "^28.1.0", + "@jest/types": "^28.1.0", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.10.2", + "jest-util": "^28.1.0", + "string-length": "^4.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jest-worker": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-28.1.0.tgz", + "integrity": "sha512-ZHwM6mNwaWBR52Snff8ZvsCTqQsvhCxP/bT1I6T6DAnb6ygkshsyLQIMxFwHpYxht0HOoqt23JlC01viI7T03A==", + "dev": true, + "requires": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "dev": true + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "dev": true + }, + "jsonc-parser": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.0.0.tgz", + "integrity": "sha512-fQzRfAbIBnR0IQvftw9FJveWiHp72Fg20giDrHz6TdfB12UH/uue0D3hm57UB5KgAVuniLMCaS8P1IMj9NR7cA==" + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "jsonschema": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.5.tgz", + "integrity": "sha512-kVTF+08x25PQ0CjuVc0gRM9EUPb0Fe9Ln/utFOgcdxEIOHuU7ooBk/UPTd7t1M91pP35m0MU1T8M5P7vP1bRRw==" + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "lines-and-columns": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", + "dev": true + }, + "linkify-it": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-3.0.3.tgz", + "integrity": "sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==", + "requires": { + "uc.micro": "^1.0.1" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "requires": { + "p-locate": "^4.1.0" + } + }, + "lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "dev": true + }, + "lodash.ismatch": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.ismatch/-/lodash.ismatch-4.4.0.tgz", + "integrity": "sha1-dWy1FQyjum8RCFp4hJZF8Yj4Xzc=", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "requires": { + "tmpl": "1.0.5" + } + }, + "map-obj": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", + "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "dev": true + }, + "markdown-it": { + "version": "12.3.2", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-12.3.2.tgz", + "integrity": "sha512-TchMembfxfNVpHkbtriWltGWc+m3xszaRD0CZup7GFFhzIgQqxIfn3eGj1yZpfuflzPvfkt611B2Q/Bsk1YnGg==", + "requires": { + "argparse": "^2.0.1", + "entities": "~2.1.0", + "linkify-it": "^3.0.1", + "mdurl": "^1.0.1", + "uc.micro": "^1.0.5" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + } + } + }, + "markdownlint": { + "version": "0.25.1", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.25.1.tgz", + "integrity": "sha512-AG7UkLzNa1fxiOv5B+owPsPhtM4D6DoODhsJgiaNg1xowXovrYgOnLqAgOOFQpWOlHFVQUzjMY5ypNNTeov92g==", + "requires": { + "markdown-it": "12.3.2" + } + }, + "markdownlint-cli": { + "version": "0.31.1", + "resolved": "https://registry.npmjs.org/markdownlint-cli/-/markdownlint-cli-0.31.1.tgz", + "integrity": "sha512-keIOMwQn+Ch7MoBwA+TdkyVMuxAeZFEGmIIlvwgV0Z1TGS5MxPnRr29XCLhkNzCHU+uNKGjU+VEjLX+Z9kli6g==", + "requires": { + "commander": "~9.0.0", + "get-stdin": "~9.0.0", + "glob": "~7.2.0", + "ignore": "~5.2.0", + "js-yaml": "^4.1.0", + "jsonc-parser": "~3.0.0", + "markdownlint": "~0.25.1", + "markdownlint-rule-helpers": "~0.16.0", + "minimatch": "~3.0.5", + "run-con": "~1.2.10" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "requires": { + "argparse": "^2.0.1" + } + }, + "minimatch": { + "version": "3.0.8", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz", + "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==", + "requires": { + "brace-expansion": "^1.1.7" + } + } + } + }, + "markdownlint-rule-helpers": { + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/markdownlint-rule-helpers/-/markdownlint-rule-helpers-0.16.0.tgz", + "integrity": "sha512-oEacRUVeTJ5D5hW1UYd2qExYI0oELdYK72k1TKGvIeYJIbqQWAz476NAc7LNixSySUhcNl++d02DvX0ccDk9/w==" + }, + "mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=" + }, + "meow": { + "version": "8.1.2", + "resolved": "https://registry.npmjs.org/meow/-/meow-8.1.2.tgz", + "integrity": "sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==", + "dev": true, + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^3.0.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.18.0", + "yargs-parser": "^20.2.3" + }, + "dependencies": { + "hosted-git-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", + "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "normalize-package-data": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", + "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", + "dev": true, + "requires": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "dev": true, + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "dev": true, + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, + "semver": { + "version": "7.3.7", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", + "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "type-fest": { + "version": "0.18.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", + "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "dev": true + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + } + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "requires": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==" + }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + } + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-releases": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz", + "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==", + "dev": true + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + }, + "dependencies": { + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + } + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "object-keys": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", + "dev": true + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.entries": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.1.tgz", + "integrity": "sha512-ilqR7BgdyZetJutmDPfXCDffGa0/Yzl2ivVNpbx/g4UeWrCdRnFDUBrKJGLhGieRHDATnyZXWBeCb29k9CJysQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "opencollective-postinstall": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", + "dev": true + }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==" + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + } + } + }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "pretty-format": { + "version": "28.1.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-28.1.0.tgz", + "integrity": "sha512-79Z4wWOYCdvQkEoEuSlBhHJqWeZ8D8YRPiPctJFCtvuaClGpiwiQYSCUOE6IEKUbbFukKOTFIUAXE8N4EQTo1Q==", + "dev": true, + "requires": { + "@jest/schemas": "^28.0.2", + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true + } + } + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true + }, + "react-is": { + "version": "18.1.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.1.0.tgz", + "integrity": "sha512-Fl7FuabXsJnV5Q1qIOQwx/sagGF18kogb4gpfcG4gjLBWO0WDiiz1ko/ExayuxE7InyQkBLkxRFG5oxY6Uu3Kg==", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + } + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==" + }, + "resolve": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.0.tgz", + "integrity": "sha512-Hhtrw0nLeSrFQ7phPp4OOcVjLPIeMnRlr5mcnVuMe7M/7eBn98A3hmFRLoFo3DLZkivSYwhRUJTyPyWAk56WLw==", + "dev": true, + "requires": { + "is-core-module": "^2.8.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", + "dev": true, + "requires": { + "resolve-from": "^5.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + } + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "resolve.exports": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", + "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", + "dev": true + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "run-con": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/run-con/-/run-con-1.2.10.tgz", + "integrity": "sha512-n7PZpYmMM26ZO21dd8y3Yw1TRtGABjRtgPSgFS/nhzfvbJMXFtJhJVyEgayMiP+w/23craJjsnfDvx4W4ue/HQ==", + "requires": { + "deep-extend": "^0.6.0", + "ini": "~2.0.0", + "minimist": "^1.2.5", + "strip-json-comments": "~3.1.1" + } + }, + "rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "semver-regex": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-3.1.4.tgz", + "integrity": "sha512-6IiqeZNgq01qGf0TId0t3NvKzSvUsjcpdEO3AQNeIjR6A2+ckTnQlDpl4qu1bjRv0RzN3FP9hzFmws3lKqRWkA==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "dev": true + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "spdx-correct": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz", + "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz", + "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==", + "dev": true + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "requires": { + "through": "2" + } + }, + "split2": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/split2/-/split2-3.2.2.tgz", + "integrity": "sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==", + "dev": true, + "requires": { + "readable-stream": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + }, + "stack-utils": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.5.tgz", + "integrity": "sha512-xrQcmYhOsn/1kX+Vraq+7j4oE2j/6BFscZ0etmYg81xuM8Gq0022Pxb8+IqgOFUIaxHs0KaSb7T1+OegiNrNFA==", + "dev": true, + "requires": { + "escape-string-regexp": "^2.0.0" + }, + "dependencies": { + "escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "dev": true + } + } + }, + "standard-version": { + "version": "9.5.0", + "resolved": "https://registry.npmjs.org/standard-version/-/standard-version-9.5.0.tgz", + "integrity": "sha512-3zWJ/mmZQsOaO+fOlsa0+QK90pwhNd042qEcw6hKFNoLFs7peGyvPffpEBbK/DSGPbyOvli0mUIFv5A4qTjh2Q==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "conventional-changelog": "3.1.25", + "conventional-changelog-config-spec": "2.1.0", + "conventional-changelog-conventionalcommits": "4.6.3", + "conventional-recommended-bump": "6.1.0", + "detect-indent": "^6.0.0", + "detect-newline": "^3.1.0", + "dotgitignore": "^2.1.0", + "figures": "^3.1.0", + "find-up": "^5.0.0", + "git-semver-tags": "^4.0.0", + "semver": "^7.1.1", + "stringify-package": "^1.0.1", + "yargs": "^16.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "semver": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "yargs-parser": { + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "dev": true + } + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" + } + } + }, + "string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "stringify-package": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.1.tgz", + "integrity": "sha512-sa4DUQsYciMP1xhKWGuFM04fB0LG/9DlluZoSVywUMRNvzid6XucHK0/90xGxRoHrAaROrcHK1aPKaijCtSrhg==", + "dev": true + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "requires": { + "ansi-regex": "^5.0.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "test-exclude": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", + "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "dev": true, + "requires": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "dev": true + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "transliteration": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/transliteration/-/transliteration-2.1.8.tgz", + "integrity": "sha512-ds3uRxcS0yCxzP4xP30dz+ImEeVhgAwSaewhlApuYYTUuT8+wFFLoFfO1nHvfJzbpoRBp4lS52Ai3wm8IkemIQ==", + "requires": { + "yargs": "^15.0.2" + } + }, + "trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true + }, + "tslib": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", + "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uc.micro": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", + "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==" + }, + "uglify-js": { + "version": "3.15.5", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.15.5.tgz", + "integrity": "sha512-hNM5q5GbBRB5xB+PMqVRcgYe4c8jbyZ1pzZhS6jbq54/4F2gFK869ZheiE5A8/t+W5jtTNpWef/5Q9zk639FNQ==", + "dev": true, + "optional": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, + "v8-to-istanbul": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.0.tgz", + "integrity": "sha512-HcvgY/xaRm7isYmyx+lFKA4uQmfUbN0J4M0nNItvzTvH/iQ9kW5j/t4YSR+Ge323/lrgDAWJoF46tzGQHwBHFw==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.7", + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0" + } + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "requires": { + "makeerror": "1.0.12" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=" + }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "dev": true + }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "write-file-atomic": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", + "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.1.tgz", + "integrity": "sha512-wNcy4NvjMYL8gogWWYAO7ZFWFfHcbdbE57tZO8e4cbpj8tfUcwrwqSl3ad8HxpYWCdXcJUCeKKZS62Av1affwQ==" + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true + }, + "yamljs": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/yamljs/-/yamljs-0.3.0.tgz", + "integrity": "sha512-C/FsVVhht4iPQYXOInoxUM/1ELSf9EsgKH34FofQOp6hwCPrW4vG4w5++TED3xRUo8gD7l0P1J1dLlDYzODsTQ==", + "requires": { + "argparse": "^1.0.7", + "glob": "^7.0.5" + } + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/markdownlint-rules-grav-pages/package.json b/markdownlint-rules-grav-pages/package.json new file mode 100644 index 00000000..f02bf3c0 --- /dev/null +++ b/markdownlint-rules-grav-pages/package.json @@ -0,0 +1,42 @@ +{ + "name": "markdownlint-rules-grav-pages", + "version": "1.0.19", + "description": "Markdownlint rules for Grav Pages", + "license": "BSD-3-Clause", + "repository": "https://github.com/syseleven/markdownlint-rules-grav-pages", + "author": "Bastian Hofmann ", + "scripts": { + "lint": "eslint .", + "test": "jest tests", + "release": "standard-version" + }, + "keywords": [ + "markdownlint-rule" + ], + "husky": { + "hooks": { + "pre-commit": "npm run lint && npm run test" + } + }, + "dependencies": { + "jsonschema": "^1.2.5", + "markdown-it": "^12.3.2", + "markdownlint": "^0.25.1", + "markdownlint-cli": "^0.31.1", + "transliteration": "^2.1.8", + "yamljs": "^0.3.0" + }, + "devDependencies": { + "eslint": "^6.8.0", + "eslint-config-airbnb-base": "^14.1.0", + "eslint-plugin-import": "^2.20.1", + "husky": "^4.2.3", + "jest": "^28.1.0", + "standard-version": "^9.5.0" + }, + "jest": { + "testEnvironmentOptions": { + "url": "http://localhost" + } + } +} diff --git a/markdownlint-rules-grav-pages/rules/frontmatter.schema.json b/markdownlint-rules-grav-pages/rules/frontmatter.schema.json new file mode 100644 index 00000000..c56d06fa --- /dev/null +++ b/markdownlint-rules-grav-pages/rules/frontmatter.schema.json @@ -0,0 +1,119 @@ +{ + "type": "object", + "properties": { + "title": { "type": "bool", "minLength": 2, "maxLength": 80 }, + "media_order": { "type": "string" }, + "body_classes": { "type": "string" }, + "published": { "type": "boolean" }, + "visible": { "type": "boolean" }, + "redirect": { "type": "string" }, + "cache_enable": { "type": "boolean" }, + "debugger": { "type": "boolean" }, + "never_cache_twig": { "type": "boolean" }, + "twig_first": { "type": "boolean" }, + "routable": { "type": "boolean" }, + "login_redirect_here": { "type": "boolean" }, + "last_modified": { "type": "boolean" }, + "http_response_code": { "type": "integer" }, + "lightbox": { "type": "boolean" }, + "etag": { "type": "boolean" }, + "template": { "type": "string" }, + "template_format": { "type": "string" }, + "date": { "type": "string" }, + "publish_date": { "type": "string" }, + "unpublish_date": { "type": "string" }, + "expires": { "type": "integer" }, + "menu": { "type": "string", "minLength": 2, "maxLength": 30 }, + "slug": { "type": "string" }, + "routes": { + "type": "object", + "properties": { + "default": { "type": "string" }, + "canonical": { "type": "string" }, + "aliases": { "type": "array", "items": { "type": "string" } } + }, + "additionalProperties": false + }, + "taxonomy": { + "type": "object", + "properties": { + "category": { "type": "array", "items": { "type": "string" } }, + "tag": { "type": "array", "items": { "type": "string" } } + }, + "additionalProperties": false + }, + "external_url": { "type": "string" }, + "external_links": { + "type": "object", + "properties": { + "target": { "type": "string" } + }, + "additionalProperties": false + }, + "author": { + "type": "object", + "properties": { + "name": { "type": "string" }, + "twitter": { "type": "string" }, + "bio": { "type": "string" } + }, + "additionalProperties": false + }, + "summary": { + "type": "object", + "properties": { + "enabled": { "type": "boolean" }, + "format": { "type": "string" }, + "size": { "type": "integer" } + }, + "additionalProperties": false + }, + "sitemap": { + "type": "object", + "properties": { + "changefreq": { "type": "string" }, + "priority": { "type": "number" } + }, + "additionalProperties": false + }, + "process": { + "type": "object", + "properties": { + "markdown": { "type": "boolean" }, + "twig": { "type": "boolean" } + }, + "additionalProperties": false + }, + "markdown": { + "type": "object", + "properties": { + "extra": { "type": "boolean" }, + "auto_line_breaks": { "type": "boolean" }, + "auto_url_links": { "type": "boolean" }, + "escape_markup": { "type": "boolean" }, + "special_chars": { "type": "object", "additionalProperties": { "type": "string" } } + }, + "additionalProperties": false + }, + "metadata": { + "type": "object", + "properties": { + "refresh": { "type": "integer" } + }, + "additionalProperties": { "type": "string" } + }, + "page-toc": { + "type": "object", + "properties": { + "active": { "type": "boolean" }, + "start": { "type": "integer" }, + "depth": { "type": "integer" } + }, + "additionalProperties": false + } + }, + "additionalProperties": false, + "required": [ + "title" + ] +} diff --git a/markdownlint-rules-grav-pages/rules/valid-images.js b/markdownlint-rules-grav-pages/rules/valid-images.js new file mode 100644 index 00000000..6f8738d0 --- /dev/null +++ b/markdownlint-rules-grav-pages/rules/valid-images.js @@ -0,0 +1,31 @@ +const fs = require('fs'); +const flat = require('../lib/flat'); + +module.exports = { + names: ['valid-images'], + description: 'Rule that reports if a file has valid image references', + tags: ['test'], + function: function rule(params, onError) { + flat(params.tokens).filter((token) => token.type === 'image').forEach((image) => { + image.attrs.forEach((attr) => { + if (attr[0] === 'src') { + let imgSrc = attr[1]; + if (!imgSrc.match(/^(https?:)/)) { + if (imgSrc.includes('?')) { + imgSrc = imgSrc.slice(0, imgSrc.indexOf('?')); + } + const path = `${params.name.split('/').slice(0, -1).join('/')}/${imgSrc}`; + + if (!fs.existsSync(path) || !fs.lstatSync(path).isFile()) { + onError({ + lineNumber: image.lineNumber, + detail: `Image src '${imgSrc}' does not link to a valid file.`, + context: image.line, + }); + } + } + } + }); + }); + }, +}; diff --git a/markdownlint-rules-grav-pages/rules/valid-internal-links.js b/markdownlint-rules-grav-pages/rules/valid-internal-links.js new file mode 100644 index 00000000..cadb3b34 --- /dev/null +++ b/markdownlint-rules-grav-pages/rules/valid-internal-links.js @@ -0,0 +1,128 @@ +const transliteration = require('transliteration'); +const fs = require('fs'); +const url = require('url'); +const md = require('markdown-it')({ html: true }); +const helpers = require('markdownlint/helpers/helpers'); +const flat = require('../lib/flat'); + +const validateAnchor = (link, href, tokens, onError) => { + let anchorFound = false; + tokens.filter((token) => token.type === 'heading_open').forEach((heading) => { + if (!heading.line) { + return; + } + + const headingAnchor = transliteration.slugify(heading.line.toLowerCase(), { + replace: { + ä: 'ae', + ö: 'oe', + ü: 'ue', + }, + }); + + if (`#${headingAnchor}` === href) { + anchorFound = true; + } + }); + if (!anchorFound) { + onError({ + lineNumber: link.lineNumber, + detail: `Did not find matching heading for anchor '${href}'`, + context: link.line, + }); + } +}; + +// Annotate tokens with line/lineNumber, duplication from markdownlint because function +// is not exposed +const annotateTokens = (tokens, lines) => { + let tbodyMap = null; + return tokens.map((token) => { + // Handle missing maps for table body + if (token.type === 'tbody_open') { + tbodyMap = token.map.slice(); + } else if ((token.type === 'tr_close') && tbodyMap) { + tbodyMap[0] += 1; + } else if (token.type === 'tbody_close') { + tbodyMap = null; + } + const mappedToken = token; + if (tbodyMap && !token.map) { + mappedToken.map = tbodyMap.slice(); + } + // Update token metadata + if (token.map) { + mappedToken.line = lines[token.map[0]]; + mappedToken.lineNumber = token.map[0] + 1; + // Trim bottom of token to exclude whitespace lines + while (token.map[1] && !(lines[token.map[1] - 1].trim())) { + mappedToken.map[1] -= 1; + } + // Annotate children with lineNumber + let childLineNumber = token.lineNumber; + (token.children || []).map((child) => { + const mappedChild = child; + mappedChild.lineNumber = childLineNumber; + mappedChild.line = lines[childLineNumber - 1]; + if ((child.type === 'softbreak') || (child.type === 'hardbreak')) { + childLineNumber += 1; + } + return mappedChild; + }); + } + + return mappedToken; + }); +}; + +const parseMarkdownContent = (fileContent) => { + // Remove UTF-8 byte order marker (if present) + let content = fileContent.replace(/^\ufeff/, ''); + // Ignore the content of HTML comments + content = helpers.clearHtmlCommentText(content); + // Parse content into tokens and lines + const tokens = md.parse(content, {}); + const lines = content.split(helpers.newLineRe); + return annotateTokens(tokens, lines); +}; + +module.exports = { + names: ['valid-internal-links'], + description: 'Rule that reports if a file has an internal link to an invalid file', + tags: ['test'], + function: function rule(params, onError) { + flat(params.tokens).filter((token) => token.type === 'link_open').forEach((link) => { + link.attrs.forEach((attr) => { + if (attr[0] === 'href') { + const href = attr[1]; + if (href.match(/^#/)) { + validateAnchor(link, href, params.tokens, onError); + } else if (href && !href.match(/^(mailto:|https?:)/)) { + const parsedHref = url.parse(href); + let path; + if (parsedHref.pathname.match(/^\//)) { + path = `pages${parsedHref.pathname}`; + } else { + path = `${params.name.split('/').slice(0, -1).join('/')}/${parsedHref.pathname}`; + } + if (!fs.existsSync(path) || !fs.lstatSync(path).isFile()) { + onError({ + lineNumber: link.lineNumber, + detail: `Relative link '${href}' does not link to a valid file.`, + context: link.line, + }); + } else if (parsedHref.hash) { + // console.log(md.parse(fs.readFileSync(path).toString())); + validateAnchor( + link, + parsedHref.hash, + parseMarkdownContent(fs.readFileSync(path).toString()), + onError, + ); + } + } + } + }); + }); + }, +}; diff --git a/markdownlint-rules-grav-pages/rules/valid-metadata-block.js b/markdownlint-rules-grav-pages/rules/valid-metadata-block.js new file mode 100644 index 00000000..70d46201 --- /dev/null +++ b/markdownlint-rules-grav-pages/rules/valid-metadata-block.js @@ -0,0 +1,69 @@ +const YAML = require('yamljs'); +const { Validator } = require('jsonschema'); +// See https://learn.getgrav.org/content/headers +const metadataSchema = require('./frontmatter.schema.json'); + +module.exports = { + names: ['valid-metadata-block'], + description: 'Rule that reports if a file does not have a valid grav metadata block', + tags: ['test'], + function: function rule(params, onError) { + if (!params.frontMatterLines || params.frontMatterLines.length < 3) { + onError({ + lineNumber: 1, + detail: 'Missing grav metadata block', + }); + return; + } + const frontMatterLines = params.frontMatterLines.filter((line) => !!line); + if (frontMatterLines[0] !== '---') { + onError({ + lineNumber: 1, + detail: "Grav metadata block has to start with a '---'", + context: frontMatterLines[0], + }); + return; + } + if (frontMatterLines[frontMatterLines.length - 1] !== '---') { + onError({ + lineNumber: 1, + detail: "Grav metadata block has to end with a '---'", + context: frontMatterLines[frontMatterLines.length - 1], + }); + return; + } + const yamlString = frontMatterLines.slice(1, -1).join('\n'); + let yamlDocument; + try { + yamlDocument = YAML.parse(yamlString); + } catch (err) { + onError({ + lineNumber: 1, + detail: 'Error parsing grav metadata block', + context: err.toString(), + }); + return; + } + + if (!yamlDocument) { + onError({ + lineNumber: 1, + detail: 'Grav metadata is not a valid yaml document', + context: yamlString, + }); + return; + } + + const v = new Validator(); + + const validation = v.validate(yamlDocument, metadataSchema); + + validation.errors.forEach((validationError) => { + onError({ + lineNumber: 1, + detail: validationError.toString(), + context: yamlString, + }); + }); + }, +}; diff --git a/markdownlint-rules-grav-pages/tests/.eslintrc b/markdownlint-rules-grav-pages/tests/.eslintrc new file mode 100644 index 00000000..d29628cb --- /dev/null +++ b/markdownlint-rules-grav-pages/tests/.eslintrc @@ -0,0 +1,9 @@ +{ + "globals": { + "test": true, + "expect": true, + "describe": true, + "beforeEach": true, + "afterEach": true + } +} \ No newline at end of file diff --git a/markdownlint-rules-grav-pages/tests/assets/test.image b/markdownlint-rules-grav-pages/tests/assets/test.image new file mode 100644 index 00000000..e69de29b diff --git a/markdownlint-rules-grav-pages/tests/assets/valid-images/test.image b/markdownlint-rules-grav-pages/tests/assets/valid-images/test.image new file mode 100644 index 00000000..e69de29b diff --git a/markdownlint-rules-grav-pages/tests/assets/valid-images/test.md b/markdownlint-rules-grav-pages/tests/assets/valid-images/test.md new file mode 100644 index 00000000..e179c31f --- /dev/null +++ b/markdownlint-rules-grav-pages/tests/assets/valid-images/test.md @@ -0,0 +1,23 @@ +# Valid Images Test + +Valid image + +![AltText](test.image) + +Valid relative image + +![AltText](../test.image) + +Invalid image + +![AltText](test.invalid) + +Invalid relative image + +![AltText](../invalid/test.image) + +## Valid External Anchor + +Valid image with modifying grav query + +![AltText](test.image?resize=100,100) diff --git a/markdownlint-rules-grav-pages/tests/assets/valid-internal-links/test.md b/markdownlint-rules-grav-pages/tests/assets/valid-internal-links/test.md new file mode 100644 index 00000000..27de00a0 --- /dev/null +++ b/markdownlint-rules-grav-pages/tests/assets/valid-internal-links/test.md @@ -0,0 +1,46 @@ +# Valid Internal Links Test + +Valid path + +[Text](test.md) + +Valid relative path + +[Text](../valid-images/test.md) + +Invalid path + +[Text](test.invalid) + +Valid relative path + +[Text](../valid-images/invalid.md) + +No file + +[Text](../valid-images) + +As child: valid [Text](test.md) invalid [Text](test.invalid) + +[Anchor](#valid-anchor) +[Anchor](#invalid-anchor) + +## Valid Anchor + +Valid relative path with anchor + +[Text](../valid-images/test.md#valid-external-anchor) + +Valid relative path with invalid anchor + +[Text](../valid-images/test.md#invalid-external-anchor) + +## Anchor with question? + +[Anchor](#anchor-with-question) + +## Anchor with umlaut üÜß + +[Anchor](#anchor-with-umlaut-ueuess) + +[LinkWithoutSrc]() diff --git a/markdownlint-rules-grav-pages/tests/assets/valid-metadata-block/invalid-too-long-title.md b/markdownlint-rules-grav-pages/tests/assets/valid-metadata-block/invalid-too-long-title.md new file mode 100644 index 00000000..0a47722b --- /dev/null +++ b/markdownlint-rules-grav-pages/tests/assets/valid-metadata-block/invalid-too-long-title.md @@ -0,0 +1,5 @@ +--- +title: VeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitle +--- + +## Content diff --git a/markdownlint-rules-grav-pages/tests/assets/valid-metadata-block/invalid-unrecognized-property.md b/markdownlint-rules-grav-pages/tests/assets/valid-metadata-block/invalid-unrecognized-property.md new file mode 100644 index 00000000..93421b36 --- /dev/null +++ b/markdownlint-rules-grav-pages/tests/assets/valid-metadata-block/invalid-unrecognized-property.md @@ -0,0 +1,6 @@ +--- +title: My Page +invalid: field +--- + +## Content diff --git a/markdownlint-rules-grav-pages/tests/assets/valid-metadata-block/valid-minimum-block.md b/markdownlint-rules-grav-pages/tests/assets/valid-metadata-block/valid-minimum-block.md new file mode 100644 index 00000000..b490a62e --- /dev/null +++ b/markdownlint-rules-grav-pages/tests/assets/valid-metadata-block/valid-minimum-block.md @@ -0,0 +1,5 @@ +--- +title: My Page +--- + +## Content diff --git a/markdownlint-rules-grav-pages/tests/assets/valid-metadata-block/valid-taxonomy.md b/markdownlint-rules-grav-pages/tests/assets/valid-metadata-block/valid-taxonomy.md new file mode 100644 index 00000000..345fd103 --- /dev/null +++ b/markdownlint-rules-grav-pages/tests/assets/valid-metadata-block/valid-taxonomy.md @@ -0,0 +1,11 @@ +--- +title: My Page +taxonomy: + category: + - one + - two + tag: + - tag +--- + +## Content diff --git a/markdownlint-rules-grav-pages/tests/valid-images.spec.js b/markdownlint-rules-grav-pages/tests/valid-images.spec.js new file mode 100644 index 00000000..56ff5ae8 --- /dev/null +++ b/markdownlint-rules-grav-pages/tests/valid-images.spec.js @@ -0,0 +1,31 @@ +const markdownlint = require('markdownlint'); +const validImagesRule = require('../rules/valid-images'); + +test('validate images', () => { + const src = `${__dirname}/assets/valid-images/test.md`; + const results = markdownlint.sync({ + customRules: validImagesRule, + files: [src], + }); + + expect(results[src]).toEqual([ + { + lineNumber: 13, + ruleNames: ['valid-images'], + ruleDescription: 'Rule that reports if a file has valid image references', + ruleInformation: null, + errorDetail: 'Image src \'test.invalid\' does not link to a valid file.', + errorContext: '![AltText](test.invalid)', + errorRange: null, + }, + { + lineNumber: 17, + ruleNames: ['valid-images'], + ruleDescription: 'Rule that reports if a file has valid image references', + ruleInformation: null, + errorDetail: 'Image src \'../invalid/test.image\' does not link to a valid file.', + errorContext: '![AltText](../invalid/test.image)', + errorRange: null, + }, + ]); +}); diff --git a/markdownlint-rules-grav-pages/tests/valid-internal-links.spec.js b/markdownlint-rules-grav-pages/tests/valid-internal-links.spec.js new file mode 100644 index 00000000..441ce155 --- /dev/null +++ b/markdownlint-rules-grav-pages/tests/valid-internal-links.spec.js @@ -0,0 +1,89 @@ +const markdownlint = require('markdownlint'); +const validInternalLinks = require('../rules/valid-internal-links'); + +test('validate internal link', () => { + const src = `${__dirname}/assets/valid-internal-links/test.md`; + const results = markdownlint.sync({ + customRules: validInternalLinks, + files: [src], + config: { + default: true, + 'no-trailing-punctuation': { + punctuation: '.,;:!', + }, + }, + }); + + expect(results[src]).toEqual([ + { + errorContext: '[LinkWithoutSrc]()', + errorDetail: null, + errorRange: [1, 18], + lineNumber: 46, + ruleDescription: 'No empty links', + ruleInformation: 'https://github.com/DavidAnson/markdownlint/blob/v0.25.1/doc/Rules.md#md042', + ruleNames: [ + 'MD042', + 'no-empty-links', + ], + }, + { + lineNumber: 13, + ruleNames: ['valid-internal-links'], + ruleDescription: 'Rule that reports if a file has an internal link to an invalid file', + ruleInformation: null, + errorDetail: 'Relative link \'test.invalid\' does not link to a valid file.', + errorContext: '[Text](test.invalid)', + errorRange: null, + }, + { + lineNumber: 17, + ruleNames: ['valid-internal-links'], + ruleDescription: 'Rule that reports if a file has an internal link to an invalid file', + ruleInformation: null, + errorDetail: 'Relative link \'../valid-images/invalid.md\' does not link to a valid file.', + errorContext: '[Text](../valid-images/invalid.md)', + errorRange: null, + }, + { + lineNumber: 21, + ruleNames: ['valid-internal-links'], + ruleDescription: 'Rule that reports if a file has an internal link to an invalid file', + ruleInformation: null, + errorDetail: 'Relative link \'../valid-images\' does not link to a valid file.', + errorContext: '[Text](../valid-images)', + errorRange: null, + }, + { + lineNumber: 23, + ruleNames: ['valid-internal-links'], + ruleDescription: 'Rule that reports if a file has an internal link to an invalid file', + ruleInformation: null, + errorDetail: 'Relative link \'test.invalid\' does not link to a valid file.', + errorContext: 'As child: valid [Text](test.md) invalid [Text](test.invalid)', + errorRange: null, + }, + { + errorContext: '[Anchor](#invalid-anchor)', + errorDetail: "Did not find matching heading for anchor '#invalid-anchor'", + errorRange: null, + lineNumber: 26, + ruleDescription: 'Rule that reports if a file has an internal link to an invalid file', + ruleInformation: null, + ruleNames: [ + 'valid-internal-links', + ], + }, + { + errorContext: '[Text](../valid-images/test.md#invalid-external-anchor)', + errorDetail: "Did not find matching heading for anchor '#invalid-external-anchor'", + errorRange: null, + lineNumber: 36, + ruleDescription: 'Rule that reports if a file has an internal link to an invalid file', + ruleInformation: null, + ruleNames: [ + 'valid-internal-links', + ], + }, + ]); +}); diff --git a/markdownlint-rules-grav-pages/tests/valid-metadata-block.spec.js b/markdownlint-rules-grav-pages/tests/valid-metadata-block.spec.js new file mode 100644 index 00000000..2375a1a7 --- /dev/null +++ b/markdownlint-rules-grav-pages/tests/valid-metadata-block.spec.js @@ -0,0 +1,60 @@ +const markdownlint = require('markdownlint'); +const validMetadataBlockRule = require('../rules/valid-metadata-block'); + +// TODO add more test cases + +test('validate valid minimum block', () => { + const src = `${__dirname}/assets/valid-metadata-block/valid-minimum-block.md`; + const results = markdownlint.sync({ + customRules: validMetadataBlockRule, + files: [src], + }); + + expect(results[src]).toEqual([]); +}); + +test('validate too long title', () => { + const src = `${__dirname}/assets/valid-metadata-block/invalid-too-long-title.md`; + const results = markdownlint.sync({ + customRules: validMetadataBlockRule, + files: [src], + }); + + expect(results[src]).toEqual([{ + errorContext: 'title: VeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitleVeryLongTitle', + errorDetail: 'instance.title does not meet maximum length of 80', + errorRange: null, + lineNumber: 5, + ruleDescription: 'Rule that reports if a file does not have a valid grav metadata block', + ruleInformation: null, + ruleNames: ['valid-metadata-block'], + }]); +}); + +test('validate unrecognized property', () => { + const src = `${__dirname}/assets/valid-metadata-block/invalid-unrecognized-property.md`; + const results = markdownlint.sync({ + customRules: validMetadataBlockRule, + files: [src], + }); + + expect(results[src]).toEqual([{ + errorContext: 'title: My Page\ninvalid: field', + errorDetail: 'instance additionalProperty "invalid" exists in instance when not allowed', + errorRange: null, + lineNumber: 6, + ruleDescription: 'Rule that reports if a file does not have a valid grav metadata block', + ruleInformation: null, + ruleNames: ['valid-metadata-block'], + }]); +}); + +test('validate valid taxonomy', () => { + const src = `${__dirname}/assets/valid-metadata-block/valid-taxonomy.md`; + const results = markdownlint.sync({ + customRules: validMetadataBlockRule, + files: [src], + }); + + expect(results[src]).toEqual([]); +}); diff --git a/orphaned/default.es.md b/orphaned/default.es.md index 41876311..44faf041 100644 --- a/orphaned/default.es.md +++ b/orphaned/default.es.md @@ -2,10 +2,10 @@ Esta página todavía no existe, puedes editarla tecleando `````` en tu teclado, o clicando en el botón "Editar" abajo a la derecha de tu pantalla. Puedes echar un vistazo a los cambios que has efectuado empujando de nuevo la tecla `````` o clicando en el botón "Vistazo". -** Nota : ** Necesitarás una dirección email para validar tu propuesta. +**Nota :** Necesitarás una dirección email para validar tu propuesta. +## Sintaxis -### Sintaxis Esta página utiliza la sintaxis Markdown, refiérete a la documentación para más informaciones : -http://daringfireball.net/projects/markdown/syntax + diff --git a/orphaned/default.fr.md b/orphaned/default.fr.md index 270beabe..1deba1e8 100644 --- a/orphaned/default.fr.md +++ b/orphaned/default.fr.md @@ -2,10 +2,10 @@ Cette page n’existe pas encore, vous pouvez l’éditer en appuyant sur la touche ```<Échap>``` de votre clavier, ou en cliquant sur le bouton "Éditer" en bas à droite de votre écran. Vous pourrez avoir un aperçu de vos changements en appuyant à nouveau sur la touche ```<Échap>``` ou en cliquant sur le bouton "Aperçu". -** Note : ** Vous aurez besoin d'une adresse email pour valider votre proposition. +**Note :** Vous aurez besoin d'une adresse email pour valider votre proposition. +## Syntaxe -### Syntaxe Cette page utilise la syntaxe Markdown, veuillez vous référer à la documentation pour plus d’informations : -http://daringfireball.net/projects/markdown/syntax + diff --git a/orphaned/default.it.md b/orphaned/default.it.md index 89f495de..54b9c340 100644 --- a/orphaned/default.it.md +++ b/orphaned/default.it.md @@ -2,10 +2,10 @@ Questa pagina non è ancora stata creata, puoi modificarla premendo `````` sulla tua tastiera o cliccando il pulsante "Modifica" in basso a destra del tuo schermo. Potrai vedere l'anteprima delle tue modifiche premendo ancora `````` o cliccando il pulsante "Anteprima". -** Nota: ** Devi fornire un indirizzo email per confermare le tue modifiche. +**Nota:** Devi fornire un indirizzo email per confermare le tue modifiche. -### Sintassi +## Sintassi Questa pagina usa la sintassi markdown, per favore fai riferimento alla documentazione per ulteriori informazioni: -http://daringfireball.net/projects/markdown/syntax + diff --git a/orphaned/default.md b/orphaned/default.md index 08ee4d98..c0339711 100644 --- a/orphaned/default.md +++ b/orphaned/default.md @@ -2,10 +2,10 @@ This page is not created yet, you can edit it by pressing `````` on your keyboard or by clicking the "edit" button on the bottom-right side of your screen. You will be able to preview your changes by pressing `````` again or by clicking the "preview" button. -** Note: ** You will need to provide an email address to validate your submission. +**Note:** You will need to provide an email address to validate your submission. -### Syntax +## Syntax This page use the markdown syntax, please refer to the documentation for further informations: -http://daringfireball.net/projects/markdown/syntax + diff --git a/orphaned/dns.es.md b/orphaned/dns.es.md index b4a5f53b..81479593 100644 --- a/orphaned/dns.es.md +++ b/orphaned/dns.es.md @@ -20,7 +20,6 @@ También existen **tipos** de registros DNS, lo que significa que un dominio pue **Por ejemplo** : `www.yunohost.org` apunta hacia `yunohost.org` - ### ¿ Cómo (bien) hacer la configuración ? Tienes varias opciones. Nota que puedes cumular estas soluciones si posees varios dominios : por ejemplo, puedes tener `mi-servidor.nohost.me` utilizando la solución **1.**, et `mi-servidor.org` utilizando la solución **2.**, redirigiéndolos hacia el mismo servidor YunoHost. diff --git a/orphaned/dns.fr.md b/orphaned/dns.fr.md index 444ceadf..a7bf8a43 100644 --- a/orphaned/dns.fr.md +++ b/orphaned/dns.fr.md @@ -6,9 +6,9 @@ La configuration des DNS est une étape cruciale pour que votre serveur soit acc ### Qu’est-ce que c’est ? -**N’hésitez pas à regarder la très bonne conférence de Stéphane Bortzmeyer :** +**N’hésitez pas à regarder la très bonne conférence de Stéphane Bortzmeyer :** -https://www.iletaitunefoisinternet.fr/post/1-dns-bortzmeyer/ + DNS signifie « Domain Name Server » en anglais, et est souvent employé pour désigner la configuration de vos noms de domaine. Vos noms de domaines doivent en effet pointer vers quelque chose (en général une adresse IP). @@ -23,7 +23,6 @@ Il existe également des **types** d’enregistrement DNS, ce qui veut dire qu **Par exemple** : `www.yunohost.org` renvoie vers `yunohost.org` - ### Comment (bien) faire la configuration ? Plusieurs choix s’offrent à vous. Notez que vous pouvez cumuler ces solutions si vous possédez plusieurs domaines : par exemple vous pouvez avoir `mon-serveur.nohost.me` en utilisant la solution **1.**, et `mon-serveur.org` en utilisant la solution **2.**, redirigeant vers le même serveur YunoHost. diff --git a/orphaned/dns.md b/orphaned/dns.md index 9666ec73..8911c4b7 100644 --- a/orphaned/dns.md +++ b/orphaned/dns.md @@ -34,5 +34,3 @@ You can also check out these pages for specific [registrar](/registrar) document 3. (Advanced, not 100% supported...) Your YunoHost instance has its own DNS service, which means it will automatically configure its own DNS records, and that you can leave the setup to the instance itself. To do this, you must explain to your **registrar** that your YunoHost instance is the authoritative DNS server for your domain name. **Warning**: If you choose this option, all configuration options will be done automatically, you will retain a good deal of flexibility, but if your server gets knocked offline you will run into many problems. **Choose this only if you understand the implications.** - - diff --git a/orphaned/index.ar.md b/orphaned/index.ar.md index af485420..45860a7c 100644 --- a/orphaned/index.ar.md +++ b/orphaned/index.ar.md @@ -1,4 +1,4 @@ - - diff --git a/orphaned/index.es.md b/orphaned/index.es.md index 3a29ed7b..1f803873 100644 --- a/orphaned/index.es.md +++ b/orphaned/index.es.md @@ -1,4 +1,4 @@ -
+
@@ -134,7 +134,6 @@
- + diff --git a/orphaned/index.fr.md b/orphaned/index.fr.md index 54333a4d..f9ee49cf 100644 --- a/orphaned/index.fr.md +++ b/orphaned/index.fr.md @@ -1,4 +1,4 @@ -
+
@@ -118,7 +118,6 @@
- - diff --git a/orphaned/index.it.md b/orphaned/index.it.md index e0884761..c60f1765 100644 --- a/orphaned/index.it.md +++ b/orphaned/index.it.md @@ -1,4 +1,4 @@ -
+
@@ -135,7 +135,6 @@
- - diff --git a/orphaned/index.md b/orphaned/index.md index c18bd033..3ae65227 100644 --- a/orphaned/index.md +++ b/orphaned/index.md @@ -1,4 +1,4 @@ -
+
@@ -44,7 +44,6 @@

Latest news

-

Setup your server with ease, you already have everything at home

diff --git a/orphaned/index.oc.md b/orphaned/index.oc.md index 80c1c013..fa9d419e 100644 --- a/orphaned/index.oc.md +++ b/orphaned/index.oc.md @@ -1,4 +1,4 @@ -
+
@@ -108,7 +108,7 @@

Donation button

- +

@@ -133,7 +133,6 @@
-
- diff --git a/orphaned/registrar.fr.md b/orphaned/registrar.fr.md index c8a5d5a0..31bb78b4 100644 --- a/orphaned/registrar.fr.md +++ b/orphaned/registrar.fr.md @@ -1,8 +1,9 @@ # Bureaux d’enregistrement Voici une liste des bureaux d’enregistrement pour acheter un nom de domaine : -* [OVH](http://ovh.com/) -* [Gandi](http://gandi.net/) -* [Namecheap](https://www.namecheap.com/) -* [BookMyName](https://www.bookmyname.com/) -* [GoDaddy](https://godaddy.com/) /!\ GoDaddy [n'est pas un bon exemple pour la censure](https://en.wikipedia.org/wiki/GoDaddy#Controversies) + +- [OVH](http://ovh.com/) +- [Gandi](http://gandi.net/) +- [Namecheap](https://www.namecheap.com/) +- [BookMyName](https://www.bookmyname.com/) +- [GoDaddy](https://godaddy.com/) /!\ GoDaddy [n'est pas un bon exemple pour la censure](https://en.wikipedia.org/wiki/GoDaddy#Controversies) diff --git a/orphaned/registrar.md b/orphaned/registrar.md index 0fa657dc..0b3b3e5d 100644 --- a/orphaned/registrar.md +++ b/orphaned/registrar.md @@ -1,8 +1,9 @@ # Registar Here is a list of Registrars to book domain names: -* [OVH](http://ovh.com/) -* [Gandi](http://gandi.net/) -* [Namecheap](https://www.namecheap.com/) -* [BookMyName](https://www.bookmyname.com/) -* [GoDaddy](https://godaddy.com/) /!\ GoDaddy is [not a good example about censorship](https://en.wikipedia.org/wiki/GoDaddy#Controversies) + +- [OVH](http://ovh.com/) +- [Gandi](http://gandi.net/) +- [Namecheap](https://www.namecheap.com/) +- [BookMyName](https://www.bookmyname.com/) +- [GoDaddy](https://godaddy.com/) /!\ GoDaddy is [not a good example about censorship](https://en.wikipedia.org/wiki/GoDaddy#Controversies) diff --git a/pages/00.home/docs.de.md b/pages/00.home/docs.de.md index 6ec4aa8a..780ea808 100644 --- a/pages/00.home/docs.de.md +++ b/pages/00.home/docs.de.md @@ -16,7 +16,6 @@ Weitere Informationen zum Selbsthosting, zur Installation deines eigenen YunoHos Du kannst in den [Anwendungskatalog](/apps) schauen, um die Apps anzusehen, die auf deinem Server installiert werden können (Natürlich geht das auch direkt über deine Administrationsoberfläche!). - Wenn du Hilfe benötigst, ist die [Community](/community) für dich da: [Chatte](/chat_rooms) mit uns oder schau in das [Forum](/community/forum)! [center] @@ -28,7 +27,6 @@ Wenn du Hilfe benötigst, ist die [Community](/community) für dich da: [Chatte] [/center] - [center] Zurück zur Homepage [/center] diff --git a/pages/00.home/docs.es.md b/pages/00.home/docs.es.md index 55b98143..d3f557af 100644 --- a/pages/00.home/docs.es.md +++ b/pages/00.home/docs.es.md @@ -27,7 +27,6 @@ La [Comunidad](/community) esta disponible para ayudarte : entra en el [chat](/c [/center] - [center] Volver a la página principal [/center] diff --git a/pages/00.home/docs.fr.md b/pages/00.home/docs.fr.md index 58ab6ccb..2fecadc5 100644 --- a/pages/00.home/docs.fr.md +++ b/pages/00.home/docs.fr.md @@ -31,5 +31,4 @@ La [communauté](/community) est là si vous avez besoin d'aide : venez discuter Retourner à la page d'accueil du site [/center] - !!!! Pour naviguer dans cette documentation, vous pouvez utiliser les flèches gauches et droites. Utilisez le [fa=bars /] panneau latéral pour aller directement dans les sections qui vous intéresse ou en utilisant la [fa=search /] barre de recherche. Enjoy! diff --git a/pages/00.home/docs.it.md b/pages/00.home/docs.it.md index 769846af..63d0bd8e 100644 --- a/pages/00.home/docs.it.md +++ b/pages/00.home/docs.it.md @@ -30,4 +30,3 @@ La [comunità](/community) è disponibile se avete bisogno di aiuto: potete veni [/center] !!!! Per navigare in questa documentazione potete utilizzare i tasti freccia destra e sinistra. Navigate direttamente nella sezione che vi interessa con il [fa=bars /] pannello laterale o utilizzate il [fa=search /] box di ricerca. Enjoy! - diff --git a/pages/00.home/docs.md b/pages/00.home/docs.md index 3f2534c9..19ce54ad 100644 --- a/pages/00.home/docs.md +++ b/pages/00.home/docs.md @@ -27,7 +27,6 @@ The [Community](/community) is here for you if you need some help : come [chat]( [/center] - [center] Go back to the homepage [/center] diff --git a/pages/00.home/docs.ru.md b/pages/00.home/docs.ru.md index 6428ad0f..db4b9758 100644 --- a/pages/00.home/docs.ru.md +++ b/pages/00.home/docs.ru.md @@ -27,7 +27,6 @@ visible: false [/center] - [center] Вернуться на главную [/center] diff --git a/pages/01.overview/05.self_hosting/self_hosting.de.md b/pages/01.overview/05.self_hosting/self_hosting.de.md index 593f9bdb..9e1e3eab 100644 --- a/pages/01.overview/05.self_hosting/self_hosting.de.md +++ b/pages/01.overview/05.self_hosting/self_hosting.de.md @@ -18,7 +18,7 @@ Beim Self-Hosting geht es nicht darum, "Ihr Internet" sicherer zu machen, und es - **Sie glauben an ein freies, offenes und dezentrales Internet.** In einem zentralisierten Internet können private Unternehmen und Behörden Personen ausspähen, analysieren und beeinflussen, indem sie diktieren, wie Sie sich miteinander verbinden, und indem sie Inhalte filtern. YunoHost wird von einer Community entwickelt, die an ein offenes und dezentrales Internet glaubt, und wir hoffen, dass Sie dies auch tun! -- **Sie möchten die Kontrolle über Ihre Daten und Dienste haben.** Ihre Bilder, Chatnachrichten, der Browserverlauf und der Text, den Sie für die Schule schreiben, haben auf dem Server eines anderen Benutzers (a.k.a. The Cloud) nichts zu suchen. Sie sind Teil Ihres Privatlebens, aber auch Teil des Lebens Ihrer Familie, Ihres Partners und so weiter. Diese Daten sollten von * Ihnen * verwaltet werden, nicht von einem zufälligen Unternehmen in den USA, dass Ihre Daten analysieren und die Ergebnisse verkaufen möchte. +- **Sie möchten die Kontrolle über Ihre Daten und Dienste haben.** Ihre Bilder, Chatnachrichten, der Browserverlauf und der Text, den Sie für die Schule schreiben, haben auf dem Server eines anderen Benutzers (a.k.a. The Cloud) nichts zu suchen. Sie sind Teil Ihres Privatlebens, aber auch Teil des Lebens Ihrer Familie, Ihres Partners und so weiter. Diese Daten sollten von *Ihnen* verwaltet werden, nicht von einem zufälligen Unternehmen in den USA, dass Ihre Daten analysieren und die Ergebnisse verkaufen möchte. - **Sie möchten lernen, wie Computer und das Internet funktionieren.** Der Betrieb eines eigenen Servers ist ein guter Kontext, um die grundlegenden Mechanismen von Betriebssystemen und dem Internet zu verstehen. Möglicherweise müssen Sie sich mit der Befehlszeilenschnittstelle, der Netzwerkarchitektur, der DNS-Konfiguration und mit SSH usw. befassen. diff --git a/pages/01.overview/05.self_hosting/self_hosting.es.md b/pages/01.overview/05.self_hosting/self_hosting.es.md index 1bc42149..7faabb72 100644 --- a/pages/01.overview/05.self_hosting/self_hosting.es.md +++ b/pages/01.overview/05.self_hosting/self_hosting.es.md @@ -6,59 +6,28 @@ taxonomy: routes: default: '/selfhosting' --- - + El auto-alojamiento se refiere al hecho de tener y administrar tú tu propio servidor, normalmente en tu casa, para hospedar tus datos personales y servicios, en lugar de depender de terceros. Por ejemplo, es posible el auto-hospedaje de tu blog, de manera que este "viva" dentro de una máquina que controlas, en lugar de que se aloje en un ordenador de otra persona/empresa (alias La Nube) contra dinero, publicidad o cesión de datos privados. - - Auto-alojar implica disponer de un servidor. Un servidor es un ordenador destinado a ser accesible en la red las 24 horas del día y que normalmente no tiene ni pantalla ni teclado, ya que se controla a distancia. Contrariamente a una creencia extendida, los servidores no son necesariamente máquinas enormes y muy potentes: en la actualidad, una pequeña placa ARM de unos ~30€/$ es suficiente para el auto-hospedaje. - La práctica del auto-alojamiento no convierte "tu internet" más segura y tampoco proporciona anonimato por si mismo. El objetivo es generalmente generar autonomía y control de tus servicios y tus datos - lo que también implica una responsabilidad. ## ¿Cuáles son los beneficios del auto-alojamiento? - - **Crées en una internet libre, abierta y descentralizada.** En una internet centralizada, entidades privadas y gobiernos pueden espiar, analizar e influir en nosotras dictando como iteraccionamos entre nosotras o filtrando contenidos. A YunoHost lo desarrolla por una comunidad que cree en una internet abierta y descentralizada. ¡Esperamos que tú también! - - **Quieres tener control de tus datos y servicios.** Tus fotos, mensajes de chat, el historial de navegación y ese trabajo del colegio no tienen nada que hacer en el ordenador de otra persona (alias La Nube). Esos datos forman parte de tu vida privada, pero también de la de tu familia, de tus amistades, etc. Estos datos deberían ser gestionados por *ti*, y no por una empresa americana cualquiera que busca analizar tus datos para vender los resultados. - - **Quieres aprender cómo funcionan los ordenadores e internet.** Operar tu propio servidor es un ejercicio muy enriquecedor para entender los mecanismos básicos en el corazón de los sistemas operativos y de internet. Es posible que tengas que escribir en la línea de comandos o a segmentos de configuración de la red y de DNS. - - - **Quieres explorar las nuevas posibilidades y personalizar tu espacio.** ¿Alguna vez has soñado con tener tu propio servidor de Minecraft para jugar con tus amistades, o un cliente sw IRC o XMPP persistente? Con tu propio servidor, puedes instalar manualmente y ejecutar prácticamente cualquier programa que quieras y personalizar cada parte. ## ¿Qué implica el auto-alojamiento? - - **Auto-alojarse requiere del trabajo y de la paciencia.** Auto-alojarte es algo parecido a cultivar tu propio jardín o huerto: requiere del trabajo y de la paciencia. Mientras que YunoHost pretende hacer todo el trabajo duro por ti, necesitarás tomarte el tiempo para aprender y configurar pequeños detalles para que tu instalación funcione correctamente. También necesitarás realizar algunas tareas de mantenimiento (como actualizaciones) de vez en cuando, o pedir soporte si las cosas no funcionan. - - **Un gran servidor conlleva una gran responsabilidad.** Operar un servidor significa que eres responsable de los datos que alojas. Nadie podrá recuperarlos por ti si se pierden. YunoHost proporciona funciones de copia de seguridad, que es recomendable utilizar regularmente para hacer copias de seguridad de las configuraciones y de los datos importantes. También deberías echar un ojo a las noticias y recomendaciones de seguridad, para que tu servidor o tus datos no se vean comprometidos. - -- **La calidad y el rendimiento probablemente no serán tan buenos como los de los servicios "premium".** YunoHost (y la mayoría de las aplicaciones empaquetadas) son programas libres basados de código abierto, desarrollados por comunidades de personas de manera voluntaria. No hay garantía absoluta de que el software funcione en todas las circunstancias posibles. El rendimiento de su servidor autohospedado también está relacionado con su procesador, a la memoria RAM y la conectividad a internet. \ No newline at end of file +- **La calidad y el rendimiento probablemente no serán tan buenos como los de los servicios "premium".** YunoHost (y la mayoría de las aplicaciones empaquetadas) son programas libres basados de código abierto, desarrollados por comunidades de personas de manera voluntaria. No hay garantía absoluta de que el software funcione en todas las circunstancias posibles. El rendimiento de su servidor autohospedado también está relacionado con su procesador, a la memoria RAM y la conectividad a internet. diff --git a/pages/01.overview/05.self_hosting/self_hosting.it.md b/pages/01.overview/05.self_hosting/self_hosting.it.md index 45c2b595..ebb3c446 100644 --- a/pages/01.overview/05.self_hosting/self_hosting.it.md +++ b/pages/01.overview/05.self_hosting/self_hosting.it.md @@ -30,5 +30,3 @@ Praticare il self-hosting non rende il "tuo internet" più sicuro e non fornisce - **Con grandi server derivano grandi responsabilità.** Gestire un server implica l'essere responsabile dei dati che ospiti: nessuno potrà recuperare i dati al tuo posto se li perderai. YunoHost offre funzionalità di salvataggio che è raccomandato utilizzare per memorizzare le configurazioni e i dati importanti. Devi tenere controllate le raccomandazioni e le novità riguardo la sicurezza perché il tuo server o i tuoi dati non vengano compromessi. - **La qualità e le performances probabilmente non saranno le stesse dei servizi premium.** YunoHost (e la maggior parte delle applicazioni che sono predisposte) sono programmi liberi e open-source, sviluppati da comunità di volontari. Non c'è la garanzia assoluta che i programmi funzionino in tutte le possibili situazioni. Le performance del tuo server self-hosting sono legate anche al processore, alla memoria RAM e alla connessione internet. - - diff --git a/pages/01.overview/05.self_hosting/self_hosting.ru.md b/pages/01.overview/05.self_hosting/self_hosting.ru.md index 7f3d6802..e8d9880b 100644 --- a/pages/01.overview/05.self_hosting/self_hosting.ru.md +++ b/pages/01.overview/05.self_hosting/self_hosting.ru.md @@ -17,16 +17,16 @@ routes: - **Вы верите в свободный, открытый и децентрализованный Интернет.** В централизованном Интернете частные компании и правительство могут шпионить, анализировать людей и влиять на них, диктуя, как они взаимодействуют друг с другом, и фильтруя контент. YunoHost разработан сообществом, которое верит в открытый и децентрализованный Интернет, и мы надеемся, что вы тоже верите! -- **Вы хотите иметь контроль над своими данными и сервисами.** Вашим фотографиям, сообщениям в чате, истории посещенных страниц и тексту, который вы пишете для школы, нечего делать на чужом сервере (он же Облако). Они являются частью вашей личной жизни, но также и частью жизни вашей семьи, жизни вашего друга и так далее. Этими данными должны управлять * вы*, а не случайная компания в США, которая хочет, чтобы ваши данные анализировались и продавались результаты. +- **Вы хотите иметь контроль над своими данными и сервисами.** Вашим фотографиям, сообщениям в чате, истории посещенных страниц и тексту, который вы пишете для школы, нечего делать на чужом сервере (он же Облако). Они являются частью вашей личной жизни, но также и частью жизни вашей семьи, жизни вашего друга и так далее. Этими данными должны управлять *вы*, а не случайная компания в США, которая хочет, чтобы ваши данные анализировались и продавались результаты. - **Вы хотите узнать о том, как работают компьютеры и Интернет.** Управление собственным сервером - довольно хороший контекст для понимания основных механизмов, лежащих в основе операционных систем и Интернета. Возможно, вам придется иметь дело с интерфейсом командной строки, сетевой архитектурой, конфигурацией DNS, SSH и так далее. - **Вы хотите исследовать новые возможности и настраивать вещи.** Вы когда-нибудь мечтали запустить сервер Minecraft для своих друзей или постоянный IRC или XMPP-клиент? Имея свой собственный сервер, вы можете вручную установить и запустить практически любую программу, которую пожелаете, и настроить все до мелочей. -## Почему вы * не должны* принимать гостей сами? +## Почему вы *не должны* принимать гостей сами? - **Самостоятельный хостинг требует некоторой работы и терпения.** Самостоятельный хостинг немного похож на выращивание собственного сада или овощей: это требует работы и терпения. В то время как YunoHost стремится выполнить всю тяжелую работу за вас, самостоятельный хостинг по-прежнему требует, чтобы вы потратили время на изучение и настройку нескольких вещей для правильной настройки вашего сервера. Вам также нужно будет время от времени выполнять задачи технического обслуживания (например, обновления) или обращаться за поддержкой, если что-то выйдет из строя. - **С отличными серверами приходит большая ответственность.** Эксплуатация сервера означает, что вы несете ответственность за данные, которые размещаете. Никто не сможет восстановить их для вас, если они потеряются. YunoHost предоставляет функции резервного копирования, которые вы должны регулярно использовать для резервного копирования нужных вам конфигураций и данных. Вам также следует следить за новостями и рекомендациями по безопасности, чтобы ваш сервер или критически важные данные не были скомпрометированы. -- **Качество и производительность, вероятно, будут не так хороши, как услуги премиум-класса.** YunoHost (и большинство приложений, упакованных для него) - это бесплатное программное обеспечение с открытым исходным кодом, разработанное сообществами людей в свободное время и на основе наилучших усилий. Нет абсолютной гарантии, что программное обеспечение будет работать при любых возможных обстоятельствах. Производительность вашего автономного сервера также зависит от его центрального процессора и оперативной памяти, а также от доступного подключения к Интернету. \ No newline at end of file +- **Качество и производительность, вероятно, будут не так хороши, как услуги премиум-класса.** YunoHost (и большинство приложений, упакованных для него) - это бесплатное программное обеспечение с открытым исходным кодом, разработанное сообществами людей в свободное время и на основе наилучших усилий. Нет абсолютной гарантии, что программное обеспечение будет работать при любых возможных обстоятельствах. Производительность вашего автономного сервера также зависит от его центрального процессора и оперативной памяти, а также от доступного подключения к Интернету. diff --git a/pages/01.overview/10.what_is_yunohost/what_is_yunohost.ar.md b/pages/01.overview/10.what_is_yunohost/what_is_yunohost.ar.md index dc13bdf2..3bf9d3e8 100644 --- a/pages/01.overview/10.what_is_yunohost/what_is_yunohost.ar.md +++ b/pages/01.overview/10.what_is_yunohost/what_is_yunohost.ar.md @@ -29,11 +29,10 @@ routes: ### أصل فكرة المشروع - تعود نشأة فكرة مشروع واي يونوهوست YunoHost إلى شهر فيفري مِن عام 2012 بعد محادثة بدأت على هذا الشكل تقريبًا : -
« تبًا، لقد سئِمتُ مِن إعادة إعداد خادم البريد الإلكتروني ... Beudbeud، كيف قُمتَ بإعداد خادومك الجميل حول LDAP ؟ » -Kload، فيفري 2012
+> « تبًا، لقد سئِمتُ مِن إعادة إعداد خادم البريد الإلكتروني ... Beudbeud، كيف قُمتَ بإعداد خادومك الجميل حول LDAP ؟ » +> Kload، فيفري 2012 Il ne manquait en fait qu’une interface d’administration au serveur de Beudbeud pour en faire quelque chose d’exploitable, alors Kload a décidé de la développer. Finalement, après l’automatisation de quelques configurations et le packaging de quelques applications web, la première version de YunoHost était sortie. @@ -43,7 +42,7 @@ Constatant l’engouement croissant autour de YunoHost et de l’auto-hébergeme ### الهدف -يهدف واي يونوهوست YunoHost إلى تسهيل عملية تنصيب و تثبيت و إدارة أي خادمٍ لأكبر عدد ممكن مِن الناس و ذلك دون المساس بجودة و موثوقية البرمجيات. +يهدف واي يونوهوست YunoHost إلى تسهيل عملية تنصيب و تثبيت و إدارة أي خادمٍ لأكبر عدد ممكن مِن الناس و ذلك دون المساس بجودة و موثوقية البرمجيات. لم يُدَّخر أي جهد لتسهيل عملية التنصيب و الإنبساط وذلك على أكبر عدد ممكن مِن الأجهزة مهما اختلفت مميزات كل جهاز (في المنزل أو على خادوم إستضافة أو على خادوم شخصي إفتراضي) @@ -79,4 +78,3 @@ Même si YunoHost est multi-domaine et multi-utilisateur, il reste **inappropri Premièrement parce que le logiciel est trop jeune, donc non-testé et non-optimisé pour être mis en production pour des centaines d’utilisateurs en même temps. Et quand bien même, ce n’est pas le chemin que l’on souhaite faire suivre à YunoHost. La virtualisation se démocratise, et c’est une façon bien plus étanche et sécurisée de faire de la mutualisation. Vous pouvez héberger vos amis, votre famille ou votre entreprise sans problème, mais vous devez **avoir confiance** en vos utilisateurs, et ils doivent de la même façon avoir confiance en vous. Si vous souhaitez tout de même fournir des services YunoHost à des inconnus, **un VPS entier par utilisateur** sera la meilleure solution. - diff --git a/pages/01.overview/10.what_is_yunohost/what_is_yunohost.de.md b/pages/01.overview/10.what_is_yunohost/what_is_yunohost.de.md index 6ab27348..9f60969a 100644 --- a/pages/01.overview/10.what_is_yunohost/what_is_yunohost.de.md +++ b/pages/01.overview/10.what_is_yunohost/what_is_yunohost.de.md @@ -23,13 +23,14 @@ YunoHost ist ein **Betriebssystem**, das auf die einfachste Verwaltung eines **S - ![](image://icon-mail.png?resize=32&classes=inline) Enthält einen **vollständigen E-Mail-Stack** (Postfix, Dovecot, Rspamd, DKIM) ; - ![](image://icon-messaging.png?resize=32&classes=inline) … sowie **einen Instant Messaging Server** (XMPP) ; - ![](image://icon-lock.png?resize=32&classes=inline) Verwaltet **SSL-Zertifikate** (basierend auf Let's Encrypt) ; -- ![](image://icon-shield.png?resize=32&classes=inline) … und **Sicherheitssysteme** (fail2ban, yunohost-firewall) ; +- ![](image://icon-shield.png?resize=32&classes=inline) … und **Sicherheitssysteme** (`fail2ban`, `yunohost-firewall`) ; ## Ursprung YunoHost wurde im Februar 2012 aus folgender Situation heraus erstellt: -

"Scheiße, ich bin zu faul, um meinen Mailserver neu zu konfigurieren ... Beudbeud, wie hast Du deinen kleinen Server mit LDAP zum Laufen gebracht?"

Kload, Februar 2012
+> "Scheiße, ich bin zu faul, um meinen Mailserver neu zu konfigurieren ... Beudbeud, wie hast Du deinen kleinen Server mit LDAP zum Laufen gebracht?" +> Kload, Februar 2012 Alles, was benötigt wurde, war eine Administrationsoberfläche für Beudbeud's Server, um etwas nutzbar zu machen, also entschied sich Kload, eine zu entwickeln. Schließlich wurde YunoHost v1, nach der Automatisierung mehrerer Konfigurationen und der Paketierung in einigen Webanwendungen, fertiggestellt. diff --git a/pages/01.overview/10.what_is_yunohost/what_is_yunohost.es.md b/pages/01.overview/10.what_is_yunohost/what_is_yunohost.es.md index 0a85df23..477a0e39 100644 --- a/pages/01.overview/10.what_is_yunohost/what_is_yunohost.es.md +++ b/pages/01.overview/10.what_is_yunohost/what_is_yunohost.es.md @@ -23,20 +23,20 @@ YunoHost es un **sistema operativo** que persigue simplificar la administración - ![](image://icon-mail.png?resize=32&classes=inline) Incluye un **servidor de correo electrónico completo** (Postfix, Dovecot, Rspamd, DKIM) ; - ![](image://icon-messaging.png?resize=32&classes=inline) … así como un **servidor de mensajería instanea** (XMPP) ; - ![](image://icon-lock.png?resize=32&classes=inline) Administra **certificados SSL** (generados por Let's Encrypt) ; -- ![](image://icon-shield.png?resize=32&classes=inline) … y los **sistemas de seguridad** (fail2ban, yunohost-firewall) ; +- ![](image://icon-shield.png?resize=32&classes=inline) … y los **sistemas de seguridad** (`fail2ban`, `yunohost-firewall`) ; ## Origen YunoHost se creó en Febrero de 2012 tras algo así: -

"¡Mierda, soy muy vago para reconfigurar mi servidor de correo!… Beudbeud, ¿Cómo hiciste para conectar tu pequeño servidor a LDAP?"

-Kload, Febrero de 2012
+> "¡Mierda, soy muy vago para reconfigurar mi servidor de correo!… Beudbeud, ¿Cómo hiciste para conectar tu pequeño servidor a LDAP?" +> Kload, Febrero de 2012 Lo único que necesitaba era un interfaz de administración para el servidor de Beudbeud para tener algo usable, así que Kload decidió desarrollar uno. Finalmente, tras automatizar varias configuraciones y empaquetar algunas aplicaciones web, YunoHost v1 quedó terminado. Notando un entusiasmo creciente alrededor de YunoHost y del autoalojamiento en general, los desarrolladores originales junto con nuevas personas contribuyentes decidieron comenzar a trabajar en la versión 2, una versión más extensible, más potente, más fácil de usar, y ya de paso, una que prepare ricas tazas de café de comercio justo para los elfos de Laponia. -El nombre **YunoHost** viene de la jerga "Y U NO Host". El [meme de Internet ](https://en.wikipedia.org/wiki/Internet_meme) debería ilustrarlo: +El nombre **YunoHost** viene de la jerga "Y U NO Host". El [meme de Internet](https://en.wikipedia.org/wiki/Internet_meme) debería ilustrarlo: ![](image://dude_yunohost.jpg) ## ¿Qué no es YunoHost? diff --git a/pages/01.overview/10.what_is_yunohost/what_is_yunohost.fr.md b/pages/01.overview/10.what_is_yunohost/what_is_yunohost.fr.md index f3c03a58..400c9114 100644 --- a/pages/01.overview/10.what_is_yunohost/what_is_yunohost.fr.md +++ b/pages/01.overview/10.what_is_yunohost/what_is_yunohost.fr.md @@ -23,14 +23,14 @@ YunoHost est un **système d’exploitation** qui vise à simplifier autant que - ![](image://icon-mail.png?resize=32&classes=inline) fourni avec un **serveur mail complet** (Postfix, Dovecot, Rspamd, DKIM) ; - ![](image://icon-messaging.png?resize=32&classes=inline) ... ainsi qu'un **serveur de messagerie instantanée** (XMPP) ; - ![](image://icon-lock.png?resize=32&classes=inline) gère les **certificats SSL** (basé sur Let's Encrypt) ; -- ![](image://icon-shield.png?resize=32&classes=inline) ... et des **systèmes de sécurité** (Fail2Ban, yunohost-firewall). +- ![](image://icon-shield.png?resize=32&classes=inline) ... et des **systèmes de sécurité** (`fail2ban`, `yunohost-firewall`). ## Origine YunoHost est un projet né en février 2012 à la suite d’à peu près ça : -

« Merde, j’ai la flemme de me reconfigurer un serveur mail... Beudbeud, comment t’as fait pour configurer ton joli serveur sous LDAP ? »

-Kload, février 2012
+> « Merde, j’ai la flemme de me reconfigurer un serveur mail... Beudbeud, comment t’as fait pour configurer ton joli serveur sous LDAP ? » +> Kload, février 2012 Il ne manquait en fait qu’une interface d’administration au serveur de Beudbeud pour en faire quelque chose d’exploitable, alors Kload a décidé de la développer. Finalement, après l’automatisation de quelques configurations et le packaging de quelques applications web, la première version de YunoHost était sortie. diff --git a/pages/01.overview/10.what_is_yunohost/what_is_yunohost.it.md b/pages/01.overview/10.what_is_yunohost/what_is_yunohost.it.md index 67e89db9..0106dee4 100644 --- a/pages/01.overview/10.what_is_yunohost/what_is_yunohost.it.md +++ b/pages/01.overview/10.what_is_yunohost/what_is_yunohost.it.md @@ -13,29 +13,30 @@ YunoHost è un **sistema operativo** che mira a rendere il più semplice possibi ## Caratteristiche -- ![](image://icon-debian.png?resize=32&classes=inline) Basato su Debian; +- ![](image://icon-debian.png?resize=32&classes=inline) Basato su Debian; - ![](image://icon-tools.png?resize=32&classes=inline) Amministra il tuo server attraverso **un'interfaccia web amichevole** ; - ![](image://icon-package.png?resize=32&classes=inline) Installa le **applicazioni in pochi clic**; -- ![](image://icon-users.png?resize=32&classes=inline) Gestisci **gli utenti ** (basato su LDAP); +- ![](image://icon-users.png?resize=32&classes=inline) Gestisci **gli utenti** (basato su LDAP); - ![](image://icon-globe.png?resize=32&classes=inline) Gestisci **i nomi di dominio**; - ![](image://icon-medic.png?resize=32&classes=inline) Crea e ripristina **i backup**; - ![](image://icon-door.png?resize=32&classes=inline) Connettiti contemporaneamente a tutte le applicazioni attraverso **il portale utente** (NGINX, SSOwat); - ![](image://icon-mail.png?resize=32&classes=inline) Include uno **stack di posta elettronica completo** (Postfix, Dovecot, Rspamd, DKIM); - ![](image://icon-messaging.png?resize=32&classes=inline)... e anche un **server di messaggistica istantanea** (XMPP); - ![](image://icon-lock.png?resize=32&classes=inline) Gestisce i **certificati SSL** (basati su Let's Encrypt) ; -- ![](image://icon-shield.png?resize=32&classes=inline)... e i **sistemi di sicurezza** (Fail2ban, yunohost-firewall); +- ![](image://icon-shield.png?resize=32&classes=inline)... e i **sistemi di sicurezza** (`fail2ban`, `yunohost-firewall`); ## Origine + YunoHost è stata creata nel febbraio 2012 dopo qualcosa del genere: -

"Merda, sono troppo pigro per riconfigurare il mio server di posta... Beudbeud, come sei riuscito a far funzionare il tuo piccolo server con LDAP?"

-Kload, Febbraio 2012
+> "Merda, sono troppo pigro per riconfigurare il mio server di posta... Beudbeud, come sei riuscito a far funzionare il tuo piccolo server con LDAP?" +> Kload, Febbraio 2012 Tutto ciò che serviva era un'interfaccia di amministrazione per il server di Beudbeud per creare qualcosa di utilizzabile, così Kload ha deciso di svilupparne una. Alla fine, dopo aver automatizzato diverse configurazioni e aver inserito alcune applicazioni web, YunoHost versione 1 è stato completato. Notando il crescente entusiasmo intorno a YunoHost e al self-hosting in generale, gli sviluppatori originari e i nuovi collaboratori hanno deciso di iniziare a lavorare alla versione 2, una versione più estensibile, più potente, più facile da usare e che prepara una bella tazza di caffè equo-solidale per gli elfi della Lapponia. -Il nome **YunoHost** deriva dal gergo "Y U NO Host". Il [meme Internet](https://en.wikipedia.org/wiki/Internet_meme) dovrebbe illustrarlo: +Il nome **YunoHost** deriva dal gergo "Y U NO Host". Il [meme Internet](https://en.wikipedia.org/wiki/Internet_meme) dovrebbe illustrarlo: ![](image://dude_yunohost.jpg) ## Cosa non è YunoHost? diff --git a/pages/01.overview/10.what_is_yunohost/what_is_yunohost.md b/pages/01.overview/10.what_is_yunohost/what_is_yunohost.md index e3add71f..1ffaa1ad 100644 --- a/pages/01.overview/10.what_is_yunohost/what_is_yunohost.md +++ b/pages/01.overview/10.what_is_yunohost/what_is_yunohost.md @@ -23,14 +23,14 @@ YunoHost is an **operating system** aiming to simplify **server administration** - ![](image://icon-mail.png?resize=32&classes=inline) Includes a **full e-mail stack** (Postfix, Dovecot, Rspamd, DKIM); - ![](image://icon-messaging.png?resize=32&classes=inline)... as well as **an instant messaging server** (XMPP); - ![](image://icon-lock.png?resize=32&classes=inline) Manages **SSL certificates** (based on Let's Encrypt); -- ![](image://icon-shield.png?resize=32&classes=inline)... and **security systems** (Fail2ban, yunohost-firewall). +- ![](image://icon-shield.png?resize=32&classes=inline)... and **security systems** (`fail2ban`, `yunohost-firewall`). ## Origin YunoHost was created in February 2012 after something like this: -

"Shit, I'm too lazy to reconfigure my mail server... Beudbeud, how were you able to get your little server running with LDAP?"

-Kload, February 2012
+> "Shit, I'm too lazy to reconfigure my mail server... Beudbeud, how were you able to get your little server running with LDAP?" +> Kload, February 2012 All that was needed was an admin interface for Beudbeud's server to make something usable, so Kload decided to develop one. Finally, after automating several configs and packaging in some web apps, YunoHost v1 was finished. diff --git a/pages/01.overview/10.what_is_yunohost/what_is_yunohost.ru.md b/pages/01.overview/10.what_is_yunohost/what_is_yunohost.ru.md index c0925cf0..b2312767 100644 --- a/pages/01.overview/10.what_is_yunohost/what_is_yunohost.ru.md +++ b/pages/01.overview/10.what_is_yunohost/what_is_yunohost.ru.md @@ -23,14 +23,14 @@ YunoHost это **операционная система** позволяюща - ![](image://icon-mail.png?resize=32&classes=inline) Включает **полный набор для работы электронной почты** (Postfix, Dovecot, Rspamd, DKIM); - ![](image://icon-messaging.png?resize=32&classes=inline)... более известный как **встроенный сервер сообщений** (XMPP); - ![](image://icon-lock.png?resize=32&classes=inline) Управляй **SSL сертификатами** (Основано на Let's Encrypt) ; -- ![](image://icon-shield.png?resize=32&classes=inline)... и **системами безопасности** (Fail2ban, yunohost-firewall); +- ![](image://icon-shield.png?resize=32&classes=inline)... и **системами безопасности** (`fail2ban`, `yunohost-firewall`); ## История YunoHost был создан в Феврале 2012 после чего-то вроде: -

"Блин, Я слишком ленив чтобы перенастроить мой почтовый сервер... Beudbeud, как вам удалось запустить свой малеький сервер LDAP?"

-Kload, Февраль 2012
+> "Блин, Я слишком ленив чтобы перенастроить мой почтовый сервер... Beudbeud, как вам удалось запустить свой малеький сервер LDAP?" +> Kload, Февраль 2012 Всё что было нужно - админ панель для сервера Beudbeud-а чтобы сделать что-то юзабельное, поэтому Kload решил её разработать. В итоге, после автоматизации нескольких конфигураций и упаковки некоторых Веб-приложений, YunoHost v1 был завершён. diff --git a/pages/02.administer/05.how_to_host_yourself/how_to_host_yourself.de.md b/pages/02.administer/05.how_to_host_yourself/how_to_host_yourself.de.md index e1016ed9..66c48787 100644 --- a/pages/02.administer/05.how_to_host_yourself/how_to_host_yourself.de.md +++ b/pages/02.administer/05.how_to_host_yourself/how_to_host_yourself.de.md @@ -11,7 +11,7 @@ Sie können zu Hause (auf einem kleinen Computer) oder auf einem Remote-Server h ### Zu Hause, zum Beispiel auf einem Einplatinencomputer oder einem alten Computer -Sie können zu Hause mit einem Einplatinencomputer oder einem überarbeiteten regulären Computer, der mit Ihrem Heimrouter verbunden ist, hosten. +Sie können zu Hause mit einem Einplatinencomputer oder einem überarbeiteten regulären Computer, der mit Ihrem Heimrouter verbunden ist, hosten. - **Pros** : Sie haben die physische Kontrolle über die Maschine und müssen nur die Hardware kaufen; - **Cons** : Sie müssen [Ihre Internet-Router manuell konfigurieren](/isp_box_config) und [sind möglicherweise von Ihrem Internet-Service-Provider eingeschränkt](/isp). diff --git a/pages/02.administer/05.how_to_host_yourself/how_to_host_yourself.md b/pages/02.administer/05.how_to_host_yourself/how_to_host_yourself.md index 7f4e8af1..38f7f2ff 100644 --- a/pages/02.administer/05.how_to_host_yourself/how_to_host_yourself.md +++ b/pages/02.administer/05.how_to_host_yourself/how_to_host_yourself.md @@ -11,7 +11,7 @@ You can host yourself at home (on a small computer), or on a remote server. Each ### At home, for instance on an ARM board or an old computer -You can host yourself at home with an ARM board or a re-purposed regular computer, connected to your home router/box. +You can host yourself at home with an ARM board or a re-purposed regular computer, connected to your home router/box. - **Pros** : you will have physical control of the machine and only need to buy the hardware; - **Cons** : you will have to [manually configure your internet box](/isp_box_config) and [might be limited by your ISP](/isp). @@ -87,4 +87,4 @@ You can rent a virtual private server or a dedicated machine from [associative]( Typically pretty good - \ No newline at end of file + diff --git a/pages/02.administer/05.how_to_host_yourself/how_to_host_yourself.ru.md b/pages/02.administer/05.how_to_host_yourself/how_to_host_yourself.ru.md index 6ffe5c3c..02844a1d 100644 --- a/pages/02.administer/05.how_to_host_yourself/how_to_host_yourself.ru.md +++ b/pages/02.administer/05.how_to_host_yourself/how_to_host_yourself.ru.md @@ -12,6 +12,7 @@ routes: ### Дома, например, на плате ARM или старом компьютере Вы можете запустить YunoHost у себя дома с помощью платы ARM или переоборудованного обычного компьютера, подключенного к вашему домашнему роутеру. + - **Плюсы** : у вас будет физический контроль над машиной, и вам нужно будет только купить оборудование; - **Минусы** : вам придется [вручную настроить свой роутер](/isp_box_config) и [возможные ограничения вашим провайдером](/isp). @@ -21,7 +22,7 @@ VPN - это зашифрованный туннель между двумя к - **Плюсы** : у вас будет физический контроль над машиной, а VPN скрывает ваш трафик от вашего интернет-провайдера и позволяет вам обойти его ограничения; - **Минусы** : вам придется оплатить ежемесячную подписку на VPN. -- + ### На удалённом сервере (VPS или выделенный) Вы можете арендовать виртуальный частный сервер (VPS) или выделенную машину у [ассоциации](https://db.ffdn.org/) или [коммерческие](/providers/server) облачные провайдеры. @@ -86,4 +87,4 @@ VPN - это зашифрованный туннель между двумя к Обычно достаточно хорошее - \ No newline at end of file + diff --git a/pages/02.administer/10.install/05.images/docs.fr.md b/pages/02.administer/10.install/05.images/docs.fr.md index d0cbe91b..c96fa756 100644 --- a/pages/02.administer/10.install/05.images/docs.fr.md +++ b/pages/02.administer/10.install/05.images/docs.fr.md @@ -45,7 +45,6 @@ Cette page requiert que Javascript soit activé pour s'afficher correctement :s.
- - diff --git a/pages/02.administer/10.install/05.images/images.de.md b/pages/02.administer/10.install/05.images/images.de.md index 1edddfeb..45168002 100644 --- a/pages/02.administer/10.install/05.images/images.de.md +++ b/pages/02.administer/10.install/05.images/images.de.md @@ -39,7 +39,6 @@ N B : Auch wenn das Image nicht der neuesten Version von YunoHost entspricht, k - - diff --git a/pages/02.administer/10.install/05.images/images.es.md b/pages/02.administer/10.install/05.images/images.es.md index c78f3524..b65b9cf8 100644 --- a/pages/02.administer/10.install/05.images/images.es.md +++ b/pages/02.administer/10.install/05.images/images.es.md @@ -38,7 +38,6 @@ N.B. : Incluso si la imagen no corresponde con la última versión de YunoHost, - - - diff --git a/pages/02.administer/10.install/05.images/images.fr.md b/pages/02.administer/10.install/05.images/images.fr.md index 8a4df6b5..af545821 100644 --- a/pages/02.administer/10.install/05.images/images.fr.md +++ b/pages/02.administer/10.install/05.images/images.fr.md @@ -40,7 +40,6 @@ Cette page requiert que Javascript soit activé pour s'afficher correctement :s. - - diff --git a/pages/02.administer/10.install/05.images/images.md b/pages/02.administer/10.install/05.images/images.md index 7e9efb0d..618e7826 100644 --- a/pages/02.administer/10.install/05.images/images.md +++ b/pages/02.administer/10.install/05.images/images.md @@ -40,7 +40,6 @@ This page requires Javascript enabled to display properly :s. - - diff --git a/pages/02.administer/10.install/05.images/images.ru.md b/pages/02.administer/10.install/05.images/images.ru.md index 6c7ef88d..baeb36af 100644 --- a/pages/02.administer/10.install/05.images/images.ru.md +++ b/pages/02.administer/10.install/05.images/images.ru.md @@ -40,7 +40,6 @@ routes: - - diff --git a/pages/02.administer/10.install/10.finding_the_local_ip/finding_the_local_ip.de.md b/pages/02.administer/10.install/10.finding_the_local_ip/finding_the_local_ip.de.md index 0c4d9b26..001569bd 100644 --- a/pages/02.administer/10.install/10.finding_the_local_ip/finding_the_local_ip.de.md +++ b/pages/02.administer/10.install/10.finding_the_local_ip/finding_the_local_ip.de.md @@ -10,14 +10,17 @@ routes: Bei einer Installation zu Hause sollte Ihr Server normalerweise über die Domäne`yunohost.local` erreichbar sein. Wenn dies aus irgendeinem Grund nicht funktioniert, müssen Sie möglicherweise die *lokale* IP-Adresse Ihres Servers ermitteln. ## Was ist ein locales IP ? + Die lokale IP-Adresse ist die, die verwendet wird, um auf Ihren Server innerhalb des lokalen Netzwerks (typischerweise Ihr Zuhause) zu verweisen, wo mehrere Geräte an einen Router (Ihre Internetbox) angeschlossen sind. Die lokale IP-Adresse sieht typischerweise so aus `192.168.x.y` (oder manchmal `10.0.x.y` oder `172.16.x.y`) ## Wie findet man es? + Jeder dieser Tricks sollte es Ihnen ermöglichen, die lokale IP-Adresse Ihres Servers zu finden: [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="(Empfohlen) Mit Angry IP Scanner"] Verwenden Sie dazu die [AngryIP](https://angryip.org/download/) Software. Sie Brauchen nur diese lokalen IP-Bereiche in dieser Reihenfolge durchsuchen, bis Sie die aktive IP-Adresse finden, die Ihrem Server entspricht: + - `192.168.0.0` -> `192.168.0.255` - `192.168.1.0` -> `192.168.1.255` - `192.168.2.0` -> `192.168.255.255` @@ -44,8 +47,9 @@ Wenn der Befehl `arp-scan` viele Geräte anzeigt, können Sie dann mit dem Befeh Bildschirm auf den Server anschliessen, sich einloggen und diesen Befehl eingeben`hostname --all-ip-address`. Die Standard-Anmeldedaten (vor der Nachinstallation!) zum Einloggen sind: -- login: root -- password: yunohost + +- login: `root` +- password: `yunohost` (Wenn Sie ein rohes Armbian-Image anstelle des vorinstallierten YunoHost-Images verwenden, lauten die Anmeldedatenen root / 1234) diff --git a/pages/02.administer/10.install/10.finding_the_local_ip/finding_the_local_ip.fr.md b/pages/02.administer/10.install/10.finding_the_local_ip/finding_the_local_ip.fr.md index d6f28e4e..426a945e 100644 --- a/pages/02.administer/10.install/10.finding_the_local_ip/finding_the_local_ip.fr.md +++ b/pages/02.administer/10.install/10.finding_the_local_ip/finding_the_local_ip.fr.md @@ -10,14 +10,17 @@ routes: Dans le cas d'une installation à la maison, votre serveur devrait typiquement être accessible (depuis son réseau local) avec le domaine `yunohost.local`. Si pour une raison quelconque cela ne fonctionne pas, il vous faut peut-être trouver l'IP locale de votre serveur. ## Qu'est ce qu'une IP locale ? + L'IP locale d'une machine est utilisée pour y faire référence à l'intérieur d'un réseau local (typiquement le réseau dans une maison) où plusieurs appareils se connectent à un même routeur (votre box internet). Une adresse IP locale ressemble généralement à `192.168.x.y` (ou parfois `10.0.x.y` ou `172.16.x.y`) ## Comment la trouver ? + L'une de ces astuces devrait permettre de trouver l'IP locale de votre serveur : [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="(Recommandé) Avec AngryIP"] Vous pouvez utiliser le logiciel [AngryIP](https://angryip.org/download/) pour y parvenir. Vous devez juste scanner ces plages d'IP dans cet ordre jusqu'à trouver l'IP correspondante à votre serveur : + - `192.168.0.0` -> `192.168.0.255` - `192.168.1.0` -> `192.168.1.255` - `192.168.2.0` -> `192.168.255.255` @@ -44,8 +47,9 @@ Si la commande `arp-scan` vous affiche beaucoup de machines, vous pouvez vérifi Branchez un écran sur votre serveur, loggez-vous et tapez `hostname --all-ip-address`. Les identifiants par défaut (avant la post-installation!) sont : -- login : root -- mot de passe : yunohost + +- login : `root` +- mot de passe : `yunohost` (Si vous utilisez une image Armbian brute plutôt que les images YunoHost pré-installées, les identifiants sont root / 1234) @@ -53,6 +57,7 @@ Les identifiants par défaut (avant la post-installation!) sont : [/ui-tabs] ## Je ne trouve toujours pas mon IP locale + Si vous n'êtes pas capable de trouver votre serveur avec les méthodes précédentes, alors peut-être que votre serveur n'a pas démarré correctement. - Assurez-vous que le serveur est correctement branché ; diff --git a/pages/02.administer/10.install/10.finding_the_local_ip/finding_the_local_ip.md b/pages/02.administer/10.install/10.finding_the_local_ip/finding_the_local_ip.md index c7b608fe..89c5ef23 100644 --- a/pages/02.administer/10.install/10.finding_the_local_ip/finding_the_local_ip.md +++ b/pages/02.administer/10.install/10.finding_the_local_ip/finding_the_local_ip.md @@ -10,14 +10,17 @@ routes: On an installation at home, your server should typically be accessible using the `yunohost.local` domain. If for any reason this does not work, you may need to find the *local* IP of your server. ## What is a local IP ? + The local IP is the address used to refer to your server inside the local network (typically your home) where multiple devices are connected to a router (your internet box). The local IP typically looks like `192.168.x.y` (or sometimes `10.0.x.y` or `172.16.x.y`) ## How to find it ? + Any of these tricks should allow you to find the local IP of your server: [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="(Recommended) With AngryIP"] You can use the [AngryIP](https://angryip.org/download/) software to achieve that. You just need to scan these local ip ranges in this order until you find the active IP corresponding to your server: + - `192.168.0.0` -> `192.168.0.255` - `192.168.1.0` -> `192.168.1.255` - `192.168.2.0` -> `192.168.255.255` @@ -44,8 +47,9 @@ If the `arp-scan` command displays a confusing number of devices, you can check Plug a screen on your server, log in and type `hostname --all-ip-address`. The default credentials (before post-installation!) to log in are: -- login: root -- password: yunohost + +- login: `root` +- password: `yunohost` (If you are using a raw Armbian image instead of the pre-installed YunoHost image, the credentials are root / 1234) diff --git a/pages/02.administer/10.install/10.finding_the_local_ip/finding_the_local_ip.ru.md b/pages/02.administer/10.install/10.finding_the_local_ip/finding_the_local_ip.ru.md index cf90aa61..6191aca4 100644 --- a/pages/02.administer/10.install/10.finding_the_local_ip/finding_the_local_ip.ru.md +++ b/pages/02.administer/10.install/10.finding_the_local_ip/finding_the_local_ip.ru.md @@ -10,14 +10,17 @@ routes: При установке дома ваш сервер, как правило, должен быть доступен с использованием домена `yunohost.local`. Если по какой-либо причине это не сработает, возможно, вам потребуется найти *локальный* IP-адрес вашего сервера. ## Что такое локальный IP-адрес ? + Локальный IP-адрес - это адрес, используемый для обращения к вашему серверу внутри локальной сети (обычно вашего дома), где несколько устройств подключены к маршрутизатору. Локальный IP-адрес обычно выглядит как `192.168.x.y` (или иногда `10.0.x.y` или `172.16.x.y`). ## Как его найти ? + Любой из этих приемов должен позволить вам найти локальный IP-адрес вашего сервера: [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="(Рекомендуемый) используя AngryIP"] Вы можете использовать [AngryIP](https://angryip.org/download/) для достижения этой цели. Вам просто нужно сканировать эти локальные диапазоны ip-адресов в таком порядке, пока вы не найдете активный IP-адрес, соответствующий вашему серверу: + - `192.168.0.0` -> `192.168.0.255` - `192.168.1.0` -> `192.168.1.255` - `192.168.2.0` -> `192.168.255.255` @@ -27,7 +30,7 @@ routes: !!! **Советы**: !!! - вы можете сделать отсортировать по ping, как показано на этом скриншоте, чтобы легко увидеть используемый IP. !!! - обычно ваш сервер должен отображаться как прослушивающий на портах 80 и 443 -!!! - в случае сомнений просто введите `https://192.168.x.y " в вашем браузере, чтобы проверить, является ли это YunoHost или нет. +!!! - в случае сомнений просто введите `https://192.168.x.y` в вашем браузере, чтобы проверить, является ли это YunoHost или нет. ![](image://angryip.png?class=inline) @@ -44,8 +47,9 @@ routes: Подключите экран к своему серверу, войдите в систему и введите `hostname --all-ip-address`. Учетные данные по умолчанию (перед постустановкой!) для входа в систему: -- логин: root -- пароль: yunohost + +- логин: `root` +- пароль: `yunohost` (Если вы используете необработанный образ Armbian вместо предустановленного образа YunoHost, учетные данные - root / 1234) @@ -59,4 +63,4 @@ routes: - Убедитесь, что ваш сервер правильно подключен; - Если вы используете SD-карту, убедитесь, что разъем не слишком запылился; - Подключите экран к вашему серверу и попробуйте перезагрузиться, чтобы проверить, правильно ли он загружается; -- Убедитесь, что ваш кабель Ethernet исправен и правильно подключен; \ No newline at end of file +- Убедитесь, что ваш кабель Ethernet исправен и правильно подключен; diff --git a/pages/02.administer/10.install/15.isp_box_config/isp_box_config.de.md b/pages/02.administer/10.install/15.isp_box_config/isp_box_config.de.md index abe7f8b1..2eabd33a 100644 --- a/pages/02.administer/10.install/15.isp_box_config/isp_box_config.de.md +++ b/pages/02.administer/10.install/15.isp_box_config/isp_box_config.de.md @@ -25,6 +25,7 @@ Ihre Box/Router-Administrationsoberfläche ist in der Regel erreichbar über [ht ### 2. Die lokale IP Ihres Servers finden Identifizieren Sie die lokale IP Ihres Servers, entweder : + - von Ihrer Box/Router-Schnittstelle, die möglicherweise angeschlossene Geräte auflistet - über die YunoHost-Schnittstelle, Abschnitt "Internetkonnektivität", dann auf "Details" im IPv4-Bericht klicken. - von der Befehlszeile Ihres Servers aus, indem Sie `hostname -I` ausführen @@ -39,12 +40,13 @@ Suchen Sie in der Verwaltungsoberfläche Ihres Routers nach etwas wie "Router-Ko Das Öffnen der unten aufgeführten Ports ist notwendig, damit die verschiedenen in YunoHost verfügbaren Dienste funktionieren. Für jeden von ihnen wird die 'TCP'-Weiterleitung benötigt. Einige Schnittstellen beziehen sich auf 'externe' und 'interne' Ports : diese sind in unserem Fall gleich. -* Web: 80 (HTTP), 443 (HTTPS) -* [SSH](/ssh): 22 -* [XMPP](/XMPP): 5222 (clients), 5269 (servers) -* [Email](/email): 25, 587 (SMTP), 993 (IMAP) +- Web: `80` (HTTP), `443` (HTTPS) +- [SSH](/ssh): `22` +- [XMPP](/XMPP): `5222` (clients), `5269` (servers) +- [Email](/email): `25`, `587` (SMTP), `993` (IMAP) Wenn Sie sowohl ein Modem als auch einen Router verwenden, dann müssen Sie Folgendes tun: + 1. zuerst auf dem Modem (der Box, die dem Internet am nächsten ist) Regeln erstellen, um die oben genannten Ports an Ihren Router weiterzuleiten; 2. dann auf dem Router (der Box zwischen dem Modem und Ihren Geräten) Regeln erstellen, um die oben genannten Ports an die statische IP-Adresse für Ihren Server weiterzuleiten. diff --git a/pages/02.administer/10.install/15.isp_box_config/isp_box_config.es.md b/pages/02.administer/10.install/15.isp_box_config/isp_box_config.es.md index e8fc229b..86e19197 100644 --- a/pages/02.administer/10.install/15.isp_box_config/isp_box_config.es.md +++ b/pages/02.administer/10.install/15.isp_box_config/isp_box_config.es.md @@ -19,18 +19,19 @@ El esquema aquí abajo intenta explicar brevemente el rol de la redirección de ### 0. Diagnosticar los puertos abiertos -Una vez que tienes la redirección configurada, deberías poder comprobar que los puertos están bien abiertos con esta herramienta : +Una vez que tienes la redirección configurada, deberías poder comprobar que los puertos están bien abiertos con esta herramienta : Comprobar la redirección de los puertos ### 1. Acceder a la interfaz de administración de tu router/caja/box -En general la interfaz de administración está accesible desde http://192.168.0.1 o http://192.168.1.1. +En general la interfaz de administración está accesible desde o . Luego, es posible que tengas que autenticarte con los ID provechos pour tu proveedor de acceso a Internet. ### 2. Descubrir la IP local del servidor Identifica cuál es la IP local de tu servidor, o sea : + - desde la interfaz de tu router/caja/box, donde tal vez estén listados los dipositivos conectados a la red local - desde la webadmin de YunoHost, en 'Estado del servidor', 'Red' - desde la línea de comandos en tu servidor, por ejemplo con `ip a | grep "scope global" | awk '{print $2}'` @@ -43,10 +44,10 @@ En la interfaz de administración de tu router/caja/box, tienes que encontrar un Luego tienes que redirigir cada uno de los puertos listados a continuación hacia la IP local de tu router para que los varios servicios de YunoHost funcionen. Para cada uno de ellos, una redirección 'TCP' es necesaria. En algunas interfaces, tal vez encontrarás referencias a un puerto 'externo' y un puerto 'interno' : en nuestro caso, se trata del mismo número de puerto, que sea interno o externo. -* Web: 80 (HTTP), 443 (HTTPS) -* [SSH](/ssh): 22 -* [XMPP](/XMPP): 5222 (clients), 5269 (servers) -* [Email](/email): 25, 587 (SMTP), 993 (IMAP) +- Web: `80` (HTTP), `443` (HTTPS) +- [SSH](/ssh): `22` +- [XMPP](/XMPP): `5222` (clients), `5269` (servers) +- [Email](/email): `25`, `587` (SMTP), `993` (IMAP) ! [fa=exclamation-triangle /] Algunos proveedores de acceso a Internet bloquean el puerto 25 (mail SMTP) por defecto para luchar con el spam. Otros (más escasos) no permiten utilizar libremente los puertos 80/443. Dependiendo de tu proveedor, puede ser posible de abrir estos puertos en la interfaz... Ver [esta página](/isp) por más informaciones. @@ -54,8 +55,6 @@ Luego tienes que redirigir cada uno de los puertos listados a continuación haci Una tecnología llamada UPnP está disponible en algunos routers/cajas/box y permite redirigir automáticamente puertos hacia una máquina que lo pide. Si UPnP está activado en tu casa, ejecutar este comando debería automáticamente redirigir los puertos correctos : - ```bash sudo yunohost firewall reload ``` - diff --git a/pages/02.administer/10.install/15.isp_box_config/isp_box_config.fr.md b/pages/02.administer/10.install/15.isp_box_config/isp_box_config.fr.md index 4ab88031..68bc6b00 100644 --- a/pages/02.administer/10.install/15.isp_box_config/isp_box_config.fr.md +++ b/pages/02.administer/10.install/15.isp_box_config/isp_box_config.fr.md @@ -22,13 +22,14 @@ YunoHost 3.8 vous permettra de vérifier si les ports sont correctement exposés ### 2. Accéder à l'interface d'administration de votre box/routeur -L'interface d'administration est généralement accessible via http://192.168.0.1 ou http://192.168.1.1. +L'interface d'administration est généralement accessible via ou . Ensuite, il vous faudra peut-être vous authentifier avec les identifiants fournis par votre fournisseur d'accès à Internet (FAI). ### 3. Trouver l'IP locale de votre serveur Identifiez quelle est l'IP locale de votre serveur, soit : + - depuis l'interface de votre routeur/box, qui liste peut-être les dispositifs connectés; - depuis la webadmin de YunoHost, dans 'Diagnostic', section 'Connectivité Internet', cliquer sur 'Détails' à côté de la ligne sur IPv4. @@ -44,10 +45,10 @@ nom diffère suivant le type / marque de la box... Il vous faut ensuite rediriger chacun des ports listés ci-dessous vers l'IP locale de votre serveur pour que les différents services de YunoHost fonctionnent. Pour chacun d'eux, une redirection 'TCP' est nécessaire. Certaines interfaces font référence à un port « externe » et un port « interne » : dans notre cas il s'agit du même. -* Web: 80 (HTTP), 443 (HTTPS) -* [SSH](/ssh): 22 -* [XMPP](/XMPP): 5222 (clients), 5269 (serveurs) -* [Email](/email): 25, 587 (SMTP), 993 (IMAP) +- Web : `80` (HTTP), `443` (HTTPS) +- [SSH](/ssh) : `22` +- [XMPP](/XMPP) : `5222` (clients), `5269` (serveurs) +- [Email](/email) : `25`, `587` (SMTP), `993` (IMAP) ! [fa=exclamation-triangle /] Certains fournisseurs d'accès à Internet bloquent le port 25 (mail SMTP) par défaut pour combattre le spam. D'autres (plus rares) ne permettent pas d'utiliser librement les ports 80/443. En fonction de votre FAI, il peut être possible d'ouvrir ces ports dans l'interface... Voir [cette page](/isp) pour plus d'informations. diff --git a/pages/02.administer/10.install/15.isp_box_config/isp_box_config.md b/pages/02.administer/10.install/15.isp_box_config/isp_box_config.md index 0f7995aa..434ee323 100644 --- a/pages/02.administer/10.install/15.isp_box_config/isp_box_config.md +++ b/pages/02.administer/10.install/15.isp_box_config/isp_box_config.md @@ -39,12 +39,13 @@ In your router admin interface, look for something like 'router configuration' o Opening the ports listed below is necessary for the various services available in YunoHost to work. For each of them, the 'TCP' forwarding is needed. Some interfaces refer to 'external' and 'internal' ports : these are the same in our case. -* Web: 80 (HTTP), 443 (HTTPS) -* [SSH](/ssh): 22 -* [XMPP](/XMPP): 5222 (clients), 5269 (servers) -* [Email](/email): 25, 587 (SMTP), 993 (IMAP) +- Web: `80` (HTTP), `443` (HTTPS) +- [SSH](/ssh): `22` +- [XMPP](/XMPP): `5222` (clients), `5269` (servers) +- [Email](/email): `25`, `587` (SMTP), `993` (IMAP) If you use both a modem and a router, then you need to do the following: + 1. first on the modem (the box closest to the internet) create rules to forward the above ports to your router; 2. then on the router (the box between the modem and your devices) create rules to forward the above ports to the static IP address for your server. @@ -57,4 +58,3 @@ A technology called UPnP is available on some internet boxes / routers and allow ```bash sudo yunohost firewall reload ``` - diff --git a/pages/02.administer/10.install/15.isp_box_config/isp_box_config.ru.md b/pages/02.administer/10.install/15.isp_box_config/isp_box_config.ru.md index 10390dcb..46d2b5f5 100644 --- a/pages/02.administer/10.install/15.isp_box_config/isp_box_config.ru.md +++ b/pages/02.administer/10.install/15.isp_box_config/isp_box_config.ru.md @@ -24,6 +24,7 @@ routes: ### 2. Найдите локальный IP-адрес вашего сервера Определите, каков *локальный* IP вашего сервера, либо : + - из вашего интерфейса box / router, в котором может быть список подключенных устройств - в веб-администраторе YunoHost, в разделе "Диагностика", "Подключение к Интернету", нажмите "Подробности" в отчете IPv4. - из командной строки на вашем сервере, запустив `hostname -I` @@ -38,12 +39,13 @@ routes: Открытие перечисленных ниже портов необходимо для работы различных сервисов, доступных в YunoHost. Для каждого из них необходима переадресация "TCP". Некоторые интерфейсы относятся к "внешним" и "внутренним" портам: в нашем случае это одно и то же. -* Веб: 80 (HTTP), 443 (HTTPS) -* [SSH](/ssh): 22 -* [XMPP](/XMPP): 5222 (клиенты), 5269 (серверы) -* [Почтовые](/email): 25, 587 (SMTP), 993 (IMAP) +- Веб: 80 (HTTP), 443 (HTTPS) +- [SSH](/ssh): 22 +- [XMPP](/XMPP): 5222 (клиенты), 5269 (серверы) +- [Почтовые](/email): 25, 587 (SMTP), 993 (IMAP) Если вы используете и модем, и маршрутизатор, то вам необходимо выполнить следующее: + 1. сначала на модеме (поле, расположенном ближе всего к Интернету) создайте правила для перенаправления вышеуказанных портов на ваш маршрутизатор; 2. затем на маршрутизаторе (поле между модемом и вашими устройствами) создайте правила для пересылки вышеуказанных портов на статический IP-адрес вашего сервера. @@ -56,4 +58,3 @@ routes: ```bash sudo yunohost firewall reload ``` - diff --git a/pages/02.administer/10.install/20.dns_config/dns_config.de.md b/pages/02.administer/10.install/20.dns_config/dns_config.de.md index 75f8271b..7a41fc2b 100644 --- a/pages/02.administer/10.install/20.dns_config/dns_config.de.md +++ b/pages/02.administer/10.install/20.dns_config/dns_config.de.md @@ -17,13 +17,15 @@ sollte die Konfiguration automatisch erfolgen. Wenn Sie Ihren eigenen Domainname Domain über die Schnittstelle Ihres Registrars konfigurieren. ## Empfohlene DNS-Konfiguration -_N.B. : Die Beispiele hier verwenden den Text: `your.domain.tld`, der durch Ihre eigene Domain (z. B.`www.yunohost.org`) zu ersetzen ist._ + +*N.B. : Die Beispiele hier verwenden den Text: `your.domain.tld`, der durch Ihre eigene Domain (z. B.`www.yunohost.org`) zu ersetzen ist.* YunoHost bietet eine empfohlene DNS-Konfiguration, die auf zwei Arten zugänglich ist : + - mit dem Webadmin, unter Domänen > your.domain.tld > DNS-Konfiguration ; - oder auf der Kommandozeile `yunohost domain dns-conf your.domain.tld` -Für einige spezielle Anforderungen oder Installationen und wenn Sie wissen, +Für einige spezielle Anforderungen oder Installationen und wenn Sie wissen, was Sie tun, müssen Sie diese Empfehlung möglicherweise ändern oder andere Datensätze hinzufügen (z. B. zur Behandlung von Subdomains). @@ -79,7 +81,7 @@ dargestellt wird: | TXT | mail._domainkey | `"v=DKIM1; k=rsa; p=irgendeingrooßerSchlüssel"` | | TXT | _dmarc | `"v=DMARC1; p=none"` | -#### Einige Hinweise zu dieser Tabelle +### Einige Hinweise zu dieser Tabelle - Nicht alle dieser Aufzeichnungen sind notwendig. Für eine Minimalinstallation werden nur die fett gedruckten Datensätze benötigt; - Der Punkt am Ende `your.domain.tld.` ist wichtig ;) ; @@ -87,7 +89,7 @@ dargestellt wird: - Die hier gezeigten Werte sind nur Beispiele! Beziehen Sie sich auf die generierte Konfiguration, um herauszufinden, welche Werte zu verwenden sind; - Wir empfehlen eine [TTL](https://de.wikipedia.org/wiki/Time_to_Live#Domain_Name_System) von 3600 (1 Stunde). Es ist aber auch möglich einen anderen Wert zu verwenden, wenn Sie wissen, was Sie tun ; - Legen Sie keinen IPv6-Eintrag an, wenn Sie nicht sicher sind, daß IPv6 auf Ihrem Server funktioniert! Sie werden Probleme mit Let's Encrypt haben, wenn dies nicht der Fall ist. -- If you're using the domain provider Namecheap the SRV DNS entries are formatted as **Service**: _xmpp-client **Protocol**: _tcp **Priority**: 0 **Weight**: 5 **Port**: 5222 **Target**: your.domain.tld +- If you're using the domain provider Namecheap the SRV DNS entries are formatted as **Service**: `_xmpp-client` **Protocol**: `_tcp` **Priority**: `0` **Weight**: `5` **Port**: `5222` **Target**: `your.domain.tld` ### Reverse DNS @@ -97,12 +99,12 @@ für Ihre öffentlichen IPv4- und/oder IPv6-Adressen. Dadurch wird verhindert, d **N.B. : Die Reverse-DNS-Konfiguration erfolgt bei Ihrem Internet Service Provider bzw. VPS-Host. Es betrifft *nicht* den Registrar Ihres Domainnamens.** -Das heißt, wenn Ihre öffentliche IPv4-Adresse `111.222.333.444`ist und Ihr -Domänename `domain.tld`ist, sollten Sie mit dem Befehl +Das heißt, wenn Ihre öffentliche IPv4-Adresse `111.222.333.444` ist und Ihr +Domänename `domain.tld` ist, sollten Sie mit dem Befehl `nslookup` das folgende Ergebnis erhalten : -```shell -$ nslookup 111.222.333.444 +```bash +nslookup 111.222.333.444 444.333.222.111.in-addr.arpa name = domain.tld. ``` diff --git a/pages/02.administer/10.install/20.dns_config/dns_config.es.md b/pages/02.administer/10.install/20.dns_config/dns_config.es.md index 913d858f..d9f7c9d3 100644 --- a/pages/02.administer/10.install/20.dns_config/dns_config.es.md +++ b/pages/02.administer/10.install/20.dns_config/dns_config.es.md @@ -13,11 +13,12 @@ DNS (sistema de nombre de dominios) es un elemento esencial de Internet que perm Si utilizas un [dominio automático](/dns_nohost_me) provecho por el Proyecto YunoHost, la configuración debería ser automática. Si quieres utilizar tu propio nombre de dominio (comprado a un registrar), hay que configurar manualmente tu proprio nombre de dominio vía la interfaz de tu registrar. - ## Configuración DNS recomendada -_Nota: los ejemplos utilizan el marcador `tu.dominio.tld`, debe ser reemplazado por su propio dominio, como `www.yunohost.org`._ + +*Nota: los ejemplos utilizan el marcador `tu.dominio.tld`, debe ser reemplazado por su propio dominio, como `www.yunohost.org`.* YunoHost provee una configuración DNS recomendada, accesible vía : + - la webadmin, en Dominios > tu.dominio.tld > Configuración DNS ; - o la linea de comando, `yunohost domain dns-conf tu.dominio.tld` @@ -57,7 +58,6 @@ _dmarc 3600 IN TXT "v=DMARC1; p=none" Pero puede ser un poco más fácil entenderla viéndola de esta manera : - | Tipo | Nombre | Valor | | :-----: | :--------------------: | :----------------------------------------------------: | | **A** | **@** | `111.222.333.444` (tu IPv4) | @@ -65,7 +65,7 @@ Pero puede ser un poco más fácil entenderla viéndola de esta manera : | AAAA | @ | `2222:444:8888:3333:bbbb:5555:3333:1111` (tu IPv6) | | AAAA | * | `2222:444:8888:3333:bbbb:5555:3333:1111` (tu IPv6) | | **SRV** | **_xmpp-client._tcp** | `0 5 5222 tu.dominio.tld.` | -| **SRV** | **_xmpp-server._tcp** | `0 5 5269 tu.dominio.tld.` | +| **SRV** | **_xmpp-server._tcp** | `0 5 5269 tu.dominio.tld.` | | CNAME | muc | `@` | | CNAME | pubsub | `@` | | CNAME | vjud | `@` | @@ -75,7 +75,7 @@ Pero puede ser un poco más fácil entenderla viéndola de esta manera : | TXT | mail._domainkey | `"v=DKIM1; k=rsa; p=uneGrannnndeClef"` | | TXT | _dmarc | `"v=DMARC1; p=none"` | -#### Algunas notas a propósito de esta tabla : +### Algunas notas a propósito de esta tabla - Todos los registros no son necesarios. Para una instalación mínima, solos los registros en negrita son necesarios. - El punto al final de `tu.dominio.tld.` es importante ;) ; @@ -83,7 +83,7 @@ Pero puede ser un poco más fácil entenderla viéndola de esta manera : - ¡ Los valores mostrados son ejemplos ! Refiérete a la configuración generada por tu servidor qué valores utilizar. - Recomendamos un [TTL](https://en.wikipedia.org/wiki/Time_to_live) de 3600 (1 hora). Pero puedes utilizar otro valor si sabes lo que estás haciendo ; - ¡ No pongas registros IPv6 si no estás seguro que el IPv6 funcione en tu servidor ! Tendrás problemas con Let's Encrypt si no es el caso :-) -- If you're using the domain provider Namecheap the SRV DNS entries are formatted as **Service**: _xmpp-client **Protocol**: _tcp **Priority**: 0 **Weight**: 5 **Port**: 5222 **Target**: your.domain.tld +- If you're using the domain provider Namecheap the SRV DNS entries are formatted as **Service**: `_xmpp-client` **Protocol**: `_tcp` **Priority**: `0` **Weight**: `5` **Port**: `5222` **Target**: `your.domain.tld` ### IP Dinámica diff --git a/pages/02.administer/10.install/20.dns_config/dns_config.fr.md b/pages/02.administer/10.install/20.dns_config/dns_config.fr.md index 1b501acc..ad959694 100644 --- a/pages/02.administer/10.install/20.dns_config/dns_config.fr.md +++ b/pages/02.administer/10.install/20.dns_config/dns_config.fr.md @@ -22,9 +22,11 @@ la configuration devrait être faite automatiquement. Si vous utilisez votre pro domaine via l'interface de votre registrar. ## Configuration DNS recommandée -_NB : les exemples utilisent ici le texte `votre.domaine.tld`, à remplacer par votre propre domaine (par exemple `www.yunohost.org`)._ + +*NB : les exemples utilisent ici le texte `votre.domaine.tld`, à remplacer par votre propre domaine (par exemple `www.yunohost.org`).* YunoHost fournit une configuration DNS recommandée, accessible via : + - la webadmin, dans Domaines > votre.domain.tld > Configuration DNS ; - ou la ligne de commande, `yunohost domain dns-conf votre.domaine.tld` @@ -84,7 +86,7 @@ suivante : | TXT | mail._domainkey | `"v=DKIM1; k=rsa; p=uneGrannnndeClef"` | | TXT | _dmarc | `"v=DMARC1; p=none"` | -#### Quelques notes à propos de cette table +### Quelques notes à propos de cette table - Tous ces enregistrements ne sont pas nécessaires. Pour une installation minimale, seuls les enregistrements en gras sont nécessaires ; - Le point à la fin de `votre.domaine.tld.` est important ;) ; @@ -92,7 +94,7 @@ suivante : - Les valeurs montrées ici sont des valeurs d'exemple ! Référez-vous à la configuration générée chez vous pour savoir quelles valeurs utiliser ; - Nous recommandons un [TTL](https://fr.wikipedia.org/wiki/Time_to_Live#Le_Time_to_Live_dans_le_DNS) de 3600 (1 heure). Mais vous pouvez utiliser une autre valeur si vous savez ce que vous faîtes ; - Ne mettez pas d'enregistrement IPv6 si vous n'êtes pas certain que l'IPv6 fonctionne sur votre serveur ! Vous aurez des problèmes avec Let's Encrypt si ce n'est pas le cas. -- Si vous utilisez le registrar Namecheap, les entrées SRV sont formattées comme **Service**: _xmpp-client **Protocol**: _tcp **Priority**: 0 **Weight**: 5 **Port**: 5222 **Target**: votre.domaine.tld +- Si vous utilisez le registrar Namecheap, les entrées SRV sont formattées comme **Service**: `_xmpp-client` **Protocol**: `_tcp` **Priority**: `0` **Weight**: `5` **Port**: `5222` **Target**: `votre.domaine.tld` ### Résolution DNS inverse @@ -108,8 +110,8 @@ Cela signifie que si votre adresse IPv4 publique est `111.222.333.444` et que votre nom de domaine est `domain.tld`, vous devez obtenir le résultat suivant en utilisant la commande `nslookup` : -```shell -$ nslookup 111.222.333.444 +```bash +nslookup 111.222.333.444 444.333.222.111.in-addr.arpa name = domain.tld. ``` diff --git a/pages/02.administer/10.install/20.dns_config/dns_config.md b/pages/02.administer/10.install/20.dns_config/dns_config.md index 061855d5..08e6f01d 100644 --- a/pages/02.administer/10.install/20.dns_config/dns_config.md +++ b/pages/02.administer/10.install/20.dns_config/dns_config.md @@ -24,6 +24,7 @@ interface. NB: Examples here use the placeholder `your.domain.tld`, you have to replace it with your real domain, such as `www.yunohost.org`. YunoHost provides a recommended DNS configuration, available via: + - the webadmin, in Domain > your.domain.tld > DNS configuration; - or the command line, `yunohost domain dns-conf your.domain.tld` @@ -65,7 +66,6 @@ _dmarc 3600 IN TXT "v=DMARC1; p=none" Though it might be easier to understand it if displayed like this: - | Type | Name | Value | | :-----: | :--------------------: | :--------------------------------------------------: | | **A** | **@** | `111.222.333.444` (your IPv4) | @@ -83,7 +83,7 @@ Though it might be easier to understand it if displayed like this: | TXT | mail._domainkey | `"v=DKIM1; k=rsa; p=someHuuuuuuugeKey"` | | TXT | _dmarc | `"v=DMARC1; p=none"` | -#### A few notes about this table +### A few notes about this table - Not all these lines are absolutely necessary. For a minimal setup, you only need the records in bold. - The dot at the end of `your.domain.tld.` is important ;); @@ -91,7 +91,7 @@ Though it might be easier to understand it if displayed like this: - These are example values ! See your generated conf for the actual values you should use; - We recommend a [TTL](https://en.wikipedia.org/wiki/Time_to_live#DNS_records) of 3600 (1 hour). But you can use something else if you know what you're doing; - Don't put an IPv6 record if you're not sure IPv6 really works on your server! You might have issues with Let's Encrypt if it doesn't. -- If you're using the domain provider Namecheap the SRV DNS entries are formatted as **Service**: _xmpp-client **Protocol**: _tcp **Priority**: 0 **Weight**: 5 **Port**: 5222 **Target**: your.domain.tld +- If you're using the domain provider Namecheap the SRV DNS entries are formatted as **Service**: `_xmpp-client` **Protocol**: `_tcp` **Priority**: `0` **Weight**: `5` **Port**: `5222` **Target**: `your.domain.tld` ### Reverse DNS @@ -106,8 +106,8 @@ If your public IPv4 address is `111.222.333.444` and your DNS domain is `domain.tld`, you should get following answer when using `nslookup` command tool: -```shell -$ nslookup 111.222.333.444 +```bash +nslookup 111.222.333.444 444.333.222.111.in-addr.arpa name = domain.tld. ``` diff --git a/pages/02.administer/10.install/20.dns_config/dns_config.ru.md b/pages/02.administer/10.install/20.dns_config/dns_config.ru.md index 1e3238c6..50d786c2 100644 --- a/pages/02.administer/10.install/20.dns_config/dns_config.ru.md +++ b/pages/02.administer/10.install/20.dns_config/dns_config.ru.md @@ -24,6 +24,7 @@ DNS (система доменных имен) - это система, кото ПРИМЕЧАНИЕ: В примерах здесь используется заполнитель `your.domain.tld`, вы должны заменить его своим реальным доменом, например `www.yunohost.org`. YunoHost предоставляет рекомендуемую конфигурацию DNS, доступную через: + - веб-администратор, Домены > `your.domain.tld` > DNS; - или в командной строке: `yunohost domain dns-conf your.domain.tld` @@ -65,7 +66,6 @@ _dmarc 3600 IN TXT "v=DMARC1; p=none" Хотя, возможно, было бы легче понять это, если бы оно отображалось следующим образом: - | Тип | Название | Значение | | :-----: | :--------------------: | :--------------------------------------------------: | | **A** | **@** | `111.222.333.444` (ваш IPv4) | @@ -83,7 +83,7 @@ _dmarc 3600 IN TXT "v=DMARC1; p=none" | TXT | mail._domainkey | `"v=DKIM1; k=rsa; p=someHuuuuuuugeKey"` | | TXT | _dmarc | `"v=DMARC1; p=none"` | -#### Несколько замечаний по поводу этой таблицы +### Несколько замечаний по поводу этой таблицы - Не все эти строки абсолютно необходимы. Для минимальной настройки вам понадобятся только записи, выделенные жирным шрифтом. - Точка в конце `ваш.домен.tld.` важна ;); @@ -91,7 +91,7 @@ _dmarc 3600 IN TXT "v=DMARC1; p=none" - Это примерные значения! Смотрите сгенерированный вами conf для получения фактических значений, которые вы должны использовать; - Мы рекомендуем использовать [TTL](https://en.wikipedia.org/wiki/Time_to_live#DNS_records ) 3600 (1 час). Но вы можете использовать что-то еще, если знаете, что делаете; - Не размещайте запись IPv6, если вы не уверены, что IPv6 действительно работает на вашем сервере! У вас могут возникнуть проблемы с Let's Encrypt, если это не так. -- Если вы используете Namecheap поставщика домена, записи SRV DNS форматируются как **Сервис**: _xmpp-client **Протокол**: _tcp **Приоритет**: 0 **Вес**: 5 **Порт**: 5222 **Цель**: your.domain.tld +- Если вы используете Namecheap поставщика домена, записи SRV DNS форматируются как **Сервис**: `_xmpp-client` **Протокол**: `_tcp` **Приоритет**: `0` **Вес**: `5` **Порт**: `5222` **Цель**: `your.domain.tld` ### Обратный DNS @@ -106,8 +106,8 @@ _dmarc 3600 IN TXT "v=DMARC1; p=none" -домен - `domain.tld`, вы должны получить следующий ответ при использовании командной строки `nslookup`: -```shell -$ nslookup 111.222.333.444 +```bash +nslookup 111.222.333.444 444.333.222.111.in-addr.arpa name = domain.tld. ``` diff --git a/pages/02.administer/10.install/25.installing_debian/installing_debian.md b/pages/02.administer/10.install/25.installing_debian/installing_debian.md index 919359c7..42870842 100644 --- a/pages/02.administer/10.install/25.installing_debian/installing_debian.md +++ b/pages/02.administer/10.install/25.installing_debian/installing_debian.md @@ -7,36 +7,36 @@ routes: default: '/installing_debian' --- -If you can't install Yunohost successfully, there's always the option to install Debian and then install Yunohost on top. +If you can't install YunoHost successfully, there's always the option to install Debian and then install YunoHost on top. ## Which Debian version -At the time of writing, only Debian 11 is supported by Yunohost. Don't use Debian 12. +At the time of writing, only Debian 11 is supported by YunoHost. Don't use Debian 12. ## Before you start -The Debian installer isn't the easiest Linux installer, especially for beginners. It'll be easier to **format the hard drive** you plan to use for Debian+Yunohost **before you install Debian**, using your disk utility of choice. +The Debian installer isn't the easiest Linux installer, especially for beginners. It'll be easier to **format the hard drive** you plan to use for Debian+YunoHost **before you install Debian**, using your disk utility of choice. ## Installing Debian ### Booting the installer -This guide won't go into details on how to boot the Debian installer. You can use Debian's own documentation for that. The short version is you'll need to flash a USB stick with the Debian 11 image, like you would flash the Yunohost image. +This guide won't go into details on how to boot the Debian installer. You can use Debian's own documentation for that. The short version is you'll need to flash a USB stick with the Debian 11 image, like you would flash the YunoHost image. ### Installing In general, you can simply follow the instructions on screen and use the suggested defaults. -Debian installer will ask for a **hostname** and a **domain name**. You can use “yunohost” and “yunohost.local”. It’s not really important since the Yunohost Installer will overwrite those anyway. +Debian installer will ask for a **hostname** and a **domain name**. You can use `yunohost` and `yunohost.local`. It’s not really important since the YunoHost Installer will overwrite those anyway. Debian will ask for a **root password**. Make sure you pick a **really long and complex** one and save it to your password manager of choice (Bitwarden, Firefox, etc…) or write it somewhere safe. Remember that this is a server that will be available on the internet, making it vulnerable to possible attacks so you should be extra safe here! -The installer will also ask for a **user account** and another password. **Important:** name it something that won’t be used by your Yunohost server later. For example, you can name it `debian`. Be sure to also use a long complex password. +The installer will also ask for a **user account** and another password. **Important:** name it something that won’t be used by your YunoHost server later. For example, you can name it `debian`. Be sure to also use a long complex password. When the install asks about where to install and how to **create disk partitions**, select the option to use the whole disk, unless you know what you're doing. - Don’t separate the /home, /var or /tmp partitions. Use the option to “keep all files in one partition”. -- Don’t encrypt any partitions, [as recommended](https://yunohost.org/en/administer/install/hardware:regular#about-encryption)) +- Don’t encrypt any partitions, [as recommended](https://yunohost.org/en/administer/install/hardware:regular#about-encryption) The installer will ask about **mirrors**. Select a country and server close to your location, or use the default options. @@ -47,9 +47,9 @@ The installer will ask about which **desktop environment** you want. You should ## After installing Debian -1. Remove the installation media (unplug the USB stick) +1. Remove the installation media (unplug the USB stick) 2. Reboot 3. Login as `root` with the long complex password you created earlier. 4. Install curl by typing `apt install curl` -5. Proceed to install Yunohost on Debian using these instructions: https://yunohost.org/en/install/hardware:vps_debian +5. Proceed to install YunoHost on Debian using these instructions: - The installer will ask for permission to overwrite some configuration files. Select Yes. diff --git a/pages/02.administer/10.install/install.de.md b/pages/02.administer/10.install/install.de.md index f76e74ef..8e8859de 100644 --- a/pages/02.administer/10.install/install.de.md +++ b/pages/02.administer/10.install/install.de.md @@ -132,57 +132,56 @@ Wähle die Hardware, auf der du YunoHost installieren willst : [/div] - {% if hardware != '' %} {% if wsl %} !! Dieses Setup ist vorwiegend für lokales Testing durch fortgeschrittene Benutzer gedacht. Aufgrund Limitierungen auf WSL Seite (insbesondere veränderliche IP Adresse), selfhosting kann damit knifflig sein und wird hier nicht weiter beschrieben. {% endif %} - ## [fa=list-alt /] Pre-requisites {% if regular %} -* Eine x86-kompatible für YunoHost bestimmte (dedizierte) Hardware: Laptop, Nettop, Netbook, Desktop mit 512MB RAM und 16GB Speicherkapazität (Minimum) + +- Eine x86-kompatible für YunoHost bestimmte (dedizierte) Hardware: Laptop, Nettop, Netbook, Desktop mit 512MB RAM und 16GB Speicherkapazität (Minimum) {% elseif rpi34 %} -* Ein Raspberry Pi 3 oder 4 +- Ein Raspberry Pi 3 oder 4 {% elseif rpi012 %} -* Ein Raspberry Pi 0, 1 oder 2 mit mindestens 512MB RAM +- Ein Raspberry Pi 0, 1 oder 2 mit mindestens 512MB RAM {% elseif internetcube %} -* Ein Orange Pi PC+ oder ein Olinuxino Lime 1 oder 2 -* Ein VPN mit einer festen öffentlichen IP Adresse und einer `.cube` Datei +- Ein Orange Pi PC+ oder ein Olinuxino Lime 1 oder 2 +- Ein VPN mit einer festen öffentlichen IP Adresse und einer `.cube` Datei {% elseif arm_sup %} -* Ein Orange Pi PC+ oder ein Olinuxino Lime 1 oder 2 +- Ein Orange Pi PC+ oder ein Olinuxino Lime 1 oder 2 {% elseif arm_unsup %} -* Ein ARM Board mit mindestens 512MB RAM +- Ein ARM Board mit mindestens 512MB RAM {% elseif vps_debian %} -* Ein dedizierter oder Virtual Private Server mit Debian 11 (Bullseye) (mit **kernel >= 3.12**) vorinstalliert, 512MB RAM und 16GB Speicherkapazität (Minimum) +- Ein dedizierter oder Virtual Private Server mit Debian 11 (Bullseye) (mit **kernel >= 3.12**) vorinstalliert, 512MB RAM und 16GB Speicherkapazität (Minimum) {% elseif vps_ynh %} -* Ein dedizierter oder Virtual Private Server mit YunoHost vorinstalliert, 512MB RAM und 16GB Speicherkapazität (Minimum) +- Ein dedizierter oder Virtual Private Server mit YunoHost vorinstalliert, 512MB RAM und 16GB Speicherkapazität (Minimum) {% elseif virtualbox %} -* Ein x86 Computer mit [VirtualBox installiert](https://www.virtualbox.org/wiki/Downloads) und ausreichend Arbeitsspeicherkapazität (RAM), um eine kleine virtuelle Maschine mit 1024MB RAM und 8GB Speicherkapazität (Minimum) betreiben zu können +- Ein x86 Computer mit [VirtualBox installiert](https://www.virtualbox.org/wiki/Downloads) und ausreichend Arbeitsspeicherkapazität (RAM), um eine kleine virtuelle Maschine mit 1024MB RAM und 8GB Speicherkapazität (Minimum) betreiben zu können {% endif %} {% if arm %} -* Eine Spannungsversorung (entweder ein Netzteil oder ein MicroUSB Kabel) für dein Board; -* Eine microSD Karte: 16GB Speicherkapazität (Minimum), [class "A1"](https://en.wikipedia.org/wiki/SD_card#Class) nachdrücklich empfohlen (so wie [diese SanDisk A1 Karte](https://www.amazon.fr/SanDisk-microSDHC-Adaptateur-homologu%C3%A9e-Nouvelle/dp/B073JWXGNT/)); +- Eine Spannungsversorung (entweder ein Netzteil oder ein MicroUSB Kabel) für dein Board; +- Eine microSD Karte: 16GB Speicherkapazität (Minimum), [class "A1"](https://en.wikipedia.org/wiki/SD_card#Class) nachdrücklich empfohlen (so wie [diese SanDisk A1 Karte](https://www.amazon.fr/SanDisk-microSDHC-Adaptateur-homologu%C3%A9e-Nouvelle/dp/B073JWXGNT/)); {% endif %} {% if regular %} -* Ein USB Stick mit mindestens 1GB Speicherkapazität ODER einem Standard CD-Rohling +- Ein USB Stick mit mindestens 1GB Speicherkapazität ODER einem Standard CD-Rohling {% endif %} {% if wsl %} -* Windows 10 und neuer -* Administrator Rechte -* Windows Subsystem for Linux, aus dem Optional Features Menü von Windows installiert -* *Empfohlen:* Windows Command Prompt App, aus dem Microsoft Store installiert. Viel besser als der Standard Terminal, weil sie Shortcuts für WSL distros bietet. +- Windows 10 und neuer +- Administrator Rechte +- Windows Subsystem for Linux, aus dem Optional Features Menü von Windows installiert +- *Empfohlen:* Windows Command Prompt App, aus dem Microsoft Store installiert. Viel besser als der Standard Terminal, weil sie Shortcuts für WSL distros bietet. {% endif %} {% if at_home %} -* Ein [vernünftiger ISP](/isp), vorzugsweise mit einer guten und unbegrenzten Upstream Bandbreite +- Ein [vernünftiger ISP](/isp), vorzugsweise mit einer guten und unbegrenzten Upstream Bandbreite {% if not virtualbox %} -* Ein Ethernet Kabel (RJ-45), um deinen Server mit deinem Router zu verbinden. {% if rpi012 %} (Oder, für Rasperry Pi Zero : und USB OTG oder ein Wifi Dongle) {% endif %} +- Ein Ethernet Kabel (RJ-45), um deinen Server mit deinem Router zu verbinden. {% if rpi012 %} (Oder, für Rasperry Pi Zero : und USB OTG oder ein Wifi Dongle) {% endif %} {% endif %} -* Ein Computer, um diese Anleitung zu lesen, das Image zu flashen und auf deinen Server zuzugreifen. +- Ein Computer, um diese Anleitung zu lesen, das Image zu flashen und auf deinen Server zuzugreifen. {% else %} -* Ein Computer oder ein Smartphone, um diese Anleitung zu lesen und auf deinen Server zuzugreifen. +- Ein Computer oder ein Smartphone, um diese Anleitung zu lesen und auf deinen Server zuzugreifen. {% endif %} {% if virtualbox %} @@ -190,7 +189,9 @@ Wähle die Hardware, auf der du YunoHost installieren willst : {% endif %} {% if wsl %} + ## Vorstellung + WSL ist ein cooles Windows 10 Feature, das Linux pseudo-Distributionen durch die Kommandozeile verfügbar macht. Lass es uns pseudo nennen, weil auch obwohl sie nicht wirklich wie virtuelle Maschinen sind, sind sie auf Virtualisierungskapazitäten angewiesen, die deren Integration mit Windows fast nahtlos machen. So kann z.B. Docker für Windows jetzt auf WSL bauen, anstatt auf Hyper-V. @@ -216,7 +217,7 @@ rmdir .\debian -R Nun kannst du darauf zugreifen: Führe `wsl.exe -d YunoHost` aus. -Da es Debian 9 Stretch ist, lass uns ein Upgrade auf Debian 11 Bullseye machen: +Da es Debian 9 Stretch ist, lass uns ein Upgrade auf Debian 11 Bullseye machen: ```bash # In WSL @@ -225,11 +226,12 @@ sudo apt update sudo apt upgrade sudo apt dist-upgrade ``` + ## Verhindern, dass WSL an Konfigurationsdateien herumfeilt Bearbeite `/etc/wsl.conf` und füge den folgenden Code darin ein: -``` +```text [network] generateHosts = false generateResolvConf = false @@ -252,6 +254,7 @@ Unter WSL fehlt Debian `systemd`, eine Service-Konfigurations-Software. Diese ist ein Schlüsselelement für YunoHost, und für jede anständige Debian Distro (also ernsthaft Microsoft, was zum Henker). Lass es uns installieren: 1. Installation der dotNET Runtime: + ```bash # In WSL wget https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb @@ -263,6 +266,7 @@ sudo apt install -y dotnet-sdk-3.1 ``` 2. Installation von [Genie](https://github.com/arkane-systems/genie): + ```bash # In WSL # Das repository hinzufügen @@ -291,26 +295,29 @@ Rufe `genie -s` immer während des Startes deiner Distro auf. `wsl -d YunoHost -e genie -s` -## Backup und Wiederherstellung der Distro +## Backup und Wiederherstellung der Distro + ### Mache dein erstes Distro Backup + Wie zuvor gesagt, gibt es keine Rollback Möglichkeit. Lass uns deshal deine frische Distro exportieren. In PowerShell: -``` +```bash cd ~ wsl --export YunoHost .\WSL\YunoHost.tar.gz ``` ### Im Falle eines Crash, lösche und stelle die gesamte Distro wieder her -``` +```bash cd ~ wsl --unregister YunoHost wsl --import YunoHost .\WSL\YunoHost .\WSL\YunoHost.tar.gz --version 2 ``` + {% endif %} - {% if vps_ynh %} + ## YunoHost VPS Provider Hier sind ein paar VPS Provider, die YunoHost nativ unterstützen : @@ -329,8 +336,8 @@ Hier sind ein paar VPS Provider, die YunoHost nativ unterstützen : [/div] {% endif %} - {% if at_home %} + ## [fa=download /] Lade das {{image_type}} Image herunter {% if rpi012 %} @@ -396,7 +403,7 @@ $(document).ready(function () { .replace('%7Bimage%7D', infos.image) .replace('{image}', infos.image) .replace('{version}', infos.version); - + if (!infos.file.startsWith("http")) infos.file="https://build.yunohost.org/"+infos.file; html = html.replace(/%7Bfile%7D/g, infos.file).replace(/{file}/g, infos.file); @@ -413,17 +420,16 @@ $(document).ready(function () { }); - - - - - {% if not virtualbox %} {% if arm %} + ## ![microSD Karte mit Adapter](image://sdcard_with_adapter.png?resize=100,75&class=inline) Flash das {{image_type}} Image + {% else %} + ## ![USB Stick](image://usb_key.png?resize=100,100&class=inline) Flash das YunoHost Image + {% endif %} Jetzt wo du das Image von {{image_type}} heruntergeladen hast, solltest du es auf {% if arm %}einer microSD Karte{% else %}einem USB stick oder einer CD/DVD flashen.{% endif %} @@ -457,16 +463,17 @@ Führe dann Folgendes aus : # Ersetze /dev/mmcblk0 durch das richtige Device, wenn der Name deines Device anders ist... dd if=/path/to/yunohost.img of=/dev/mmcblk0 ``` + [/ui-tab] {% if regular %} [ui-tab title="Eine CD/DVD brennen"] Für ältere Geräte könntest du eine CD/DVD brennen wollen. Die zu verwendende Software hängt von deinem Betriebssystem ab. -* Auf Windows, benutze [ImgBurn](http://www.imgburn.com/), um die Image Datei auf die Disc zu schreiben. +- Auf Windows, benutze [ImgBurn](http://www.imgburn.com/), um die Image Datei auf die Disc zu schreiben. -* Auf macOS, benutze [Disk Utility](http://support.apple.com/kb/ph7025) +- Auf macOS, benutze [Disk Utility](http://support.apple.com/kb/ph7025) -* Auf GNU/Linux hat man eine große Auswahl, wie [Brasero](https://wiki.gnome.org/Apps/Brasero) oder [K3b](http://www.k3b.org/) +- Auf GNU/Linux hat man eine große Auswahl, wie [Brasero](https://wiki.gnome.org/Apps/Brasero) oder [K3b](http://www.k3b.org/) [/ui-tab] {% endif %} [/ui-tabs] @@ -485,34 +492,28 @@ Für ältere Geräte könntest du eine CD/DVD brennen wollen. Die zu verwendende Gehe zu **Settings** > **Network**: -* Wähle `Bridged adapter` -* Wähle den Namen deines Interface: +- Wähle `Bridged adapter` +- Wähle den Namen deines Interface: **wlan0**, wenn du kabellos verbunden bist, oder andernfalls **eth0**. ![](image://virtualbox_2.png?class=inline) {% endif %} - - - - - - - - {% if arm %} + ## [fa=plug /] Das Board einschalten -* Schließe das Ethernet Kabel an (ein Ende an deinem Router, das andere an deinem Board). - * Fortgeschrittene Nutzer, die das Board konfigurieren möchten, um sich stattdessen per WiFi zu verbinden, können bspw. [hier](https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md) nachlesen. -* Stecke die SD Karte in dein Board. -* (Optional) Du kannst Bildschirm+Tastatur direkt an deinem Board anschließen, wenn du Fehler am Boot Prozess beheben willst oder wenn du dich wohler fühlst zu "sehen was passiert" oder du direkten Zugriff auf das Board haben willst. -* Schalte das Board ein. -* Warte ein paar Minuten während sich das Board beim ersten Boot automatisch selbst konfiguriert. -* Stelle sicher, dass dein Computer (Desktop/Laptop) mit dem selben lokalen Netzwerk verbunden ist (z.B. mit der selben Internet Box) wie dein Server. +- Schließe das Ethernet Kabel an (ein Ende an deinem Router, das andere an deinem Board). + - Fortgeschrittene Nutzer, die das Board konfigurieren möchten, um sich stattdessen per WiFi zu verbinden, können bspw. [hier](https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md) nachlesen. +- Stecke die SD Karte in dein Board. +- (Optional) Du kannst Bildschirm+Tastatur direkt an deinem Board anschließen, wenn du Fehler am Boot Prozess beheben willst oder wenn du dich wohler fühlst zu "sehen was passiert" oder du direkten Zugriff auf das Board haben willst. +- Schalte das Board ein. +- Warte ein paar Minuten während sich das Board beim ersten Boot automatisch selbst konfiguriert. +- Stelle sicher, dass dein Computer (Desktop/Laptop) mit dem selben lokalen Netzwerk verbunden ist (z.B. mit der selben Internet Box) wie dein Server. {% elseif virtualbox %} + ## [fa=plug /] Die virtuelle Maschine hochfahren Starte die virtuelle Maschine nach der Auswahl des YunoHost Image. @@ -521,17 +522,18 @@ Starte die virtuelle Maschine nach der Auswahl des YunoHost Image. ! Wenn du an den Fehler "VT-x ist nicht erreichbar" gerätst, musst du wahrscheinlich Virtualisierung im BIOS deines Computers einschalten. - {% else %} + ## [fa=plug /] Die Maschine von deinem USB Stick booten -* Schließe das Ethernet Kabel an (ein Ende an deinem Router, das andere an deinem Board). -* Fahre deinen Server mit dem USB Stick oder einer eingesteckten CD-ROM hoch und wähle es durch Drücken einer der folgenden (Hardware spezifischen) Tasten als **bootable device** aus: +- Schließe das Ethernet Kabel an (ein Ende an deinem Router, das andere an deinem Board). +- Fahre deinen Server mit dem USB Stick oder einer eingesteckten CD-ROM hoch und wähle es durch Drücken einer der folgenden (Hardware spezifischen) Tasten als **bootable device** aus: ``, ``, ``, ``, `` oder ``. - * Anmerkung: Wenn auf dem Server zuvor eine aktuelle Windows Version (8+) installiert war, musst du Windows zuerst "actually reboot" sagen. Das kann irgendwo in "Advanced startup options" gemacht werden. + - Anmerkung: Wenn auf dem Server zuvor eine aktuelle Windows Version (8+) installiert war, musst du Windows zuerst "actually reboot" sagen. Das kann irgendwo in "Advanced startup options" gemacht werden. {% endif %} {% if regular or virtualbox %} + ## [fa=rocket /] Die grafische Installation starten Du solltest einen Bildschirm wie diesen sehen: @@ -554,9 +556,10 @@ Du solltest einen Bildschirm wie diesen sehen: Das YunoHost-Projekt hat die klassische Installation so weit wie möglich vereinfacht, damit sich möglichst viele Menschen nicht in zu technischen oder fallbezogenen Fragen verlieren. -Mit der Installation im Expertenmodus hast du mehr Möglichkeiten, insbesondere was die genaue Partitionierung deiner Speichermedien betrifft. Du kannst dich auch für den klassischen Modus entscheiden und [deine Festplatten anschließend hinzufügen](/external_storage). +Mit der Installation im Expertenmodus hast du mehr Möglichkeiten, insbesondere was die genaue Partitionierung deiner Speichermedien betrifft. Du kannst dich auch für den klassischen Modus entscheiden und [deine Festplatten anschließend hinzufügen](/external_storage). + +### Zusammenfassung der Schritte im Expertenmodus -### Zusammenfassung der Schritte im Expertenmodus: 1. Wähle `Expert graphical install` aus. 2. Wähle deine Sprache, deinen Standort, dein Tastaturlayout und möglicherweise deine Zeitzone aus. 3. Partitioniere deine Festplatten. Hier kanst du ein RAID einrichten oder den Server ganz oder teilweise verschlüsseln. @@ -577,38 +580,45 @@ Wenn du über eine oder mehrere Festplatten zum Speichern von Daten verfügst, k | `/home/yunohost.backup/archives` | YunoHost-Backups, die idealerweise an anderer Stelle als auf den Datenträgern platziert werden, auf denen die Daten verwaltet werden | | `/home/yunohost.app` | Umfangreiche Datenmengen aus YunoHost Apps (nextcloud, matrix...) | | `/home/yunohost.multimedia` | Große Datenmenge, die von mehreren Anwendungen gemeinsam genutzt wird | -| `/var/mail` | User mail +| `/var/mail` | User mail | Wenn du Flexibilität haben möchtest und die Größe von Partitionen nicht (verändern) möchtest, kannst du dich auch dafür entscheiden, auf `/mnt/hdd` zu mounten und dieser [Anleitung zum Mounten aller dieser Ordner mit `mount --bind`](/external_storage) zu folgen. ### Über Verschlüsselung + Beachte: Wenn du deine Festplatten ganz oder teilweise verschlüsselst, musst du bei jedem Neustart deines Servers die Passphrase eingeben. Das kann ein Problem darstellen, wenn du nicht vor Ort bist. Es gibt jedoch (ziemlich schwierig zu implementierende) Lösungen, die es dir ermöglichen, die Passphrase über SSH oder über eine Webseite einzugeben (suche nach "Dropbear Encrypted Disk"). ### Über RAID + Denk daran, dass: - * die Festplatten in deinen RAIDs von unterschiedlichen Marken, Abnutzungserscheinungen oder Chargen sein müssen (insbesondere, wenn es sich um SSDs handelt). - * ein RAID 1 (auch ohne Ersatz) aus Wahrscheinlichkeitssicht zuverlässiger als ein RAID 5 ist. - * und Hardware-Raids von der Raid-Karte abhängen. Wenn die Karte ausfällt, benötigst du einen Ersatz, um das Array zu lesen und neu aufzubauen. + +- die Festplatten in deinen RAIDs von unterschiedlichen Marken, Abnutzungserscheinungen oder Chargen sein müssen (insbesondere, wenn es sich um SSDs handelt). +- ein RAID 1 (auch ohne Ersatz) aus Wahrscheinlichkeitssicht zuverlässiger als ein RAID 5 ist. +- und Hardware-Raids von der Raid-Karte abhängen. Wenn die Karte ausfällt, benötigst du einen Ersatz, um das Array zu lesen und neu aufzubauen. [/ui-tab] [/ui-tabs] {% endif %} - {% if rpi012 %} + ## [fa=bug /] Mit dem Board verbinden und das Image per Hotfix reparieren + Raspberry Pi 1 und 0 werden aufgrund von [Kompilierungsproblemen für diese Architektur](https://github.com/YunoHost/issues/issues/1423) nicht vollständig unterstützt. Es ist jedoch möglich, das Image selbst zu reparieren, bevor du die Erstkonfiguration ausführst. -Um das zu erreichen, musst du dich auf deinem Raspberry Pi als Root-Benutzer [über SSH](/ssh) mit dem temporären Passwort „yunohost“ verbinden: -``` +Um das zu erreichen, musst du dich auf deinem Raspberry Pi als Root-Benutzer [über SSH](/ssh) mit dem temporären Passwort `yunohost` verbinden: + +```bash ssh root@yunohost.local ``` -(oder „yunohost-2.local“ usw., wenn sich mehrere YunoHost-Server in deinem Netzwerk befinden) + +(oder `yunohost-2.local` usw., wenn sich mehrere YunoHost-Server in deinem Netzwerk befinden) Führe dann die folgenden Befehle aus, um das Metronomproblem zu umgehen: -``` + +```bash mv /usr/bin/metronome{,.bkp} mv /usr/bin/metronomectl{,.bkp} ln -s /usr/bin/true /usr/bin/metronome @@ -616,18 +626,20 @@ ln -s /usr/bin/true /usr/bin/metronomectl ``` Und diesen hier, um das UpnPC-Problem zu umgehen: -``` + +```bash sed -i 's/import miniupnpc/#import miniupnpc/g' /usr/lib/moulinette/yunohost/firewall.py ``` -! Der letzte Befehl muss nach jedem Yunohost-Upgrade ausgeführt werden :/ +! Der letzte Befehl muss nach jedem YunoHost-Upgrade ausgeführt werden :/ {% elseif arm_unsup %} + ## [fa=terminal /] Verbindung zum Board Als nächstes musst du [die lokale IP-Adresse deines Servers finden](/finding_the_local_ip), um dich als Root-Benutzer [über SSH](/ssh) mit dem temporären Passwort `1234` zu verbinden. -``` +```bash ssh root@192.168.x.xxx ``` @@ -635,8 +647,8 @@ ssh root@192.168.x.xxx {% endif %} - {% if vps_debian or arm_unsup %} + ## [fa=rocket /] Das Installationsskript ausführen - Öffne eine Kommandozeile auf deinem Server (entweder direkt oder [über SSH](/ssh)) @@ -692,15 +704,15 @@ Du kannst die Post-Installation auch mit dem Befehl `yunohost tools postinstall` {% if not internetcube %} -##### [fa=globe /] Haupt-Domain +### [fa=globe /] Haupt-Domain Dies ist die Domäne, über die die Benutzer deines Servers auf das **Authentifizierungsportal** zugreifen. Du kannst später weitere Domains hinzufügen und bei Bedarf ändern, welche Domain die Haupt-Domain ist. {% if not wsl %} -* Wenn du neu im Self-Hosting bist und noch keinen Domain-Namen hast, empfehlen wir die Verwendung eines **.nohost.me** / **.noho.st** / **.ynh.fr** (z.B. `homersimpson.nohost.me`). Sofern die Domain noch nicht vergeben ist, wird sie automatisch konfiguriert und du benötigst keinen weiteren Konfigurationsschritt. Bitte beachte, dass der Nachteil darin besteht, dass du nicht die vollständige Kontrolle über die DNS-Konfiguration hast. +- Wenn du neu im Self-Hosting bist und noch keinen Domain-Namen hast, empfehlen wir die Verwendung eines **.nohost.me** / **.noho.st** / **.ynh.fr** (z.B. `homersimpson.nohost.me`). Sofern die Domain noch nicht vergeben ist, wird sie automatisch konfiguriert und du benötigst keinen weiteren Konfigurationsschritt. Bitte beachte, dass der Nachteil darin besteht, dass du nicht die vollständige Kontrolle über die DNS-Konfiguration hast. -* Wenn du bereits einen Domain-Namen besitzt, möchtest du ihn wahrscheinlich hier verwenden. Später musst du DNS-Einträge konfigurieren, so wie [hier](/dns_config) beschrieben. +- Wenn du bereits einen Domain-Namen besitzt, möchtest du ihn wahrscheinlich hier verwenden. Später musst du DNS-Einträge konfigurieren, so wie [hier](/dns_config) beschrieben. !!! Ja, du *musst* eine Domain-Namen konfigurieren. Wenn du keinen Domain-Namen hast und auch keine **.nohost.me** / **.noho.st** / **.ynh.fr** möchtest, kannst du eine Dummy-Domain einrichten wie `yolo.test` und passt deine **lokale** `/etc/hosts` Datei so an, dass diese Dummy-Domain [auf die entsprechende IP verweist, wie hier erklärt](/dns_local_network). @@ -711,25 +723,24 @@ Zum Beispiel `ynh.wsl`. Der schwierige Teil besteht darin, diese Domain bei dein Ändere deine `C:\Windows\System32\drivers\etc\hosts` Datei. Du solltest eine Zeile haben, die mit `::1` beginnt. Aktualisiere sie oder füge sie bei Bedarf hinzu, um Folgendes zu erhalten: -``` +```text ::1 ynh.wsl localhost ``` Wenn du Subdomains erstellen möchtest, denk daran, diese auch in der Datei `hosts` hinzuzufügen: -``` +```text ::1 ynh.wsl subdomain.ynh.wsl localhost ``` {% endif %} -##### [fa=key /] Der erste Benutzer +### [fa=key /] Der erste Benutzer [Seit YunoHost 11.1](https://forum.yunohost.org/t/yunohost-11-1-release-sortie-de-yunohost-11-1/23378) wird in dieser Phase der erste Benutzer erstellt. Du solltest einen Benutzernamen und ein einigermaßen komplexes Passwort wählen. (Wir können nicht genug betonen, dass das Passwort **robust** sein sollte!) Dieser Benutzer wird der Administratoren-Gruppe hinzugefügt und kann daher auf das Benutzerportal und die Webadministrationsoberfläche zugreifen und eine Verbindung [über **SSH**](/ssh) oder [**SFTP**](/filezilla) herstellen. Administratoren erhalten außerdem E-Mails an `root@yourdomain.tld` und `admin@yourdomain.tld`: Diese E-Mails können zum Versenden technischer Informationen oder Warnungen verwendet werden. Du kannst später weitere Benutzer hinzufügen, die du auch zur Administratoren-Gruppe hinzufügen kannst. Dieser Benutzer ersetzt den alten `admin` Benutzer, auf den sich einige alte Dokumentationsseiten möglicherweise noch beziehen. In diesem Fall: Ersetzen Sie einfach `admin` durch Ihren Benutzernamen. - ## [fa=stethoscope /] Die Erstdiagnose durchführen Sobald die Post-Installation abgeschlossen ist, solltest du dich tatsächlich mit den Credentials des ersten Benutzers, den du gerade erstellt hast, bei der Webadministrationsoberfläche anmelden können. @@ -747,7 +758,6 @@ Das Diagnosesystem soll eine einfache Möglichkeit bieten, zu überprüfen, ob a !!! Ist eine Warnung für dich nicht relevant (z.B. weil du nicht vor hast, eine bestimmte Funktion zu verwenden), ist es völlig in Ordnung, das Problem als 'ignoriert' zu markieren, indem du im Webadmin > Diagnose auf den "Ignorieren" Button (für diese bestimmte Funktion) klickst. - [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="(Empfohlen) Über die Weboberfläche"] Um eine Diagnose auszuführen, gehe im Web Admin auf den Abschnitt "Diagnose". Klicke auf "Erstdiagnose ausführen". Du solltest nun einen Bildschirm wie diesen erhalten: @@ -758,10 +768,12 @@ Um eine Diagnose auszuführen, gehe im Web Admin auf den Abschnitt "Diagnose". K [/ui-tab] [ui-tab title="In der Kommandozeile"] -``` + +```bash yunohost diagnosis run yunohost diagnosis show --issues --human-readable ``` + [/ui-tab] [/ui-tabs] @@ -782,9 +794,11 @@ Gehe zu Domains > Klicke auf deine Domain > SSL Zertifikat [/ui-tab] [ui-tab title="In der Kommandozeile"] -``` + +```bash yunohost domain cert install ``` + [/ui-tab] [/ui-tabs] diff --git a/pages/02.administer/10.install/install.fr.md b/pages/02.administer/10.install/install.fr.md index 80299e72..7e1aca11 100644 --- a/pages/02.administer/10.install/install.fr.md +++ b/pages/02.administer/10.install/install.fr.md @@ -126,56 +126,54 @@ Sélectionnez le matériel sur lequel vous souhaitez installer YunoHost : [/div] - {% if hardware != '' %} ## [fa=list-alt /] Pré-requis {% if regular %} -* Un matériel compatible x86 dédié à YunoHost : portable, netbook, ordinateur avec 512Mo de RAM et 16Go de capacité de stockage (au moins) ; + +- Un matériel compatible x86 dédié à YunoHost : portable, netbook, ordinateur avec 512Mo de RAM et 16Go de capacité de stockage (au moins) ; {% elseif rpi34 %} -* Un Raspberry Pi 3 ou 4 ; +- Un Raspberry Pi 3 ou 4 ; {% elseif rpi012 %} -* Un Raspberry Pi 0, 1 ou 2 avec au moins 512Mo de RAM ; +- Un Raspberry Pi 0, 1 ou 2 avec au moins 512Mo de RAM ; {% elseif internetcube %} -* Un Orange Pi PC+ ou une Olinuxino Lime 1 ou 2 ; -* Un VPN avec une IP publique dédiée et un fichier `.cube` ; +- Un Orange Pi PC+ ou une Olinuxino Lime 1 ou 2 ; +- Un VPN avec une IP publique dédiée et un fichier `.cube` ; {% elseif arm_sup %} -* Un Orange Pi PC+ ou une Olinuxino Lime 1 ou 2 ; +- Un Orange Pi PC+ ou une Olinuxino Lime 1 ou 2 ; {% elseif arm_unsup %} -* Une carte ARM avec au moins 512Mo de RAM ; +- Une carte ARM avec au moins 512Mo de RAM ; {% elseif vps_debian %} -* Un serveur dédié ou virtuel avec Debian 11 (Bullseye) pré-installé (avec un **kernel >= 3.12**), avec au moins 512Mo de RAM et 16Go de capacité de stockage ; +- Un serveur dédié ou virtuel avec Debian 11 (Bullseye) pré-installé (avec un **kernel >= 3.12**), avec au moins 512Mo de RAM et 16Go de capacité de stockage ; {% elseif vps_ynh %} -* Un serveur dédié ou virtuel avec YunoHost pré-installé, avec au moins 512Mo de RAM et 16Go de capacité de stockage ; +- Un serveur dédié ou virtuel avec YunoHost pré-installé, avec au moins 512Mo de RAM et 16Go de capacité de stockage ; {% elseif virtualbox %} -* Un ordinateur x86 avec [VirtualBox installé](https://www.virtualbox.org/wiki/Downloads) et assez de RAM disponible pour lancer une petite machine virtuelle avec au moins 1024Mo de RAM et 8Go de capacité de stockage ; +- Un ordinateur x86 avec [VirtualBox installé](https://www.virtualbox.org/wiki/Downloads) et assez de RAM disponible pour lancer une petite machine virtuelle avec au moins 1024Mo de RAM et 8Go de capacité de stockage ; {% endif %} {% if arm %} -* Une alimentation électrique (soit un adaptateur, soit un câble microUSB) pour alimenter la carte ; -* Une carte microSD : au moins 16Go de capacité, [classe « A1 »](https://fr.wikipedia.org/wiki/Carte_SD#Vitesse) hautement recommandée (comme par exemple [cette carte SanDisk A1](https://www.amazon.fr/SanDisk-microSDHC-Adaptateur-homologu%C3%A9e-Nouvelle/dp/B073JWXGNT/)) ; +- Une alimentation électrique (soit un adaptateur, soit un câble microUSB) pour alimenter la carte ; +- Une carte microSD : au moins 16Go de capacité, [classe « A1 »](https://fr.wikipedia.org/wiki/Carte_SD#Vitesse) hautement recommandée (comme par exemple [cette carte SanDisk A1](https://www.amazon.fr/SanDisk-microSDHC-Adaptateur-homologu%C3%A9e-Nouvelle/dp/B073JWXGNT/)) ; {% endif %} {% if regular %} -* Une clé USB avec au moins 1Go de capacité OU un CD vierge standard ; +- Une clé USB avec au moins 1Go de capacité OU un CD vierge standard ; {% endif %} {% if at_home %} -* Un [fournisseur d'accès à Internet correct](/isp), de préférence avec une bonne vitesse d’upload ; +- Un [fournisseur d'accès à Internet correct](/isp), de préférence avec une bonne vitesse d’upload ; {% if not virtualbox %} -* Un câble ethernet/RJ-45 pour brancher la carte à votre routeur/box internet {% if rpi012 %} (Ou pour Rasperry Pi Zero : Un câble OTG ou un adaptateur Wifi USB) {% endif %} ; +- Un câble ethernet/RJ-45 pour brancher la carte à votre routeur/box internet {% if rpi012 %} (Ou pour Rasperry Pi Zero : Un câble OTG ou un adaptateur Wifi USB) {% endif %} ; {% endif %} -* Un ordinateur pour lire ce guide, flasher l'image et accéder à votre serveur. +- Un ordinateur pour lire ce guide, flasher l'image et accéder à votre serveur. {% else %} -* Un ordinateur ou un smartphone pour lire ce guide et accéder à votre serveur. +- Un ordinateur ou un smartphone pour lire ce guide et accéder à votre serveur. {% endif %} {% if virtualbox %} ! N.B. : Installer YunoHost dans une VirtualBox est généralement destiné à tester la distribution ou pour développer. VirtualBox n'est pas pratique pour faire tourner un 'vrai' serveur sur le long terme car la machine surlaquelle il est installé ne sera sans doute pas allumé 24h/24, et parce que Virtualbox rajoute une couche de complexité supplémentaire pour ce qui est d'exposer la machine sur Internet. {% endif %} - - - {% if vps_ynh %} + ## Fournisseurs de VPS YunoHost Ci-dessous une liste de fournisseurs de VPS supportant nativement YunoHost : @@ -194,8 +192,8 @@ Ci-dessous une liste de fournisseurs de VPS supportant nativement YunoHost : [/div] {% endif %} - {% if at_home %} + ## [fa=download /] Télécharger l'image {{image_type}} {% if rpi012 %} @@ -261,7 +259,7 @@ $(document).ready(function () { .replace('%7Bimage%7D', infos.image) .replace('{image}', infos.image) .replace('{version}', infos.version); - + if (!infos.file.startsWith("http")) infos.file="https://build.yunohost.org/"+infos.file; html = html.replace(/%7Bfile%7D/g, infos.file).replace(/{file}/g, infos.file); @@ -278,17 +276,16 @@ $(document).ready(function () { }); - - - - - {% if not virtualbox %} {% if arm %} + ## ![microSD card with adapter](image://sdcard_with_adapter.png?resize=100,75&class=inline) Flasher l'image {{image_type}} + {% else %} + ## ![USB drive](image://usb_key.png?resize=100,100&class=inline) Flasher l'image YunoHost + {% endif %} Maintenant que vous avez téléchargé l’image de {{image_type}}, vous devez la mettre sur {% if arm %}une carte microSD{% else %}une clé USB ou un CD/DVD.{% endif %} @@ -328,23 +325,24 @@ dd if=/path/to/yunohost.img of=/dev/mmcblk0 [ui-tab title="Copier un CD/DVD"] Pour les anciens matériels, il vous faut peut-être utiliser un CD/DVD. Le logiciel à utiliser est différent suivant votre système d’exploitation. -* Sur Windows, utilisez [ImgBurn](http://www.imgburn.com/) pour écrire l’image sur le disque +- Sur Windows, utilisez [ImgBurn](http://www.imgburn.com/) pour écrire l’image sur le disque -* Sur macOS, utilisez [Disk Utility](http://support.apple.com/kb/ph7025) +- Sur macOS, utilisez [Disk Utility](http://support.apple.com/kb/ph7025) -* Sur GNU/Linux, vous avez plusieurs choix, tels que [Brasero](https://wiki.gnome.org/Apps/Brasero) ou [K3b](http://www.k3b.org/) +- Sur GNU/Linux, vous avez plusieurs choix, tels que [Brasero](https://wiki.gnome.org/Apps/Brasero) ou [K3b](http://www.k3b.org/) [/ui-tab] [ui-tab title="Utiliser Ventoy"] -Ventoy sera utile si vous n'arrivez pas à démarrer l'image de Yunohost en utilisant les autres méthodes +Ventoy sera utile si vous n'arrivez pas à démarrer l'image de YunoHost en utilisant les autres méthodes [Ventoy](https://www.ventoy.net/) est un outil pratique qui permet de mettre plusieurs images Linux sur une même clé USB et démarrer ces images sans devoir re-flasher la clé USB à chaque fois. C'est aussi pratique pour démarer une image qui refuse de démarrer: Ventoy réussi habituellement à tout démarrer! + 1. Installer [Ventoy](https://www.ventoy.net/) sur la clé USB. Référez-vous aux [instructions d'installation](https://www.ventoy.net/en/doc_start.html). - Cela va créer 2 partition sur la clé USB. -3. En utilisant votre application de fichiers préférée, copiez l'image Yunohost sur la grande partition "Ventoy (pas celle "VTOYEFI") +2. En utilisant votre application de fichiers préférée, copiez l'image YunoHost sur la grande partition "Ventoy (pas celle "VTOYEFI") - N'utilisez pas *Balena Etcher*, USBImager ou `dd` pour faire ça! -Insérez cette clé USB dans l'ordinateur et démarrez en utisant celle-ci. Ventoy va apparaitre et lister toutes les images qui sont sur la clé USB. Sélectionnez l'image de Yunohost. Sélectionnez ensuite "GRUB2" comme option de démarrage (ou utilisez n'importe laquelle qui fonctionnera sur votre ordinateur 😉) +Insérez cette clé USB dans l'ordinateur et démarrez en utisant celle-ci. Ventoy va apparaitre et lister toutes les images qui sont sur la clé USB. Sélectionnez l'image de YunoHost. Sélectionnez ensuite "GRUB2" comme option de démarrage (ou utilisez n'importe laquelle qui fonctionnera sur votre ordinateur 😉) [/ui-tab] {% endif %} [/ui-tabs] @@ -363,34 +361,28 @@ Insérez cette clé USB dans l'ordinateur et démarrez en utisant celle-ci. Vent Allez dans **Réglages** > **Réseau** : -* Sélectionnez `Accès par pont` -* Choisissez votre interface selon son nom : +- Sélectionnez `Accès par pont` +- Choisissez votre interface selon son nom : **wlan0** si vous êtes connecté sans-fil, **eth0** ou **eno1** sinon. ![](image://virtualbox_2.png?class=inline) {% endif %} - - - - - - - - {% if arm %} + ## [fa=plug /] Démarrer la carte -* Branchez le câble Ethernet (un côté sur votre box, l'autre côté à votre carte). - * Pour les utilisateurs et utilisatrices souhaitant configurer la carte pour la connecter via le WiFi à la place, voir [cet exemple](https://www.raspberrypi.com/documentation/computers/configuration.html#connect-to-a-wireless-network) ([ou là avant YunoHost12/bookworm](https://www.raspberryme.com/configurer-le-wifi-sur-un-pi-manuellement-a-laide-de-wpa_supplicant-conf/). -* Mettez la carte SD dans le serveur. -* (Facultatif) Il est possible de brancher un écran et un clavier sur votre serveur en cas de soucis, pour vérifier que le processus de démarrage (boot) se passe bien, ou encore pour avoir un accès direct en console. -* Branchez l'alimentation. -* Laissez quelques minutes à votre serveur pour s'autoconfigurer durant le premier démarrage. -* Assurez-vous que votre ordinateur (de bureau ou portable) est connecté au même réseau local (c'est-à-dire la même box Internet) que votre serveur. +- Branchez le câble Ethernet (un côté sur votre box, l'autre côté à votre carte). + - Pour les utilisateurs et utilisatrices souhaitant configurer la carte pour la connecter via le WiFi à la place, voir [cet exemple](https://www.raspberrypi.com/documentation/computers/configuration.html#connect-to-a-wireless-network) ([ou là avant YunoHost12/bookworm](https://www.raspberryme.com/configurer-le-wifi-sur-un-pi-manuellement-a-laide-de-wpa_supplicant-conf/). +- Mettez la carte SD dans le serveur. +- (Facultatif) Il est possible de brancher un écran et un clavier sur votre serveur en cas de soucis, pour vérifier que le processus de démarrage (boot) se passe bien, ou encore pour avoir un accès direct en console. +- Branchez l'alimentation. +- Laissez quelques minutes à votre serveur pour s'autoconfigurer durant le premier démarrage. +- Assurez-vous que votre ordinateur (de bureau ou portable) est connecté au même réseau local (c'est-à-dire la même box Internet) que votre serveur. {% elseif virtualbox %} + ## [fa=plug /] Lancer la machine virtuelle Démarrez votre machine virtuelle après avoir sélectionné l'image YunoHost. @@ -400,19 +392,20 @@ Démarrez votre machine virtuelle après avoir sélectionné l'image YunoHost. ! Si vous rencontrez l'erreur "VT-x is not available", il vous faut probablement activer (enable) la virtualisation dans les options du BIOS de votre ordinateur. {% else %} + ## [fa=plug /] Démarrer la machine sur la clé USB -* Branchez le câble Ethernet (un côté à votre box, de l'autre côté à votre carte). -* Démarrez votre serveur avec la clé USB ou le CD-ROM inséré, et sélectionnez-le comme **périphérique de démarrage (bootable device)** en pressant l’une des touches suivantes (dépendant de votre ordinateur) : +- Branchez le câble Ethernet (un côté à votre box, de l'autre côté à votre carte). +- Démarrez votre serveur avec la clé USB ou le CD-ROM inséré, et sélectionnez-le comme **périphérique de démarrage (bootable device)** en pressant l’une des touches suivantes (dépendant de votre ordinateur) : ``, ``, ``, ``, ``, `` ou . - * N.B. : si le serveur était précédemment installé avec une version récente de Windows (8+), vous devez d'abord demander à Windows de « redémarrer réellement ». Vous pouvez le faire dans une option du menu « Options de démarrage avancées ». - -!!! Si vous n'arrivez pas à démarrer l'image Yunohost, essayez d'utiliser Ventoy (sélectionnez "Ventoy" dans la section "Flasher l'image YunoHost" ci-dessus). + - N.B. : si le serveur était précédemment installé avec une version récente de Windows (8+), vous devez d'abord demander à Windows de « redémarrer réellement ». Vous pouvez le faire dans une option du menu « Options de démarrage avancées ». + +!!! Si vous n'arrivez pas à démarrer l'image YunoHost, essayez d'utiliser Ventoy (sélectionnez "Ventoy" dans la section "Flasher l'image YunoHost" ci-dessus). {% endif %} {% if regular or virtualbox %} -## [fa=rocket /] Lancer l’installation graphique +## [fa=rocket /] Lancer l’installation graphique Votre écran devrait ressembler à la capture ci-dessous : @@ -432,9 +425,10 @@ Votre écran devrait ressembler à la capture ci-dessous : Le projet YunoHost a simplifié au maximum l'installation classique afin d'éviter au plus grand nombre d'être perdu avec des questions trop techniques ou liées à des cas particuliers. -Avec l'installation en mode expert, vous avez plus de possibilités notamment concernant le partitionnement exact de vos supports de stockages. Vous pouvez aussi décider d'utiliser le mode classique et [ajouter vos disques après coup](/external_storage). +Avec l'installation en mode expert, vous avez plus de possibilités notamment concernant le partitionnement exact de vos supports de stockages. Vous pouvez aussi décider d'utiliser le mode classique et [ajouter vos disques après coup](/external_storage). + +### Résumé des étapes en mode expert -### Résumé des étapes en mode expert: 1. Sélectionnez `Expert graphical install` 2. Sélectionnez votre langue, votre localisation, votre agencement de clavier et éventuellement votre timezone. 3. Partitionner vos disques. C'est à cette étape que vous pouvez configurer un RAID ou chiffrer tout ou partie du serveur. @@ -460,35 +454,42 @@ Si vous avez un ou des disques durs pour stocker les données, vous pouvez chois Si vous souhaitez de la souplesse et ne pas avoir à (re-)dimensionner des partitions, vous pouvez aussi choisir de monter sur `/mnt/hdd` et de suivre ce [tutoriel pour monter l'ensemble de ces dossiers avec `mount --bind`](/external_storage). ### A propos du chiffrement + Prenez bien en compte que si vous chiffrez tout ou partie de vos disques, vous aurez à taper la phrase de passe à chaque redémarrage de votre serveur, ce qui peut poser problème si vous n'êtes pas sur place. Il existe toutefois des solutions (assez difficiles à mettre en oeuvre) qui permettent de tapper la phrase via SSH ou via une page web (cherchez "dropbear encrypted disk"). ### A propos du RAID + Ne perdez pas de vue que: - * les disques de vos RAID doivent être de marque, d'usure ou de lots distincts (surtout si ce sont des SSD) - * un RAID 1 (même sans disque de spare) est plus fiable qu'un RAID5 d'un point de vue probabilité - * les raid matériels sont dépendant de la carte raid, si celle-ci fait défaut il en faudra une de remplacement pour pouvoir lire et reconstruire la grappe + +- les disques de vos RAID doivent être de marque, d'usure ou de lots distincts (surtout si ce sont des SSD) +- un RAID 1 (même sans disque de spare) est plus fiable qu'un RAID5 d'un point de vue probabilité +- les raid matériels sont dépendant de la carte raid, si celle-ci fait défaut il en faudra une de remplacement pour pouvoir lire et reconstruire la grappe [/ui-tab] [/ui-tabs] -!!! Si l'installation de Yunohost échoue sur votre machine et que vous n'arrivez pas à résoudre le problème, sachez qu'il est aussi possible d'installer Debian et ensuite d'installer Yunohost dessus. Pour les instructions, au sommet de cette page, sélectionnez "Serveur distant" puis "VPS ou serveur dédié avec Debian". +!!! Si l'installation de YunoHost échoue sur votre machine et que vous n'arrivez pas à résoudre le problème, sachez qu'il est aussi possible d'installer Debian et ensuite d'installer YunoHost dessus. Pour les instructions, au sommet de cette page, sélectionnez "Serveur distant" puis "VPS ou serveur dédié avec Debian". {% endif %} - {% if rpi012 %} + ## [fa=bug /] Se connecter à la carte et corriger l'image + Les Raspberry Pi 1 et Zero ne sont pas totalement supportés à cause de [problèmes de compilation pour cette architecture](https://github.com/YunoHost/issues/issues/1423). Cependant, il est possible de corriger l'image par vous-même avant de lancer la configuration initiale. Pour y parvenir, vous devez vous connecter à votre Raspberry Pi en tant que root [via SSH](/ssh) avec le mot de passe temporaire `yunohost`: -``` + +```bash ssh root@yunohost.local ``` + (utilisez `yunohost-2.local`, etc. s'il y a plusieurs serveurs YunoHost sur le réseau) Ensuite, lancez les commandes suivantes pour contourner le dysfonctionnement de Metronome : -``` + +```bash mv /usr/bin/metronome{,.bkp} mv /usr/bin/metronomectl{,.bkp} ln -s /usr/bin/true /usr/bin/metronome @@ -496,18 +497,20 @@ ln -s /usr/bin/true /usr/bin/metronomectl ``` Et celle-ci pour contourner celui de upnpc : -``` + +```bash sed -i 's/import miniupnpc/#import miniupnpc/g' /usr/lib/moulinette/yunohost/firewall.py ``` ! Cette dernière commande nécessite d'être lancée après chaque mise à jour de YunoHost :/ {% elseif arm_unsup %} + ## [fa=terminal /] Se connecter à la carte Ensuite, il vous faut [trouver l'adresse IP locale de votre serveur](/finding_the_local_ip) pour vous connecter en tant que root [via SSH](/ssh) avec le mot de passe temporaire `1234`. -``` +```bash ssh root@192.168.x.xxx ``` @@ -515,8 +518,8 @@ ssh root@192.168.x.xxx {% endif %} - {% if vps_debian or arm_unsup %} + ## [fa=rocket /] Lancer le script d'installation - Ouvrez la ligne de commande sur votre serveur (soit directement, soit avec [SSH](/ssh)) @@ -526,6 +529,7 @@ ssh root@192.168.x.xxx ```bash curl https://install.yunohost.org | bash ``` + !!! Si `curl` n'est pas installé sur votre système, il vous faudra peut-être l'installer avec `apt install curl`. !!! Autrement, si la commande n'affiche rien du tout, vous pouvez tenter `apt install ca-certificates` @@ -533,7 +537,6 @@ curl https://install.yunohost.org | bash {% endif %} - ## [fa=cog /] Lancer la configuration initiale !!! Si vous êtes en train de restaurer une sauvegarde YunoHost, vous devez sauter cette étape et vous référer à la section [Restaurer durant la post-installation à la place de cette étape de configuration initiale](/backup#restoring-during-the-postinstall). @@ -572,20 +575,20 @@ Vous pouvez aussi lancer la post-installation avec la commande `yunohost tools p {% if not internetcube %} -##### [fa=globe /] Domaine principal +### [fa=globe /] Domaine principal C’est le nom de domaine qui permettra l’accès à votre serveur ainsi qu’au **portail d’authentification** des utilisateurs. Vous pourrez ensuite ajouter d'autres domaines, et changer celui qui sera le domaine principal si besoin. -* Si l'auto-hébergement est tout neuf pour vous et que vous n'avez pas encore de nom de domaine, nous recommandons d'utiliser un domaine en **.nohost.me** / **.noho.st** / **.ynh.fr** (exemple : `homersimpson.nohost.me`). S'il n'est pas déjà utilisé, le domaine sera automatiquement rattaché à votre serveur YunoHost, et vous n’aurez pas d’étape de configuration supplémentaire. Toutefois, notez que l'utilisation d'un de ces noms de domaines implique que vous n'aurez pas le contrôle complet sur votre configuration DNS. +- Si l'auto-hébergement est tout neuf pour vous et que vous n'avez pas encore de nom de domaine, nous recommandons d'utiliser un domaine en **.nohost.me** / **.noho.st** / **.ynh.fr** (exemple : `homersimpson.nohost.me`). S'il n'est pas déjà utilisé, le domaine sera automatiquement rattaché à votre serveur YunoHost, et vous n’aurez pas d’étape de configuration supplémentaire. Toutefois, notez que l'utilisation d'un de ces noms de domaines implique que vous n'aurez pas le contrôle complet sur votre configuration DNS. -* Si en revanche vous avez déjà votre propre nom de domaine, vous souhaitez probablement l'utiliser. Vous aurez donc besoin ensuite de configurer les enregistrements DNS comme expliqué [ici](/dns_config). +- Si en revanche vous avez déjà votre propre nom de domaine, vous souhaitez probablement l'utiliser. Vous aurez donc besoin ensuite de configurer les enregistrements DNS comme expliqué [ici](/dns_config). !!! Oui, vous *devez* configurer un nom de domaine. Si vous n'avez pas de nom de domaine et que vous n'en voulez pas en **.nohost.me**, **.noho.st** ou **.ynh.fr**, vous pouvez utilisez un « faux » domaine comme par exemple `yolo.test` et [modifier votre fichier `/etc/hosts` **sur votre ordinateur local** pour que ce domaine pointe vers l'IP de votre serveur, comme expliqué ici](/dns_local_network). -##### [fa=key /] Premier compte utilisateur +### [fa=key /] Premier compte utilisateur [Depuis YunoHost 11.1](https://forum.yunohost.org/t/yunohost-11-1-release-sortie-de-yunohost-11-1/23378), le premier compte utilisateur est créé à cette étape. Il vous faudra choisir un nom d'utilisateur et un mot de passe raisonablement complexe. (Nous ne pouvons que souligner l'importance du choix d'un mot de passe **robuste** !) Ce compte utilisateur sera ajouté au groupe Admins, et pourra se connecter au portail utilisateur, à la webadmin, et se connecter [via **SSH**](/ssh) ou [**SFTP**](/filezilla). Les admins recevront aussi les mails envoyés à `root@votredomaine.tld` et `admin@votredomaine.tld` : ces emails peuvent être utilisés pour envoyer des informations ou des alertes techniques. Vous pourrez plus tard ajouter d'autres comptes utilisateur supplémentaire, qu'il est aussi possible d'ajouter au groupe Admins. - + Ce compte remplace l'ancien compte `admin`, qui est peut être toujours mentionné dans certaines pages de documentation. Dans ce cas, remplacez simplement `admin` par votre identifiant. ## [fa=stethoscope /] Lancer le diagnostic @@ -612,10 +615,12 @@ Pour lancer le diagnostic, allez dans l'Administration Web dans la partie Diagno [/ui-tab] [ui-tab title="À partir de la ligne de commande"] -``` + +```bash yunohost diagnosis run yunohost diagnosis show --issues --human-readable ``` + [/ui-tab] [/ui-tabs] @@ -634,9 +639,11 @@ Pour plus d'instructions détaillées, ou pour en savoir plus à propos des cert [/ui-tab] [ui-tab title="À partir de la ligne de commande"] -``` + +```bash yunohost domain cert install ``` + [/ui-tab] [/ui-tabs] diff --git a/pages/02.administer/10.install/install.md b/pages/02.administer/10.install/install.md index d9890a3a..7691c5c6 100644 --- a/pages/02.administer/10.install/install.md +++ b/pages/02.administer/10.install/install.md @@ -132,57 +132,56 @@ Select the hardware on which you want install YunoHost : [/div] - {% if hardware != '' %} {% if wsl %} !! This setup is mainly meant for local testing by advanced users. Due to limitations on WSL's side (changing IP address, notably), selfhosting from it can be tricky and will not be described here. {% endif %} - ## [fa=list-alt /] Pre-requisites {% if regular %} -* A x86-compatible hardware dedicated to YunoHost: laptop, nettop, netbook, desktop with 512MB RAM and 16GB capacity (at least) + +- A x86-compatible hardware dedicated to YunoHost: laptop, nettop, netbook, desktop with 512MB RAM and 16GB capacity (at least) {% elseif rpi34 %} -* A Raspberry Pi 3 or 4 +- A Raspberry Pi 3 or 4 {% elseif rpi012 %} -* A Raspberry Pi 0, 1 or 2 with at least 512MB RAM +- A Raspberry Pi 0, 1 or 2 with at least 512MB RAM {% elseif internetcube %} -* An Orange Pi PC+ or an Olinuxino Lime 1 or 2 -* A VPN with a dedicated public IP and a `.cube` file +- An Orange Pi PC+ or an Olinuxino Lime 1 or 2 +- A VPN with a dedicated public IP and a `.cube` file {% elseif arm_sup %} -* An Orange Pi PC+ or an Olinuxino Lime 1 or 2 +- An Orange Pi PC+ or an Olinuxino Lime 1 or 2 {% elseif arm_unsup %} -* An ARM board with at least 512MB RAM +- An ARM board with at least 512MB RAM {% elseif vps_debian %} -* A dedicated or virtual private server with Debian 11 (Bullseye) (with **kernel >= 3.12**) preinstalled, 512MB RAM and 16GB capacity (at least) +- A dedicated or virtual private server with Debian 11 (Bullseye) (with **kernel >= 3.12**) preinstalled, 512MB RAM and 16GB capacity (at least) {% elseif vps_ynh %} -* A dedicated or virtual private server with yunohost preinstalled, 512MB RAM and 16GB capacity (at least) +- A dedicated or virtual private server with YunoHost preinstalled, 512MB RAM and 16GB capacity (at least) {% elseif virtualbox %} -* An x86 computer with [VirtualBox installed](https://www.virtualbox.org/wiki/Downloads) and enough RAM capacity to be able to run a small virtual machine with 1024MB RAM and 8GB capacity (at least) +- An x86 computer with [VirtualBox installed](https://www.virtualbox.org/wiki/Downloads) and enough RAM capacity to be able to run a small virtual machine with 1024MB RAM and 8GB capacity (at least) {% endif %} {% if arm %} -* A power supply (either an adapter or a MicroUSB cable) for your board; -* A microSD card: 16GB capacity (at least), [class "A1"](https://en.wikipedia.org/wiki/SD_card#Class) highly recommended (such as [this SanDisk A1 card](https://www.amazon.fr/SanDisk-microSDHC-Adaptateur-homologu%C3%A9e-Nouvelle/dp/B073JWXGNT/)); +- A power supply (either an adapter or a MicroUSB cable) for your board; +- A microSD card: 16GB capacity (at least), [class "A1"](https://en.wikipedia.org/wiki/SD_card#Class) highly recommended (such as [this SanDisk A1 card](https://www.amazon.fr/SanDisk-microSDHC-Adaptateur-homologu%C3%A9e-Nouvelle/dp/B073JWXGNT/)); {% endif %} {% if regular %} -* A USB stick with at least 1GB capacity OR a standard blank CD +- A USB stick with at least 1GB capacity OR a standard blank CD {% endif %} {% if wsl %} -* Windows 10 and above -* Administration rights -* Windows Subsystem for Linux, installed from the Optional Features menu of Windows -* *Recommended:* Windows Terminal (Preview) app, installed from the Microsoft Store. Much better than the standard Terminal, as it offers shortcuts to the WSL distros. +- Windows 10 and above +- Administration rights +- Windows Subsystem for Linux, installed from the Optional Features menu of Windows +- *Recommended:* Windows Terminal (Preview) app, installed from the Microsoft Store. Much better than the standard Terminal, as it offers shortcuts to the WSL distros. {% endif %} {% if at_home %} -* A [reasonable ISP](/isp), preferably with a good and unlimited upstream bandwidth +- A [reasonable ISP](/isp), preferably with a good and unlimited upstream bandwidth {% if not virtualbox %} -* An ethernet cable (RJ-45) to connect your server to your router. {% if rpi012 %} (Or, for Rasperry Pi Zero : and USB OTG or a wifi Dongle) {% endif %} +- An ethernet cable (RJ-45) to connect your server to your router. {% if rpi012 %} (Or, for Rasperry Pi Zero : and USB OTG or a wifi Dongle) {% endif %} {% endif %} -* A computer to read this guide, flash the image and access your server. +- A computer to read this guide, flash the image and access your server. {% else %} -* A computer or a smartphone to read this guide and access your server. +- A computer or a smartphone to read this guide and access your server. {% endif %} {% if virtualbox %} @@ -190,7 +189,9 @@ Select the hardware on which you want install YunoHost : {% endif %} {% if wsl %} + ## Introduction + WSL is a nice feature of Windows 10, making Linux pseudo-distributions available through command line. Let's say pseudo, because even though they are not really like virtual machines, they rely on virtualization capacities that make their integration with Windows almost seamless. Docker for Windows can now rely on WSL instead of Hyper-V, for example. @@ -216,7 +217,7 @@ rmdir .\debian -R You can now access it: run `wsl.exe -d YunoHost` -It is under Debian 9 Stretch, so let's upgrade it: +It is under Debian 9 Stretch, so let's upgrade it: ```bash # In WSL @@ -225,11 +226,12 @@ sudo apt update sudo apt upgrade sudo apt dist-upgrade ``` + ## Prevent WSL from tweaking configuration files Edit `/etc/wsl.conf` and put the following code in it: -``` +```text [network] generateHosts = false generateResolvConf = false @@ -252,6 +254,7 @@ Debian on WSL does not have `systemd`, a service configuration software. This is a key element for YunoHost, and for any decent Debian distro (seriously MS, what the heck). Let's install it: 1. Install dotNET runtime: + ```bash # In WSL wget https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb @@ -263,6 +266,7 @@ sudo apt install -y dotnet-sdk-3.1 ``` 2. Install [Genie](https://github.com/arkane-systems/genie): + ```bash # In WSL # Add their repository @@ -291,26 +295,29 @@ Always call `genie -s` while starting your distro. `wsl -d YunoHost -e genie -s` -## Backup and restore the distro +## Backup and restore the distro + ### Make your first distro backup + As said before, there is no rollback capability. So let's export your fresh distro. In PowerShell: -``` +```bash cd ~ wsl --export YunoHost .\WSL\YunoHost.tar.gz ``` ### In case of crash, delete and restore the whole distro -``` +```bash cd ~ wsl --unregister YunoHost wsl --import YunoHost .\WSL\YunoHost .\WSL\YunoHost.tar.gz --version 2 ``` + {% endif %} - {% if vps_ynh %} + ## YunoHost VPS providers Here are some VPS providers supporting YunoHost natively : @@ -329,8 +336,8 @@ Here are some VPS providers supporting YunoHost natively : [/div] {% endif %} - {% if at_home %} + ## [fa=download /] Download the {{image_type}} image {% if rpi012 %} @@ -396,7 +403,7 @@ $(document).ready(function () { .replace('%7Bimage%7D', infos.image) .replace('{image}', infos.image) .replace('{version}', infos.version); - + if (!infos.file.startsWith("http")) infos.file="https://build.yunohost.org/"+infos.file; html = html.replace(/%7Bfile%7D/g, infos.file).replace(/{file}/g, infos.file); @@ -413,17 +420,16 @@ $(document).ready(function () { }); - - - - - {% if not virtualbox %} {% if arm %} + ## ![microSD card with adapter](image://sdcard_with_adapter.png?resize=100,75&class=inline) Flash the {{image_type}} image + {% else %} + ## ![USB drive](image://usb_key.png?resize=100,100&class=inline) Flash the YunoHost image + {% endif %} Now that you downloaded the image of {{image_type}}, you should flash it on {% if arm %}a microSD card{% else %}a USB stick or a CD/DVD.{% endif %} @@ -457,27 +463,29 @@ Then run : # Replace /dev/mmcblk0 if the name of your device is different... dd if=/path/to/yunohost.img of=/dev/mmcblk0 ``` + [/ui-tab] {% if regular %} [ui-tab title="Burning a CD/DVD"] For older devices, you might want to burn a CD/DVD. The software to use depends on your operating system. -* On Windows, use [ImgBurn](http://www.imgburn.com/) to write the image file on the disc +- On Windows, use [ImgBurn](http://www.imgburn.com/) to write the image file on the disc -* On macOS, use [Disk Utility](http://support.apple.com/kb/ph7025) +- On macOS, use [Disk Utility](http://support.apple.com/kb/ph7025) -* On GNU/Linux, you have plenty of choices, like [Brasero](https://wiki.gnome.org/Apps/Brasero) or [K3b](http://www.k3b.org/) +- On GNU/Linux, you have plenty of choices, like [Brasero](https://wiki.gnome.org/Apps/Brasero) or [K3b](http://www.k3b.org/) [/ui-tab] [ui-tab title="Using Ventoy"] -Ventoy will be useful if you can't sucessfully boot the Yunohost image using the other methods. +Ventoy will be useful if you can't sucessfully boot the YunoHost image using the other methods. [Ventoy](https://www.ventoy.net/) is a nice tool that makes it really easy to put multiple linux images on a USB stick. When the computer refuses to boot from an image on a usb stick, Ventoy will usually be able to boot it anyway! + 1. Install [Ventoy](https://www.ventoy.net/) on the USB stick. Refer to the [install instructions](https://www.ventoy.net/en/doc_start.html). - This will create 2 partitions on the stick. -3. Using your favorite file explorer app, copy the Yunohost image file on the big `Ventoy` partition (not "VTOYEFI") +2. Using your favorite file explorer app, copy the YunoHost image file on the big `Ventoy` partition (not "VTOYEFI") - Don't use *Balena Etcher*, USBImager or `dd` for this! -Later, when you'll boot the computer using this usb stick, Ventoy will appear and will list the images on the USB stick. Select the Yunohost image, then select GRUB2 launch option (or use whichever works for your computer 😉) +Later, when you'll boot the computer using this usb stick, Ventoy will appear and will list the images on the USB stick. Select the YunoHost image, then select GRUB2 launch option (or use whichever works for your computer 😉) [/ui-tab] {% endif %} [/ui-tabs] @@ -496,34 +504,28 @@ Later, when you'll boot the computer using this usb stick, Ventoy will appear an Go to **Settings** > **Network**: -* Select `Bridged adapter` -* Select your interface's name: +- Select `Bridged adapter` +- Select your interface's name: **wlan0** if you are connected wirelessly, or **eth0** otherwise. ![](image://virtualbox_2.png?class=inline) {% endif %} - - - - - - - - {% if arm %} + ## [fa=plug /] Power up the board -* Plug the ethernet cable (one side on your main router, the other on your board). - * For advanced users willing to configure the board to connect to WiFi instead, see for example [here](https://www.raspberrypi.com/documentation/computers/configuration.html#connect-to-a-wireless-network) ([or here prior to YunoHost12/bookworm](https://www.raspberryme.com/configurer-le-wifi-sur-un-pi-manuellement-a-laide-de-wpa_supplicant-conf/). -* Plug the SD card in your board -* (Optional) You can connect a screen+keyboard directly on your board if you want to troubleshoot the boot process or if you're more comfortable to "see what happens" or want a direct access to the board. -* Power up the board -* Wait a couple minutes while the board autoconfigure itself during the first boot -* Make sure that your computer (desktop/laptop) is connected to the same local network (i.e. same internet box) as your server. +- Plug the ethernet cable (one side on your main router, the other on your board). + - For advanced users willing to configure the board to connect to WiFi instead, see for example [here](https://www.raspberrypi.com/documentation/computers/configuration.html#connect-to-a-wireless-network) ([or here prior to YunoHost12/bookworm](https://www.raspberryme.com/configurer-le-wifi-sur-un-pi-manuellement-a-laide-de-wpa_supplicant-conf/). +- Plug the SD card in your board +- (Optional) You can connect a screen+keyboard directly on your board if you want to troubleshoot the boot process or if you're more comfortable to "see what happens" or want a direct access to the board. +- Power up the board +- Wait a couple minutes while the board autoconfigure itself during the first boot +- Make sure that your computer (desktop/laptop) is connected to the same local network (i.e. same internet box) as your server. {% elseif virtualbox %} + ## [fa=plug /] Boot up the virtual machine Start the virtual machine after selecting the YunoHost image. @@ -532,19 +534,20 @@ Start the virtual machine after selecting the YunoHost image. ! If you encounter the error "VT-x is not available", you probably need to enable Virtualization in the BIOS of your computer. - {% else %} + ## [fa=plug /] Boot the machine on your USB stick -* Plug the ethernet cable (one side on your main router, the other on your server). -* Boot up your server with the USB stick or a CD-ROM inserted, and select it as **bootable device**. Depending on your hardware, you will need to press one of the following keys: +- Plug the ethernet cable (one side on your main router, the other on your server). +- Boot up your server with the USB stick or a CD-ROM inserted, and select it as **bootable device**. Depending on your hardware, you will need to press one of the following keys: ``, ``, ``, ``, ``, `` or ``. - * N.B. : if the server was previously installed with a recent version of Windows (8+), you first need to tell Windows, to "actually reboot". This can be done somewhere in "Advanced startup options". + - N.B. : if the server was previously installed with a recent version of Windows (8+), you first need to tell Windows, to "actually reboot". This can be done somewhere in "Advanced startup options". -!!! If you can't boot the Yunohost image, try using Ventoy (select "Ventoy" in the section "Flash the YunoHost image" above). +!!! If you can't boot the YunoHost image, try using Ventoy (select "Ventoy" in the section "Flash the YunoHost image" above). {% endif %} {% if regular or virtualbox %} + ## [fa=rocket /] Launch the graphical install You should see a screen like this: @@ -567,9 +570,10 @@ You should see a screen like this: The YunoHost project simplified the classic installation as much as possible in order to avoid as many people as possible being lost with questions that are too technical or related to specific cases. -With the expert mode installation, you have more possibilities, especially concerning the exact partitioning of your storage media. You can also decide to use the classic mode and [add your disks afterwards](/external_storage). +With the expert mode installation, you have more possibilities, especially concerning the exact partitioning of your storage media. You can also decide to use the classic mode and [add your disks afterwards](/external_storage). + +### Summary of the steps in expert mode -### Summary of the steps in expert mode: 1. Select `Expert graphical install`. 2. Select your language, location, keyboard layout and possibly your timezone. 3. Partition your disks. This is where you can set up a RAID or encrypt all or part of the server. @@ -590,40 +594,47 @@ If you have one or more hard drives to store data, you can choose to mount it on | `/home/yunohost.backup/archives` | YunoHost backups to be placed ideally elsewhere than on the disks that manage the data | | `/home/yunohost.app` | Heavy data from YunoHost applications (nextcloud, matrix...) | | `/home/yunohost.multimedia` | Heavy data shared between several applications | -| `/var/mail` | User mail +| `/var/mail` | User mail | If you want flexibility and don't want to (re)size partitions, you can also choose to mount on `/mnt/hdd` and follow this [tutorial to mount all these folders with `mount --bind`](/external_storage). ### About encryption + Be aware that if you encrypt all or part of your disks, you will have to type the passphrase every time you restart your server, which can be a problem if you are not on site. There are however solutions (quite difficult to implement) that allow you to type the passphrase via SSH or via a web page (search for "dropbear encrypted disk"). ### About RAID + Keep in mind that: - * the disks in your RAIDs must be of different brands, wear and tear or batches (especially if they are SSDs) - * a RAID 1 (even without a spare) is more reliable than a RAID 5 from a probability point of view - * hardware raids are dependent on the raid card, if the card fails you will need a replacement to read and rebuild the array + +- the disks in your RAIDs must be of different brands, wear and tear or batches (especially if they are SSDs) +- a RAID 1 (even without a spare) is more reliable than a RAID 5 from a probability point of view +- hardware raids are dependent on the raid card, if the card fails you will need a replacement to read and rebuild the array [/ui-tab] [/ui-tabs] -!!! If the Yunohost installer fails and you can't solve the issue, know that it's also possible to install Debian and then install Yunohost on top. For instructions, at the top of this page, select "Remote server", then "VPS or dedicated server with Debian". +!!! If the YunoHost installer fails and you can't solve the issue, know that it's also possible to install Debian and then install YunoHost on top. For instructions, at the top of this page, select "Remote server", then "VPS or dedicated server with Debian". {% endif %} - {% if rpi012 %} + ## [fa=bug /] Connect to the board and hotfix the image + Raspberry Pi 1 and 0 are not totally supported due to [compilation issues for this architecture](https://github.com/YunoHost/issues/issues/1423). However, it is possible to fix by yourself the image before to run the initial configuration. To achieve this, you need to connect on your raspberry pi as root user [via SSH](/ssh) with the temporary password `yunohost`: -``` + +```bash ssh root@yunohost.local ``` + (or `yunohost-2.local`, and so on if multiple YunoHost servers are on your network) Then run the following commands to work around the metronome issue: -``` + +```bash mv /usr/bin/metronome{,.bkp} mv /usr/bin/metronomectl{,.bkp} ln -s /usr/bin/true /usr/bin/metronome @@ -631,18 +642,20 @@ ln -s /usr/bin/true /usr/bin/metronomectl ``` And this one to work around the upnpc issue: -``` + +```bash sed -i 's/import miniupnpc/#import miniupnpc/g' /usr/lib/moulinette/yunohost/firewall.py ``` -! This last command need to be run after each yunohost upgrade :/ +! This last command need to be run after each YunoHost upgrade :/ {% elseif arm_unsup %} + ## [fa=terminal /] Connect to the board Next you need to [find the local IP address of your server](/finding_the_local_ip) to connect as root user [via SSH](/ssh) with the temporary password `1234`. -``` +```bash ssh root@192.168.x.xxx ``` @@ -650,8 +663,8 @@ ssh root@192.168.x.xxx {% endif %} - {% if vps_debian or arm_unsup %} + ## [fa=rocket /] Run the install script - Open a command line prompt on your server (either directly or [through SSH](/ssh)) @@ -707,15 +720,15 @@ You can also perform the postinstallation with the command `yunohost tools posti {% if not internetcube %} -##### [fa=globe /] Main domain +### [fa=globe /] Main domain This will be the domain used by your server's users to access the **authentication portal**. You can later add other domains, and change which one is the main domain if needed. {% if not wsl %} -* If you're new to self-hosting and do not already have a domain name, we recommend using a **.nohost.me** / **.noho.st** / **.ynh.fr** (e.g. `homersimpson.nohost.me`). Provided that it's not already taken, the domain will be configured automatically and you won't need any further configuration step. Please note that the downside is that you won't have full-control over the DNS configuration. +- If you're new to self-hosting and do not already have a domain name, we recommend using a **.nohost.me** / **.noho.st** / **.ynh.fr** (e.g. `homersimpson.nohost.me`). Provided that it's not already taken, the domain will be configured automatically and you won't need any further configuration step. Please note that the downside is that you won't have full-control over the DNS configuration. -* If you already own a domain name, you probably want to use it here. You will later need to configure DNS records as explained [here](/dns_config). +- If you already own a domain name, you probably want to use it here. You will later need to configure DNS records as explained [here](/dns_config). !!! Yes, you *have to* configure a domain name. If you don't have any domain name and don't want a **.nohost.me** / **.noho.st** / **.ynh.fr** either, you can set up a dummy domain such as `yolo.test` and tweak your **local** `/etc/hosts` file such that this dummy domain [points to the appropriate IP, as explained here](/dns_local_network). @@ -726,25 +739,24 @@ For example, `ynh.wsl`. The tricky part is advertising this domain to your host. Alter your `C:\Windows\System32\drivers\etc\hosts` file. You should have a line starting by `::1`, update it or add it if needed to get: -``` +```text ::1 ynh.wsl localhost ``` If you want to create subdomains, do not forget to add them in the `hosts` file too: -``` +```text ::1 ynh.wsl subdomain.ynh.wsl localhost ``` {% endif %} -##### [fa=key /] First user +### [fa=key /] First user [Since YunoHost 11.1](https://forum.yunohost.org/t/yunohost-11-1-release-sortie-de-yunohost-11-1/23378), the first user is now created at this stage. You should pick a username and a reasonably complex password. (We cannot stress enough that the password should be **robust**!) This user will be added to the Admins group, and will therefore be able to access the user portal, the web admin interface, and connect [via **SSH**](/ssh) or [**SFTP**](/filezilla). Admins will also receive emails sent to `root@yourdomain.tld` and `admin@yourdomain.tld` : these emails may be used to send technical informations or alerts. You can later add additional users, which you can also add to the Admins group. This user replaces the old `admin` user, which some old documentation page may still refer to. In which case : just replace `admin` with your username. - ## [fa=stethoscope /] Run the initial diagnosis Once the postinstall is done, you should be able to actually log in the web admin interface using the credentials of the first user you just created. @@ -772,10 +784,12 @@ To run a diagnosis, go on Web Admin in the Diagnosis section. Click Run initial [/ui-tab] [ui-tab title="From the command line"] -``` + +```bash yunohost diagnosis run yunohost diagnosis show --issues --human-readable ``` + [/ui-tab] [/ui-tabs] @@ -796,9 +810,11 @@ Go in Domains > Click on your domain > SSL Certificate [/ui-tab] [ui-tab title="From the command line"] -``` + +```bash yunohost domain cert install ``` + [/ui-tab] [/ui-tabs] diff --git a/pages/02.administer/10.install/install.ru.md b/pages/02.administer/10.install/install.ru.md index 060545f1..68d2a972 100644 --- a/pages/02.administer/10.install/install.ru.md +++ b/pages/02.administer/10.install/install.ru.md @@ -132,57 +132,56 @@ routes: [/div] - {% if hardware != '' %} {% if wsl %} !! Эта настройка в основном предназначена для локального тестирования продвинутыми пользователями. Из-за ограничений на стороне WSL (в частности, изменение IP-адреса) самостоятельный хостинг с него может быть сложным и здесь описываться не будет. {% endif %} - ## [fa=list-alt /] Предварительные условия {% if regular %} -* x86-совместимое оборудование, предназначенное для YunoHost: ноутбук, неттоп, нетбук, настольный компьютер с 512 МБ оперативной памяти и емкостью 16 ГБ (не менее) + +- x86-совместимое оборудование, предназначенное для YunoHost: ноутбук, неттоп, нетбук, настольный компьютер с 512 МБ оперативной памяти и емкостью 16 ГБ (не менее) {% elseif rpi34 %} -* Raspberry Pi 3 or 4 +- Raspberry Pi 3 or 4 {% elseif rpi012 %} -* Raspberry Pi 0, 1 или 2 с ОЗУ не менее 512 МБ +- Raspberry Pi 0, 1 или 2 с ОЗУ не менее 512 МБ {% elseif internetcube %} -* Orange Pi PC+ или Olinuxino Lime 1 или 2 -* VPN с выделенным общедоступным IP-адресом и файлом `.cube` +- Orange Pi PC+ или Olinuxino Lime 1 или 2 +- VPN с выделенным общедоступным IP-адресом и файлом `.cube` {% elseif arm_sup %} -* Orange Pi PC+ или Olinuxino Lime 1 или 2 +- Orange Pi PC+ или Olinuxino Lime 1 или 2 {% elseif arm_unsup %} -* Плата ARM с объемом оперативной памяти не менее 512 МБ +- Плата ARM с объемом оперативной памяти не менее 512 МБ {% elseif vps_debian %} -* Выделенный или виртуальный частный сервер с Debian 11 (Bullseye) (с **kernel >= 3.12**) предустановленный, 512 МБ оперативной памяти и емкость 16 ГБ (не менее) +- Выделенный или виртуальный частный сервер с Debian 11 (Bullseye) (с **kernel >= 3.12**) предустановленный, 512 МБ оперативной памяти и емкость 16 ГБ (не менее) {% elseif vps_ynh %} -* Выделенный или виртуальный частный сервер с предустановленным YunoHost, 512 МБ оперативной памяти и емкостью не менее 16 ГБ +- Выделенный или виртуальный частный сервер с предустановленным YunoHost, 512 МБ оперативной памяти и емкостью не менее 16 ГБ {% elseif virtualbox %} -* Компьютер x86 с [установленным VirtualBox](https://www.virtualbox.org/wiki/Downloads) и достаточный объем оперативной памяти, чтобы иметь возможность запускать небольшую виртуальную машину с 1024 МБ оперативной памяти и емкостью 8 ГБ (как минимум). +- Компьютер x86 с [установленным VirtualBox](https://www.virtualbox.org/wiki/Downloads) и достаточный объем оперативной памяти, чтобы иметь возможность запускать небольшую виртуальную машину с 1024 МБ оперативной памяти и емкостью 8 ГБ (как минимум). {% endif %} {% if arm %} *Источник питания (либо адаптер, либо кабель microUSB) для вашей платы; -* Карта microSD: емкость 16 ГБ (не менее), [класса "A1"](https://club.dns-shop.ru/blog/t-127-kartyi-pamyati/59683-klassyi-skorosti-kart-pamyati-kak-razobratsya-i-chto-brat/#sub_Klass__skorosti__dlya__rabotyi__s__prilojeniyami) настоятельно рекомендуется (например, [эта SanDisk A1 карта](https://www.dns-shop.ru/product/dd976fc32e66ed20/karta-pamati-sandisk-ultra-microsdxc-64-gb-sdsqua4-064g-gn6mn/)); +- Карта microSD: емкость 16 ГБ (не менее), [класса "A1"](https://club.dns-shop.ru/blog/t-127-kartyi-pamyati/59683-klassyi-skorosti-kart-pamyati-kak-razobratsya-i-chto-brat/#sub_Klass__skorosti__dlya__rabotyi__s__prilojeniyami) настоятельно рекомендуется (например, [эта SanDisk A1 карта](https://www.dns-shop.ru/product/dd976fc32e66ed20/karta-pamati-sandisk-ultra-microsdxc-64-gb-sdsqua4-064g-gn6mn/)); {% endif %} {% if regular %} -* USB-накопитель емкостью не менее 1 ГБ или стандартный чистый компакт-диск +- USB-накопитель емкостью не менее 1 ГБ или стандартный чистый компакт-диск {% endif %} {% if wsl %} -* Windows 10 и выше -* Права администратора -* Подсистема Windows для Linux, устанавливаемая из *Включение или отключение компонентов Windows* -* *Рекомендуется:* Приложение Windows Terminal (предварительный просмотр), установленное из магазина Microsoft Store. Намного лучше, чем стандартный терминал, поскольку он предлагает быстрые пути к дистрибутивам WSL. +- Windows 10 и выше +- Права администратора +- Подсистема Windows для Linux, устанавливаемая из *Включение или отключение компонентов Windows* +- *Рекомендуется:* Приложение Windows Terminal (предварительный просмотр), установленное из магазина Microsoft Store. Намного лучше, чем стандартный терминал, поскольку он предлагает быстрые пути к дистрибутивам WSL. {% endif %} {% if at_home %} -* [хороший Интернет-провайдер](/isp), предпочтительно с хорошей и неограниченной восходящей полосой пропускания +- [хороший Интернет-провайдер](/isp), предпочтительно с хорошей и неограниченной восходящей полосой пропускания {% if not virtualbox %} -* Кабель Ethernet (RJ-45) для подключения вашего сервера к маршрутизатору. {% if rpi012 %} (Или, для Rasperry Pi Zero: и USB OTG или wifi-адаптер) {% endif %} +- Кабель Ethernet (RJ-45) для подключения вашего сервера к маршрутизатору. {% if rpi012 %} (Или, для Rasperry Pi Zero: и USB OTG или wifi-адаптер) {% endif %} {% endif %} -* Компьютер, чтобы прочитать это руководство, прошейте изображение и получите доступ к вашему серверу. +- Компьютер, чтобы прочитать это руководство, прошейте изображение и получите доступ к вашему серверу. {% else %} -* Компьютер или смартфон, чтобы прочитать это руководство и получить доступ к вашему серверу. +- Компьютер или смартфон, чтобы прочитать это руководство и получить доступ к вашему серверу. {% endif %} {% if virtualbox %} @@ -190,7 +189,9 @@ routes: {% endif %} {% if wsl %} + ## Вступление + WSL is a nice feature of Windows 10, making Linux pseudo-distributions available through command line. Let's say pseudo, because even though they are not really like virtual machines, they rely on virtualization capacities that make their integration with Windows almost seamless. Docker for Windows can now rely on WSL instead of Hyper-V, for example. @@ -216,7 +217,7 @@ rmdir .\debian -R You can now access it: run `wsl.exe -d YunoHost` -It is under Debian 9 Stretch, so let's upgrade it: +It is under Debian 9 Stretch, so let's upgrade it: ```bash # In WSL @@ -225,6 +226,7 @@ sudo apt update sudo apt upgrade sudo apt dist-upgrade ``` + ## Prevent WSL from tweaking configuration files Edit `/etc/wsl.conf` and put the following code in it: @@ -252,6 +254,7 @@ Debian on WSL does not have `systemd`, a service configuration software. This is a key element for YunoHost, and for any decent Debian distro (seriously MS, what the heck). Let's install it: 1. Install dotNET runtime: + ```bash # In WSL wget https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb @@ -263,6 +266,7 @@ sudo apt install -y dotnet-sdk-3.1 ``` 2. Install [Genie](https://github.com/arkane-systems/genie): + ```bash # In WSL # Add their repository @@ -291,26 +295,29 @@ Always call `genie -s` while starting your distro. `wsl -d YunoHost -e genie -s` -## Backup and restore the distro +## Backup and restore the distro + ### Make your first distro backup + As said before, there is no rollback capability. So let's export your fresh distro. In PowerShell: -``` +```bash cd ~ wsl --export YunoHost .\WSL\YunoHost.tar.gz ``` ### In case of crash, delete and restore the whole distro -``` +```bash cd ~ wsl --unregister YunoHost wsl --import YunoHost .\WSL\YunoHost .\WSL\YunoHost.tar.gz --version 2 ``` + {% endif %} - {% if vps_ynh %} + ## YunoHost VPS providers Here are some VPS providers supporting YunoHost natively : @@ -329,8 +336,8 @@ Here are some VPS providers supporting YunoHost natively : [/div] {% endif %} - {% if at_home %} + ## [fa=download /] Download the {{image_type}} image {% if rpi012 %} @@ -396,7 +403,7 @@ $(document).ready(function () { .replace('%7Bimage%7D', infos.image) .replace('{image}', infos.image) .replace('{version}', infos.version); - + if (!infos.file.startsWith("http")) infos.file="https://build.yunohost.org/"+infos.file; html = html.replace(/%7Bfile%7D/g, infos.file).replace(/{file}/g, infos.file); @@ -413,17 +420,16 @@ $(document).ready(function () { }); - - - - - {% if not virtualbox %} {% if arm %} + ## ![microSD card with adapter](image://sdcard_with_adapter.png?resize=100,75&class=inline) Flash the {{image_type}} image + {% else %} + ## ![USB drive](image://usb_key.png?resize=100,100&class=inline) Flash the YunoHost image + {% endif %} Now that you downloaded the image of {{image_type}}, you should flash it on {% if arm %}a microSD card{% else %}a USB stick or a CD/DVD.{% endif %} @@ -457,16 +463,17 @@ Then run : # Replace /dev/mmcblk0 if the name of your device is different... dd if=/path/to/yunohost.img of=/dev/mmcblk0 ``` + [/ui-tab] {% if regular %} [ui-tab title="Burning a CD/DVD"] For older devices, you might want to burn a CD/DVD. The software to use depends on your operating system. -* On Windows, use [ImgBurn](http://www.imgburn.com/) to write the image file on the disc +- On Windows, use [ImgBurn](http://www.imgburn.com/) to write the image file on the disc -* On macOS, use [Disk Utility](http://support.apple.com/kb/ph7025) +- On macOS, use [Disk Utility](http://support.apple.com/kb/ph7025) -* On GNU/Linux, you have plenty of choices, like [Brasero](https://wiki.gnome.org/Apps/Brasero) or [K3b](http://www.k3b.org/) +- On GNU/Linux, you have plenty of choices, like [Brasero](https://wiki.gnome.org/Apps/Brasero) or [K3b](http://www.k3b.org/) [/ui-tab] {% endif %} [/ui-tabs] @@ -485,34 +492,28 @@ For older devices, you might want to burn a CD/DVD. The software to use depends Go to **Settings** > **Network**: -* Select `Bridged adapter` -* Select your interface's name: +- Select `Bridged adapter` +- Select your interface's name: **wlan0** if you are connected wirelessly, or **eth0** otherwise. ![](image://virtualbox_2.png?class=inline) {% endif %} - - - - - - - - {% if arm %} + ## [fa=plug /] Power up the board -* Plug the ethernet cable (one side on your main router, the other on your board). - * For advanced users willing to configure the board to connect to WiFi instead, see for example [here](https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md). -* Plug the SD card in your board -* (Optional) You can connect a screen+keyboard directly on your board if you want to troubleshoot the boot process or if you're more comfortable to "see what happens" or want a direct access to the board. -* Power up the board -* Wait a couple minutes while the board autoconfigure itself during the first boot -* Make sure that your computer (desktop/laptop) is connected to the same local network (i.e. same internet box) as your server. +- Plug the ethernet cable (one side on your main router, the other on your board). + - For advanced users willing to configure the board to connect to WiFi instead, see for example [here](https://www.raspberrypi.org/documentation/configuration/wireless/wireless-cli.md). +- Plug the SD card in your board +- (Optional) You can connect a screen+keyboard directly on your board if you want to troubleshoot the boot process or if you're more comfortable to "see what happens" or want a direct access to the board. +- Power up the board +- Wait a couple minutes while the board autoconfigure itself during the first boot +- Make sure that your computer (desktop/laptop) is connected to the same local network (i.e. same internet box) as your server. {% elseif virtualbox %} + ## [fa=plug /] Boot up the virtual machine Start the virtual machine after selecting the YunoHost image. @@ -521,17 +522,18 @@ Start the virtual machine after selecting the YunoHost image. ! If you encounter the error "VT-x is not available", you probably need to enable Virtualization in the BIOS of your computer. - {% else %} + ## [fa=plug /] Boot the machine on your USB stick -* Plug the ethernet cable (one side on your main router, the other on your server). -* Boot up your server with the USB stick or a CD-ROM inserted, and select it as **bootable device** by pressing one of the following keys (hardware specific): +- Plug the ethernet cable (one side on your main router, the other on your server). +- Boot up your server with the USB stick or a CD-ROM inserted, and select it as **bootable device** by pressing one of the following keys (hardware specific): ``, ``, ``, ``, `` or ``. - * N.B. : if the server was previously installed with a recent version of Windows (8+), you first need to tell Windows, to "actually reboot". This can be done somewhere in "Advanced startup options". + - N.B. : if the server was previously installed with a recent version of Windows (8+), you first need to tell Windows, to "actually reboot". This can be done somewhere in "Advanced startup options". {% endif %} {% if regular or virtualbox %} + ## [fa=rocket /] Launch the graphical install You should see a screen like this: @@ -554,9 +556,10 @@ You should see a screen like this: The YunoHost project simplified the classic installation as much as possible in order to avoid as many people as possible being lost with questions that are too technical or related to specific cases. -With the expert mode installation, you have more possibilities, especially concerning the exact partitioning of your storage media. You can also decide to use the classic mode and [add your disks afterwards](/external_storage). +With the expert mode installation, you have more possibilities, especially concerning the exact partitioning of your storage media. You can also decide to use the classic mode and [add your disks afterwards](/external_storage). + +### Summary of the steps in expert mode -### Summary of the steps in expert mode: 1. Select `Expert graphical install`. 2. Select your language, location, keyboard layout and possibly your timezone. 3. Partition your disks. This is where you can set up a RAID or encrypt all or part of the server. @@ -577,38 +580,45 @@ If you have one or more hard drives to store data, you can choose to mount it on | `/home/yunohost.backup/archives` | YunoHost backups to be placed ideally elsewhere than on the disks that manage the data | | `/home/yunohost.app` | Heavy data from YunoHost applications (nextcloud, matrix...) | | `/home/yunohost.multimedia` | Heavy data shared between several applications | -| `/var/mail` | User mail +| `/var/mail` | User mail | If you want flexibility and don't want to (re)size partitions, you can also choose to mount on `/mnt/hdd` and follow this [tutorial to mount all these folders with `mount --bind`](/external_storage). ### About encryption + Be aware that if you encrypt all or part of your disks, you will have to type the passphrase every time you restart your server, which can be a problem if you are not on site. There are however solutions (quite difficult to implement) that allow you to type the passphrase via SSH or via a web page (search for "dropbear encrypted disk"). ### About RAID + Keep in mind that: - * the disks in your RAIDs must be of different brands, wear and tear or batches (especially if they are SSDs) - * a RAID 1 (even without a spare) is more reliable than a RAID 5 from a probability point of view - * hardware raids are dependent on the raid card, if the card fails you will need a replacement to read and rebuild the array + +- the disks in your RAIDs must be of different brands, wear and tear or batches (especially if they are SSDs) +- a RAID 1 (even without a spare) is more reliable than a RAID 5 from a probability point of view +- hardware raids are dependent on the raid card, if the card fails you will need a replacement to read and rebuild the array [/ui-tab] [/ui-tabs] {% endif %} - {% if rpi012 %} + ## [fa=bug /] Connect to the board and hotfix the image + Raspberry Pi 1 and 0 are not totally supported due to [compilation issues for this architecture](https://github.com/YunoHost/issues/issues/1423). However, it is possible to fix by yourself the image before to run the initial configuration. To achieve this, you need to connect on your raspberry pi as root user [via SSH](/ssh) with the temporary password `yunohost`: -``` + +```bash ssh root@yunohost.local ``` + (or `yunohost-2.local`, and so on if multiple YunoHost servers are on your network) Then run the following commands to work around the metronome issue: -``` + +```bash mv /usr/bin/metronome{,.bkp} mv /usr/bin/metronomectl{,.bkp} ln -s /usr/bin/true /usr/bin/metronome @@ -616,18 +626,20 @@ ln -s /usr/bin/true /usr/bin/metronomectl ``` And this one to work around the upnpc issue: -``` + +```bash sed -i 's/import miniupnpc/#import miniupnpc/g' /usr/lib/moulinette/yunohost/firewall.py ``` -! This last command need to be run after each yunohost upgrade :/ +! This last command need to be run after each YunoHost upgrade :/ {% elseif arm_unsup %} + ## [fa=terminal /] Connect to the board Next you need to [find the local IP address of your server](/finding_the_local_ip) to connect as root user [via SSH](/ssh) with the temporary password `1234`. -``` +```bash ssh root@192.168.x.xxx ``` @@ -635,8 +647,8 @@ ssh root@192.168.x.xxx {% endif %} - {% if vps_debian or arm_unsup %} + ## [fa=rocket /] Run the install script - Open a command line prompt on your server (either directly or [through SSH](/ssh)) @@ -692,15 +704,15 @@ You can also perform the postinstallation with the command `yunohost tools posti {% if not internetcube %} -##### [fa=globe /] Main domain +### [fa=globe /] Main domain This will be the domain used by your server's users to access the **authentication portal**. You can later add other domains, and change which one is the main domain if needed. {% if not wsl %} -* If you're new to self-hosting and do not already have a domain name, we recommend using a **.nohost.me** / **.noho.st** / **.ynh.fr** (e.g. `homersimpson.nohost.me`). Provided that it's not already taken, the domain will be configured automatically and you won't need any further configuration step. Please note that the downside is that you won't have full-control over the DNS configuration. +- If you're new to self-hosting and do not already have a domain name, we recommend using a **.nohost.me** / **.noho.st** / **.ynh.fr** (e.g. `homersimpson.nohost.me`). Provided that it's not already taken, the domain will be configured automatically and you won't need any further configuration step. Please note that the downside is that you won't have full-control over the DNS configuration. -* If you already own a domain name, you probably want to use it here. You will later need to configure DNS records as explained [here](/dns_config). +- If you already own a domain name, you probably want to use it here. You will later need to configure DNS records as explained [here](/dns_config). !!! Yes, you *have to* configure a domain name. If you don't have any domain name and don't want a **.nohost.me** / **.noho.st** / **.ynh.fr** either, you can set up a dummy domain such as `yolo.test` and tweak your **local** `/etc/hosts` file such that this dummy domain [points to the appropriate IP, as explained here](/dns_local_network). @@ -711,25 +723,24 @@ For example, `ynh.wsl`. The tricky part is advertising this domain to your host. Alter your `C:\Windows\System32\drivers\etc\hosts` file. You should have a line starting by `::1`, update it or add it if needed to get: -``` +```text ::1 ynh.wsl localhost ``` If you want to create subdomains, do not forget to add them in the `hosts` file too: -``` +```text ::1 ynh.wsl subdomain.ynh.wsl localhost ``` {% endif %} -##### [fa=key /] First user +### [fa=key /] First user [Since YunoHost 11.1](https://forum.yunohost.org/t/yunohost-11-1-release-sortie-de-yunohost-11-1/23378), the first user is now created at this stage. You should pick a username and a reasonably complex password. (We cannot stress enough that the password should be **robust**!) This user will be added to the Admins group, and will therefore be able to access the user portal, the web admin interface, and connect [via **SSH**](/ssh) or [**SFTP**](/filezilla). Admins will also receive emails sent to `root@yourdomain.tld` and `admin@yourdomain.tld` : these emails may be used to send technical informations or alerts. You can later add additional users, which you can also add to the Admins group. This user replaces the old `admin` user, which some old documentation page may still refer to. In which case : just replace `admin` with your username. - ## [fa=stethoscope /] Run the initial diagnosis Once the postinstall is done, you should be able to actually log in the web admin interface using the credentials of the first user you just created. @@ -757,10 +768,12 @@ To run a diagnosis, go on Web Admin in the Diagnosis section. Click Run initial [/ui-tab] [ui-tab title="From the command line"] -``` + +```bash yunohost diagnosis run yunohost diagnosis show --issues --human-readable ``` + [/ui-tab] [/ui-tabs] @@ -781,9 +794,11 @@ Go in Domains > Click on your domain > SSL Certificate [/ui-tab] [ui-tab title="From the command line"] -``` + +```bash yunohost domain cert install ``` + [/ui-tab] [/ui-tabs] diff --git a/pages/02.administer/15.admin_guide/05.guidelines/guidelines.de.md b/pages/02.administer/15.admin_guide/05.guidelines/guidelines.de.md index a8ec4025..ef05baeb 100644 --- a/pages/02.administer/15.admin_guide/05.guidelines/guidelines.de.md +++ b/pages/02.administer/15.admin_guide/05.guidelines/guidelines.de.md @@ -14,6 +14,7 @@ Diese Seite listet einige Tipps und Richtlinien auf, die jeder YunoHost-Administ Das heißt : Entweder ist der Server für den Betreib vorgesehen, oder ein Testserver, auf dem Sie sich erlauben, zu experimentieren. Ist Ihr Ziel, einen Produktionserver zu benutzen, so beachten Sie folgendes : + - ein Server ist ein empfindliches System : Seien Sie vorsichtig, methodisch und geduldig ; - experimentieren und Anpassen einschränken - insbesondere von Konfigurationsdateien ; - nicht Dutzende von Anwendungen installieren, bloß zum sehen, wie sie aussehen ; @@ -23,6 +24,7 @@ Ist Ihr Ziel, einen Produktionserver zu benutzen, so beachten Sie folgendes : ## Keep it simple ! YunoHost ist für allgemeine und einfache Anwendungsfälle konzipiert. Wenn Sie von diesen Bedingungen abweichen, wird es schwieriger, und Sie benötigen technisches Wissen, um sie zu erfüllen. Zum Beispiel: + - Versuchen Sie nicht, YunoHost in einem Kontext auszuführen, in dem Sie keine Kontrolle über die Ports 80 und 443 haben (oder überhaupt kein Internet); - Versuchen Sie nicht, fünf Server über dieselbe Internetverbindung zu hosten, wenn Sie nicht bereits ein fortgeschrittener Benutzer sind; - Reiben Sie sich nicht an dem Versuch auf, NGINX durch Apache zu ersetzen (oder beides gleichzeitig laufen zu lassen); @@ -45,7 +47,7 @@ Wenn Sie Dienste und Daten hosten, die für Ihre Benutzer wichtig sind, ist es w Als Administrator sollten Sie einen E-Mail-Client so einrichten, dass er E-Mails prüft, die an `root@your.domain.tld` (das muss ein Alias für den ersten von Ihnen hinzugefügten Benutzer sein) gesendet werden, oder sie an eine andere Adresse weiterleitet, die Sie aktiv prüfen. Diese E-Mails können Informationen darüber enthalten, was auf Ihrem Server passiert, wie z. B. periodische automatisierte Aufgaben. -## YunoHost ist freie Software, die von Freiwilligen instand gehalten wird. +## YunoHost ist freie Software, die von Freiwilligen instand gehalten wird Schließlich sollten Sie bedenken, dass YunoHost eine freie Software ist, die von Freiwilligen gepflegt wird - und dass das Ziel von YunoHost (die Demokratisierung des Selbst-Hostings) nicht einfach ist! Die Software wird ohne jegliche Garantie zur Verfügung gestellt. Das YunoHost Team tut sein Bestes, um das bestmögliche Erlebnis zu erhalten und zu bieten - dennoch sind die Funktionen, Anwendungen und YunoHost als Ganzes weit davon entfernt, perfekt zu sein, und Sie werden früher oder später auf kleine oder große Probleme stoßen. Wenn das passiert, kommen Sie bitte [in den Chat oder das Forum und bitten um Hilfe, oder melden das Problem](/help) :)! diff --git a/pages/02.administer/15.admin_guide/05.guidelines/guidelines.fr.md b/pages/02.administer/15.admin_guide/05.guidelines/guidelines.fr.md index f6e8c2b6..bfea2ab4 100644 --- a/pages/02.administer/15.admin_guide/05.guidelines/guidelines.fr.md +++ b/pages/02.administer/15.admin_guide/05.guidelines/guidelines.fr.md @@ -14,15 +14,17 @@ Cette page énumère quelques conseils et lignes directrices que tout administra En d'autres termes : votre serveur est soit un « serveur de production » (destiné à fonctionner), soit un serveur de test sur lequel vous vous permettez d'expérimenter. Si votre but est d'avoir un serveur de production : + - soyez conscient qu'un serveur est un système fragile : restez prudent, méthodique et patient ; - limitez les expérimentations et la personnalisation - notamment des fichiers de config ; - n'installez pas des douzaines d'applications juste pour voir de quoi elles ont l'air ; - utilisez les applications non-officielles avec prudence, et interdisez-vous d'utiliser celles marquées 'in progress', 'not working' ou qui sont en niveau 0 ; - si quelque chose casse, réfléchissez à deux fois avant de tenter de le réparer vous-même si vous ne savez pas ce que vous faites. (Par exemple, n'essayez pas de recréer vous-même l'utilisateur admin juste parce qu'il a mystérieusement disparu...) -## Keep it simple ! +## Restez simple ! + +YunoHost est conçu pour fonctionner avec des cas d'utilisation généraux et simples. S'écarter de ces conditions rendra les choses plus difficiles et vous aurez besoin de connaissances techniques pour les faire fonctionner. Par exemple : -YunoHost est conçu pour fonctionner avec des cas d'utilisation généraux et simples. S'écarter de ces conditions rendra les choses plus difficiles et vous aurez besoin de connaissances techniques pour les faire fonctionner. Par exemple, - n'essayez pas d'exécuter YunoHost dans un contexte où vous ne pouvez pas avoir le contrôle des ports 80 et 443 (ou pas d'Internet du tout) ; - n'essayez pas d'héberger cinq serveurs derrière la même connexion Internet si vous n'êtes pas déjà un utilisateur avancé ; - ne vous tourmentez pas à vouloir remplacer NGINX par Apache (ou faire tourner les deux à la fois) ; @@ -45,7 +47,7 @@ Si vous hébergez des services et des données qui sont importants pour vos util En tant qu'administrateur, vous devriez configurer un client de messagerie pour vérifier les e-mails envoyés à `root@votre.domaine.tld` (qui doit être un alias pour le premier utilisateur que vous avez ajouté) ou les transférer à une autre adresse que vous vérifiez activement. Ces courriels peuvent contenir des informations sur ce qui se passe sur votre serveur, comme les tâches périodiques automatisées. -## YunoHost est un logiciel gratuit, maintenu par des bénévoles. +## YunoHost est un logiciel gratuit, maintenu par des bénévoles Enfin, gardez à l'esprit que YunoHost est un logiciel libre maintenu par des volontaires - et que le but de YunoHost (démocratiser l'auto-hébergement) n'est pas simple ! Le logiciel est fourni sans aucune garantie. L'équipe de bénévoles fait de son mieux pour maintenir et fournir la meilleure expérience possible - pourtant les fonctionnalités, les applications et YunoHost dans son ensemble sont loin d'être parfaits et vous ferez face tôt ou tard à de petit ou gros problèmes. Lorsque cela se produit, venez gentiment [demander de l'aide sur le chat ou le forum, ou signaler le problème](/help) :) ! diff --git a/pages/02.administer/15.admin_guide/05.guidelines/guidelines.it.md b/pages/02.administer/15.admin_guide/05.guidelines/guidelines.it.md index bbce4194..e1ba2ab1 100644 --- a/pages/02.administer/15.admin_guide/05.guidelines/guidelines.it.md +++ b/pages/02.administer/15.admin_guide/05.guidelines/guidelines.it.md @@ -14,6 +14,7 @@ Questa pagina elenca qualche consiglio e delle linee guida che tutti gli amminis In altre parole: il tuo server può essere un "server in produzione" (destinato a funzionare), oppure un server di test che ti permette di sperimentare. Se il tuo obiettivo è avere un server in produzione: + - sii consapevole che i server sono sistemi fragili: sii prudente, metodico e paziente; - limita gli esperimenti e le personalizzazioni (per le istanze il file config) - non installare dozzine di installazioni solo per vedere come sono; @@ -22,7 +23,8 @@ Se il tuo obiettivo è avere un server in produzione: ## Keep it simple ! -YunoHost è progettato per funzionare in casi d'uso generici e semplici. Deviare da queste condizioni renderà le cose più difficili e avrai bisogno di conoscenze tecniche perché tutto funzioni. Per esempio, +YunoHost è progettato per funzionare in casi d'uso generici e semplici. Deviare da queste condizioni renderà le cose più difficili e avrai bisogno di conoscenze tecniche perché tutto funzioni. Per esempio: + - non provare ad eseguire YunoHost in un contesto dove non puoi controllare le porte 80 e 443 (o senza Internet del tutto); - non provare a hostare cinque server dietro la stessa connessione Internet se non sei un utente esperto; - non cadere nei capricci dei nerd che vogliono sostituire NGINX con Apache (o farli girare tutti e due insieme); @@ -45,7 +47,7 @@ Se ospiti dei servizi e dei dati che sono importanti per i tuoi utenti, è impor Come amministratore, dovrai configurare un client di posta per controllare le mail inviate a `root@your.domani.tld` (che dovrà essere un alias per il primo utente che aggiungerai) o trasferitele ad un altro indirizzo mail che controlli attivamente. Queste mail possono contenere informazioni riguardo quello che avviene sul tuo server, come i compiti periodici automatici. -## YunoHost è software libero, mantenuto da volontari. +## YunoHost è software libero, mantenuto da volontari Infine, tieni presente che YunoHost è software libero mantenuto da volontari - e che l'obiettivo di YunoHost (democratizzare il self-hosting) non è semplice! Il software è fornito senza nessuna garanzia. Il team di volontari fa del suo meglio per mantenere e fornire la migliore esperienza possibile - quindi le funzionalità, le applicazioni e YunoHost nel suo insieme sono lontani dall'essere perfetti e presto o tardi incontrerai piccoli o grossi problemi. Quando accadrà potrai [chiedere aiuto sulla chat o nel forum, o segnalare il problema](/help) :)! diff --git a/pages/02.administer/15.admin_guide/05.guidelines/guidelines.md b/pages/02.administer/15.admin_guide/05.guidelines/guidelines.md index d4b3151f..9085bb66 100644 --- a/pages/02.administer/15.admin_guide/05.guidelines/guidelines.md +++ b/pages/02.administer/15.admin_guide/05.guidelines/guidelines.md @@ -13,7 +13,8 @@ This page lists some advice and guidelines which every YunoHost administrator sh To put it another way: your server is either a production server (meant to work) or a test server on which you allow yourself to experiment. -If your goal is to run a production server: +If your goal is to run a production server: + - be aware that servers are fragile system. Stay cautious, methodical and patient; - limit experimentations and customizations (for instance of config file); - do not install dozens of apps just to see how they look; @@ -22,10 +23,11 @@ If your goal is to run a production server: ## Keep it simple! -YunoHost is designed to work with general and simple use cases in mind. Deviating from those conditions will make things harder and you will need technical knowledge to make it work. For instance, -- do not try to run YunoHost in a context where you cannot have control over ports 80 and 443 (or no internet at all); -- do not try to host five servers behind the same internet connection if you are not already an advanced user; -- do not fall into nerd whims such as willing to replace NGINX with Apache (or run both at the same time); +YunoHost is designed to work with general and simple use cases in mind. Deviating from those conditions will make things harder and you will need technical knowledge to make it work. For instance: + +- do not try to run YunoHost in a context where you cannot have control over ports 80 and 443 (or no internet at all); +- do not try to host five servers behind the same internet connection if you are not already an advanced user; +- do not fall into nerd whims such as willing to replace NGINX with Apache (or run both at the same time); - do not try to use custom SSL certificates if you don't really need them; - ... @@ -45,7 +47,7 @@ If you host services and data that are important for your users, it is important As an administrator, you should configure an email client to check emails sent to `root@your.domain.tld` (which should be an alias to the first user your added) or otherwise forward them to another address that you actively check. Those mails may contain information on what is happening on your server such as automated periodic tasks. -## YunoHost is free software, maintained by volunteers +## YunoHost is free software, maintained by volunteers Finally, keep in mind that YunoHost is a free software maintained by volunteers - and that the goal of YunoHost (to democratize self-hosting) is not an easy one! It is provided without any warranty. The team of volunteers does its best to maintain and provide the best possible experience - yet features, applications and YunoHost as a whole are far from being perfect and you will experience small and big shortcomings at some points. When this happens, kindly [reach for help on the chat or forum, or report the issue](/help)! :) diff --git a/pages/02.administer/15.admin_guide/10.admin/admin.de.md b/pages/02.administer/15.admin_guide/10.admin/admin.de.md index 84c36284..8167477e 100644 --- a/pages/02.administer/15.admin_guide/10.admin/admin.de.md +++ b/pages/02.administer/15.admin_guide/10.admin/admin.de.md @@ -11,6 +11,6 @@ YunoHost hat ein Administrator-Webinterface. Die andere Möglichkeit, Ihre YunoH ### Zugang -Sie können auf Ihr Administrator-Webinterface unter folgender Adresse zugreifen: https://example.org/yunohost/admin (ersetzen Sie 'example.org' durch Ihren eigenen Domainnamen) +Sie können auf Ihr Administrator-Webinterface unter folgender Adresse zugreifen: (ersetzen Sie `example.org` durch Ihren eigenen Domainnamen) ![](image://webadmin.png) diff --git a/pages/02.administer/15.admin_guide/10.admin/admin.es.md b/pages/02.administer/15.admin_guide/10.admin/admin.es.md index c95fa880..03594b19 100644 --- a/pages/02.administer/15.admin_guide/10.admin/admin.es.md +++ b/pages/02.administer/15.admin_guide/10.admin/admin.es.md @@ -11,6 +11,6 @@ YunoHost tiene una interfaz gráfica de administración. El otro método consist ### Acceso -La interfaz admin está accesible desde tu instancia YunoHost en esta dirección : https://ejemplo.org/yunohost/admin (reemplaza ejemplo.org por tu nombre de dominio) +La interfaz admin está accesible desde tu instancia YunoHost en esta dirección : (reemplaza `ejemplo.org` por tu nombre de dominio) ![](image://webadmin.png) diff --git a/pages/02.administer/15.admin_guide/10.admin/admin.fr.md b/pages/02.administer/15.admin_guide/10.admin/admin.fr.md index c8d0b285..6a7f462e 100644 --- a/pages/02.administer/15.admin_guide/10.admin/admin.fr.md +++ b/pages/02.administer/15.admin_guide/10.admin/admin.fr.md @@ -11,7 +11,6 @@ YunoHost est fourni avec une interface graphique d’administration (aussi appel ### Accès -L’interface d'administration web est accessible depuis votre instance YunoHost à l’adresse https://exemple.org/yunohost/admin (remplacez exemple.org par la bonne valeur) +L’interface d'administration web est accessible depuis votre instance YunoHost à l’adresse (remplacez `exemple.org` par la bonne valeur) ![](image://webadmin_fr.png) - diff --git a/pages/02.administer/15.admin_guide/10.admin/admin.it.md b/pages/02.administer/15.admin_guide/10.admin/admin.it.md index 03582144..173fa1e9 100644 --- a/pages/02.administer/15.admin_guide/10.admin/admin.it.md +++ b/pages/02.administer/15.admin_guide/10.admin/admin.it.md @@ -11,7 +11,6 @@ YunoHost ha un'interfaccia web di amministrazione. L'altro metodo è quello di u ### Accesso -L'interfaccia di amministrazione è accessibile all'indirizzo https://example.org/yunohost/admin (sostituisci 'example.org' con il tuo dominio) +L'interfaccia di amministrazione è accessibile all'indirizzo (sostituisci `example.org` con il tuo dominio) ![](image://webadmin.png) - diff --git a/pages/02.administer/15.admin_guide/10.admin/admin.md b/pages/02.administer/15.admin_guide/10.admin/admin.md index 4b2f6004..be5246d2 100644 --- a/pages/02.administer/15.admin_guide/10.admin/admin.md +++ b/pages/02.administer/15.admin_guide/10.admin/admin.md @@ -11,6 +11,6 @@ YunoHost has an administrator web interface. The other way to administrate your ### Access -You can access your administrator web interface at this address: https://example.org/yunohost/admin (replace 'example.org' with your own domain name) +You can access your administrator web interface at this address: (replace `example.org` with your own domain name) ![](image://webadmin.png) diff --git a/pages/02.administer/15.admin_guide/15.command_line/command_line.de.md b/pages/02.administer/15.admin_guide/15.command_line/command_line.de.md index 432597fc..bd5d81f3 100644 --- a/pages/02.administer/15.admin_guide/15.command_line/command_line.de.md +++ b/pages/02.administer/15.admin_guide/15.command_line/command_line.de.md @@ -17,17 +17,18 @@ page-toc: ## Während der YunoHost Installation -#### Finde deine IP +### Finde deine IP -Solltest du auf einem VPS installieren, dann hat der VPS Provider die IP-Adresse, die du bei ihm erfragen solltest. +Solltest du auf einem VPS installieren, dann hat der VPS Provider die IP-Adresse, die du bei ihm erfragen solltest. Wenn du Zuhause installierst (z.B. auf einem Raspberry Pi oder OLinuXino), dann musst du herausfinden, welche IP-Adresse dein Router dem System zugewiesen hat. Hierfür existieren mehrere Wege: + - Öffne ein Terminal und tippe `sudo arp-scan --local` ein, um eine Liste der aktiven IP-Adressen deines lokalen Netzwerks anzuzeigen; - wenn dir der arp-scan eine zu unübersichtliche Zahl an Adressen anzeigt, versuche mit `nmap -p 22 192.168.**x**.0/24` nur die anzuzeigen, deren SSH-Port 22 offen ist. (passe das **x** deinem Netzwerk an); - Prüfe die angezeigten Geräte in der Benutzeroberfläche deines Routers, ob du das Gerät findest; - Schließe einen Bildschirm und Tastatur an deinen Server, logge dich ein und tippe `hostname --all-ip-address`. -#### Verbinden +### Verbinden Angenommen deine IP Addresse ist `111.222.333.444`, öffne einen Terminal und gib Folgendes ein: @@ -39,11 +40,11 @@ Es wird nach einem Passwort gefragt. Handelt es sich um einen VPS, sollte der VP ! Seit YunoHost 3.4 kann man sich nach dem Ausführen der Postinstallation nicht mehr als `root` anmelden. **Stattdessen sollte man sich mit dem `admin` Benutzer anmelden!** Für den Fall, dass der LDAP-Server defekt und der `admin` Benutzer nicht verwendbar ist, kann man sich eventuell trotzdem noch mit `root` über das lokale Netzwerk anmelden. -#### Ändere das Passwort! +### Ändere das Passwort! Nach dem allerersten Login sollte man das root Passwort ändern. Der Server könnte dazu automatisch auffordern. Falls nicht, ist der Befehl `passwd` zu benutzen. Es ist wichtig, ein einigermaßen starkes Passwort zu wählen. Beachte, dass das root Passwort durch das admin Passwort überschrieben wird, wenn man die Postinstallation durchführt. -#### Auf ans Konfigurieren! +### Auf ans Konfigurieren! Wir sind nun bereit, mit der [Postinstallation](/postinstall) zu beginnen. @@ -103,23 +104,22 @@ N.B.: `fail2ban` sperrt deine IP für 10 Minuten, wenn du 5 fehlgeschlagene Logi Eine ausführlichere Diskussion über Sicherheit & SSH findest du auf der [dedicated page](/security). - ## YunoHost Kommandozeile !!! Ein vollständiges Tutorial über die Kommandozeile würde den Rahmen der YunoHost-Dokumentation sprengen: Lies dazu am besten ein spezielles Tutorial wie [dieses](https://ryanstutorials.net/linuxtutorial/) oder [dieses](http://linuxcommand.org/). Aber sei versichert, dass du kein CLI-Experte sein musst, um es zu benutzen! -Der Befehl "yunohost" kann zur Verwaltung deines Servers verwendet werden und führt verschiedene Aktionen aus, die denen des Webadmin ähneln. Der Befehl muss entweder vom `root`-Benutzer oder vom `admin`-Benutzer durch Voranstellen von `sudo` gestartet werden. (ProTip™ : Du kannst `root` mit dem Befehl `sudo su` als `admin` werden). +Der Befehl `yunohost` kann zur Verwaltung deines Servers verwendet werden und führt verschiedene Aktionen aus, die denen des Webadmin ähneln. Der Befehl muss entweder vom `root`-Benutzer oder vom `admin`-Benutzer durch Voranstellen von `sudo` gestartet werden. (ProTip™ : Du kannst `root` mit dem Befehl `sudo su` als `admin` werden). -YunoHost-Befehle haben normalerweise diese Art von Struktur: +YunoHost-Befehle haben normalerweise diese Art von Struktur: -```bash +```text yunohost app install wordpress --label Webmail ^ ^ ^ ^ | | | | category action argument options ``` -Zögere nicht, nach weiteren Informationen zu einer bestimmten Kategorie oder Aktion zu fragen, indem du die Option `--help` verwendest. Zum Beispiel listen diese Befehle : +Zögere nicht, nach weiteren Informationen zu einer bestimmten Kategorie oder Aktion zu fragen, indem du die Option `--help` verwendest. Zum Beispiel listen diese Befehle : ```bash yunohost --help diff --git a/pages/02.administer/15.admin_guide/15.command_line/command_line.es.md b/pages/02.administer/15.admin_guide/15.command_line/command_line.es.md index 5ed7c26f..abed9b90 100644 --- a/pages/02.administer/15.admin_guide/15.command_line/command_line.es.md +++ b/pages/02.administer/15.admin_guide/15.command_line/command_line.es.md @@ -19,9 +19,9 @@ La interfaz de línea de comandos (CLI) es, en informática, la manera original ## Durante la instalación de YunoHost -#### Encontrar su IP +### Encontrar su IP -Si instalas YunoHost en un VPS, tu proveedor debería haberte comunicado la dirección IP de tu servidor. +Si instalas YunoHost en un VPS, tu proveedor debería haberte comunicado la dirección IP de tu servidor. Si instalas un servidor en tu casa (por ejemplo en Raspberry Pi u OLinuXino), tienes que encontrar el IP que fue atribuido a tu tarjeta cuando la conectaste a tu router / caja Internet. Hay varias maneras de hacerlo : @@ -29,7 +29,7 @@ Si instalas un servidor en tu casa (por ejemplo en Raspberry Pi u OLinuXino), ti - utiliza la interfaz de tu router caja internet para listar las máquinas conectadas, o mira los los ; - conecta una pantalla en tu servidor, inicia una sesión y escribe `hostname --all-ip-address`. -#### Conectarse +### Conectarse Suponiendo que tu dirección IP sea `111.222.333.444`, abre una terminal y escribe : @@ -41,11 +41,10 @@ Ahora te piden una contraseña. Si es un VPS, tu proveedor ya te hará comunicad ! Desde YunoHost 3.4, después de la post-instalación ya no es posible conectarse con el usuario `root`. En lugar de eso, hace falta **conectarse con el usuario `admin`**. Incluso si el servidor LDAP fuera quebrado (haciendo que el usuario `admin` ya no fuera utilizable) todavía deberías poder conectarte con el usuario `root` desde la red local. -#### ¡ Cambiar la contraseña root ! +### ¡ Cambiar la contraseña root ! Después de haberte conectado por primera vez, tienes que cambiar la contraseña `root`. Tal vez el servidor te pida automáticamente que lo hagas. Si no es el caso, hay que utilizar el comando `passwd`. Es muy importante que elijas una contraseña bastante complicada. Nota que esta contraseña luego estará reemplazada por la contraseña admin elegida durante la post-instalación. - ## En una instancia que ya está instalada Si instalaste tu servidor en casa y que quieres conectarte desde fuera de la red local, asegúrate que hayas previamente redirigido el puerto 22 de tu router / caja hacia tu servidor (con el usuario `admin` !) @@ -77,16 +76,19 @@ ssh -p 2244 admin@tu.dominio.tld Por defecto, sólo el usuario `admin` puede conectarse en SSH en una instancia YunoHost. Los usuarios YunoHost creados vea la interfaz de administración están administrados por la base de datos LDAP. Por defecto, no pueden conectarse en SSH por razones de seguridad. Si necesitas absolutamente que uno de estos usuarios disponga de un acceso SSH, puedes utilizar el comando : + ```bash yunohost user permission add ssh.main ``` Del mismo modo, es posible cancelar el acceso SSH de un usuario con el comando : + ```bash yunohost user permission remove ssh.main ``` Finalmente, es posible añadir, suprimir y listar llaves SSH, para mejorar la seguridad del acceso SSH, con estos comandos : + ```bash yunohost user ssh add-key yunohost user ssh remove-key @@ -107,7 +109,7 @@ El comando `yunohost` puede ser utilizado para administrar tu servidor o realiza Los comandos YunoHost tienen este tipo de estructura : -```bash +```text yunohost app install wordpress --label Webmail ^ ^ ^ ^ | | | | diff --git a/pages/02.administer/15.admin_guide/15.command_line/command_line.fr.md b/pages/02.administer/15.admin_guide/15.command_line/command_line.fr.md index 19632c76..d5e521f8 100644 --- a/pages/02.administer/15.admin_guide/15.command_line/command_line.fr.md +++ b/pages/02.administer/15.admin_guide/15.command_line/command_line.fr.md @@ -18,6 +18,7 @@ page-toc: L'interface en ligne de commande (CLI) est, en informatique, la manière originale (et plus technique) d'interagir avec un ordinateur, comparée aux interfaces graphiques. La ligne de commande est généralement considérée comme plus complète, puissante et efficace que les interfaces graphiques, bien que plus difficile à apprendre. ## Comment se connecter ? + ### Identifiant à utiliser [ui-tabs position="top-left" active="0" theme="lite"] @@ -38,9 +39,10 @@ Durant la post-installation, vous avez défini un mot de passe d'administration. ### Adresse à utiliser Si vous hébergez votre serveur **à la maison** (par ex. Raspberry Pi ou OLinuXino ou vieil ordinateur) - - vous devriez pouvoir vous connecter à la machine en utilisant `yunohost.local` (ou `yunohost-2.local`, selon le nombre de serveurs sur le réseau). - - si `yunohost.local` et consorts ne fonctionnent pas, il vous faut [trouver l'IP locale de votre serveur](/finding_the_local_ip). - - si vous avez installé votre serveur à la maison mais essayez d'y accéder depuis l'extérieur du réseau local, assurez-vous d'avoir bien configuré une redirection de port pour le port 22. + +- vous devriez pouvoir vous connecter à la machine en utilisant `yunohost.local` (ou `yunohost-2.local`, selon le nombre de serveurs sur le réseau). +- si `yunohost.local` et consorts ne fonctionnent pas, il vous faut [trouver l'IP locale de votre serveur](/finding_the_local_ip). +- si vous avez installé votre serveur à la maison mais essayez d'y accéder depuis l'extérieur du réseau local, assurez-vous d'avoir bien configuré une redirection de port pour le port 22. S'il s'agit d'une machine distante (VPS), votre fournisseur devrait vous avoir communiqué l'IP de votre machine. @@ -87,6 +89,7 @@ Si vous souhaitez ajouter une clé publique SSH à l'utilisateur, vous devez le [/ui-tab] [ui-tab title="À partir de la ligne de commande"] Pour autoriser un utilisateur ou un groupe à accéder en SFTP ou en SSH : + ```bash # SFTP yunohost user permission add sftp @@ -95,6 +98,7 @@ yunohost user permission add ssh ``` Pour enlever la permission : + ```bash # SFTP yunohost user permission remove sftp @@ -103,11 +107,13 @@ yunohost user permission remove ssh ``` Enfin, il est possible d'ajouter, de supprimer et de lister des clés SSH, pour améliorer la sécurité de l'accès SSH, avec les commandes : + ```bash yunohost user ssh add-key yunohost user ssh remove-key yunohost user ssh list-keys ``` + [/ui-tab] [/ui-tabs] @@ -125,7 +131,7 @@ La commande `yunohost` peut être utilisée pour administrer votre serveur ou r Les commandes YunoHost ont ce type de structure : -```bash +```text yunohost app install wordpress --label Webmail ^ ^ ^ ^ | | | | @@ -143,25 +149,31 @@ yunohost user create --help vont successivement lister toutes les catégories disponibles, puis les actions de la catégorie `user`, puis expliquer comment utiliser l'action `user create`. Vous devriez remarquer que l'arbre des commandes YunoHost suit une structure similaire aux pages de la webadmin. ### La commande `yunopaste` + Cette commande est utile lorsque vous voulez communiquer à une autre personne le retour d'une commande. Exemple : + ```bash yunohost tools diagnosis | yunopaste ``` + ### Quelques commandes utiles Si votre interface web d'administration indique que l'API est injoignable, essayez de démarrer `yunohost-api` : + ```bash systemctl start yunohost-api ``` Si vous ne parvenez plus à vous connecter avec l'utilisateur `admin` via SSH et via l'interface web, le service `slapd` est peut-être éteint, essayez de le redémarrer : + ```bash systemctl restart slapd ``` Si vous avez des configurations modifiées manuellement et souhaitez connaître les modifications : + ```bash yunohost tools regen-conf --with-diff --dry-run ``` diff --git a/pages/02.administer/15.admin_guide/15.command_line/command_line.it.md b/pages/02.administer/15.admin_guide/15.command_line/command_line.it.md index 104f43ff..b394fb86 100644 --- a/pages/02.administer/15.admin_guide/15.command_line/command_line.it.md +++ b/pages/02.administer/15.admin_guide/15.command_line/command_line.it.md @@ -17,16 +17,17 @@ page-toc: ## Durante l'installazione di YunoHost -#### Individuare il proprio IP +### Individuare il proprio IP Se stai installando su un VPS allora il provider dovrebbe averti indicato il tuo indirizzo IP. Se stai installando su un computer casalingo (ad esempio un Raspberry Pi o un OLinuXino) devi individuare l'indirizzo IP che è stato attribuito al computer dopo averlo collegato al router. Questi sono alcuni sistemi: + - avvia un terminale e dai il comando `sudo arp-scan --local` per elencare gli indirizzi IP sulla rete locale; - usa l'interfaccia del router per vedere la lista dei computer collegati o controllane i log; - collega un monitor al tuo server YunoHost, fai login e digita `hostname --all-ip-address`. -#### Collegamento +### Collegamento Se come esempio il tuo indirizzo IP è `111.222.333.444` avvia un terminale e digita: @@ -38,7 +39,7 @@ Ti verrà richiesta una password. Nel caso tu stia utilizzando un VPS questa ti ! Dalla versione 3.4 di YunoHost, dopo aver completato il processo di post installazione, non sarà più possibile fare login da `root`: invece **sarà necessario fare login usando l'utente `admin`!**. Nel caso in cui il server LDAP non stia funzionando e l'utente `admin` sia inutilizzabile sarà sempre possibile fare login da `root` solo dalla rete locale. -#### Cambio della password +### Cambio della password Dopo esserci loggati per la prima volta è necessario cambiare la password di root e ti dovrebbe essere richiesto dal server stesso; nel caso in cui questo non accada usa il comando `passwd`. È importante scegliere una password ragionevolmente robusta. Nota che la password di root verrà sovrascritta dalla password di admin dal processo di postinstallazione. @@ -104,16 +105,16 @@ Una discussione più approfondita relativa a sicurezza & SSH è su [questa pagin The `yunohost` command can be used to administrate your server and perform the various actions similarly to what you do on the webadmin. The command must be launched either from the `root` user or from the `admin` user by preceeding them with `sudo`. (ProTip™ : you can become `root` with the command `sudo su` as `admin`). -YunoHost commands usually have this kind of structure : +YunoHost commands usually have this kind of structure : -```bash +```text yunohost app install wordpress --label Webmail ^ ^ ^ ^ | | | | category action argument options ``` -Don't hesitate to browse and ask for more information about a given category or action using the the `--help` option. For instance, those commands : +Don't hesitate to browse and ask for more information about a given category or action using the the `--help` option. For instance, those commands : ```bash yunohost --help diff --git a/pages/02.administer/15.admin_guide/15.command_line/command_line.md b/pages/02.administer/15.admin_guide/15.command_line/command_line.md index 99f6de1b..432c080c 100644 --- a/pages/02.administer/15.admin_guide/15.command_line/command_line.md +++ b/pages/02.administer/15.admin_guide/15.command_line/command_line.md @@ -18,8 +18,8 @@ page-toc: The command line interface (CLI) is, in the computer world, the original (and more technical) way of interacting with a computer compared to graphical interface. Command line interfaces are generally said to be more complete, powerful or efficient than a graphical interface, though also more difficult to learn. ## How to connect -### Login credentials +### Login credentials [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="Before running the initial configuration (post-installation)"] @@ -39,19 +39,18 @@ During the postinstall, you've been asked to choose an administration password. ### Address to use If you are **installing at home** (e.g. on a Raspberry Pi or OLinuXino or old computer): - - you should be able to connect to your server using `yunohost.local` (or `yunohost-2.local`, depending on how many servers are on your network). - - if `yunohost.local` and the like do not work, your need to [find out the local IP of the server](/finding_the_local_ip). - - if you installed a server at home but are attempting to connect from outside your local network, make sure port 22 is correctly forwarded to your server. +- you should be able to connect to your server using `yunohost.local` (or `yunohost-2.local`, depending on how many servers are on your network). +- if `yunohost.local` and the like do not work, your need to [find out the local IP of the server](/finding_the_local_ip). +- if you installed a server at home but are attempting to connect from outside your local network, make sure port 22 is correctly forwarded to your server. If your server is a remote server (VPS), your provider should have communicated you the IP address of the machine In any cases, if you already configured a domain name pointing to the appropriate IP, it's much better to use `yourdomain.tld` instead of the IP address. - ### Connecting -The SSH command typically looks like: +The SSH command typically looks like: ```bash # before the postinstall: @@ -76,7 +75,7 @@ N.B. : `fail2ban` will ban your IP for 10 minutes if you perform 10 failed login By default, only the `admin` user can log in to YunoHost SSH server. -YunoHost's users created via the administration interface are managed by the LDAP directory. By default, they can't connect via SSH for security reasons. Via the permissions system it is possible to allow the connection in SFTP or if it is really necessary in SSH. +YunoHost's users created via the administration interface are managed by the LDAP directory. By default, they can't connect via SSH for security reasons. Via the permissions system it is possible to allow the connection in SFTP or if it is really necessary in SSH. ! Be careful who you give SSH access to. This increases even more the attack surface available to a malicious user. @@ -90,6 +89,7 @@ If you want to add an SSH public key to the user, you have to do it from the com [/ui-tab] [ui-tab title="From the command line"] To allow a user or group to access via SFTP or SSH: + ```bash # SFTP yunohost user permission add sftp @@ -98,6 +98,7 @@ yunohost user permission add ssh ``` To remove permission: + ```bash # SFTP yunohost user permission remove sftp @@ -106,15 +107,16 @@ yunohost user permission remove ssh ``` Finally, it is possible to add, delete and list SSH keys, to improve SSH access security, using the commands: + ```bash yunohost user ssh add-key yunohost user ssh remove-key yunohost user ssh list-keys ``` + [/ui-tab] [/ui-tabs] - ## Security and SSH A more extensive discussion about security & SSH can be found on the [dedicated page](/security). @@ -127,16 +129,16 @@ A more extensive discussion about security & SSH can be found on the [dedicated The `yunohost` command can be used to administer your server and perform the various actions similarly to what you do on the webadmin. The command must be launched either from the `root` user or from the `admin` user by preceeding them with `sudo`. (ProTip™ : you can become `root` with the command `sudo su` as `admin`). -YunoHost commands usually have this kind of structure : +YunoHost commands usually have this kind of structure : -```bash +```text yunohost app install wordpress --label Webmail ^ ^ ^ ^ | | | | category action argument options ``` -Don't hesitate to browse and ask for more information about a given category or action using the the `--help` option. For instance, those commands : +Don't hesitate to browse and ask for more information about a given category or action using the the `--help` option. For instance, those commands : ```bash yunohost --help @@ -147,16 +149,18 @@ yunohost user create --help will successively list all the categories available, then the actions available in the `user` category, then the usage of the action `user create`. You might notice that the YunoHost command tree is built with a structure similar to the YunoHost admin pages. ### The `yunopaste` command + This command allow you to share with an other person the output of a command. Example: + ```bash yunohost tools diagnosis | yunopaste ``` ### The `ynh-vpnclient-loadcubefile.sh` command -This command is only available if you have the `VPN Client` application installed. You can use it to load a new .cube in case you can't get to the VPN Client interface to do so. +This command is only available if you have the `VPN Client` application installed. You can use it to load a new .cube in case you can't get to the VPN Client interface to do so. ```bash ynh-vpnclient-loadcubefile.sh -u -p -c .cube @@ -165,16 +169,19 @@ ynh-vpnclient-loadcubefile.sh -u -p -c .cube ### Some useful commands If your administration web interface indicates that the API is unreachable, try starting `yunohost-api`: + ```bash systemctl start yunohost-api ``` If you can no longer connect with the user `admin` via SSH and via the web interface, the `slapd` service may be down, try restarting it: + ```bash systemctl restart slapd ``` If you have manually modified configurations and want to know the changes: + ```bash yunohost tools regen-conf --with-diff --dry-run ``` diff --git a/pages/02.administer/15.admin_guide/20.users/05.groups_and_permissions/groups_and_permissions.fr.md b/pages/02.administer/15.admin_guide/20.users/05.groups_and_permissions/groups_and_permissions.fr.md index e907cc91..78ddac37 100644 --- a/pages/02.administer/15.admin_guide/20.users/05.groups_and_permissions/groups_and_permissions.fr.md +++ b/pages/02.administer/15.admin_guide/20.users/05.groups_and_permissions/groups_and_permissions.fr.md @@ -19,17 +19,18 @@ L'utilisation de groupes est cependant utile pour la sémantique, par exemple si Il est également possible de définir des alias mail pour un groupe, afin que les mails envoyés à `groupe@domain.tld` soient redirigés vers tous les membres du groupe. - ### Groupes par défaut + Par défaut, deux groupes spéciaux sont créés : + - `all_users`, qui contient tous les utilisateurs enregistrés sur YunoHost, -- `visitors`, c'est-à-dire les personnes qui consultent le serveur sans être connectées. -- `admins`, apparut depuis Yunohost 11.1, ce groupe permet de gérer les administrateurs de la machine, chaque utilisateur aura alors (selon la configuration du serveur) accès en SSH ainsi que la webadmin. +- `visitors`, c'est-à-dire les personnes qui consultent le serveur sans être connectées. +- `admins`, apparut depuis YunoHost 11.1, ce groupe permet de gérer les administrateurs de la machine, chaque utilisateur aura alors (selon la configuration du serveur) accès en SSH ainsi que la webadmin. Vous ne pouvez pas changer le contenu de ces groupes, seulement les permissions qui leur sont accordées. - ### Lister les groupes existants + [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="À partir de l'interface web"] Les groupes existants sont listés en haut de la page *groupes et autorisations*. @@ -40,9 +41,8 @@ Les groupes existants sont listés en haut de la page *groupes et autorisations* [ui-tab title="À partir de la ligne de commande"] Pour obtenir la liste des groupes existants en ligne de commande : - -```shell -$ yunohost user group list +```bash +yunohost user group list groups: all_users: members: @@ -51,10 +51,12 @@ groups: - charlie - delphine ``` + [/ui-tab] [/ui-tabs] ### Créer un nouveau groupe + [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="À partir de l'interface web"] Pour créer un nouveau groupe, il suffit de cliquer sur le bouton "Nouveau groupe" en haut de la page. Vous ne pouvez choisir qu'un nom formé de lettres (majuscules et minuscules) et d'espaces. Le groupe est créé vide et sans aucune permission. @@ -65,13 +67,15 @@ Pour créer un nouveau groupe, il suffit de cliquer sur le bouton "Nouveau group [ui-tab title="À partir de la ligne de commande"] Dans la ligne de commande, pour créer un nouveau groupe appelé `yolo_crew`, il faut utiliser -```shell -$ yunohost user group create yolo_crew +```bash +yunohost user group create yolo_crew ``` + [/ui-tab] [/ui-tabs] ### Mettre à jour un groupe + [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="À partir de l'interface web"] Ajoutons un premier utilisateur à ce groupe : dans le panneau du groupe, cliquez sur le bouton "Ajouter un utilisateur" et faites défiler jusqu'à l'utilisateur souhaité, puis cliquez dessus. @@ -86,16 +90,16 @@ Pour supprimer un utilisateur, cliquez sur la croix à côté de son nom d'utili [ui-tab title="À partir de la ligne de commande"] En ligne de commande, utilisez la commande suivante pour ajouter `charlie` et `delphine` au groupe `yolo_crew` : -```shell -$ yunohost user group add yolo_crew charlie delphine +```bash +yunohost user group add yolo_crew charlie delphine ``` (De même, `remove` peut être utilisé pour retirer des membres d'un groupe.) Dans la liste des groupes, nous devrions voir : -```shell -$ yunohost user group list +```bash +yunohost user group list groups: all_users: members: @@ -108,6 +112,7 @@ groups: - charlie - delphine ``` + [/ui-tab] [/ui-tabs] @@ -124,9 +129,10 @@ Pour supprimer un groupe, cliquez sur la croix rouge en haut à droite du pannea Pour supprimer le groupe `yolo_crew` en ligne de commande, vous pouvez exécuter : -```shell -$ yunohost user group delete yolo_crew +```bash +yunohost user group delete yolo_crew ``` + [/ui-tab] [/ui-tabs] @@ -145,8 +151,9 @@ La page des groupes liste les permissions données à chaque groupe, y compris l [/ui-tab] [ui-tab title="À partir de la ligne de commande"] Pour répertorier les permissions et les accès correspondants en ligne de commande : -```shell -$ yunohost user permission list + +```bash +yunohost user permission list permissions: mail.main: allowed: all_users @@ -157,6 +164,7 @@ permissions: xmpp.main: allowed: all_users ``` + Ici, nous constatons que tous les utilisateurs enregistrés peuvent utiliser le mail, XMPP, et accéder au blog WordPress. Cependant, personne ne peut accéder à l'interface d'administration de WordPress. Plus de détails peuvent être affichés en ajoutant l'option `--full` qui affichera la liste des utilisateurs correspondant aux groupes autorisés, ainsi que les adresses web associées à une permission (pertinent pour les applications web). @@ -181,20 +189,20 @@ Notez que, par exemple, si nous voulons restreindre la permission pour le mail a [ui-tab title="À partir de la ligne de commande"] Pour permettre à un groupe d'accéder à l'interface d'administration de WordPress via la ligne de commande : -```shell -$ yunohost user permission update wordpress.admin --add yolo_crew +```bash +yunohost user permission update wordpress.admin --add yolo_crew ``` Vous pouvez également autoriser un seul utilisateur : -```shell -$ yunohost user permission update wordpress.admin --add alice +```bash +yunohost user permission update wordpress.admin --add alice ``` Et maintenant, nous pouvons voir que YoloCrew et Alice ont tous deux accès à l'interface d'administration de WordPress : -```shell -$ yunohost user permission list +```bash +yunohost user permission list [...] wordpress.admin: allowed: @@ -205,8 +213,8 @@ $ yunohost user permission list Pour permettre seulement à Bob d'accéder aux emails en ligne de commande : -```shell -$ yunohost user permission update mail --remove all_users --add bob +```bash +yunohost user permission update mail --remove all_users --add bob ``` [/ui-tab] @@ -231,21 +239,22 @@ Depuis la webadmin, vous pouvez changer cela en allant dans la vue de l'applicat En ligne de commande, le même genre de chose peut être fait avec : -```shell +```bash # Activer la tuile pour l'interface d'admin de WordPress -$ yunohost user permission update wordpress.admin --show_tile True +yunohost user permission update wordpress.admin --show_tile True ``` + [/ui-tab] [/ui-tabs] - ### Gérer les alias des groupes -Chaque groupe peut utiliser des alias de mail, bien que leur configuration se fasse actuellement uniquement depuis la CLI. Par défaut, le groupe `admins` dispose ainsi de `admins@domain.tld`, `root@domain.tld` ... : les messages envoyés à ces adresses sont redirigés vers tous les membres du groupe `admins`. + +Chaque groupe peut utiliser des alias de mail, bien que leur configuration se fasse actuellement uniquement depuis la CLI. Par défaut, le groupe `admins` dispose ainsi de `admins@domain.tld`, `root@domain.tld` ... : les messages envoyés à ces adresses sont redirigés vers tous les membres du groupe `admins`. L'utilisation de la commande `yunohost user group info` permet de lister tous les alias pour le groupe renseigné. -```shell -$ yunohost user group info admins +```bash +yunohost user group info admins [...] mail-aliases: - root@maindomain.tld @@ -258,6 +267,7 @@ $ yunohost user group info admins ``` Il est possible de les ajouter avec l'action `add-mailalias` ou de les enlever avec `remove-mailalias`. -```shell -$ yunohost user group add-mailalias + +```bash +yunohost user group add-mailalias ``` diff --git a/pages/02.administer/15.admin_guide/20.users/05.groups_and_permissions/groups_and_permissions.md b/pages/02.administer/15.admin_guide/20.users/05.groups_and_permissions/groups_and_permissions.md index 587d25ac..1119de3d 100644 --- a/pages/02.administer/15.admin_guide/20.users/05.groups_and_permissions/groups_and_permissions.md +++ b/pages/02.administer/15.admin_guide/20.users/05.groups_and_permissions/groups_and_permissions.md @@ -20,12 +20,12 @@ Using groups is however useful for semantics, for example if you host multiple g It's also possible to define mail aliases for a group, such that mails sent to `groupe@domain.tld` will be dispatched to all members of the group. - ### Default groups By default, two special groups are created: + - `all_users`, that contain all users registered on YunoHost, -- `visitors`, that applies to people viewing the server while not logged in. +- `visitors`, that applies to people viewing the server while not logged in. The content of those groups cannot be changed, only the permissions given to them. @@ -42,8 +42,8 @@ The existing groups are listed at the top of the *groups and permissions* page. To list the currently existing groups in CLI : -```shell -$ yunohost user group list +```bash +yunohost user group list groups: all_users: members: @@ -52,6 +52,7 @@ groups: - charlie - delphine ``` + [/ui-tab] [/ui-tabs] @@ -67,9 +68,10 @@ To create a new group, simply click on the "New Group" button at the top of the [ui-tab title="From the command line"] In CLI, to create a new group called `yolo_crew` -```shell -$ yunohost user group create yolo_crew +```bash +yunohost user group create yolo_crew ``` + [/ui-tab] [/ui-tabs] @@ -89,16 +91,16 @@ To remove a user, click on the cross next to their username, in the group panel. [ui-tab title="From the command line"] In CLI, use the following command to add `charlie` and `delphine`to the `yolo_crew` group: -```shell -$ yunohost user group add yolo_crew charlie delphine +```bash +yunohost user group add yolo_crew charlie delphine ``` (similarly, `remove` can be used to remove members from a group) Now in the group list we should see: -```shell -$ yunohost user group list +```bash +yunohost user group list groups: all_users: members: @@ -111,6 +113,7 @@ groups: - charlie - delphine ``` + [/ui-tab] [/ui-tabs] @@ -126,9 +129,10 @@ To delete a group, click on the red cross on the top right of the group panel. Y [ui-tab title="From the command line"] To delete the group `yolo_crew` in CLI, you may run -```shell -$ yunohost user group delete yolo_crew +```bash +yunohost user group delete yolo_crew ``` + [/ui-tab] [/ui-tabs] @@ -148,8 +152,8 @@ The groups page lists the permissions given to each group, including the special [ui-tab title="From the command line"] To list permissions and corresponding accesses in CLI: -```shell -$ yunohost user permission list +```bash +yunohost user permission list permissions: mail.main: allowed: all_users @@ -183,20 +187,20 @@ Note that you can also allow a single user, by using the specific panel at the b [ui-tab title="From the command line"] To allow a group to access the WordPress admin interface in CLI: -```shell -$ yunohost user permission update wordpress.admin --add yolo_crew +```bash +yunohost user permission update wordpress.admin --add yolo_crew ``` Note that you can also allow a single user, by using the specific panel at the bottom of the page. -```shell -$ yunohost user permission update wordpress.admin --add alice +```bash +yunohost user permission update wordpress.admin --add alice ``` And now we may see that both the YoloCrew and Alice have access to the WordPress admin interface: -```shell -$ yunohost user permission list +```bash +yunohost user permission list [...] wordpress.admin: allowed: @@ -207,9 +211,10 @@ $ yunohost user permission list Note that, for example, if we want to restrict permission for email so that only Bob is allowed to email, we should also remove `all_users` from the permission, by deleting it from the `all_users` group panel, or in CLI: -```shell -$ yunohost user permission update mail --remove all_users --add bob +```bash +yunohost user permission update mail --remove all_users --add bob ``` + [/ui-tab] [/ui-tabs] @@ -224,28 +229,29 @@ The webadmin will issue a warning if you set a permission that is superseded by Since YunoHost 4.1, you can choose to hide/display specific tiles in the SSO. [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="From the web interface"] -In the webadmin, you can do so by going in the corresponding app view, go in `Manage label and tiles` and check/uncheck the option `Display the tile in the user portal` for the corresponding permission. +In the webadmin, you can do so by going in the corresponding app view, go in `Manage label and tiles` and check/uncheck the option `Display the tile in the user portal` for the corresponding permission. [/ui-tab] [ui-tab title="From the command line"] In command line, this may be done with: -```shell +```bash # Enable the tile for the WordPress admin interface -$ yunohost user permission update wordpress.admin --show_tile True +yunohost user permission update wordpress.admin --show_tile True ``` + [/ui-tab] [/ui-tabs] - ### Config alias group + Each group can use mail aliases, but their configuration is only available from the CLI so far. For example, the `admins` group is configured with aliases such as `admins@domain.tld`, `root@domain.tld` ... : mail sent to these addresses will be dispatched to all members of the `admins` group. The command `yunohost user group info` will list them. -```shell -$ yunohost user group info admins +```bash +yunohost user group info admins [...] mail-aliases: - root@maindomain.tld @@ -258,6 +264,7 @@ $ yunohost user group info admins ``` To add a new mail, use the action `add-mailalias` or `remove-mailalias` to delete it. -```shell -$ yunohost user group add-mailalias + +```bash +yunohost user group add-mailalias ``` diff --git a/pages/02.administer/15.admin_guide/20.users/users.fr.md b/pages/02.administer/15.admin_guide/20.users/users.fr.md index 64696fe8..e24b3813 100644 --- a/pages/02.administer/15.admin_guide/20.users/users.fr.md +++ b/pages/02.administer/15.admin_guide/20.users/users.fr.md @@ -34,4 +34,3 @@ Voir [cette page de documentation dédiée](/groups_and_permissions). ## Accès SSH Voir [cette page de documentation dédiée](/ssh). - diff --git a/pages/02.administer/15.admin_guide/25.domains/01.certificate/certificate.de.md b/pages/02.administer/15.admin_guide/25.domains/01.certificate/certificate.de.md index acca9712..884f0080 100644 --- a/pages/02.administer/15.admin_guide/25.domains/01.certificate/certificate.de.md +++ b/pages/02.administer/15.admin_guide/25.domains/01.certificate/certificate.de.md @@ -14,7 +14,7 @@ Und zwar, werden die Benutzer eine solche Warnung auf dem Bildschirm sehen: ![](image://postinstall_error_de.png) -Was im Wesentlichen den Besucher fragt: **"Vertrauen Sie dem Server, der diese Website hostet? "**. +Was im Wesentlichen den Besucher fragt: **"Vertrauen Sie dem Server, der diese Website hostet?"**. Dies kann viele Menschen selbstverständlich erschrecken. Um diese Verwirrung zu vermeiden, ist es möglich, ein digitales Zertifikat zu erhalten, welches direkt von den Browsern anerkannt wurde, und von einer "bekannten" Zertifizierungsstelle unterzeichnet wird: **Let's Encrypt**, **Gandi**, **RapidSSL**, **StartSSL**, **Cacert**. @@ -37,7 +37,7 @@ Wurde der Domain-Name vor kurzem hinzugefügt, so steht ein selbst-signiertes Ze ![](image://certificate-before-LE.png) -Wenn die Domain korrekt konfiguriert ist, dann ist es möglich +Wenn die Domain korrekt konfiguriert ist, dann ist es möglich mit dem grünen Knopf ein Let's Encrypt-Zertifikat einzusetzen. ![](image://certificate-after-LE.png) @@ -52,7 +52,7 @@ von Let's Encrypt zu überprüfen. Das digitale Zertifikat wird automatisch etwa SSH-Zugang auf Ihrem Server herstellen. -So können Sie den aktuellen Status des digitalen Zertifikats überprüfen +So können Sie den aktuellen Status des digitalen Zertifikats überprüfen ```bash yunohost domain cert-status Ihre.domain.tld @@ -91,5 +91,3 @@ manschmal die Einstellungen verweigern. In diesem Fall ist es notwendig : - die Parameter `127.0.0.1 Ihre.domain.tld` auf der Datei `/etc/hosts` des Webserver hinzufügen. Wenn es immer noch nicht funktionsfähig ist, also die Überprüfungen deaktivieren mit `--no-checks` nach dem Befehl `cert-install`. - - diff --git a/pages/02.administer/15.admin_guide/25.domains/01.certificate/certificate.es.md b/pages/02.administer/15.admin_guide/25.domains/01.certificate/certificate.es.md index 3d1b2d80..bc887a5d 100644 --- a/pages/02.administer/15.admin_guide/25.domains/01.certificate/certificate.es.md +++ b/pages/02.administer/15.admin_guide/25.domains/01.certificate/certificate.es.md @@ -47,7 +47,7 @@ Una vez la instalación terminada, puedes ir a tu dominio vía tu navegador, en Conectate en tu servidor en SSH. -Puedes comprobar el estatus corriente de tu certificado vía +Puedes comprobar el estatus corriente de tu certificado vía ```bash yunohost domain cert-status tu.dominio.tld diff --git a/pages/02.administer/15.admin_guide/25.domains/01.certificate/certificate.it.md b/pages/02.administer/15.admin_guide/25.domains/01.certificate/certificate.it.md index 04a6894e..b8719133 100644 --- a/pages/02.administer/15.admin_guide/25.domains/01.certificate/certificate.it.md +++ b/pages/02.administer/15.admin_guide/25.domains/01.certificate/certificate.it.md @@ -19,7 +19,7 @@ Il browser fondamentalmente ci chiede **«Potete fidarvi del server che ospita q Per evitare questa situazione è possibile ottenere un certificato riconosciuto dai browser e firmato da un'autorità conosciuta come **Let's Encrypt**, **Gandi**, **RapidSSL**, **StartSSL**, **Cacert**. -In particolare **Let's Encrypt** offre i certificati gratuitamente. Dalla versione 2.5 YunoHost permette di installare il certificato direttamente dall'interfaccia di amministrazione web o da linea di comando. Di seguito troverete la documentazione per l'installazione e la gestione di un certificato. È comunque possibile [installare ugualmente un certificato di un'autorità diversa da Let's Encrypt](/certificate_custom). +In particolare **Let's Encrypt** offre i certificati gratuitamente. Dalla versione 2.5 YunoHost permette di installare il certificato direttamente dall'interfaccia di amministrazione web o da linea di comando. Di seguito troverete la documentazione per l'installazione e la gestione di un certificato. È comunque possibile [installare ugualmente un certificato di un'autorità diversa da Let's Encrypt](/certificate_custom). ### Installare un certificato Let's Encrypt @@ -35,7 +35,6 @@ Recatevi nella sezione 'Domini' dell'interfaccia di amministrazione, scegliete l ![](image://domain-certificate-button.png) - Nella sezione 'Certificati SSL' potere visualizzare lo stato attuale del certificato. Se avete appena creato il dominio, esso disporrà di un certificato auto firmato. diff --git a/pages/02.administer/15.admin_guide/25.domains/01.certificate/certificate.md b/pages/02.administer/15.admin_guide/25.domains/01.certificate/certificate.md index 2c6144cd..fe8b57fe 100644 --- a/pages/02.administer/15.admin_guide/25.domains/01.certificate/certificate.md +++ b/pages/02.administer/15.admin_guide/25.domains/01.certificate/certificate.md @@ -83,4 +83,3 @@ If YunoHost thinks that your domain is badly configured despite the fact that yo - add a line `127.0.0.1 your.domain.tld` to the file `/etc/hosts` on your server; - if the certificate installation still doesn't work, you can disable the checks with `--no-checks` after the `cert-install` command. - diff --git a/pages/02.administer/15.admin_guide/25.domains/domains.de.md b/pages/02.administer/15.admin_guide/25.domains/domains.de.md index 905fc39a..5dd3b28d 100644 --- a/pages/02.administer/15.admin_guide/25.domains/domains.de.md +++ b/pages/02.administer/15.admin_guide/25.domains/domains.de.md @@ -19,7 +19,7 @@ Beachten Sie abschließend, dass es im Kontext von YunoHost keine Hierarchie zwi ## Nicht-lateinische Zeichen -Wenn Ihre Domain spezielle, nicht-lateinische Zeichen enthält, müssen Sie ihre [internationalisierte Version](https://de.wikipedia.org/wiki/Internationalisierter_Domainname) über [Punycode](https://de.wikipedia.org/wiki/Punycode) verwenden. Sie können [diesen Konverter](https://www.charset.org/punycode) verwenden und den konvertierten Domainnamen in Ihrer YunoHost-Konfiguration verwenden. +Wenn Ihre Domain spezielle, nicht-lateinische Zeichen enthält, müssen Sie ihre [internationalisierte Version](https://de.wikipedia.org/wiki/Internationalisierter_Domainname) über [Punycode](https://de.wikipedia.org/wiki/Punycode) verwenden. Sie können [diesen Konverter](https://www.charset.org/punycode) verwenden und den konvertierten Domainnamen in Ihrer YunoHost-Konfiguration verwenden. ## Subdomains @@ -28,7 +28,7 @@ Wenn Ihre Domain spezielle, nicht-lateinische Zeichen enthält, müssen Sie ihre ## DNS-Konfiguration -DNS (Domain Name System) ist ein System, das es Computern auf der ganzen Welt ermöglicht, von Menschen lesbare Domain-Namen (wie z.B. `yolo.com`) in maschinenverständliche Adressen, sogenannte IP-Adressen (wie z.B. `11.22.33.44`), zu übersetzen. Damit diese Übersetzung (und andere Funktionen) funktioniert, müssen Sie DNS-Einträge sorgfältig konfigurieren. +DNS (Domain Name System) ist ein System, das es Computern auf der ganzen Welt ermöglicht, von Menschen lesbare Domain-Namen (wie z.B. `yolo.com`) in maschinenverständliche Adressen, sogenannte IP-Adressen (wie z.B. `11.22.33.44`), zu übersetzen. Damit diese Übersetzung (und andere Funktionen) funktioniert, müssen Sie DNS-Einträge sorgfältig konfigurieren. YunoHost kann eine empfohlene DNS-Konfiguration für jede Domain generieren, einschließlich der für Mail und XMPP benötigten Elemente. Die empfohlene DNS-Konfiguration ist im Webadmin über Domain > (die Domain) > DNS-Konfiguration oder mit dem Befehl `yunohost domain dns-conf the.domain.tld` verfügbar. @@ -40,9 +40,9 @@ Ein weiterer wichtiger Aspekt der Domain-Konfiguration ist das SSL/HTTPS-Zertifi !!!! Section to be moved to a translated /apps_overview page -Im Zusammenhang mit YunoHost ist es durchaus üblich, eine einzige (oder einige wenige) Domains zu haben, auf denen mehrere Anwendungen in "Unterpfaden" installiert sind, so dass man am Ende etwas wie dieses erhält: +Im Zusammenhang mit YunoHost ist es durchaus üblich, eine einzige (oder einige wenige) Domains zu haben, auf denen mehrere Anwendungen in "Unterpfaden" installiert sind, so dass man am Ende etwas wie dieses erhält: -```bash +```text yolo.com ├── /blog : Wordpress (ein Blog) ├─── /cloud : Nextcloud (ein Cloud-Dienst) @@ -56,7 +56,7 @@ Dies mag für Endbenutzer hübscher aussehen, wird aber im Allgemeinen als kompl Wenn alle Anwendungen aus dem vorherigen Beispiel auf einer separaten Domain installiert wären, würde dies etwa so aussehen: -```bash +```text blog.yolo.com : Wordpress (ein Blog) cloud.yolo.com : Nextcloud (ein Cloud-Dienst) rss.yolo.com : TinyTiny RSS (ein RSS-Reader) diff --git a/pages/02.administer/15.admin_guide/25.domains/domains.fr.md b/pages/02.administer/15.admin_guide/25.domains/domains.fr.md index 3706d12e..3527d1b5 100644 --- a/pages/02.administer/15.admin_guide/25.domains/domains.fr.md +++ b/pages/02.administer/15.admin_guide/25.domains/domains.fr.md @@ -42,7 +42,7 @@ Le chiffre risque de changer selon quel serveur démarre en premier, donc ne com ## Configuration DNS -DNS (Domain Name System) est un système qui permet aux ordinateurs du monde entier de traduire les noms de domaine lisibles par l'homme (comme `yolo.com`) en adresses IP compréhensibles par les machines (comme `11.22.33.44`). Pour que cette traduction (et d'autres fonctionnalités) fonctionne, il faut configurer soigneusement les enregistrements DNS. +DNS (Domain Name System) est un système qui permet aux ordinateurs du monde entier de traduire les noms de domaine lisibles par l'homme (comme `yolo.com`) en adresses IP compréhensibles par les machines (comme `11.22.33.44`). Pour que cette traduction (et d'autres fonctionnalités) fonctionne, il faut configurer soigneusement les enregistrements DNS. YunoHost peut générer une configuration DNS recommandée pour chaque domaine, y compris les enregistrements nécessaires pour les parties emails et XMPP. La configuration DNS recommandée est disponible dans l'administrateur web via Domaines > (le domaine) > configuration DNS, ou avec la commande `yunohost domain dns-conf the.domain.tld`. diff --git a/pages/02.administer/15.admin_guide/25.domains/domains.it.md b/pages/02.administer/15.admin_guide/25.domains/domains.it.md index c5b5f340..f98b1b0c 100644 --- a/pages/02.administer/15.admin_guide/25.domains/domains.it.md +++ b/pages/02.administer/15.admin_guide/25.domains/domains.it.md @@ -7,9 +7,9 @@ routes: default: '/domains' --- -Yunohost permette l'installazione e la gestione di più domini sullo stesso server. Potrete quindi ospitare, ad esempio, un blog e una istanza Nextcloud sul dominio primario yolo.com, e un altro servizio su un secondo dominio swag.nohost.me. Ogni dominio viene automaticamente configurato affinché possa gestire i servizi web, le mail, e un servizio di chat XMPP. +YunoHost permette l'installazione e la gestione di più domini sullo stesso server. Potrete quindi ospitare, ad esempio, un blog e una istanza Nextcloud sul dominio primario yolo.com, e un altro servizio su un secondo dominio swag.nohost.me. Ogni dominio viene automaticamente configurato affinché possa gestire i servizi web, le mail, e un servizio di chat XMPP. -I domini possono essere configurati a partire dalla sezione 'Domini' della pagina di amministrazione web, o attraverso la sezione `yunohost domain` da linea di comando. +I domini possono essere configurati a partire dalla sezione 'Domini' della pagina di amministrazione web, o attraverso la sezione `yunohost domain` da linea di comando. Ogni volta che aggiungete un dominio, sia esso vostro o del quale abbiate facoltà di gestione, dovete averne il pieno controllo per la poter effettuare la sua [configurazione DNS](/dns_config). Fanno eccezione i [domini in .nohost.me, .noho.st et ynh.fr](/dns_nohost_me) offerti dal progetto YunoHost, che possono essere direttamente integrati nel vostro server YunoHost grazie alla configurazione automatica di un servizio DynDns. Al fine di impedire abusi e limitare i costi, una instanza YunoHost può essere configurata con un solo dominio offerto, tuttavia potete aggiungere tutti i suoi sotto domini che desiderate. Ad esempio, se scegliete il dominio `exemple.ynh.fr` potrete in un secondo tempo aggiungere i domini `video.exemple.ynh.fr` o `www.exemple.ynh.fr` o qualsiasi altro sottodominio che possa servirvi. @@ -49,10 +49,3 @@ YunoHost può generare una configurazione DNS raccomandata per ogni dominio che ## Certificati SSL/HTTPS Un altro importante aspetto della configurazione dei domini è quello riguardante il certificato SSL/HTTPS. YuhoHost integra Let's Encrypt, potete installare il certificato e impostare il rinnovo automatico. La documentazione relativa e altre informazioni si trovano alla pagina [certificati](/certificate). - - - - - - - diff --git a/pages/02.administer/15.admin_guide/25.domains/domains.md b/pages/02.administer/15.admin_guide/25.domains/domains.md index 359f4b5d..bdffd650 100644 --- a/pages/02.administer/15.admin_guide/25.domains/domains.md +++ b/pages/02.administer/15.admin_guide/25.domains/domains.md @@ -21,11 +21,12 @@ Domains can be managed in the 'Domain' section of the webadmin, or through the ` ## 3 types of domains [ui-tabs position="top-left" active="0" theme="lite"] -[ui-tab title="Yunohost's domains (the free and easy way)"] +[ui-tab title="YunoHost's domains (the free and easy way)"] In order to make self-hosting as accessible as possible, the YunoHost Project provides a *free* and *automatically configured* domain name service. By using this service, you won't have to [configure DNS records](/dns_config) yourself, which can be tedious and technical. The following (sub)domains are offered: + - `whateveryouwant.nohost.me`; - `whateveryouwant.noho.st`; - `whateveryouwant.ynh.fr`. @@ -46,19 +47,17 @@ To get one of this domain you simply need to choose `I don't have a domaine name [ui-tab title="Your own domains"] Having your own domain brings several advantages: - * more control and autonomy - * simpler domain name (for example directly in .net or .org) +- more control and autonomy +- simpler domain name (for example directly in .net or .org) However, you have to pay for it each year (about 15€/year) and you have to do some extra configuration to [setup a correct DNS zone](/dns_config). Our diagnosis tool can trigger alert to help you to do this configuration. -If you already have your own domain, you can simply click "I already have a domain name…". If you don't, in order to simplify and automate the DNS configuration, we suggest you to buy it from a [registrar whose API is supported by YunoHost](/providers/registrar). +If you already have your own domain, you can simply click "I already have a domain name…". If you don't, in order to simplify and automate the DNS configuration, we suggest you to buy it from a [registrar whose API is supported by YunoHost](/providers/registrar). ![Here a screenshot of the "Add domain" page where you can choose "I already have a domain name"](image://webadmin_domain_owndomain.png) - [Know more on DNS zone configuration](/dns_config) - [/ui-tab] [ui-tab title="Local domains (only reachable in your local network)"] @@ -80,11 +79,11 @@ The number may change depending on which server starts first, so do not rely on ! Unfortunately, Android devices before version 12 (released in 2021) do not seem to be listening to mDNS protocol. ! To be able to reach `.local` domains on your Android devices, you will have to add in their DNS settings your YunoHost server's local IP address. - [/ui-tab] [/ui-tabs] ## The main domain + The domain chosen during the initial configuration (post-install) is defined as the main (or default) domain of the server : this is where [the user portal (SSO)](/users) will be available. The main domain can later be changed through the web admin in Domains > (the domain) > Set default, or with the command line `yunohost tools maindomain`. More technically, the main domain is also used as hostname by SMTP protocol to send email (EHLO) and determine which value should be configured in the reverse DNS bind to your public IP. If this 2 values are mis-configured, the diagnosis tool will trigger you an alert. @@ -98,7 +97,6 @@ More technically, the main domain is also used as hostname by SMTP protocol to s If your domain has special, non-latin characters, it will be transformed by YunoHost into its [internationalized version](https://en.wikipedia.org/wiki/Internationalized_domain_name) through [Punycode](https://en.wikipedia.org/wiki/Punycode). So when you use the command line, you have to use the punycode format return for example by `yunohost domain list`. - ## SSL/HTTPS certificates Another important aspect of domain configuration is the SSL/HTTPS certificate. YunoHost is integrated with Let's Encrypt, so once your server is correctly reachable from anybody on the internet through the domain name, the administrator can request a Let's Encrypt certificate. See the documentation about [certificates](/certificate) for more information. diff --git a/pages/02.administer/15.admin_guide/30.apps/apps.fr.md b/pages/02.administer/15.admin_guide/30.apps/apps.fr.md index 72d7d4bc..37c26b4e 100644 --- a/pages/02.administer/15.admin_guide/30.apps/apps.fr.md +++ b/pages/02.administer/15.admin_guide/30.apps/apps.fr.md @@ -47,6 +47,7 @@ L'accès aux applications peut être limité à certains utilisateurs seulement. À partir de YunoHost v11.1.21.4, si vous avez besoin d'exécuter des commandes avec le binaire de l'application, ou des commandes PHP, etc., vous pouvez exécuter la commande `yunohost app shell `. Cela aura pour effet de : + - ouvrir un nouveau shell Bash en tant qu'utilisateur système de l'application - ouvrir le répertoire de travail de l'application (par exemple `/var/www/`) - précharger l'environnement avec des variables provenant du service de l'application, s'il existe @@ -58,9 +59,9 @@ Si vous voulez apprendre ou contribuer à l'empaquetage des applications, veuill ## Sous-chemins vs. domaines individuels par application -Dans le contexte de YunoHost, il est assez courant d'avoir un seul (ou quelques) domaines sur lesquels plusieurs applications sont installées dans des "sous-chemins", de sorte que l'on se retrouve avec quelque chose comme ceci : +Dans le contexte de YunoHost, il est assez courant d'avoir un seul (ou quelques) domaines sur lesquels plusieurs applications sont installées dans des "sous-chemins", de sorte que l'on se retrouve avec quelque chose comme ceci : -```bash +```text yolo.com ├─── /blog : Wordpress (un blog) ├─── /cloud : Nextcloud (un service de cloud) @@ -72,7 +73,7 @@ Alternativement, on peut choisir d'installer chaque application (ou certaines) s Si toutes les applications de l'exemple précédent étaient installées sur un domaine séparé, cela donnerait quelque chose comme ceci : -```bash +```text blog.yolo.com : Wordpress (un blog) cloud.yolo.com : Nextcloud (un service de cloud) rss.yolo.com : TinyTiny RSS (un lecteur RSS) diff --git a/pages/02.administer/15.admin_guide/30.apps/apps.it.md b/pages/02.administer/15.admin_guide/30.apps/apps.it.md index 8e38f1a4..3d36e67c 100644 --- a/pages/02.administer/15.admin_guide/30.apps/apps.it.md +++ b/pages/02.administer/15.admin_guide/30.apps/apps.it.md @@ -11,7 +11,7 @@ routes: Una delle caratteristiche principali di YunoHost è la possibilità di installare facilmente applicazioni che saranno immediatamente utilizzabili. Ad esempio possiamo installare un blog, un "cloud" (per salvare e sincronizzare file), un sito web, un lettore RSS... -Le applicazioni possono essere installate e gestite tramite l'interfaccia di amministrazione web nella sezione `[fa=cubes /] Applicazioni`, oppure utilizzando i comandi della categoria `yunohost app`. +Le applicazioni possono essere installate e gestite tramite l'interfaccia di amministrazione web nella sezione `[fa=cubes /] Applicazioni`, oppure utilizzando i comandi della categoria `yunohost app`. [center] ![Apps list](image://apps_list.png?resize=512&classes=caption "Lista di applicazioni nella pagina webadmin con il relativo bottone Installa.") @@ -21,7 +21,6 @@ Le applicazioni possono essere installate e gestite tramite l'interfaccia di amm
Lista applicazioni
- ! Siate ragionevoli sul numero di programmi che installate. Ogni programma aumenta le possibilità di errori e attacchi dall'esterno. È preferibile, se desiderate effettuare dei test, utilizzare una [macchina virtuale](https://yunohost.org/en/install/hardware:virtualbox) con un'altra istanza. @@ -48,7 +47,7 @@ Fra le domande specifiche i form normalmente chiedono di scegliere un dominio ed In un'installazione normale di YunoHost è normale avere un dominio singolo (o al limite un piccolo numero di domini) per tutte le applicazioni installate si "sotto-directory" con una configurazione di questo tipo: -```bash +```text yolo.com ├── /blog : Wordpress (a blog) ├── /cloud : Nextcloud (a cloud service) @@ -65,14 +64,13 @@ Questo può sembrare più facile per gli utenti finali ma è considerato più co Se le applicazioni dell'esempio precedente fossero state installate su un dominio separato questo potrebbe essere il risultato: -```bash +```text blog.yolo.com : Wordpress (a blog) cloud.yolo.com : Nextcloud (a cloud service) rss.yolo.com : TinyTiny RSS (a RSS reader) wiki.yolo.com : DokuWiki (a wiki) ``` - !!! Molte applicazioni integrano una caratteristica che permette di cambiare l'URL dell'applicazione. La scelta fra sotto-directory e sotto-dominio in alcuni casi può essere cambiata con una semplice modifica nell'interfaccia di amministrazione. ### Gestione accessi utente e applicazioni pubbliche @@ -113,8 +111,8 @@ Da questa pagina è anche possibile eliminare l'applicazione. Dalla riga di comando è possibile cambiare: -* l'etichetta dell'applicazione nel sistema SSO: `yunohost app change-label ` -* l'url di connessione: `yunohost app change-url [-d ] [-p ]` +- l'etichetta dell'applicazione nel sistema SSO: `yunohost app change-label ` +- l'url di connessione: `yunohost app change-url [-d ] [-p ]` È anche possibile eliminare l'applicazione: `yunohost app remove ` @@ -141,7 +139,7 @@ Alcune applicazioni includono un *pannello di configurazione* che contiene azion Dalla riga di comando è possibile elencare le impostazione del pannello di configurazione con il comando `yunohost app config get ` -``` +```bash $ yunohost app config get my_webapp main.php_fpm_config.phpversion: ask: PHP version @@ -165,6 +163,7 @@ La parola `` è il nome dell'impostazione come nell'esempio sopra `main.sft Dalla versione di YunoHost v11.1.21.4 è possibile eseguire un comando con il binario dell'applicazione o comandi PHP con il comando `yunohost app shell `. In questo modo: + - verrà avviata una shell Bash come l'utente di sistema dell'applicazione - verrà aperta la directory di lavoro dell'applicazione (ad esempio `/var/www/`) - carico di tutte le variabili d'ambiente come da file service dell'applicazione se queste esistono @@ -172,7 +171,7 @@ In questo modo: ## Packaging delle applicazioni -Le applicazioni devono essere preparate (packaging) manualmente dai programmatori (packagers)/manutentori. Le applicazioni possono essere integrate con YunoHost perché supportino gli upgrade, i backup e restore e l'integrazione con LDAP/SSO fra le altre cose. +Le applicazioni devono essere preparate (packaging) manualmente dai programmatori (packagers)/manutentori. Le applicazioni possono essere integrate con YunoHost perché supportino gli upgrade, i backup e restore e l'integrazione con LDAP/SSO fra le altre cose. ## Integrazione e qualità @@ -180,6 +179,4 @@ Test automatici sono regolarmente eseguiti per controllare l'integrazione e la q Alcuni risultati sono disponibili su [questa pagina](https://dash.yunohost.org/appci/branch/stable). - Solo i programmi con una qualità sufficiente sono inseriti nell'elenco delle applicazioni installabili. Nel caso i test dovessero segnalare una diminuzione dell'indice di qualità, gli aggiornamenti saranno sospesi e le nuove installazioni non saranno possibili fino alla soluzione del problema che ha causato l'abbassamento dell'indice. - diff --git a/pages/02.administer/15.admin_guide/30.apps/apps.md b/pages/02.administer/15.admin_guide/30.apps/apps.md index a8b12cde..aa70ca7b 100644 --- a/pages/02.administer/15.admin_guide/30.apps/apps.md +++ b/pages/02.administer/15.admin_guide/30.apps/apps.md @@ -21,10 +21,8 @@ The application catalog and its categories can be browsed directly from the weba
Applications catalog
- ! Be careful and stay reasonable on the number of installed applications. Each additional installation increases the attack surface and the risk of failure. Ideally, if you want to test, do it with another instance for example in [a virtual machine](/install/hardware:virtualbox). - ## Installing an app Let's say you want to install a *Custom Webapp*. Before actually running the installation steps, YunoHost will usually have you fill in a form to properly set it up for you. @@ -46,9 +44,9 @@ Let's say you want to install a *Custom Webapp*. Before actually running the ins Among specific questions, forms usually ask you to choose a domain and a path onto which the app will be accessible. -In the context of YunoHost, it is quite common to have a single (or a few) domains on which several apps are installed in "subpaths", so that you end up with something like this: +In the context of YunoHost, it is quite common to have a single (or a few) domains on which several apps are installed in "subpaths", so that you end up with something like this: -```bash +```text yolo.com ├── /blog : Wordpress (a blog) ├── /cloud : Nextcloud (a cloud service) @@ -62,7 +60,7 @@ This might look prettier for end users, but is generally considered more complic If all apps from the previous example were installed on a separate domain, this would give something like this: -```bash +```text blog.yolo.com : Wordpress (a blog) cloud.yolo.com : Nextcloud (a cloud service) rss.yolo.com : TinyTiny RSS (a RSS reader) @@ -109,8 +107,8 @@ You can also delete the application from this page. From the command line, you can change: -* the app's label in the SSO: `yunohost app change-label ` -* the app's url: `yunohost app change-url app [-d ] [-p ]` +- the app's label in the SSO: `yunohost app change-label ` +- the app's url: `yunohost app change-url app [-d ] [-p ]` You can also delete the app: `yunohost app remove ` @@ -137,7 +135,7 @@ The configuration panels are accessible in the webadmin in their operations page From the command line, you can list the configuration panel settings with the following command: `yunohost app config get ` -``` +```bash $ yunohost app config get my_webapp main.php_fpm_config.phpversion: ask: PHP version @@ -161,6 +159,7 @@ The `` is the setting name, for example `main.sftp.with_sftp` from above. Starting YunoHost v11.1.21.4, if you need to execute commands with the app's binary, or PHP commands, etc., you can execute the command `yunohost app shell `. It will: + - open a new Bash shell as the app's system user - open the app's working directory (e.g. `/var/www/`) - preload the environment with variables taken from the app's service, if it exists @@ -170,11 +169,10 @@ It will: Applications must be packaged manually by application packagers/maintainers. Apps can be integrated with YunoHost to support upgrades, backup/restore and LDAP/SSO integration among other things. -If you want to learn or contribute to app packaging, please check the [contributor documentation](/contributordoc). +If you want to learn or contribute to app packaging, please check the [contributor documentation](/contributordoc). ### Integration and quality levels Automated tests are being run regularly to test the integration and quality of all apps who were declared to be `working` by packagers. The result is a level between 0 and 8, whose meaning is detailed on [this page](/packaging_apps_levels). Some tests results may also be available [on this dashboard](https://dash.yunohost.org/appci/branch/stable). By default, only applications of sufficient quality are offered. When the quality of an application drops and until the problem is reolved, the app is hidden from the catalog to prevent its installation and its upgrades are put on hold. - diff --git a/pages/02.administer/15.admin_guide/35.nginx/nginx.md b/pages/02.administer/15.admin_guide/35.nginx/nginx.md index 256591bc..e1891fc5 100644 --- a/pages/02.administer/15.admin_guide/35.nginx/nginx.md +++ b/pages/02.administer/15.admin_guide/35.nginx/nginx.md @@ -16,11 +16,9 @@ Most of the web applications installed with YunoHost will automatically have the Generally, you should refrain from manually tinkering and installing apps, except if you are sure they will not interfere with your server. YunoHost proposes two generic apps to help you out: - If you already have a website ready to be deployed, consider using a **Custom Webapp**. It allows you to easily setup a directory into which you can upload your HTML, PHP, CSS, JS files with SFTP, and a database if needed. - - If you want to use YunoHost as a reverse proxy, i.e. serve an app from another server or an internal web server (think NodeJS, Ruby, Python, ...), you can use the **Redirect app** in proxy mode. - - The **Redirect app** can also simply run in redirect mode, for example to create shortcuts for your users in their SSO page, or redirect `www.yourdomain.tld` to `yourdomain.tld`. For more information on these apps, and for more application use cases, have a look to the [Tutorials](/tutorials) section. -!! Do not try to install Apache or other public web servers. This will break your system. \ No newline at end of file +!! Do not try to install Apache or other public web servers. This will break your system. diff --git a/pages/02.administer/15.admin_guide/40.xmpp/xmpp.es.md b/pages/02.administer/15.admin_guide/40.xmpp/xmpp.es.md index 2cfd454e..32c61d10 100644 --- a/pages/02.administer/15.admin_guide/40.xmpp/xmpp.es.md +++ b/pages/02.administer/15.admin_guide/40.xmpp/xmpp.es.md @@ -11,9 +11,9 @@ routes: YunoHost está instalado con un servidor de mensajería instantánea Metronome que implementa el [protocolo XMPP](https://es.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol). -XMPP es un protocolo abierto y extensible que también permite crear salones de discusión, compartir status y datos, echar llamadas en VoIP y hacer videoconferencias. +XMPP es un protocolo abierto y extensible que también permite crear salones de discusión, compartir status y datos, echar llamadas en VoIP y hacer videoconferencias. -Todas las aplicaciones basadas en XMPP son compatibles entre ellas : cuando utilizas un cliente XMPP puedes discutir con cualquier persona que tenga una cuenta XMPP/Jabber. Este protocolo ya es utilizado por millones de personas en el mundo. +Todas las aplicaciones basadas en XMPP son compatibles entre ellas : cuando utilizas un cliente XMPP puedes discutir con cualquier persona que tenga una cuenta XMPP/Jabber. Este protocolo ya es utilizado por millones de personas en el mundo. ## Cuenta XMPP/Jabber @@ -27,4 +27,4 @@ Prosody, un servidor XMPP alternativo, está empaquetado para YunoHost. En particular, lo utilizan el plugin de chat Peertube y Jitsi para las videoconferencias. Estas aplicaciones instalará Prosody, que requiere que Metronome esté desactivado para funcionar. -! En pocas palabras, la instalación de Prosody o de una aplicación que dependa de ella desactivará el servidor XMPP. \ No newline at end of file +! En pocas palabras, la instalación de Prosody o de una aplicación que dependa de ella desactivará el servidor XMPP. diff --git a/pages/02.administer/15.admin_guide/40.xmpp/xmpp.fr.md b/pages/02.administer/15.admin_guide/40.xmpp/xmpp.fr.md index c5ca9de5..509fb561 100644 --- a/pages/02.administer/15.admin_guide/40.xmpp/xmpp.fr.md +++ b/pages/02.administer/15.admin_guide/40.xmpp/xmpp.fr.md @@ -29,4 +29,4 @@ Prosody, un serveur XMPP alternatif, est packagé pour YunoHost. Il est notamment utilisé par le plugin de chat de Peertube, et Jitsi pour des vidéoconférences. Installer ces apps installera Prosody, qui nécessite de désactiver Metronome pour fonctionner. -! En résumé, installer Prosody ou une app en dépendant désactivera le serveur XMPP. \ No newline at end of file +! En résumé, installer Prosody ou une app en dépendant désactivera le serveur XMPP. diff --git a/pages/02.administer/15.admin_guide/40.xmpp/xmpp.md b/pages/02.administer/15.admin_guide/40.xmpp/xmpp.md index 9256b279..3da63c2e 100644 --- a/pages/02.administer/15.admin_guide/40.xmpp/xmpp.md +++ b/pages/02.administer/15.admin_guide/40.xmpp/xmpp.md @@ -31,4 +31,4 @@ Prosody, an alternative XMPP server, is packaged for YunoHost. It is notably used by Peertube's chat feature, and Jitsi for video conferences. Installing these apps will install Prosody, which needs to disable Metronome to work properly. -! In summary, installing Prosody or an app relying on it will disable the XMPP server. \ No newline at end of file +! In summary, installing Prosody or an app relying on it will disable the XMPP server. diff --git a/pages/02.administer/15.admin_guide/45.emails/email.de.md b/pages/02.administer/15.admin_guide/45.emails/email.de.md index c6cd979f..16e3d616 100644 --- a/pages/02.administer/15.admin_guide/45.emails/email.de.md +++ b/pages/02.administer/15.admin_guide/45.emails/email.de.md @@ -17,16 +17,16 @@ E-Mail ist ein kompliziertes Ökosystem und eine ganze Reihe von Details können Um Ihre Einstellungen zu validieren: -- Wenn Sie zu Hause selbst hosten und kein VPN verwenden, stellen Sie sicher das [Ihr ISP den Port 25 nicht blockiert](https://yunohost.org/#/isp); -- leiten Sie Ports weiter, wie in [dieser Dokumentation](https://yunohost.org/#/isp_box_config) beschrieben; -- Mail-DNS-Einträge nach [dieser Dokumentation](https://yunohost.org/#/dns_config) sorgfältig konfigurieren; +- Wenn Sie zu Hause selbst hosten und kein VPN verwenden, stellen Sie sicher das [Ihr ISP den Port 25 nicht blockiert](/isp); +- leiten Sie Ports weiter, wie in [dieser Dokumentation](/isp_box_config) beschrieben; +- Mail-DNS-Einträge nach [dieser Dokumentation](/dns_config) sorgfältig konfigurieren; - testen Sie Ihre Konfiguration mit [Mail-tester.com](https://mail-tester.com/) (Vorsicht : nur 3 Tests pro Domain und Tag sind erlaubt) ; Eine Punktzahl von mindestens 8~9/10 ist ein angemessenes Ziel. ## E-Mail-Programme -Um mit dem E-Mail-Server zu interagieren (E-Mails lesen und senden), können Sie entweder einen Webclient wie Roundcube oder Rainloop auf Ihrem Server installieren - oder einen Desktop-/Mobil-Client, wie auf [dieser Seite](https://yunohost.org/#/email_configure_client) beschrieben, konfigurieren. +Um mit dem E-Mail-Server zu interagieren (E-Mails lesen und senden), können Sie entweder einen Webclient wie Roundcube oder Rainloop auf Ihrem Server installieren - oder einen Desktop-/Mobil-Client, wie auf [dieser Seite](/email_configure_client) beschrieben, konfigurieren. Desktop- und Mobil-Clients haben den Vorteil, dass sie Ihre E-Mails auf das Gerät kopieren, was eine Offline-Anzeige und einen relativen Schutz gegen mögliche Hardware-Ausfälle Ihres Servers ermöglicht. @@ -42,9 +42,8 @@ Wenn Ihr Server nicht mehr verfügbar ist, bleiben die an Ihren Server gesendete ## Formulare zum Entfernen seiner IP-Adresse von der schwarzen Liste -Es ist möglich, dass die von Ihrer YunoHost-Instanz gesendeten E-Mails von den großen E-Mail-Diensten als Spam betrachtet werden. Ist es möglich, dass die IP-Adresse von Ihrem Server bereits früher zum Versenden von Spam verwendet wurde oder dass diese E-Mail-Dienste Ihren Server als Spam-Versender betrachten? Um sicherzustellen, dass die IP-Adresse Ihrer Server nicht in diese schwarzen Listen aufgenommen wird und um sie aus diesen zu entfernen, folgen Sie [diesem Link](https://yunohost.org/#/blacklist_forms). +Es ist möglich, dass die von Ihrer YunoHost-Instanz gesendeten E-Mails von den großen E-Mail-Diensten als Spam betrachtet werden. Ist es möglich, dass die IP-Adresse von Ihrem Server bereits früher zum Versenden von Spam verwendet wurde oder dass diese E-Mail-Dienste Ihren Server als Spam-Versender betrachten? Um sicherzustellen, dass die IP-Adresse Ihrer Server nicht in diese schwarzen Listen aufgenommen wird und um sie aus diesen zu entfernen, folgen Sie [diesem Link](/blacklist_forms). ## Eine Migration von E-Mails von einem E-Mail-Provider zu einer YunoHost-Instanz -Siehe [diese Seite](https://yunohost.org/#/email_migration). - +Siehe [diese Seite](/email_migration). diff --git a/pages/02.administer/15.admin_guide/45.emails/email.es.md b/pages/02.administer/15.admin_guide/45.emails/email.es.md index 7bbcc224..5b6a59a4 100644 --- a/pages/02.administer/15.admin_guide/45.emails/email.es.md +++ b/pages/02.administer/15.admin_guide/45.emails/email.es.md @@ -16,6 +16,7 @@ Este ecosistema comprende un servidor SMTP (postfix), un servidor IMAP (Dovecot) Los emails son un ecosistema complicado y una multitud de detalles puedes impedir que funcionen correctamente. Para validar que tu configuración es correcta : + - si te alojas en casa y que no tienes VPN, asegúrate de que [tu proveedor de Internet no esté bloqueando el puerto 25](/isp) ; - redirige los puertos siguiendo [esta documentación](/isp_box_config) ; - configura con cuidado los registros DNS del correo electrónico siguiendo [esta documentación](/dns_config) ; @@ -23,13 +24,13 @@ Para validar que tu configuración es correcta : Una nota de al menos 8~9/10 es un objetivo razonable. -## Clientes de mensajería +## Clientes de mensajería -Para interactuar con el servidor de mail, o sea leer y mandar emails, puedes instalar un cliente web como Roundcube o Rainloop en tu servidor - o configurar un cliente de Desktop o móvil como descrito en [esta página][cette page](/email_configure_client). +Para interactuar con el servidor de mail, o sea leer y mandar emails, puedes instalar un cliente web como Roundcube o Rainloop en tu servidor - o configurar un cliente de Desktop o móvil como descrito en [esta página](/email_configure_client). Los clientes Desktop o móvil tienen la ventaja de copiar tu emails en el equipo, así permitiendo la consulta desconectada de tus mensajes, y cierta protección frente a la posibilidad de un servidor averiado. -## Configuration de los aliases de mensajeras y de las redirecciones automáticas +## Configuration de los aliases de mensajeras y de las redirecciones automáticas Aliases de mensajeras y redirecciones pueden ser configurados por cada usuario. Por ejemplo, el primer usuario creado en el servidor automáticamente dispone de un alias `root@tu.dominio.tld` - lo que significa que un email mandado hacia esta dirección se encontrará en el buzón de entrada de este usuario. Las redirecciones automáticas pueden ser configuradas, por ejemplo si un usuario no quiere configurar una cuenta de correo adicional y simplemente desea recibir correos del servidor en - por ejemplo - su dirección gmail. @@ -37,7 +38,7 @@ Otra función desconocida es el uso del sufijo "+". Por ejemplo, email mandados ## ¿ Qué ocurre si mi servidor se pone indisponible ? -Si tu servidor se pone indisponible, los correos electrónicos mandados a tu servir se quedarán en una fila de espera por el lado del expedidor durante aproximadamente 5 días. El proveedor de hosting del expedidor intentará mandarte regularmente el correo, hasta que lo tire si no lo puede enviar. +Si tu servidor se pone indisponible, los correos electrónicos mandados a tu servir se quedarán en una fila de espera por el lado del expedidor durante aproximadamente 5 días. El proveedor de hosting del expedidor intentará mandarte regularmente el correo, hasta que lo tire si no lo puede enviar. ## Más información diff --git a/pages/02.administer/15.admin_guide/45.emails/email.fr.md b/pages/02.administer/15.admin_guide/45.emails/email.fr.md index 3a9dd3c3..0a635fe2 100644 --- a/pages/02.administer/15.admin_guide/45.emails/email.fr.md +++ b/pages/02.administer/15.admin_guide/45.emails/email.fr.md @@ -16,6 +16,7 @@ Cet écosystème comprend un serveur SMTP (postfix), un serveur IMAP (Dovecot), Les emails sont un écosystème compliqué et un grand nombre de détails peuvent les empêcher de fonctionner correctement. Pour valider que votre configuration est correcte : + - si vous vous hébergez chez vous et n'utilisez pas de VPN, assurez-vous que [votre FAI ne bloque pas le port 25](/isp) ; - routez les ports selon [cette documentation](/isp_box_config) ; - configurez soigneusement les enregistrements DNS du courrier électronique selon [cette documentation](/dns_config) ; diff --git a/pages/02.administer/15.admin_guide/45.emails/email.md b/pages/02.administer/15.admin_guide/45.emails/email.md index 5a9bea26..cb61758f 100644 --- a/pages/02.administer/15.admin_guide/45.emails/email.md +++ b/pages/02.administer/15.admin_guide/45.emails/email.md @@ -16,10 +16,11 @@ The mail stack includes a SMTP server (postfix), an IMAP server (Dovecot), an an Email is a complicated ecosystem and quite a few details can prevent it from working properly. To validate your setup: + - if you are self-hosting at home and not using a VPN, ensure [your ISP won't block port 25](/isp) ; - route ports according to [this documentation](/isp_box_config) ; - carefully configure mail DNS records according to [this documentation](/dns_config) ; -- test your configuration using the diagnostic features (`Webadmin > Diagnosis > Email`). You can also use [mail-tester.com](https://mail-tester.com), a score of at least 8~9/10 is a reasonnable goal (be careful : only 3 tests per domain per day are allowed) +- test your configuration using the diagnostic features (`Webadmin > Diagnosis > Email`). You can also use [mail-tester.com](https://mail-tester.com), a score of at least 8~9/10 is a reasonnable goal (be careful : only 3 tests per domain per day are allowed) ## Email clients @@ -40,6 +41,7 @@ Groups also can use alias features, by default the group `admins` have `root@ Archives locales` et en cliquant sur `Nouvelle sauvegarde`. Vous pourrez ensuite sélectionner les éléments à sauvegarder (configuration, données "système", applications). - ![Image de l'écran de sauvegarde de YunoHost dans la webadmin](image://backup.png) [/ui-tab] @@ -38,26 +37,31 @@ Vous pouvez facilement créer des archives depuis la webadmin en allant dans `Sa Vous pouvez créer de nouvelles archives depuis la ligne de commande. Voici quelques exemples de commandes et leur comportement correspondant : - Tout sauvegarder (système et apps) : + ```bash yunohost backup create ``` - Sauvegarder seulement les apps : + ```bash yunohost backup create --apps ``` - Sauvegarder seulement deux apps (WordPress et Shaarli) : + ```bash yunohost backup create --apps wordpress shaarli ``` - Sauvegarder seulement les mails : + ```bash yunohost backup create --system data_mail ``` - Sauvegarder les mails et WordPress : + ```bash yunohost backup create --system data_mail --apps wordpress ``` @@ -68,6 +72,7 @@ Pour plus d'informations et d'options sur la création d'archives, consultez `yu [/ui-tabs] #### Télécharger la sauvegarde + [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="À partir de l'interface web"] Après avoir créé des sauvegardes, il est possible de les lister et de les inspecter grâce aux vues correspondantes dans l'interface d'administration web. Un bouton propose de télécharger l'archive. Si l'archive fait plus de 3Go, il peut être préférable de procéder via SFTP. @@ -101,14 +106,12 @@ scp -P port_ssh admin@votre.domaine.tld:/home/yunohost.backup/archives/ Archives locales` et sélectionnez l'archive. Vous pou ![](image://restore.png) - [/ui-tab] [ui-tab title="À partir de la ligne de commande"] @@ -147,6 +150,7 @@ Vous pouvez ensuite exécuter `yunohost backup restore ` (donc sans Pour restaurer une application, le domaine sur laquelle elle est installée doit déjà être configuré (ou il vous faut restaurer en même temps la configuration correspondante). Aussi, il n'est pas possible de restaurer une application déjà installée... ce qui veut dire que pour restaurer une sauvegarde d'une app, il vous faut déjà la désinstaller. #### Téléverser une archive + Dans de nombreux cas, l'archive n'est pas sur le serveur sur lequel on souhaite la restaurer. Il faut donc la téléverser, ce qui selon son poids peut prend plus ou moins de temps. [ui-tabs position="top-left" active="0" theme="lite"] @@ -175,15 +179,15 @@ scp -P port_ssh /path/to/your/.tar admin@your.domain.tld:/home/yu Il existe 3 applications YunoHost qui proposent d'étendre YunoHost avec une méthode de sauvegarde automatisées. - * [BorgBackup](/backup/borgbackup) - * [Restic](/backup/restic) - * [Archivist](/backup/archivist) +- [BorgBackup](/backup/borgbackup) +- [Restic](/backup/restic) +- [Archivist](/backup/archivist) ## Aller plus loin - * [Évaluer la qualité de sa sauvegarde](/backup/strategies) - * [Cloner son système de fichier](/backup/clone_filesystem) - * [Éviter une panne matérielle](/backup/avoid_hardware_failure) - * [Inclure/exclure des fichiers](/backup/include_exclude_files) - * [Méthodes personnalisées](/backup/custom_backup_methods) - * [Migrer ou fusionner des serveurs](/backup/migrate_or_merge_servers) +- [Évaluer la qualité de sa sauvegarde](/backup/strategies) +- [Cloner son système de fichier](/backup/clone_filesystem) +- [Éviter une panne matérielle](/backup/avoid_hardware_failure) +- [Inclure/exclure des fichiers](/backup/include_exclude_files) +- [Méthodes personnalisées](/backup/custom_backup_methods) +- [Migrer ou fusionner des serveurs](/backup/migrate_or_merge_servers) diff --git a/pages/02.administer/15.admin_guide/50.backups/backup.it.md b/pages/02.administer/15.admin_guide/50.backups/backup.it.md index 1b9fa5c1..90bf638b 100644 --- a/pages/02.administer/15.admin_guide/50.backups/backup.it.md +++ b/pages/02.administer/15.admin_guide/50.backups/backup.it.md @@ -29,7 +29,6 @@ Potete creare gli archivi di backup dalla pagina web di amministrazione andando Potete fare un nuovo archivio di backup dalla riga di comando. Questi sono alcuni esempi di comandi e i relativi risultati: - - Esecuzione di un backup completo (tutti i componenti del sistema e delle app): ```bash @@ -62,7 +61,6 @@ Potete fare un nuovo archivio di backup dalla riga di comando. Questi sono alcun Per maggiori informazioni e opzioni sulla creazione di backup leggete `yunohost backup create --help`. Potrete anche elencare le parti del sistema delle quali si può farne il backup con `yunohost hook list backup`. - ### Configurazioni specifiche per le app Alcune app come ad esempio Nextcloud possono contenere grandi quantità di dati. È possibile in questi casi eseguire il backup dell'app senza i dati degli utenti, modalità che viene indicata come "backing up only the core" (delle app). @@ -70,7 +68,6 @@ Eseguendo un aggiornamento, delle app con grandi quantità di dati normalmente v Per disabilitare esplicitamente il backup di grandi quantità di dati, per le applicazioni che implementano questa possibilità, dovete impostare la variabile `BACKUP_CORE_ONLY` prima di eseguire il comando di backup: `sudo BACKUP_CORE_ONLY=1 yunohost backup create --apps nextcloud`. Fate attenzione però perché dovrete fare il backup di questi dati autonomamente: è possibile eseguire questi backup, di tipo incrementale o differenziale, opzione che però non è ancora provvista da YunoHost. - ## Download e upload dei backup Dopo aver creato gli archivi di backup è possibile elencarli e ispezionarli sia dalla pagina web di amministrazione relativa sia dalla riga di comando con i comandi `yunohost backup list` e `yunohost backup info `. Di default i backup sono copiati nella directory `/home/yunohost.backup/archives/`. @@ -79,7 +76,6 @@ Attualmente il modo più semplice per scaricare gli archivi è usando il program Una soluzione alternativa è quella di installare Nextcloud o un'applicazione simile e configurarle per accedere ai file contenuti in `/home/yunohost.backup/archives/` da un browser. - Un'altra soluzione è quella di usare `scp` (un programma che si basa su [`ssh`](/ssh)) per copiare i file fra due computer usando la riga di comando. In questo modo usando un computer con GNU/Linux potete copiare uno specifico backup con questo comando: ```bash @@ -110,34 +106,29 @@ scp -P porta_ssh /path/to/your/.tar admin@your.domain.tld:/home/yun Dovete andare in Backup > Archivi locali e selezionare il vostro archivio. È possibile selezionare ciò che volete ripristinare e poi cliccare su 'Ripristina'. - ![picture of YunoHost's restore pannel](image://restore.png) ### Dalla riga di comando Dalla riga di comando date il comando `yunohost backup restore ` (senza il `.tar.gz`) per ripristinare un archivio. Così come `yunohost backup create`, questo comando ripristinerà di default tutto il contenuto dell'archivio; se invece volete ripristinare solo alcuni file potete usare ad esempio il comando `yunohost backup restore --apps wordpress` per ripristinare esclusivamente wordpress. - ### Limiti Per ripristinare una app, il dominio sul quale era stata installata dovrà essere già stato configurato oppure dovrete avere già ripristinato la configurazione di sistema relativa. Inoltre non è possibile ripristinare una app che è già installata ... il che comporta che se volete ripristinare una versione passata della app dovrete prima disinstallarla. - ### Ripristino durante il postinstall È possibile ripristinare un archivio completo *invece* di eseguire il passaggio di postinstall. Questo è utile se volete reinstallare un sistema interamente da un backup preesistente. Per fare questo dovrete copiare l'archivio sul server nella directory `/home/yunohost.backup/archives` e poi, **invece di dare il comando** `yunohost tools postinstall` darete il comando: - ```bash yunohost backup restore ``` Nota: se il vostro archivio non si trova in `/home/yunohost.backup/archives` potete specificare il path giusto con: - ```bash yunohost backup restore /path/to/ -``` +``` ## Ulteriori possibilità @@ -145,7 +136,6 @@ yunohost backup restore /path/to/ Potete connettere e montare un disco esterno per tenerci gli archivi di backup (oltre a tutto il resto): per fare questo prima spostate gli archivi e poi aggiungete un link simbolico. - ```bash PATH_TO_DRIVE="/media/my_external_drive" # Come esempio, dipende da dove monterete il vostro disco mv /home/yunohost.backup/archives $PATH_TO_DRIVE/yunohost_backup_archives @@ -169,7 +159,6 @@ chmod +x /etc/cron.weekly/backup-wordpress Prestate attenzione a ciò di cui fate il backup e quando perché altrimenti è possibile esaurire lo spazio del vostro disco eseguendo, ad esempio, 30 Gb di backup ogni giorno. - #### Backup del server su un server remoto Potete seguire questo tutorial sul forum per impostare Borg fra due server: @@ -181,9 +170,10 @@ Alternativamente, la app Archivist permette di impostare un sistema simile: .tar admin@your.domain.tld:/home/yun There are 3 YunoHost applications that offer to extend YunoHost with an automated backup method. - * [BorgBackup](/backup/borgbackup) - * [Restic](/backup/restic) - * [Archivist](/backup/archivist) +- [BorgBackup](/backup/borgbackup) +- [Restic](/backup/restic) +- [Archivist](/backup/archivist) ## Go further - * [Evaluate the quality of your backup](/backup/strategies) - * [Clone your file system](/backup/clone_filesystem) - * [Avoid a hardware failure](/backup/avoid_hardware_failure) - * [Include/exclude files](/backup/include_exclude_files) - * [Custom methods](/backup/custom_backup_methods) - * [Migrate or merge servers](/backup/migrate_or_merge_servers) - - +- [Evaluate the quality of your backup](/backup/strategies) +- [Clone your file system](/backup/clone_filesystem) +- [Avoid a hardware failure](/backup/avoid_hardware_failure) +- [Include/exclude files](/backup/include_exclude_files) +- [Custom methods](/backup/custom_backup_methods) +- [Migrate or merge servers](/backup/migrate_or_merge_servers) diff --git a/pages/02.administer/15.admin_guide/55.upgrade/10.stretch_buster_migration/stretch_buster_migration.fr.md b/pages/02.administer/15.admin_guide/55.upgrade/10.stretch_buster_migration/stretch_buster_migration.fr.md index 317d3746..b308c36c 100644 --- a/pages/02.administer/15.admin_guide/55.upgrade/10.stretch_buster_migration/stretch_buster_migration.fr.md +++ b/pages/02.administer/15.admin_guide/55.upgrade/10.stretch_buster_migration/stretch_buster_migration.fr.md @@ -19,13 +19,13 @@ L'objectif cette page est de décrire le processus de migration d'une instance e ## Procédure de migration -#### Depuis la webadmin +### Depuis la webadmin Après avoir mis à jour vers la version en 3.8.5.x, allez dans Outils > Migrations pour accéder à l'interface de migration. Il vous faudra ensuite lire l'avertissement attentivement et l'accepter pour lancer la migration. -#### Depuis la ligne de commande +### Depuis la ligne de commande -Après avoir mis à jour vers la version 3.8.5.x, lancez : +Après avoir mis à jour vers la version 3.8.5.x, lancez : ```bash sudo yunohost tools migrations migrate @@ -37,25 +37,25 @@ puis lisez attentivement l'avertissement et les instructions. En fonction de votre matériel et des paquets installés, la migration peut prendre jusqu'à une ou deux heures. -Les logs seront affichés dans la barre de message en haut (vous pouvez approcher la souris dessus pour voir l'historique en entier). Ils seront également consultable après coup (comme les autres opérations) dans Outils > Journaux. +Les logs seront affichés dans la barre de message en haut (vous pouvez approcher la souris dessus pour voir l'historique en entier). Ils seront également consultable après coup (comme les autres opérations) dans Outils > Journaux. Notez que même si vous fermez la page d'admin, la migration continuera (par contre l'interface d'admin sera partiellement indisponible). -#### Si la migration a crashé / échoué à un moment. +### Si la migration a crashé / échoué à un moment Si la migration a échoué a un moment donné, la première chose à faire est de tenter de la relancer. Si cela ne fonctionne toujours pas, il vous faut [trouver de l'aide](/help) (prière de fournir le/les messages correspondants ou tout élément qui vous fait penser que ça n'a pas marché). ## Choses à vérifier après la migration -#### Vérifiez que vous êtes véritablement sous Debian Buster / YunoHost 4.x +### Vérifiez que vous êtes véritablement sous Debian Buster / YunoHost 4.x Pour cela, vous pouvez aller dans la partie Diagnostic (section Système de base). (Vous pouvez aussi regarder ce qui est affiché à droite dans le pied de page de la webadmin). En ligne de commande, vous pouvez aussi utiliser `lsb_release -a` et `yunohost --version`. -#### Vérifiez que le diagnostic ne rapporte pas de problème particulier +### Vérifiez que le diagnostic ne rapporte pas de problème particulier Également dans la section Diagnostic de la webadmin, vérifiez qu'il n'y a pas de problème apparu suite à la migration (par exemple un service qui ne tournerais plus...) -#### Vérifiez que les applications fonctionnent +### Vérifiez que les applications fonctionnent Vérifiez que vos applications installées fonctionnent... Si elles ne fonctionnent pas, il est recommandé de tenter de les mettre à jour. (ou bien de manière générale, il est recommandé de les mettre à jour même si elles fonctionnent !). diff --git a/pages/02.administer/15.admin_guide/55.upgrade/10.stretch_buster_migration/stretch_buster_migration.md b/pages/02.administer/15.admin_guide/55.upgrade/10.stretch_buster_migration/stretch_buster_migration.md index 138bbdc0..e7498578 100644 --- a/pages/02.administer/15.admin_guide/55.upgrade/10.stretch_buster_migration/stretch_buster_migration.md +++ b/pages/02.administer/15.admin_guide/55.upgrade/10.stretch_buster_migration/stretch_buster_migration.md @@ -19,13 +19,13 @@ This page is dedicated to help you migrating an instance from YunoHost 3.8.x (ru ## Migration procedure -#### From the webadmin +### From the webadmin -After upgrading to 3.8.5.x, go to Tools > Migrations to access the migrations interface. You will have to read carefully and accept the disclaimer then launch the migration. +After upgrading to 3.8.5.x, go to Tools > Migrations to access the migrations interface. You will have to read carefully and accept the disclaimer then launch the migration. -#### From the command line +### From the command line -After upgrading to 3.8.5.x, run : +After upgrading to 3.8.5.x, run: ```bash sudo yunohost tools migrations migrate @@ -35,33 +35,33 @@ then read carefully and accept the disclaimer. ## During the migration -Depending on your hardware and packages installed, the migration might take up to a few hours. +Depending on your hardware and packages installed, the migration might take up to a few hours. The logs will be shown in the message bar (you can hover it to see the whole history). They will also be available after the migration (like any other operations) in Tools > Logs. Note that even if you close the webadmin page for some reason, the migration will continue in the background (but the webadmin will be partially unavailable). -#### If the migration crashed / failed at some point. +### If the migration crashed / failed at some point If the migration failed at some point, it should be possible to relaunch it. If it still doesn't work, you can try to [get help](/help) (please provide the corresponding messages or whatever makes you tell that it's not working). ## What to do after the upgrade -#### Check that you actually are on Debian Buster and YunoHost 4.x +### Check that you actually are on Debian Buster and YunoHost 4.x For this, go in Diagnosis (category Base system) or look at the footer of the webadmin. In the command line, you can use `lsb_release -a` and `yunohost --version`. -#### Check that no issue appeared in the diagnosis +### Check that no issue appeared in the diagnosis Also in the Diagnosis in the webadmin, make sure that no specific issue appeared after running the migration (for example a service that crashed for some reason). -#### Check that your applications are working +### Check that your applications are working Test that your applications are working. If they aren't, you should try to upgrade them (it is also a good idea to upgrade them even if they are working anyway). ## Current known (minor) issues after the migration -- Some file (`/etc/nsswitch.conf` and `/etc/nslcd.conf`) will appear as manually modified after the migration. You can safely apply the regen-conf with: +- Some file (`/etc/nsswitch.conf` and `/etc/nslcd.conf`) will appear as manually modified after the migration. You can safely apply the regen-conf with: ```bash yunohost tools regen-conf nsswitch nslcd --force diff --git a/pages/02.administer/15.admin_guide/55.upgrade/15.buster_bullseye/buster_bullseye_migration.fr.md b/pages/02.administer/15.admin_guide/55.upgrade/15.buster_bullseye/buster_bullseye_migration.fr.md index 7bfda98f..6a6165b6 100644 --- a/pages/02.administer/15.admin_guide/55.upgrade/15.buster_bullseye/buster_bullseye_migration.fr.md +++ b/pages/02.administer/15.admin_guide/55.upgrade/15.buster_bullseye/buster_bullseye_migration.fr.md @@ -19,13 +19,13 @@ L'objectif cette page est de décrire le processus de migration d'une instance e ## Procédure de migration -#### Depuis la webadmin +### Depuis la webadmin Après avoir mis à jour vers la version en 4.4.x, allez dans Outils > Migrations pour accéder à l'interface de migration. Il vous faudra ensuite lire l'avertissement attentivement et l'accepter pour lancer la migration. -#### Depuis la ligne de commande +### Depuis la ligne de commande -Après avoir mis à jour vers la version 4.4.x, lancez : +Après avoir mis à jour vers la version 4.4.x, lancez : ```bash sudo yunohost tools migrations migrate @@ -37,57 +37,57 @@ puis lisez attentivement l'avertissement et les instructions. En fonction de votre matériel et des paquets installés, la migration peut prendre jusqu'à une ou deux heures. -Les logs seront affichés dans la barre de message au centre de la page (vous pouvez approcher la souris dessus pour voir l'historique en entier). Ils seront également consultable après coup (comme les autres opérations) dans Outils > Journaux. +Les logs seront affichés dans la barre de message au centre de la page (vous pouvez approcher la souris dessus pour voir l'historique en entier). Ils seront également consultable après coup (comme les autres opérations) dans Outils > Journaux. Notez que même si vous fermez la page d'admin, la migration continuera (par contre l'interface d'admin sera partiellement indisponible). -#### Si la migration a crashé / échoué à un moment. +### Si la migration a crashé / échoué à un moment Si la migration a échoué a un moment donné, la première chose à faire est de tenter de la relancer. Si cela ne fonctionne toujours pas, il vous faut [trouver de l'aide](/help) (prière de fournir le/les messages correspondants ou tout élément qui vous fait penser que ça n'a pas marché). ## Choses à vérifier après la migration -#### Exécuter la migration pour réparer votre application python +### Exécuter la migration pour réparer votre application python + Après la mise à jour, vos applications python devraient être indisponibles car leur environnement virtuel doit être reconstruit. Pour ce faire, vous pouvez exécuter les migrations en cours dans `Webadmin > Mises à jour`. Les applications ci-dessous ne seront pas réparées automatiquement, vous devez les mettre à jour manuellement avec `yunohost app upgrade -F APP`. Les applications qui ne seront pas réparées automatiquement et nécessitent une mise à jour forcée : - * calibreweb - * django-for-runners - * ffsync (cette application est en python2 et n'est plus maintenue, aucune garantie) - * jupiterlab - * librephotos - * mautrix - * mediadrop - * mopidy - * pgadmin - * tracim - * synapse - * weblate +- calibreweb +- django-for-runners +- ffsync (cette application est en python2 et n'est plus maintenue, aucune garantie) +- jupiterlab +- librephotos +- mautrix +- mediadrop +- mopidy +- pgadmin +- tracim +- synapse +- weblate ! !! Si nécessaire, vous pouvez désactiver la reconstruction automatique pour une application python spécifique, en supprimant le fichier dédié terminé par `.requirements_backup_for_bullseye_upgrade.txt` avant d'appliquer la migration. Vous pouvez trouver ce fichier près du venv de votre application dans `/opt` ou `/var/www`. -#### Vérifiez que vous êtes véritablement sous Debian Bullseye et YunoHost 11.x +### Vérifiez que vous êtes véritablement sous Debian Bullseye et YunoHost 11.x Pour cela, vous pouvez aller dans la partie Diagnostic (section Système de base). (Vous pouvez aussi regarder ce qui est affiché à droite dans le pied de page de la webadmin). En ligne de commande, vous pouvez aussi utiliser `lsb_release -a` et `yunohost --version`. -#### Vérifiez que le diagnostic ne rapporte pas de problème particulier +### Vérifiez que le diagnostic ne rapporte pas de problème particulier Également dans la section Diagnostic de la webadmin, vérifiez qu'il n'y a pas de problème apparu suite à la migration (par exemple un service qui ne tournerais plus...) -#### Vérifiez que les applications fonctionnent +### Vérifiez que les applications fonctionnent Vérifiez que vos applications installées fonctionnent... Si elles ne fonctionnent pas, il est recommandé de tenter de les mettre à jour. (ou bien de manière générale, il est recommandé de les mettre à jour même si elles fonctionnent !). - Si votre app est cassée et que vous étiez déjà sur la dernière version d'une application, vous pouvez relancer la mise à jour grâce à l'option `--force`: -``` + +```bash yunohost app upgrade --force NOM_APP ``` ## Soucis (mineurs) connus après la migration Voir la [page anglaise](https://yunohost.org/en/buster_bullseye_migration#current-known-minor-issues-after-the-migration) - diff --git a/pages/02.administer/15.admin_guide/55.upgrade/15.buster_bullseye/buster_bullseye_migration.md b/pages/02.administer/15.admin_guide/55.upgrade/15.buster_bullseye/buster_bullseye_migration.md index b62cbd93..d2fc0453 100644 --- a/pages/02.administer/15.admin_guide/55.upgrade/15.buster_bullseye/buster_bullseye_migration.md +++ b/pages/02.administer/15.admin_guide/55.upgrade/15.buster_bullseye/buster_bullseye_migration.md @@ -21,13 +21,13 @@ This page is dedicated to help you migrating an instance from YunoHost 4.4.x (ru ## Migration procedure -#### From the webadmin +### From the webadmin -After upgrading to 4.4.x, go to Tools > Migrations to access the migrations interface. You will have to read carefully and accept the disclaimer then launch the migration. +After upgrading to 4.4.x, go to Tools > Migrations to access the migrations interface. You will have to read carefully and accept the disclaimer then launch the migration. -#### From the command line +### From the command line -After upgrading to 4.4.x, run : +After upgrading to 4.4.x, run: ```bash sudo yunohost tools migrations run @@ -37,63 +37,66 @@ then read carefully and accept the disclaimer. ## During the migration -Depending on your hardware and packages installed, the migration might take up to a few hours. +Depending on your hardware and packages installed, the migration might take up to a few hours. The logs will be shown in the message bar (you can hover it to see the whole history). They will also be available after the migration (like any other operations) in Tools > Logs. Note that even if you close the webadmin page for some reason, the migration will continue in the background (but the webadmin will be partially unavailable). -#### If the migration crashed / failed at some point. +### If the migration crashed / failed at some point If the migration failed at some point, it should be possible to relaunch it. If it still doesn't work, you can try to [get help](/help) (please provide the corresponding messages or whatever makes you say that it's not working). ## What to do after the upgrade -#### Check that you actually are on Debian Bullseye and YunoHost 11.x +### Check that you actually are on Debian Bullseye and YunoHost 11.x For this, go to Diagnosis (category Base system) or look at the footer of the webadmin. In the command line, you can use `lsb_release -a` and `yunohost --version`. -#### Run the migration to repair your python app +### Run the migration to repair your python app + After upgrading, your python apps should be unavailable because their virtual environment (venv) needs to be rebuilt. To do that you can run the pending migrations in `Webadmin > Update`. The apps below won't be automatically repaired, you need to force-upgrade them manually instead with `yunohost app upgrade -F APP`. Apps which won't be automatically repaired and need a force upgrade: - * calibreweb - * django-for-runners - * ffsync (this app is in python2 and no longer maintained, no guarantee) - * jupiterlab - * librephotos - * mautrix - * mediadrop - * mopidy - * pgadmin - * tracim - * synapse - * weblate +- calibreweb +- django-for-runners +- ffsync (this app is in python2 and no longer maintained, no guarantee) +- jupiterlab +- librephotos +- mautrix +- mediadrop +- mopidy +- pgadmin +- tracim +- synapse +- weblate !!! If needed, you can disable the automatic rebuild for a specific python app, by removing the dedicated file ending with `.requirements_backup_for_bullseye_upgrade.txt` before applying the migration. You can find this file near the venv (Python virtual environment) of your app inside `/opt` or `/var/www`. -#### Check that no issue appeared in the diagnosis +### Check that no issue appeared in the diagnosis Also in the webadmin Diagnosis section, make sure that no specific issue appeared after running the migration (for example a service that crashed for some reason). If the service `php7.3-fpm` appears to be dead, you should upgrade your PHP apps like the custom web app. Next, you can run `apt autoremove`. -#### Check that your applications are working +### Check that your applications are working Test that your applications are working. If they aren't, you should try to upgrade them (it is also a good idea to upgrade them even if they are working anyway). If your app is broken and you were already with the latest version, you can rerun the upgrade thanks to the `-F|--force` option: -``` + +```bash yunohost app upgrade --force APP_NAME ``` ## Current known issues after the migration -### Can't run the migration due to `libc6-dev : Breaks: libgcc-8-dev issue`. -Note: This issue should be resolved in yunohost_version: 4.4.2.13 +### Can't run the migration due to `libc6-dev : Breaks: libgcc-8-dev issue` + +Note: This issue should be resolved in `yunohost_version`: `4.4.2.13` You have an app that depends on the `build-essential` package. See this [solution](https://forum.yunohost.org/t/migration-to-11-wont-start-libc6-dev-breaks-libgcc-8-dev/20617/42) to fix it manually @@ -107,18 +110,17 @@ We haven't yet found solution for this issue. ! If you have not yet rebooted your server, don't do it (we are looking for a solution). This will avoid you the use of a keyboard and screen. We found this in the Raspberry Pi documentation -``` -when the dhcpcd5 package is updated to the latest version (1:8.1.2-1+rpt1 -> 1:8.1.2-1+rpt2), the Raspberry Pi will fail to obtain a DHCP IP address following the next reboot or startup. This problem can be avoided by disabling and re-enabling the "System Options -> Network at Boot" option using the latest raspi-config after the dhcpcd5 package has been updated and prior to the system being shutdown or rebooted -``` + +> when the dhcpcd5 package is updated to the latest version (1:8.1.2-1+rpt1 -> 1:8.1.2-1+rpt2), the Raspberry Pi will fail to obtain a DHCP IP address following the next reboot or startup. This problem can be avoided by disabling and re-enabling the "System Options -> Network at Boot" option using the latest raspi-config after the dhcpcd5 package has been updated and prior to the system being shutdown or rebooted If you are using a Raspberry Pi 4 (or maybe 3), see this [solution](https://forum.yunohost.org/t/aucun-acces-a-internet-suite-a-migration-4-4-to-11-depuis-raspberry-pi-4-pi-400/20652/17) ### Restore ynh4 backup onto a fresh ynh11 If you can't restore your app but your system has been restored, you probably should use the regen conf to fix the nginx issues: -``` + +```bash yunohost tools regenconf nginx --force ``` After that you should be able to restore your apps. Don't forget to force upgrade them if you have 502 errors. - diff --git a/pages/02.administer/15.admin_guide/55.upgrade/5.jessie_stretch_migration/jessie_stretch_migration.fr.md b/pages/02.administer/15.admin_guide/55.upgrade/5.jessie_stretch_migration/jessie_stretch_migration.fr.md index 537e0c92..92d2fbdf 100644 --- a/pages/02.administer/15.admin_guide/55.upgrade/5.jessie_stretch_migration/jessie_stretch_migration.fr.md +++ b/pages/02.administer/15.admin_guide/55.upgrade/5.jessie_stretch_migration/jessie_stretch_migration.fr.md @@ -23,13 +23,13 @@ L'objectif cette page est de décrire le processus de migration d'une instance e ## Procédure de migration -#### Depuis la webadmin +### Depuis la webadmin Après avoir mis à jour vers la version 2.7.14, allez dans Outils > Migrations pour accéder à l'interface de migration. Il vous faudra ensuite lire l'avertissement attentivement et l'accepter pour lancer la migration. Les logs seront affichés dans la barre de message en haut (vous pouvez approcher la souris dessus pour voir l'historique en entier). -#### Depuis la ligne de commande +### Depuis la ligne de commande -Après avoir mis à jour vers la version 2.7.14, lancez : +Après avoir mis à jour vers la version 2.7.14, lancez : ```bash sudo yunohost tools migrations migrate @@ -43,24 +43,24 @@ En fonction de votre matériel et des paquets installés, la migration peut pren Notez qu'il est attendu de voir certaines erreurs (en particulier à propos de Fail2Ban) pendant la migration - ne vous en inquiétez pas trop. -#### Si la migration a crashé / échoué à un moment. +### Si la migration a crashé / échoué à un moment Si la migration a échoué a un moment donné, la première chose à faire est de tenter de la relancer. Si cela ne fonctionne toujours pas, il vous faut [trouver de l'aide](/help) (prière de fournir le/les messages correspondants ou tout élément qui vous fait penser que ça n'a pas marché). ## Choses à vérifier après la migration -#### Vérifiez que vous êtes véritablement sous Debian Stretch / YunoHost 3.0 +### Vérifiez que vous êtes véritablement sous Debian Stretch / YunoHost 3.0 Pour cela, allez dans Outils > Diagnostique. (Vous pouvez aussi regarder ce qui est affiché dans le pied de page). En ligne de commande, vous pouvez aussi utiliser `lsb_release -a` et `yunohost --version`. -#### Vérifiez que Fail2Ban et le pare-feu sont actifs. +### Vérifiez que Fail2Ban et le pare-feu sont actifs -Vous devriez voir que Fail2Ban et le firewall sont actifs. Depuis la webadmin, dans Services (chercher 'fail2ban' et 'yunohost-firewall'). Depuis la ligne de commande, faites `yunohost service status fail2ban yunohost-firewall` : les deux devraient être en `active: active`. +Vous devriez voir que Fail2Ban et le firewall sont actifs. Depuis la webadmin, dans Services (chercher `fail2ban` et `yunohost-firewall`). Depuis la ligne de commande, faites `yunohost service status fail2ban yunohost-firewall` : les deux devraient être en `active: active`. -#### Vérifiez que les applications fonctionnent +### Vérifiez que les applications fonctionnent Vérifiez que vos applications installées fonctionnent... Si elles ne fonctionnent pas, il est recommandé de tenter de les mettre à jour. (ou bien de manière générale, il est recommandé de les mettre à jour même si elles fonctionnent !). -#### Si vous utilisez les mails : vérifiez votre score +### Si vous utilisez les mails : vérifiez votre score Si vous utilisez les emails (en particulier les envois), vérifiez que votre score est toujours bon via [mail-tester](https://www.mail-tester.com/) par exemple. diff --git a/pages/02.administer/15.admin_guide/55.upgrade/5.jessie_stretch_migration/jessie_stretch_migration.md b/pages/02.administer/15.admin_guide/55.upgrade/5.jessie_stretch_migration/jessie_stretch_migration.md index 8896e845..fde3c32f 100644 --- a/pages/02.administer/15.admin_guide/55.upgrade/5.jessie_stretch_migration/jessie_stretch_migration.md +++ b/pages/02.administer/15.admin_guide/55.upgrade/5.jessie_stretch_migration/jessie_stretch_migration.md @@ -23,13 +23,13 @@ This page is dedicated to help you migrating an instance from YunoHost 2.7.x (ru ## Migration procedure -#### From the webadmin +### From the webadmin After upgrading to 2.7.14, go to Tools > Migrations to access the migrations interface. You will have to read carefully and accept the disclaimer then launch the migration. The logs will be shown in the message bar (you can hover it to see the whole history). -#### From the command line +### From the command line -After upgrading to 2.7.14, run: +After upgrading to 2.7.14, run: ```bash sudo yunohost tools migrations migrate @@ -39,28 +39,28 @@ then read carefully and accept the disclaimer. ## During the migration -Depending on your hardware and packages installed, the migration might take up to a few hours. +Depending on your hardware and packages installed, the migration might take up to a few hours. Note that it is expected to see some errors (in particular about Fail2Ban) during the migration, so don't worry too much about them. -#### If the migration crashed / failed at some point. +### If the migration crashed / failed at some point If the migration failed at some point, it should be possible to relaunch it. If it still doesn't work, you can try to [get help](/help) (please provide the corresponding messages or whatever makes you tell that it's not working). ## What to do after the upgrade -#### Check that you actually are on Debian Stretch and YunoHost 3.0 +### Check that you actually are on Debian Stretch and YunoHost 3.0 You should be able to see this from the webadmin Tools > Diagnosis, and also in the footer of the page. On the command line, you can use `lsb_release -a` and `yunohost --version`. -#### Check that Fail2Ban and the firewall are active +### Check that Fail2Ban and the firewall are active -You should be able to see that Fail2Ban and the firewall are active. From the webadmin in Services (look for 'fail2ban' and 'yunohost-firewall'). From the command line, run `yunohost service status fail2ban yunohost-firewall`. They should both have `active: active`. +You should be able to see that Fail2Ban and the firewall are active. From the webadmin in Services (look for `fail2ban` and `yunohost-firewall`). From the command line, run `yunohost service status fail2ban yunohost-firewall`. They should both have `active: active`. -#### Check that your applications are working +### Check that your applications are working Test that your applications are working. If they aren't, you should try to upgrade them (it is also a good idea to upgrade them even if they are working anyway). -#### Mail users: check your mail score +### Mail users: check your mail score If you are using mails (especially sending them), check that your score is still good by using [mail-tester](https://www.mail-tester.com/) for example. diff --git a/pages/02.administer/15.admin_guide/55.upgrade/upgrade.fr.md b/pages/02.administer/15.admin_guide/55.upgrade/upgrade.fr.md index e748cd92..26c7b69b 100644 --- a/pages/02.administer/15.admin_guide/55.upgrade/upgrade.fr.md +++ b/pages/02.administer/15.admin_guide/55.upgrade/upgrade.fr.md @@ -19,7 +19,7 @@ Cliquez sur les boutons verts pour lancer les mises à jour du système et des a Voici quelques exemples en ligne de commande correspondants : -``` bash +```bash # Aller chercher les mises à jour disponibles yunohost tools update diff --git a/pages/02.administer/15.admin_guide/55.upgrade/upgrade.md b/pages/02.administer/15.admin_guide/55.upgrade/upgrade.md index 8acb8a8a..05f4e021 100644 --- a/pages/02.administer/15.admin_guide/55.upgrade/upgrade.md +++ b/pages/02.administer/15.admin_guide/55.upgrade/upgrade.md @@ -19,7 +19,7 @@ Click on green upgrade buttons to upgrade the system and applications. Here are some example of corresponding command lines: -``` bash +```bash # Fetch available updates yunohost tools update diff --git a/pages/02.administer/15.admin_guide/admin_guide.de.md b/pages/02.administer/15.admin_guide/admin_guide.de.md index a62af6f6..9b216a8e 100644 --- a/pages/02.administer/15.admin_guide/admin_guide.de.md +++ b/pages/02.administer/15.admin_guide/admin_guide.de.md @@ -10,11 +10,10 @@ routes: Diese Seite bietet eine Übersicht über das Ökosystem eines YunoHost-Servers. Diese Übersicht macht mehrere Vereinfachungen und zielt wesentlich darauf ab, ein globales Bild zu vermitteln, bevor tiefer auf die verschiedenen Aspekte eingegangen wird. - ![](image://ecosystem.png) Alles beginnt mit dem speziellen **admin** Benutzer. Dies ist der Administrator des Computers, der Dinge auf dem Server über die Webverwaltungsoberfläche oder über SSH und die Befehlszeilenschnittstelle installieren, konfigurieren und verwalten kann. *(Wenn du bereits mit GNU / Linux vertraut bist, ist dies root ziemlich ähnlich. YunoHost hat diesen zusätzlichen 'Admin'-Benutzer aus verschiedenen technischen Gründen.)* Der Administrator kann unter anderem Benutzer erstellen und Anwendungen installieren. Benutzer haben, wenn sie erstellt werden, automatisch eine eigene E-Mail-Adresse sowie ein XMPP-Konto. Benutzer können auch eine Verbindung zum Benutzerportal (SSO) herstellen, um auf Anwendungen zuzugreifen. Einige Anwendungen können normalerweise entweder öffentlich zugänglich oder privat installiert werden. Letzteres bedeutes, dass nur einige Benutzer Zugriff darauf haben. -Anwendungen und andere Funktionen des Servers hängen von verschiedenen Diensten ab, damit sie ordnungsgemäß funktionieren. Dienste (manchmal auch als Daemons bezeichnet) sind Programme, die ständig auf dem Server ausgeführt werden. Sie stellen sicher, dass verschiedene Aufgaben, z.B. das Beantworten von Webanfragen von Webbrowsern oder das Weiterleiten von E-Mails, ausgeführt werden. +Anwendungen und andere Funktionen des Servers hängen von verschiedenen Diensten ab, damit sie ordnungsgemäß funktionieren. Dienste (manchmal auch als Daemons bezeichnet) sind Programme, die ständig auf dem Server ausgeführt werden. Sie stellen sicher, dass verschiedene Aufgaben, z.B. das Beantworten von Webanfragen von Webbrowsern oder das Weiterleiten von E-Mails, ausgeführt werden. diff --git a/pages/02.administer/15.admin_guide/admin_guide.md b/pages/02.administer/15.admin_guide/admin_guide.md index 6268f320..8379ec1c 100644 --- a/pages/02.administer/15.admin_guide/admin_guide.md +++ b/pages/02.administer/15.admin_guide/admin_guide.md @@ -17,5 +17,3 @@ Everything starts with the special user **admin**. This is the administrator of The administrator can create users and install applications, among other admin actions. Users automatically have their own email address as well as an XMPP account when they get created. Users will also be able to connect to the user portal (SSO) to access applications. Some applications can typically be installed either as publicly-accessible, or as private, i.e. only some users will have access to it. Applications and their features of the server rely on different services to work properly. Services (sometimes also called daemons) are programs that are constantly running on the server to ensure various tasks are done, such as answering to web requests from web browsers, or relaying emails. - - diff --git a/pages/02.administer/20.backups/05.evaluate/evaluate.fr.md b/pages/02.administer/20.backups/05.evaluate/evaluate.fr.md index 29a67704..30ca8f73 100644 --- a/pages/02.administer/20.backups/05.evaluate/evaluate.fr.md +++ b/pages/02.administer/20.backups/05.evaluate/evaluate.fr.md @@ -13,6 +13,7 @@ page-toc: Dans le contexte de l'auto-hébergement, les sauvegardes (backup) sont un élément important pour pallier les événements inattendus (incendies, corruption de base de données, perte d'accès au serveur, serveur compromis...). La politique de sauvegardes à mettre en place dépend de l'importance des services et des données que vous gérez. Par exemple, sauvegarder un serveur de test aura peu d'intérêt, tandis que vous voudrez montrer beaucoup plus de prudence si vous gérez des données critiques pour une association ou une entreprise - et dans ce genre de cas, vous souhaiterez stocker les sauvegardes *dans un ou des endroits différents*. ## Qu'est-ce qu'une bonne sauvegarde ? + Une bonne sauvegarde est constituée d'au moins **3 copies des données** (en comptant les données originales), sur au moins **2 stockages distincts**, dans au moins **2 lieux distincts** (suffisamment éloignés) et idéalement avec 2 méthodes distinctes. Si vos sauvegardes sont chiffrées **ces règles s'appliquent aussi à la phrase/clé de déchiffrement**. Une bonne sauvegarde est aussi dans de nombreux cas, une sauvegarde récente, il faut donc soit beaucoup de rigueur, soit **automatiser** le processus. @@ -22,43 +23,43 @@ Une bonne sauvegarde est vérifiée régulièrement afin de s'assurer de l'effec Enfin, une bonne sauvegarde est une sauvegarde **restaurable dans des délais acceptables** pour vous. Pensez notamment à documenter votre méthode de restauration et à estimer le temps de transfert d'une copie notamment si les connexions internet en jeu ne sont pas symétriques. !!! Exemple d'**une combinaison** robuste et comfortable: -* une sauvegarde distante et automatique avec borg -* une sauvegarde sur disque externe et automatique avec borg -* un snapshot/image régulier (et avant les mises à jour) -* une grappe RAID 1 monitorée (ou un VPS du commerce qui sera aussi sur une grappe) -* une passphrase de déchiffrement stockée sur 3 supports dans 2 lieux +- une sauvegarde distante et automatique avec borg +- une sauvegarde sur disque externe et automatique avec borg +- un snapshot/image régulier (et avant les mises à jour) +- une grappe RAID 1 monitorée (ou un VPS du commerce qui sera aussi sur une grappe) +- une passphrase de déchiffrement stockée sur 3 supports dans 2 lieux ## Quelques méthodes possibles -* [générer une archive et la télécharger manuellement (méthode par défaut de YunoHost)](/backup#sauvegarde-manuelle) -* [sauvegarder automatiquement (méthode conseillée)](/backup#sauvegarde-automatique-ou-distante) -* [générer une archive directement sur un autre disque](/external_storage) -* [faire une image du disque ou un snapshot](/backup/clone_filesystem) -* [sauvegarder les données utiles via une méthode personnalisée](/backup/custom_backup_methods) +- [générer une archive et la télécharger manuellement (méthode par défaut de YunoHost)](/backup#sauvegarde-manuelle) +- [sauvegarder automatiquement (méthode conseillée)](/backup#sauvegarde-automatique-ou-distante) +- [générer une archive directement sur un autre disque](/external_storage) +- [faire une image du disque ou un snapshot](/backup/clone_filesystem) +- [sauvegarder les données utiles via une méthode personnalisée](/backup/custom_backup_methods) ## Risques -Ci-dessous, une liste de risques triés du plus au moins probable, dont la probabilité reste à adapter selon votre situation (lieu du serveur, qualité des installations, profils d'usagers, etc.). À vous de mettre le curseur là où il faut, notamment en considérant les conséquences d'une perte de données. -!!! Gardez en tête que les vrais accidents sont liés à la survenue de 2 événements de façon simultanée. +Ci-dessous, une liste de risques triés du plus au moins probable, dont la probabilité reste à adapter selon votre situation (lieu du serveur, qualité des installations, profils d'usagers, etc.). À vous de mettre le curseur là où il faut, notamment en considérant les conséquences d'une perte de données. -* **Manque de rigueur**: les stratégies à base de sauvegardes manuelles nécessitent beaucoup de rigueur dans la régularité -* **Mauvaise manipulation**: il peut arriver d'effacer une sauvegarde par erreur lors d'une restauration ou si vous comptez sur un système de synchronisation, vous pourriez supprimer un fichier et que la suppression soit synchronisée de façon instantanée -* **Cryptolocker**: il s'agit de virus qui chiffrent les fichiers et réclament une rançon. Si vos utilisateurs ou utilisatrices utilisent nextcloud et windows, un windows infecté pourrait synchroniser des fichiers chiffrés et ainsi vous perdriez votre copie. -* **Panne matérielle**: les cartes SD sont les supports les moins fiables dans le temps (~2ans de vie dans un serveur), viennent ensuite les disques SSD (environ 3 ans de vie) et les disques durs (3 ans). À noter qu'un équipement neuf a aussi une probabilité non nulle de tomber en panne lors des 6 premiers mois. Dans tous les cas, vos copies ne devraient pas être sur le même support physique. -* **Panne logicielle/bug**: un bug logiciel peut aboutir à la suppression de données ou vous pourriez ne pas savoir réparer un problème et souhaiter restaurer votre système. -* **Panne d'électricité ou d'internet**: avez-vous un plan si ça arrive ? Quid si vous êtes en vacances ? -* **Catastrophe ou événement naturel ou non**: un petit enfant, un chat, la foudre ou une simple fuite peuvent détruire votre matériel. Les incendies ou inondations peuvent aussi mettre à mal votre copie de sauvegarde à l'autre bout de votre logement... -* **Compromission du serveur**: une personne malveillante ou un robot pourrait attaquer votre serveur et supprimer vos données. -* **Vol de machine**: un cambriolage ou le vol d'un ordinateur sur lequel se trouve votre gestionnaire de mots de passe pour déchiffrer vos sauvegardes. -* **Perquisition**: que vous soyez coupable ou non, une perquisition peut aboutir à la saisie entière du matériel informatique d'un lieu (voir de plusieurs lieux). -* **Décès/problème de santé**: vous pourriez ne plus être en mesure de taper votre phrase de passe. +!!! Gardez en tête que les vrais accidents sont liés à la survenue de 2 événements de façon simultanée. + +- **Manque de rigueur**: les stratégies à base de sauvegardes manuelles nécessitent beaucoup de rigueur dans la régularité +- **Mauvaise manipulation**: il peut arriver d'effacer une sauvegarde par erreur lors d'une restauration ou si vous comptez sur un système de synchronisation, vous pourriez supprimer un fichier et que la suppression soit synchronisée de façon instantanée +- **Cryptolocker**: il s'agit de virus qui chiffrent les fichiers et réclament une rançon. Si vos utilisateurs ou utilisatrices utilisent nextcloud et windows, un windows infecté pourrait synchroniser des fichiers chiffrés et ainsi vous perdriez votre copie. +- **Panne matérielle**: les cartes SD sont les supports les moins fiables dans le temps (~2ans de vie dans un serveur), viennent ensuite les disques SSD (environ 3 ans de vie) et les disques durs (3 ans). À noter qu'un équipement neuf a aussi une probabilité non nulle de tomber en panne lors des 6 premiers mois. Dans tous les cas, vos copies ne devraient pas être sur le même support physique. +- **Panne logicielle/bug**: un bug logiciel peut aboutir à la suppression de données ou vous pourriez ne pas savoir réparer un problème et souhaiter restaurer votre système. +- **Panne d'électricité ou d'internet**: avez-vous un plan si ça arrive ? Quid si vous êtes en vacances ? +- **Catastrophe ou événement naturel ou non**: un petit enfant, un chat, la foudre ou une simple fuite peuvent détruire votre matériel. Les incendies ou inondations peuvent aussi mettre à mal votre copie de sauvegarde à l'autre bout de votre logement... +- **Compromission du serveur**: une personne malveillante ou un robot pourrait attaquer votre serveur et supprimer vos données. +- **Vol de machine**: un cambriolage ou le vol d'un ordinateur sur lequel se trouve votre gestionnaire de mots de passe pour déchiffrer vos sauvegardes. +- **Perquisition**: que vous soyez coupable ou non, une perquisition peut aboutir à la saisie entière du matériel informatique d'un lieu (voir de plusieurs lieux). +- **Décès/problème de santé**: vous pourriez ne plus être en mesure de taper votre phrase de passe. ## À propos de la synchronisation Nextcloud ou Thunderbird (IMAP) -Une méthode qui permet une sauvegarde partielle consiste à sauvegarder les fichiers et les emails via des logiciels de synchronisation comme Nextcloud client ou ThunderBird. De cette façon, vous évitez le risque de panne matérielle. + +Une méthode qui permet une sauvegarde partielle consiste à sauvegarder les fichiers et les emails via des logiciels de synchronisation comme Nextcloud client ou ThunderBird. De cette façon, vous évitez le risque de panne matérielle. Si cette méthode est simple à mettre en place, elle n'est pas sans risque du fait de la synchronisation elle-même. Par exemple, si vous êtes sur windows ou mac, vous augmentez de façon non négligeable le risque de perte de données suite au chiffrement des fichiers par un virus de type [cryptolocker](https://fr.wikipedia.org/wiki/Ran%C3%A7ongiciel). Sur tout type de système, une fausse manipulation peut supprimer l'ensemble de vos copies sur le serveur et sur les équipements qui synchronisent. Ce souci est aggravé par le fait que la synchronisation de suppression est en général plutôt instantanée. Si le risque de fausse manipulation peut être atténué via des logiciels de sauvegarde pour PC de bureau comme TimeShift, seule une sauvegarde sur un disque dur externe déconnecté vous protège vraiment des rançongiciels. - - diff --git a/pages/02.administer/20.backups/05.evaluate/evaluate.it.md b/pages/02.administer/20.backups/05.evaluate/evaluate.it.md index 26b518c2..8059a1b3 100644 --- a/pages/02.administer/20.backups/05.evaluate/evaluate.it.md +++ b/pages/02.administer/20.backups/05.evaluate/evaluate.it.md @@ -1,4 +1,4 @@ -# --- +--- title: Strategie di backup template: docs taxonomy: @@ -10,10 +10,10 @@ page-toc: depth: 3 --- - In un contesto di self hosting le strategie di backup sono un fattore chiave per sopperire ad eventi inattesi (incendio, corruzione del database, impossibilità di accedere al server, compromissione del server...). La tipologia di backup da adottare dipende dalla importanza dei dati e dei servizi che vogliamo proteggere. Ad esempio, nel contesto di un server di test possiamo evitare un backup integrale (dati e sistema operativo), al contrario, dovremo porre molta più attenzione nel caso di un server in produzione che contenga dati importanti. In questo caso è necessario conservare più copie di backup *in posti diversi*. ## Ottimizzare il backup + Un buon backuo consiste in almeno **tre copie dei dati** (compreso l'originale), salvate su almeno **due supporti distinti** che si trovano a loro volta **in due luoghi distinti** (sufficientemente lontani tra loro) e con due diversi sistemi di stoccaggio. Se il vostro backup è cifrato **questa regola aurea si applica anche alla password o frase di decifrazione**. Un buon backup deve anche essere recente, dovrete quindi essere molto precisi e quando possibile **automatizzare il processo**. @@ -22,46 +22,44 @@ Controllate sempre l'integrità del file di backup. Per ultimo, un buon backup **deve essere facilmente e velocemente accessibile**. Ricorda di documentare il metodo di recupero e di controllare la velocità delle connessioni in download specialmente se la connessione Internet non è simmetrica. - !! Esempi di **backup sicuro e facilmente recuperabile**. -* backup remoto e automatizzato con borg -* backup automatizzato su unità locale esterna con borg -* snapshot o immagine (eseguiti prima di ogni aggiornamento) -* server monitorato con RAID 1 (o una VPS commerciale che può essere su un array) -* password di decifratura salvata su (tre supporti e due luoghi diversi) + +- backup remoto e automatizzato con borg +- backup automatizzato su unità locale esterna con borg +- snapshot o immagine (eseguiti prima di ogni aggiornamento) +- server monitorato con RAID 1 (o una VPS commerciale che può essere su un array) +- password di decifratura salvata su (tre supporti e due luoghi diversi) ## Alcuni esempi di esecuzione del backup -* [creare un file di backup e salvarlo manualmente (scelta di default per YunoHost)](/backup#manual-backup) -* [backup automatizzato (scelta consigliata)](/backup#automatic-or-remote-backup) -* [backup su disco esterno](/external_storage) -* [creazione di un'immagine o snapshot](/backup/clone_filesystem) -* [salvataggio dei dati con metodo personalizzato](/backup/custom_backup_methods) - +- [creare un file di backup e salvarlo manualmente (scelta di default per YunoHost)](/backup#manual-backup) +- [backup automatizzato (scelta consigliata)](/backup#automatic-or-remote-backup) +- [backup su disco esterno](/external_storage) +- [creazione di un'immagine o snapshot](/backup/clone_filesystem) +- [salvataggio dei dati con metodo personalizzato](/backup/custom_backup_methods) ## Rischi + Di seguito un elenco di errori in ordine crescente di pericolosità. L'ordine proposto varia in base alla vostra situazione (tipo di server, complessità dell'installazione, permessi degli utenti), ponete attenzione alla vostra configurazione, avendo ben presenti le conseguenze di una possibile perdita dei dati. !!! Tenete presente che i rischi reali sono collegati all'evenienza di 2 eventi contemporanei -* **Imprecisione**: i backup manuali richiedono rigore e regolarità -* **Errata gestione**: cancellazione involontaria di un file di backup in un sistema di sincronizzazione client server di backup, cancellazione che si propaga instantaneamente -* **Cryptolocker**: si tratta di virus che cifrano i file e chiedono un riscatto. Se i vostri utenti usano nextcloud e windows un sistema windows infetto può sincronizzare file cifrati perdendo così le copie di backup. -* **Guasto hardware**: le schede SD sono i supporti meno affidabili nel tempo (si stima meno di 2 anni di vita in un server), seguite dai dischi SSD (circa 3 anni di vita) e i dischi HD (3 anni). Ricordate che neppure un'infrastruttura nuova è esente al 100% da guasti nei primi sei mesi di vita. In ogni caso le copie non devono stare sugli stessi supporti fisici. -* **Bug software**: il malfunzionamento del software può portare alla perdita dei dati oppure potreste non sapere come risolvere un problema e quindi vorrete recuperare il vostro sistema. -* **Assenza di energia elettrica o connessione**: prevedete un piano di azione se dovesse succedere...quando siete in vacanza. -* **Catastrofi naturali e non**: un bambino o di un gatto, un fulmine o una perdita di acqua, incendio e inondazioni possono rovinare il vostro backup custodito nella stanza adiacente. -* **Compromissione del server**: un attacco informatico diretto al vostro server potrebbe cancellarne i dati -* **Furto**: nel caso di furto potreste perdere il software di gestione della password per decriptare il backup. -* **Problemi legali**: per poter dimostrare la vostra innocenza i vostri pc potrebbero essere sequestrati, a casa vostra e altrove -* **Decesso o malattia**: potreste non essere più in grado di digitare la vostra password +- **Imprecisione**: i backup manuali richiedono rigore e regolarità +- **Errata gestione**: cancellazione involontaria di un file di backup in un sistema di sincronizzazione client server di backup, cancellazione che si propaga instantaneamente +- **Cryptolocker**: si tratta di virus che cifrano i file e chiedono un riscatto. Se i vostri utenti usano nextcloud e windows un sistema windows infetto può sincronizzare file cifrati perdendo così le copie di backup. +- **Guasto hardware**: le schede SD sono i supporti meno affidabili nel tempo (si stima meno di 2 anni di vita in un server), seguite dai dischi SSD (circa 3 anni di vita) e i dischi HD (3 anni). Ricordate che neppure un'infrastruttura nuova è esente al 100% da guasti nei primi sei mesi di vita. In ogni caso le copie non devono stare sugli stessi supporti fisici. +- **Bug software**: il malfunzionamento del software può portare alla perdita dei dati oppure potreste non sapere come risolvere un problema e quindi vorrete recuperare il vostro sistema. +- **Assenza di energia elettrica o connessione**: prevedete un piano di azione se dovesse succedere...quando siete in vacanza. +- **Catastrofi naturali e non**: un bambino o di un gatto, un fulmine o una perdita di acqua, incendio e inondazioni possono rovinare il vostro backup custodito nella stanza adiacente. +- **Compromissione del server**: un attacco informatico diretto al vostro server potrebbe cancellarne i dati +- **Furto**: nel caso di furto potreste perdere il software di gestione della password per decriptare il backup. +- **Problemi legali**: per poter dimostrare la vostra innocenza i vostri pc potrebbero essere sequestrati, a casa vostra e altrove +- **Decesso o malattia**: potreste non essere più in grado di digitare la vostra password ## Qualche info sulla sincronizzazione Nextcloud o Thunderbird (IMAP) + Un metodo per un parziale backup consiste nello salvare i file e le mail tramite dei programmi di sincronizzazione quali Nextcloud o Thunderbird. In questo modo eviterete le perdite dovute ad un guasto fisico. La semplicità di tale operazione comporta qualche rischio intrinseco nella natura stessa del metodo, sopratutto se usato in ambiente mac o windows. Un [crytolocker](https://en.wikipedia.org/wiki/Ransomware) sul vostro pc porterebbe come conseguenza la perdita dei file sul server nextcloud, così come una involontaria cancellazione del file sul pc. Normalmente la sincronizzazione tra il pc e il server nextcloud è istantanea e quindi i danni sono irreparabili. Anche se il rischio di evento del genere può essere attenuato con programmi quali Timeshift, solo il backup su un supporto non connesso vi proteggerà dai crytolocker. - - - diff --git a/pages/02.administer/20.backups/05.evaluate/evaluate.md b/pages/02.administer/20.backups/05.evaluate/evaluate.md index 00e6023f..6a96dc5c 100644 --- a/pages/02.administer/20.backups/05.evaluate/evaluate.md +++ b/pages/02.administer/20.backups/05.evaluate/evaluate.md @@ -10,10 +10,10 @@ page-toc: depth: 3 --- - In the context of self-hosting, backups are an important element to compensate for unexpected events (fire, database corruption, loss of access to the server, compromised server...). The backup policy to implement depends on the importance of the services and data you manage. For example, backing up a test server will be of little interest, while you will want to be very careful if you are managing critical data for an association or a company - and in such cases, you will want to store the backups *in a different location or locations*. ## What is a good backup ? + A good backup consists of at least **3 copies of the data** (including the original data), on at least **2 separate storages**, in at least **2 separate locations** (far enough apart) and ideally with 2 separate methods. If your backups are encrypted **these rules also apply to the decryption phrase/key**. A good backup is also in many cases, a recent backup, so it takes either a lot of rigor or to **automate** the process. @@ -22,42 +22,43 @@ A good backup is checked regularly to ensure the effectiveness and integrity of Finally, a good backup is one that is **restorable within an acceptable timeframe** for you. Remember to document your restoration method and to estimate the transfer time of a copy, especially if the Internet connections involved are not symmetrical. - !!! Example of **a robust and comfortable combination**: -* a remote and automatic backup with borg -* a backup on external disk and automatic with borg -* a regular snapshot/image (and before updates) -* a monitored RAID 1 array (or a commercial VPS that will also be on an array) -* a decryption passphrase stored on 3 media in 2 locations + +- a remote and automatic backup with borg +- a backup on external disk and automatic with borg +- a regular snapshot/image (and before updates) +- a monitored RAID 1 array (or a commercial VPS that will also be on an array) +- a decryption passphrase stored on 3 media in 2 locations ## Some possible methods -* [generate an archive and download it manually (default method of YunoHost)](/backup#manual-backup) -* [backup automatically (recommended method)](/backup#automatic-or-remote-backup) -* [generate an archive directly on another disk](/external_storage) -* [make a disk image or snapshot](/backup/clone_filesystem) -* [save useful data via a custom method](/backup/custom_backup_methods) - +- [generate an archive and download it manually (default method of YunoHost)](/backup#manual-backup) +- [backup automatically (recommended method)](/backup#automatic-or-remote-backup) +- [generate an archive directly on another disk](/external_storage) +- [make a disk image or snapshot](/backup/clone_filesystem) +- [save useful data via a custom method](/backup/custom_backup_methods) ## Risks -Below, a list of risks sorted from the most to the least probable, whose probability remains to be adapted according to your situation (location of the server, quality of the installations, user profiles, etc.). It is up to you to put the cursor where it should be, especially considering the consequences of a data loss. -!!! Keep in mind that real accidents are linked to the occurrence of 2 events simultaneously. +Below, a list of risks sorted from the most to the least probable, whose probability remains to be adapted according to your situation (location of the server, quality of the installations, user profiles, etc.). It is up to you to put the cursor where it should be, especially considering the consequences of a data loss. -* **Lack of rigor**: strategies based on manual backups require a lot of rigor in the regularity -* **Bad handling**: it can happen that a backup is erased by mistake during a restoration or if you rely on a synchronization system, you could delete a file and the deletion would be synchronized instantly -* **Cryptolocker**: this is a virus that encrypts files and demands a ransomware. If your users are using nextcloud and windows, an infected windows could synchronize encrypted files and thus you lose your copy. -* **Hardware failure**: SD cards are the least reliable media over time (~2 years of life in a server), followed by SSD disks (about 3 years of life) and hard drives (3 years). Note that a new equipment has also probability to break down during the first 6 months. In all cases, your copies should not be on the same physical media. -* **Software failure/bug**: a software bug may result in data deletion or you may not know how to fix a problem and want to restore your system. -* **Electricity or internet failure**: do you have a plan if this happens? What if you are on vacation? -* **Disaster or natural or unnatural event**: a small child, a cat, lightning or a simple leak can destroy your equipment. Fires or floods can also destroy your backup copy at the other end of your home... -* **Server compromise**: a malicious person or a robot could attack your server and delete your data -* **Machine theft**: a burglary or theft of a computer on which your password manager is located to decrypt your backups -* **Search**: whether you are guilty or not, a search can result in the seizure of the entire computer equipment of a place (or even several) -* **Death/health problem**: you may not be able to type your passphrase anymore +!!! Keep in mind that real accidents are linked to the occurrence of 2 events simultaneously. + +- **Lack of rigor**: strategies based on manual backups require a lot of rigor in the regularity +- **Bad handling**: it can happen that a backup is erased by mistake during a restoration or if you rely on a synchronization system, you could delete a file and the deletion would be synchronized instantly +- **Cryptolocker**: this is a virus that encrypts files and demands a ransomware. If your users are using nextcloud and windows, an infected windows could synchronize encrypted files and thus you lose your copy. +- **Hardware failure**: SD cards are the least reliable media over time (~2 years of life in a server), followed by SSD disks (about 3 years of life) and hard drives (3 years). Note that a new equipment has also probability to break down during the first 6 months. In all cases, your copies should not be on the same physical media. +- **Software failure/bug**: a software bug may result in data deletion or you may not know how to fix a problem and want to restore your system. +- **Electricity or internet failure**: do you have a plan if this happens? What if you are on vacation? +- **Disaster or natural or unnatural event**: a small child, a cat, lightning or a simple leak can destroy your equipment. Fires or floods can also destroy your backup copy at the other end of your home... +- **Server compromise**: a malicious person or a robot could attack your server and delete your data +- **Machine theft**: a burglary or theft of a computer on which your password manager is located to decrypt your backups +- **Search**: whether you are guilty or not, a search can result in the seizure of the entire computer equipment of a place (or even several) +- **Death/health problem**: you may not be able to type your passphrase anymore ## About Nextcloud or Thunderbird (IMAP) synchronization -A method that allows a partial backup is to backup files and emails via synchronization software like Nextcloud client or ThunderBird. This way, you avoid the risk of hardware failure. + +A method that allows a partial backup is to backup files and emails via synchronization software like Nextcloud client or ThunderBird. This way, you avoid the risk of hardware failure. If this method is easy to set up, it is not without risk because of the synchronization itself. For example, if you are on Windows or Mac, you increase the risk of data loss following the encryption of files by a [cryptolocker](https://en.wikipedia.org/wiki/Ransomware) type virus. On any type of system, a false manipulation can delete all your copies on the server and on the equipment that synchronizes. This concern is aggravated by the fact that the deletion synchronization is usually rather instantaneous. diff --git a/pages/02.administer/20.backups/10.backup_methods/01.borgbackup/borgbackup.fr.md b/pages/02.administer/20.backups/10.backup_methods/01.borgbackup/borgbackup.fr.md index a0d505ad..2ec15e89 100644 --- a/pages/02.administer/20.backups/10.backup_methods/01.borgbackup/borgbackup.fr.md +++ b/pages/02.administer/20.backups/10.backup_methods/01.borgbackup/borgbackup.fr.md @@ -10,27 +10,28 @@ page-toc: depth: 3 --- - YunoHost propose un couple d'applications pour [BorgBackup](https://www.borgbackup.org/). ## Fonctionnalité + Cette application propose: -* la sauvegarde des données sur un disque externe ou sur un dépôt borg distant -* la déduplication et la compression des fichiers ce qui permet de conserver de nombreuses copies antérieures -* le chiffrement des données, ce qui permet de pouvoir stocker chez un tiers -* de définir finement la fréquence et le type de données à sauvegarder -* un système d'alerte mail en cas de défaut de sauvegarde. + +- la sauvegarde des données sur un disque externe ou sur un dépôt borg distant +- la déduplication et la compression des fichiers ce qui permet de conserver de nombreuses copies antérieures +- le chiffrement des données, ce qui permet de pouvoir stocker chez un tiers +- de définir finement la fréquence et le type de données à sauvegarder +- un système d'alerte mail en cas de défaut de sauvegarde. Il existe des [fournisseurs de dépôts borg distants](https://www.borgbackup.org/support/commercial.html), il est également possible de créer son propre dépôt sur un autre YunoHost avec l'[application borgserver](https://github.com/YunoHost-Apps/borgserver_ynh). La future méthode de sauvegarde intégrée par défaut dans YunoHost sera basée sur ce logiciel. ## Mise en place de la sauvegarde + !!! Pour la mise en place, il faut d'abord installer l'[application borg](https://github.com/YunoHost-Apps/borg_ynh), puis éventuellement l'[application borgserver](https://github.com/YunoHost-Apps/borgserver_ynh). - - ## Tester + Avec les apps borg un email est envoyé pour dire si la sauvegarde échoue ou si le repo distant n'a rien reçu. On peut toutefois analyser manuellement pour s'assurer que tout va bien de façon plus complète. ```bash @@ -55,27 +56,32 @@ app=borg; BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" BORG_RSH="ss Si on est dans le cas d'une migration ou d'une réinstallation, il faut réinstaller borg de la même façon. Si le repo est distant il faut changer la clé publique. Lister les archives disponibles -``` + +```bash app=borg; BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" BORG_RSH="ssh -i /root/.ssh/id_${app}_ed25519 -oStrictHostKeyChecking=yes " borg list "$(yunohost app setting $app repository)" ``` Créer les archives tar (une archive par app et partie de système) -``` + +```bash app=borg; BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" BORG_RSH="ssh -i /root/.ssh/id_${app}_ed25519 -oStrictHostKeyChecking=yes " borg export-tar "$(yunohost app setting $app repository)::ARCHIVE" /home/yunohost.backup/archives/ARCHIVE.tar ``` Puis restaurer l'archive de façon classique. ### Restaurer des grosses archives + Si l'espace disponible est inférieur au poids de votre archive, des données décompressées et des dépendances, vous devrez restaurer partie par partie, app par app. Si restaurer app par app ne suffit pas OU si une archive est trop grosse, il peut être judicieux de générer une archive tar sans les "grosses" données d'une app comme si elle avait été générée avec l'[option BACKUP_CORE_ONLY](/backup/include_exclude_files#ne-pas-sauvegarder-les-grosses-quantites-de-donnees). Exemple avec Nextcloud: -``` + +```bash app=borg; BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" BORG_RSH="ssh -i /root/.ssh/id_${app}_ed25519 -oStrictHostKeyChecking=yes " borg export-tar -e apps/nextcloud/backup/home/yunohost.app "$(yunohost app setting $app repository)::ARCHIVE" /home/yunohost/archives/ARCHIVE.tar ``` Il faudra ensuite extraire ces données directement avec borg -``` + +```bash cd /home/yunohost.app/ app=borg; BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" BORG_RSH="ssh -i /root/.ssh/id_${app}_ed25519 -oStrictHostKeyChecking=yes " borg extract "$(yunohost app setting $app repository)::ARCHIVE" apps/nextcloud/backup/home/yunohost.app/ mv apps/nextcloud/backup/home/yunohost.app/nextcloud ./ diff --git a/pages/02.administer/20.backups/10.backup_methods/01.borgbackup/borgbackup.it.md b/pages/02.administer/20.backups/10.backup_methods/01.borgbackup/borgbackup.it.md index c9ff5c29..71be14b6 100644 --- a/pages/02.administer/20.backups/10.backup_methods/01.borgbackup/borgbackup.it.md +++ b/pages/02.administer/20.backups/10.backup_methods/01.borgbackup/borgbackup.it.md @@ -13,14 +13,16 @@ page-toc: YunoHost propone due programmi per [BorgBackup](https://www.borgbackup.org/). ## Funzionalità -con BorgBackup potrete: -* effettuare il backup dei dati in un HD esterno o in un repository borg remoto -* deduplicare e comprimere i file, che permette di mantenere molte versioni precedenti -* la cifratura dei dati, permettendo così di conservare in modo sicuro i file presso soggetti terzi -* definire i tipi di dati da copiare e la frequenza di backup -* ricevere una mail di allerta in caso di fallimento del backup -Oltre ai [fornitori terzi di repository](https://www.borgbackup.org/support/commercial.html), vi è la possibilità di hostare il proprio repository su una differente installazione yunohost con installata l'[applicazione borgserver](https://github.com/YunoHost-Apps/borgserver_ynh). +con BorgBackup potrete: + +- effettuare il backup dei dati in un HD esterno o in un repository borg remoto +- deduplicare e comprimere i file, che permette di mantenere molte versioni precedenti +- la cifratura dei dati, permettendo così di conservare in modo sicuro i file presso soggetti terzi +- definire i tipi di dati da copiare e la frequenza di backup +- ricevere una mail di allerta in caso di fallimento del backup + +Oltre ai [fornitori terzi di repository](https://www.borgbackup.org/support/commercial.html), vi è la possibilità di hostare il proprio repository su una differente installazione YunoHost con installata l'[applicazione borgserver](https://github.com/YunoHost-Apps/borgserver_ynh). Il futuro metodo di backup integrato in YunoHost sarà basato su BorgBackup @@ -28,10 +30,9 @@ Il futuro metodo di backup integrato in YunoHost sarà basato su BorgBackup !!!Installate l'[applicazione borg](https://github.com/YunoHost-Apps/borg_ynh), ed eventualmente l'[applicazione borgserver](https://github.com/YunoHost-Apps/borgserver_ynh). - ## Test -Con il programma borg una mail viene inviata nel caso la sessione di backup fallisca o nel caso il repository di destinazione non riceva nessun dato. Da terminale possiamo controllare nei minimi dettagli, che tutto funzioni. +Con il programma borg una mail viene inviata nel caso la sessione di backup fallisca o nel caso il repository di destinazione non riceva nessun dato. Da terminale possiamo controllare nei minimi dettagli, che tutto funzioni. ```bash # Elencare i files @@ -55,31 +56,36 @@ app=borg; BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" BORG_RSH="ss Se effettuiamo il ripristino dopo una migrazione o una reinstallazione dobbiamo reinstallare borg nello stessa maniera. Se il repository si trova in un server remoto bisogna cambiare la chiave pubblica. Elencare gli archivi disponibili -``` + +```bash app=borg; BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" BORG_RSH="ssh -i /root/.ssh/id_${app}_ed25519 -oStrictHostKeyChecking=yes " borg list "$(yunohost app setting $app repository)" ``` Creare gli archivi tar (uno per ogni applicazione e componente del sistema) -``` + +```bash app=borg; BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" BORG_RSH="ssh -i /root/.ssh/id_${app}_ed25519 -oStrictHostKeyChecking=yes " borg export-tar "$(yunohost app setting $app repository)::ARCHIVE" /home/yunohost/archives/ARCHIVE.tar ``` In seguito ripristinare l'archivio come di consueto. ### Ripristino di archivi di grandi dimensioni + Se lo spazio disponibile è inferiore alla dimensione del vostro archivio, dei dati scompattati e delle dipendenze, dovrete ripristinare un'applicazione alla volta. Se il ripristino non riesce o se un archivio è troppo grande, è più prudente creare un archivio tar senza la parte più grande dei dati, cioè come se l'archivio fosse stato creato con l'[opzione BACKUP_CORE_ONLY](/backup/include_exclude_files#don't-save-large-quantities-of-data). Di seguito un esempio con Nextcloud: -``` + +```bash app=borg; BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" BORG_RSH="ssh -i /root/.ssh/id_${app}_ed25519 -oStrictHostKeyChecking=yes " borg export-tar -e apps/nextcloud/backup/home/yunohost.app "$(yunohost app setting $app repository)::ARCHIVE" /home/yunohost/archives/ARCHIVE.tar ``` In seguito si estrarranno questi dati direttamente con borg -``` + +```bash cd /home/yunohost.app/ app=borg; BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" BORG_RSH="ssh -i /root/.ssh/id_${app}_ed25519 -oStrictHostKeyChecking=yes " borg extract "$(yunohost app setting $app repository)::ARCHIVE" apps/nextcloud/backup/home/yunohost.app/ mv apps/nextcloud/backup/home/yunohost.app/nextcloud ./ rm -r apps ``` - Procedere poi con il consueto metodo di ripristino + Procedere poi con il consueto metodo di ripristino diff --git a/pages/02.administer/20.backups/10.backup_methods/01.borgbackup/borgbackup.md b/pages/02.administer/20.backups/10.backup_methods/01.borgbackup/borgbackup.md index 11584f08..f12648e0 100644 --- a/pages/02.administer/20.backups/10.backup_methods/01.borgbackup/borgbackup.md +++ b/pages/02.administer/20.backups/10.backup_methods/01.borgbackup/borgbackup.md @@ -10,28 +10,29 @@ page-toc: depth: 3 --- - YunoHost offers a couple of applications for [BorgBackup](https://www.borgbackup.org/). ## Functionality + This application offers: -* backup of data on an external disk or on a remote Borg repository -* deduplication and compression of files, which allows to keep many previous copies -* data encryption, which allows you to store data with a third party -* to define the frequency and type of data to be backed up -* a mail alert system in case of backup failure. + +- backup of data on an external disk or on a remote Borg repository +- deduplication and compression of files, which allows to keep many previous copies +- data encryption, which allows you to store data with a third party +- to define the frequency and type of data to be backed up +- a mail alert system in case of backup failure. There are [remote borg repository providers](https://www.borgbackup.org/support/commercial.html), it is also possible to create your own repository on another YunoHost with the [borgserver application](https://github.com/YunoHost-Apps/borgserver_ynh). The future default backup method integrated in YunoHost will be based on this software. ## Setting up the backup + !!! To set up, first install the [borg application](https://github.com/YunoHost-Apps/borg_ynh), then optionally the [borgserver application](https://github.com/YunoHost-Apps/borgserver_ynh). - ## Test -With the borg apps an email is sent to say if the backup fails or if the remote repo has received nothing. However, you can manually test to make sure everything is fine in a more complete way. +With the borg apps an email is sent to say if the backup fails or if the remote repo has received nothing. However, you can manually test to make sure everything is fine in a more complete way. ```bash # List files @@ -55,27 +56,32 @@ app=borg; BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" BORG_RSH="ss If we are in the case of a migration or a reinstallation, we must reinstall borg in the same way. If the repo is remote you have to change the public key. List the available archives -``` + +```bash app=borg; BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" BORG_RSH="ssh -i /root/.ssh/id_${app}_ed25519 -oStrictHostKeyChecking=yes " borg list "$(yunohost app setting $app repository)" ``` Create tar archives (one archive per app and system part) -``` + +```bash app=borg; BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" BORG_RSH="ssh -i /root/.ssh/id_${app}_ed25519 -oStrictHostKeyChecking=yes " borg export-tar "$(yunohost app setting $app repository)::ARCHIVE" /home/yunohost/archives/ARCHIVE.tar ``` Then restore the archive in the usual way. ### Restore large archives + If the available space is less than the weight of your archive, decompressed data and dependencies, you will have to restore part by part, app by app. If restoring app by app is not enough OR if an archive is too big, it may be a good idea to generate a tarball without the "big" data of an app as if it had been generated with the [BACKUP_CORE_ONLY option](/backup/include_exclude_files#don't-save-large-quantities-of-data). Example with Nextcloud: -``` + +```bash app=borg; BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" BORG_RSH="ssh -i /root/.ssh/id_${app}_ed25519 -oStrictHostKeyChecking=yes " borg export-tar -e apps/nextcloud/backup/home/yunohost.app "$(yunohost app setting $app repository)::ARCHIVE" /home/yunohost.backup/archives/ARCHIVE.tar ``` You will then have to extract these data directly with borg -``` + +```bash cd /home/yunohost.app/ app=borg; BORG_PASSPHRASE="$(yunohost app setting $app passphrase)" BORG_RSH="ssh -i /root/.ssh/id_${app}_ed25519 -oStrictHostKeyChecking=yes " borg extract "$(yunohost app setting $app repository)::ARCHIVE" apps/nextcloud/backup/home/yunohost.app/ mv apps/nextcloud/backup/home/yunohost.app/nextcloud ./ diff --git a/pages/02.administer/20.backups/10.backup_methods/02.restic/restic.fr.md b/pages/02.administer/20.backups/10.backup_methods/02.restic/restic.fr.md index 6f4aa03a..d096cc15 100644 --- a/pages/02.administer/20.backups/10.backup_methods/02.restic/restic.fr.md +++ b/pages/02.administer/20.backups/10.backup_methods/02.restic/restic.fr.md @@ -10,13 +10,12 @@ page-toc: depth: 3 --- - ## Fonctionnalité Cette application propose: -* la sauvegarde des données sur un stockage distant (support de différents types de stockage) -* la déduplication et la compression des fichiers ce qui permet de conserver de nombreuses copies antérieures -* le chiffrement des données, ce qui permet de pouvoir stocker chez un tiers + +- la sauvegarde des données sur un stockage distant (support de différents types de stockage) +- la déduplication et la compression des fichiers ce qui permet de conserver de nombreuses copies antérieures +- le chiffrement des données, ce qui permet de pouvoir stocker chez un tiers Le paquet permet aussi de définir finement la fréquence et le type de données à sauvegarder et intègre un système d'alerte mail en cas de défaut de sauvegarde. - diff --git a/pages/02.administer/20.backups/10.backup_methods/02.restic/restic.it.md b/pages/02.administer/20.backups/10.backup_methods/02.restic/restic.it.md index 638e618a..9108e0bc 100644 --- a/pages/02.administer/20.backups/10.backup_methods/02.restic/restic.it.md +++ b/pages/02.administer/20.backups/10.backup_methods/02.restic/restic.it.md @@ -14,8 +14,8 @@ page-toc: Questa applicazione permette: -* il backup dei dati in rete (compatibile con diverse modalità di stoccaggio dei dati) -* deduplicare e comprimere i file, permettendo di mantenere molte copie precedenti -* la cifratura dei dati, permettendo così di conservare in modo sicuro i file presso soggetti terzi +- il backup dei dati in rete (compatibile con diverse modalità di stoccaggio dei dati) +- deduplicare e comprimere i file, permettendo di mantenere molte copie precedenti +- la cifratura dei dati, permettendo così di conservare in modo sicuro i file presso soggetti terzi Il programma permette di configurare con precisione i dati che devono essere salvati e la frequenza dei backup, e comprende un sistema di allerta via mail nel caso di fallimento nell'esecuzione del backup diff --git a/pages/02.administer/20.backups/10.backup_methods/02.restic/restic.md b/pages/02.administer/20.backups/10.backup_methods/02.restic/restic.md index 30ba422c..97fe4df4 100644 --- a/pages/02.administer/20.backups/10.backup_methods/02.restic/restic.md +++ b/pages/02.administer/20.backups/10.backup_methods/02.restic/restic.md @@ -10,12 +10,12 @@ page-toc: depth: 3 --- - ## Functionality This application offers: -* backup of data to remote storage (support for different types of storage) -* deduplication and compression of files, which makes it possible to keep many previous copies -* data encryption, which allows to store data at a third party + +- backup of data to remote storage (support for different types of storage) +- deduplication and compression of files, which makes it possible to keep many previous copies +- data encryption, which allows to store data at a third party The package also allows you to finely define the frequency and type of data to be backed up and integrates an email alert system in case of backup failure. diff --git a/pages/02.administer/20.backups/10.backup_methods/03.archivist/archivist.fr.md b/pages/02.administer/20.backups/10.backup_methods/03.archivist/archivist.fr.md index 0e8c9fcb..c8f25f72 100644 --- a/pages/02.administer/20.backups/10.backup_methods/03.archivist/archivist.fr.md +++ b/pages/02.administer/20.backups/10.backup_methods/03.archivist/archivist.fr.md @@ -10,13 +10,13 @@ page-toc: depth: 3 --- - ## Fonctionnalité + Cette application se base sur rsync et GPG, elle propose: -* la sauvegarde des données sur un stockage distant (support de différents types de stockage) -* le chiffrement des données, ce qui permet de pouvoir stocker chez un tiers + +- la sauvegarde des données sur un stockage distant (support de différents types de stockage) +- le chiffrement des données, ce qui permet de pouvoir stocker chez un tiers Le paquet permet aussi de définir finement la fréquence et le type de données à sauvegarder et intègre un système d'alerte mail en cas de défaut de sauvegarde. -Pour plus d'information : [https://forum.yunohost.org/t/new-app-archivist/3747](https://forum.yunohost.org/t/new-app-archivist/3747) - +Pour plus d'information : diff --git a/pages/02.administer/20.backups/10.backup_methods/03.archivist/archivist.md b/pages/02.administer/20.backups/10.backup_methods/03.archivist/archivist.md index 4debd205..e4b3d96e 100644 --- a/pages/02.administer/20.backups/10.backup_methods/03.archivist/archivist.md +++ b/pages/02.administer/20.backups/10.backup_methods/03.archivist/archivist.md @@ -10,14 +10,13 @@ page-toc: depth: 3 --- -!! This application is currently broken! To help fix this application please checkout [https://github.com/YunoHost-Apps/archivist_ynh](https://github.com/YunoHost-Apps/archivist_ynh) - ## Functionality + This application is based on rsync and GPG, it offers: -* backup of data on a remote storage (support for different types of storage) -* data encryption, which allows to store data at a third party + +- backup of data on a remote storage (support for different types of storage) +- data encryption, which allows to store data at a third party The package also allows you to finely define the frequency and type of data to be backed up and integrates an email alert system in case of backup failure. -For more information: [https://forum.yunohost.org/t/new-app-archivist/3747](https://forum.yunohost.org/t/new-app-archivist/3747) - +For more information: diff --git a/pages/02.administer/20.backups/10.backup_methods/backup_methods.md b/pages/02.administer/20.backups/10.backup_methods/backup_methods.md index 37f283b4..daed09c2 100644 --- a/pages/02.administer/20.backups/10.backup_methods/backup_methods.md +++ b/pages/02.administer/20.backups/10.backup_methods/backup_methods.md @@ -11,21 +11,27 @@ page-toc: --- ## [BorgBackup](/borgbackup) + This application offers: -* backup of data on an external disk or on a remote Borg repository -* deduplication and compression of files, which allows to keep many previous copies -* data encryption, which allows you to store data with a third party -* to define the frequency and type of data to be backed up -* a mail alert system in case of backup failure. + +- backup of data on an external disk or on a remote Borg repository +- deduplication and compression of files, which allows to keep many previous copies +- data encryption, which allows you to store data with a third party +- to define the frequency and type of data to be backed up +- a mail alert system in case of backup failure. ## [Restic](/restic) + This application offers: -* backup of data to remote storage (support for different types of storage) -* deduplication and compression of files, which makes it possible to keep many previous copies -* data encryption, which allows to store data at a third party + +- backup of data to remote storage (support for different types of storage) +- deduplication and compression of files, which makes it possible to keep many previous copies +- data encryption, which allows to store data at a third party ## [Archivist](/archivist) + !! This application is currently broken! This application is based on rsync and GPG, it offers: -* backup of data on a remote storage (support for different types of storage) -* data encryption, which allows to store data at a third party + +- backup of data on a remote storage (support for different types of storage) +- data encryption, which allows to store data at a third party diff --git a/pages/02.administer/20.backups/15.clone_filesystem/clone_filesystem.fr.md b/pages/02.administer/20.backups/15.clone_filesystem/clone_filesystem.fr.md index 0f17dd91..bdb8e3f2 100644 --- a/pages/02.administer/20.backups/15.clone_filesystem/clone_filesystem.fr.md +++ b/pages/02.administer/20.backups/15.clone_filesystem/clone_filesystem.fr.md @@ -19,6 +19,7 @@ Réaliser des images complètes du système peut être un moyen complémentaire Selon votre type d'installation, vous pouvez soit créer un snapshot, soit cloner le support de stockage en le retirant de votre serveur (éteint). ## Déclencher un snapshot + Un snapshot permet de figer une image du système de fichiers. Les snapshots sont très pratiques lorsque l'on fait une mise à jour ou des essais, car ils vous permettent de revenir facilement en arrière en cas de pépin. En revanche, en dehors de quelques clusters de très haute disponibilité, les snapshots ne vous protègent pas vraiment face à des pannes matérielles ou des catastrophes (cf. incendie d'OVH à Strasbourg en 2021). En général, les snapshots sont assez économes en espace disque, le principe est que votre système de fichier va stocker les différences survenues depuis votre snapshot. Ainsi, seules les modifications consomment de l'espace. @@ -30,10 +31,11 @@ Vous pouvez utiliser cette méthode avec la plupart des VPS (souvent payant), de [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="VPS"] Ci-dessous, quelques documentations pour les fournisseurs les plus connus: - * [DigitalOcean (EN)](https://docs.digitalocean.com/products/images/snapshots/) - * [Gandi](https://docs.gandi.net/fr/simple_hosting/operations_courantes/snapshots.html) - * [OVH](https://docs.ovh.com/fr/vps/snapshot-vps/) - * [Scaleway (EN)](https://www.scaleway.com/en/docs/backup-your-data-with-snapshots/) + +- [DigitalOcean (EN)](https://docs.digitalocean.com/products/images/snapshots/) +- [Gandi](https://docs.gandi.net/fr/simple_hosting/operations_courantes/snapshots.html) +- [OVH](https://docs.ovh.com/fr/vps/snapshot-vps/) +- [Scaleway (EN)](https://www.scaleway.com/en/docs/backup-your-data-with-snapshots/) [/ui-tab] [ui-tab title="VirtualBox"] Sélectionner la machine virtuelle et cliquer sur `Snapshots`, puis spécifier le nom du snapshot et cliquer sur `OK`. @@ -47,36 +49,41 @@ Ensuite cliquer sur `Restore Snapshot`. [/ui-tab] [ui-tab title="Proxmox"] - * Sélectionner la machine virtuelle - * Aller dans l'onglet `Backup` - * Cliquer sur `Backup now` - * Choisir le mode `Snapshot` - * Valider +- Sélectionner la machine virtuelle +- Aller dans l'onglet `Backup` +- Cliquer sur `Backup now` +- Choisir le mode `Snapshot` +- Valider [/ui-tab] [ui-tab title="BTRFS"] Ci-dessous on considère que `/pool/volume` est le volume à snapshoter. Créer un snapshot en lecture seule -``` + +```bash btrfs subvolume snapshot /pool/volume /pool/volume/$(date +"%Y-%m-%d_%H:%M") ``` Lister les snapshots -``` + +```bash btrfs subvolume show /pool/volume ``` Restaurer un snapshot -``` + +```bash btrfs sub del /pool/volume btrfs sub snap /pool/volume/2021-07-22_16:12 /pool/volume btrfs sub del /pool/volume/2021-07-22_16:12 ``` Supprimer un snapshot -``` + +```bash btrfs subvolume delete /pool/volume/2021-07-22_16:12 ``` + !! Attention de ne pas supprimer le volume original !!! Voir [ce tutoriel](https://www.linux.com/training-tutorials/how-create-and-manage-btrfs-snapshots-and-rollbacks-linux-part-2/) pour plus d'info @@ -85,52 +92,60 @@ btrfs subvolume delete /pool/volume/2021-07-22_16:12 Ci-dessous on considère que `pool/volume` est le volume à snapshoter. Créer un snapshot -``` + +```bash rbd snap create pool/volume@$(date +"%Y-%m-%d_%H:%M") ``` Lister les snapshots -``` + +```bash rbd snap ls pool/volume ``` Restaurer un snapshot -``` + +```bash rbd snap rollback pool/volume@2021-07-22_16:22 ``` Supprimer un snapshot -``` + +```bash rbd snap rm pool/volume@2021-07-22_16:12 ``` + [/ui-tab] [ui-tab title="ZFS"] Ci-dessous on considère que `pool/volume` est le volume à snapshoter. Créer un snapshot -``` + +```bash zfs snapshot pool/volume@$(date +"%Y-%m-%d_%H:%M") ``` Lister les snapshots -``` + +```bash zfs list -t snapshot -o name,creation ``` Restaurer un snapshot -``` + +```bash zfs rollback pool/volume@2021-07-22_16:22 ``` Supprimer un snapshot -``` + +```bash zfs destroy pool/volume@2021-07-22_16:12 ``` [/ui-tab] [/ui-tabs] - ## Créer une image du système de fichier à froid Vous pouvez cloner votre support (carte SD, disque ssd, volume de VPS...) pour créer une image disque. Cette image avant compression sera de la taille exacte de votre support, c'est pourquoi cette méthode s'applique plutôt aux machines de moins de 64Go. @@ -140,6 +155,7 @@ Vous pouvez cloner votre support (carte SD, disque ssd, volume de VPS...) pour c [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="Avec USBimager"] Ceci peut être effectué avec [USBimager](https://bztsrc.gitlab.io/usbimager/) (N.B. : assurez-vous de télécharger la version 'Read-write' ! Pas la version 'Write-only' !). Le processus consiste ensuite à "l'inverse" du processus de flashage de la carte SD: + - Éteignez votre serveur - Récupérez la carte SD et branchez-la dans votre ordinateur - Dans USBimager, cliquez sur "Read" pour créer une image ("photographie") de la carte SD. Vous pouvez utiliser le fichier obtenu pour plus tard restaurer le système en entier. @@ -158,4 +174,3 @@ dd if=/dev/mmcblk0 | gzip > ./my_snapshot.gz [/ui-tab] [/ui-tabs] - diff --git a/pages/02.administer/20.backups/15.clone_filesystem/clone_filesystem.it.md b/pages/02.administer/20.backups/15.clone_filesystem/clone_filesystem.it.md index 3e8ea2c1..c2bd4b78 100644 --- a/pages/02.administer/20.backups/15.clone_filesystem/clone_filesystem.it.md +++ b/pages/02.administer/20.backups/15.clone_filesystem/clone_filesystem.it.md @@ -12,13 +12,14 @@ page-toc: !! Images are missing on this page -Lo strumento di backup di Yunohost salva solamente i files utili e si basa su degli script di ripristino per reinstallare le dipendenze dei vostri programmi installati. In altre parole, il ripristino di YunoHost prevede in un primo tempo la reinstallazione del sistema e in seguito il ripristino dei dati. +Lo strumento di backup di YunoHost salva solamente i files utili e si basa su degli script di ripristino per reinstallare le dipendenze dei vostri programmi installati. In altre parole, il ripristino di YunoHost prevede in un primo tempo la reinstallazione del sistema e in seguito il ripristino dei dati. Realizzare un'immagine completa può essere un metodo, complementare o alternativo, per un backup del vostro server. Il vantaggio sta nel fatto che il vostro server può essere ripristinato nella stessa configurazione presente al momento del backup. In base a quale tipo di installazione avete, potrete creare uno snapshot oppure clonare il supporto che ospita il sistema (mentre è spento). ## Eseguire uno snapshot + Lo snapshot permette di congelare l'immagine del file system. Gli snapshot sono molto comodi in caso di aggiornamenti frequenti o di prove, perché vi permettono di tornare facilmente sui vostri passi in caso di problemi. Purtroppo, a meno di non avere un cluster ad altissima affidabilità, gli snapshot non vi proteggono efficacemente contro i guasti hardware o catastrofi (come l'incendio di OVH a Strasburgo nel 2021). Generalmente gli snapshot non occupano molto spazio sull'hard disk, si basano sul principio del backup differenziale, salvano cioè solo le variazioni dei file avvenute dopo la creazione del primo snapshot. Di conseguenza solo le modifiche prendono spazio. @@ -30,10 +31,11 @@ Potete usare questo sistema con la maggior parte dei fornitori VPS (quasi sempre [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="VPS"] Sotto la documentazione per i provider più conosciuti: - * [DigitalOcean (EN)](https://docs.digitalocean.com/products/images/snapshots/) - * [Gandi](https://docs.gandi.net/fr/simple_hosting/operations_courantes/snapshots.html) - * [OVH](https://docs.ovh.com/fr/vps/snapshot-vps/) - * [Scaleway (EN)](https://www.scaleway.com/en/docs/backup-your-data-with-snapshots/) + +- [DigitalOcean (EN)](https://docs.digitalocean.com/products/images/snapshots/) +- [Gandi](https://docs.gandi.net/fr/simple_hosting/operations_courantes/snapshots.html) +- [OVH](https://docs.ovh.com/fr/vps/snapshot-vps/) +- [Scaleway (EN)](https://www.scaleway.com/en/docs/backup-your-data-with-snapshots/) [/ui-tab] [ui-tab title="VirtualBox"] Seleziona la macchina virtuale e clicca su `Snapshot`, poi indica il nome dello snapshot e clicca `OK`. @@ -47,36 +49,41 @@ Infine cliccate su `Restore Snapshot`. [/ui-tab] [ui-tab title="Proxmox"] -* Selezionate la macchina virtuale -* Andate al tab `Backup` -* Cliccate su `Backup now` -* Scegliete `Snapshot` -* Confermate +- Selezionate la macchina virtuale +- Andate al tab `Backup` +- Cliccate su `Backup now` +- Scegliete `Snapshot` +- Confermate [/ui-tab] [ui-tab title="BTRFS"] Nell'esempio seguente `/pool/volume` è il volume da salvare. Creare uno snapshot in sola lettura -``` + +```bash btrfs subvolume snapshot /pool/volume /pool/volume/$(date +"%Y-%m-%d_%H:%M") ``` Elencare gli snapshots -``` + +```bash btrfs subvolume show /pool/volume ``` Ripristinare uno snapshots -``` + +```bash btrfs sub del /pool/volume btrfs sub snap /pool/volume/2021-07-22_16:12 /pool/volume btrfs sub del /pool/volume/2021-07-22_16:12 ``` Cancellare uno snapshot -``` + +```bash btrfs subvolume delete /pool/volume/2021-07-22_16:12 ``` + !! Attenzione a non cancellate il volume originale !!! Seguite [questo tutorial](https://www.linux.com/training-tutorials/how-create-and-manage-btrfs-snapshots-and-rollbacks-linux-part-2/) per maggiori informazioni @@ -85,51 +92,60 @@ btrfs subvolume delete /pool/volume/2021-07-22_16:12 Nell'esempio seguente `pool/volume` è il volume che vogliamo salvare Creare uno snapshots -``` + +```bash rbd snap create pool/volume@$(date +"%Y-%m-%d_%H:%M") ``` Elencare gli snapshot -``` + +```bash rbd snap ls pool/volume ``` Ripristinare uno snapshot -``` + +```bash rbd snap rollback pool/volume@2021-07-22_16:22 ``` Cancellare uno snapshot -``` + +```bash rbd snap rm pool/volume@2021-07-22_16:12 ``` + [/ui-tab] [ui-tab title="ZFS"] Nell'esempio seguente `pool/volume` è il volume che vogliamo salvare. Creare uno snapshot -``` + +```bash zfs snapshot pool/volume@$(date +"%Y-%m-%d_%H:%M") ``` Elencare gli snapshots -``` + +```bash zfs list -t snapshot -o name,creation ``` + Ripristinare uno snapshot -``` + +```bash zfs rollback pool/volume@2021-07-22_16:22 ``` Cancellare uno snapshot -``` + +```bash zfs destroy pool/volume@2021-07-22_16:12 ``` [/ui-tab] [/ui-tabs] - ## Creare una immagine a freddo del server Potete clonare il supporto del vostro server (scheda SD, disco SSD, volume di un VPS...) al fine di creare una immagine del disco. L'immagine creata, prima che venga compressa, sarà della stessa dimensione del vostro supporto e di conseguenza questa procedura è consigliata per supporti di capacità inferiore a 64GB. @@ -139,6 +155,7 @@ Questo metodo comporta lo spegnimento del server per il tempo necessario alla cr [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="Usando USBimager"] Questo può essere fatto con il programma [USBimager](https://bztsrc.gitlab.io/usbimager/) (N.B.: assicuratevi di scaricare la versione 'Read-write'! Non la versione 'Write-only'!). Il processo poi prosegue "all'opposto" della copia sulla scheda SD: + - Spegnete il vostro server - Estraete la scheda SD e inseritela nel pc - Nel programma USBimage cliccate su "Read" per creare l'immagine ("photograph") della scheda SD. Il file ottenuto verrà utilizzato per il ripristino del sistema. @@ -157,4 +174,3 @@ dove `/dev/mmcblk0` sarà il vostro supporto (scheda SD o disco). [/ui-tab] [/ui-tabs] - diff --git a/pages/02.administer/20.backups/15.clone_filesystem/clone_filesystem.md b/pages/02.administer/20.backups/15.clone_filesystem/clone_filesystem.md index f58727ab..9d32b1d1 100644 --- a/pages/02.administer/20.backups/15.clone_filesystem/clone_filesystem.md +++ b/pages/02.administer/20.backups/15.clone_filesystem/clone_filesystem.md @@ -19,6 +19,7 @@ Making full system images can be a complementary or alternative way to backup yo Depending on your type of installation, you can either create a snapshot or clone the storage medium by removing it from your server (turned off). ## Trigger a snapshot + A snapshot allows you to freeze an image of the file system. Snapshots are very useful when doing an update or testing, because they allow you to easily go back in case of a glitch. On the other hand, apart from some very high availability clusters, snapshots do not really protect you against hardware failures or disasters (cf. OVH fire in Strasbourg in 2021). In general, snapshots are quite disk space saving, the principle is that your file system will store the differences that occurred since your snapshot. Thus, only the modifications consume space. @@ -30,10 +31,11 @@ You can use this method with most VPS (often paying), virtual machine managers o [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="VPS"] Below, some documentation for the most known suppliers: - * [DigitalOcean (EN)](https://docs.digitalocean.com/products/images/snapshots/) - * [Gandi](https://docs.gandi.net/fr/simple_hosting/operations_courantes/snapshots.html) - * [OVH](https://docs.ovh.com/fr/vps/snapshot-vps/) - * [Scaleway (EN)](https://www.scaleway.com/en/docs/backup-your-data-with-snapshots/) + +- [DigitalOcean (EN)](https://docs.digitalocean.com/products/images/snapshots/) +- [Gandi](https://docs.gandi.net/fr/simple_hosting/operations_courantes/snapshots.html) +- [OVH](https://docs.ovh.com/fr/vps/snapshot-vps/) +- [Scaleway (EN)](https://www.scaleway.com/en/docs/backup-your-data-with-snapshots/) [/ui-tab] [ui-tab title="VirtualBox"] Select the virtual machine and click `Snapshots`, then specify the snapshot name and click `OK`. @@ -47,36 +49,41 @@ Then click on `Restore Snapshot`. [/ui-tab] [ui-tab title="Proxmox"] - * Select the virtual machine - * Go to the `Backup` tab - * Click on `Backup now`. - * Choose `Snapshot` mode - * Validate +- Select the virtual machine +- Go to the `Backup` tab +- Click on `Backup now`. +- Choose `Snapshot` mode +- Validate [/ui-tab] [ui-tab title="BTRFS"] Below we consider that `/pool/volume` is the volume to snapshot. Create a read-only snapshot -``` + +```bash btrfs subvolume snapshot /pool/volume /pool/volume/$(date +"%Y-%m-%d_%H:%M") ``` List snapshots -``` + +```bash btrfs subvolume show /pool/volume ``` Restore a snapshot -``` + +```bash btrfs sub del /pool/volume btrfs sub snap /pool/volume/2021-07-22_16:12 /pool/volume btrfs sub del /pool/volume/2021-07-22_16:12 ``` Delete a snapshot -``` + +```bash btrfs subvolume delete /pool/volume/2021-07-22_16:12 ``` + !! Be careful not to delete the original volume !!! See [this tutorial](https://www.linux.com/training-tutorials/how-create-and-manage-btrfs-snapshots-and-rollbacks-linux-part-2/) for more info @@ -85,52 +92,61 @@ btrfs subvolume delete /pool/volume/2021-07-22_16:12 Below we consider that `pool/volume` is the volume to snapshot. Create a snapshot -``` + +```bash rbd snap create pool/volume@$(date +"%Y-%m-%d_%H:%M") ``` List snapshots -``` + +```bash rbd snap ls pool/volume ``` Restore a snapshot -``` + +```bash rbd snap rollback pool/volume@2021-07-22_16:22 ``` Delete a snapshot -``` + +```bash rbd snap rm pool/volume@2021-07-22_16:12 ``` + [/ui-tab] [ui-tab title="ZFS"] Below we consider that `pool/volume` is the volume to snapshot. Create a snapshot -``` + +```bash zfs snapshot pool/volume@$(date +"%Y-%m-%d_%H:%M") ``` List snapshots -``` + +```bash zfs list -t snapshot -o name,creation ``` + Restore a snapshot -``` + +```bash zfs rollback pool/volume@2021-07-22_16:22 ``` Delete a snapshot -``` + +```bash zfs destroy pool/volume@2021-07-22_16:12 ``` [/ui-tab] [/ui-tabs] - -## Create a cold image of the file system +## Create a cold image of the file system You can clone your media (SD card, ssd disk, VPS volume...) to create a disk image. This image before compression will be the exact size of your media, that's why this method applies rather to machines of less than 64GB. @@ -139,6 +155,7 @@ Unless you can read a snapshot, this method requires you to stop the server whil [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="With USBimager"] This can be done with [USBimager](https://bztsrc.gitlab.io/usbimager/) (Note: make sure you download the 'Read-write' version! Not the 'Write-only' version!). The process then consists of the "reverse" of the SD card flashing process: + - Turn off your server - Retrieve the SD card and plug it into your computer - In USBimager, click on "Read" to create an image ("photograph") of the SD card. You can use the resulting file to restore the whole system later. @@ -157,4 +174,3 @@ dd if=/dev/mmcblk0 | gzip > ./my_snapshot.gz [/ui-tab] [/ui-tabs] - diff --git a/pages/02.administer/20.backups/20.avoid_hardware_failure/avoid_hardware_failure.fr.md b/pages/02.administer/20.backups/20.avoid_hardware_failure/avoid_hardware_failure.fr.md index 4d32160c..ec9e10d8 100644 --- a/pages/02.administer/20.backups/20.avoid_hardware_failure/avoid_hardware_failure.fr.md +++ b/pages/02.administer/20.backups/20.avoid_hardware_failure/avoid_hardware_failure.fr.md @@ -11,29 +11,38 @@ page-toc: --- ## Sécuriser physiquement votre serveur + Très souvent les personnes qui s'autohébergent n'ont pas de rangement correct pour leur système. Laisser le serveur en plusieurs parties, dans un lieu de passage, accessible à des enfants ou des animaux, ou dans un endroit peu aéré peut vite tourner à la catastrophe. ## Fixer vos disques durs + Idéalement, vos disques durs doivent être fixés pour éviter les vibrations qui peuvent accélérer l'usure du matériel voire atténuer ses performances, notamment s'il y a un autre disque à côté. ## Réduire la swapiness pour les cartes SD et disques SSD + Si vous utilisez un fichier de swap avec un SSD ou une carte SD avec une swapiness trop élevée, votre support de stockage pourrait rendre l'âme prématurément en raison d'un trop grand nombre d'écritures. Pour éviter ça: -``` + +```bash cat /proc/sys/vm/swappiness ``` + Si elle est au-dessus de 10: -``` + +```bash sysctl vm.swappiness=10 nano /etc/sysctl.conf ``` + Si la ligne est présente, changez la valeur vm.swappiness à 10.Sinon, ajoutez la ligne: -``` + +```text vm.swappiness = 10 ``` ## Redondance de stockage + Afin de limiter les pannes matérielles des supports de stockage, il peut être pertinent de mettre en place une grappe de disques en miroir (RAID, ZFS). L'idée ici est que tout ce qui est écrit sur un disque le sera sur l'autre. Ainsi, si l'un tombe en panne, l'autre continue de fonctionner et le serveur est toujours pleinement fonctionnel. Il existe aussi des grappes plus évoluées qui maximisent la tolérance de panne (panne de 2 disques comme le RAID6) ou le stockage (voir RAID 5). @@ -41,11 +50,12 @@ Il existe aussi des grappes plus évoluées qui maximisent la tolérance de pann Toutefois, ces techniques de grappes de disques ne devraient pas être considérées comme des copies de sauvegarde. Une grappe RAID devrait être considérée comme un seul support de stockage. En effet, si cette technique permet d'éviter de devoir réinstaller en cas de crash probable d'un disque, on est loin du risque zéro. Quelques exemples de situations connues des administrateurs systèmes professionnels: -* les disques d'une grappe montée avec des disques de la même marque peuvent tomber en panne quasiment en même temps en moins de quelques heures -* sans monitoring de la santé des disques, il y a de fortes chances que l'on ne remarque la panne d'un disque de la grappe que lorsqu'un deuxième tombe en panne (><) -* si on n'a pas de disque de rechange, le délai d'achat peut aboutir à un crash de l'autre disque -* un disque à moitié fonctionnel qui produit des erreurs peut propager son erreur à travers la grappe -* les connectiques des disques ou le contrôleur RAID peuvent produire des erreurs aussi ou tomber en panne -* plus on complexifie l'architecture avec de nombreux composants, plus il y a de chances que l'un d'eux tombe en panne + +- les disques d'une grappe montée avec des disques de la même marque peuvent tomber en panne quasiment en même temps en moins de quelques heures +- sans monitoring de la santé des disques, il y a de fortes chances que l'on ne remarque la panne d'un disque de la grappe que lorsqu'un deuxième tombe en panne (><) +- si on n'a pas de disque de rechange, le délai d'achat peut aboutir à un crash de l'autre disque +- un disque à moitié fonctionnel qui produit des erreurs peut propager son erreur à travers la grappe +- les connectiques des disques ou le contrôleur RAID peuvent produire des erreurs aussi ou tomber en panne +- plus on complexifie l'architecture avec de nombreux composants, plus il y a de chances que l'un d'eux tombe en panne !!! Si vous souhaitez mettre en place une grappe RAID ou utiliser btrfs, le plus simple est de le faire à l'installation avec l'iso YunoHost en mode expert (lors du partitionnement du système). diff --git a/pages/02.administer/20.backups/20.avoid_hardware_failure/avoid_hardware_failure.it.md b/pages/02.administer/20.backups/20.avoid_hardware_failure/avoid_hardware_failure.it.md index 75e3858a..b4325629 100644 --- a/pages/02.administer/20.backups/20.avoid_hardware_failure/avoid_hardware_failure.it.md +++ b/pages/02.administer/20.backups/20.avoid_hardware_failure/avoid_hardware_failure.it.md @@ -12,29 +12,38 @@ page-toc: ## Rendere sicuro fisicamente il tuo server + Frequentemente la persone che fanno selfhosting non dispongono di spazi adatti per posizionare il proprio server. Posizionare il server, o parti di esso, in un luogo di passaggio, accessibile a bambini o animali, o in un luogo poco ventilato, può avere conseguenze catastrofiche. ## Fissate i vostri HD + Sarebbe opportuno fissare saldamente i propri hard disk al fine di evitare vibrazioni che provocano usura prematura del disco, o ne pregiudicano le performance, in particolar modo se si trovano vicini ad altri dischi. ## Ridurre lo swapiness nelle schede SD e nei dischi SSD + Se utilizzate un file di swap, in un disco SSD o in una scheda SD, con uno swapiness troppo elevato correte il serio rischio di usurare prematuramente il vostro supporto a causa di un numero eccessivo di scritture sul disco. Per evitare il problema -``` + +```bash cat /proc/sys/vm/swappiness ``` + Se il comando restituisce un valore superiore a 10: -``` + +```bash sysctl vm.swappiness=10 nano /etc/sysctl.conf ``` + Se la riga è presente, cambiate il valore vm.swappiness con 10. In caso contrario aggiungete la riga: -``` + +```text vm.swappiness = 10: ``` ## Ridondanza dei supporti + Al fine di limitare i guasti dei supporti si dovrebbe ricorrere ad un cluster di dischi in modalità mirror (RAID, ZFS). Il concetto è che tutto quello che verrà scritto su un disco verrà scritto anche negli altri. In questo modo se un disco subisce un guasto, gli altri garantiranno la funzionalità del server. Altre configurazioni più evolute, migliorano la tolleranza ai guasti (guasto di 2 dischi nel RAID6) o la suddivisione dei dati (RAID 5). @@ -42,11 +51,12 @@ Altre configurazioni più evolute, migliorano la tolleranza ai guasti (guasto di Comunque i sistemi RAID non vanno considerati come metodi di backup. Un RAID deve essere considerato un normale supporto dei dati. Se questo sistema permette di evitare reinstallazioni in caso di guasto ad un disco, esso non ci garantisce che i nostri dati non correranno nessun rischio. Alcune situazioni ben conosciute dagli amministratori di sistema. -* i dischi di un cluster creato con dischi della stessa marca possono guastarsi quasi contemporaneamente nel giro di poche ore -* se non monitoriamo lo stato di salute dei nostri dischi, probabilmente ci accorgeremo di un problema ai dischi della configurazione RAID solo quando si guasterà un secondo disco (><) -* se non abbiamo un HD di scorta, nell'attesa che arrivi il disco nuovo per sostituire quello danneggiato, si guasterà anche l'altro -* un disco che non funziona correttamente può provocare errori in tutta la catena -* anche i controller RAID o i connettori possono guastarsi o dare errori -* più complessa è la nostra catena, maggiori sono le possibilità di un guasto + +- i dischi di un cluster creato con dischi della stessa marca possono guastarsi quasi contemporaneamente nel giro di poche ore +- se non monitoriamo lo stato di salute dei nostri dischi, probabilmente ci accorgeremo di un problema ai dischi della configurazione RAID solo quando si guasterà un secondo disco (><) +- se non abbiamo un HD di scorta, nell'attesa che arrivi il disco nuovo per sostituire quello danneggiato, si guasterà anche l'altro +- un disco che non funziona correttamente può provocare errori in tutta la catena +- anche i controller RAID o i connettori possono guastarsi o dare errori +- più complessa è la nostra catena, maggiori sono le possibilità di un guasto !!! Se pianificate di creare una catena RAID o utilizzare il filesystem btrfs, la procedura più semplice è quella di installare YunoHost in modalità esperto (nella parte relativa alle partizioni del disco). diff --git a/pages/02.administer/20.backups/20.avoid_hardware_failure/avoid_hardware_failure.md b/pages/02.administer/20.backups/20.avoid_hardware_failure/avoid_hardware_failure.md index 1d8e8865..30fe81e5 100644 --- a/pages/02.administer/20.backups/20.avoid_hardware_failure/avoid_hardware_failure.md +++ b/pages/02.administer/20.backups/20.avoid_hardware_failure/avoid_hardware_failure.md @@ -12,29 +12,38 @@ page-toc: ## Physically secure your server + Very often people who self-host don't have proper storage for their system. Leaving the server in several parts, in a high traffic area, accessible to children or pets, or in a poorly ventilated area can quickly turn into a disaster. ## Secure your hard drives + Ideally, your hard disks should be fixed to avoid vibrations which can accelerate the wear of the equipment or even reduce its performance, especially if there is another disk next to it. ## Reduce swapiness for SD cards and SSDs + If you use a swap file with an SSD or SD card with too much swapiness, your storage media could give up the ghost prematurely due to too many writes. To avoid this: -``` + +```bash cat /proc/sys/vm/swappiness ``` + If it is above 10: -``` + +```bash sysctl vm.swappiness=10 nano /etc/sysctl.conf ``` + If present, change the vm.swappiness value to 10. Otherwise add the line: -``` + +```text vm.swappiness = 10 ``` ## Storage redundancy + In order to limit hardware failures of storage media, it can be relevant to set up a cluster of mirrored disks (RAID, ZFS). The idea here is that everything that is written to one disk will be written to the other. This way, if one fails, the other continues to work and the server is still fully functional. There are also more advanced clusters that maximize fault tolerance (failure of 2 disks like RAID6) or storage (see RAID 5). @@ -42,11 +51,12 @@ There are also more advanced clusters that maximize fault tolerance (failure of However, these disk clustering techniques should not be considered as backups. A RAID array should be considered as a single storage medium. Indeed, if this technique avoids having to reinstall in case of a probable disk crash, it is far from zero risk. Some examples of situations known to professional system administrators: -* the disks of a cluster mounted with disks of the same brand can fail almost at the same time within a few hours -* without monitoring the health of the disks, there is a good chance that the failure of one disk in the cluster will only be noticed when a second one fails (><) -* if you don't have a spare disk, the delay in purchasing one may result in the other disk crashing -* a half-functional disk that produces errors can propagate its error through the cluster -* the disk connectors or the RAID controller can also produce errors or fail -* the more complex you make the architecture with many components, the more likely it is that one of them will fail + +- the disks of a cluster mounted with disks of the same brand can fail almost at the same time within a few hours +- without monitoring the health of the disks, there is a good chance that the failure of one disk in the cluster will only be noticed when a second one fails (><) +- if you don't have a spare disk, the delay in purchasing one may result in the other disk crashing +- a half-functional disk that produces errors can propagate its error through the cluster +- the disk connectors or the RAID controller can also produce errors or fail +- the more complex you make the architecture with many components, the more likely it is that one of them will fail !!! If you want to set up a RAID array or use btrfs, the easiest way is to do it at installation with the YunoHost iso in expert mode (when partitioning the system). diff --git a/pages/02.administer/20.backups/25.include_exclude_files/include_exclude_files.fr.md b/pages/02.administer/20.backups/25.include_exclude_files/include_exclude_files.fr.md index d36f8429..0c29a2f0 100644 --- a/pages/02.administer/20.backups/25.include_exclude_files/include_exclude_files.fr.md +++ b/pages/02.administer/20.backups/25.include_exclude_files/include_exclude_files.fr.md @@ -18,7 +18,8 @@ Par défaut, si des configurations suivies par YunoHost sont modifiées, elles s Vous pouvez créer un hook de sauvegarde et un hook de restauration pour ajouter des données à sauvegarder. Ci-dessous un exemple: -/etc/yunohost/hooks.d/backup/99-conf_custom +`/etc/yunohost/hooks.d/backup/99-conf_custom` + ```bash #!/bin/bash @@ -58,7 +59,8 @@ ynh_backup "/etc/yunohost/hooks.d/backup/99-conf_custom" ynh_backup "/etc/yunohost/hooks.d/restore/99-conf_custom" ``` -/etc/yunohost/hooks.d/restore/99-conf_custom +`/etc/yunohost/hooks.d/restore/99-conf_custom` + ```bash #!/bin/bash @@ -105,9 +107,11 @@ ynh_restore_file "/etc/yunohost/hooks.d/restore/99-conf_custom" ``` ## Exclure des fichiers + Il n'existe pas de mécanisme pour exclure d'une sauvegarde au format YunoHost des fichiers spécifiques, en dehors des 2 options présentées ci-dessous: ### Éviter de sauvegarder certains dossiers du `/home` + Si besoin, vous pouvez spécifier que certains dossiers `home` d'utilisateurs ou utilisatrices ne soient pas sauvegardés par la commande `yunohost backup`, en créant un fichier vide nommé `.nobackup` à l'intérieur. Attention ce mécanisme ne fonctionne que pour les **sous-dossiers de premier niveau** du `/home`, comme par exemple `/home/user1` ou `/home/yunohost.multimedia` . Cela ne fonctionne pas pour les autres dossiers ou sous-dossiers, comme par exemple `/home/user1/grosdossier`. @@ -117,7 +121,8 @@ Attention ce mécanisme ne fonctionne que pour les **sous-dossiers de premier ni Certaines apps comme Nextcloud sont potentiellement rattachées à des quantités importantes de données. Il est possible de ne pas les sauvegarder par défaut. Dans ce cas, on dit que l'app "sauvegarde uniquement le core" (de l'app). Lors d'une mise à jour, les apps contenant une grande quantité de données effectuent généralement une sauvegarde sans ces données. -Pour désactiver temporairement la sauvegarde des données volumineuses, pour les applications qui implémentent cette fonctionnalité, vous pouvez définir la variable `BACKUP_CORE_ONLY`. Pour ce faire, la variable doit être définie avant la commande de backup : +Pour désactiver temporairement la sauvegarde des données volumineuses, pour les applications qui implémentent cette fonctionnalité, vous pouvez définir la variable `BACKUP_CORE_ONLY`. Pour ce faire, la variable doit être définie avant la commande de backup : + ```bash BACKUP_CORE_ONLY=1 yunohost backup create --apps nextcloud ``` @@ -125,7 +130,7 @@ BACKUP_CORE_ONLY=1 yunohost backup create --apps nextcloud Faites montre de prudence : il vous faudra alors sauvegarder vous-même les données des utilisateurs et utilisatrices de Nextcloud. Si vous souhaitez que ce comportement soit permanent: + ```bash yunohost app setting nextcloud do_not_backup_data -v 1 ``` - diff --git a/pages/02.administer/20.backups/25.include_exclude_files/include_exclude_files.it.md b/pages/02.administer/20.backups/25.include_exclude_files/include_exclude_files.it.md index a275c742..d50b4199 100644 --- a/pages/02.administer/20.backups/25.include_exclude_files/include_exclude_files.it.md +++ b/pages/02.administer/20.backups/25.include_exclude_files/include_exclude_files.it.md @@ -18,8 +18,8 @@ YunoHost tiene traccia delle modifiche effettuate utilizzando gli strumenti di d Potete creare un hook di backup e un hook di ripristino per aggiungere i file da salvare. Esempio: +`/etc/yunohost/hooks.d/backup/99-conf_custom` -/etc/yunohost/hooks.d/backup/99-conf_custom ```bash #!/bin/bash @@ -59,7 +59,8 @@ ynh_backup "/etc/yunohost/hooks.d/backup/99-conf_custom" ynh_backup "/etc/yunohost/hooks.d/restore/99-conf_custom" ``` -/etc/yunohost/hooks.d/restore/99-conf_custom +`/etc/yunohost/hooks.d/restore/99-conf_custom` + ```bash #!/bin/bash @@ -105,12 +106,12 @@ ynh_restore_file "/etc/yunohost/hooks.d/backup/99-conf_custom" ynh_restore_file "/etc/yunohost/hooks.d/restore/99-conf_custom" ``` - - ## Escludere file + Esistono solo due metodi per escludere file dal backup di YunoHost: ### Escludere alcune cartelle presenti in `/home` + Se necessario potete specificare quali cartelle nella `home` di un utente non siano da includere nel comando `yunohost backup`, creando al loro interno un file vuoto con l'estensione `.nobackup`. Attenzione: questo metodo funziona solo con la **prima sottodirectory di `/home`** ad esempio `/home/user1` o `/home/yunohost.multimedia`. Al contrario non funzionerà per altre sottodirectory come `/home/user1/miacartella`. @@ -120,8 +121,8 @@ Attenzione: questo metodo funziona solo con la **prima sottodirectory di `/home` Alcuni programmi come Nextcloud sono potenzialmente accompagnati da grandi quantità di dati. In questi casi viene fatto il backup solo del programma stesso (il "core"). Generalmente negli aggiornamenti dei programmi che contengono grandi quantità di dati, questi vengono esclusi dal backup. - Per disattivare temporaneamente, nei programmi che supportano tale procedura, il backup di file di grandi dimensioni potete definire la variabile `BACKUP_CORE_ONLY`. La variabile deve essere definita prima di eseguire il comando di backup: + ```bash BACKUP_CORE_ONLY=1 yunohost backup create --apps nextcloud ``` @@ -129,6 +130,7 @@ BACKUP_CORE_ONLY=1 yunohost backup create --apps nextcloud Attenzione: dovrete procedere fare backup dei dati degli utenti Nextcloud separatamente. Se volete rendere permanente l'impostazione: + ```bash yunohost app setting nextcloud do_not_backup_data -v 1 ``` diff --git a/pages/02.administer/20.backups/25.include_exclude_files/include_exclude_files.md b/pages/02.administer/20.backups/25.include_exclude_files/include_exclude_files.md index a99ed2ac..57d51818 100644 --- a/pages/02.administer/20.backups/25.include_exclude_files/include_exclude_files.md +++ b/pages/02.administer/20.backups/25.include_exclude_files/include_exclude_files.md @@ -18,8 +18,8 @@ By default, if configurations tracked by YunoHost are changed, they will be back You can create a backup hook and a restore hook to add data to backup. Here is an example: +`/etc/yunohost/hooks.d/backup/99-conf_custom` -/etc/yunohost/hooks.d/backup/99-conf_custom ```bash #!/bin/bash @@ -59,7 +59,8 @@ ynh_backup "/etc/yunohost/hooks.d/backup/99-conf_custom" ynh_backup "/etc/yunohost/hooks.d/restore/99-conf_custom" ``` -/etc/yunohost/hooks.d/restore/99-conf_custom +`/etc/yunohost/hooks.d/restore/99-conf_custom` + ```bash #!/bin/bash @@ -105,12 +106,12 @@ ynh_restore_file "/etc/yunohost/hooks.d/backup/99-conf_custom" ynh_restore_file "/etc/yunohost/hooks.d/restore/99-conf_custom" ``` - - ## Exclude files + There is no mechanism to exclude specific files from a YunoHost backup, other than the 2 options presented below: ### Avoid backing up certain `/home` folders + If needed, you can specify that certain user `home` folders not be backed up by the `yunohost backup` command, by creating an empty file named `.nobackup` inside. Caution: this setup only works with **first-level subfolders of `/home`**, such as `/home/user1` or `/home/yunohost.multimedia`. It does not work for other levels of subfolders, like `/home/user1/bigfolder/`. @@ -120,8 +121,8 @@ Caution: this setup only works with **first-level subfolders of `/home`**, such Some apps like Nextcloud are potentially attached to large amounts of data. It is possible to not backup them by default. In this case, the app is said to "backup only the core" (of the app). During an update, apps containing a large amount of data usually make a backup without these data. +To temporarily disable backup of large data, for applications that implement this feature, you can set the `BACKUP_CORE_ONLY` variable. To do this, the variable must be set before the backup command: -To temporarily disable backup of large data, for applications that implement this feature, you can set the `BACKUP_CORE_ONLY` variable. To do this, the variable must be set before the backup command: ```bash BACKUP_CORE_ONLY=1 yunohost backup create --apps nextcloud ``` @@ -129,7 +130,7 @@ BACKUP_CORE_ONLY=1 yunohost backup create --apps nextcloud Be careful: you will have to backup Nextcloud users' data yourself. If you want this behavior to be permanent: + ```bash yunohost app setting nextcloud do_not_backup_data -v 1 ``` - diff --git a/pages/02.administer/20.backups/30.custom_backup_methods/custom_backup_methods.fr.md b/pages/02.administer/20.backups/30.custom_backup_methods/custom_backup_methods.fr.md index 31570cc1..7e03aae7 100644 --- a/pages/02.administer/20.backups/30.custom_backup_methods/custom_backup_methods.fr.md +++ b/pages/02.administer/20.backups/30.custom_backup_methods/custom_backup_methods.fr.md @@ -13,13 +13,15 @@ page-toc: Il est possible de créer votre propre méthode de sauvegarde et de la lier au système de collecte de fichiers à sauvegarder de YunoHost. Ceci peut être utile si vous souhaitez utiliser votre propre logiciel de sauvegarde ou mener des opérations de montages démontages de disques par exemple. Cette opération se fait à l'aide d'un hook et vous permettra de lancer une sauvegarde de cette façon: -``` + +```bash yunohost backup create --method custom ``` Ci-dessous, un exemple simpliste qui peut permettre de mettre en place un backup rotationnel avec différents disques que l'on change toutes les semaines: -/etc/yunohost/hooks.d/backup_method/05-custom +`/etc/yunohost/hooks.d/backup_method/05-custom` + ```bash #!/bin/bash set -euo pipefail diff --git a/pages/02.administer/20.backups/30.custom_backup_methods/custom_backup_methods.it.md b/pages/02.administer/20.backups/30.custom_backup_methods/custom_backup_methods.it.md index de2e2cb9..ab1b9559 100644 --- a/pages/02.administer/20.backups/30.custom_backup_methods/custom_backup_methods.it.md +++ b/pages/02.administer/20.backups/30.custom_backup_methods/custom_backup_methods.it.md @@ -10,17 +10,18 @@ page-toc: depth: 3 --- - È possibile creare un proprio metodo di backup e includerlo nel sistema di raccolta file di backup di YunoHost. Questo può essere utilizzato ad esempio, nel caso utilizziate un particolare programma di backup o vogliate effettuare delle operazioni di montaggio o smontaggio sui vostri HD. Dovrete creare un hook che lancerà il backup utilizzando il metodo personalizzato con questo comando: -``` + +```bash yunohost backup create --method custom ``` Di seguito un esempio, semplificato, che esegue il backup con rotazione dei dischi, che vengono sostituiti ogni settimana. -/etc/yunohost/hooks.d/backup_method/05-custom +`/etc/yunohost/hooks.d/backup_method/05-custom` + ```bash #!/bin/bash set -euo pipefail diff --git a/pages/02.administer/20.backups/30.custom_backup_methods/custom_backup_methods.md b/pages/02.administer/20.backups/30.custom_backup_methods/custom_backup_methods.md index 5f27a37b..2c542042 100644 --- a/pages/02.administer/20.backups/30.custom_backup_methods/custom_backup_methods.md +++ b/pages/02.administer/20.backups/30.custom_backup_methods/custom_backup_methods.md @@ -10,17 +10,18 @@ page-toc: depth: 3 --- - It is possible to create your own backup method and link it to YunoHost's backup file collection system. This can be useful if you want to use your own backup software or conduct disk mount/dismount operations for example. This operation is done with a hook and will allow you to launch a backup this way: -``` + +```bash yunohost backup create --method custom ``` Below is a simplistic example that can be used to set up a rotational backup with different disks that are changed every week: -/etc/yunohost/hooks.d/backup_method/05-custom +`/etc/yunohost/hooks.d/backup_method/05-custom` + ```bash #!/bin/bash set -euo pipefail diff --git a/pages/02.administer/20.backups/35.migrate_or_merge_servers/migrate_or_merge_servers.fr.md b/pages/02.administer/20.backups/35.migrate_or_merge_servers/migrate_or_merge_servers.fr.md index c6f1aa8f..531d4dc0 100644 --- a/pages/02.administer/20.backups/35.migrate_or_merge_servers/migrate_or_merge_servers.fr.md +++ b/pages/02.administer/20.backups/35.migrate_or_merge_servers/migrate_or_merge_servers.fr.md @@ -15,6 +15,7 @@ page-toc: Si le système d'archive de YunoHost est assez pratique pour migrer un serveur, on peut aussi [migrer de serveur à serveur avec rsync](https://www.man42.net/blog/2017/07/how-to-migrate-a-debian-server/). ## Fusionner 2 serveurs YunoHost -Si vous fusionnez 2 serveurs ensemble, vous devrez recréer les utilisateurs et utilisatrices, ainsi que les domaines et les permissions du premier serveur sur le serveur de destination. Puis vous pourrez restaurer app par app. + +Si vous fusionnez 2 serveurs ensemble, vous devrez recréer les utilisateurs et utilisatrices, ainsi que les domaines et les permissions du premier serveur sur le serveur de destination. Puis vous pourrez restaurer app par app. !! Il existe tout de même une limite concernant les apps qui ont le même ID. Il ne sera pas possible de les restaurer facilement. Attention également à ne pas supprimer l'app éponyme du serveur de destination :/ diff --git a/pages/02.administer/20.backups/35.migrate_or_merge_servers/migrate_or_merge_servers.it.md b/pages/02.administer/20.backups/35.migrate_or_merge_servers/migrate_or_merge_servers.it.md index 4fe9cb8b..93a8aa09 100644 --- a/pages/02.administer/20.backups/35.migrate_or_merge_servers/migrate_or_merge_servers.it.md +++ b/pages/02.administer/20.backups/35.migrate_or_merge_servers/migrate_or_merge_servers.it.md @@ -16,6 +16,7 @@ page-toc: Il sistema di archiviazione di YunoHost permette di migrare facilmente un server ma potete anche seguire [questo link per migrare un server ad un altro con rsync](https://www.man42.net/blog/2017/07/how-to-migrate-a-debian-server/). ## Aggregare 2 server YunoHost + Se volete aggregare 2 server dovrete ricreare i domini, gli account utenti e i relativi permessi dal primo al server di destinazione. In seguito potrete ripristinare i programmi uno alla volta. !! Esiste però un limite che riguarda i programmi che hanno lo stesso ID che saranno difficilmente ripristinabili. Abbiate cura di non cancellare il programma eponymous del server di destinazione :/ diff --git a/pages/02.administer/20.backups/35.migrate_or_merge_servers/migrate_or_merge_servers.md b/pages/02.administer/20.backups/35.migrate_or_merge_servers/migrate_or_merge_servers.md index 64daf853..f5a19ea6 100644 --- a/pages/02.administer/20.backups/35.migrate_or_merge_servers/migrate_or_merge_servers.md +++ b/pages/02.administer/20.backups/35.migrate_or_merge_servers/migrate_or_merge_servers.md @@ -16,6 +16,7 @@ page-toc: If YunoHost's archive system is not convenient enough to migrate a server, you can also [migrate from server to server with rsync](https://www.man42.net/blog/2017/07/how-to-migrate-a-debian-server/). ## Merge 2 YunoHost servers -If you merge 2 servers together, you will need to recreate the users, domains and permissions of the first server on the destination server. Then you can restore app by app. + +If you merge 2 servers together, you will need to recreate the users, domains and permissions of the first server on the destination server. Then you can restore app by app. !! There is a limitation concerning apps that have the same ID. It will not be possible to restore them easily. Also be careful not to delete the eponymous app from the destination server :/ diff --git a/pages/02.administer/45.tutorials/05.domains/01.dns_nohost_me/dns_nohost_me.es.md b/pages/02.administer/45.tutorials/05.domains/01.dns_nohost_me/dns_nohost_me.es.md index a3aa8723..6449a5cf 100644 --- a/pages/02.administer/45.tutorials/05.domains/01.dns_nohost_me/dns_nohost_me.es.md +++ b/pages/02.administer/45.tutorials/05.domains/01.dns_nohost_me/dns_nohost_me.es.md @@ -10,6 +10,7 @@ routes: Para hacer que el auto-alojamiento esté lo más accesible posible, el Proyecto YunoHost provee un servicio de nombres de dominio *ofertos* y *automáticamente configurados*. Cuando utilizas este servicio, no tienes que configurar tú mismo la [configuración de los registros DNS](/dns_config) que es bastante técnica. Los subdominios siguientes están propuestos : + - `loquequieras.nohost.me` ; - `loquequieras.noho.st` ; - `loquequieras.ynh.fr`. @@ -55,8 +56,9 @@ Si reinstalas tu servidor y quieres utilizar un dominio automático que ya utili ### Cambiar un dominio nohost.me, noho.st o ynh.fr Si quieres utilizar otro dominio automático en tu servidor, primero tienes que cancelar el que ya está configurado, siguiendo estas instrucciones : + 1. Suprimir el dominio de tu instancia (vía webadmin o `yunohost domain remove`). **Cuidado : esto suprimirá todas las aplicaciones instaladas en este dominio así como sus datos**. 2. Pedir la supresión de tu suscripción [en el hilo de discusión dedicado del foro](https://forum.yunohost.org/t/nohost-domain-recovery/442). 3. Suprimir los archivos de configuración automática de tu instancia (únicamente desde la linea de comando por ahora) : `sudo rm /etc/cron.d/yunohost-dyndns && sudo rm -r /etc/yunohost/dyndns` -Luego podrás registrar un nuevo dominio automático. +Luego podrás registrar un nuevo dominio automático. diff --git a/pages/02.administer/45.tutorials/05.domains/01.dns_nohost_me/dns_nohost_me.fr.md b/pages/02.administer/45.tutorials/05.domains/01.dns_nohost_me/dns_nohost_me.fr.md index 0a0897a3..270c9570 100644 --- a/pages/02.administer/45.tutorials/05.domains/01.dns_nohost_me/dns_nohost_me.fr.md +++ b/pages/02.administer/45.tutorials/05.domains/01.dns_nohost_me/dns_nohost_me.fr.md @@ -10,6 +10,7 @@ routes: Afin de rendre l'auto-hébergement le plus accessible possible, le Projet YunoHost fournit un service de noms de domaine *offerts* et *automatiquement configurés*. En utilisant ce service, vous n'avez donc pas à réaliser vous-même la [configuration des enregistrements DNS](/dns_config) qui est assez technique. Les (sous-)domaines suivants sont proposés : + - `cequevousvoulez.nohost.me` ; - `cequevousvoulez.noho.st` ; - `cequevousvoulez.ynh.fr`. @@ -24,7 +25,7 @@ Le service de domaines `nohost.me`, `noho.st` et `ynh.fr` autorise la création YunoHost permet l'installation d'applications sur des sous-domaines (par exemple avoir l'application ownCloud accessible depuis l'adresse `cloud.mondomaine.org`), cette fonctionnalité est aussi permise avec les domaines `nohost.me`, `noho.st` et `ynh.fr` et il est donc possible d’avoir un sous-sous-domaine tel `monapplication.mondomaine.nohost.me`. -Pour créer un sous domaine à un domaine `nohost.me`, `noho.st` et `ynh.fr` il suffit d'ajouter celui-ci à YunoHost de la même manière que n'importe quel autre nom de domaine. +Pour créer un sous domaine à un domaine `nohost.me`, `noho.st` et `ynh.fr` il suffit d'ajouter celui-ci à YunoHost de la même manière que n'importe quel autre nom de domaine. ### Ajouter un domaine nohost.me, noho.st ou ynh.fr après la post-installation @@ -57,6 +58,7 @@ Si vous réinstallez votre serveur et voulez utiliser un domaine automatique dé ### Changer un domaine nohost.me, noho.st ou ynh.fr Si vous voulez utiliser un autre domaine automatique sur votre serveur, vous devez d'abord supprimer celui qui est déjà configuré, selon les instructions suivantes : + 1. Supprimer le domaine de votre instance (par webadmin ou `yunohost domain remove`). **Attention : cela supprimera toute application installée sur ce domaine, ainsi que ses données**. 2. Demander la suppression de votre souscription [dans le fil de discussion dédié du forum](https://forum.yunohost.org/t/nohost-domain-recovery/442). 3. Enlever les fichiers de configuration automatique sur votre instance (uniquement depuis la ligne de commande pour le moment) : `sudo rm /etc/cron.d/yunohost-dyndns && sudo rm -r /etc/yunohost/dyndns` diff --git a/pages/02.administer/45.tutorials/05.domains/01.dns_nohost_me/dns_nohost_me.it.md b/pages/02.administer/45.tutorials/05.domains/01.dns_nohost_me/dns_nohost_me.it.md index 299f3174..2869d1b4 100644 --- a/pages/02.administer/45.tutorials/05.domains/01.dns_nohost_me/dns_nohost_me.it.md +++ b/pages/02.administer/45.tutorials/05.domains/01.dns_nohost_me/dns_nohost_me.it.md @@ -8,8 +8,9 @@ routes: --- Al fine di rendere il self-hosting accessibile al maggior numero di persone, il progetto YunoHost fornisce un servizio *gratuito* di nomi di dominio *configurati automaticamente*. Utilizzando questo servizio non dovrete [configurare i record DNS](/dns_config), in generale un'operazione abbastanza complessa. - + Potete scegliere tra i (sotto-) domini seguenti: + - `miosito.nohost.me`; - `miosito.noho.st`; - `miosito.ynh.fr`. @@ -24,9 +25,9 @@ Il servizio di domini `nohost.me`, `noho.st` e `ynh.fr` permette la creazione di YunoHost permette l'installazione di applicazioni in sotto domini (ad esempio avere l'applicazione NextCloud accessibile dall'indirizzo `cloud.miosito.org`), e questa funzionalità è permessa anche con i domini `nohost.me`, `noho.st` e `ynh.fr.` e quindi è possibile avere un sotto-sotto dominio com ad esempio `cloud.miosito.nohost.me`. Per creare un sotto dominio in un dominio `nohost.me`, `noho.st` e `ynh.fr` è sufficiente aggiungere quest'ultimo a YunoHost, con la stessa procedura di un qualsiasi altro nome di dominio. -### Aggiungere un dominio nohost.me, noho.st e ynh.fr dopo la post-installazione. +### Aggiungere un dominio nohost.me, noho.st e ynh.fr dopo la post-installazione -Se avete già effettuato la post-installazione e desiderate aggiungere un dominio del tipo nohost.me, potere utilizzare la sezione "Domini" dall'interfaccia web di amministrazione, +Se avete già effettuato la post-installazione e desiderate aggiungere un dominio del tipo nohost.me, potere utilizzare la sezione "Domini" dall'interfaccia web di amministrazione, scegliendo l'opzione "Non ho un nome di dominio.." Potete compiere la stessa operazione da shell con i seguenti comandi. @@ -51,7 +52,6 @@ yunohost domain main-domain -n miosito.nohost.me Se dovete reinstallare il vostro server e volete utilizzare un dominio offerto da YunoHost ma già utilizzato precedentemente, dovete chiedere la reinizializzazione del dominio [nella specifica sezione del forum](https://forum.yunohost.org/t/nohost-domain-recovery/442). - ### Cambiare uno dominio nohost.me, noho.st, ynh.fr Se volete cambiare il dominio automatico, dovete inizialmente cancellare quello già configurato seguendo le istruzioni seguenti: diff --git a/pages/02.administer/45.tutorials/05.domains/01.dns_nohost_me/dns_nohost_me.md b/pages/02.administer/45.tutorials/05.domains/01.dns_nohost_me/dns_nohost_me.md index 0ad0fe9a..b8773e5e 100644 --- a/pages/02.administer/45.tutorials/05.domains/01.dns_nohost_me/dns_nohost_me.md +++ b/pages/02.administer/45.tutorials/05.domains/01.dns_nohost_me/dns_nohost_me.md @@ -10,6 +10,7 @@ routes: In order to make self-hosting as accessible as possible, the YunoHost Project provides a *free* and *automatically configured* domain name service. By using this service, you won't have to [configure DNS records](/dns_config) yourself, which can be tedious and technical. The following (sub)domains are offered: + - `whateveryouwant.nohost.me`; - `whateveryouwant.noho.st`; - `whateveryouwant.ynh.fr`. @@ -22,8 +23,7 @@ To use this service, you simply have to choose such a domain during the post-ins The `nohost.me`, `noho.st` and `ynh.fr` domain service allows the creation of subdomains. -YunoHost allows the installation of applications on subdomains (for example, having the Nextcloud application accessible from the `cloud.mydomain.org` address), this feature is also allowed with the `nohost.me`, `noho.st` and `ynh.fr` domains and so it is possible to have a subdomain such as `my.application.mydomain.nohost.me`. To create a subdomain on `nohost.me`, `noho.st` and `ynh.fr`, you just have to add the subdomain to yunohost like any other domains. - +YunoHost allows the installation of applications on subdomains (for example, having the Nextcloud application accessible from the `cloud.mydomain.org` address), this feature is also allowed with the `nohost.me`, `noho.st` and `ynh.fr` domains and so it is possible to have a subdomain such as `my.application.mydomain.nohost.me`. To create a subdomain on `nohost.me`, `noho.st` and `ynh.fr`, you just have to add the subdomain to YunoHost like any other domains. ### Adding a nohost.me, noho.st or ynh.fr domain after the post-installation @@ -51,12 +51,11 @@ yunohost domain main-domain -n whateveryouwant.nohost.me If you reinstall your server and want to use a domain already used previously, you must request a domain reset on the forum [in the dedicated thread](https://forum.yunohost.org/t/nohost-domain-recovery/442). - ### Change a nohost.me, noho.st or ynh.fr domain If you wish to use a different automatic domain, you first have to remove your present domain registration. This is done in 3 steps: -1. Remove the domain from your instance (via webadmin or the `yunohost domain remove` in the CLI). +1. Remove the domain from your instance (via webadmin or the `yunohost domain remove` in the CLI). 2. Ask for registration removal [in the dedicated forum thread](https://forum.yunohost.org/t/nohost-domain-recovery/442). 3. Remove automatic domain configuration files on your server, via CLI only: `sudo rm /etc/cron.d/yunohost-dyndns && sudo rm -r /etc/yunohost/dyndns` diff --git a/pages/02.administer/45.tutorials/05.domains/02.dns_dynamic_ip/dns_dynamicip.fr.md b/pages/02.administer/45.tutorials/05.domains/02.dns_dynamic_ip/dns_dynamicip.fr.md index 252a63b5..c1a8436b 100644 --- a/pages/02.administer/45.tutorials/05.domains/02.dns_dynamic_ip/dns_dynamicip.fr.md +++ b/pages/02.administer/45.tutorials/05.domains/02.dns_dynamic_ip/dns_dynamicip.fr.md @@ -7,7 +7,7 @@ routes: default: '/dns_dynamicip' --- -! Avant d’aller plus loin, assurez-vous que votre adresse IP publique est dynamique à l’aide de : [ip.yunohost.org](http://ip.yunohost.org/). L’adresse IP publique de votre box change à peu près tous les jours. +! Avant d’aller plus loin, assurez-vous que votre adresse IP publique est dynamique à l’aide de : [`ip.yunohost.org`](http://ip.yunohost.org/). L’adresse IP publique de votre box change à peu près tous les jours. Ce tutoriel a pour but de contourner le problème d’IP dynamique qui est le suivant : lorsque l’adresse IP publique de la box change, la zone DNS n’est pas mise à jour pour pointer vers la nouvelle adresse IP. @@ -16,43 +16,50 @@ Après avoir mis en place la solution proposée dans ce tutoriel, la redirection La méthode qui sera mise en place consiste à rendre automatique le fait que la box annonce au DNS dynamique qu’elle a changé d’adresse IP publique, et qu’ensuite la zone DNS soit automatiquement changée. ### Bureaux d'enregistrement + Voici quelques bureaux d'enregistrement, qui permettent d'acheter des noms de domaine : -* [OVH](http://ovh.com/) -* [GoDaddy](https://godaddy.com/) -* [Gandi](http://gandi.net/) -* [Namecheap](https://www.namecheap.com/) -* [BookMyName](https://www.bookmyname.com/) + +- [OVH](http://ovh.com/) +- [GoDaddy](https://godaddy.com/) +- [Gandi](http://gandi.net/) +- [Namecheap](https://www.namecheap.com/) +- [BookMyName](https://www.bookmyname.com/) Si vous possédez un nom de domaine chez **OVH**, vous pouvez aller à l’étape 4 et suivre ce [tutoriel](/OVH) étant donné qu’OVH propose un service de DynDNS. #### 1. Créer un compte pour un service de DNS dynamique Voici des sites qui proposent un service de DynDNS gratuitement : -* [DNSexit](https://www.dnsexit.com/Direct.sv?cmd=dynDns) -* [No-IP](https://www.noip.com/remote-access) -* [ChangeIP](https://changeip.com) -* [DynDNS.it (en italien, payant)](https://dyndns.it) -* [DynDNS avec votre propre nom de domaine](https://github.com/opi/DynDNS-with-HE.NET) -* [Duck DNS](https://www.duckdns.org/) -* [ydns.io](https://ydns.io/) + +- [DNSexit](https://www.dnsexit.com/Direct.sv?cmd=dynDns) +- [No-IP](https://www.noip.com/remote-access) +- [ChangeIP](https://changeip.com) +- [DynDNS.it (en italien, payant)](https://dyndns.it) +- [DynDNS avec votre propre nom de domaine](https://github.com/opi/DynDNS-with-HE.NET) +- [Duck DNS](https://www.duckdns.org/) +- [ydns.io](https://ydns.io/) Créer un compte chez l’un d’eux. #### 2. Déplacer les zones DNS -Déplacer les [zones DNS](/dns_config), à l’exception des champs NS, du [bureau d’enregistrement](#registrar) où vous avez acheté votre nom de domaine vers le DNS dynamique où vous avez créé un compte à l’étape 1. + +Déplacer les [zones DNS](/dns_config), à l’exception des champs NS, du [bureau d’enregistrement](#bureaux-d-enregistrement) où vous avez acheté votre nom de domaine vers le DNS dynamique où vous avez créé un compte à l’étape 1. #### 3. Basculer la gestion de votre nom de domaine vers le serveur DNS dynamique -Cette étape consiste à faire savoir au [bureau d’enregistrement](#registrar) que le service de DNS sera assuré par le service de DynDNS. + +Cette étape consiste à faire savoir au [bureau d’enregistrement](#bureaux-d-enregistrement) que le service de DNS sera assuré par le service de DynDNS. Redirigez le champ NS vers l’adresse IP donnée par le service de DynDNS. -Ensuite, supprimez les [zones DNS](/dns_config), à l’exception des champs NS, du [bureau d’enregistrement](#registrar). +Ensuite, supprimez les [zones DNS](/dns_config), à l’exception des champs NS, du [bureau d’enregistrement](#bureaux-d-enregistrement). #### 4. Créer un identifiant de DNS dynamique + Sur le service de DNS dynamique créer un identifiant qui sera entré dans un client de DNS dynamique. Ce client peut être votre box ou un paquet installé sur votre serveur comme `ddclient`. Nous allons utiliser le client de la box qui est plus simple à mettre en place. #### 5. Configurer la box + Mettez l’identifiant du DNS dynamique et l’[adresse IP publique](http://ip.yunohost.org/) dans votre box. ![](image://dns_dynamic-ip_box_conf.png?resize=600) diff --git a/pages/02.administer/45.tutorials/05.domains/02.dns_dynamic_ip/dns_dynamicip.it.md b/pages/02.administer/45.tutorials/05.domains/02.dns_dynamic_ip/dns_dynamicip.it.md index 30e1a2c3..a286d63a 100644 --- a/pages/02.administer/45.tutorials/05.domains/02.dns_dynamic_ip/dns_dynamicip.it.md +++ b/pages/02.administer/45.tutorials/05.domains/02.dns_dynamic_ip/dns_dynamicip.it.md @@ -7,9 +7,9 @@ routes: default: '/dns_dynamicip' --- -! Prima di continuare, assicuratevi che il vostro indirizzo IP pubblico sia dinamico utilizzando: [ip.yunohost.org](http://ip.yunohost.org/). L'indirizzo IP del vostro router cambia quasi ogni giorno. +! Prima di continuare, assicuratevi che il vostro indirizzo IP pubblico sia dinamico utilizzando: [`ip.yunohost.org`](http://ip.yunohost.org/). L'indirizzo IP del vostro router cambia quasi ogni giorno. -Questo tutorial cerca di risolvere il problema con gli IP dinamici: quando l'IP pubblico del vostro router cambia, la zona DNS non viene aggiornata per riflettere il nuovo indirizzo IP e di conseguenza il vostro server non è più raggiungibile con il nome di dominio. +Questo tutorial cerca di risolvere il problema con gli IP dinamici: quando l'IP pubblico del vostro router cambia, la zona DNS non viene aggiornata per riflettere il nuovo indirizzo IP e di conseguenza il vostro server non è più raggiungibile con il nome di dominio. Dopo aver applicato le configurazioni proposte in questo tutorial la redirezione dal vostro nome di dominio del vostro server all'IP reale non verrà più persa. @@ -18,61 +18,48 @@ La configurazione che adotteremo consiste nel rendere automatica la comunicazion ### Registrars Di seguito un elenco, non esaustivo, dei registrar. Qui potere acquistare il vostro dominio: -* [OVH](http://ovh.com/) -* [GoDaddy](https://godaddy.com) -* [Gandi](http://gandi.net) -* [Namecheap](https://www.namecheap.com) -* [BookMyName](https://www.bookmyname.com) -* [Ionos](https://ionos.com) -* [Infomaniak](https://infomaniak.com) + +- [OVH](http://ovh.com/) +- [GoDaddy](https://godaddy.com) +- [Gandi](http://gandi.net) +- [Namecheap](https://www.namecheap.com) +- [BookMyName](https://www.bookmyname.com) +- [Ionos](https://ionos.com) +- [Infomaniak](https://infomaniak.com) Se siete in possesso di un dominio presso **OVH**, saltate al punto 4 e proseguite con il [tutorial](/OVH) considerando che OVH propone un servizio DynDNS. #### 1. Create un account per il servizio DynDNS -Di seguito un elenco, non esaustivo, di offerte dei servizi DynDNS: -* [DNSexit](https://www.dnsexit.com/Direct.sv?cmd=dynDns) -* [No-IP](https://www.noip.com/remote-access) -* [ChangeIP](https://changeip.com/) -* [DynDNS.it (in italiano, a pagamento)](https://dyndns.it/) -* [DynDNS con il suo nome di dominio](https://github.com/opi/DynDNS-with-HE.NET) -* [Duck DNS](https://www.duckdns.org/) -* [ydns.io](https://ydns.io/) -Create un account presso il fornitore scelto. Dovrebbe comunicarvi uno (o più) indirizzi IP per raggiungere il servizio e un login (che dovreste poter configurare da soli). +Di seguito un elenco, non esaustivo, di offerte dei servizi DynDNS: + +- [DNSexit](https://www.dnsexit.com/Direct.sv?cmd=dynDns) +- [No-IP](https://www.noip.com/remote-access) +- [ChangeIP](https://changeip.com/) +- [DynDNS.it (in italiano, a pagamento)](https://dyndns.it/) +- [DynDNS con il suo nome di dominio](https://github.com/opi/DynDNS-with-HE.NET) +- [Duck DNS](https://www.duckdns.org/) +- [ydns.io](https://ydns.io/) + +Create un account presso il fornitore scelto. Dovrebbe comunicarvi uno (o più) indirizzi IP per raggiungere il servizio e un login (che dovreste poter configurare da soli). #### 2. Configurate la zona DNS -Copiate la [zona DNS](/dns_config), tranne il record NS, del vostro [registrar](#registrar) verso il DNS dinamico del servizio DynDNS che avete scelto al punto 1 del tutorial. + +Copiate la [zona DNS](/dns_config), tranne il record NS, del vostro [registrar](#registrars) verso il DNS dinamico del servizio DynDNS che avete scelto al punto 1 del tutorial. #### 3. Reindirizzate la gestione del vostro dominio verso il server DNS dinamico -In questo passaggio informeremo il [registrar](#registrar) che il servizio DNS sarà affidato al servizio DyDNS. + +In questo passaggio informeremo il [registrar](#registrars) che il servizio DNS sarà affidato al servizio DyDNS. Reindirizzate il campo NS verso l'indirizzo IP fornito dal servizio DyDNS. -In seguito cancellate la [zona DNS](/dns_config) (eccetto il precedente campo NS) nel vostro [registrar](#registrar). +In seguito cancellate la [zona DNS](/dns_config) (eccetto il precedente campo NS) nel vostro [registrar](#registrars). ## 4. Configurazione del router/client + Configurate il vostro router o un client specifico installato sul vostro server come ad esempio `ddclient` con i dati del vostro account DNS dinamico. Qui useremo il client fornito dal router che è il sistema sicuramente più facile. -Inserite il login del servizio di DNS dinamico e l'indirizzo IP pubblico nel vostro router (l'interfaccia varierà sicuramente a seconda dell'ISP che state usando). +Inserite il login del servizio di DNS dinamico e l'indirizzo IP pubblico nel vostro router (l'interfaccia varierà sicuramente a seconda dell'ISP che state usando). ![](image://dns_dynamic-ip_box_conf.png?resize=600) - - - - - - - - - - - - - - - - - - - diff --git a/pages/02.administer/45.tutorials/05.domains/02.dns_dynamic_ip/dns_dynamicip.md b/pages/02.administer/45.tutorials/05.domains/02.dns_dynamic_ip/dns_dynamicip.md index 9e9a06d2..82fe50a0 100644 --- a/pages/02.administer/45.tutorials/05.domains/02.dns_dynamic_ip/dns_dynamicip.md +++ b/pages/02.administer/45.tutorials/05.domains/02.dns_dynamic_ip/dns_dynamicip.md @@ -7,7 +7,7 @@ routes: default: '/dns_dynamicip' --- -! Before going further, make sure your global IP address is dynamic with: [ip.yunohost.org](http://ip.yunohost.org/). The global IP address of your box changes almost every day. +! Before going further, make sure your global IP address is dynamic with: [`ip.yunohost.org`](http://ip.yunohost.org/). The global IP address of your box changes almost every day. This tutorial aim to get around dynamic IP issue which is: when the IP public address of your (Internet Service Provider-) box changes, the DNS zone is not updated to point towards the new IP address, and consequently your server is no more reachable via its domain name @@ -18,37 +18,43 @@ The method proposed here consists of automatizing the fact the box announces its ### Registrars Here are some examples of registrars, companies where you can buy domain names: -* [OVH](http://ovh.com/) -* [GoDaddy](https://godaddy.com/) -* [Gandi](http://gandi.net/) -* [Namecheap](https://www.namecheap.com/) -* [BookMyName](https://www.bookmyname.com/) + +- [OVH](http://ovh.com/) +- [GoDaddy](https://godaddy.com/) +- [Gandi](http://gandi.net/) +- [Namecheap](https://www.namecheap.com/) +- [BookMyName](https://www.bookmyname.com/) If you own a domain name at **OVH**, you may go to step 4 and follow this [tutorial](/OVH), given that OVH proposes a DynDNS service. #### 1. Create an account to a Dynamic DNS service + Here are sites which offer a DynDNS service free of charge: -* [DNSexit](https://www.dnsexit.com/Direct.sv?cmd=dynDns) -* [No-IP](https://www.noip.com/remote-access) -* [ChangeIP](https://changeip.com) -* [DynDNS.it (in italian, paid plan)](https://dyndns.it) -* [DynDNS with your own domain](https://github.com/opi/DynDNS-with-HE.NET) -* [Duck DNS](https://www.duckdns.org/) -* [ydns.io](https://ydns.io/) + +- [DNSexit](https://www.dnsexit.com/Direct.sv?cmd=dynDns) +- [No-IP](https://www.noip.com/remote-access) +- [ChangeIP](https://changeip.com) +- [DynDNS.it (in italian, paid plan)](https://dyndns.it) +- [DynDNS with your own domain](https://github.com/opi/DynDNS-with-HE.NET) +- [Duck DNS](https://www.duckdns.org/) +- [ydns.io](https://ydns.io/) Register to one of them. It should provide you with one (or more) IP address to reach the service, and a login (that you may be able to self-define). #### 2. Move the DNS zones -Copy the [DNS zones](/dns_config), except for the NS fields, from the [registrar](#registrar) where you bought your domain name from to the dynamic DNS service you registrer at in step 1. + +Copy the [DNS zones](/dns_config), except for the NS fields, from the [registrar](#registrars) where you bought your domain name from to the dynamic DNS service you registrer at in step 1. #### 3. Switch the management of your domain name to the dynamic DNS server -This step consists in declaring to your [registrar](#registrar) that the DNS service will now be managed by the DynDNS service provider. + +This step consists in declaring to your [registrar](#registrars) that the DNS service will now be managed by the DynDNS service provider. For this, first declare in the NS field(s) the IP address provided by the DynDNS service. -Then, remove any other item in the [DNS zones](/dns_config) (except the previous NS fields), from the [registrar](#registrar). +Then, remove any other item in the [DNS zones](/dns_config) (except the previous NS fields), from the [registrar](#registrars). #### 4. Configure the client + This client could be your ISP-box, or a package installed on your server, such as `ddclient`. Here, we will use the client provided by the box, which is the more easy way. diff --git a/pages/02.administer/45.tutorials/05.domains/03.dns_subdomains/dns_subdomains.fr.md b/pages/02.administer/45.tutorials/05.domains/03.dns_subdomains/dns_subdomains.fr.md index 37b2b14d..997792b1 100644 --- a/pages/02.administer/45.tutorials/05.domains/03.dns_subdomains/dns_subdomains.fr.md +++ b/pages/02.administer/45.tutorials/05.domains/03.dns_subdomains/dns_subdomains.fr.md @@ -15,7 +15,8 @@ YunoHost permet l’usage de sous-domaine. Il faut avoir un nom de domaine par e Dans la configuration de son DNS, on aura donc une entrée A avec l’adresse IPv4, une entrée AAAA avec l’adresse IPv6 et ensuite différents CNAME pour les sous-domaines que l’on souhaite créer. Nom Type Valeur -```bash + +```text @ A XYZ.XYZ.XYZ.XYZ @ AAAA 1234:1234:1234:FFAA:FFAA:FFAA:FFAA:AAFF * CNAME mondomaine.fr. @@ -23,6 +24,7 @@ agenda CNAME mondomaine.fr. blog CNAME mondomaine.fr. rss CNAME mondomaine.fr. ``` + permet d’avoir un `agenda.mondomaine.fr`, un `blog.mondomaine.fr` etc. ### Installer une application sur un sous-domaine @@ -36,7 +38,7 @@ L’application est alors accessible via `blog.mondomaine.fr` (et non via `mondo ### Déplacer une application sur un sous-domaine ? Que se passe-t-il si on a déjà installé l’application ? On veut par exemple passer de `mondomaine.fr/wordpress` à `blog.mondomaine.fr`. -Pour l’instant il n’y a pas de façon simple (via l’interface graphique de l’administration de YunoHost) pour déplacer une application sur un sous-domaine. +Pour l’instant il n’y a pas de façon simple (via l’interface graphique de l’administration de YunoHost : Applications > nom_de_lapp > Modifier l’URL) pour déplacer une application sur un sous-domaine. Solution : réinstaller l’application diff --git a/pages/02.administer/45.tutorials/05.domains/03.dns_subdomains/dns_subdomains.md b/pages/02.administer/45.tutorials/05.domains/03.dns_subdomains/dns_subdomains.md index c70a0291..3676d3fb 100644 --- a/pages/02.administer/45.tutorials/05.domains/03.dns_subdomains/dns_subdomains.md +++ b/pages/02.administer/45.tutorials/05.domains/03.dns_subdomains/dns_subdomains.md @@ -16,7 +16,8 @@ YunoHost allows the use of subdomains. If one owns a domain name `mydomain.com`, The DNS configuration needs an A record with an IPv4 address, an AAAA record with an IPv6 address, and various CNAME records, one for each desired subdomain. If your DNS configuration looks like: -```bash + +```text @ A XYZ.XYZ.XYZ.XYZ @ AAAA 1234:1234:1234:FFAA:FFAA:FFAA:FFAA:AAFF * CNAME mydomain.com. @@ -24,6 +25,7 @@ agenda CNAME mydomain.com. blog CNAME mydomain.com. rss CNAME mydomain.com. ``` + then you can access `agenda.mydomain.com`, `blog.mydomain.com` and `rss.mydomain.com` subdomains. ### Install an application on a subdomain @@ -37,8 +39,8 @@ The application is then available at `blog.mydomain.com` (and not `mydomain.com/ ### Moving an application to a subdomain What happens if the application is already installed? For example, one wants to move `mydomain.com/wordpress` to `blog.mydomain.com`. -It depends on the application. -Some applications allow the change of domain. In that case, one can proceed to the change through the administration panel Applications>the_app>change URL. +It depends on the application. +Some applications allow the change of domain. In that case, one can proceed to the change through the administration panel: Applications > the_app_name > change URL. If the application doesn't allow URL change, then there is no easy way to do it. The best solution is to reinstall the application. ### Reinstalling an application diff --git a/pages/02.administer/45.tutorials/05.domains/04.dns_local_network/dns_local_network.es.md b/pages/02.administer/45.tutorials/05.domains/04.dns_local_network/dns_local_network.es.md index dcb362d7..b08bab1e 100644 --- a/pages/02.administer/45.tutorials/05.domains/04.dns_local_network/dns_local_network.es.md +++ b/pages/02.administer/45.tutorials/05.domains/04.dns_local_network/dns_local_network.es.md @@ -10,12 +10,14 @@ routes: After completing your server installation, it is possible that your domain will not be accessible through the local network. This is an issue known as [hairpinning](http://en.wikipedia.org/wiki/Hairpinning) - a feature that is not well supported by some internet routers. To solve this issue you can: + - configure your router's DNS - or alternatively - your /etc/hosts files on your clients workstation ### Find the local IP address of your server First you need to find out the local IP of your server + - either using the tricks lister [here](/finding_the_local_ip) - or if in the webadmin, in the Diagnosis section, under Internet Connectivity, IPv4, click on 'Details' and you should find an entry for 'Local IP' - or using the command line on the server : `hostname -I` @@ -25,6 +27,7 @@ First you need to find out the local IP of your server Vas a crear una redirección que estará activa en toda tu red local. El objetivo es crear una redirección DNS hacia el IP de tu servidor en tu caja Internet. Hay que acceder a la interfaz de configuración de tu caja y a los parámetros DNS, y luego crear una redirección local (por ejemplo, `yunohost.local` puede redigir hacia `192.168.1.21`). ## Configurar el archivo [hosts](https://es.wikipedia.org/wiki/Archivo_hosts) del ordenador cliente + Sólo deberías modificar el archivo hosts si no puedes modificar el DNS de tu caja Internet / router, porque el archivo hosts únicamente afectará el ordenador en el cual el archivo esté modificado. - En Windows, encontrarás el archivo hosts aquí : @@ -37,5 +40,5 @@ Sólo deberías modificar el archivo hosts si no puedes modificar el DNS de tu c Simplemente añade al final del archivo hosts una linea conteniendo la dirección IP privada del servidor y tu nombre de dominio ```bash -192.168.1.62 domain.tld +192.168.1.62 domain.tld ``` diff --git a/pages/02.administer/45.tutorials/05.domains/04.dns_local_network/dns_local_network.fr.md b/pages/02.administer/45.tutorials/05.domains/04.dns_local_network/dns_local_network.fr.md index cfbf0e32..fa7b9a67 100644 --- a/pages/02.administer/45.tutorials/05.domains/04.dns_local_network/dns_local_network.fr.md +++ b/pages/02.administer/45.tutorials/05.domains/04.dns_local_network/dns_local_network.fr.md @@ -10,12 +10,14 @@ routes: Après installation de votre serveur, il est possible que votre nom de domaine ne soit pas accessible depuis le réseau local où se trouve le serveur. Ceci est un problème connu sous le nom de [hairpinning](http://fr.wikipedia.org/wiki/Hairpinning) - une fonctionnalité mal supportée par certaines box internet. Pour résoudre ce problème: -- il est nécessaire de configurer le DNS de votre routeur + +- il est nécessaire de configurer le DNS de votre routeur - à défaut, il est possible de modifier le ou les fichiers /etc/hosts de vos ordinateurs clients. ### Trouver l’adresse IP locale du serveur Tout d'abord il vous faut trouver l'adresse IP locale du serveur + - soit en utilisant l'une de astuces expliquées [ici](/finding_the_local_ip) - ou en utilisant la webadmin, dans l'écran Diagnostic, section Connexion Internet, IPv4, cliquer sur 'Détails' et vous devriez trouver une entrée pour 'IP locale'. - ou en ligne de commande sur le serveur: `hostname -I` @@ -31,6 +33,7 @@ Si vous ne disposez toujours pas de l’adresse IP privée de votre serveur, vou #### Configurer le DNS de la box SFR + Rendez-vous dans l’onglet Réseau puis DNS pour ajouter votre nom de domaine au DNS de la box. @@ -48,5 +51,5 @@ La modification du fichier hosts devrait être effectuée seulement si vous ne p Ajoutez simplement à la fin du fichier hosts une ligne contenant l’adresse IP privée du serveur suivi de votre nom de domaine ```bash -192.168.1.62 domain.tld +192.168.1.62 domain.tld ``` diff --git a/pages/02.administer/45.tutorials/05.domains/04.dns_local_network/dns_local_network.it.md b/pages/02.administer/45.tutorials/05.domains/04.dns_local_network/dns_local_network.it.md index 0487c54b..8bb10b7a 100644 --- a/pages/02.administer/45.tutorials/05.domains/04.dns_local_network/dns_local_network.it.md +++ b/pages/02.administer/45.tutorials/05.domains/04.dns_local_network/dns_local_network.it.md @@ -10,21 +10,24 @@ routes: Dopo aver concluso l'installazione del server, è possibile che il vostro dominio non sia accessibile dalla rete locale del server. Questo problema è noto con il nome di [hairpinning](http://en.wikipedia.org/wiki/Hairpinning) ed è una caratteristica non supportata da alcuni router. Per risolvere questo problema dobbiamo: + - configurare i DNS del nostro router -- o in alternativa modificare il file /etc/hosts dei client dai quali vogliamo raggiungere il server +- o in alternativa modificare il file /etc/hosts dei client dai quali vogliamo raggiungere il server ### Trovare l'indirizzo IP del server nella rete locale Dobbiamo innanzitutto conoscere l'IP locale del server + - utilizziamo uno di questi [metodi](https://yunohost.org/en/finding_the_local_ip) - dalla pagina di amministrazione, sezione Diagnostica > Connessione Internet > IPv4 cliccando su 'Dettagli' dovrebbe apparire il valore di 'IP locale' - dal terminale con il comando: `hostname -I` - + ## Configurare il DNS del router Andremo a creare un reindirizzamento attivo su tutta la LAN. Lo scopo è di creare, nel router, un reindirizzamento DNS verso l'IP del server YunoHost. Dobbiamo accedere all'interfaccia di configurazione del router, nella sezione DNS e creare il reindirizzamento nella LAN (ad esempio, `yunohost.local` invia a `192.168.1.21`). ### Box SFR + Se non trovate l'indirizzo IP privato lo potete trovare nel pannello di amministrazione: Andate su Etichetta Network > Generale @@ -38,7 +41,7 @@ Andate all'etichetta Network > DNS e aggiungete il vostro nome a dominio al DNS L'opzione di modificare il file /etc/hosts deve essere presa in considerazione solo se non è possibile configurare il DNS del router, perché tale modifica avrà effetto solo sul pc specifico. -- In windows trovate il file qui: +- In windows trovate il file qui: `%SystemRoot%\system32\drivers\etc\` > È necessario abilitare la visualizzazione dei file nascosti e di sistema per rendere visibile il file hosts. - In sistemi UNIX (GNU/Linux, macOS), trovate il file qui: @@ -48,5 +51,5 @@ L'opzione di modificare il file /etc/hosts deve essere presa in considerazione s Aggiungete alla fine del file una riga contenente l'indirizzo IP del server seguito dal dominio ```bash -192.168.1.62 domain.tld +192.168.1.62 domain.tld ``` diff --git a/pages/02.administer/45.tutorials/05.domains/04.dns_local_network/dns_local_network.md b/pages/02.administer/45.tutorials/05.domains/04.dns_local_network/dns_local_network.md index 10b777ca..c8ef01d4 100644 --- a/pages/02.administer/45.tutorials/05.domains/04.dns_local_network/dns_local_network.md +++ b/pages/02.administer/45.tutorials/05.domains/04.dns_local_network/dns_local_network.md @@ -10,12 +10,14 @@ routes: After completing your server installation, it is possible that your domain will not be accessible through the local network. This is an issue known as [hairpinning](http://en.wikipedia.org/wiki/Hairpinning) - a feature that is not well supported by some internet routers. To solve this issue you can: + - configure your router's DNS - or alternatively - your /etc/hosts files on your clients workstation ### Find the local IP address of your server First you need to find out the local IP of your server + - either using the tricks lister [here](/finding_the_local_ip) - or if in the webadmin, in the Diagnosis section, under Internet Connectivity, IPv4, click on 'Details' and you should find an entry for 'Local IP' - or using the command line on the server : `hostname -I` @@ -25,6 +27,7 @@ First you need to find out the local IP of your server The goal here is to create a network wide redirection handled by your router. The idea is to create a DNS redirection to your server's IP. You should access your router's configuration and look for DNS configuration, then add a redirection to your server's IP (e.g. redirect `yunohost.local` to `192.168.1.21`). ### SFR Box + If you haven't found your server private IP, you may find it using the SFR box admin panel: Go to Network tab > General @@ -48,5 +51,5 @@ Modifying hosts file should be done only if you cannot alter your box's DNS or r Add a line at the end of the file containing your server private IP followed by a space and your domain name ```bash -192.168.1.62 domain.tld +192.168.1.62 domain.tld ``` diff --git a/pages/02.administer/45.tutorials/15.filezilla/filezilla.fr.md b/pages/02.administer/45.tutorials/15.filezilla/filezilla.fr.md index 464bf5c8..e50ddcc4 100644 --- a/pages/02.administer/45.tutorials/15.filezilla/filezilla.fr.md +++ b/pages/02.administer/45.tutorials/15.filezilla/filezilla.fr.md @@ -55,12 +55,12 @@ Installez le programme et lancez *Filezilla*. ![Copier les sauvegardes de YunoHost sur l'ordinateur local](image://filezilla_8.png) ----- +--- Sources -* [Documentation officielle](https://wiki.filezilla-project.org/FileZilla_Client_Tutorial_(fr)) -* [Tutoriel général à Filezilla](https://www.rc.fas.harvard.edu/resources/documentation/sftp-file-transfer/) +- [Documentation officielle](https://wiki.filezilla-project.org/FileZilla_Client_Tutorial_(fr)) +- [Tutoriel général à Filezilla](https://www.rc.fas.harvard.edu/resources/documentation/sftp-file-transfer/) ## Alternatives à Filezilla @@ -70,14 +70,14 @@ Depuis n'importe quel GNU/Linux récent, vous devriez pouvoir utiliser le gestio Nautilus de Gnome3 et Dolphin de KDE intègrent de base des fonctionnalités similaires à FileZilla : -* -* -* +- +- +- ### Sous Windows -* [WinSCP](https://winscp.net/) est aussi un bon candidat pour Windows +- [WinSCP](https://winscp.net/) est aussi un bon candidat pour Windows ### Sous macOS -* [Cyberduck](https://cyberduck.io/) logiciel libre pour macOS +- [Cyberduck](https://cyberduck.io/) logiciel libre pour macOS diff --git a/pages/02.administer/45.tutorials/15.filezilla/filezilla.it.md b/pages/02.administer/45.tutorials/15.filezilla/filezilla.it.md index 1c610aac..152bee88 100644 --- a/pages/02.administer/45.tutorials/15.filezilla/filezilla.it.md +++ b/pages/02.administer/45.tutorials/15.filezilla/filezilla.it.md @@ -18,8 +18,8 @@ Potete scaricare FileZilla [da questa pagina](https://filezilla-project.org/down Installate e lanciate *FileZilla* ## Configurazione - -1. Cliccate sull'icona in alto a sinistra *Site Manager*. + +1. Cliccate sull'icona in alto a sinistra *Site Manager*. ![Pagina principale di Filezilla](image://filezilla_1.png) @@ -27,7 +27,7 @@ Installate e lanciate *FileZilla* ![Schermata del site manager](image://filezilla_2.png) -3. Apparirà un avviso poiché vi state collegando per la prima volta al server. *Se è la prima connessione, potete ignorarlo* +3. Apparirà un avviso poiché vi state collegando per la prima volta al server. *Se è la prima connessione, potete ignorarlo* ![Avviso per la fingerprint del server sconosciuta](image://filezilla_3.png) @@ -35,9 +35,9 @@ Installate e lanciate *FileZilla* ![schermata per la richiesta della password](image://filezilla_4.png) -5. Una volta salvato nei segnalibri, il server verrà salvato e vedrete questa schermata. +5. Una volta salvato nei segnalibri, il server verrà salvato e vedrete questa schermata. - ![Schermata del "site manager" con il server appena aggiunto](image://filezilla_5.png) + ![Schermata del "site manager" con il server appena aggiunto](image://filezilla_5.png) ## Utilizzo @@ -55,12 +55,12 @@ Installate e lanciate *FileZilla* ![Copia dei backup da YunoHost ad un computer locale](image://filezilla_8.png) ----- +--- Link a fonti esterne: -* [Documentazione ufficiale](https://wiki.filezilla-project.org/FileZilla_Client_Tutorial_(en)) -* [Tutorial generale su FileZilla](https://www.rc.fas.harvard.edu/resources/documentation/sftp-file-transfer/) +- [Documentazione ufficiale](https://wiki.filezilla-project.org/FileZilla_Client_Tutorial_(en)) +- [Tutorial generale su FileZilla](https://www.rc.fas.harvard.edu/resources/documentation/sftp-file-transfer/) ## Alternative a FileZilla @@ -70,13 +70,13 @@ Qualsiasi distribuzione recente di GNU/Linux dovrebbe permettere di accedere al Nautilus di Gnome3 integra delle funzionalità simili a FileZilla: -* -* +- +- ### Windows -* [WinSCP](https://winscp.net/) è un ottimo programma per Windows +- [WinSCP](https://winscp.net/) è un ottimo programma per Windows ### MacOS -* [Cyberduck](https://cyberduck.io/) un programma libero per macOS +- [Cyberduck](https://cyberduck.io/) un programma libero per macOS diff --git a/pages/02.administer/45.tutorials/15.filezilla/filezilla.md b/pages/02.administer/45.tutorials/15.filezilla/filezilla.md index 8f191f46..a43d3984 100644 --- a/pages/02.administer/45.tutorials/15.filezilla/filezilla.md +++ b/pages/02.administer/45.tutorials/15.filezilla/filezilla.md @@ -55,12 +55,12 @@ Install the program and run *Filezilla*. ![Copy backups from YunoHost to local computer](image://filezilla_8.png) ----- +--- Sources -* [Official documentation](https://wiki.filezilla-project.org/FileZilla_Client_Tutorial_(en)) -* [General tutorial about using FileZilla](https://www.rc.fas.harvard.edu/resources/documentation/sftp-file-transfer/) +- [Official documentation](https://wiki.filezilla-project.org/FileZilla_Client_Tutorial_(en)) +- [General tutorial about using FileZilla](https://www.rc.fas.harvard.edu/resources/documentation/sftp-file-transfer/) ## Alternatives to Filezilla @@ -70,14 +70,14 @@ From any recent GNU/Linux, you should be able to use the `file manager` to reach Nautilus from Gnome3 and Dolphin from KDE have features similar to FileZilla, out of the box. -* -* -* +- +- +- ### Windows -* [WinSCP](https://winscp.net/) is also a nice candidate for Windows +- [WinSCP](https://winscp.net/) is also a nice candidate for Windows ### macOS -* [Cyberduck](https://cyberduck.io/) is a free software available on macOS +- [Cyberduck](https://cyberduck.io/) is a free software available on macOS diff --git a/pages/02.administer/45.tutorials/25.external_storage/external_storage.fr.md b/pages/02.administer/45.tutorials/25.external_storage/external_storage.fr.md index 07f7e07d..3f91f1b9 100644 --- a/pages/02.administer/45.tutorials/25.external_storage/external_storage.fr.md +++ b/pages/02.administer/45.tutorials/25.external_storage/external_storage.fr.md @@ -23,19 +23,19 @@ Ci-dessous, vous trouverez des explications pour parvenir à déplacer vos donn ## [fa=list-alt /] Pré-requis -* Avoir un peu de temps à un moment où les utilisateurs de votre serveur peuvent accepter un arrêt des services. Les étapes à réaliser, même si elles sont relativement simples, peuvent parfois paraître techniques et nécessitent dans tous les cas **de prendre son temps**. +- Avoir un peu de temps à un moment où les utilisateurs de votre serveur peuvent accepter un arrêt des services. Les étapes à réaliser, même si elles sont relativement simples, peuvent parfois paraître techniques et nécessitent dans tous les cas **de prendre son temps**. -* Savoir se connecter en root sur votre système, par exemple via [SSH](/ssh). (Note : en étant connecté en tant qu'utilisateur `admin`, vous pouvez passer root avec `sudo su`) +- Savoir se connecter en root sur votre système, par exemple via [SSH](/ssh). (Note : en étant connecté en tant qu'utilisateur `admin`, vous pouvez passer root avec `sudo su`) -* Connaître les commandes basiques `cd`, `ls`, `mkdir`, `rm` +- Connaître les commandes basiques `cd`, `ls`, `mkdir`, `rm` -* Avoir une sauvegarde au cas où ça ne se passe pas comme prévu +- Avoir une sauvegarde au cas où ça ne se passe pas comme prévu -* Disposer d'un stockage supplémentaire (disque SSD, disque dur, clé USB) branché à votre serveur en USB ou en SATA +- Disposer d'un stockage supplémentaire (disque SSD, disque dur, clé USB) branché à votre serveur en USB ou en SATA ## 1. Identifier les dossiers à déplacer -La commande `ncdu /` vous permet de naviguer dans les dossiers de votre serveur afin de constater leurs tailles. +La commande `ncdu /` vous permet de naviguer dans les dossiers de votre serveur afin de constater leurs tailles. Ci-dessous, une explication de certains chemins qui peuvent prendre du poids avec quelques commentaires pour vous aider à réduire leur poids ou à choisir de les déplacer. @@ -43,7 +43,7 @@ Ci-dessous, une explication de certains chemins qui peuvent prendre du poids ave |--------|---|---| | `/home` | Dossiers utilisateurs accessibles via SFTP | Déplaçable sur un disque dur | | `/home/yunohost.backup` | Sauvegardes YunoHost | Selon votre stratégie de sauvegarde, il peut être préférable de placer ce dossier sur un disque distinct de celui où se trouvent vos données ou vos bases de données | -| `/home/yunohost.app` | Données lourdes des applications yunohost (nextcloud, matrix...) | Déplaçable sur un disque dur | +| `/home/yunohost.app` | Données lourdes des applications YunoHost (nextcloud, matrix...) | Déplaçable sur un disque dur | | `/home/yunohost.multimedia` | Données lourdes partagées entre plusieurs applications | Déplaçable sur un disque dur | | `/var/lib/mysql` | Base de données utilisées par les applications | A laisser idéalement sur le SSD pour des raisons de performances | | `/var/lib/postgresql` | Base de données utilisées par les applications | A laisser idéalement sur le SSD pour des raisons de performances | @@ -107,13 +107,14 @@ mkfs.ext4 /dev/VOTRE_DISQUE1 Remplacez `VOTRE_DISQUE1` par le nom de la première partition sur le disque par exemple `sda1`. -!!! Il est possible d'adapter cette étape, pour par exemple créer un volume raid 1 (disques en miroir) ou chiffrer le dossier. +!!! Il est possible d'adapter cette étape, pour par exemple créer un volume raid 1 (disques en miroir) ou chiffrer le dossier. ## 4. Monter le disque Contrairement à Windows où les disques sont accessibles avec des lettres (C:/), sous linux, les disques sont rendus accessibles via l'arborescence. "Monter" un disque signifie le rendre effectivement accessible dans l'arborescence des fichiers. Nous allons choisir arbitrairement de monter le disque dans `/mnt/hdd` mais vous pouvez le nommer différemment (par exemple `/mnt/disque` ...). Commençons par créer le répertoire : + ```bash mkdir /mnt/hdd ``` @@ -126,12 +127,12 @@ mount /dev/VOTRE_DISQUE1 /mnt/hdd (Ici, `/dev/VOTRE_DISQUE1` correspond à la première partition sur le disque) - -## 5. Monter un dossier de /mnt/hdd sur un des dossiers dont on veut déplacer les données +## 5. Monter un dossier de `/mnt/hdd` sur un des dossiers dont on veut déplacer les données Ici on va considérer que vous souhaitez déplacer les grosses données des applications qui se trouvent dans `/home/yunohost.app` ainsi que les mails sur votre disque dur. ### 5.1 Création des sous-dossiers sur le disque + Pour commencer, on crée un dossier dans le disque dur ```bash @@ -140,6 +141,7 @@ mkdir -p /mnt/hdd/var/mail ``` ### 5.2 Passage en mode maintenance + Puis, idéalement on passe en maintenance les applications qui pourraient être en train d'écrire des données. Exemple, pour nextcloud: @@ -205,7 +207,6 @@ A partir de cette étape, vos services tournent avec leurs données sur le disqu ## 6. Monter automatiquement au démarrage - Jusqu'ici, nous avons monté manuellement le disque et les sous-dossiers. Cependant, il est nécessaire de configurer le système pour qu'il monte automatiquement le disque après un démarrage. Si vos tests sont concluants, il faut pérenniser les points de montages, sinon dépêchez-vous de faire machine arrière en commençant par remettre en maintenance. @@ -239,6 +240,7 @@ Utiliser Ctrl+X puis `o` pour sauvegarder. Vous pouvez ensuite tester de redémarrer le système pour vérifier si le disque et les sous-dossiers sont montés automatiquement. ## 7. Nettoyer les anciennes données + Dès que votre nouveau setup est validé, vous pouvez procéder à la suppression des anciennes données issues de l'étape 6.3: ```bash diff --git a/pages/02.administer/45.tutorials/25.external_storage/external_storage.it.md b/pages/02.administer/45.tutorials/25.external_storage/external_storage.it.md index 01ed4d7a..f418362d 100644 --- a/pages/02.administer/45.tutorials/25.external_storage/external_storage.it.md +++ b/pages/02.administer/45.tutorials/25.external_storage/external_storage.it.md @@ -11,28 +11,27 @@ routes: ## Introduzione - Oltre al monitoraggio delle dimensioni delle partizioni (che controlla che non siano troppo piccole), YunoHost non si occupa, al momento, dell'organizzazione delle partizioni dei vostri dischi. Se la vostra configurazione è basata su una board ARM con scheda SD, oppure il server dispone di un disco SSD di piccole dimensioni, potreste, per motivi di spazio o di sicurezza, voler aggiungere uno o più dischi al vostro server. ! Se avete esaurito lo spazio sul disco del vostro server, potete provare con il comando `apt clean` per tentare di recuperarne un po' e avere modo di seguire le istruzioni di seguito riportate. - + Troverete qui le istruzioni per riuscire a spostare i vostri dati su un disco esterno in modo corretto e con un impatto minimo sul funzionamento di YunoHost. Potete eseguire lo spostamento durante l'installazione o in un secondo momento, quando si presenterà la necessità di più spazio o temete per l'affidabilità della scheda SD. !!! Il procedimento presentato qui inizia montando l'unica partizione del disco, in seguito utilizza una o più sotto-cartelle per creare diversi punti di montaggio sull'albero del file system del pc. Questo metodo è preferibile rispetto al utilizzo di link simbolici poiché questi possono entrare in conflitto con alcune applicazioni, tra le quali il sistema di backup di YunoHost. Potreste scegliere di montare le partizioni invece che le sotto-cartelle, ma sorge la difficoltà di prevedere la stima della dimensione della cartella. ## [fa=list-alt /] Prerequisiti -* Prevedere un periodo temporale nel quale gli utenti del vostro server possono sopportare una interruzione dei servizi. I passaggi da compiere, anche se relativamente semplici, sono tecnicamente complessi e necessitano di un lasso di tempo **da dedicare in modo esclusivo**. +- Prevedere un periodo temporale nel quale gli utenti del vostro server possono sopportare una interruzione dei servizi. I passaggi da compiere, anche se relativamente semplici, sono tecnicamente complessi e necessitano di un lasso di tempo **da dedicare in modo esclusivo**. -* Conoscenza della connessione come root sul server anche via [SSH](/ssh). (Nota bene: se siete connessi come utente `admin`, potete passare root con il comando `sudo su`) +- Conoscenza della connessione come root sul server anche via [SSH](/ssh). (Nota bene: se siete connessi come utente `admin`, potete passare root con il comando `sudo su`) -* Conoscere i comandi `cd`, `ls`, `mkdir`, `rm`. - -* Disporre di un backup nel caso le cose non vadano come previsto +- Conoscere i comandi `cd`, `ls`, `mkdir`, `rm`. -* Disporre di un disco aggiuntivo (SSD, hard disk, chiavetta USB) collegato al server via USB o SATA +- Disporre di un backup nel caso le cose non vadano come previsto + +- Disporre di un disco aggiuntivo (SSD, hard disk, chiavetta USB) collegato al server via USB o SATA ## 1. Identificare le cartelle da spostare @@ -54,7 +53,6 @@ Di seguito, alcuni esempi di percorsi che possono essere di notevoli dimensioni | `/opt` | Programmi e dipendenze di alcune applicazioni YunoHost | Per motivi di velocità è consigliato lasciare sul disco principale. Per le applicazioni nodejs è possibile recuperare dello spazio cancellando le versioni non in uso | | `/boot` | Kernel e file di avvio | Non spostare se non perfettamente a conoscenza delle possibili conseguenze. Si possono eliminare vecchi kernel non in uso | - ## 2. Collegare e identificare il disco Collegate il disco al server e identificate il nome assegnato dal sistema. @@ -116,6 +114,7 @@ Sostituite `miodisco` con il nome della prima partizione del disco di destinazio Contrariamente a Windows, dove i dischi sono contraddistinti da lette (C:/), in linux i dischi sono accessibili dall'albero del gestore dei file. "Montare" un disco significa renderlo accessibile nell'albero dei file. Sceglieremo di montare il disco in `/mnt/hdd` ma possiamo anche assegnare un nome di fantasia. (Ad esempio `/mnt/disco` ...). Iniziamo creando la directory: + ```bash mkdir /mnt/hdd ``` @@ -128,11 +127,12 @@ mount /dev/miodisco /mnt/hdd (In questo caso, `/dev/miodisco` corrisponde alla prima partizione del disco) -## 5. Montare una cartella /mnt/hdd nella cartella che contiene i dati da spostare +## 5. Montare una cartella `/mnt/hdd` nella cartella che contiene i dati da spostare Ipotizzeremo, di seguito, lo spostamento delle mail e di una notevole quantità di dati delle applicazioni, che si trovano in `/home/yunohost.app`. ### 5.1 Creazione delle sotto cartelle sul disco + Iniziamo creando due cartelle nel disco di destinazione. ```bash @@ -141,6 +141,7 @@ mkdir -p /mnt/hdd/var/mail ``` ### 5.2 Passaggio alla modalità manutenzione + Precauzionalmente portiamo nello stato di manutenzione le applicazioni che potrebbero scrivere dei dati nella cartella che vogliamo spostare. Ad esempio, per nextcloud: @@ -206,10 +207,9 @@ Dopo aver impartito i comandi di avvio, le applicazioni e i servizi sfrutteranno ## 6. Automatizzare il montaggio all'avvio - Fino ad ora, abbiamo montato manualmente il disco e le sotto cartelle. È però necessario configurare il sistema affinché il disco esterno venga montato in automatico ad ogni avvio. -Se i test di velocità sono soddisfacenti, bisogna rendere definitivo il punto di montaggio. In caso contrario affrettatevi a fare dietro front iniziando a ripristinare la modalità di manutenzione. +Se i test di velocità sono soddisfacenti, bisogna rendere definitivo il punto di montaggio. In caso contrario affrettatevi a fare dietro front iniziando a ripristinare la modalità di manutenzione. Iniziamo cercando l'UUID (universal identifier, identificatore universale) del nostro disco: @@ -240,6 +240,7 @@ Salvate le modifiche con CTRL+x e `o`. Riavviate il server per assicurarvi che il disco e le sotto cartelle vengano montate in automatico. ## 7. Cancellare i dati precedenti + Quando siete sicuri che la configurazione sia corretta, potete procedere alla cancellazione della configurazione creata nel punto 5.3: ```bash @@ -250,4 +251,3 @@ rm -Rf /var/mail.bkp ### ![](image://tada.png?resize=32&classes=inline) Complimenti!!! Se siete giunti fino qui senza incidenti, avete configurato un server che sfrutta uno o più dischi per il salvataggio dei dati. - diff --git a/pages/02.administer/45.tutorials/25.external_storage/external_storage.md b/pages/02.administer/45.tutorials/25.external_storage/external_storage.md index d5bec860..de63071f 100644 --- a/pages/02.administer/45.tutorials/25.external_storage/external_storage.md +++ b/pages/02.administer/45.tutorials/25.external_storage/external_storage.md @@ -10,7 +10,6 @@ routes: --- ## Introduction - Apart from the monitoring system that ensures that your system's partitions are not too small, YunoHost does not currently deal with the organisation of your partitions and disks. @@ -24,36 +23,35 @@ Below you will find explanations on how to move your data to a hard disk in a co ## [fa=list-alt /] Prerequisites -* Have some time at a moment when your server users can accept a shutdown. The steps to be performed, even if they are relatively simple, can sometimes seem technical and require in any case **to take your time**. +- Have some time at a moment when your server users can accept a shutdown. The steps to be performed, even if they are relatively simple, can sometimes seem technical and require in any case **to take your time**. -* Know how to connect as root on your system, for example via [SSH](/ssh). (Note: while logged in as `admin`, you can root with `sudo su`) +- Know how to connect as root on your system, for example via [SSH](/ssh). (Note: while logged in as `admin`, you can root with `sudo su`) -* Know the basic commands `cd`, `ls`, `mkdir`, `rm`. +- Know the basic commands `cd`, `ls`, `mkdir`, `rm`. -* Have a backup in case things don't work out as planned +- Have a backup in case things don't work out as planned -* Have extra storage (SSD, hard drive, USB stick) connected to your server via USB or SATA +- Have extra storage (SSD, hard drive, USB stick) connected to your server via USB or SATA ## 1. Identify directories to be moved -The `ncdu /` command allows you to browse the folders on your server to see how big they are. +The `ncdu /` command allows you to browse the folders on your server to see how big they are. Below is an explanation of some of the paths that can take up weight with some comments to help you reduce their weight or choose to move them. | Paths | Contents | Tips | |--------|---|---| | `/home` | User folders accessible via SFTP | Moveable to a hard disk | -| `/home/yunohost.backup` | YunoHost's backups | Depending on your backup strategy, you may want to place this folder on a separate drive from your data or databases. -| `/home/yunohost.app` |Heavy data from yunohost applications (nextcloud, matrix...)|Moveable to a hard disk +| `/home/yunohost.backup` | YunoHost's backups | Depending on your backup strategy, you may want to place this folder on a separate drive from your data or databases. | +| `/home/yunohost.app` |Heavy data from YunoHost applications (nextcloud, matrix...)|Moveable to a hard disk | | `/home/yunohost.multimedia` | Heavy data shared between several applications | Moveable to a hard disk | | `/var/lib/mysql` | Database used by applications | Ideally leave on SSD for performance reasons | | `/var/lib/postgresql` | Database used by applications | Ideally leave on SSD for performance reasons | | `/var/mail` | User e-mails | Movable to a hard disk | | `/var/www` | Program of installed web applications | Ideally leave on SSD for performance reasons | -| `/var/log` | Event logs (pages consulted, connection attempts, hardware errors...). | This directory should not take up too much space, if it grows quickly, it may be a looping error that should be resolved. -| `/opt` | Program and dependency of some YunoHost applications. | Ideally leave it on the SSD for performance reasons. For nodejs applications it is possible to do some cleanup of unused versions. -| `/boot` | Kernels and boot files | Do not move unless you know what you are doing. It can happen that too many kernels are kept, it is possible to do some cleanup. - +| `/var/log` | Event logs (pages consulted, connection attempts, hardware errors...). | This directory should not take up too much space, if it grows quickly, it may be a looping error that should be resolved. | +| `/opt` | Program and dependency of some YunoHost applications. | Ideally leave it on the SSD for performance reasons. For nodejs applications it is possible to do some cleanup of unused versions. | +| `/boot` | Kernels and boot files | Do not move unless you know what you are doing. It can happen that too many kernels are kept, it is possible to do some cleanup. | ## 2. Connect and identify the disk @@ -109,13 +107,14 @@ mkfs.ext4 /dev/YOUR_DISK1 Replace `YOUR_DISK1` with the name of the first partition on the disk e.g. `sda1`. -!!! It is possible to adapt this step, for example to create a raid 1 volume (mirrored disks) or encrypt the folder. +!!! It is possible to adapt this step, for example to create a raid 1 volume (mirrored disks) or encrypt the folder. ## 4. Mount the disk Unlike Windows where disks are accessed with letters (C:/), under Linux, disks are made accessible via the file tree. "Mounting" a disk means making it effectively accessible in the file tree. We will arbitrarily choose to mount the disk in `/mnt/hdd` but you can name it differently (e.g. `/mnt/disk` ...). Let's start by creating the directory : + ```bash mkdir /mnt/hdd ``` @@ -128,11 +127,12 @@ mount /dev/YOUR_DISK1 /mnt/hdd (Here, `/dev/YOUR_DISK1` corresponds to the first partition on the disk) -## 5. Mount a /mnt/hdd folder on one of the folders you want to move data from +## 5. Mount a `/mnt/hdd` folder on one of the folders you want to move data from -Here we will consider that you want to move the big data of the applications which are in /home/yunohost.app and the mails on your hard disk. +Here we will consider that you want to move the big data of the applications which are in `/home/yunohost.app` and the mails on your hard disk. ### 5.1 Creating subfolders on the disk + To begin with, we create a folder on the hard drive ```bash @@ -141,6 +141,7 @@ mkdir -p /mnt/hdd/var/mail ``` ### 5.2 Switching to maintenance mode + Then, ideally, we switch to maintenance mode the applications that might be writing data. Example, for nextcloud: @@ -206,7 +207,6 @@ From this point on, your services are running with their data on disk, so it's t ## 6. Automatically mount on boot - So far we have manually mounted the disk and subfolders. However, it is necessary to configure the system to automatically mount the disk after a boot. If your tests are successful, you should keep the mount points, otherwise you should hurry up and go back to maintenance first. @@ -238,6 +238,7 @@ Use Ctrl+X then `y` to save. You can then try rebooting the system to check if the disk and subfolders are mounted automatically. ## 7. Clean up old data + Once your new setup is validated, you can proceed to delete the old data from step 5.3: ```bash diff --git a/pages/02.administer/45.tutorials/35.email_relay/email_configure_relay.fr.md b/pages/02.administer/45.tutorials/35.email_relay/email_configure_relay.fr.md index 006c0bfb..765d27f2 100644 --- a/pages/02.administer/45.tutorials/35.email_relay/email_configure_relay.fr.md +++ b/pages/02.administer/45.tutorials/35.email_relay/email_configure_relay.fr.md @@ -39,12 +39,14 @@ Habituellement les fournisseurs ont une documentation à ce sujet. ! [fa=exclamation-triangle /] Attention une fois la zone DNS enregistrée, le relais SMTP peut envoyer des e-mails à votre nom sans que vous ne le sachiez ## Étape 3 :Configurer YunoHost correctement + Il est possible de configurer soit via la webadmin ou en ligne de commande. -[ui-tabs position="top-left" active="0" theme="lite"] +[ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="Depuis la webadmin"] Depuis l'interface d'administration, dans la section `Outils` > `Paramètres de YunoHost`, et l'onglet `Email`. Il suffit d'activer l'option, et de renseigner les champs nécessaires : + - **Adresse du relais SMTP** : L'url pour le serveur SMTP. - **Port du relais SMTP** : Le port utilisé sur le serveur renseigné. - **Utilisateur du relais SMTP** : Login ou mail d'identification pour le serveur. @@ -54,11 +56,12 @@ Il suffit d'activer l'option, et de renseigner les champs nécessaires : ![Option-Relais-Smtp](image://relay_smtp_option_webadmin_en.png?resize=800) -[/ui-tab] +[/ui-tab] [ui-tab title="En ligne de commande"] Pour que YunoHost soit capable d'utiliser le relais, il faut paramétrer 4 choses. + 1. Votre url de relais SMTP (on utilisera `smtprelay.tld`). -2. Le port sur lequel on accède au relais (on utilisera le port 2525 ci-dessous) +2. Le port sur lequel on accède au relais (on utilisera le port 2525 ci-dessous) 3. Votre nom d'utilisateur SMTP (on utilisera `username`). 4. Votre mot de passe SMTP (on utilisera `password`). @@ -66,13 +69,13 @@ Pour que YunoHost soit capable d'utiliser le relais, il faut paramétrer 4 chose Le fournisseur SMTP vous fournit ces trois informations. -Premièrement se connecter sur son serveur en SSH avec la commande : +Premièrement se connecter sur son serveur en SSH avec la commande : ```bash ssh admin@domain.tld ``` -Ensuite, mettre à jour les informations suivantes : +Ensuite, mettre à jour les informations suivantes : ```bash sudo yunohost settings set email.smtp.smtp_relay_enabled -v yes diff --git a/pages/02.administer/45.tutorials/35.email_relay/email_configure_relay.md b/pages/02.administer/45.tutorials/35.email_relay/email_configure_relay.md index 2a09fa01..0e901a00 100644 --- a/pages/02.administer/45.tutorials/35.email_relay/email_configure_relay.md +++ b/pages/02.administer/45.tutorials/35.email_relay/email_configure_relay.md @@ -36,31 +36,34 @@ Once registered, the SMTP relay provider will usually ask you to modify your DNS Standard procedure is to add a DKIM key and a SPF key to your DNS records. The way to modify these records and the value of the keys you'll have to add depend both on your domain name provider and SMTP relay provider. -Usually, the SMTP relay provider will provide you with a guide on how to modify these records, together with an automatic check tool that will tell you when your DNS have been setup correctly. That step is mandatory to prove "the world" that you, owner of your domain name, did explicitly authorize your SMTP relay provider to send emails on your behalf. +Usually, the SMTP relay provider will provide you with a guide on how to modify these records, together with an automatic check tool that will tell you when your DNS have been setup correctly. That step is mandatory to prove "the world" that you, owner of your domain name, did explicitly authorize your SMTP relay provider to send emails on your behalf. Please note that modifying your DNS records could sometimes take over 24h to take effect, so be patient! ! [fa=exclamation-triangle /] From now on, a non trusty SMTP relay provider could send emails from your main domain without telling you. ### Step 3: Setup YunoHost correctly + It can be configured either from the webadmin or the command line. -[ui-tabs position="top-left" active="0" theme="lite"] +[ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="From the webadmin"] Go to your web admin, in `Tools` > `Yunohost Settings` and `Email`. Now set all options requests : + - **SMTP relay host** : SMTP server url. - **SMTP relay port** : Port use with the distant server. - **SMTP relay user** : Login or identification mail server. - **SMTP relay password** : Your SMTP relay password. -- + ! [fa=exclamation-triangle /] Password with `#` char won't works properly due to postfix limitation (it's possible other chars are forbidden, don't hesitate to report it to update this doc). ![Option-Relais-Smtp](image://relay_smtp_option_webadmin_en.png?resize=800) -[/ui-tab] +[/ui-tab] [ui-tab title="From the command line"] In order to setup your YunoHost to use your SMTP relay, you will have to configure four things: + 1. Your SMTP relay URL (for this tutorial we will use `smtprelay.tld`) 2. The port on which you access the relay (for this tutorial we will use port 2525 below) 3. Your SMTP relay username (for this tutorial we will use `username`) @@ -71,6 +74,7 @@ In order to setup your YunoHost to use your SMTP relay, you will have to configu Your SMTP relay will obviously provide you with these four things, that should be available in your control panel or whatsoever. You can log into your YunoHost server using SSH: + ```bash ssh admin@yourdomain.tld ``` diff --git a/pages/02.administer/45.tutorials/40.tor/torhiddenservice.fr.md b/pages/02.administer/45.tutorials/40.tor/torhiddenservice.fr.md index a8409335..6877e91a 100644 --- a/pages/02.administer/45.tutorials/40.tor/torhiddenservice.fr.md +++ b/pages/02.administer/45.tutorials/40.tor/torhiddenservice.fr.md @@ -7,28 +7,32 @@ routes: default: '/torhiddenservice' --- -! Ce tuto n'est pas complet ! Des données peuvent être récupérées avec cette installation comme le nom de domaine principal de votre yunohost, donc ce n'est pas un "service caché". Voir https://www.torproject.org/docs/tor-hidden-service.html.en (anglais) +! Ce tuto n'est pas complet ! Des données peuvent être récupérées avec cette installation comme le nom de domaine principal de votre YunoHost, donc ce n'est pas un "service caché". Voir (anglais) ### Installer Tor + ```bash apt install tor ``` -### Configurer notre service caché +###  Configurer notre service caché + Éditer le fichier `/etc/tor/torrc`, et ajouter ces lignes : -```bash +```text HiddenServiceDir /var/lib/tor/hidden_service/ HiddenServicePort 80 127.0.0.1:80 HiddenServicePort 443 127.0.0.1:443 ``` ### Redémarrer Tor + ```bash systemctl restart tor ``` ### Obtenir l’adresse du service caché + ```bash cat /var/lib/tor/hidden_service/hostname ``` @@ -36,23 +40,27 @@ cat /var/lib/tor/hidden_service/hostname Le nom de domaine ressemble à *random123456789.onion* ### Ajouter le domaine .onion à YunoHost + ```bash yunohost domain add random123456789.onion ``` ### Éviter la redirection vers le SSO (optionnel) + Si vous voulez éviter d’être redirigé vers le portail à la connexion pour des raisons de traçabilité, vous pouvez désactiver SSOwat pour le domaine, en éditant le fichier `/etc/nginx/conf.d/random123456789.onion.conf` et en commentant la ligne suivante (elle apparaît deux fois dans le fichier) : -```bash +```text #access_by_lua_file /usr/share/ssowat/access.lua; ``` ### Vérifier que l'on a pas fait d'erreurs dans la configuration de NGINX + ```bash nginx -t ``` ### Si tout est OK on applique les modifications de la configuration + ```bash systemctl reload nginx ``` diff --git a/pages/02.administer/45.tutorials/40.tor/torhiddenservice.it.md b/pages/02.administer/45.tutorials/40.tor/torhiddenservice.it.md index 406e2fa3..431d5737 100644 --- a/pages/02.administer/45.tutorials/40.tor/torhiddenservice.it.md +++ b/pages/02.administer/45.tutorials/40.tor/torhiddenservice.it.md @@ -7,28 +7,32 @@ routes: default: '/torhiddenservice' --- -! Questo tutorial non è completo! Con queste impostazioni alcuni dati possono essere rivelati come ad esempio il dominio principale del tuo yunohost, di conseguenza non può essere considerato un reale "Hidden service". Vedi https://www.torproject.org/docs/tor-hidden-service.html +! Questo tutorial non è completo! Con queste impostazioni alcuni dati possono essere rivelati come ad esempio il dominio principale del tuo YunoHost, di conseguenza non può essere considerato un reale "Hidden service". Vedi ### Installare Tor + ```bash apt install tor ``` ### Configurazione dell'hidden service + Modifica `/etc/tor/torrc` aggiungendo queste righe: -```bash +```text HiddenServiceDir /var/lib/tor/hidden_service/ HiddenServicePort 80 127.0.0.1:80 HiddenServicePort 443 127.0.0.1:443 ``` ### Riavvia Tor + ```bash service tor restart ``` ### Copia l'hostname del tuo Hidden Service + ```bash cat /var/lib/tor/hidden_service/hostname ``` @@ -36,19 +40,21 @@ cat /var/lib/tor/hidden_service/hostname Il dominio dell'hidden service sarà una cosa tipo *random123456789.onion* ### Aggiungi il dominio .onion a YunoHost + ```bash yunohost domain add random123456789.onion ``` ### Disabilita la redirezione SSO (opzionale) + Se non vuoi essere rediretto al portale SSO al login puoi disattivare SSOwat specificatamente per questo dominio modificando il file `/etc/nginx/conf.d/random123456789.onion.conf` commentando le seguenti linee (due volte): -```bash +```text #access_by_lua_file /usr/share/ssowat/access.lua; ``` ### Riavvia NGINX + ```bash service nginx restart ``` - diff --git a/pages/02.administer/45.tutorials/40.tor/torhiddenservice.md b/pages/02.administer/45.tutorials/40.tor/torhiddenservice.md index 71dadd67..5b636df6 100644 --- a/pages/02.administer/45.tutorials/40.tor/torhiddenservice.md +++ b/pages/02.administer/45.tutorials/40.tor/torhiddenservice.md @@ -7,28 +7,32 @@ routes: default: '/torhiddenservice' --- -! This tuto is not finished ! Some data could leak with this setup like the main domain of your yunohost, so it's not a "Hidden Service". See https://www.torproject.org/docs/tor-hidden-service.html.en +! This tuto is not finished ! Some data could leak with this setup like the main domain of your YunoHost, so it's not a "Hidden Service". See + +###  Installing Tor -### Installing Tor ```bash apt install tor ``` -### Configuring our hidden service +###  Configuring our hidden service + Edit `/etc/tor/torrc`, and add these lines: -```bash +```text HiddenServiceDir /var/lib/tor/hidden_service/ HiddenServicePort 80 127.0.0.1:80 HiddenServicePort 443 127.0.0.1:443 ``` -### Restart Tor +###  Restart Tor + ```bash service tor restart ``` ### Get your Tor Hidden Service hostname + ```bash cat /var/lib/tor/hidden_service/hostname ``` @@ -36,18 +40,21 @@ cat /var/lib/tor/hidden_service/hostname Your domain looks like *random123456789.onion* ### Add the .onion domain to YunoHost + ```bash yunohost domain add random123456789.onion ``` ### Avoid SSO redirection (optional) + If you want to avoid being redirected to the SSO portal at login, you can deactivate SSOwat for this specific tor domain, by editing the file `/etc/nginx/conf.d/random123456789.onion.conf` and commenting the following line (two times): -```bash +```text #access_by_lua_file /usr/share/ssowat/access.lua; ``` ### Restart NGINX + ```bash service nginx restart ``` diff --git a/pages/02.administer/45.tutorials/45.certificate_custom/certificate_custom.fr.md b/pages/02.administer/45.tutorials/45.certificate_custom/certificate_custom.fr.md index 2ff450ab..87536214 100644 --- a/pages/02.administer/45.tutorials/45.certificate_custom/certificate_custom.fr.md +++ b/pages/02.administer/45.tutorials/45.certificate_custom/certificate_custom.fr.md @@ -11,13 +11,13 @@ routes: Quelques changements ont eu lieu qui impactent les procédures indiquées ci-dessous : -* Le groupe metronome n'est plus utilisé directement mais ssl-cert. -* Un repertoire `/etc/yunohost/certs/DOMAIN.LTD-history/stamp` est utilisé pour conserver chaque configuration créée et un lien symbolique est créé dessus. +- Le groupe metronome n'est plus utilisé directement mais ssl-cert. +- Un repertoire `/etc/yunohost/certs/DOMAIN.LTD-history/stamp` est utilisé pour conserver chaque configuration créée et un lien symbolique est créé dessus. ### Ajout d’un certificat signé par une autorité (autre que Let's Encrypt) Après création du certificat auprès de votre autorité d’enregistrement, vous devez être en possession d’une clé privée, le fichier *key* et d’un certificat public, le fichier *crt*. -> Attention, le fichier *key* est très sensible, il est strictement personnel et doit être très bien sécurisé. +! Attention, le fichier *key* est très sensible, il est strictement personnel et doit être très bien sécurisé. Ces deux fichiers doivent être copiés sur le serveur, s’ils ne s’y trouvent pas déjà. @@ -57,27 +57,31 @@ sudo mv *.pem *.cnf yunohost_self_signed/ En fonction de l’autorité d’enregistrement, des certificats intermédiaires et racines doivent être obtenus. -> **StartSSL** -> ```bash -> sudo wget http://www.startssl.com/certs/ca.pem -O ae_certs/ca.pem -> sudo wget http://www.startssl.com/certs/sub.class1.server.ca.pem -O ae_certs/intermediate_ca.pem ->``` +#### StartSSL -> **Gandi** -> ```bash -> sudo wget https://www.gandi.net/static/CAs/GandiStandardSSLCA2.pem -O ae_certs/intermediate_ca.pem ->``` +```bash +sudo wget http://www.startssl.com/certs/ca.pem -O ae_certs/ca.pem +sudo wget http://www.startssl.com/certs/sub.class1.server.ca.pem -O ae_certs/intermediate_ca.pem +``` -> **RapidSSL** -> ```bash -> sudo wget https://knowledge.rapidssl.com/library/VERISIGN/INTERNATIONAL_AFFILIATES/RapidSSL/AR1548/RapidSSLCABundle.txt -O ae_certs/intermediate_ca.pem ->``` +#### Gandi -> **Cacert** -> ```bash -> sudo wget http://www.cacert.org/certs/root.crt -O ae_certs/ca.pem -> sudo wget http://www.cacert.org/certs/class3.crt -O ae_certs/intermediate_ca.pem ->``` +```bash +sudo wget https://www.gandi.net/static/CAs/GandiStandardSSLCA2.pem -O ae_certs/intermediate_ca.pem +``` + +#### RapidSSL + +```bash +sudo wget https://knowledge.rapidssl.com/library/VERISIGN/INTERNATIONAL_AFFILIATES/RapidSSL/AR1548/RapidSSLCABundle.txt -O ae_certs/intermediate_ca.pem +``` + +#### Cacert + +```bash +sudo wget http://www.cacert.org/certs/root.crt -O ae_certs/ca.pem +sudo wget http://www.cacert.org/certs/class3.crt -O ae_certs/intermediate_ca.pem +``` Les certificats intermédiaires et root doivent être réunis avec le certificat obtenu pour créer une chaîne de certificats unifiés. @@ -99,7 +103,7 @@ cat crt.pem key.pem Les certificats et la clé privée doivent ressembler à cela : -```plaintext +```text -----BEGIN CERTIFICATE----- MIICVDCCAb0CAQEwDQYJKoZIhvcNAQEEBQAwdDELMAkGA1UEBhMCRlIxFTATBgNV BAgTDENvcnNlIGR1IFN1ZDEQMA4GA1UEBxMHQWphY2NpbzEMMAoGA1UEChMDTExC @@ -138,4 +142,4 @@ Rechargez la configuration de NGINX pour prendre en compte le nouveau certificat sudo service nginx reload ``` -Votre certificat est prêt à servir. Vous pouvez toutefois vous assurer de sa mise en place en testant le certificat à l’aide du service de geocerts. +Votre certificat est prêt à servir. Vous pouvez toutefois vous assurer de sa mise en place en testant le certificat à l’aide du service de [geocerts](https://www.geocerts.com/ssl_checker). diff --git a/pages/02.administer/45.tutorials/45.certificate_custom/certificate_custom.md b/pages/02.administer/45.tutorials/45.certificate_custom/certificate_custom.md index ee6eeb54..3e70980e 100644 --- a/pages/02.administer/45.tutorials/45.certificate_custom/certificate_custom.md +++ b/pages/02.administer/45.tutorials/45.certificate_custom/certificate_custom.md @@ -11,13 +11,13 @@ routes: Some changes have taken place which impact the procedures indicated below: -* Metronome group is no longer used directly but ssl-cert. -* A `/etc/yunohost/certs/DOMAIN.LTD-history/stamp` directory is used to keep each configuration created and a symlink is created. +- Metronome group is no longer used directly but ssl-cert. +- A `/etc/yunohost/certs/DOMAIN.LTD-history/stamp` directory is used to keep each configuration created and a symlink is created. ### Adding a signed certificate by an authority (other than Let's Encrypt) After the certificate creation with your registration authority, you must have a private key, the key file, and a public certificate, the crt file. -> Note that the key file is very sensitive, it is strictly personal and must be very well secured. +! Note that the key file is very sensitive, it is strictly personal and must be very well secured. These two files should be copied to the server, if they are not already there. @@ -56,27 +56,31 @@ sudo mv *.pem *.cnf yunohost_self_signed/ Depending on the registration authority, intermediate and root certificates must be obtained. -> **StartSSL** -> ```bash -> sudo wget http://www.startssl.com/certs/ca.pem -O ae_certs/ca.pem -> sudo wget http://www.startssl.com/certs/sub.class1.server.ca.pem -O ae_certs/intermediate_ca.pem ->``` +#### StartSSL -> **Gandi** -> ```bash -> sudo wget https://www.gandi.net/static/CAs/GandiStandardSSLCA2.pem -O ae_certs/intermediate_ca.pem ->``` +```bash +sudo wget http://www.startssl.com/certs/ca.pem -O ae_certs/ca.pem +sudo wget http://www.startssl.com/certs/sub.class1.server.ca.pem -O ae_certs/intermediate_ca.pem +``` -> **RapidSSL** -> ```bash -> sudo wget https://knowledge.rapidssl.com/library/VERISIGN/INTERNATIONAL_AFFILIATES/RapidSSL/AR1548/RapidSSLCABundle.txt -O ae_certs/intermediate_ca.pem ->``` +#### Gandi -> **Cacert** -> ```bash -> sudo wget http://www.cacert.org/certs/root.crt -O ae_certs/ca.pem -> sudo wget http://www.cacert.org/certs/class3.crt -O ae_certs/intermediate_ca.pem ->``` +```bash +sudo wget https://www.gandi.net/static/CAs/GandiStandardSSLCA2.pem -O ae_certs/intermediate_ca.pem +``` + +#### RapidSSL + +```bash +sudo wget https://knowledge.rapidssl.com/library/VERISIGN/INTERNATIONAL_AFFILIATES/RapidSSL/AR1548/RapidSSLCABundle.txt -O ae_certs/intermediate_ca.pem +``` + +#### Cacert + +```bash +sudo wget http://www.cacert.org/certs/root.crt -O ae_certs/ca.pem +sudo wget http://www.cacert.org/certs/class3.crt -O ae_certs/intermediate_ca.pem +``` Intermediate and root certificates must be combined with the obtained certificate to create a unified certificate chain. @@ -98,7 +102,7 @@ cat crt.pem key.pem The certificates and private key should look like this: -```plaintext +```text -----BEGIN CERTIFICATE----- MIICVDCCAb0CAQEwDQYJKoZIhvcNAQEEBQAwdDELMAkGA1UEBhMCRlIxFTATBgNV BAgTDENvcnNlIGR1IFN1ZDEQMA4GA1UEBxMHQWphY2NpbzEMMAoGA1UEChMDTExC @@ -137,5 +141,4 @@ Reload NGINX configuration to take into account the new certificate. sudo service nginx reload ``` -Your certificate is ready. However, you can ensure that it is in place by testing the certificate using the geocerts. - +Your certificate is ready. However, you can ensure that it is in place by testing the certificate using the [geocerts](https://www.geocerts.com/ssl_checker). diff --git a/pages/02.administer/45.tutorials/55.moving_app_folder/moving_app_folder.fr.md b/pages/02.administer/45.tutorials/55.moving_app_folder/moving_app_folder.fr.md index 6f3f3c32..df17fffa 100644 --- a/pages/02.administer/45.tutorials/55.moving_app_folder/moving_app_folder.fr.md +++ b/pages/02.administer/45.tutorials/55.moving_app_folder/moving_app_folder.fr.md @@ -13,31 +13,27 @@ Lorsqu'un dossier d'application devient trop volumineux il peut être intéressa Partant du principe que [le stockage externe est déjà monté](/external_storage), voici un guide pour déplacer le dossier de l'application wordpress : - #### 1. Déplacer le dossier wordpress et tout son contenu vers le stockage externe -```shell +```bash mv /var/www/wordpress /media/externalharddrive/ ``` -___ -#### 2. Créer un lien symbolique +#### 2. Créer un lien symbolique Le programme qui va chercher des informations dans le dossier /var/www/wordpress sera redirigé vers le stockage externe. -```shell +```bash ln -s /media/externalharddrive/wordpress /var/www/wordpress ``` -___ #### 3. (peut être) bidouiller les permissions Après tout ça, il est possible que vous ayez à modifier les permissions de `/media/externalharddrive` pour que `www-data` (ou l'utilisateur de l'app) puisse y accéder. Quelque chose comme : - -```shell + +```bash chgrp www-data /media/externalharddrive chmod g+rx /media/externalharddrive - ``` (À préciser par un expert) diff --git a/pages/02.administer/45.tutorials/55.moving_app_folder/moving_app_folder.md b/pages/02.administer/45.tutorials/55.moving_app_folder/moving_app_folder.md index e0802f0e..932e15a0 100644 --- a/pages/02.administer/45.tutorials/55.moving_app_folder/moving_app_folder.md +++ b/pages/02.administer/45.tutorials/55.moving_app_folder/moving_app_folder.md @@ -16,30 +16,28 @@ Here's a summary of how to do this the application wordpress. Here, is is assume #### 1. Move the entire wordpress folder to an external hard drive -```shell +```bash mv /var/www/wordpress /media/externalharddrive/ ``` -#### 2. Create a symbolic link +#### 2. Create a symbolic link So that programs looking for files in /var/www/wordpress will actually take them from the harddrive -```shell +```bash ln -s /media/externalharddrive/wordpress /var/www/wordpress ``` #### 3. Tweak permissions (maybe?) After this, note that you may need to tweak the permissions of `/media/externalharddrive` so that `www-data` (or the user corresponding to the app) is able to read through the folder... Something like : - -```shell + +```bash chgrp www-data /media/externalharddrive chmod g+rx /media/externalharddrive - ``` (but it depends on your exact setup... Please update this doc page if you figure out what to do exactly) !!! If you want to do it with *NextCloud*, see [this Tutorial](/app_nextcloud). - diff --git a/pages/02.administer/45.tutorials/60.security/security.fr.md b/pages/02.administer/45.tutorials/60.security/security.fr.md index b96d2d24..f09c2c33 100644 --- a/pages/02.administer/45.tutorials/60.security/security.fr.md +++ b/pages/02.administer/45.tutorials/60.security/security.fr.md @@ -13,9 +13,9 @@ Tous les protocoles que YunoHost utilise sont **chiffrés**, les mots de passe n Deux points sont néanmoins importants à noter : -* L’installation d’applications supplémentaires **augmente le nombre de failles** potentielles. Il est donc conseillé de se renseigner sur chacune d’elle **avant l’installation**, d’en comprendre le fonctionnement et juger ainsi l’impact que provoquerait une potentielle attaque. N’installez **que** les applications qui semblent importantes pour votre usage. +- L’installation d’applications supplémentaires **augmente le nombre de failles** potentielles. Il est donc conseillé de se renseigner sur chacune d’elle **avant l’installation**, d’en comprendre le fonctionnement et juger ainsi l’impact que provoquerait une potentielle attaque. N’installez **que** les applications qui semblent importantes pour votre usage. -* Le fait que YunoHost soit un logiciel répandu augmente les chances de subir une attaque. Si une faille est découverte, elle peut potentiellement **toucher toutes les instances YunoHost** à un temps donné. Nous nous efforçons de corriger ces failles le plus rapidement possible, pensez donc à **mettre à jour régulièrement** votre système. +- Le fait que YunoHost soit un logiciel répandu augmente les chances de subir une attaque. Si une faille est découverte, elle peut potentiellement **toucher toutes les instances YunoHost** à un temps donné. Nous nous efforçons de corriger ces failles le plus rapidement possible, pensez donc à **mettre à jour régulièrement** votre système. !!!! Si vous avez besoin de conseil, n’hésitez pas à [nous demander](/help). diff --git a/pages/02.administer/45.tutorials/60.security/security.it.md b/pages/02.administer/45.tutorials/60.security/security.it.md index 17a7cd85..1ca3ff47 100644 --- a/pages/02.administer/45.tutorials/60.security/security.it.md +++ b/pages/02.administer/45.tutorials/60.security/security.it.md @@ -11,11 +11,11 @@ YunoHost è stato sviluppato per la migliore sicurezza senza troppe complicazion Rimangono due punti importanti da notare: -* L'installazione di applicazioni addizionali può **aumentare significativamente** il numero di potenziali problemi di sicurezza. È importante chiedere informazioni relative a problemi di sicurezza **prima di installare un'applicazione** e provare ad installare solo le applicazioni necessarie. +- L'installazione di applicazioni addizionali può **aumentare significativamente** il numero di potenziali problemi di sicurezza. È importante chiedere informazioni relative a problemi di sicurezza **prima di installare un'applicazione** e provare ad installare solo le applicazioni necessarie. -* Poiché YunoHost è un software molto conosciuto ed usato aumenta le possibilità di un attacco. Se viene scoperto un problema potrebbe essere usato contemporaneamente contro tutte le istanze. Mantenete **aggiornato** il vostro sistema per aumentare la sicurezza. Gli aggiornamenti possono essere automatizzati installando l'[applicazione "Unattended_upgrades"](https://install-app.yunohost.org/?app=unattended_upgrades). +- Poiché YunoHost è un software molto conosciuto ed usato aumenta le possibilità di un attacco. Se viene scoperto un problema potrebbe essere usato contemporaneamente contro tutte le istanze. Mantenete **aggiornato** il vostro sistema per aumentare la sicurezza. Gli aggiornamenti possono essere automatizzati installando l'[applicazione "Unattended_upgrades"](https://install-app.yunohost.org/?app=unattended_upgrades). -!!!! Se avete bisogno di aiuto non esitate a [chiedere](/help). +!!!! Se avete bisogno di aiuto non esitate a [chiedere](/help). !! [fa=shield /] Per discutere di problemi di sicurezza contattate il [team YunoHost security](/security_team). @@ -27,11 +27,11 @@ Se il vostro server YunoHost è usato in situazioni critiche di produzione oppur ! **ATTENZIONE:** Per seguire queste istruzioni è necessario essere in possesso di conoscenze avanzate di amministrazione di sistema. -!!!! **SUGGERIMENTO** Non chiudete mai la connessione SSH in uso prima di aver controllato che le modifiche fatte siano corrette. Provate la nuova configurazione aprendo un nuovo terminale o una nuova finestra cosicché possiate eliminare le modifiche se c'è qualcosa di sbagliato. +!!!! **SUGGERIMENTO** Non chiudete mai la connessione SSH in uso prima di aver controllato che le modifiche fatte siano corrette. Provate la nuova configurazione aprendo un nuovo terminale o una nuova finestra cosicché possiate eliminare le modifiche se c'è qualcosa di sbagliato. ### Autenticazione SSH con la chiave -Di default l'autenticazione SSH chiede la password dell'amministratore. È consigliato disattivare questo tipo di autenticazione per sostituirlo con il sistema basato sulle chiavi. +Di default l'autenticazione SSH chiede la password dell'amministratore. È consigliato disattivare questo tipo di autenticazione per sostituirlo con il sistema basato sulle chiavi. **Sul client**: @@ -40,7 +40,7 @@ ssh-keygen ssh-copy-id -i ~/.ssh/id_rsa.pub ``` -!!! Se incontrate problemi di permessi impostate `username` come proprietario della directory `~/.ssh` con il comando `chown`. Fate attenzione al fatto che, per ragiorni di sicurezza questa directory deve essere con il modo `700`. +!!! Se incontrate problemi di permessi impostate `username` come proprietario della directory `~/.ssh` con il comando `chown`. Fate attenzione al fatto che, per ragiorni di sicurezza questa directory deve essere con il modo `700`. !!! Se state usando Ubuntu 16.04 dovete avviare `ssh-add` per avviare l'agente SSH. @@ -51,6 +51,7 @@ Digitate la password di amministrazione e la chiave verrà copiata nel vostro se ```bash sudo yunohost settings set security.ssh.password_authentication -v no ``` + --- ### Modificare la porta SSH @@ -58,7 +59,7 @@ sudo yunohost settings set security.ssh.password_authentication -v no Per prevenire i tentativi di connessione dei robot che fanno scan di internet alla ricerca di server con SSH attivato è possibile cambiare la porta SSH. Questa impostazione è gestita da un'impostazione di sistema che aggiorna le configurazioni di SSH e di fail2ban. -! Se modificate una qualsiasi impostazione nel file `/etc/ssh/sshd_config`, anche solo la porta di ascolto, YunoHost non gestirà più il file. Per questa ragione è necessario usare sempre gli strumenti di amministrazione per fare modifiche ai file di configurazione del sistema. +! Se modificate una qualsiasi impostazione nel file `/etc/ssh/sshd_config`, anche solo la porta di ascolto, YunoHost non gestirà più il file. Per questa ragione è necessario usare sempre gli strumenti di amministrazione per fare modifiche ai file di configurazione del sistema. ```bash sudo yunohost settings set security.ssh.port -v @@ -81,11 +82,13 @@ La configurazione TLS di default per i servizi è pensata per offrire una buona Il cambio di livello di compatibilità non è definitivo e può essere ripristinato nel caso in cui non si adatti alle vostre necessità. **Sul vostro server**, cambio della policy per NGINX + ```bash sudo yunohost settings set security.nginx.compatibility -v modern ``` **Sul vostro server**, cambio della policy per SSH + ```bash sudo yunohost settings set security.ssh.compatibility -v modern ``` diff --git a/pages/02.administer/45.tutorials/60.security/security.md b/pages/02.administer/45.tutorials/60.security/security.md index a25e72c1..8e59416d 100644 --- a/pages/02.administer/45.tutorials/60.security/security.md +++ b/pages/02.administer/45.tutorials/60.security/security.md @@ -11,9 +11,9 @@ YunoHost has been developed to provide the best security without too much compli Two things remain important to note: -* Installing additional apps can **significantly increase** the number of potential security flaws. Do not hesitate to get information about security flaws **before installing an app**, and try to only install apps which will suit your needs. +- Installing additional apps can **significantly increase** the number of potential security flaws. Do not hesitate to get information about security flaws **before installing an app**, and try to only install apps which will suit your needs. -* The fact that YunoHost is a well-known and used piece of software increases the chances of an attack. If a flaw is discovered, it could potentially affect all YunoHost instances at once. Keep your system **up-to-date** to remain safe. Updates can be automated by installing the ["Unattended_upgrades" app](https://install-app.yunohost.org/?app=unattended_upgrades). +- The fact that YunoHost is a well-known and used piece of software increases the chances of an attack. If a flaw is discovered, it could potentially affect all YunoHost instances at once. Keep your system **up-to-date** to remain safe. Updates can be automated by installing the ["Unattended_upgrades" app](https://install-app.yunohost.org/?app=unattended_upgrades). !!!! If you need advice, do not hesitate to [ask us](/help). diff --git a/pages/02.administer/45.tutorials/65.sftp_on_apps/sftp_on_apps.it.md b/pages/02.administer/45.tutorials/65.sftp_on_apps/sftp_on_apps.it.md index 06c05747..02d6a6db 100644 --- a/pages/02.administer/45.tutorials/65.sftp_on_apps/sftp_on_apps.it.md +++ b/pages/02.administer/45.tutorials/65.sftp_on_apps/sftp_on_apps.it.md @@ -29,6 +29,3 @@ setfacl -m u:wordpress:r-- /var/www/wordpress/wp-config.php setfacl -R -m u:USER:rwX /var/www/wordpress setfacl -R -d -m u:USER:rwX /var/www/wordpress ``` - - - diff --git a/pages/02.administer/45.tutorials/65.sftp_on_apps/sftp_on_apps.md b/pages/02.administer/45.tutorials/65.sftp_on_apps/sftp_on_apps.md index d90aced5..22cde23a 100644 --- a/pages/02.administer/45.tutorials/65.sftp_on_apps/sftp_on_apps.md +++ b/pages/02.administer/45.tutorials/65.sftp_on_apps/sftp_on_apps.md @@ -29,5 +29,3 @@ setfacl -m u:wordpress:r-- /var/www/wordpress/wp-config.php setfacl -R -m u:USER:rwX /var/www/wordpress setfacl -R -d -m u:USER:rwX /var/www/wordpress ``` - - diff --git a/pages/02.administer/50.troubleshooting/10.admin_password/change_admin_password.fr.md b/pages/02.administer/50.troubleshooting/10.admin_password/change_admin_password.fr.md index 925aa9b1..6dc53420 100644 --- a/pages/02.administer/50.troubleshooting/10.admin_password/change_admin_password.fr.md +++ b/pages/02.administer/50.troubleshooting/10.admin_password/change_admin_password.fr.md @@ -9,7 +9,7 @@ routes: Vous voudrez peut-être changer votre mot de passe d'administrateur pour des raisons de sécurité ou parce que vous l'avez oublié. -Si vous avez oublié votre mot de passe ou si vous ne pouvez pas vous connecter en utilisant l'utilisateur `admin`, vous +Si vous avez oublié votre mot de passe ou si vous ne pouvez pas vous connecter en utilisant l'utilisateur `root`, vous pouvez peut-être encore changer le mot de passe en vous connectant en tant que "root" sur SSH (à partir de votre réseau local ! ou en utilisant un mode rescure si vous êtes sur un VPS...) @@ -18,11 +18,8 @@ SSH (à partir de votre réseau local ! ou en utilisant un mode rescure si vous 1. Connectez-vous à l'interface web d'administration. 2. Allez dans la section Outis > Changer le mot de passe d’administration. - ## En ligne de commande - ```bash -yunohost tools adminpw +yunohost tools rootpw ``` - diff --git a/pages/02.administer/50.troubleshooting/10.admin_password/change_admin_password.it.md b/pages/02.administer/50.troubleshooting/10.admin_password/change_admin_password.it.md index efadb568..cde0d4fa 100644 --- a/pages/02.administer/50.troubleshooting/10.admin_password/change_admin_password.it.md +++ b/pages/02.administer/50.troubleshooting/10.admin_password/change_admin_password.it.md @@ -17,10 +17,8 @@ Innanzitutto collegati all'interfaccia web d'amministrazione. Poi vai su Strumenti > Cambia password amministrazione. - ## Usando l'interfaccia a linea di comando - ```bash yunohost tools rootpw ``` diff --git a/pages/02.administer/50.troubleshooting/10.admin_password/change_admin_password.md b/pages/02.administer/50.troubleshooting/10.admin_password/change_admin_password.md index d01d6eb6..d249c898 100644 --- a/pages/02.administer/50.troubleshooting/10.admin_password/change_admin_password.md +++ b/pages/02.administer/50.troubleshooting/10.admin_password/change_admin_password.md @@ -19,10 +19,8 @@ First, connect to your web administration. Then go to Tools > Change administration password. - ## Using the command line interface - ```bash yunohost tools rootpw ``` diff --git a/pages/02.administer/50.troubleshooting/15.noaccess/noaccess.fr.md b/pages/02.administer/50.troubleshooting/15.noaccess/noaccess.fr.md index 3102fc7b..53405fd5 100644 --- a/pages/02.administer/50.troubleshooting/15.noaccess/noaccess.fr.md +++ b/pages/02.administer/50.troubleshooting/15.noaccess/noaccess.fr.md @@ -11,50 +11,47 @@ Il existe de nombreuses causes pouvant empêcher totalement ou partiellement d'a Cette page va vous aider à diagnostiquer, obtenir un accès et si besoin réparer votre système. Les pannes les plus courantes sont priorisées de haut en bas. Il vous suffit de tester chaque hypothèse. - ## Vous avez accès au serveur via l'adresse IP, mais pas avec le nom de domaine ? -#### Si vous êtes auto-hébergé à la maison : il faut configurer les redirection de ports +### Si vous êtes auto-hébergé à la maison : il faut configurer les redirection de ports -Vérifier que vous arrivez à accéder au serveur en utilisant son IP globale (que vous pouvez trouver sur https://ip.yunohost.org). Si cela ne fonctionne pas: - - Assurez-vous d'avoir [configuré les redirections de ports](/isp_box_config) - - Certaines box de FAI ne supportent pas le hairpinning et vous ne pouvez pas accéder à votre serveur depuis l'intérieur du réseau local (sauf à passer par l'IP locale). Pour contourner le problème, vous pouvez utiliser un des moyens suivants: - - utiliser une connexion cellulaire (4/5G) - - modifier le fichier /etc/hosts sur vos équipements - - déclarer l'ip locale de yunohost comme resolveur DNS dans votre routeur (partie DHCP) et ouvrir le port 53 UDP sur votre yunohost en faisant attention de ne pas activer l'upnp sur le port 53. Surtout, n'ouvrez pas le port 53 de votre routeur. +Vérifier que vous arrivez à accéder au serveur en utilisant son IP globale (que vous pouvez trouver sur ). Si cela ne fonctionne pas: -#### Il faut configurer vos enregistrement DNS +- Assurez-vous d'avoir [configuré les redirections de ports](/isp_box_config) +- Certaines box de FAI ne supportent pas le hairpinning et vous ne pouvez pas accéder à votre serveur depuis l'intérieur du réseau local (sauf à passer par l'IP locale). Pour contourner le problème, vous pouvez utiliser un des moyens suivants: + - utiliser une connexion cellulaire (4/5G) + - modifier le fichier `/etc/hosts` sur vos équipements + - déclarer l'ip locale de YunoHost comme resolveur DNS dans votre routeur (partie DHCP) et ouvrir le port `53` UDP sur votre YunoHost en faisant attention de ne pas activer l'upnp sur le port `53`. Surtout, n'ouvrez pas le port `53` de votre routeur. + +### Il faut configurer vos enregistrement DNS (N.B.: ce n'est pas nécessaire si vous utilisez un domaine de type nohost.me, noho.st ou ynh.fr) -Il vous faut configurer vos enregistrement DNS comme expliqué sur [cette page](/dns_config) (à minima l'enregistrement A, et AAAA si vous avez de l'IPv6). +Il vous faut configurer vos enregistrement DNS comme expliqué sur [cette page](/dns_config) (à minima l'enregistrement A, et AAAA si vous avez de l'IPv6). -Vous pouvez valider que les enregistrements DNS sont corrects en comparant le résultat de https://www.whatsmydns.net/ avec l'IP globale de votre serveur (si vous êtes hébergé à la maison, vous pouvez obtenir cette IP sur https://ip.yunohost.org) +Vous pouvez valider que les enregistrements DNS sont corrects en comparant le résultat de avec l'IP globale de votre serveur (si vous êtes hébergé à la maison, vous pouvez obtenir cette IP sur ) - -#### Autres causes possibles +### Autres causes possibles - Votre nom de domaine noho.st, nohost.me ou ynh.fr est inaccessible suite à une panne de l'infra YunoHost. Vérifiez sur le forum si d'autre personnes signalent le même problème. - Votre nom de domaine est peut-être expiré. Vous pouvez vérifier que votre nom de domaine a expiré en vous connectant sur l'interface de votre registrar ou en utilisant le whois par exemple via la commande `whois NOM_DE_DOMAINE`. - Vous avez une IP dynamique. Dans ce cas, il faut mettre en place un script qui se charge de mettre à jour régulièrement votre IP (ou d'utiliser un nom de domaine en nohost.me, noho.st ou ynh.fr qui inclue un tel mécanisme) - ## Vous êtes face à une erreur de certificat qui vous empêche d’accéder à la webadmin Si vous venez d'installer votre serveur ou d'ajouter un nouveau domaine, il utilise pour le moment un certificat auto-signé. Dans ce cas, il devrait être possible et légitime d'ajouter *exceptionnellement* une exception de sécurité le temps d'[installer un certificat Let's Encrypt](/certificate) à condition d'être sur une connexion internet sûre (pas avec Tor Browser par exemple). Une erreur de certificat peut également être affichée dans certain cas où vous avez fait une faute de frappe dans la barre d'adresse de votre navigateur. - ## Vous avez accès en SSH mais pas à la Web admin ou inversement -#### Vous essayez de vous connecter en SSH avec `root` plutôt qu'avec `admin` +### Vous essayez de vous connecter en SSH avec `root` plutôt qu'avec `admin` Par défaut, la connexion en SSH doit s'effectuer avec l'utilisateur `admin`. Il est possible de se connecter à la machine avec l'utilisateur `root` *seulement depuis le réseau local* sur lequel se situe le serveur (ou bien via la console web / VNC pour des VPS). Lorsque vous exécutez des commandes `yunohost` en tant qu'admin, il faut les précéder de la commande `sudo` (par exemple `sudo yunohost user list`). Vous pouvez également devenir `root` en tapant `sudo su`. -#### Vous avez été banni temporairement +### Vous avez été banni temporairement Votre serveur YunoHost inclut un mécanisme (Fail2Ban) qui banni automatiquement les IPs qui échouent plusieurs fois à s'authentifier. Dans certains cas, il peut s'agir d'un programme (par exemple un client Nextcloud) qui est configuré avec un ancien mot de passe ou d'un utilisateur qui utilise la même IP que vous. @@ -66,17 +63,17 @@ Voir aussi : [débannir une IP sur Fail2Ban](/fail2ban) NB : le bannissement dure en général 10 à 12 minutes. Le bannissement n'est actif qu'en IPv4. - -#### Le serveur web NGINX est cassé +### Le serveur web NGINX est cassé Peut-être que le serveur web NGINX est en panne. Vous pouvez vérifier cela [en ssh](/ssh) avec `yunohost service status nginx`. Si il est en panne, vérifiez que la configuration ne comporte pas d'erreur avec `nginx -t`. Si la configuration est cassée, ceci est peut-être du à une l'installation ou désinstallation d'une application de mauvaise qualité... Si vous êtes perdu, [demandez de l'aide](/help). Il se peut également que le serveur web (NGINX) ou le serveur ssh aient été tués suite à un manque d'espace disque ou de RAM / swap. + - Tentez de relancer le service avec `systemctl restart nginx`. - Vous pouvez contrôler l'espace disque utilisé avec `df -h`. Si une de vos partitions est remplie à 100%, il faut identifier ce qui prend de la place sur votre système et faire de la place. Il est possible d'installer l'utilitaire `ncdu` avec `apt install ncdu` puis de faire `ncdu /` pour analyser la taille des dossiers de toute l'arborescence. - Vous pouvez contrôler l'utilisation de la RAM / swap avec `free -h`. En fonction des résultats, il peut être nécessaire d'optimiser votre serveur pour qu'il utilise moins de RAM (suppression d'app lourdes et inutiles...), d'ajouter de la RAM ou d'ajouter un fichier de swap. -#### Votre serveur est accessible en IPv6 mais pas en IPv4 ou inversement +### Votre serveur est accessible en IPv6 mais pas en IPv4 ou inversement Vous pouvez le vérifier en tentant de faire des ping sur votre serveur en IPv4 et en IPv6. @@ -86,26 +83,24 @@ Dans ce cas il faut résoudre votre problème de connectivité. Dans certains, cas une mise à jour de votre box a activé l'IPv6, entraînant des problèmes de configuration au niveau de votre nom de domaine. +## La webadmin fonctionne, mais certaines applications web me renvoient une erreur 502 -## La webadmin fonctionne, mais certaines applications web me renvoient une erreur 502. - -Il est fort probablement que le service correspondant à ces applications soit en panne (typiquement pour les applications PHP, il s'agit de php7.0-fpm ou php7.3-fpm). Vous pouvez alors tenter de relancer le service, et si cela ne fonctionne pas, regarder les logs du service correspondant et/ou [demander de l'aide](/help). - +Il est fort probablement que le service correspondant à ces applications soit en panne (typiquement pour les applications PHP, il s'agit de `php7.0-fpm` ou `php7.3-fpm`). Vous pouvez alors tenter de relancer le service, et si cela ne fonctionne pas, regarder les logs du service correspondant et/ou [demander de l'aide](/help). ## Vous avez perdu votre mot de passe administrateur ? (ou bien le mot de passe est refusé) Si vous arrivez à afficher la page web d'administration (forcez le rafraîchissement avec CTRL + F5 pour être sur) et que vous n'arrivez pas à vous connectez, vous avez probablement un mot de passe erroné. Si vous êtes certain du mot de passe, il est possible que le service SLAPD qui gère l'authentification soit en panne. Si c'est le cas, il vous faut vous connecter en `root`. + - Si votre serveur est chez vous, vous avez sans doute accès au réseau local du serveur. Depuis ce réseau, vous pouvez vous connecter [en SSH](/ssh) avec l'utilisateur `root`. -- Si vous êtes sur un VPS, votre hébergeur vous fournit peut-être la possibilité d'avoir une console sur votre serveur depuis le navigateur web. +- Si vous êtes sur un VPS, votre hébergeur vous fournit peut-être la possibilité d'avoir une console sur votre serveur depuis le navigateur web. Une fois connecté, il vous faut regarder l'état du service avec la commande `yunohost service status slapd` et/ou tenter de réinitialiser votre mot de passe avec la commande `yunohost tools adminpw`. Si vous ne pouvez pas ou ne réussissez pas non plus à vous connecter en `root`, vous allez devoir opérer en mode rescue. TODO: à compléter - ## Votre VPN a expiré ou ne se monte plus Si vous utilisez un VPN a IP fixe, peut être que celui-ci est arrivé à expiration ou que l'infrastructure de votre fournisseur est en difficulté. @@ -113,6 +108,7 @@ Si vous utilisez un VPN a IP fixe, peut être que celui-ci est arrivé à expira Dans ce cas, vous pouvez peut être accéder à votre serveur avec son IP locale s'agissant probablement d'un serveur auto-hébergé chez-vous. Pour connaître votre IP locale, certaines BOX proposent une cartographie du réseau en cours avec les équipements connectés. Sinon, en ligne de commande avec linux: + ```bash sudo arp-scan --local ``` @@ -135,7 +131,6 @@ Si les disques sont corrompus et difficiles à monter, il faut sauvegarder les d Sinon, relancer `grub-update` et `grub-install` en `chroot` ou avec `systemd-nspawn`. - ## L’accès en VNC ou via écran ne fonctionne pas Dans ce cas il peut s'agir d'un problème matériel sur votre serveur physique ou d'un problème d'hyperviseur si c'est un VPS. diff --git a/pages/02.administer/50.troubleshooting/15.noaccess/noaccess.it.md b/pages/02.administer/50.troubleshooting/15.noaccess/noaccess.it.md index bef33fc9..309c30b0 100644 --- a/pages/02.administer/50.troubleshooting/15.noaccess/noaccess.it.md +++ b/pages/02.administer/50.troubleshooting/15.noaccess/noaccess.it.md @@ -11,15 +11,16 @@ Ci possono essere diverse ragioni che possono portare al blocco parziale o total Questa pagina cercherà di trovare il problema, riottenere l'accesso ed eventualmente riparare il vostro sistema. Le cause più comuni sono all'inizio per cui siete invitati a seguire questo tutorial dall'inizio. -## Hai l'accesso al server usando l'indirizzo IP locale ma non dal nome di dominio. +## Hai l'accesso al server usando l'indirizzo IP locale ma non dal nome di dominio -#### Se il server è self-hosted a casa: controlla il port forwarding +### Se il server è self-hosted a casa: controlla il port forwarding Controlla di riuscire ad accedere al server usando l'IP pubblico (lo puoi trovare su [https://ip.yunohost.org](https://ip.yunohost.org)). Se questo non funziona: - - Assicurati di aver [impostato il forwarding](/isp_box_config). - - Alcuni ISP non supportano l'*hairpinning*, cosa che ti impedirà di raggiungere il tuo server dal nome di dominio dalla rete locale. Nel caso puoi usare una connessione cellulare o modificare il file `hosts` del tuo computer in modo da associare il nome di dominio all'indirizzo IP locale invece che a quello pubblico. - -#### Configura i record DNS + +- Assicurati di aver [impostato il forwarding](/isp_box_config). +- Alcuni ISP non supportano l'*hairpinning*, cosa che ti impedirà di raggiungere il tuo server dal nome di dominio dalla rete locale. Nel caso puoi usare una connessione cellulare o modificare il file `hosts` del tuo computer in modo da associare il nome di dominio all'indirizzo IP locale invece che a quello pubblico. + +### Configura i record DNS ! Questo non è un problema se stai usando un dominio fornito da `nohost.me`, `noho.st` or `ynh.fr` @@ -27,7 +28,7 @@ Devi configurare i tuoi [record DNS](/dns_config) (come minimo i record `A` e `A Puoi verificare la correttezza dei record DNS confrontando i risultati dati da [questo servizio](https://www.whatsmydns.net/) con l'[IP restituito dal nostro servizio](https://ip.yunohost.org). -#### Altre probabili cause +### Altre probabili cause - Il tuo dominio `noho.st`, `nohost.me` o `ynh.fr` non è raggiungibile a causa di un problema nell'infrastruttura di YunoHost. Controlla il [forum](https://forum.yunohost.org/) per annunci o post di persone relativi allo stesso problema. - Il tuo nome di dominio potrebbe essere scaduto. Controlla la pagina del registrar usato per la registrazione oppure usa il comando `whois yourdomain.tld`. @@ -41,13 +42,13 @@ Puoi verificare la correttezza dei record DNS confrontando i risultati dati da [ ## Puoi accedere via SSH ma non dalla pagina di amministrazione o l'inverso -#### Stai provando a loggarti via SSH come `root` invece che con l'utente `admin` +### Stai provando a loggarti via SSH come `root` invece che con l'utente `admin` Di default è possibile loggarsi via SSH solo come `admin`. È possibile loggarsi come `root` *solo dall'interno della rete locale del server*. Se il server è su una VPS la console web o VNC fornita dal provider DPS dovrebbe funzionare. Se stai provando ad avviare i comandi `yunohost` dalla riga di comando come `admin` è necessario avviarlo preceduto dal comando `sudo` (ad esempio `sudo yunohost user list`). È possibile diventare `root` anche con il comando `sudo su`. -#### Sei stato bannato temporaneamente +### Sei stato bannato temporaneamente Il tuo server YunoHost include il servizio Fail2Ban che banna automaticamente gli indirizzi IP che falliscono più volte di seguito. In alcuni casi possono essere programmi configurati con password vecchie (ad esempio client Nextcloud) oppure un utente che ha il tuo stesso IP. @@ -59,7 +60,7 @@ Vedi anche: [togliere il ban ad un indirizzo](/fail2ban) !!!! I ban normalmente durano dai 0 ai 12 minuti e solo su IPv4. -#### Il server web NGINX non funziona +### Il server web NGINX non funziona Può essere che il server web NGINX non stia funzionando. @@ -68,10 +69,10 @@ Maybe the NGINX web server is out of order. You can check that [trough SSH](/ssh The NGINX or SSH servers may have been killed due to a lack of storage space, RAM, or swap. - Try restarting the service with `systemctl restart nginx`. -- You can check used storage with `df -h`. If one of your partitions is full, you need to identify what fills it and make rooù. You can use `ncdu` command (install it with `apt install ncdu` to browse from the root directory: `ncdu /` +- You can check used storage with `df -h`. If one of your partitions is full, you need to identify what fills it and make rooù. You can use `ncdu` command (install it with `apt install ncdu`) to browse from the root directory: `ncdu /` - You can check RAM and swap usage with `free -h`. Depending on the result, it may be necessary to optimize your server to use less RAM (removal of heavy or unused apps...), add more RAM or add a swap file. -#### Your server is reachable by IPv6, but not IPv4, or inversely +### Your server is reachable by IPv6, but not IPv4, or inversely You can check that by `ping`ing it: @@ -84,7 +85,7 @@ If one of the two is working, use it to connect by SSH or the webadmin. If none are working, you need to resolv your connection issue. In some cases, an update of your router may have enabled IPv6 and DNS configuration may be disrupted. -## Webadmin is working, but some web apps are returning 502 errors. +## Webadmin is working, but some web apps are returning 502 errors It is highly probable that the underlying service for these apps is failing (e.g. PHP apps requiring `php7.0-fpm` or `php7.3-fpm`). You can then try to restart the services, and/or ask for [help](/help) @@ -93,6 +94,7 @@ It is highly probable that the underlying service for these apps is failing (e.g If you can reach the webadmin login page (force reload with `CTRL + F5` to be sure), and you cannot log in, your password is probably wrong. If yoy are sure of your passord, it may be due to the `slapd` service failing. If that's the case, log into the server by SSH as `root`. + - If your server is at home, you most likely have access to the local network. From this network, you can follow the [SSH instructions](/ssh)`. - If your server is a VPS, your provider may offer a web console. @@ -109,6 +111,7 @@ If you have a VPN with fixed IP, maybe it has expired, or the provider's infrast In that case, contact your VPN provider to renew it and update the parameters of the VPN Client app. Meanwhile, try reaching your server if it is at home, by: + - its local IP, retrievable from your router configuration panel or `sudo arp-scan --local` - reaching it at `yunohost.local`, if it is at home and that you have only one YunoHost server in your network. diff --git a/pages/02.administer/50.troubleshooting/15.noaccess/noaccess.md b/pages/02.administer/50.troubleshooting/15.noaccess/noaccess.md index 1e283e0d..e0034f7f 100644 --- a/pages/02.administer/50.troubleshooting/15.noaccess/noaccess.md +++ b/pages/02.administer/50.troubleshooting/15.noaccess/noaccess.md @@ -11,23 +11,24 @@ There are several reasons that could lead to one administrator's access being pa This page will help you diagnose the issue, get back access, and if needed repair your system. Most common causes are listed first, so follow the tutorial from top to bottom. -## You have access to the server with its local IP address, but not its domain name. +## You have access to the server with its local IP address, but not its domain name -#### If you are self-hosted at home: fix ports forwarding +### If you are self-hosted at home: fix ports forwarding Check that you are getting access to the server by using its public IP (you can find at [https://ip.yunohost.org](https://ip.yunohost.org). If this does not work: - - Make sure you have [set up forwarding](/isp_box_config) - - Some ISP routers do not support *hairpinning*, which prevents you from reaching your server by its domain name from within your local network. If so, you can use a cellular connection, or tweak your `hosts` file on your computer to make it bind your domain name to the local IP address instead of the public one. -#### Configure DNS records +- Make sure you have [set up forwarding](/isp_box_config) +- Some ISP routers do not support *hairpinning*, which prevents you from reaching your server by its domain name from within your local network. If so, you can use a cellular connection, or tweak your `hosts` file on your computer to make it bind your domain name to the local IP address instead of the public one. + +### Configure DNS records ! This is not a problem if you are using a domain from `nohost.me`, `noho.st` or `ynh.fr`) -You have to configure your [DNS records](/dns_config) (at least `A` records, and `AAAA` if you have an IPv6 connection). +You have to configure your [DNS records](/dns_config) (at least `A` records, and `AAAA` if you have an IPv6 connection). You can check that the DNS records are correct by comparing the results given by [this service](https://www.whatsmydns.net/) with the [IP given by our service](https://ip.yunohost.org). -#### Other probable causes +### Other probable causes - You domain `noho.st`, `nohost.me`, or `ynh.fr` is unreachable following a failure on YunoHost's infrastructure. Check the [forum](https://forum.yunohost.org/) for announcements or people posting about the same issue. - Your domain name may be expired. Check that on your registrar's client panel, or by using the command `whois yourdomain.tld`. @@ -41,13 +42,13 @@ You can check that the DNS records are correct by comparing the results given by ## You have access via SSH but not via the webadmin, or inversely -#### You are trying to log in with SSH as `root` instead of `admin` user. +### You are trying to log in with SSH as `root` instead of `admin` user By default, SSH connection has to be made as `admin`. It possible to log into the server as `root` *only from the local network of the server*. If your server is a VPS, the web console or VNC provided by VPS providers may work. If you are running `yunohost` commands in the CLI as `admin`, you have to call them with `sudo` before (for example `sudo yunohost user list`). You can also become `root` by running `sudo su`. -#### You have been temporarily banned +### You have been temporarily banned Your YunoHost server includes a service, Fail2ban, which automatically bans IPs that fail several times in a row to log in. In some cases it can be software (e.g. Nextcloud client) that are confifured with an old password, or a user who has the same IP as you have. @@ -59,17 +60,17 @@ See also : [unban an IP on Fail2Ban](/fail2ban) !!!! Ban are usually 10 to 12-minute-long, and on IPv4 only. -#### NGINX web server is broken +### NGINX web server is broken Maybe the NGINX web server is out of order. You can check that [trough SSH](/ssh) with the command `yunohost service status nginx`. If it is failing, check that its configuration is correct by running `nginx -t`. If it is indeed broken, it may be due to the installation or removal of a low-quality app... If you need support, [ask for it](/help). The NGINX or SSH servers may have been killed due to a lack of storage space, RAM, or swap. - Try restarting the service with `systemctl restart nginx`. -- You can check used storage with `df -h`. If one of your partitions is full, you need to identify what fills it and make room. You can use `ncdu` command (install it with `apt install ncdu` to browse from the root directory: `ncdu /` +- You can check used storage with `df -h`. If one of your partitions is full, you need to identify what fills it and make room. You can use `ncdu` command (install it with `apt install ncdu`) to browse from the root directory: `ncdu /` - You can check RAM and swap usage with `free -h`. Depending on the result, it may be necessary to optimize your server to use less RAM (removal of heavy or unused apps...), add more RAM or add a swap file. -#### Your server is reachable by IPv6, but not IPv4, or inversely +### Your server is reachable by IPv6, but not IPv4, or inversely You can check that by `ping`ing it: @@ -82,7 +83,7 @@ If one of the two is working, use it to connect by SSH or the webadmin. If none are working, you need to resolv your connection issue. In some cases, an update of your router may have enabled IPv6 and DNS configuration may be disrupted. -## Webadmin is working, but some web apps are returning 502 errors. +## Webadmin is working, but some web apps are returning 502 errors It is highly probable that the underlying service for these apps is failing (e.g. PHP apps requiring `php7.0-fpm` or `php7.3-fpm`). You can then try to restart the services, and/or ask for [help](/help) @@ -91,6 +92,7 @@ It is highly probable that the underlying service for these apps is failing (e.g If you can reach the webadmin login page (force reload with `CTRL + F5` to be sure), and you cannot log in, your password is probably wrong. If yoy are sure of your passord, it may be due to the `slapd` service failing. If that's the case, log into the server by SSH as `root`. + - If your server is at home, you most likely have access to the local network. From this network, you can follow the [SSH instructions](/ssh)`. - If your server is a VPS, your provider may offer a web console. @@ -107,6 +109,7 @@ If you have a VPN with fixed IP, maybe it has expired, or the provider's infrast In that case, contact your VPN provider to renew it and update the parameters of the VPN Client app. Meanwhile, try reaching your server if it is at home, by: + - its local IP, retrievable from your router configuration panel or `sudo arp-scan --local` - reaching it at `yunohost.local`, or `yunohost-2.local`, etc. depending on how many YunoHost servers are on your network. diff --git a/pages/02.administer/50.troubleshooting/20.ipv6/ipv6.fr.md b/pages/02.administer/50.troubleshooting/20.ipv6/ipv6.fr.md index f1700a1b..3608073c 100644 --- a/pages/02.administer/50.troubleshooting/20.ipv6/ipv6.fr.md +++ b/pages/02.administer/50.troubleshooting/20.ipv6/ipv6.fr.md @@ -12,29 +12,30 @@ L'IPv6 peut fonctionner directement dans certains cas. Mais dans d'autres, ou ch ## Avec un VPS chez OVH OVH donne une adresse IPv4 et une IPv6 pour ses VPS, mais par défaut, seule l'IPv4 fonctionne. -La documentation d'OVH à ce sujet est ici : https://docs.ovh.com/fr/vps/configurer-ipv6/ +La documentation d'OVH à ce sujet est ici : ### Configurer le serveur DNS -Ici : https://yunohost.org/#/dns_subdomains +Ici : ### Configurer le serveur Sur le panneau de gestion d'OVH, vous aller récupérer 3 informations : + - l'adresse IPv6 du serveur -- l'adresse passerelle IPv6 +- l'adresse passerelle IPv6 - le préfixe IPv6. Les offres VPS SSD d'OVH ne fournissent qu'**une** seule adresse IPV6, le préfixe est donc `/128` Sur votre VPS, vous allez créer une sauvegarde de votre fichier de configuration des interfaces réseau dans votre répertoire home avec la commande : `cp /etc/network/interfaces ~/interfaces`. 2 possibilités pour inscrire vos données ipv6 : -1/ vous pouvez modifier le fichier de configuration `/etc/network/interfaces` +1/ vous pouvez modifier le fichier de configuration `/etc/network/interfaces` 2/ vous pouvez créer un autre fichier "à part" par la commande `sudo nano /etc/network/interfaces.d/ovh-ipv6.cfg` (ce dernier fichier est pris en compte car appartenant au dossier) -! Découvrir et vérifier avec la commande `ip a` l'interface utilisée sur votre VPS ( généralement du type ENS3 chez OVH) +! Découvrir et vérifier avec la commande `ip a` l'interface utilisée sur votre VPS ( généralement du type ENS3 chez OVH) ! Dans cet exemple, nous considérons que votre interface réseau est `eth0`. Vous devez adapter l'exemple pour correspondre à votre situation. -```plaintext +```text iface eth0 inet6 static address netmask @@ -47,6 +48,7 @@ pre-down /sbin/ip -6 route del dev eth0 Maintenant, enregistrez le fichier et redémarrez les services réseau avec : `service networking restart`. (TODO : ideally we should find a way to validate the content of the configuration, otherwise it could fuck up the network stack and get disconnected from the VPS ?) Vérifiez votre configuration avec les commandes : + - `ip a` pour afficher les adresses IP des interfaces - `hostname -I` pour afficher les adresses IP du système - essayez de faire un test de `ping` sur un serveur IPv6 (vous pouvez utiliser `ping6 ipv6.yunohost.org`) diff --git a/pages/02.administer/50.troubleshooting/20.ipv6/ipv6.it.md b/pages/02.administer/50.troubleshooting/20.ipv6/ipv6.it.md index a83d0c3d..b08ca6c3 100644 --- a/pages/02.administer/50.troubleshooting/20.ipv6/ipv6.it.md +++ b/pages/02.administer/50.troubleshooting/20.ipv6/ipv6.it.md @@ -12,15 +12,16 @@ IPv6 dovrebbe funzionare automaticamente in molti casi ma in alcune situzioni o ## Usando una VPS di OVH OVH fornisce un indirizzo IPv4 e uno IPv6 ma di default funziona solo il primo. -La documentazione di OVH la puoi trovare qui: https://docs.ovh.com/gb/en/vps/configuring-ipv6/ +La documentazione di OVH la puoi trovare qui: ### Configurare il server DNS -Qui : https://yunohost.org/#/dns_subdomains +Qui : ### Configurare il server Nella pagina di configurazione di OVH dovrai copiare questi 3 elementi: + - l'indirizzo IPv6 - l'indirizzo del gateway IPv6 - il prefisso IPv6. Nelle VPS SSD di OVH i prefissi sono `/128` perché hai a disposizione solo *uno* indirizzo IPv6. @@ -30,7 +31,7 @@ Poi puoi modificare il file di configurazione (`/etc/network/interfaces`) come i ! In questo esempio si assume che il nome della tua interfaccia di rete sia `eth0`. Nel caso invece che sia differente (controlla con il comando `ip a`) devi adattare di conseguenza l'esempio qui sotto. -```plaintext +```text iface eth0 inet6 static address netmask @@ -43,6 +44,7 @@ pre-down /sbin/ip -6 route del dev eth0 Now, save the file and restart the network service with : `service networking restart`. (TODO : ideally we should find a way to validate the content of the configuration, otherwise it could fuck up the network stack and get disconnected from the VPS ?) Check your configuration with these commands : + - `ip a` to display network interfaces and addresses - `hostname -I` to display the system IP addresses - try to ping an IPv6 server (for example you can use `ping6 ip6.yunohost.org`) diff --git a/pages/02.administer/50.troubleshooting/20.ipv6/ipv6.md b/pages/02.administer/50.troubleshooting/20.ipv6/ipv6.md index 8cc8efc8..b20b51c7 100644 --- a/pages/02.administer/50.troubleshooting/20.ipv6/ipv6.md +++ b/pages/02.administer/50.troubleshooting/20.ipv6/ipv6.md @@ -12,25 +12,26 @@ IPv6 may work out of the box in many cases. But in some cases or some specific p ## With a VPS from OVH OVH gives one IPv4 address and one IPv6 address for VPS but by default, only IPv4 is OK. -The OVH's documentation is here : https://docs.ovh.com/gb/en/vps/configuring-ipv6/ +The OVH's documentation is here : ### Configure the DNS server -Here : https://yunohost.org/#/dns_subdomains +Here : ### Configure the server On the OVH panel, you will copy 3 elements: + - the IPv6 address - the IPv6 gateway address - the IPv6 prefix. On OVH's VPS SSD, prefixes are `/128` because you have only *one* IPv6 address. On your VPS, create a backup of the network configuration with : `cp /etc/network/interfaces ~/interfaces` in home directory. -Then, you can edit the configuration file (`/etc/network/interfaces`) with the following. +Then, you can edit the configuration file (`/etc/network/interfaces`) with the following. ! In this example, it is assumed that your network interface is `eth0`. If it's different (check with `ip a`) you need to adapt the example below. -```plaintext +```text iface eth0 inet6 static address netmask @@ -43,6 +44,7 @@ pre-down /sbin/ip -6 route del dev eth0 Now, save the file and restart the network service with : `service networking restart`. (TODO : ideally we should find a way to validate the content of the configuration, otherwise it could fuck up the network stack and get disconnected from the VPS ?) Check your configuration with these commands : + - `ip a` to display network interfaces and addresses - `hostname -I` to display the system IP addresses - try to ping an IPv6 server (for example you can use `ping6 ip6.yunohost.org`) diff --git a/pages/02.administer/50.troubleshooting/25.unblacklisting/blacklist_forms.fr.md b/pages/02.administer/50.troubleshooting/25.unblacklisting/blacklist_forms.fr.md index d45f637e..9c92fd17 100644 --- a/pages/02.administer/50.troubleshooting/25.unblacklisting/blacklist_forms.fr.md +++ b/pages/02.administer/50.troubleshooting/25.unblacklisting/blacklist_forms.fr.md @@ -10,21 +10,21 @@ routes: Il peut arriver que votre serveur (son adresse IP) soit ajouté à la liste noire de certains fournisseurs d’adresse de courrier électronique ou de services anti-spam. Les courriels envoyés à ces adresses sont alors filtrés et n’arrivent pas à destination. #### Testez votre serveur + Pour tester si votre serveur est sur une liste noire, vous pouvez utiliser les outils suivants : -* [Test en envoyant un email](https://www.mail-tester.com) -* [Test à partir de l’adresse IP](http://whatismyipaddress.com/blacklist-check) + +- [Test en envoyant un email](https://www.mail-tester.com) +- [Test à partir de l’adresse IP](http://whatismyipaddress.com/blacklist-check) Le cas échéant, voici certains des formulaires vous permettant de retirer votre adresse IP de ces listes : ##### Fournisseurs Email -* [Microsoft](https://support.microsoft.com/en-us/getsupport?oaspworkflow=start_1.0.0.0&wfname=capsub&productkey=edfsmsbl3&locale=en-us) -* [GMail](https://support.google.com/mail/contact/msgdelivery) +- [Microsoft](https://support.microsoft.com/en-us/getsupport?oaspworkflow=start_1.0.0.0&wfname=capsub&productkey=edfsmsbl3&locale=en-us) +- [GMail](https://support.google.com/mail/contact/msgdelivery) -##### Services anti-spam +##### Services anti-spam -* [SpamHaus](http://www.spamhaus.org/lookup) +- [SpamHaus](http://www.spamhaus.org/lookup) Si le fournisseur vous concernant n’apparaît pas dans la liste, cherchez le formulaire adéquat, il existe probablement. - - diff --git a/pages/02.administer/50.troubleshooting/25.unblacklisting/blacklist_forms.it.md b/pages/02.administer/50.troubleshooting/25.unblacklisting/blacklist_forms.it.md index a47867aa..9ccd90c9 100644 --- a/pages/02.administer/50.troubleshooting/25.unblacklisting/blacklist_forms.it.md +++ b/pages/02.administer/50.troubleshooting/25.unblacklisting/blacklist_forms.it.md @@ -11,17 +11,17 @@ Può succedere talvolta che il tuo IP venga inserito nelle blacklist da parte di ## Prova il tuo server -* [Prova mandando un email](https://www.mail-tester.com) +- [Prova mandando un email](https://www.mail-tester.com) - [Prova da un indirizzo IP](http://whatismyipaddress.com/blacklist-check) Di seguito vengono elencati alcuni form che possono aiutarti a far rimuovere il tuo indirizzo IP da queste liste ## Provider email -* [Microsoft](https://support.microsoft.com/en-us/getsupport?oaspworkflow=start_1.0.0.0&wfname=capsub&productkey=edfsmsbl3&locale=en-us) -* [GMail](https://support.google.com/mail/contact/msgdelivery) +- [Microsoft](https://support.microsoft.com/en-us/getsupport?oaspworkflow=start_1.0.0.0&wfname=capsub&productkey=edfsmsbl3&locale=en-us) +- [GMail](https://support.google.com/mail/contact/msgdelivery) -## Servizi anti-spam +## Servizi anti-spam -* [SpamHaus](http://www.spamhaus.org/lookup) -* http://whatismyipaddress.com/blacklist-check +- [SpamHaus](http://www.spamhaus.org/lookup) +- diff --git a/pages/02.administer/50.troubleshooting/25.unblacklisting/blacklist_forms.md b/pages/02.administer/50.troubleshooting/25.unblacklisting/blacklist_forms.md index 3670bcf6..25152679 100644 --- a/pages/02.administer/50.troubleshooting/25.unblacklisting/blacklist_forms.md +++ b/pages/02.administer/50.troubleshooting/25.unblacklisting/blacklist_forms.md @@ -15,6 +15,7 @@ To check your Email deliverability, YunoHost provide some tests avilables in the all the points evaluated by [the well known mail-tester.com](https://www.mail-tester.com) except for mail content (usefull if you prepare a newsletter). However, if you have a doubt on the internal diagnosis results, you could check on external tools: + - by sending an emails : [Mail tester](https://www.mail-tester.com) - by providing the public ip : [MultiRBL Valli](https://multirbl.valli.org/) or [Whatismyip](https://whatismyipaddress.com/blacklist-check) @@ -22,45 +23,50 @@ However, if you have a doubt on the internal diagnosis results, you could check This command can help you to summarize which emails has been refused by other SMTP server and why. -``` +```bash cat /var/log/mail.log | grep "deferred" | sed -E "s/(:[0-9][0-9]).+.+dsn/\terror/g" | sed -E "s/, status=deferred \(/ /g" | sed -E "s/\)$//g" ``` See [the list of SMTP return code](https://en.wikipedia.org/wiki/List_of_SMTP_server_return_codes) from wikipedia. ## Untestable email providers + YunoHost is only able to test generic blacklist using the DNS RBL mechanism. However, Gmail, Microsoft, Yahoo or Free maintains their own blacklisting mechanism, so in some situation you may need to contact their teams through dedicated forms or use dedicated tools. ### Microsoft -* No way to test easily IP reputation -* [Microsoft guide for postmaster](https://sendersupport.olc.protection.outlook.com/pm/) -* [Information about SMTP return code from Microsoft](https://sendersupport.olc.protection.outlook.com/pm/troubleshooting.aspx#Codes) -* Reputation Management tools : - * [Junk Email Reporting Program (JMRP)](https://postmaster.live.com/snds/JMRP.aspx) - * [Smart Network Data Services (SNDS)](https://postmaster.live.com/snds/index.aspx) -* [Get support form for deliverability issues](https://support.microsoft.com/supportrequestform/8ad563e3-288e-2a61-8122-3ba03d6b8d75) (Sadly you need a Microsoft account :/ ) +- No way to test easily IP reputation +- [Microsoft guide for postmaster](https://sendersupport.olc.protection.outlook.com/pm/) +- [Information about SMTP return code from Microsoft](https://sendersupport.olc.protection.outlook.com/pm/troubleshooting.aspx#Codes) +- Reputation Management tools : + - [Junk Email Reporting Program (JMRP)](https://postmaster.live.com/snds/JMRP.aspx) + - [Smart Network Data Services (SNDS)](https://postmaster.live.com/snds/index.aspx) +- [Get support form for deliverability issues](https://support.microsoft.com/supportrequestform/8ad563e3-288e-2a61-8122-3ba03d6b8d75) (Sadly you need a Microsoft account :/ ) ### Gmail -* No way to test easily IP reputation -* [Google guide for postmaster](https://support.google.com/a/topic/1354753) -* [Information about SMTP return code from Google](https://support.google.com/a/answer/3726730) -* Reputation Management tools : [Google Postmaster Tools](https://postmaster.google.com) -* [Get support form for deliverability issues](https://support.google.com/mail/contact/bulk_send_new) + +- No way to test easily IP reputation +- [Google guide for postmaster](https://support.google.com/a/topic/1354753) +- [Information about SMTP return code from Google](https://support.google.com/a/answer/3726730) +- Reputation Management tools : [Google Postmaster Tools](https://postmaster.google.com) +- [Get support form for deliverability issues](https://support.google.com/mail/contact/bulk_send_new) ### Yahoo -* No way to test easily IP reputation -* [Yahoo guide for postmaster](https://senders.yahooinc.com/best-practices) -* [Information about SMTP return code from Yahoo](https://senders.yahooinc.com/smtp-error-codes) -* Reputation Management tools : [Complaint Feedback Loop](https://io.help.yahoo.com/contact/index?page=contactform&locale=en_US&token=Zh%2FBBVqXzLHlIbokbUqVWTUbuuQeXGkGnZzhKR2JQ4O6mMQdy9JSWdtWFXvjthcYCRj9bUIFfycOfG%2B4GOHPHoOGa8HwDO2%2B0kYRtTcdR8Nja5P9HWkKh3VWfS3pyu4UdjhvwG%2BBCvnYFl5dToDK%2Fw%3D%3D&selectedChannel=email-icon) -* [Get support form for deliverability issues](https://senders.yahooinc.com/contact) + +- No way to test easily IP reputation +- [Yahoo guide for postmaster](https://senders.yahooinc.com/best-practices) +- [Information about SMTP return code from Yahoo](https://senders.yahooinc.com/smtp-error-codes) +- Reputation Management tools : [Complaint Feedback Loop](https://io.help.yahoo.com/contact/index?page=contactform&locale=en_US&token=Zh%2FBBVqXzLHlIbokbUqVWTUbuuQeXGkGnZzhKR2JQ4O6mMQdy9JSWdtWFXvjthcYCRj9bUIFfycOfG%2B4GOHPHoOGa8HwDO2%2B0kYRtTcdR8Nja5P9HWkKh3VWfS3pyu4UdjhvwG%2BBCvnYFl5dToDK%2Fw%3D%3D&selectedChannel=email-icon) +- [Get support form for deliverability issues](https://senders.yahooinc.com/contact) ### Free + You can find a tool to test your IP, advices, explanation of error code and a way to contact Free on [this page](https://postmaster.free.fr/) ## Get alert about emails sent without SPF or DKIM + If you use your own domains and think that some mails are sent by unauthorized servers (so without SPF/DKIM), you get report about this mail with. -``` + +```text _dmarc.DOMAIN 3600 IN TXT "v=DMARC1; p=none; fo=1; rua=mailto:example@domain.tld!10m" ``` - diff --git a/pages/02.administer/50.troubleshooting/troubleshooting.fr.md b/pages/02.administer/50.troubleshooting/troubleshooting.fr.md index f933f200..3634e5c0 100644 --- a/pages/02.administer/50.troubleshooting/troubleshooting.fr.md +++ b/pages/02.administer/50.troubleshooting/troubleshooting.fr.md @@ -13,7 +13,7 @@ Voici quelques conseils généraux à suivre lorsque vous rencontrez des problè Restez calme. La plupart des problèmes sont moins grave que ce que les débutants pensent. Pour l'amour de Dieu (ou de votre déité, animal, nourriture préférée), ne sautez pas à pieds joint dans la "spirate de réinstallation" en pensant que réinstaller à partir de zéro va magiquement résoudre vos problèmes. Réinstaller est une opération lourde et n'est pas une bonne stratégie sur le long-terme pour résoudre les problèmes. Vous finirez par vous lasser et n'apprendrez rien. -## 1. Regardez sur le forum ou bugtrackers si quelqu'un a eu un problème similaire. +## 1. Regardez sur le forum ou bugtrackers si quelqu'un a eu un problème similaire Cherchez dans [le forum](https://forum.yunohost.org) des fils de discussions qui discutent de choses similaire aux problème que vous rencontrez. Si vous avez un soucis lié à une application en particulier, vous pouvez également tenter de chercher un ticket similaire sur le bugtracker de l'application, par exemple [ici se trouve le bugtracker de l'app wordpress](https://github.com/YunoHost-Apps/wordpress_ynh/issues). @@ -22,5 +22,3 @@ Cherchez dans [le forum](https://forum.yunohost.org) des fils de discussions qui Soit sur [le forum](https://forum.yunohost.org) ou bien le chat : c.f. [cette page](/help) !!! POUR L'AMOUR DE DIEU, PRIÈRE DE fournir du contexte ! Les bénévoles ne peuvent PAS vous aider si vous ne prenez pas *cinq* petites minutes pour décrire votre contexte : quel type de hardware, quelle version de YunoHost, qu'est-ce que vous essayez de faire, ce qui s'est passé, et **les journaux (logs) correspondants**. - - diff --git a/pages/02.administer/50.troubleshooting/troubleshooting.it.md b/pages/02.administer/50.troubleshooting/troubleshooting.it.md index 3d8f1186..fce8652d 100644 --- a/pages/02.administer/50.troubleshooting/troubleshooting.it.md +++ b/pages/02.administer/50.troubleshooting/troubleshooting.it.md @@ -9,11 +9,11 @@ routes: Di seguito alcuni consigli generali per risolvere problemi con il vostro server. -## 0. Don't panic. +## 0. Don't panic Mantenete la calma. La maggior parte dei problemi sono meno gravi di quanto pensa chi è alle prime armi. Per amor di Dio (o le vostre divinità preferite / animali / cibo), non cadete nella "spirale della reinstallazione" presupponendo che reinstallare il vostro server da capo possa risolvere magicamente i problemi. La reinstallazione è un'operazione gravosa e non è una buona strategia per risolvere i problemi. Ti stancherai e non imparerai niente. -## 1. Cerca problemi simili nel forum o nei bugtrackers. +## 1. Cerca problemi simili nel forum o nei bugtrackers Cerca [nel forum](https://forum.yunohost.org) per argomenti simili al problema che stai trovando. Se hai problemi con una app specifica puoi consultare il bugtracker relativo, ad esempio [questo è il bugtracker per l'app Wordpress app](https://github.com/YunoHost-Apps/wordpress_ynh/issues). @@ -22,5 +22,3 @@ Cerca [nel forum](https://forum.yunohost.org) per argomenti simili al problema c Sia [sul forum](https://forum.yunohost.org) siaa nella chat : vedi [questa pagina](/help) !!! PER AMOR DI DIO, PER FAVORE fornisci un minimo di contesto! I volontari non possono aiutarti se non ti prendi *cinque* minuti per descrivere il contesto: il tipo di hardware, la versione di YunoHost, cosa stai cercando di fare e cos'hai provato a fare, cos'è successo e **i log relativi**. - - diff --git a/pages/02.administer/50.troubleshooting/troubleshooting.md b/pages/02.administer/50.troubleshooting/troubleshooting.md index 72370d48..de5c6f8e 100644 --- a/pages/02.administer/50.troubleshooting/troubleshooting.md +++ b/pages/02.administer/50.troubleshooting/troubleshooting.md @@ -9,11 +9,11 @@ routes: Here are some general advices when encountering issues with your server. -## 0. Don't panic. +## 0. Don't panic Stay calm. Most issues are less worse than newcomers usually think. For the love of God (or your favourite deity / animal / food), please don't jump into the "reinstallation spiral" thinking reinstalling your server from scratch will magically fix stuff. Reinstalling is a heavy operation and is not a good long-term strategy for fixing problems. You will get tired and won't learn anything. -## 1. Look for similar issues on the forum or bugtrackers. +## 1. Look for similar issues on the forum or bugtrackers Search [the forum](https://forum.yunohost.org) for topics similar to the issue you're encountering. If you have issues with a specific app, you may also want to check the corresponding bugtracker of the app, for example [here is the bugtracker for the Wordpress app](https://github.com/YunoHost-Apps/wordpress_ynh/issues). @@ -22,5 +22,3 @@ Search [the forum](https://forum.yunohost.org) for topics similar to the issue y Either on [the forum](https://forum.yunohost.org) or the chat: c.f. [this page](/help) !!! FOR THE LOVE OF GOD, PLEASE provide basic context! Volunteers can NOT help you if you do not take *five* minutes to describe your context: which kind of hardware, which YunoHost version, what you are trying to do, what you tried, what happened and **the corresponding logs**. - - diff --git a/pages/02.administer/55.providers/05.registrar/gandi/autodns.it.md b/pages/02.administer/55.providers/05.registrar/gandi/autodns.it.md index d59cb98e..b09e6957 100644 --- a/pages/02.administer/55.providers/05.registrar/gandi/autodns.it.md +++ b/pages/02.administer/55.providers/05.registrar/gandi/autodns.it.md @@ -13,12 +13,8 @@ Questa pagina indica come ottenere una chiave API con Gandi di modo da configura ! NB. : **NON comunicare a nessuno il token API!** Un attaccante malizioso con il tuo token potrebbe prendere il controllo del tuo dominio e quindi anche del tuo server! -1. Connettiti a https://account.gandi.net/ - +1. Connettiti a 2. Dovresti vedere questa pagina e quindi clicca su 'Security' - -![](image://registrar_api_gandi_1.png?resize=800) - + ![](image://registrar_api_gandi_1.png?resize=800) 3. Nella pagina successiva clicca su '(re)Generate the API key'. - -![](image://registrar_api_gandi_2.png?resize=800) + ![](image://registrar_api_gandi_2.png?resize=800) diff --git a/pages/02.administer/55.providers/05.registrar/gandi/autodns.md b/pages/02.administer/55.providers/05.registrar/gandi/autodns.md index 2cad29eb..63c210ef 100644 --- a/pages/02.administer/55.providers/05.registrar/gandi/autodns.md +++ b/pages/02.administer/55.providers/05.registrar/gandi/autodns.md @@ -14,11 +14,7 @@ This page is meant to guide you in obtaining an API key from Gandi in order to c ! NB. : **DO NOT share your API tokens with anybody!** A malicious attacker obtaining your tokens could take over your domain, and possibly your server! 1. Go to [https://account.gandi.net/](https://account.gandi.net/) - 2. You should land on this page. Then click on 'Security' - -![](image://registrar_api_gandi_1.png?resize=800) - + ![](image://registrar_api_gandi_1.png?resize=800) 3. In the next page, click on '(re)Generate the API key'. - -![](image://registrar_api_gandi_2.png?resize=800) + ![](image://registrar_api_gandi_2.png?resize=800) diff --git a/pages/02.administer/55.providers/05.registrar/namecheap/autodns.md b/pages/02.administer/55.providers/05.registrar/namecheap/autodns.md index 09b9c478..a1369514 100644 --- a/pages/02.administer/55.providers/05.registrar/namecheap/autodns.md +++ b/pages/02.administer/55.providers/05.registrar/namecheap/autodns.md @@ -1,11 +1,22 @@ -[API Documentation](https://www.namecheap.com/support/api/intro/) +--- +title: Obtaining an API key from Namecheap +template: docs +taxonomy: + category: docs +routes: + default: '/providers/registrar/namecheap/autodns' + aliases: + - '/registar_api_namecheap' +--- + +[API Documentation](https://www.namecheap.com/support/api/intro/) > 1. Login to your Namecheap account. > > 2. Go to the Profile > Tools menu. -> +> > 3. Scroll down to the Business & Dev Tools section. Click on MANAGE next to Namecheap API Access. -> +> > 4. Toggle ON/OFF, read our Terms of Service, enter your account password. -> +> > 5. After enabling API access, you will be allotted an APIKey. Your Namecheap account username will act as API username. Your access to the API is authenticated using these elements. diff --git a/pages/02.administer/55.providers/05.registrar/ovh/autodns/autodns.fr.md b/pages/02.administer/55.providers/05.registrar/ovh/autodns/autodns.fr.md index 040c4cca..03bcfc6b 100644 --- a/pages/02.administer/55.providers/05.registrar/ovh/autodns/autodns.fr.md +++ b/pages/02.administer/55.providers/05.registrar/ovh/autodns/autodns.fr.md @@ -13,7 +13,7 @@ Cette page a pour but de vous guider dans l'obtention d'une clé API d'OVH afin ! NB. : **Ne partagez PAS vos tokens API avec qui que ce soit !** Un attaquant malveillant obtenant vos tokens pourrait prendre le contrôle de votre domaine, et éventuellement de votre serveur ! -1. Allez sur https://eu.api.ovh.com/createToken/ +1. Allez sur 2. Remplissez le formulaire avec les informations requises comme indiqué ci-dessous : @@ -23,10 +23,10 @@ Cette page a pour but de vous guider dans l'obtention d'une clé API d'OVH afin - Description du script : par exemple `YunoHost Auto DNS` - Validité : `Unlimited` - Droits : utilisez le bouton `+` pour ajouter les lignes suivantes - - `GET` : `/domain/zone/*` - - `POST` : `/domain/zone/*` - - `PUT` : `/domain/zone/*` - - `DELETE` : `/domain/zone/*` + - `GET` : `/domain/zone/*` + - `POST` : `/domain/zone/*` + - `PUT` : `/domain/zone/*` + - `DELETE` : `/domain/zone/*` ![](image://registrar_api_ovh_1.png?resize=800) diff --git a/pages/02.administer/55.providers/05.registrar/ovh/autodns/autodns.it.md b/pages/02.administer/55.providers/05.registrar/ovh/autodns/autodns.it.md index c6262ee7..74b83555 100644 --- a/pages/02.administer/55.providers/05.registrar/ovh/autodns/autodns.it.md +++ b/pages/02.administer/55.providers/05.registrar/ovh/autodns/autodns.it.md @@ -7,13 +7,13 @@ routes: default: '/providers/registrar/ovh/autodns' aliases: - '/registar_api_ovh' --- +--- Questa parte ha lo scopo di guidarvi nella procedura necessaria all'ottenimento di una chiave API di OVH, necessaria per impostare la procedura di configurazione automatica dei DNS di YunoHost. ! NB. : **Non divulgate MAI i vostri token API !** Un attaccante maligno con i vostri token potrebbe prendere il controllo del vostro dominio ed anche eventualmente del vostro server! -1. Recatevi su https://eu.api.ovh.com/createToken/ +1. Recatevi su 2. Compilate il formulario con le informazioni richieste, come nell'esempio seguente: @@ -23,12 +23,11 @@ Questa parte ha lo scopo di guidarvi nella procedura necessaria all'ottenimento - Date una sommaria descrizione: es. `YunoHost Auto DNS` - Validità: `Unlimited` - Rights: utilizzate il pulsante `+` per aggiungere le seguenti linee - - `GET` : `/domain/zone/*` - - `POST` : `/domain/zone/*` - - `PUT` : `/domain/zone/*` - - `DELETE` : `/domain/zone/*` + - `GET` : `/domain/zone/*` + - `POST` : `/domain/zone/*` + - `PUT` : `/domain/zone/*` + - `DELETE` : `/domain/zone/*` ![](image://registrar_api_ovh_1.png?resize=800) - 3. Otterrete tre tokens (una chiave segreta, una chiave pubblica, e una chiave consumer) che dovranno essere utilizzate nella configurazione di YunoHost diff --git a/pages/02.administer/55.providers/05.registrar/ovh/autodns/autodns.md b/pages/02.administer/55.providers/05.registrar/ovh/autodns/autodns.md index 588310a2..31f1ad35 100644 --- a/pages/02.administer/55.providers/05.registrar/ovh/autodns/autodns.md +++ b/pages/02.administer/55.providers/05.registrar/ovh/autodns/autodns.md @@ -13,7 +13,7 @@ This page is meant to guide you in obtaining an API key from OVH in order to con ! NB. : **DO NOT share your API tokens with anybody!** A malicious attacker obtaining your tokens could take over your domain, and possibly your server! -1. Go to https://eu.api.ovh.com/createToken/ +1. Go to 2. Fill the form with the required informations as shown below: @@ -23,10 +23,10 @@ This page is meant to guide you in obtaining an API key from OVH in order to con - Script description: for example `YunoHost Auto DNS` - Validity: `Unlimited` - Rights: use the `+` button to add the following lines - - `GET` : `/domain/zone/*` - - `POST` : `/domain/zone/*` - - `PUT` : `/domain/zone/*` - - `DELETE` : `/domain/zone/*` + - `GET` : `/domain/zone/*` + - `POST` : `/domain/zone/*` + - `PUT` : `/domain/zone/*` + - `DELETE` : `/domain/zone/*` ![](image://registrar_api_ovh_1.png?resize=800) diff --git a/pages/02.administer/55.providers/05.registrar/ovh/manualdns/manualdns.fr.md b/pages/02.administer/55.providers/05.registrar/ovh/manualdns/manualdns.fr.md index fd4f390e..8ae0531f 100644 --- a/pages/02.administer/55.providers/05.registrar/ovh/manualdns/manualdns.fr.md +++ b/pages/02.administer/55.providers/05.registrar/ovh/manualdns/manualdns.fr.md @@ -20,14 +20,15 @@ Cliquez sur l'onglet **Zone DNS**, puis sur **Ajouter une entrée** : ![](image://ovh_dns_zone.png?resize=800) Cliquer sur "Modifier en mode textuel", garder les 4 premières lignes : -```bash + +```text $TTL 3600 -@ IN SOA dns104.ovh.net. tech.ovh.net. (2020083101 86400 3600 3600000 60) +@ IN SOA dns104.ovh.net. tech.ovh.net. (2020083101 86400 3600 3600000 60) IN NS dns104.ovh.net. IN NS ns104.ovh.net. ``` -puis effacer tout ce qu'il y a en-dessous, et le remplacer par la configuration donnée par votre serveur, comme indiqué dans la [configuration DNS standard](/dns_config). +puis effacer tout ce qu'il y a en-dessous, et le remplacer par la configuration donnée par votre serveur, comme indiqué dans la [configuration DNS standard](/dns_config). ### IP dynamique @@ -43,7 +44,8 @@ Suivez [ce tutoriel](http://blog.developpez.com/brutus/p6316/ubuntu/configurer_d ddclient annonce à OVH le changement d’IP. OVH va alors changer votre IP. Il faut ajouter dans le fichier de configuration : -* votre identifiant et votre mot de passe DynHost -* votre nom de domaine + +- votre identifiant et votre mot de passe DynHost +- votre nom de domaine Il existe un [guide d'utilisation DynHost fait par OVH](https://docs.ovh.com/fr/fr/web/domains/utilisation-dynhost/). diff --git a/pages/02.administer/55.providers/05.registrar/ovh/manualdns/manualdns.it.md b/pages/02.administer/55.providers/05.registrar/ovh/manualdns/manualdns.it.md index b22ab3c5..1cd95631 100644 --- a/pages/02.administer/55.providers/05.registrar/ovh/manualdns/manualdns.it.md +++ b/pages/02.administer/55.providers/05.registrar/ovh/manualdns/manualdns.it.md @@ -22,14 +22,15 @@ Scegliete la sezione **Zona DNS**, e poi **Aggiungere un record**: Ora dovrete aggiungere la redirezione del DNS così come specificato nella [configurazione standard delle zone del DNS](/dns_config) Cliccate su "Modifica in modalità testo", lasciando invariate le prime 4 righe: -```bash + +```text $TTL 3600 -@ IN SOA dns104.ovh.net. tech.ovh.net. (2020083101 86400 3600 3600000 60) +@ IN SOA dns104.ovh.net. tech.ovh.net. (2020083101 86400 3600 3600000 60) IN NS dns104.ovh.net. IN NS ns104.ovh.net. ``` -cancellate tutto il resto e sostituitelo con la configurazione necessaria per raggiungere il vostro server come illustrato nel paragrafo [questa pagina](/dns config). +cancellate tutto il resto e sostituitelo con la configurazione necessaria per raggiungere il vostro server come illustrato nel paragrafo [questa pagina](/dns config). ### IP dinamico @@ -45,8 +46,8 @@ Seguite [questa guida](http://blog.developpez.com/brutus/p6316/ubuntu/configurer ddclient si occuperà di avvisare OVH quando il vostro IP cambierà e OVH adatterà la sua configurazione. Nel file di configurazione di ddclient dovrete aggiungere: -* il vostro user e la vostra password DynHost -* il nome del vostro dominio + +- il vostro user e la vostra password DynHost +- il nome del vostro dominio Seguite anche questa [guida creata da OVH](https://docs.ovh.com/fr/fr/web/domains/utilisation-dynhost/). - diff --git a/pages/02.administer/55.providers/05.registrar/ovh/manualdns/manualdns.md b/pages/02.administer/55.providers/05.registrar/ovh/manualdns/manualdns.md index 4fcc5cc1..74bf8b9c 100644 --- a/pages/02.administer/55.providers/05.registrar/ovh/manualdns/manualdns.md +++ b/pages/02.administer/55.providers/05.registrar/ovh/manualdns/manualdns.md @@ -22,14 +22,15 @@ Click on the **DNS Zone** tab, then on **Add an entry**: Now you need to add the DNS redirections as specified by the [standard DNS zone configuration](/dns_config) Click on "Change in text format", keep the first four lines: -```bash + +```text $TTL 3600 -@ IN SOA dns104.ovh.net. tech.ovh.net. (2020083101 86400 3600 3600000 60) +@ IN SOA dns104.ovh.net. tech.ovh.net. (2020083101 86400 3600 3600000 60) IN NS dns104.ovh.net. IN NS ns104.ovh.net. ``` -then erase everything below, and replace it with the configuration generated by YunoHost as explained in [this page](/dns_config). +then erase everything below, and replace it with the configuration generated by YunoHost as explained in [this page](/dns_config). ### Dynamic IP @@ -45,7 +46,8 @@ Follow [this tutorial](http://blog.developpez.com/brutus/p6316/ubuntu/configurer ddclient will take care of telling OVH that the IP has changed. Then OVH will update the IP. You need to add in the configuration file: -* your login and password DynHost -* your domain name + +- your login and password DynHost +- your domain name You should also check out [OVH's guide on DynHost](https://www.ovh.co.uk/g2024.hosting_dynhost). diff --git a/pages/02.administer/55.providers/05.registrar/registrar.it.md b/pages/02.administer/55.providers/05.registrar/registrar.it.md index 63c1f51e..a892d136 100644 --- a/pages/02.administer/55.providers/05.registrar/registrar.it.md +++ b/pages/02.administer/55.providers/05.registrar/registrar.it.md @@ -22,7 +22,6 @@ Non sono supportati tutti i registrar. Fino ad ora la comunità ha testato e val Questa lista può aiutarti a scegliere un registrar se conti di acquistare un nome a dominio da usare con YunoHost. - | Registrar | Compatibilità | Facilità per ottenere una chiave API | Howto | | --------- | ------------- | ------------------ | | [Gandi](https://www.gandi.net) | ✔ (testato) | ✔ | [Obtain an API key](/providers/registrar/gandi/autodns) | diff --git a/pages/02.administer/55.providers/05.registrar/registrar.md b/pages/02.administer/55.providers/05.registrar/registrar.md index 33d4c736..62efa294 100644 --- a/pages/02.administer/55.providers/05.registrar/registrar.md +++ b/pages/02.administer/55.providers/05.registrar/registrar.md @@ -22,7 +22,6 @@ Not all registrars are supported. So far, the community tested and validated the The list below can help you to choose a registrar if you plan to buy a domain name to use it with YunoHost. - | Registrar | Compatibility | Easy to obtain an API key | Howto | | --------- | ------------- | ------------------ | | [Gandi](https://www.gandi.net) | ✔ (tested) | ✔ | [Obtain an API key](/providers/registrar/gandi/autodns) | diff --git a/pages/02.administer/55.providers/10.isp/free/isp_free.fr.md b/pages/02.administer/55.providers/10.isp/free/isp_free.fr.md index 35d056a1..7b2bd721 100644 --- a/pages/02.administer/55.providers/10.isp/free/isp_free.fr.md +++ b/pages/02.administer/55.providers/10.isp/free/isp_free.fr.md @@ -11,21 +11,21 @@ routes: *Trouvez la liste d’autres fournisseurs d’accès à Internet **[ici](/isp)**.* -#### Accès à l’administration de la box (v5/v6) +## Accès à l’administration de la box (v5/v6) -##### Freebox ≤ v5 +### Freebox ≤ v5 Rendez-vous sur la [console d'administration du site de free](https://subscribe.free.fr/login/). -##### Freebox v6 (Revolution / Mini4k) +### Freebox v6 (Revolution / Mini4k) Allez à l’adresse : [mafreebox.freebox.fr](http://mafreebox.freebox.fr) puis authentifiez-vous. -#### Ouverture des ports +## Ouverture des ports [Liste des ports à ouvrir](/isp_box_config). -##### Freebox ≤ v5 +### Freebox ≤ v5 Cela se passe dans la section *Ma Freebox / Configurer mon routeur*. Il faut : @@ -34,11 +34,11 @@ Cela se passe dans la section *Ma Freebox / Configurer mon routeur*. Il faut : La présence conjointe de ces deux règles permettent d'accéder à votre serveur de l'extérieur comme de l'intérieur de votre réseau local. -##### Freebox v6 +### Freebox v6 + [Tutoriel d’ouverture des ports sur Freebox](http://www.astuces-pratiques.fr/informatique/ouvrir-un-port-sur-la-freebox-revolution) - -#### Déblocage de l’envoi de courriel +## Déblocage de l’envoi de courriel Pour pouvoir envoyer des mails, le déblocage se fait dans la [partie client](https://subscribe.free.fr/login/). @@ -46,37 +46,43 @@ Depuis le menu Ma freebox allez sur « Blocage SMTP sortant ». Pour pouvoir envoyer des mails, passez le blocage en « inactif ». -#### Fonction NAS de la Freebox +## Fonction NAS de la Freebox Il faut installer le paquet `cifs-utils` + ```bash -$ sudo apt install cifs-utils +sudo apt install cifs-utils ``` Il faut créer un point de montage (ici `/home/monlogin/freebox`) + ```bash -$ mkdir ~/freebox +mkdir ~/freebox ``` On monte le répertoire NAS par défaut avec les droits de lecture / écriture pour tous + ```bash -$ sudo mount -t cifs //mafreebox.freebox.fr/Disque\ dur/ /home/monlogin/freebox -o guest,iocharset=utf8,file_mode=0777,dir_mode=0777 +sudo mount -t cifs //mafreebox.freebox.fr/Disque\ dur/ /home/monlogin/freebox -o guest,iocharset=utf8,file_mode=0777,dir_mode=0777 ``` -##### Automatiser le montage +### Automatiser le montage Une ligne à ajouter à la fin du `/etc/fstab` : -```bash + +```text //mafreebox.freebox.fr/Disque\040dur/ /home/monlogin/freebox cifs _netdev,guest,uid=monlogin,gid=users,iocharset=utf8 0 0 ``` Le `_netdev` signale que c'est un périphérique réseau, afin que le système ne le monte que s'il a accès au réseau. `guest` est le mode d'identification à la Freebox : pour une connexion authentifiée, placez vos identifiants dans un fichier sous la forme -```bash + +```text username=your_user password=your_pass domain=FREEBOX ``` + et remplacez `guest` par `credentials=/path/to/file` (c'est aussi possible de spécifier directement `username=xx,password=xx` dans le fstab, mais déconseillé pour des raisons de sécurité) `uid` et `gid` sont pour les id user et group auxquels appartiendra le répertoire une fois monté. Par défault (sur la Freebox V5 en tout cas), ils se retrouvent avec les uid/gid de 4242. Il est aussi possible de mettre des droits particuliers avec les paramètres `file_mode=0777,dir_mode=0777`. diff --git a/pages/02.administer/55.providers/10.isp/isp.md b/pages/02.administer/55.providers/10.isp/isp.md index 27fc8739..f8a97ce2 100644 --- a/pages/02.administer/55.providers/10.isp/isp.md +++ b/pages/02.administer/55.providers/10.isp/isp.md @@ -24,38 +24,38 @@ Here is a non-comprehensive list of internet service providers by country, which [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="Africa"] - * [Ivory Coast](/isp/country:civ) +- [Ivory Coast](/isp/country:civ) [/ui-tab] [ui-tab title="Asia"] - * [South Korea](/isp/country:kor) +- [South Korea](/isp/country:kor) [/ui-tab] [ui-tab title="Europe"] - * [Belgium (nl)](/isp/country:belnl) - * [Belgium (fr)](/isp/country:belfr) - * [Finland](/isp/country:fin) - * [France](/isp/country:fra) - * [Hungary](/isp/country:hun) - * [Ireland](/isp/country:irl) - * [Sweden](/isp/country:swe) - * [Switzerland](/isp/country:che) - * [UK](/isp/country:gbr) +- [Belgium (nl)](/isp/country:belnl) +- [Belgium (fr)](/isp/country:belfr) +- [Finland](/isp/country:fin) +- [France](/isp/country:fra) +- [Hungary](/isp/country:hun) +- [Ireland](/isp/country:irl) +- [Sweden](/isp/country:swe) +- [Switzerland](/isp/country:che) +- [UK](/isp/country:gbr) [/ui-tab] [ui-tab title="North america"] - * [Canada](/isp/country:can) - * [USA](/isp/country:usa) +- [Canada](/isp/country:can) +- [USA](/isp/country:usa) [/ui-tab] [ui-tab title="Oceania"] [/ui-tab] [ui-tab title="South america"] - * [Brazil](/isp/country:bra) +- [Brazil](/isp/country:bra) [/ui-tab] [/ui-tabs] @@ -77,38 +77,35 @@ A "no" may cause problems for using your server or may require you to make addit **Proximus** ne serait pas ouvert à l’auto-hébergement. L’ouverture des ports serait plus difficile afin d’éviter tout SPAM. Il serait préférable de passer par [Neutrinet](http://neutrinet.be), un des [membres de la Fédération French Data Network](http://www.ffdn.org/fr/membres). - {% elseif country == 'belnl' %} ### België | Service provider | Box/ router | uPnP beschikbaar | [Poort 25 openen mogelijk](/email)| [Hairpinning](http://fr.wikipedia.org/wiki/Hairpinning) | [Reverse DNS](https://en.wikipedia.org/wiki/Reverse_DNS_lookup) | vaste IP | | :---: | :---: | :---: | :---: | :---: | :---: | :---: | -| **Proximus** | BBox2 | ja (geactiveerd) | ja | **nee** | **nee** | **nee** | -| | BBox3 | ja (geactiveerd) | ja | **nee** | **nee** | **nee** | -| **Scarlet** | BBox2 | ja (geactiveerd) | ja | **nee** | **nee** | **nee** | - -**Proximus** zou niet openstaan voor self-hosting. Het openen van de poorten zou moeilijker zijn om SPAM te voorkomen. Het loont de moeite om een vpn te gebruiken. +| **Proximus*- | BBox2 | ja (geactiveerd) | ja | **nee*- | **nee*- | **nee*- | +| | BBox3 | ja (geactiveerd) | ja | **nee*- | **nee*- | **nee*- | +| **Scarlet*- | BBox2 | ja (geactiveerd) | ja | **nee*- | **nee*- | **nee*- | +**Proximus*- zou niet openstaan voor self-hosting. Het openen van de poorten zou moeilijker zijn om SPAM te voorkomen. Het loont de moeite om een vpn te gebruiken. {% elseif country == 'bra' %} ### Brazil + | Service provider | Box (modem/router) | uPnP available | Port 25 openable | [Hairpinning](http://en.wikipedia.org/wiki/Hairpinning) | Customizable reverse DNS | Fix IP | | --- | --- | --- | --- | --- | --- | --- | | Global Village Telecom | Multiple | Yes | No. Only for Fix IP| No | No | Yes, extra charge. | - {% elseif country == 'can' %} ### Canada + | Service provider | Box (modem/router) | uPnP available | Port 25 openable | [Hairpinning](http://en.wikipedia.org/wiki/Hairpinning) | Customizable reverse DNS | Fix IP | | --- | --- | --- | --- | --- | --- | --- | | Telus | Multiple | - | No. Extra charge | - | - | No. Extra charge | | TekSavvy | Multiple | - | Yes | No | - | No. Extra charge | - - {% elseif country == 'fin' %} ### Finland @@ -121,14 +118,14 @@ A "no" may cause problems for using your server or may require you to make addit [^fi-port25]: Regulations in Finland prohibit the use of Port 25 for consumers. - {% elseif country == 'fra' %} ### France Tous les fournisseurs d’accès à Internet [membres de la Fédération French Data Network](http://www.ffdn.org/fr/membres) ont une politique favorable à l’auto-hébergement. -* ✔ : oui -* ✘ : non + +- ✔ : oui +- ✘ : non | Fournisseur d’accès | OVH | [Free](/isp_free) | [SFR](/isp_sfr) | [Orange](/isp_orange) | Bouygues
Télécom | Darty | | :---: | :---: | :---: | :---: | :---: | :---: | :---: | @@ -136,16 +133,15 @@ Tous les fournisseurs d’accès à Internet [membres de la Fédération French | **[UPnP](https://fr.wikipedia.org/wiki/Universal_Plug_and_Play)** | ✔ | ✔ | ✔ | ✔ | ✔ | ✔ | | **[Port 25 ouvrable](/email)**
(fermé par défaut) | ✔ | ✔ | ✔ | ✘ | ✔ | ✔ | | **[Hairpinning](http://fr.wikipedia.org/wiki/Hairpinning)** | ✔ | ✔ | ✔/✘ | ✔ (depuis la Livebox 4) | ✔ | ✔ | -| **[Reverse DNS](https://en.wikipedia.org/wiki/Reverse_DNS_lookup)
personnalisable ** | ✔ | ✔ (sauf IPv6, pas de support, et buggué sur certaines plages d'adresses ipv4) | … | ✘ (XXX.pro.dns-orange.fr disponible sur les abonnements orange pro) | ✘ | ✘ | +| **[Reverse DNS](https://en.wikipedia.org/wiki/Reverse_DNS_lookup)
personnalisable** | ✔ | ✔ (sauf IPv6, pas de support, et buggué sur certaines plages d'adresses ipv4) | … | ✘ (XXX.pro.dns-orange.fr disponible sur les abonnements orange pro) | ✘ | ✘ | | **[IP fixe](/dns_dynamicip)** | ✔ | ✔ | ✔/✘ | ✘ (en option depuis la Livebox 3 et sur les abonnements orange pro) | ✔ | ✔ | | **[IPv6](https://fr.wikipedia.org/wiki/IPv6)** | ✔ | ✔ | ✔ | ✔ | … | … | | **[Non listé sur le DUL](https://en.wikipedia.org/wiki/Dialup_Users_List)** | … | ✘ | … | … | … | … | + Pour une liste plus complète et précise, référez-vous à la très bonne documentation de [wiki.auto-hebergement.fr](http://wiki.auto-hebergement.fr/fournisseurs/fai#d%C3%A9tail_des_fai). **Astuce** : [FDN](http://www.fdn.fr) fournit des [VPN](http://www.fdn.fr/-VPN-.html) permettant de rapatrier une (ou plusieurs sur demande) IPv4 fixe et un /48 en IPv6 et ainsi « nettoyer » votre connexion si vous êtes chez l’un des FAI *limitants* du tableau ci-dessus. - - {% elseif country == 'hun' %} ### Hungary @@ -160,12 +156,11 @@ Pour une liste plus complète et précise, référez-vous à la très bonne docu {% elseif country == 'irl' %} ### Ireland + | Service provider | Box (modem/router) | uPnP available | Port 25 openable | [Hairpinning](http://en.wikipedia.org/wiki/Hairpinning) | Customizable reverse DNS | Fix IP | | --- | --- | --- | --- | --- | --- | --- | | Whizzy Internet | Multiple | Yes | Yes| Yes | Yes | Yes | - - {% elseif country == 'civ' %} ### Côte d'Ivoire @@ -188,8 +183,6 @@ Pour une liste plus complète et précise, référez-vous à la très bonne docu Ownit reserves port 3 and 4 of their router to TV. With a simple call to their hotline, explaining that you want to selfhost, they can reassign one of the ports to be in bridge mode. It means that your server will have its own public fixed IP address, in addition to the modem's. - - {% elseif country == 'che' %} ### Switzerland @@ -202,8 +195,6 @@ Most of non business IP provided by ISP are blacklisted. | Swisscom | Multiple | No | Yes | No | No | No | | VTX | Multiple | No | Yes | No | - | - | - - {% elseif country == 'kor' %} ### South Korea @@ -214,10 +205,10 @@ Most of non business IP provided by ISP are blacklisted. | KT(SkyLife, Qook&Show) | Multiple | Yes | Yes | No | - | Partial | | SKT (SK Broadband) | Multiple | Yes | Yes | No | - | Partial | - {% elseif country == 'gbr' %} ### UK + | Service provider | Box (modem/router) | uPnP available | Port 25 openable | [Hairpinning](http://en.wikipedia.org/wiki/Hairpinning) | Customizable reverse DNS | Fix IP | | --- | --- | --- | --- | --- | --- | --- | | BT Internet | Yes | - | Yes| - | - | No | @@ -228,6 +219,7 @@ Most of non business IP provided by ISP are blacklisted. {% elseif country == 'usa' %} ### USA + | Service provider | Box (modem/router) | uPnP available | Port 25 openable | [Hairpinning](http://en.wikipedia.org/wiki/Hairpinning) | Customizable reverse DNS | Fix IP | | --- | --- | --- | --- | --- | --- | --- | | Cox | Multiple | Yes | No. Only for business class customer. | No | No | Yes, as a business class customer | @@ -236,6 +228,4 @@ Most of non business IP provided by ISP are blacklisted. | AT&T| Multiple | Yes | No. Only for business class customer. | unknown. | unknown. | unknown. | | Xfinity (Comcast)| Multiple | Yes | No. Only for business class customer. | unknown. | unknown. | Yes, as a business class customer| - {% endif %} - diff --git a/pages/02.administer/55.providers/10.isp/orange/isp_orange.fr.md b/pages/02.administer/55.providers/10.isp/orange/isp_orange.fr.md index e308d26f..de1a3654 100644 --- a/pages/02.administer/55.providers/10.isp/orange/isp_orange.fr.md +++ b/pages/02.administer/55.providers/10.isp/orange/isp_orange.fr.md @@ -11,7 +11,7 @@ routes: *Trouvez la liste d’autres fournisseurs d’accès à Internet **[ici](/isp)**.* -#### Le courrier électronique +## Le courrier électronique La box d’Orange bloque le port 25 pour limiter l’envoi de spam. @@ -28,7 +28,7 @@ sudo nano /etc/postfix/main.cf puis, rajouter à la ligne le relai SMTP d’Orange : -```bash +```text relayhost = smtp.orange.fr ``` @@ -38,7 +38,7 @@ redémarrez Postfix : sudo service postfix restart ``` -##### Problèmes +### Problèmes Si vous avez une erreur "Authentification requise", la solution est la suivante : **[source](http://viruslocker.free.fr/?page_id=1749)**. @@ -47,9 +47,10 @@ Si vous avez une erreur "Authentification requise", la solution est la suivante ```bash sudo nano /etc/postfix/main.cf ``` + puis, rajouter à la ligne : -```bash +```text smtp_sasl_password_maps = hash:/etc/postfix/sasl/mdp_fai.conf smtp_sasl_auth_enable = yes smtp_sasl_security_options = noanonymous @@ -64,10 +65,11 @@ sudo nano /etc/postfix/sasl/mdp_fai.conf ajouter -```bash +```text # mdp_fai.conf [smtp.orange.fr]:25 adresseemail@chez.orange:son-mot-de-passe ``` + avec votre mot de passe du compte d'orange. Intégrer le mot de passe à Postfix : @@ -92,7 +94,8 @@ Si ils ne sont pas présents, installez-les : apt install libsasl2-modules sasl2-bin ``` -Il est possible que postfix ne prenne pas en compte tout de suite vos modifications. Pour le forcer à le faire, exécutez +Il est possible que postfix ne prenne pas en compte tout de suite vos modifications. Pour le forcer à le faire, exécutez + ```bash systemctl restart postfix ``` diff --git a/pages/02.administer/55.providers/10.isp/sfr/isp_sfr.fr.md b/pages/02.administer/55.providers/10.isp/sfr/isp_sfr.fr.md index 80374876..14ea8ea5 100644 --- a/pages/02.administer/55.providers/10.isp/sfr/isp_sfr.fr.md +++ b/pages/02.administer/55.providers/10.isp/sfr/isp_sfr.fr.md @@ -11,13 +11,15 @@ routes: *Trouvez la liste d’autres fournisseurs d’accès à Internet **[ici](/isp)**.* -#### Accès à l’administration de la box -* Allez à cette adresse : http://192.168.1.1. -* Authentifiez-vous, soit en appuyant sur le bouton de la box pendant 5 secondes soit avec les identifiants d’administration. +## Accès à l’administration de la box + +- Allez à cette adresse : +- Authentifiez-vous, soit en appuyant sur le bouton de la box pendant 5 secondes soit avec les identifiants d’administration. ![](image://sfr-authentification.png?resize=900) -#### Courrier électronique +## Courrier électronique + Pour pouvoir envoyer des mails, il faut désactiver le filtrage. ![](image://sfr-filtrage.png?resize=600) diff --git a/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.de.md b/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.de.md index 4fe05ccd..1afffb70 100644 --- a/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.de.md +++ b/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.de.md @@ -9,24 +9,28 @@ routes: Es ist unüblich, zu Hause einen Server einzurichten, und die meisten Internetanschlüsse, die Privatpersonen zur Verfügung stehen, sind für diesen Zweck ungeeignet. Ein netzneutrales VPN, das eine feste IPv4-Adresse und IPv6-Adressen bereitstellt, kann helfen, einige der Einschränkungen oder Schwierigkeiten zu überwinden. -! Vorsicht: nicht alle bestehenden VPN-Anbieter erfüllen diese Bedingungen, vergewissern Sie sich, dass der von Ihnen gewählte Anbieter sie erfüllt. +! **Vorsicht**: nicht alle bestehenden VPN-Anbieter erfüllen diese Bedingungen, vergewissern Sie sich, dass der von Ihnen gewählte Anbieter sie erfüllt. ## Vorteile ### Plug & Play + Indem Sie ein VPN auf Ihrem Server einrichten, können Sie ihn für den Rest des Internets zugänglich machen, ohne die Konfiguration des Routers, an den Sie ihn anschließen, ändern zu müssen. Dies kann sehr praktisch sein, wenn Sie in den Urlaub fahren, umziehen oder einen Internetausfall haben, da Sie das Gerät einfach an eine Person Ihres Vertrauens anschließen können, ohne den Router der Person konfigurieren zu müssen, die Ihnen hilft. Außerdem ersparen Sie sich die Mühe, die Ports Ihres Routers zu öffnen und das Hairpinning zu umgehen. ### Keine Mikro-DNS-Ausfälle + Wenn Ihr Internetanschluss keine feste öffentliche IP hat, müssen Sie einen dynamischen Domänennamen (Dynamic DNS) einrichten. Diese Lösung mag akzeptabel sein, aber das DNS wird nur in regelmäßigen Abständen aktualisiert (alle zwei Minuten, wenn es sich um einen `noho.st` oder `nohost.me` Domänennamen handelt). Es besteht also die Möglichkeit, dass dies gelegentlich zu Darstellungsfehlern im Browser führt oder dass sogar eine andere Website angezeigt wird (die Risiken sind jedoch geringer, da die Praxis des Self-Hosting nicht weit verbreitet ist). -Mit einem neutralen VPN wird dieses Problem umgangen, da das VPN mit einer virtuellen Internetverbindung verglichen werden kann, die eine eigene feste IPv4-Adresse hat, so dass der Domänenname nicht aktualisiert werden muss. +Mit einem neutralen VPN wird dieses Problem umgangen, da das VPN mit einer virtuellen Internetverbindung verglichen werden kann, die eine eigene feste IPv4-Adresse hat, so dass der Domänenname nicht aktualisiert werden muss. ### Der Fall der E-Mail + E-Mail ist eines der komplexesten Protokolle, die man selbst hosten kann, und in der Regel ist es das, was ein Benutzer zuletzt selbst hostet. In der Tat kann es leicht passieren, dass vom Server gesendete E-Mails von den SMTP-Servern der Empfänger abgelehnt werden. Um dies zu vermeiden, müssen Sie u. a. : + - den umgekehrten DNS der Internetverbindung des Servers (oder VPN) konfigurieren - eine feste IPv4 - dass diese IPv4 aus allen Blacklists entfernt werden kann (insbesondere darf die IP nicht in der DUL enthalten sein) @@ -37,15 +41,20 @@ Leider beachtet keiner der gängigsten französischen Internetanbieter alle dies Um dies zu vermeiden, kann die Verwendung eines VPN, das diese Punkte berücksichtigt, eine Alternative darstellen. ### Vertrauen + Wenn Sie nicht möchten, dass der Inhalt der Kommunikation Ihres Servers von Geräten im Netz Ihres Internetanbieters ausspioniert wird, können Sie ein VPN verwenden, um Ihre Kommunikation zu verschlüsseln und Ihr Vertrauen in einen VPN-Anbieter zu setzen. Zur Erinnerung: Seit 2015 hat die Regierung offiziell Blackboxes bei großen Netzbetreibern installiert, um die gesamte digitale Kommunikation in Frankreich abzuhören und so die wissenschaftlichen, wirtschaftlichen und industriellen Interessen Frankreichs zu schützen. ## Benachteiligung + ### Kosten + Ein neutrales VPN ist mit Kosten verbunden, da der Betreiber, der es bereitstellt, einen Server betreiben und Bandbreite nutzen muss. Die Preise für die assoziativen VPNs des FFDN liegen bei etwa 6 € pro Monat. ### Packet Routing + Wenn Sie ein VPN auf Ihrem Server einrichten, wird die Übertragung einer Datei von einem Computer im lokalen Netzwerk zum Server, der das VPN nutzt, über das Ende des VPN, d.h. über den Server des VPN-Anbieters, laufen, wenn Sie keine besondere Konfiguration einrichten. Um dies zu vermeiden, gibt es zwei Lösungen : + - Wenn Sie den Server in einen Router umwandeln und die Heimgeräte daran anschließen, profitieren auch diese Geräte von der VPN-Vertraulichkeit. - Verwenden Sie den YunoHost-Server als DNS-Resolver, wenn Sie zu Hause sind, um die Domänennamen des Servers auf die lokale IP und nicht auf die öffentliche IP umzuleiten. Dies kann entweder auf jedem Gerät oder auf dem Router erfolgen (sofern letzterer dies zulässt). diff --git a/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.es.md b/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.es.md index d6cdd1c1..adda66ee 100644 --- a/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.es.md +++ b/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.es.md @@ -9,7 +9,7 @@ routes: Dado que la instalación de un servidor en casa es una práctica poco habitual, la mayoría de las conexiones a Internet que se proporcionan a los particulares no son adecuadas para este fin. Una VPN de red neutra que proporcione una dirección IPv4 fija y direcciones IPv6 puede ayudar a superar algunas limitaciones o dificultades. -! Advertencia: no todos los proveedores de VPN existentes cumplen estos requisitos, asegúrese de que el que elija los cumpla. +! **Advertencia**: no todos los proveedores de VPN existentes cumplen estos requisitos, asegúrese de que el que elija los cumpla. ## Ventajas @@ -31,10 +31,10 @@ El correo es uno de los protocolos más complejos de autoalojar, normalmente es Para evitarlo, necesitas, entre otras cosas: - -configurar el DNS inverso de la conexión a Internet del servidor (o VPN) - -una IPv4 fija - -que esta IPv4 sea eliminada de todas las listas negras (en particular, la IP no debe estar en el DUL) - -poder abrir el puerto 25 (así como otros puertos SMTP) +- configurar el DNS inverso de la conexión a Internet del servidor (o VPN) +- una IPv4 fija +- que esta IPv4 sea eliminada de todas las listas negras (en particular, la IP no debe estar en el DUL) +- poder abrir el puerto 25 (así como otros puertos SMTP) Desgraciadamente, ninguno de los ISP franceses más habituales respeta todos estos puntos. @@ -45,7 +45,9 @@ Para superar esto, el uso de una VPN que respete estos puntos puede ser una alte Por último, si no quiere que el contenido de las comunicaciones de su servidor sea espiable por los equipos presentes en la red de su proveedor de servicios de Internet, puede utilizar una VPN para cifrar sus comunicaciones y deportar su confianza a un proveedor de VPN. A modo de recordatorio, desde 2015, el gobierno despliega oficialmente cajas negras en los principales operadores de red cuyo objetivo es espiar todas las comunicaciones digitales francesas para, entre otras cosas, preservar los intereses científicos, económicos e industriales de Francia. ## Desvenjajas + ### Coste + Una VPN neutra tiene un coste, ya que el operador que la proporciona debe gestionar un servidor y utilizar el ancho de banda. Los precios de las VPN asociadas a FFDN rondan los 6 euros al mes. ### Enrutamiento de paquetes @@ -54,5 +56,5 @@ Cuando se establece una VPN en el servidor, si no se establece una configuració Para superar este punto, hay dos soluciones: - -transformando su servidor en un router y conectando su equipo doméstico a él, este equipo se beneficiará también de la confidencialidad de la VPN. - -utilizar el servidor de YunoHost como resolvedor de DNS cuando estés en casa, para redirigir los nombres de dominio del servidor a la ip local en lugar de la ip pública. Esta operación puede realizarse en cada dispositivo o en el router (si éste lo permite). +- transformando su servidor en un router y conectando su equipo doméstico a él, este equipo se beneficiará también de la confidencialidad de la VPN. +- utilizar el servidor de YunoHost como resolvedor de DNS cuando estés en casa, para redirigir los nombres de dominio del servidor a la ip local en lugar de la ip pública. Esta operación puede realizarse en cada dispositivo o en el router (si éste lo permite). diff --git a/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.fr.md b/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.fr.md index ae8665e3..f903b026 100644 --- a/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.fr.md +++ b/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.fr.md @@ -9,24 +9,28 @@ routes: L'installation d'un serveur chez soi étant une pratique peu courante, la plupart des connexions Internet fournies aux particuliers sont inadaptées à sa mise en pratique. Un VPN respectant la neutralité du net et fournissant une adresse IPv4 fixe et des adresses IPv6 peut permettre de contourner certaines limitations ou certaines difficultés. -! Attention : tous les fournisseurs VPN existants ne remplissent pas ces conditions, assurez-vous bien que celui que vous choisissez les remplit. +! **Attention** : tous les fournisseurs VPN existants ne remplissent pas ces conditions, assurez-vous bien que celui que vous choisissez les remplit. ## Avantages ### Plug & Play + En configurant un VPN sur votre serveur, vous serez en mesure de le rendre accessible au reste d'Internet sans avoir à modifier la configuration du routeur auquel vous le branchez. Ce point peut être vraiment pratique si vous partez en vacances, que vous déménagez ou si vous avez une coupure d'Internet, car vous serez en mesure de le brancher facilement chez une personne de confiance sans avoir besoin de configurer le routeur de la personne qui vous aide. De la même façon, vous vous économisez l'ouverture des ports de votre routeur ainsi que le contournement du hairpinning. ### Pas de micro-coupure DNS + Si votre connexion Internet n'a pas d'IP publique fixe, vous serez obligé de mettre en place un nom de domaine dynamique (Dynamique DNS). Cette solution peut être acceptable, mais la mise à jour du DNS ne se fera qu'à intervalle régulier (Toutes les deux minutes si c'est un nom de domaine en `noho.st` ou `nohost.me`). Il y a donc une chance que cela provoque de temps en temps des erreurs d'affichage dans le navigateur, voir même qu'un autre site s'affiche (les risques sont toutefois réduits car la pratique de l'auto-hébergement n'est pas répandue). -Avec un VPN neutre, ce problème est contourné car le VPN peut être comparé à une connexion Internet Virtuelle, qui a sa propre adresse IPv4 fixe, dès lors plus besoin de mettre à jour le nom de domaine. +Avec un VPN neutre, ce problème est contourné car le VPN peut être comparé à une connexion Internet Virtuelle, qui a sa propre adresse IPv4 fixe, dès lors plus besoin de mettre à jour le nom de domaine. ### Le cas du mail + Le mail est un des protocoles les plus complexes à auto-héberger, en général c'est ce qu'un utilisateur auto-héberge en dernier. En effet, il est très facile de se retrouver dans une situation où les emails envoyés par le serveur sont refusés par les serveurs SMTP destinataires. Pour éviter ça il faut entre autre : + - configurer le reverse DNS de la connexion Internet (ou du VPN) du serveur - une IPv4 fixe - que cette IPv4 soit enlevable de toutes les listes noires (notamment l'IP ne doit pas être sur le DUL) @@ -37,15 +41,20 @@ Malheureusement, aucun des FAI français les plus courants ne respecte la totali Pour pallier cela, l'usage d'un VPN respectant ces points peut être une alternative. ### Confiance + Enfin, si vous ne souhaitez pas que le contenu des communications de votre serveur soit espionnable par des équipements présents sur le réseau de votre fournisseur d'accès à Internet, vous pouvez utiliser un VPN pour chiffrer vos communications et déporter votre confiance sur un fournisseur de VPN. Rappel, depuis 2015, le gouvernement déploie officiellement des boîtes noires chez les gros opérateurs réseau qui ont pour objectif de mettre sur écoute l'ensemble des communications numériques françaises entre autre pour préserver les intérêts scientifiques, économiques et industrielles de la France. ## Inconvénient + ### Coût + Un VPN neutre a un coût puisque l'opérateur qui le fournit doit faire fonctionner un serveur et utiliser de la bande passante. Les prix des VPN associatifs de la FFDN sont autour de 6 € par mois. ### Trajet des paquets + Lorsque l'on met en place un VPN sur son serveur, si on ne met pas en place de configuration particulière, le transfert d'un fichier d'un ordinateur du réseau local vers le serveur utilisant le VPN, passera par le bout du VPN c'est-à-dire par le serveur du fournisseur de VPN. Pour pallier ce point, il y a deux solutions : + - transformer son serveur en routeur et connecter les équipements de la maison à ce dernier, ces équipements bénéficieront alors de la confidentialité du VPN également. - utiliser le serveur YunoHost comme résolveur DNS lorsque l'on est chez soi, de façon à rediriger les noms de domaines du serveur l'IP locale plutôt que l'IP publique. Cette opération peut se faire soit sur chaque équipement, soit sur le routeur (si ce dernier le permet). diff --git a/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.it.md b/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.it.md index 05fafd1b..66ceadff 100644 --- a/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.it.md +++ b/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.it.md @@ -9,24 +9,28 @@ routes: Poiché installare un server a casa è una pratica abbastanza poco comune molte connessioni Internet casalinghe non sono realmente utilizzabili per questo scopo. Una VPN rispettosa della neutralità di rete (net neutrality) con un indirizzo IPv4 fisso e indirizzi IPv6 può aiutare a superare alcune limitazioni e difficoltà. -! Attenzione: non tutti i provider di VPN rispettano queste condizioni, controllate che quello scelto le rispetti. +! **Attenzione**: non tutti i provider di VPN rispettano queste condizioni, controllate che quello scelto le rispetti. ## Vantaggi ### Plug & Play + Usare una VPN per il vostro server vi permetterà di renderlo accessibile a tutta Internet senza dover fare alcun cambiamento al router al quale lo connettete. Questa cosa risulta estremamente comoda se state andando in vacanza, se state traslocando o nel caso di una disconnessione da Internet poiché potrete facilmente riconnettere il server da qualcuno di fiducia senza necessità di riconfigurare il router della persone che vi sta aiutando. Allo stesso modo vi risparmierete il problema di aprire le porte del vostro router per bypassare l'hairpinning. ### Nessun micro distacco del DNS + Se la vostra connessione ad Internet non ha un IP pubblico fisso dovrete utilizzare un sistema di nome a dominio dinamico (Dynamic DNS). La soluzione è accettabile però il DNS verrà aggiornato ad intervalli regolari (ad esempio con i domini registrati su `noho.st` e `nohost.me` ogni due minuti). Di conseguenza è possibile che i browser possano mostrare degli errori di tanto in tanto o che addirittura venga mostrato un altro sito (anche se questa possibilità è abbastanza remota in quanto il self-hosting non è ancora molto diffuso). Con una VPN neutrale il problema è bypassato in quanto la VPN può essere assimilata ad una connessione ad Internet virtuale con un indirizzo IPv4 fisso e quindi il dominio non deve essere aggiornato. ### La questione della posta elettronica + La posta elettronica è uno dei protocolli più complessi per il self-hosting e di conseguenza quello che viene impostato per ultimo. E difatti è molto facile trovarsi nella situazione in cui le email inviate dal server vengono rifiutate dai server SMTP di destinazione. Per evitare questa situazione dovete: + - configurare il reverse DNS della connessione ad Internet del server (o della VPN) - un Ipv4 statico - fare in modo che questo indirizzo IPv4 sia eliminabile da tutte le blacklist (in particolare l'IP non deve essere nel DUL) @@ -37,15 +41,20 @@ Purtroppo quasi nessun IPS francese diffuso (e neanche italiano) permette di ris Di conseguenza usare una VPN che rispetta queste richieste è una valida alternativa. ### Fiducia + Infine, se non volete che la comunicazioni del vostro server possano essere intercettate dall'infrastruttura di rete del vostro ISP potete usare la VPN per cifrare le vostre comunicazioni e spostare la fiducia al provider della VPN. Ricordate che fin dal 2015 il governo (francese) installa ufficialmente delle `black box` nelle sedi dei grandi operatori di rete con l'obbiettivo di intercettare tutte le comunicazioni digitali francesi per controllare gli interessi scientifici, economici e industriali della Francia (non è chiaro cosa succede in Italia). ## Svantaggi + ### Costi + Una VPN neutrale presenta dei costi aggiuntivi poiché l'operatore che a fornisce deve gestire un server e consumare banda. Il costo di una VPN di un associato a FFDN (consorzio francese di operatori di rete sociali) si aggira intorno ai 6€ al mese. ### Packet path + Usando una VPN su vostro server, a meno di particolari configurazioni, la strada percorsa dai file da un computer sulla vostra rete locale al server della VPN passerà dal nodo terminale della VPN, cioè dal server del provider. Ci sono due possibili soluzioni a questo problema: + - trasformare il server in un router e connettere attraverso questo gli apparecchi casalinghi che così anche questi godranno della protezione della VPN. - usare il server YunoHost in un resolver del DNS a casa di modo da redirigere i nomi a dominio locali ad indirizzi locali invece che quelli pubblici. Questa Questa operazione deve essere compiuta per tutti gli apparecchi oppure sul router (se lo permette). diff --git a/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.md b/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.md index 0f8b3f52..9d2afb94 100644 --- a/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.md +++ b/pages/02.administer/55.providers/15.vpn/01.vpn/vpn_advantage.md @@ -9,24 +9,28 @@ routes: Since setting up a server at home is an uncommon practice, most Internet connections provided to individuals are unsuitable for this purpose. A net neutral VPN providing a fixed IPv4 address and IPv6 addresses can help to circumvent some limitations or difficulties. -! Beware: not all existing VPN providers meet these conditions, make sure the one you choose meets them. +! **Beware**: not all existing VPN providers meet these conditions, make sure the one you choose meets them. ## Advantages ### Plug & Play + By setting up a VPN on your server, you'll be able to make it accessible to the rest of the Internet without having to change the configuration of the router you connect it to. This can be really handy if you are going on vacation, moving or have an Internet disconnection, as you will be able to easily connect it to someone you trust without having to configure the router of the person who is helping you. In the same way, you save yourself the trouble of opening your router's ports and bypassing hairpinning. ### No micro DNS outages + If your Internet connection does not have a fixed public IP, you will be forced to set up a dynamic domain name (Dynamic DNS). This solution may be acceptable, but the DNS will only be updated at regular intervals (every two minutes if it is a `noho.st` or `nohost.me` domain name). So there is a chance that this will cause some display errors in the browser from time to time, or even that another site will be displayed (the risks are however reduced because the practice of self-hosting is not widespread). -With a neutral VPN, this problem is circumvented because the VPN can be compared to a Virtual Internet connection, which has its own fixed IPv4 address, so no need to update the domain name. +With a neutral VPN, this problem is circumvented because the VPN can be compared to a Virtual Internet connection, which has its own fixed IPv4 address, so no need to update the domain name. ### The case of email + Email is one of the most complex protocols to self-host, usually it is what a user self-hosts last. Indeed, it is very easy to find yourself in a situation where emails sent by the server are refused by the recipient SMTP servers. To avoid this you need to: + - configure the reverse DNS of the server's Internet connection (or VPN) - a fixed IPv4 - that this IPv4 is removable from all blacklists (notably the IP must not be on the DUL) @@ -37,15 +41,20 @@ Unfortunately, none of the most common French ISPs respect all these points. To overcome this, the use of a VPN respecting these points can be an alternative. ### Trust + Finally, if you do not want the content of your server's communications to be spied on by equipment present on your ISP's network, you can use a VPN to encrypt your communications and deport your trust to a VPN provider. Remember, since 2015, the government officially deploys black boxes at the large network operators whose objective is to tap all French digital communications to preserve the scientific, economic and industrial interests of France. ## Disadvantage + ### Cost + A neutral VPN has a cost since the operator who provides it must run a server and use bandwidth. The prices of the FFDN's associative VPNs are around 6 € per month. ### Packet path + When you set up a VPN on your server, if you don't set up any particular configuration, the transfer of a file from a computer on the local network to the server using the VPN, will go through the end of the VPN i.e. through the server of the VPN provider. To solve this problem, there are two solutions: + - transform the server into a router and connect the home equipments to it, these equipments will then benefit from the VPN confidentiality too. - use the YunoHost server as a DNS resolver when you are at home, in order to redirect the server's domain names to the local IP rather than the public IP. This operation can be done either on each equipment or on the router (if the latter allows it). diff --git a/pages/02.administer/55.providers/15.vpn/vpn.md b/pages/02.administer/55.providers/15.vpn/vpn.md index 334c7b6b..e453896c 100644 --- a/pages/02.administer/55.providers/15.vpn/vpn.md +++ b/pages/02.administer/55.providers/15.vpn/vpn.md @@ -14,15 +14,14 @@ routes: Since setting up a server at home is an uncommon practice, most Internet connections provided to individuals are unsuitable for this purpose especially if you desire to send mail. A net neutral VPN providing a dedicated fixed public IPv4 address and IPv6 addresses [can help to circumvent some limitations or difficulties](/vpn_advantage). - Below, you can find a list of providers compatible for self-hosting and especially those providing .cube format for VPNClient apps and those providing [internetcube](https://internetcu.be). !!! By **compatible for self-hosting** we means VPN offers with at least: -!!! * a fixed dedicated public IPv4 -!!! * port forwarding or opened features -!!! * net neutrality: no traffic analysis, no user data resale, no alteration of traffic (without legal obligations)... +!!! - a fixed dedicated public IPv4 +!!! - port forwarding or opened features +!!! - net neutrality: no traffic analysis, no user data resale, no alteration of traffic (without legal obligations)... ------------------- +--- ## English speaking-site @@ -32,10 +31,10 @@ Below, you can find a list of providers compatible for self-hosting and especial ¹ [Pay what you want](https://en.wikipedia.org/wiki/Pay_what_you_want) !!! If you try an other VPN provider that include **public dedicated ipv4 and port forwarding**, feel free to contribute to this documentation. We need people to test specific offers of those commercial providers: -!!! * [VPN area](https://vpnarea.com/front/home/dedicated-ip) ✘ does not allow forwarding port 80. Running a webserver is against their TOS. -!!! * [Trust zone](https://trust.zone/fr/order?p=25) -!!! * [PureVPN](https://www.purevpn.fr/ip-vpn-dedie) -!!! * [RapidVPN](https://www.rapidvpn.com/vpn) +!!! - [VPN area](https://vpnarea.com/front/home/dedicated-ip) ✘ does not allow forwarding port 80. Running a webserver is against their TOS. +!!! - [Trust zone](https://trust.zone/fr/order?p=25) +!!! - [PureVPN](https://www.purevpn.fr/ip-vpn-dedie) +!!! - [RapidVPN](https://www.rapidvpn.com/vpn) ## French speaking-site diff --git a/pages/02.administer/55.providers/20.server/server.md b/pages/02.administer/55.providers/20.server/server.md index 0c688dc5..a4cd2396 100644 --- a/pages/02.administer/55.providers/20.server/server.md +++ b/pages/02.administer/55.providers/20.server/server.md @@ -14,15 +14,13 @@ routes: ## Pre-installed YunoHost Offers - * [Alsace Réseau Neutre](https://arn-fai.net) (VPS) FFDN CHATONS - - * [Association ECOWAN](https://ecowan.fr) (VPS) - - * [Scaleway Dedibox](https://www.scaleway.com/en/dedibox/operating-systems/) (dedicated server) +- [Alsace Réseau Neutre](https://arn-fai.net) (VPS) FFDN CHATONS +- [Association ECOWAN](https://ecowan.fr) (VPS) +- [Scaleway Dedibox](https://www.scaleway.com/en/dedibox/operating-systems/) (dedicated server) ## YunoHost IT outsourcing - * [ReflexLibre](https://reflexlibre.net) (France only) CHATONS +- [ReflexLibre](https://reflexlibre.net) (France only) CHATONS - - - - + + + + - diff --git a/pages/02.administer/admindoc.es.md b/pages/02.administer/admindoc.es.md index 7a8fd7fd..67a1364b 100644 --- a/pages/02.administer/admindoc.es.md +++ b/pages/02.administer/admindoc.es.md @@ -9,4 +9,4 @@ routes: ### Administrar -# Descubre el auto-hospedaje, cómo instalar y usar tu YunoHost \ No newline at end of file +# Descubre el auto-hospedaje, cómo instalar y usar tu YunoHost diff --git a/pages/02.administer/admindoc.it.md b/pages/02.administer/admindoc.it.md index 0b5090d9..ae434ffd 100644 --- a/pages/02.administer/admindoc.it.md +++ b/pages/02.administer/admindoc.it.md @@ -1,7 +1,5 @@ - - - --- + title: Guida di amministrazione template: chapter taxonomy: diff --git a/pages/03.user_guide/05.emailclients/email_configure_client.de.md b/pages/03.user_guide/05.emailclients/email_configure_client.de.md index 27d221a7..65b66997 100644 --- a/pages/03.user_guide/05.emailclients/email_configure_client.de.md +++ b/pages/03.user_guide/05.emailclients/email_configure_client.de.md @@ -16,25 +16,28 @@ Moderne Mail-Clients sollten in der Lage sein, sich automatisch zu konfigurieren Hier sind die Elemente, die Sie eingeben sollten, um Ihren Mail-Client manuell zu konfigurieren (`domain.tld` bezieht sich auf das, was nach dem @ in Ihrer E-Mail Adresse steht, und `Benutzername` auf das, was vor dem @ steht). | Protokoll | Port | Verschlüsselung | Authentifizierung | Benutzername | -| :--: | :-: | :--: | :--: | :--: | +| :--: | :-: | :--: | :--: | :--: | | IMAP | 993 | SSL/TLS | Normales Passwort | `Benutzername` (ohne die `@domain.tld`) | | SMTP | 587 | STARTTLS | Normales Passwort | `Benutzername` (ohne die `@domain.tld`) | ### Client für Client + [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="Mozilla Thunderbird"] -##### ![](image://thunderbird.png?resize=50&classes=inline) Mozilla Thunderbird konfigurieren (auf einem Desktop-Computer) + +#### ![](image://thunderbird.png?resize=50&classes=inline) Mozilla Thunderbird konfigurieren (auf einem Desktop-Computer) Um ein neues Konto in Thunderbird manuell zu konfigurieren, fügen Sie die Kontoinformationen hinzu und wählen dann Port 993 mit SSL/TLS für IMAP und Port 587 mit STARTTLS für SMTP. Wählen Sie anschließend "Normales Passwort" für die Authentifizierung und klicken Sie auf "Erweiterte Konfiguration". Möglicherweise müssen Sie die Zertifikatsausnahmen für das Abrufen von E-Mails und nach dem Senden Ihrer ersten E-Mail akzeptieren. Vergessen Sie nicht, den Punkt vor dem Domainnamen zu entfernen. ![](image://thunderbird_config_1.png?resize=900) ![](image://thunderbird_config_2.png?resize=900) -* [Alias-Mails verwalten](https://support.mozilla.org/de/kb/configuring-email-aliases) +- [Alias-Mails verwalten](https://support.mozilla.org/de/kb/configuring-email-aliases) [/ui-tab] [ui-tab title="K-9 Mail"] -##### ![](image://k9mail.png?resize=50&classes=inline) K-9 Mail konfigurieren (auf Android) + +#### ![](image://k9mail.png?resize=50&classes=inline) K-9 Mail konfigurieren (auf Android) Führen Sie die folgenden Schritte aus. (Wie bei Thunderbird müssen Sie möglicherweise an einigen Stellen Zertifikate akzeptieren) @@ -43,14 +46,14 @@ Führen Sie die folgenden Schritte aus. (Wie bei Thunderbird müssen Sie möglic ![](image://k9mail_config_3.png?resize=280&classes=inline) ![](image://k9mail_config_4.png?resize=280&classes=inline) - [/ui-tab] [ui-tab title="Dekko"] -##### ![](image://dekko-app.png?resize=50&classes=inline) Dekko konfigurieren (auf Ubuntu Touch) + +#### ![](image://dekko-app.png?resize=50&classes=inline) Dekko konfigurieren (auf Ubuntu Touch) Beim ersten Mal können Sie einfach "Konto hinzufügen" wählen. Wenn Sie bereits ein Konto eingerichtet haben, tippen Sie auf das Hamburger-Menü, dann auf das Zahnrad, wählen Sie Mail, Konten und drücken Sie das '+'-Symbol. -Dann wählen Sie IMAP. Füllen Sie die Felder aus und drücken Sie auf Weiter. Jetzt sucht Dekko nach der Konfiguration. Überprüfen Sie, ob alle Felder korrekt ausgefüllt sind. Vergewissern Sie sich, dass Sie Ihren yunohost-Benutzernamen und NICHT Ihre Mailadresse eingeben und wählen Sie "Nicht vertrauenswürdige Zertifikate zulassen". Tun Sie dies für IMAP und SMTP und drücken Sie auf Weiter. Dekko wird nun das Konto synchronisieren, danach sind Sie fertig. Herzlichen Glückwunsch! +Dann wählen Sie IMAP. Füllen Sie die Felder aus und drücken Sie auf Weiter. Jetzt sucht Dekko nach der Konfiguration. Überprüfen Sie, ob alle Felder korrekt ausgefüllt sind. Vergewissern Sie sich, dass Sie Ihren YunoHost-Benutzernamen und NICHT Ihre Mailadresse eingeben und wählen Sie "Nicht vertrauenswürdige Zertifikate zulassen". Tun Sie dies für IMAP und SMTP und drücken Sie auf Weiter. Dekko wird nun das Konto synchronisieren, danach sind Sie fertig. Herzlichen Glückwunsch! ![](image://dekko_config_1.png?resize=280&classes=inline) ![](image://dekko_config_2.png?resize=280&classes=inline) diff --git a/pages/03.user_guide/05.emailclients/email_configure_client.es.md b/pages/03.user_guide/05.emailclients/email_configure_client.es.md index 871841d6..48644c0b 100644 --- a/pages/03.user_guide/05.emailclients/email_configure_client.es.md +++ b/pages/03.user_guide/05.emailclients/email_configure_client.es.md @@ -19,7 +19,6 @@ A continuación puedes encontrar los elementos a configurar en el cliente de cor | IMAP | 993 | SSL/TLS | Normal password | `nombre_de_usuario` (sin `@domain.tld`) | | SMTP | 587 | STARTTLS | Normal password | `nombre_de_usuario` (sin `@domain.tld`) | - ### ![](image://thunderbird.png?resize=50&classes=inline) Configurar Mozilla Thunderbird (en un ordenador) Para configurar manualmente un nuevo cuenta en Thunderbird, añadir las informaciones de la cuenta, y después seleccionar el puerto 993 con SSL/TLS para IMAP, y puerto 587 con STARTTLS para SMTP. Después seleccionar 'Normal Password' para Autenticación y haz click en el botón 'Advanced Config'. Se puede que tendrás que aceptar los certificados para que todo funciona normalmente. @@ -27,7 +26,7 @@ Para configurar manualmente un nuevo cuenta en Thunderbird, añadir las informac ![](image://thunderbird_config_1.png?resize=900) ![](image://thunderbird_config_2.png?resize=900) -* [Gestionar un alias para una dirección de correo electrónico](https://support.mozilla.org/es/kb/configurar-un-alias-para-una-direccin-de-correo-el) +- [Gestionar un alias para una dirección de correo electrónico](https://support.mozilla.org/es/kb/configurar-un-alias-para-una-direccin-de-correo-el) ### ![](image://k9mail.png?resize=50&classes=inline) Configurar K-9 Mail (en Android) diff --git a/pages/03.user_guide/05.emailclients/email_configure_client.fr.md b/pages/03.user_guide/05.emailclients/email_configure_client.fr.md index 3f5b33d0..ea5b3a11 100644 --- a/pages/03.user_guide/05.emailclients/email_configure_client.fr.md +++ b/pages/03.user_guide/05.emailclients/email_configure_client.fr.md @@ -16,27 +16,29 @@ Normalement, votre client email devrait recevoir la configuration automatiquemen Voici les éléments que vous devrez entrer pour configurer manuellement votre client email (`votre.domaine.tld` fait référence à ce qui est après le @ dans votre adresse email, et `nom_utilisateur` ce qui est avant @). | Protocole | Port | Chiffrement | Authentification | Login | -| :--: | :-: | :--: | :--: | :--: | +| :--: | :-: | :--: | :--: | :--: | | IMAP | 993 | SSL/TLS | Mot de passe normal | `nom_utilisateur` (sans `@votre.domaine.tld`) | | SMTP | 587 | STARTTLS | Mot de passe normal | `nom_utilisateur` (sans `@votre.domaine.tld`) | - ### Client par client + [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="Mozilla Thunderbird"] -##### ![](image://thunderbird.png?resize=50&classes=inline) Configurer Mozilla Thunderbird + +#### ![](image://thunderbird.png?resize=50&classes=inline) Configurer Mozilla Thunderbird Pour configurer manuellement un nouveau compte dans Thunderbird commencez par remplir les informations de base (nom, adresse et mot de passe), cliquez sur Continuer puis Configuration Manuelle. Enlevez le `.` avant le nom de domaine. Sélectionnez le port 993 avec SSL/TLS pour IMAP, et le port 587 avec STARTTLS pour SMTP. Sélectionnez 'Mot de passe normal' pour l'authentification. Testez la configuration puis validez (il vous faudra ensuite peut-être accepter des certificats pour que tout fonctionne correctement). ![](image://thunderbird_config_1.png?resize=900) ![](image://thunderbird_config_2.png?resize=900) -* [Gérer les alias mails](https://support.mozilla.org/en-US/kb/configuring-email-aliases) +- [Gérer les alias mails](https://support.mozilla.org/en-US/kb/configuring-email-aliases) [/ui-tab] [ui-tab title="K-9 Mail"] -##### ![](image://k9mail.png?resize=50&classes=inline) Configurer K-9 Mail (sur Android) + +#### ![](image://k9mail.png?resize=50&classes=inline) Configurer K-9 Mail (sur Android) Suivez les instructions suivantes (comme pour Thunderbird, il vous faudra peut-être accepter des certificats à un moment). @@ -48,7 +50,8 @@ Suivez les instructions suivantes (comme pour Thunderbird, il vous faudra peut- [/ui-tab] [ui-tab title="Dekko"] -##### ![](image://dekko-app.png?resize=50&classes=inline) Configurer Dekko (sur Ubuntu Touch) + +#### ![](image://dekko-app.png?resize=50&classes=inline) Configurer Dekko (sur Ubuntu Touch) La première fois, vous pouvez simplement choisir « Ajouter un compte ». Si vous avez déjà un compte configuré, appuyez sur le menu hamburger puis sur le rouage, choisissez Courrier, Comptes et appuyez sur le symbole '+'. diff --git a/pages/03.user_guide/05.emailclients/email_configure_client.it.md b/pages/03.user_guide/05.emailclients/email_configure_client.it.md index c1647a30..41224f4e 100644 --- a/pages/03.user_guide/05.emailclients/email_configure_client.it.md +++ b/pages/03.user_guide/05.emailclients/email_configure_client.it.md @@ -15,26 +15,29 @@ Normalmente, il vostro client email si configura automaticamente quando aggiunge Ecco i valori da immettere per la configurazione manuale del vostro client mail (`vostro.dominio.tld` si riferisce a quello che appare dopo la @ nel vostro indirizzo mail, `nome utente` è riferito a quello che appare prima della @). -|Protocollo | Porta | Sicurezza della connessione | Metodo di autenticazione | Nome utente -| :--: | :-: | :--: | :--: | :--: | +|Protocollo | Porta | Sicurezza della connessione | Metodo di autenticazione | Nome utente | +| :--: | :-: | :--: | :--: | :--: | | IMAP | 993 | SSL/TLS | Password normale | nome utente (senza `@vostro.domino.tld`) | | SMTP | 587 | STARTTLS | Password normale| nome utente (senza `@vostro.domino.tld`) | ### Esempio di alcuni client + [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="Mozilla Thunderbird"] -##### ![](image://thunderbird.png?resize=50&classes=inline) Configurazione di Mozilla Thunderbird (su computer desktop) + +#### ![](image://thunderbird.png?resize=50&classes=inline) Configurazione di Mozilla Thunderbird (su computer desktop) Per configurare manualmente un nuovo account in Thunderbird, iniziate ad inserire le informazioni iniziali (nome, indirizzo e password), cliccate su Continua e poi su Configurazione Manuale selezionando la porta 993 con SSL/TLS per IMAP e la porta 587 con STARTTLS per SMTP. Selezionate 'Password normale' come autenticazione e poi cliccate su 'Configurazione avanzata'. Può darsi che dobbiate accettare l'eccezione per il certificato prima di riuscire a scaricare l'email e prima di riuscire ad inviare la prima email. Non dimenticate di togliere il punto prima del nome del dominio. ![](image://thunderbird_config_1.png?resize=900) ![](image://thunderbird_config_2.png?resize=900) -* [Gestione alias email](https://support.mozilla.org/en-US/kb/configuring-email-aliases) +- [Gestione alias email](https://support.mozilla.org/en-US/kb/configuring-email-aliases) [/ui-tab] [ui-tab title="K-9 Mail"] -##### ![](image://k9mail.png?resize=50&classes=inline) Configurazione di K-9 Mail (per Android) + +#### ![](image://k9mail.png?resize=50&classes=inline) Configurazione di K-9 Mail (per Android) Seguite le istruzioni seguenti (come per dovrete forse accettare i certificati affinché tutto funzioni correttamente): @@ -43,10 +46,10 @@ Seguite le istruzioni seguenti (come per dovrete forse accettare i certificati a ![](image://k9mail_config_3.png?resize=280&classes=inline) ![](image://k9mail_config_4.png?resize=280&classes=inline) - [/ui-tab] [ui-tab title="Dekko"] -##### ![](image://dekko-app.png?resize=50&classes=inline) Configurazione di Dekko (per Ubuntu Touch) + +#### ![](image://dekko-app.png?resize=50&classes=inline) Configurazione di Dekko (per Ubuntu Touch) Se nessun account è già configurato, potete semplicemente scegliere "Aggiungi account". Se un account è già presente, premete sul menù a panino e in seguito sugli ingranaggi, scegliete Mail, Accounts e il simbolo '+'. @@ -58,4 +61,3 @@ Selezionate IMAP. Compilate i campi e premete Successivo. Dekko cercherà la con ![](image://dekko_config_4.png?resize=280&classes=inline) [/ui-tab] [/ui-tabs] - diff --git a/pages/03.user_guide/05.emailclients/email_configure_client.md b/pages/03.user_guide/05.emailclients/email_configure_client.md index d5a95bdc..77d6e7d3 100644 --- a/pages/03.user_guide/05.emailclients/email_configure_client.md +++ b/pages/03.user_guide/05.emailclients/email_configure_client.md @@ -16,25 +16,28 @@ Modern mail clients should be able to configure themselves automatically. If aut Here are the element you should enter to manually configure your mail client (`domain.tld` refers to what's after the @ in your email address, and `username` what's before @). | Protocol | Port | Encryption | Authentication | Username | -| :--: | :-: | :--: | :--: | :--: | +| :--: | :-: | :--: | :--: | :--: | | IMAP | 993 | SSL/TLS | Normal password | `username` (without the `@domain.tld`) | | SMTP | 587 | STARTTLS | Normal password | `username` (without the `@domain.tld`) | ### Client by client + [ui-tabs position="top-left" active="0" theme="lite"] [ui-tab title="Mozilla Thunderbird"] -##### ![](image://thunderbird.png?resize=50&classes=inline) Configure Mozilla Thunderbird (on a desktop computer) + +#### ![](image://thunderbird.png?resize=50&classes=inline) Configure Mozilla Thunderbird (on a desktop computer) To manually configure a new account in Thunderbird, add the account information, then select port 993 with SSL/TLS for IMAP, and port 587 with STARTTLS for SMTP. Afterwards select 'Normal Password' for Authentication and click on 'Advanced Config'. You may need to accept the certificate exceptions for fetching mails and after you send your first mail. Don't forget to remove the dot before the domain name. ![](image://thunderbird_config_1.png?resize=900) ![](image://thunderbird_config_2.png?resize=900) -* [Manage alias mails](https://support.mozilla.org/en-US/kb/configuring-email-aliases) +- [Manage alias mails](https://support.mozilla.org/en-US/kb/configuring-email-aliases) [/ui-tab] [ui-tab title="K-9 Mail"] -##### ![](image://k9mail.png?resize=50&classes=inline) Configure K-9 Mail (on Android) + +#### ![](image://k9mail.png?resize=50&classes=inline) Configure K-9 Mail (on Android) Follow the following steps. (As for Thunderbird, you might need to accept certificates at some points) @@ -43,14 +46,14 @@ Follow the following steps. (As for Thunderbird, you might need to accept certif ![](image://k9mail_config_3.png?resize=280&classes=inline) ![](image://k9mail_config_4.png?resize=280&classes=inline) - [/ui-tab] [ui-tab title="Dekko"] -##### ![](image://dekko-app.png?resize=50&classes=inline) Configure Dekko (on Ubuntu Touch) + +#### ![](image://dekko-app.png?resize=50&classes=inline) Configure Dekko (on Ubuntu Touch) The first time you can simply choose "Add account". If you already have an account configured, tap the hamburger menu then tap the gear, choose Mail, Accounts and press the '+'-symbol. -Then you choose IMAP. Fill in the fields and press Next. Now Dekko will look for the configuration. Check that all fields are correct. Make sure you have your yunohost username, NOT your email address and choose "Allow untrusted certificates". Do this for IMAP and SMTP and press Next. Dekko will now synchronise the account after which you are done. Congratz! +Then you choose IMAP. Fill in the fields and press Next. Now Dekko will look for the configuration. Check that all fields are correct. Make sure you have your YunoHost username, NOT your email address and choose "Allow untrusted certificates". Do this for IMAP and SMTP and press Next. Dekko will now synchronise the account after which you are done. Congratz! ![](image://dekko_config_1.png?resize=280&classes=inline) ![](image://dekko_config_2.png?resize=280&classes=inline) diff --git a/pages/03.user_guide/10.email_migration/email_migration.fr.md b/pages/03.user_guide/10.email_migration/email_migration.fr.md index 69859b6e..63be3455 100644 --- a/pages/03.user_guide/10.email_migration/email_migration.fr.md +++ b/pages/03.user_guide/10.email_migration/email_migration.fr.md @@ -20,10 +20,13 @@ Cet outil doit être installé sur votre ordinateur de bureau. La procédure de [Site d’ImapSync](http://imapsync.lamiral.info/) Installez ImapSync sur votre ordinateur client en suivant ce [guide](http://imapsync.lamiral.info/INSTALL) : + ```bash sudo dnf install imapsync # Sous Fedora ``` + Transférez les mails d’un serveur à l’autre : + ```bash imapsync --host1 --port1 993 --ssl1 --user1 --password1 \ --host2 --port2 993 --ssl2 --user2 --password2 @@ -36,11 +39,15 @@ Notez que les paramètres de transfert `--port 993` et `--ssl` sont spécifiques [Site de Larch](https://github.com/rgrove/larch/) Après avoir préalablement installé `gem`, installez `larch` sur votre ordinateur client : + ```bash sudo gem install larch ``` + Transférez les mails d’un serveur à l’autre : + ```bash larch -a -f imaps://serveur_d'origine.org -t imaps://serveur_de_destination.org ``` + Pour d’autres types de transferts référez-vous à la documentation de Larch. diff --git a/pages/03.user_guide/10.email_migration/email_migration.md b/pages/03.user_guide/10.email_migration/email_migration.md index 20d40c0e..3db5245b 100644 --- a/pages/03.user_guide/10.email_migration/email_migration.md +++ b/pages/03.user_guide/10.email_migration/email_migration.md @@ -20,10 +20,13 @@ This tool must be installed on your desktop computer. The transfer method looks [ImapSync site](http://imapsync.lamiral.info/) Install ImapSync on your client computer by following this [guide](http://imapsync.lamiral.info/INSTALL): + ```bash sudo dnf install imapsync # Under Fedora ``` + Transfer emails from one server to another: + ```bash imapsync --host1 --port1 993 --ssl1 --user1 --password1 \ --host2 --port2 993 --ssl2 --user2 --password2 @@ -36,11 +39,15 @@ Note that transfer settings `--port 993` and `--ssl` are specific to YunoHost em [Larch site](https://github.com/rgrove/larch/) After beforehand installed `gem`, install `larch` on your client computer: + ```bash sudo gem install larch ``` + Transfer emails from one server to another: + ```bash larch -a -f imaps://serveur_d'origine.org -t imaps://serveur_de_destination.org ``` + For other types of transfer refer to [Larch documentation](https://github.com/rgrove/larch#label-Usage). diff --git a/pages/03.user_guide/15.xmpp/xmpp.es.md b/pages/03.user_guide/15.xmpp/xmpp.es.md index 69466c08..434e67fe 100644 --- a/pages/03.user_guide/15.xmpp/xmpp.es.md +++ b/pages/03.user_guide/15.xmpp/xmpp.es.md @@ -11,9 +11,9 @@ routes: YunoHost está instalado con un servidor de mensajería instantánea Metronome que implementa el [protocolo XMPP](https://es.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol). -XMPP es un protocolo abierto y extensible que también permite crear salones de discusión, compartir status y datos, echar llamadas en VoIP y hacer videoconferencias. +XMPP es un protocolo abierto y extensible que también permite crear salones de discusión, compartir status y datos, echar llamadas en VoIP y hacer videoconferencias. -Todas las aplicaciones basadas en XMPP son compatibles entre ellas : cuando utilizas un cliente XMPP puedes discutir con cualquier persona que tenga una cuenta XMPP/Jabber. Este protocolo ya es utilizado por millones de personas en el mundo. +Todas las aplicaciones basadas en XMPP son compatibles entre ellas : cuando utilizas un cliente XMPP puedes discutir con cualquier persona que tenga una cuenta XMPP/Jabber. Este protocolo ya es utilizado por millones de personas en el mundo. ## Cuenta XMPP/Jabber @@ -22,11 +22,13 @@ Una cuenta XMPP/Jabber está basada en un ID bajo la forma `usuario@dominio.tld` ## Conectarse a XMPP Existen varios clientes web de tipo red social, como : + - [Movim](https://movim.eu) - [ConverseJS](https://conversejs.org/) - [Libervia/Salut à Toi](https://salut-a-toi.org/) También puedes utilizar un cliente Desktop como : + - [Gajim](https://gajim.org/es/) (Linux, Windows) - [Dino](https://dino.im) (Linux) - [Thunderbird](https://www.thunderbird.net/es-ES/) (multiplataformas) @@ -34,6 +36,7 @@ También puedes utilizar un cliente Desktop como : - [Profanity](https://profanity-im.github.io/) (Linux) ... o un cliente smartphone : + - [Conversations](https://conversations.im/) (Android) - [Xabber](http://xabber.com) (Android) - [Movim](https://movim.eu) (Android) @@ -42,18 +45,19 @@ También puedes utilizar un cliente Desktop como : - [Monal](https://monal.im/) (iOS) - [Kaidan](https://www.kaidan.im/) (Ubuntu Touch / Plasma Mobile) -Aquí tienes una lista más exhaustiva de clientes XMPP (en) : https://xmpp.org/software/clients.html +Aquí tienes una lista más exhaustiva de clientes XMPP (en) : -### Cifrar tu conversaciones con OMEMO : +### Cifrar tu conversaciones con OMEMO Es posible cifrar tu conversaciones XMPP con la ayuda de [OMEMO](https://xmpp.org/extensions/xep-0384.html), por ejemplo utilizando Gajim : -* Instalar `gajim` y el plugin `gajim-omemo` -* Activar el plugin en `Tools > Plugins` -* Activar el cifrado en una conversación con un contacto que también tiene OMEMO activado. -### Salón de discusión +- Instalar `gajim` y el plugin `gajim-omemo` +- Activar el plugin en `Tools > Plugins` +- Activar el cifrado en una conversación con un contacto que también tiene OMEMO activado. -Para crear un salón de discusión (Multi-user chat) en tu servidor YunoHost, utiliza el ID nombredelsalon@muc.dominio.tld (donde dominio.tld es el dominio principal de tu servidor). +### Salón de discusión + +Para crear un salón de discusión (Multi-user chat) en tu servidor YunoHost, utiliza el ID (donde dominio.tld es el dominio principal de tu servidor). Si utilizas un nombre de dominio personal, es necesario [añadir una redirección de tipo CNAME para el subdominio `muc.`](/dns_config) en tu servidor DNS. diff --git a/pages/03.user_guide/15.xmpp/xmpp.fr.md b/pages/03.user_guide/15.xmpp/xmpp.fr.md index 8ac31781..fa5f6ba9 100644 --- a/pages/03.user_guide/15.xmpp/xmpp.fr.md +++ b/pages/03.user_guide/15.xmpp/xmpp.fr.md @@ -54,13 +54,14 @@ Voici une liste plus exhaustive des clients XMPP : [https://fr.wikipedia.org/wi ## Chiffrer ses conversations avec OMEMO Il est possible de rendre les conversations plus sécurisées et privées en les chiffrant à l'aide de [OMEMO](https://xmpp.org/extensions/xep-0384.html), notamment en utilisant Gajim : + - Installez `gajim` et le plugin `gajim-omemo` ; - Activez le plugin dans `Outils > Plugins` ; - Activez le chiffrement dans une conversation avec un contact disposant de OMEMO. ## Salon de discussion -Pour créer un salon de discussion (Multi-user chat) sur votre serveur YunoHost, utilisez l’identifiant nomsalon@muc.domaine.tld (où domaine.tld est le domaine principal de votre serveur). +Pour créer un salon de discussion (Multi-user chat) sur votre serveur YunoHost, utilisez l’identifiant (où domaine.tld est le domaine principal de votre serveur). Si vous utilisez un nom de domaine personnel, il est nécessaire d’[ajouter une redirection de type CNAME pour le sous domaine `muc.`](/dns_config) au niveau de votre serveur DNS. diff --git a/pages/03.user_guide/15.xmpp/xmpp.it.md b/pages/03.user_guide/15.xmpp/xmpp.it.md index 6e146657..91266e2c 100644 --- a/pages/03.user_guide/15.xmpp/xmpp.it.md +++ b/pages/03.user_guide/15.xmpp/xmpp.it.md @@ -9,7 +9,7 @@ routes: ![](image://XMPP_logo.png?resize=100) -L'installazione di YunoHost comprende il server di messaggistica istantanea Metronome che supporta il [protocollo XMPP](https://it.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol) (precedentemente conosciuto come Jabber). +L'installazione di YunoHost comprende il server di messaggistica istantanea Metronome che supporta il [protocollo XMPP](https://it.wikipedia.org/wiki/Extensible_Messaging_and_Presence_Protocol) (precedentemente conosciuto come Jabber). Questo protocollo utilizzato da milioni di persone nel mondo è un protocollo aperto. Tutte le applicazioni basate su XMPP sono tra di loro compatibili: quando utilizzate un client XMPP potete interagire con chiunque possieda un account XMPP. @@ -20,7 +20,7 @@ XMPP è un protocollo espandibile: ciò significa che gli utenti possono configu Per utilizzare XMPP è necessario disporre di un account che rispetti questa sintassi come identificativo: `utente@mio.dominio.tld` e di una password. -In YunoHost un account XMPP è creato automaticamente per ogni utente. +In YunoHost un account XMPP è creato automaticamente per ogni utente. L'identificativo XMPP corrisponde all'indirizzo mail principale di ogni utente e relativa password. ## Collegarsi al proprio account XMPP YunoHost @@ -56,6 +56,7 @@ Qui un elenco completo dei client XMPP [Qui](https://fr.wikipedia.org/wiki/Liste ## Cifrare le conversazioni con OMEMO È possibile proteggere e cifrare le conversazioni con l'uso di [OMEMO encryption](https://xmpp.org/extensions/xep-0384.html), ben supportato in Gajim: + - Installate `gajim` e il plugim `gajim-omemo`. - Attivate il plugin nel menù `Strumenti > Plugins`. - Attivate la cifratura in una conversazione con un contatto che adotta OMEMO diff --git a/pages/03.user_guide/15.xmpp/xmpp.md b/pages/03.user_guide/15.xmpp/xmpp.md index 03767c82..1337a1a2 100644 --- a/pages/03.user_guide/15.xmpp/xmpp.md +++ b/pages/03.user_guide/15.xmpp/xmpp.md @@ -51,11 +51,12 @@ You can connect to your YunoHost XMPP account in different ways. - [Siskin IM](https://siskin.im/) (iOS) - [Kaidan](https://www.kaidan.im/) (Ubuntu Touch / Plasma Mobile) -Here is an exhaustive list of XMPP clients: https://xmpp.org/software/clients.html +Here is an exhaustive list of XMPP clients: ## Encrypt conversations with OMEMO XMPP chats can be made secure and private using [OMEMO encryption](https://xmpp.org/extensions/xep-0384.html), for instance using Gajim: + - Install `gajim` and the plugin `gajim-omemo`. - Turn on the plugin in `Tools > Plugins`. - Turn on the encryption in the chat with somebody who also has OMEMO. diff --git a/pages/03.user_guide/user_overview.fr.md b/pages/03.user_guide/user_overview.fr.md index 3c5f7d4c..5e900b79 100644 --- a/pages/03.user_guide/user_overview.fr.md +++ b/pages/03.user_guide/user_overview.fr.md @@ -8,4 +8,4 @@ routes: default: '/user_guide' --- -!! Cette section est en cours d'élaboration. \ No newline at end of file +!! Cette section est en cours d'élaboration. diff --git a/pages/03.user_guide/user_overview.md b/pages/03.user_guide/user_overview.md index c7b7616c..a31c91a6 100644 --- a/pages/03.user_guide/user_overview.md +++ b/pages/03.user_guide/user_overview.md @@ -8,4 +8,4 @@ routes: default: '/user_guide' --- -!! This section is being worked on. \ No newline at end of file +!! This section is being worked on. diff --git a/pages/04.applications/15.framasoft/apps_framasoft.md b/pages/04.applications/15.framasoft/apps_framasoft.md index 43a3f4d8..52c7c354 100644 --- a/pages/04.applications/15.framasoft/apps_framasoft.md +++ b/pages/04.applications/15.framasoft/apps_framasoft.md @@ -9,42 +9,42 @@ routes: | Framasoft App | Original project | Package | | :---: | :---: | :---: | -| Framabag | [Wallabag ](https://www.wallabag.it) | [[fa=git /]](https://github.com/YunoHost-Apps/wallabag2_ynh) ![](https://ci-apps.yunohost.org/ci/badges/wallabag2.status.svg) ![](https://dash.yunohost.org/integration/wallabag2.svg) | -| Framabee | [Searx ](https://searx.ir) | [[fa=git /]](https://github.com/YunoHost-Apps/searx_ynh) ![](https://ci-apps.yunohost.org/ci/badges/searx.status.svg) ![](https://dash.yunohost.org/integration/searx.svg) | -| Framabin | [PrivateBin ](https://privatebin.info) | [[fa=git /]](https://github.com/YunoHost-apps/zerobin_ynh) ![](https://ci-apps.yunohost.org/ci/badges/zerobin.status.svg) ![](https://dash.yunohost.org/integration/zerobin.svg) | -| Framaboard | [Kanboard ](https://kanboard.org) | [[fa=git /]](https://github.com/YunoHost-Apps/kanboard_ynh) ![](https://ci-apps.yunohost.org/ci/badges/kanboard.status.svg) ![](https://dash.yunohost.org/integration/kanboard.svg) | -| Framabookin | [BicBucStriim ](https://github.com/rvolz/BicBucStriim) | [[fa=git /]](https://github.com/YunoHost-Apps/bicbucstriim_ynh) ![](https://ci-apps.yunohost.org/ci/badges/bicbucstriim.status.svg) ![](https://dash.yunohost.org/integration/bicbucstriim.svg) | -| Framacalc | [Ethercalc ](https://ethercalc.net) | [[fa=git /]](https://github.com/YunoHost-Apps/ethercalc_ynh) ![](https://ci-apps.yunohost.org/ci/badges/ethercalc.status.svg) ![](https://dash.yunohost.org/integration/ethercalc.svg) | -| Framacarte | [uMap ](http://umap.openstreetmap.fr) | [[fa=git /]](https://github.com/YunoHost-Apps/umap_ynh) ![](https://ci-apps.yunohost.org/ci/badges/umap.status.svg) ![](https://dash.yunohost.org/integration/umap.svg) | -| Framaclic | [Dolomon ](https://dolomon.org) | Non Packagé | -| Framadate | [OpenSondage ](https://framadate.org) | [[fa=git /]](https://github.com/YunoHost-Apps/opensondage_ynh) ![](https://ci-apps.yunohost.org/ci/badges/opensondage.status.svg) ![](https://dash.yunohost.org/integration/opensondage.svg) | -| Framadrive | [Nextcloud ](https://nextcloud.com) | [[fa=git /]](https://github.com/YunoHost-apps/nextcloud_ynh) ![](https://ci-apps.yunohost.org/ci/badges/nextcloud.status.svg) ![](https://dash.yunohost.org/integration/nextcloud.svg) | -| Framadrop | [Lufi ](https://framagit.org/fiat-tux/hat-softwares/lufi) | [[fa=git /]](https://github.com/YunoHost-Apps/lufi_ynh) ![](https://ci-apps.yunohost.org/ci/badges/lufi.status.svg) ![](https://dash.yunohost.org/integration/lufi.svg) | -| Framaestro | [Framaestro ](https://framaestro.org) | [[fa=git /]](https://github.com/YunoHost-Apps/framaestro_ynh) ![](https://ci-apps.yunohost.org/ci/badges/framaestro.status.svg) ![](https://dash.yunohost.org/integration/framaestro.svg) | -| Framaforms | [Framaforms ](https://framaforms.org) | [[fa=git /]](https://github.com/YunoHost-Apps/framaforms_ynh) ![](https://ci-apps.yunohost.org/ci/badges/framaforms.status.svg) ![](https://dash.yunohost.org/integration/framaforms.svg) | -| Framagames | [Framagames ](https://framagames.org) | [[fa=git /]](https://github.com/YunoHost-Apps/framagames_ynh) ![](https://ci-apps.yunohost.org/ci/badges/framagames.status.svg) ![](https://dash.yunohost.org/integration/framagames.svg) | +| Framabag | [Wallabag](https://www.wallabag.it) | [[fa=git /]](https://github.com/YunoHost-Apps/wallabag2_ynh) ![](https://ci-apps.yunohost.org/ci/badges/wallabag2.status.svg) ![](https://dash.yunohost.org/integration/wallabag2.svg) | +| Framabee | [Searx](https://searx.ir) | [[fa=git /]](https://github.com/YunoHost-Apps/searx_ynh) ![](https://ci-apps.yunohost.org/ci/badges/searx.status.svg) ![](https://dash.yunohost.org/integration/searx.svg) | +| Framabin | [PrivateBin](https://privatebin.info) | [[fa=git /]](https://github.com/YunoHost-apps/zerobin_ynh) ![](https://ci-apps.yunohost.org/ci/badges/zerobin.status.svg) ![](https://dash.yunohost.org/integration/zerobin.svg) | +| Framaboard | [Kanboard](https://kanboard.org) | [[fa=git /]](https://github.com/YunoHost-Apps/kanboard_ynh) ![](https://ci-apps.yunohost.org/ci/badges/kanboard.status.svg) ![](https://dash.yunohost.org/integration/kanboard.svg) | +| Framabookin | [BicBucStriim](https://github.com/rvolz/BicBucStriim) | [[fa=git /]](https://github.com/YunoHost-Apps/bicbucstriim_ynh) ![](https://ci-apps.yunohost.org/ci/badges/bicbucstriim.status.svg) ![](https://dash.yunohost.org/integration/bicbucstriim.svg) | +| Framacalc | [Ethercalc](https://ethercalc.net) | [[fa=git /]](https://github.com/YunoHost-Apps/ethercalc_ynh) ![](https://ci-apps.yunohost.org/ci/badges/ethercalc.status.svg) ![](https://dash.yunohost.org/integration/ethercalc.svg) | +| Framacarte | [uMap](http://umap.openstreetmap.fr) | [[fa=git /]](https://github.com/YunoHost-Apps/umap_ynh) ![](https://ci-apps.yunohost.org/ci/badges/umap.status.svg) ![](https://dash.yunohost.org/integration/umap.svg) | +| Framaclic | [Dolomon](https://dolomon.org) | Non Packagé | +| Framadate | [OpenSondage](https://framadate.org) | [[fa=git /]](https://github.com/YunoHost-Apps/opensondage_ynh) ![](https://ci-apps.yunohost.org/ci/badges/opensondage.status.svg) ![](https://dash.yunohost.org/integration/opensondage.svg) | +| Framadrive | [Nextcloud](https://nextcloud.com) | [[fa=git /]](https://github.com/YunoHost-apps/nextcloud_ynh) ![](https://ci-apps.yunohost.org/ci/badges/nextcloud.status.svg) ![](https://dash.yunohost.org/integration/nextcloud.svg) | +| Framadrop | [Lufi](https://framagit.org/fiat-tux/hat-softwares/lufi) | [[fa=git /]](https://github.com/YunoHost-Apps/lufi_ynh) ![](https://ci-apps.yunohost.org/ci/badges/lufi.status.svg) ![](https://dash.yunohost.org/integration/lufi.svg) | +| Framaestro | [Framaestro](https://framaestro.org) | [[fa=git /]](https://github.com/YunoHost-Apps/framaestro_ynh) ![](https://ci-apps.yunohost.org/ci/badges/framaestro.status.svg) ![](https://dash.yunohost.org/integration/framaestro.svg) | +| Framaforms | [Framaforms](https://framaforms.org) | [[fa=git /]](https://github.com/YunoHost-Apps/framaforms_ynh) ![](https://ci-apps.yunohost.org/ci/badges/framaforms.status.svg) ![](https://dash.yunohost.org/integration/framaforms.svg) | +| Framagames | [Framagames](https://framagames.org) | [[fa=git /]](https://github.com/YunoHost-Apps/framagames_ynh) ![](https://ci-apps.yunohost.org/ci/badges/framagames.status.svg) ![](https://dash.yunohost.org/integration/framagames.svg) | | Framagenda | [Nextcloud Calendar](https://apps.nextcloud.com/apps/calendar) | c.f. Nextcloud | -| Framagit | [GitLab ](https://about.gitlab.com) | [[fa=git /]](https://github.com/YunoHost-Apps/gitlab_ynh) ![](https://ci-apps.yunohost.org/ci/badges/gitlab.status.svg) ![](https://dash.yunohost.org/integration/gitlab.svg) | -| Frama.link | [Lstu ](https://lstu.fr) | [[fa=git /]](https://github.com/YunoHost-Apps/lstu_ynh) ![](https://ci-apps.yunohost.org/ci/badges/lstu.status.svg) ![](https://dash.yunohost.org/integration/lstu.svg) | -| Framalistes | [Sympa ](http://www.sympa.org) | [[fa=git /]](https://github.com/alexAubin/sympa_ynh) ![](https://ci-apps.yunohost.org/ci/badges/sympa.status.svg) ![](https://dash.yunohost.org/integration/sympa.svg) | -| Framanews | [TinyTinyRSS ](https://tt-rss.org) | [[fa=git /]](https://github.com/YunoHost-apps/ttrss_ynh) ![](https://ci-apps.yunohost.org/ci/badges/ttrss.status.svg) ![](https://dash.yunohost.org/integration/ttrss.svg) | -| Framanotes | [Turtl ](https://turtlapp.com) | [[fa=git /]](https://github.com/YunoHost-Apps/turtl_ynh) ![](https://ci-apps.yunohost.org/ci/badges/turtl.status.svg) ![](https://dash.yunohost.org/integration/turtl.svg) | +| Framagit | [GitLab](https://about.gitlab.com) | [[fa=git /]](https://github.com/YunoHost-Apps/gitlab_ynh) ![](https://ci-apps.yunohost.org/ci/badges/gitlab.status.svg) ![](https://dash.yunohost.org/integration/gitlab.svg) | +| Frama.link | [Lstu](https://lstu.fr) | [[fa=git /]](https://github.com/YunoHost-Apps/lstu_ynh) ![](https://ci-apps.yunohost.org/ci/badges/lstu.status.svg) ![](https://dash.yunohost.org/integration/lstu.svg) | +| Framalistes | [Sympa](http://www.sympa.org) | [[fa=git /]](https://github.com/alexAubin/sympa_ynh) ![](https://ci-apps.yunohost.org/ci/badges/sympa.status.svg) ![](https://dash.yunohost.org/integration/sympa.svg) | +| Framanews | [TinyTinyRSS](https://tt-rss.org) | [[fa=git /]](https://github.com/YunoHost-apps/ttrss_ynh) ![](https://ci-apps.yunohost.org/ci/badges/ttrss.status.svg) ![](https://dash.yunohost.org/integration/ttrss.svg) | +| Framanotes | [Turtl](https://turtlapp.com) | [[fa=git /]](https://github.com/YunoHost-Apps/turtl_ynh) ![](https://ci-apps.yunohost.org/ci/badges/turtl.status.svg) ![](https://dash.yunohost.org/integration/turtl.svg) | | Framapad | [Etherpad](https://etherpad.org) + [MyPads](https://framagit.org/framasoft/Etherpad/ep_mypads) | [[fa=git /]](https://github.com/YunoHost-Apps/etherpad_mypads_ynh) ![](https://ci-apps.yunohost.org/ci/badges/etherpad_mypads.status.svg) ![](https://dash.yunohost.org/integration/etherpad_mypads.svg) | -| Framapiaf | [Mastodon ](https://joinmastodon.org) | [[fa=git /]](https://github.com/YunoHost-Apps/mastodon_ynh) ![](https://ci-apps.yunohost.org/ci/badges/mastodon.status.svg) ![](https://dash.yunohost.org/integration/mastodon.svg) | -| Framapic | [Lutim ](https://lut.im/) | [[fa=git /]](https://github.com/YunoHost-Apps/lutim_ynh) ![](https://ci-apps.yunohost.org/ci/badges/lutim.status.svg) ![](https://dash.yunohost.org/integration/lutim.svg) | -| Framasites | [Grav ](https://getgrav.org) | [[fa=git /]](https://github.com/YunoHost-Apps/grav_ynh) ![](https://ci-apps.yunohost.org/ci/badges/grav.status.svg) ![](https://dash.yunohost.org/integration/grav.svg) | -| Framaslides | [Strut ](https://strut.io) | [[fa=git /]](https://github.com/YunoHost-Apps/strut_ynh) ![](https://ci-apps.yunohost.org/ci/badges/strut.status.svg) ![](https://dash.yunohost.org/integration/strut.svg) | -| Framasphère | [Diaspora ](https://diasporafoundation.org) | [[fa=git /]](https://github.com/aymhce/diaspora_ynh) ![](https://ci-apps.yunohost.org/ci/badges/diaspora.status.svg) ![](https://dash.yunohost.org/integration/diaspora.svg) | -| Framatalk | [Jitsi Meet ](https://meet.jit.si) | [[fa=git /]](https://github.com/YunoHost-Apps/jitsi_ynh) ![](https://ci-apps.yunohost.org/ci/badges/jitsi.status.svg) ![](https://dash.yunohost.org/integration/jitsi.svg) | -| Framateam | [Mattermost ](https://mattermost.com) | [[fa=git /]](https://github.com/YunoHost-Apps/mattermost_ynh) ![](https://ci-apps.yunohost.org/ci/badges/mattermost.status.svg) ![](https://dash.yunohost.org/integration/mattermost.svg) | -| Framatrad | [Weblate ](https://weblate.org) | [[fa=git /]](https://github.com/YunoHost-Apps/weblate_ynh) ![](https://ci-apps.yunohost.org/ci/badges/weblate.status.svg) ![](https://dash.yunohost.org/integration/weblate.svg) | -| Framatube | [Peertube ](https://joinpeertube.org) | [[fa=git /]](https://github.com/YunoHost-Apps/peertube_ynh) ![](https://ci-apps.yunohost.org/ci/badges/peertube.status.svg) ![](https://dash.yunohost.org/integration/peertube.svg) | -| Framavectoriel | [SVG-Edit ](https://github.com/SVG-Edit/svgedit) | [[fa=git /]](https://github.com/YunoHost-Apps/svgedit_ynh) ![](https://ci-apps.yunohost.org/ci/badges/svgedit.status.svg) ![](https://dash.yunohost.org/integration/svgedit.svg) | -| Framavox | [Loomio ](https://www.loomio.org) | Non packagé | -| Framemo | [Scrumblr ](http://scrumblr.ca) | [[fa=git /]](https://github.com/YunoHost-Apps/scrumblr_ynh) ![](https://ci-apps.yunohost.org/ci/badges/scrumblr.status.svg) ![](https://dash.yunohost.org/integration/scrumblr.svg) | -| Framindmap | [Wisemapping ](https://www.wisemapping.com) | [[fa=git /]](https://github.com/YunoHost-Apps/wisemapping_ynh) ![](https://ci-apps.yunohost.org/ci/badges/wisemapping.status.svg) ![](https://dash.yunohost.org/integration/wisemapping.svg) | -| Framinetest | [Minetest ](https://www.minetest.net) | [[fa=git /]](https://github.com/YunoHost-Apps/minetest_ynh) ![](https://ci-apps.yunohost.org/ci/badges/minetest.status.svg) ![](https://dash.yunohost.org/integration/minetest.svg) | -| MyFrama | [Shaarli ](https://github.com/shaarli/Shaarli) | [[fa=git /]](https://github.com/YunoHost-Apps/shaarli_ynh) ![](https://ci-apps.yunohost.org/ci/badges/shaarli.status.svg) ![](https://dash.yunohost.org/integration/shaarli.svg) | +| Framapiaf | [Mastodon](https://joinmastodon.org) | [[fa=git /]](https://github.com/YunoHost-Apps/mastodon_ynh) ![](https://ci-apps.yunohost.org/ci/badges/mastodon.status.svg) ![](https://dash.yunohost.org/integration/mastodon.svg) | +| Framapic | [Lutim](https://lut.im/) | [[fa=git /]](https://github.com/YunoHost-Apps/lutim_ynh) ![](https://ci-apps.yunohost.org/ci/badges/lutim.status.svg) ![](https://dash.yunohost.org/integration/lutim.svg) | +| Framasites | [Grav](https://getgrav.org) | [[fa=git /]](https://github.com/YunoHost-Apps/grav_ynh) ![](https://ci-apps.yunohost.org/ci/badges/grav.status.svg) ![](https://dash.yunohost.org/integration/grav.svg) | +| Framaslides | [Strut](https://strut.io) | [[fa=git /]](https://github.com/YunoHost-Apps/strut_ynh) ![](https://ci-apps.yunohost.org/ci/badges/strut.status.svg) ![](https://dash.yunohost.org/integration/strut.svg) | +| Framasphère | [Diaspora](https://diasporafoundation.org) | [[fa=git /]](https://github.com/aymhce/diaspora_ynh) ![](https://ci-apps.yunohost.org/ci/badges/diaspora.status.svg) ![](https://dash.yunohost.org/integration/diaspora.svg) | +| Framatalk | [Jitsi Meet](https://meet.jit.si) | [[fa=git /]](https://github.com/YunoHost-Apps/jitsi_ynh) ![](https://ci-apps.yunohost.org/ci/badges/jitsi.status.svg) ![](https://dash.yunohost.org/integration/jitsi.svg) | +| Framateam | [Mattermost](https://mattermost.com) | [[fa=git /]](https://github.com/YunoHost-Apps/mattermost_ynh) ![](https://ci-apps.yunohost.org/ci/badges/mattermost.status.svg) ![](https://dash.yunohost.org/integration/mattermost.svg) | +| Framatrad | [Weblate](https://weblate.org) | [[fa=git /]](https://github.com/YunoHost-Apps/weblate_ynh) ![](https://ci-apps.yunohost.org/ci/badges/weblate.status.svg) ![](https://dash.yunohost.org/integration/weblate.svg) | +| Framatube | [Peertube](https://joinpeertube.org) | [[fa=git /]](https://github.com/YunoHost-Apps/peertube_ynh) ![](https://ci-apps.yunohost.org/ci/badges/peertube.status.svg) ![](https://dash.yunohost.org/integration/peertube.svg) | +| Framavectoriel | [SVG-Edit](https://github.com/SVG-Edit/svgedit) | [[fa=git /]](https://github.com/YunoHost-Apps/svgedit_ynh) ![](https://ci-apps.yunohost.org/ci/badges/svgedit.status.svg) ![](https://dash.yunohost.org/integration/svgedit.svg) | +| Framavox | [Loomio](https://www.loomio.org) | Non packagé | +| Framemo | [Scrumblr](http://scrumblr.ca) | [[fa=git /]](https://github.com/YunoHost-Apps/scrumblr_ynh) ![](https://ci-apps.yunohost.org/ci/badges/scrumblr.status.svg) ![](https://dash.yunohost.org/integration/scrumblr.svg) | +| Framindmap | [Wisemapping](https://www.wisemapping.com) | [[fa=git /]](https://github.com/YunoHost-Apps/wisemapping_ynh) ![](https://ci-apps.yunohost.org/ci/badges/wisemapping.status.svg) ![](https://dash.yunohost.org/integration/wisemapping.svg) | +| Framinetest | [Minetest](https://www.minetest.net) | [[fa=git /]](https://github.com/YunoHost-Apps/minetest_ynh) ![](https://ci-apps.yunohost.org/ci/badges/minetest.status.svg) ![](https://dash.yunohost.org/integration/minetest.svg) | +| MyFrama | [Shaarli](https://github.com/shaarli/Shaarli) | [[fa=git /]](https://github.com/YunoHost-Apps/shaarli_ynh) ![](https://ci-apps.yunohost.org/ci/badges/shaarli.status.svg) ![](https://dash.yunohost.org/integration/shaarli.svg) | ### See also diff --git a/pages/04.applications/20.app_bundle/05.ngo/use_case_non-profit_organisations.ca.md b/pages/04.applications/20.app_bundle/05.ngo/use_case_non-profit_organisations.ca.md index 8d878678..b46f31e9 100644 --- a/pages/04.applications/20.app_bundle/05.ngo/use_case_non-profit_organisations.ca.md +++ b/pages/04.applications/20.app_bundle/05.ngo/use_case_non-profit_organisations.ca.md @@ -21,23 +21,23 @@ Organitzacions sense ànim de lucre, ONGs o qualsevol tipus d'associació. Normalment les organitzacions sense ànim de lucre han de donar alguns serveis públics: -* Consell d'administració / Comitè director / Voluntàries amb: - * [Correus electrònics](#mails) - * [Calendari](#calendar) - * [Contacte](#contact) - * [Fitxers compartits / Drive](#shared-files) - * [Missatgeria instantània](#instant-communication) - * [Intranet / base de coneixements](#intranet) - * [ERP / Comptabilitat](#erp-accounting) -* Membres amb: - * [Pàgina web pública amb accés privat i individual](#public-web-site) - * [Adhesió](#membership) - * [Inscripció a esdeveniments](#events-registration) - * [Butlletí d'informació](#newsletter-mailing) - * [Fòrum](#forum) -* Públic amb: - * [Pàgina web pública](#public-web-site) - * [Butlletí d'informació](#newsletter-mailing) +- Consell d'administració / Comitè director / Voluntàries amb: + - [Correus electrònics](#mails) + - [Calendari](#calendar) + - [Contacte](#contact) + - [Fitxers compartits / Drive](#shared-files) + - [Missatgeria instantània](#instant-communication) + - [Intranet / base de coneixements](#intranet) + - [ERP / Comptabilitat](#erp-accounting) +- Membres amb: + - [Pàgina web pública amb accés privat i individual](#public-web-site) + - [Adhesió](#membership) + - [Inscripció a esdeveniments](#events-registration) + - [Butlletí d'informació](#newsletter-mailing) + - [Fòrum](#forum) +- Públic amb: + - [Pàgina web pública](#public-web-site) + - [Butlletí d'informació](#newsletter-mailing) ## Quan @@ -46,15 +46,15 @@ Quan l'organització estigui preparada per a fer el pas. ## On El servidor YunoHost de l'organització pot estar allotjat en diferents llocs: -* Allotjament propi en un servidor, ordinador o Raspberry darrera una connexió ADSL, SDSL o fibra -* Serveis d'allotjament de [Chatons](https://chatons.org), [librehosters](https://framagit.org/librehosters/awesome-librehosters) -* Serveis d'allotjament comercials que ofereixin màquines virtuals Debian + +- Allotjament propi en un servidor, ordinador o Raspberry darrera una connexió ADSL, SDSL o fibra +- Serveis d'allotjament de [Chatons](https://chatons.org), [librehosters](https://framagit.org/librehosters/awesome-librehosters) +- Serveis d'allotjament comercials que ofereixin màquines virtuals Debian ## Per què YunoHost pot cobrir la majoria de necessitats d'una organització sense ànim de lucre i permet tenir el control sobre les dades de l'organització. - ## Com ### YunoHost @@ -64,20 +64,21 @@ YunoHost és una distribució GNU/Linux basada en Debian empaquetada amb program ![](https://upload.wikimedia.org/wikipedia/commons/0/07/Yunohost_user_portal.png) YunoHost de base ofereix: -* Un sistema d'aplicacions -* Una interfície web -* Una interfície per línia de comandes (CLI): Moulinette -* Un servidor web: NGINX -* Un servidor DNS: Dnsmasq -* Una base de dades: MariaDB -* Un sistema de còpies de seguretat -* Un SSO: SSOwat -* OpenLDAP -* Correu electrònic: - * SMTP: Postfix - * IMAP & POP3: Dovecot - * Un antispam: rspamd, rmilter -* Un servidor de missatgeria instantània XMPP: Metronome IM + +- Un sistema d'aplicacions +- Una interfície web +- Una interfície per línia de comandes (CLI): Moulinette +- Un servidor web: NGINX +- Un servidor DNS: Dnsmasq +- Una base de dades: MariaDB +- Un sistema de còpies de seguretat +- Un SSO: SSOwat +- OpenLDAP +- Correu electrònic: + - SMTP: Postfix + - IMAP & POP3: Dovecot + - Un antispam: rspamd, rmilter +- Un servidor de missatgeria instantània XMPP: Metronome IM ### Nom de domini @@ -89,21 +90,24 @@ De base, YunoHost ofereix un sistema de correus electrònics disponible utilitza Els comptes de correu electrònic es poden gestionar per mitjà de la interfície web o de la línia de comandes. Els comptes creats es guarden en l'OpenLDAP. Es poden instal·lar paquets addicionals per donar més funcionalitats al sistema de correu electrònic de YunoHost: -* Un client web utilitzant [Roundcube](https://github.com/YunoHost-Apps/roundcube_ynh), [Rainloop](https://github.com/YunoHost-Apps/rainloop_ynh) -* ActiveSync utilitzant [Z-Push](https://github.com/YunoHost-Apps/z-push_ynh) -* Un grup de difusió interna utilitzant [Mailman](https://github.com/YunoHost-Apps/mailman_ynh) + +- Un client web utilitzant [Roundcube](https://github.com/YunoHost-Apps/roundcube_ynh), [Rainloop](https://github.com/YunoHost-Apps/rainloop_ynh) +- ActiveSync utilitzant [Z-Push](https://github.com/YunoHost-Apps/z-push_ynh) +- Un grup de difusió interna utilitzant [Mailman](https://github.com/YunoHost-Apps/mailman_ynh) ### Calendari Per oferir calendaris personals o compartits haureu d'instal·lar: -* [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh) -* [Baikal](https://github.com/YunoHost-Apps/baikal_ynh) + +- [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh) +- [Baikal](https://github.com/YunoHost-Apps/baikal_ynh) ### Contactes Per oferir un sistema de contactes personal haureu d'instal·lar: -* [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh) -* [Baïkal](https://github.com/YunoHost-Apps/baikal_ynh) + +- [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh) +- [Baïkal](https://github.com/YunoHost-Apps/baikal_ynh) ### Fitxers compartits @@ -115,30 +119,35 @@ Els fitxers estaran disponibles a través d'una interfície web o bé utilitzant De base YunoHost ofereix un servidor XMPP, pel que podeu instal·lar un client web: [Jappix](https://github.com/YunoHost-Apps/jappix_ynh). També podeu instal·lar un servidor matrix: -* El servidor: [Synapse](https://github.com/YunoHost-Apps/synapse_ynh) -* Un client web: [Riot](https://github.com/YunoHost-Apps/riot_ynh) + +- El servidor: [Synapse](https://github.com/YunoHost-Apps/synapse_ynh) +- Un client web: [Riot](https://github.com/YunoHost-Apps/riot_ynh) ### Intranet Per a una organització sense ànim de lucre, una bona manera d'implementar una intranet és oferir una wiki interna per a que les usuàries puguin llegir, editar i afegir contingut. Vegeu aquí alguns paquets que permeten implementar una wiki: -* [DokuWiki](https://github.com/YunoHost-Apps/docuwiki_ynh) utilitzant la sintaxi wiki -* [Wiki.js](https://github.com/YunoHost-Apps/wikijs_ynh) utilitzant la sintaxi markdown + +- [DokuWiki](https://github.com/YunoHost-Apps/docuwiki_ynh) utilitzant la sintaxi wiki +- [Wiki.js](https://github.com/YunoHost-Apps/wikijs_ynh) utilitzant la sintaxi markdown ### ERP / Comptabilitat Arribats a un cert punt una organització sense ànim de lucre podria necessitar un sistema de comptabilitat / ERP, aquí hi ha dos propostes: -* [OpenERP/Odoo](https://github.com/YunoHost-Apps/libreerp_ynh) -* [Dolibarr](https://github.com/YunoHost-Apps/dolibarr_ynh) + +- [OpenERP/Odoo](https://github.com/YunoHost-Apps/libreerp_ynh) +- [Dolibarr](https://github.com/YunoHost-Apps/dolibarr_ynh) ### Pàgina web pública Hi ha múltiples maneres d'implementar una pàgina web pública: -* Un pàgina simple amb HTML, CSS, etc. utilitzant: [Custom Webapp](https://github.com/YunoHost-Apps/my_webapp_ynh) -* Utilitzant un CMS (sistema de gestió de contingut) com [Wordpress](https://github.com/YunoHost-Apps/_ynh), [Drupal](https://github.com/YunoHost-Apps/drupal_ynh) , [Grav](https://github.com/YunoHost-Apps/grav_ynh), [PluXml](https://github.com/YunoHost-Apps/pluxml_ynh) + +- Un pàgina simple amb HTML, CSS, etc. utilitzant: [Custom Webapp](https://github.com/YunoHost-Apps/my_webapp_ynh) +- Utilitzant un CMS (sistema de gestió de contingut) com [Wordpress](https://github.com/YunoHost-Apps/_ynh), [Drupal](https://github.com/YunoHost-Apps/drupal_ynh) , [Grav](https://github.com/YunoHost-Apps/grav_ynh), [PluXml](https://github.com/YunoHost-Apps/pluxml_ynh) Però us proposem una alternativa una mica més potent: [CiviCRM on Drupal 7](https://github.com/YunoHost-Apps/civicrm_drupal7_ynh): -* Drupal és un entorn de treball potent de codi obert per la gestió de contingut -* amb CiviCRM que és un CRM de codi obert per a les organitzacions sense ànim de lucre + +- Drupal és un entorn de treball potent de codi obert per la gestió de contingut +- amb CiviCRM que és un CRM de codi obert per a les organitzacions sense ànim de lucre ### Adhesió @@ -162,40 +171,41 @@ YunoHost ofereix el seu propi sistema de còpies de seguretat. Abans de cada act Les còpies de seguretat de YunoHost s'emmagatzemen localment a `/home/yunohost.backup/archives`. Però per un servidor en producció, còpies de seguretat locals no són suficients, així que s'hauran d'implementar còpies de seguretat alternatives: -* Còpia de seguretat de la màquina virtual si ho permet el sistema d'allotjament. -* [Archivist](https://github.com/YunoHost-Apps/archivist_ynh) és un sistema de còpies de seguretat automàtiques del servidor. Les còpies de seguretat es poden enviar a d'altres llocs, locals o distants. -* [Borg](https://github.com/YunoHost-Apps/borg_ynh) i [Borg Server](https://github.com/YunoHost-Apps/borgserver_ynh) permeten externalitzar les còpies de seguretat. -* [Fallback](https://github.com/YunoHost-Apps/fallback_ynh), si teniu de servidors YunoHost, permet tenir un servidor secundari que pot ser utilitzat en cas que caigui el servidor principal. Aquest servidor secundari permetrà desplegar una còpia del servidor i tornar a posar en marxar YunoHost durant la caiguda. + +- Còpia de seguretat de la màquina virtual si ho permet el sistema d'allotjament. +- [Archivist](https://github.com/YunoHost-Apps/archivist_ynh) és un sistema de còpies de seguretat automàtiques del servidor. Les còpies de seguretat es poden enviar a d'altres llocs, locals o distants. +- [Borg](https://github.com/YunoHost-Apps/borg_ynh) i [Borg Server](https://github.com/YunoHost-Apps/borgserver_ynh) permeten externalitzar les còpies de seguretat. +- [Fallback](https://github.com/YunoHost-Apps/fallback_ynh), si teniu de servidors YunoHost, permet tenir un servidor secundari que pot ser utilitzat en cas que caigui el servidor principal. Aquest servidor secundari permetrà desplegar una còpia del servidor i tornar a posar en marxar YunoHost durant la caiguda. ### Anar més enllà #### Galeria de fotografies federada -* [Pixelfed](https://github.com/YunoHost-Apps/pixelfed_ynh) +- [Pixelfed](https://github.com/YunoHost-Apps/pixelfed_ynh) #### Galeria àudio federada -* [Reel2Bits](https://github.com/YunoHost-Apps/reel2bits_ynh) -* [Funkwhale](https://github.com/YunoHost-Apps/funkwhale_ynh) +- [Reel2Bits](https://github.com/YunoHost-Apps/reel2bits_ynh) +- [Funkwhale](https://github.com/YunoHost-Apps/funkwhale_ynh) #### Galeria vídeo federada -* [PeerTube](https://github.com/YunoHost-Apps/peertube_ynh) +- [PeerTube](https://github.com/YunoHost-Apps/peertube_ynh) #### Xarxa social federada -* [Mastodon](https://github.com/YunoHost-Apps/mastodon_ynh) -* [Pleroma](https://github.com/YunoHost-Apps/pleroma_ynh) -* [Mobilizon](https://github.com/YunoHost-Apps/mobilizon_ynh) - +- [Mastodon](https://github.com/YunoHost-Apps/mastodon_ynh) +- [Pleroma](https://github.com/YunoHost-Apps/pleroma_ynh) +- [Mobilizon](https://github.com/YunoHost-Apps/mobilizon_ynh) + #### Blog federat -* [Plume](https://github.com/YunoHost-Apps/plume_ynh) -* [Writefreely](https://github.com/YunoHost-Apps/writefreely_ynh) +- [Plume](https://github.com/YunoHost-Apps/plume_ynh) +- [Writefreely](https://github.com/YunoHost-Apps/writefreely_ynh) #### Xat -* [Mattermost](https://github.com/YunoHost-Apps/mattermost_ynh) +- [Mattermost](https://github.com/YunoHost-Apps/mattermost_ynh) ## Conclusió diff --git a/pages/04.applications/20.app_bundle/05.ngo/use_case_non-profit_organisations.fr.md b/pages/04.applications/20.app_bundle/05.ngo/use_case_non-profit_organisations.fr.md index 787d3112..086f574a 100644 --- a/pages/04.applications/20.app_bundle/05.ngo/use_case_non-profit_organisations.fr.md +++ b/pages/04.applications/20.app_bundle/05.ngo/use_case_non-profit_organisations.fr.md @@ -21,23 +21,23 @@ Organisations à but non lucratif, ONG ou tout type d'association. Les organisations à but non lucratif doivent généralement fournir différents services à différents publics : -* Conseil d'administration / Comité directeur / Bénévoles avec : - * [Mails](#mails) - * [Calendrier](#calendrier) - * [Contact](#contact) - * [Fichiers partagés / Drive](#fichiers-partag-s) - * [Communication instantanée](#communication-instantan-e) - * [Intranet / Base de connaissances](#intranet) - * [ERP / Comptabilité](#erp-comptabilit-) -* Membres avec : - * [Site Web public avec accès privé et individuel](#site-web-public) - * [Adhésion](#adh-sion) - * [Inscriptions aux événements](#inscriptions-aux-v-nements) - * [Mailings](#newsletter-mailing) - * [Forum](#forum) -* Public avec : - * [Site Web public](#site-web-public) - * [Newsletter](#newsletter-mailing) +- Conseil d'administration / Comité directeur / Bénévoles avec : + - [Mails](#mails) + - [Calendrier](#calendrier) + - [Contact](#contact) + - [Fichiers partagés / Drive](#fichiers-partag-s) + - [Communication instantanée](#communication-instantan-e) + - [Intranet / Base de connaissances](#intranet) + - [ERP / Comptabilité](#erp-comptabilit-) +- Membres avec : + - [Site Web public avec accès privé et individuel](#site-web-public) + - [Adhésion](#adh-sion) + - [Inscriptions aux événements](#inscriptions-aux-v-nements) + - [Mailings](#newsletter-mailing) + - [Forum](#forum) +- Public avec : + - [Site Web public](#site-web-public) + - [Newsletter](#newsletter-mailing) ## Quand @@ -46,9 +46,10 @@ Lorsque l'organisation à but non lucratif est prête à franchir le pas. ## Où Le serveur YunoHost peut être hébergé à différents endroits : -* Hébergement en propre sur un serveur, un ordinateur ou Raspberry derrière ADSL, SDSL ou Fibre -* [Chatons](https://chatons.org), [librehosters](https://framagit.org/librehosters/awesome-librehosters) -* Services d'hébergement commercial fournissant une machine virtuelle Debian + +- Hébergement en propre sur un serveur, un ordinateur ou Raspberry derrière ADSL, SDSL ou Fibre +- [Chatons](https://chatons.org), [librehosters](https://framagit.org/librehosters/awesome-librehosters) +- Services d'hébergement commercial fournissant une machine virtuelle Debian ## Pourquoi @@ -63,20 +64,21 @@ YunoHost est une distribution basée sur Debian GNU/Linux qui automatise l’ins ![](https://upload.wikimedia.org/wikipedia/commons/0/07/Yunohost_user_portal.png) YunoHost fournit immédiatement: -* Un système d'application -* Une interface Web -* Une interface de ligne de commande (CLI) : Moulinette -* Un serveur Web : NGINX -* Un serveur DNS : Dnsmasq -* Une base de données : MariaDB -* Un système de sauvegarde -* Un SSO : SSOwat -* OpenLDAP -* Email : - * SMTP : Postfix - * IMAP & POP3 : Dovecot - * Un antispam : rspamd, rmilter -* Serveur XMPP de messagerie instantanée : Metronome IM + +- Un système d'application +- Une interface Web +- Une interface de ligne de commande (CLI) : Moulinette +- Un serveur Web : NGINX +- Un serveur DNS : Dnsmasq +- Une base de données : MariaDB +- Un système de sauvegarde +- Un SSO : SSOwat +- OpenLDAP +- Email : + - SMTP : Postfix + - IMAP & POP3 : Dovecot + - Un antispam : rspamd, rmilter +- Serveur XMPP de messagerie instantanée : Metronome IM ### Nom de domaine @@ -88,21 +90,24 @@ YunoHost fournit par défaut un système de messagerie disponible en utilisant P Les comptes de messagerie seront gérés à l'aide de l'interface Web ou de la ligne de commande. Les comptes créés sont stockés dans OpenLDAP. Des packages supplémentaires peuvent être installés pour fournir davantage de fonctionnalités au système de messagerie YunoHost : -* un webmail en utilisant [Roundcube](https://github.com/YunoHost-Apps/roundcube_ynh), [Rainloop](https://github.com/YunoHost-Apps/rainloop_ynh) -* ActiveSync utilisant [Z-Push](https://github.com/YunoHost-Apps/z-push_ynh) -* Groupe de distribution interne en utilisant [Mailman](https://github.com/YunoHost-Apps/mailman_ynh) + +- un webmail en utilisant [Roundcube](https://github.com/YunoHost-Apps/roundcube_ynh), [Rainloop](https://github.com/YunoHost-Apps/rainloop_ynh) +- ActiveSync utilisant [Z-Push](https://github.com/YunoHost-Apps/z-push_ynh) +- Groupe de distribution interne en utilisant [Mailman](https://github.com/YunoHost-Apps/mailman_ynh) ### Calendrier Pour fournir des calendriers personnels ou partagés, vous devrez installer : -* [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh) -* [Baïkal](https://github.com/YunoHost-Apps/baikal_ynh) + +- [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh) +- [Baïkal](https://github.com/YunoHost-Apps/baikal_ynh) ### Contact Pour fournir un système de contact personnel, vous devrez installer : -* [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh) -* [Baïkal](https://github.com/YunoHost-Apps/baikal_ynh) + +- [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh) +- [Baïkal](https://github.com/YunoHost-Apps/baikal_ynh) ### Fichiers partagés @@ -114,30 +119,35 @@ Les fichiers seront disponibles à partir d'une interface Web ou à l'aide d'un Par défaut, YunoHost fournit immédiatement un serveur XMPP pour lequel vous pouvez installer un client Web : [Jappix](https://github.com/YunoHost-Apps/jappix_ynh) Vous pouvez également installer un serveur Matrix : -* Le serveur : [Synapse](https://github.com/YunoHost-Apps/synapse_ynh) -* Un client Web : [Element](https://github.com/YunoHost-Apps/element_ynh) + +- Le serveur : [Synapse](https://github.com/YunoHost-Apps/synapse_ynh) +- Un client Web : [Element](https://github.com/YunoHost-Apps/element_ynh) ### Intranet Pour une organisation à but non lucratif, un bon moyen de mettre en œuvre un intranet est de fournir un wiki permettant aux utilisateurs internes de lire, éditer et ajouter du contenu. Voici quelques paquets pour implémenter un wiki : -* [DokuWiki](https://github.com/YunoHost-Apps/docuwiki_ynh) utilisant une syntaxe wiki -* [Wiki.js](https://github.com/YunoHost-Apps/wikijs_ynh) utilisant une syntaxe Markdown + +- [DokuWiki](https://github.com/YunoHost-Apps/docuwiki_ynh) utilisant une syntaxe wiki +- [Wiki.js](https://github.com/YunoHost-Apps/wikijs_ynh) utilisant une syntaxe Markdown ### ERP / Comptabilité À un moment donné, une organisation à but non lucratif pourrait avoir besoin d’un système de Comptabilité / ERP, voici deux propositions : -* [OpenERP/Odoo](https://github.com/YunoHost-Apps/libreerp_ynh) -* [Dolibarr](https://github.com/YunoHost-Apps/dolibarr_ynh) + +- [OpenERP/Odoo](https://github.com/YunoHost-Apps/libreerp_ynh) +- [Dolibarr](https://github.com/YunoHost-Apps/dolibarr_ynh) ### Site Web Public Il existe plusieurs façons d'implémenter un site Web public : -* Un simple site HTML, CSS, etc. en utilisant : [Custom Webapp](https://github.com/YunoHost-Apps/my_webapp_ynh) -* Utiliser un CMS (système de gestion de contenu) comme [WordPress](https://github.com/YunoHost-Apps/_ynh), [Drupal](https://github.com/YunoHost-Apps/drupal_ynh), [Grav](https://github.com/YunoHost-Apps/grav_ynh), [PluXml](https://github.com/YunoHost-Apps/pluxml_ynh) + +- Un simple site HTML, CSS, etc. en utilisant : [Custom Webapp](https://github.com/YunoHost-Apps/my_webapp_ynh) +- Utiliser un CMS (système de gestion de contenu) comme [WordPress](https://github.com/YunoHost-Apps/_ynh), [Drupal](https://github.com/YunoHost-Apps/drupal_ynh), [Grav](https://github.com/YunoHost-Apps/grav_ynh), [PluXml](https://github.com/YunoHost-Apps/pluxml_ynh) Mais nous proposerons quelque chose de plus puissant : [CiviCRM on Drupal 7](https://github.com/YunoHost-Apps/civicrm_drupal7_ynh) : -* Drupal qui est un puissant framework de gestion de contenu -* avec CiviCRM qui est un CRM open source à destination des organisations à but non lucratif + +- Drupal qui est un puissant framework de gestion de contenu +- avec CiviCRM qui est un CRM open source à destination des organisations à but non lucratif #### Adhésion @@ -161,40 +171,41 @@ YunoHost fournit son propre système de sauvegarde. Avant toute mise à niveau d Les sauvegardes YunoHost sont stockées localement dans `/home/yunohost.backup/archives`. Mais pour la production, la sauvegarde stockée localement ne suffit pas, vous devez donc mettre en œuvre des stratégies de sauvegarde supplémentaires : -* Sauvegarde de la machine virtuelle si fournie par le système d'hébergement. -* [Archivist](https://github.com/YunoHost-Apps/archivist_ynh) est un système de sauvegarde automatique de votre serveur. Vos sauvegardes peuvent être envoyées à de nombreux autres endroits, locaux ou distants. -* [Borg](https://github.com/YunoHost-Apps/borg_ynh) and [Borg Server](https://github.com/YunoHost-Apps/borgserver_ynh) permettent d'externaliser les sauvegardes. -* [Fallback](https://github.com/YunoHost-Apps/fallback_ynh), si vous avez deux serveurs YunoHost, fournissez un moyen d'avoir un serveur secondaire que vous pourrez utiliser si votre serveur principal tombe en panne. Ce serveur secondaire vous permettra de déployer une copie de votre serveur pour ramener votre YunoHost lors de votre panne. + +- Sauvegarde de la machine virtuelle si fournie par le système d'hébergement. +- [Archivist](https://github.com/YunoHost-Apps/archivist_ynh) est un système de sauvegarde automatique de votre serveur. Vos sauvegardes peuvent être envoyées à de nombreux autres endroits, locaux ou distants. +- [Borg](https://github.com/YunoHost-Apps/borg_ynh) and [Borg Server](https://github.com/YunoHost-Apps/borgserver_ynh) permettent d'externaliser les sauvegardes. +- [Fallback](https://github.com/YunoHost-Apps/fallback_ynh), si vous avez deux serveurs YunoHost, fournissez un moyen d'avoir un serveur secondaire que vous pourrez utiliser si votre serveur principal tombe en panne. Ce serveur secondaire vous permettra de déployer une copie de votre serveur pour ramener votre YunoHost lors de votre panne. ### Aller plus loin #### Galerie de photos fédérées -* [Pixelfed](https://github.com/YunoHost-Apps/pixelfed_ynh) +- [Pixelfed](https://github.com/YunoHost-Apps/pixelfed_ynh) #### Galerie audio fédérée -* [Reel2Bits](https://github.com/YunoHost-Apps/reel2bits_ynh) -* [Funkwhale](https://github.com/YunoHost-Apps/funkwhale_ynh) +- [Reel2Bits](https://github.com/YunoHost-Apps/reel2bits_ynh) +- [Funkwhale](https://github.com/YunoHost-Apps/funkwhale_ynh) #### Galerie vidéo fédérée -* [PeerTube](https://github.com/YunoHost-Apps/peertube_ynh) +- [PeerTube](https://github.com/YunoHost-Apps/peertube_ynh) #### Réseaux sociaux fédérés -* [Mastodon](https://github.com/YunoHost-Apps/mastodon_ynh) -* [Pleroma](https://github.com/YunoHost-Apps/pleroma_ynh) -* [Mobilizon](https://github.com/YunoHost-Apps/mobilizon_ynh) +- [Mastodon](https://github.com/YunoHost-Apps/mastodon_ynh) +- [Pleroma](https://github.com/YunoHost-Apps/pleroma_ynh) +- [Mobilizon](https://github.com/YunoHost-Apps/mobilizon_ynh) #### Blog fédéré -* [Plume](https://github.com/YunoHost-Apps/plume_ynh) -* [Writefreely](https://github.com/YunoHost-Apps/writefreely_ynh) +- [Plume](https://github.com/YunoHost-Apps/plume_ynh) +- [Writefreely](https://github.com/YunoHost-Apps/writefreely_ynh) #### Chat -* [Mattermost](https://github.com/YunoHost-Apps/mattermost_ynh) +- [Mattermost](https://github.com/YunoHost-Apps/mattermost_ynh) ## Conclusion diff --git a/pages/04.applications/20.app_bundle/05.ngo/use_case_non-profit_organisations.md b/pages/04.applications/20.app_bundle/05.ngo/use_case_non-profit_organisations.md index e477d492..9df8645a 100644 --- a/pages/04.applications/20.app_bundle/05.ngo/use_case_non-profit_organisations.md +++ b/pages/04.applications/20.app_bundle/05.ngo/use_case_non-profit_organisations.md @@ -21,23 +21,23 @@ Non-profit organizations, NGO or any kind of association. Usually non-profit organizations need to provide several services to several publics: -* Board of Directors / Steering Committee / Volunteers with: - * [Mails](#mails) - * [Calendar](#calendar) - * [Contact](#contact) - * [Shared files / Drive](#shared-files) - * [Instant communication](#instant-communication) - * [Intranet / knowledge database](#intranet) - * [ERP / Accounting](#erp-accounting) -* Members with: - * [Public website with private and individual access](#public-web-site) - * [Membership](#membership) - * [Events registrations](#events-registrations) - * [Mailings](#newsletter-mailing) - * [Forum](#forum) -* Public with: - * [Public website](#public-web-site) - * [Newsletter](#newsletter-mailing) +- Board of Directors / Steering Committee / Volunteers with: + - [Mails](#mails) + - [Calendar](#calendar) + - [Contact](#contact) + - [Shared files / Drive](#shared-files) + - [Instant communication](#instant-communication) + - [Intranet / knowledge database](#intranet) + - [ERP / Accounting](#erp-accounting) +- Members with: + - [Public website with private and individual access](#public-web-site) + - [Membership](#membership) + - [Events registrations](#events-registrations) + - [Mailings](#newsletter-mailing) + - [Forum](#forum) +- Public with: + - [Public website](#public-web-site) + - [Newsletter](#newsletter-mailing) ## When @@ -46,9 +46,10 @@ When ready to move forward. ## Where You YunoHost for non profit can be hosted in several places: -* Own hosting on a server, computer or Raspberry behind ASDL, SDSL or Fiber -* [Chatons](https://chatons.org), [librehosters](https://framagit.org/librehosters/awesome-librehosters) hosting services -* Commercial hosting services providing Debian virtual machine + +- Own hosting on a server, computer or Raspberry behind ASDL, SDSL or Fiber +- [Chatons](https://chatons.org), [librehosters](https://framagit.org/librehosters/awesome-librehosters) hosting services +- Commercial hosting services providing Debian virtual machine ## Why @@ -64,20 +65,21 @@ YunoHost is a Debian GNU/Linux based distribution packaged with free software th ![](https://upload.wikimedia.org/wikipedia/commons/0/07/Yunohost_user_portal.png) Out of the box YunoHost provide: -* A system of application -* A web interface -* A command-line interface (CLI): Moulinette -* A web server: NGINX -* A DNS server: Dnsmasq -* A database: MariaDB -* A backup system -* An SSO: SSOwat -* OpenLDAP -* Email: - * SMTP: Postfix - * IMAP & POP3: Dovecot - * An antispam: rspamd,rmilter -* Instant messaging XMPP server: Metronome IM + +- A system of application +- A web interface +- A command-line interface (CLI): Moulinette +- A web server: NGINX +- A DNS server: Dnsmasq +- A database: MariaDB +- A backup system +- An SSO: SSOwat +- OpenLDAP +- Email: + - SMTP: Postfix + - IMAP & POP3: Dovecot + - An antispam: rspamd,rmilter +- Instant messaging XMPP server: Metronome IM ### Domain Name @@ -89,21 +91,24 @@ From scratch, YunoHost provide mail system available using POP/IMAP/SMTP. Mails accounts will be managed using the web interface or the command line. Created accounts are stored in OpenLDAP. Additional package can be installed to provide more functionality to the YunoHost mail system: -* Webmail using [Roundcube](https://github.com/YunoHost-Apps/roundcube_ynh), [Rainloop](https://github.com/YunoHost-Apps/rainloop_ynh) -* ActiveSync using [Z-Push](https://github.com/YunoHost-Apps/z-push_ynh) -* Internal distribution group using [Mailman](https://github.com/YunoHost-Apps/mailman_ynh) + +- Webmail using [Roundcube](https://github.com/YunoHost-Apps/roundcube_ynh), [Rainloop](https://github.com/YunoHost-Apps/rainloop_ynh) +- ActiveSync using [Z-Push](https://github.com/YunoHost-Apps/z-push_ynh) +- Internal distribution group using [Mailman](https://github.com/YunoHost-Apps/mailman_ynh) ### Calendar To provide personal or shared calendars you will need to install: -* [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh) -* [Baïkal](https://github.com/YunoHost-Apps/baikal_ynh) + +- [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh) +- [Baïkal](https://github.com/YunoHost-Apps/baikal_ynh) ### Contact To provide personal contact system you will need to install: -* [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh) -* [Baïkal](https://github.com/YunoHost-Apps/baikal_ynh) + +- [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh) +- [Baïkal](https://github.com/YunoHost-Apps/baikal_ynh) ### Shared files @@ -115,30 +120,35 @@ Files will be available from a web interface or using a synchronization client. Out of the box, YunoHost provide an XMPP server, for which you can install a web client: [Jappix](https://github.com/YunoHost-Apps/jappix_ynh). You can also install a matrix server: -* The server: [Synapse](https://github.com/YunoHost-Apps/synapse_ynh) -* A web client: [Element](https://github.com/YunoHost-Apps/element_ynh) + +- The server: [Synapse](https://github.com/YunoHost-Apps/synapse_ynh) +- A web client: [Element](https://github.com/YunoHost-Apps/element_ynh) ### Intranet For an non-profit organization a good way to implement an intranet is to provide a wiki to let internal users read, edit and add content. Here are some packages to implement a wiki: -* [DokuWiki](https://github.com/YunoHost-Apps/docuwiki_ynh) using wiki syntax -* [Wiki.js](https://github.com/YunoHost-Apps/wikijs_ynh) using Markdown syntax + +- [DokuWiki](https://github.com/YunoHost-Apps/docuwiki_ynh) using wiki syntax +- [Wiki.js](https://github.com/YunoHost-Apps/wikijs_ynh) using Markdown syntax ### ERP / Accounting At some time a non-profit organization could need an accounting/erp system, here are two propositions: -* [OpenERP/Odoo](https://github.com/YunoHost-Apps/libreerp_ynh) -* [Dolibarr](https://github.com/YunoHost-Apps/dolibarr_ynh) + +- [OpenERP/Odoo](https://github.com/YunoHost-Apps/libreerp_ynh) +- [Dolibarr](https://github.com/YunoHost-Apps/dolibarr_ynh) ### Public Web Site There are several way to implement a Public Web Site: -* Simple HTML, CSS, etc. Website using: [Custom Webapp](https://github.com/YunoHost-Apps/my_webapp_ynh) -* Using a CMS (Content Management System) like [WordPress](https://github.com/YunoHost-Apps/_ynh), [Drupal](https://github.com/YunoHost-Apps/drupal_ynh), [Grav](https://github.com/YunoHost-Apps/grav_ynh), [PluXml](https://github.com/YunoHost-Apps/pluxml_ynh) + +- Simple HTML, CSS, etc. Website using: [Custom Webapp](https://github.com/YunoHost-Apps/my_webapp_ynh) +- Using a CMS (Content Management System) like [WordPress](https://github.com/YunoHost-Apps/_ynh), [Drupal](https://github.com/YunoHost-Apps/drupal_ynh), [Grav](https://github.com/YunoHost-Apps/grav_ynh), [PluXml](https://github.com/YunoHost-Apps/pluxml_ynh) But we will propose something more powerful: [CiviCRM on Drupal 7](https://github.com/YunoHost-Apps/civicrm_drupal7_ynh): -* Drupal that is a powerful open source content management framework -* with CiviCRM that is an open source constituent relationship management for non-profits + +- Drupal that is a powerful open source content management framework +- with CiviCRM that is an open source constituent relationship management for non-profits #### Membership @@ -162,40 +172,41 @@ YunoHost provide is own backup system. Before any package upgrade, YunoHost back YunoHost backup are stored localy in `/home/yunohost.backup/archives`. But for production, localy stored backup are not enough, so you will need to implement aditional backup strategies: -* Backup of the the Virtual Machine if provided by the hosting system. -* [Archivist](https://github.com/YunoHost-Apps/archivist_ynh) is an automatic backup system for your server. Your backups can be send to many other places, local or distant. -* [Borg](https://github.com/YunoHost-Apps/borg_ynh) and [Borg Server](https://github.com/YunoHost-Apps/borgserver_ynh) allow to externalize backups. -* [Fallback](https://github.com/YunoHost-Apps/fallback_ynh), if you have two YunoHost servers, provide a way to have a secondary server which you can used if your main server goes down. This secondary server will allow you to deploy a copy of your server to bring back your YunoHost during your break down. + +- Backup of the the Virtual Machine if provided by the hosting system. +- [Archivist](https://github.com/YunoHost-Apps/archivist_ynh) is an automatic backup system for your server. Your backups can be send to many other places, local or distant. +- [Borg](https://github.com/YunoHost-Apps/borg_ynh) and [Borg Server](https://github.com/YunoHost-Apps/borgserver_ynh) allow to externalize backups. +- [Fallback](https://github.com/YunoHost-Apps/fallback_ynh), if you have two YunoHost servers, provide a way to have a secondary server which you can used if your main server goes down. This secondary server will allow you to deploy a copy of your server to bring back your YunoHost during your break down. ### Go further #### Federated Photo Gallery -* [Pixelfed](https://github.com/YunoHost-Apps/pixelfed_ynh) +- [Pixelfed](https://github.com/YunoHost-Apps/pixelfed_ynh) #### Federated Audio Gallery -* [Reel2Bits](https://github.com/YunoHost-Apps/reel2bits_ynh) -* [Funkwhale](https://github.com/YunoHost-Apps/funkwhale_ynh) +- [Reel2Bits](https://github.com/YunoHost-Apps/reel2bits_ynh) +- [Funkwhale](https://github.com/YunoHost-Apps/funkwhale_ynh) #### Federated Video Gallery -* [PeerTube](https://github.com/YunoHost-Apps/peertube_ynh) +- [PeerTube](https://github.com/YunoHost-Apps/peertube_ynh) #### Federated Social Networking -* [Mastodon](https://github.com/YunoHost-Apps/mastodon_ynh) -* [Pleroma](https://github.com/YunoHost-Apps/pleroma_ynh) -* [Mobilizon](https://github.com/YunoHost-Apps/mobilizon_ynh) +- [Mastodon](https://github.com/YunoHost-Apps/mastodon_ynh) +- [Pleroma](https://github.com/YunoHost-Apps/pleroma_ynh) +- [Mobilizon](https://github.com/YunoHost-Apps/mobilizon_ynh) #### Federated Blog -* [Plume](https://github.com/YunoHost-Apps/plume_ynh) -* [Writefreely](https://github.com/YunoHost-Apps/writefreely_ynh) +- [Plume](https://github.com/YunoHost-Apps/plume_ynh) +- [Writefreely](https://github.com/YunoHost-Apps/writefreely_ynh) #### Chat -* [Mattermost](https://github.com/YunoHost-Apps/mattermost_ynh) +- [Mattermost](https://github.com/YunoHost-Apps/mattermost_ynh) ## Conclusion diff --git a/pages/04.applications/20.app_bundle/05.ngo/use_case_non-profit_organisations.oc.md b/pages/04.applications/20.app_bundle/05.ngo/use_case_non-profit_organisations.oc.md index 842133bb..b46ed05d 100644 --- a/pages/04.applications/20.app_bundle/05.ngo/use_case_non-profit_organisations.oc.md +++ b/pages/04.applications/20.app_bundle/05.ngo/use_case_non-profit_organisations.oc.md @@ -21,23 +21,23 @@ Organizacions sens tòca lucrativa, ONG o qualque siá associacion. Las organizacions sens tòca lucrativa devon generalament fornir diferents servicis a diferents publics : -* Conselh d'administracion / Comitat director / Benevòls amb : - * [Mails](#mails) - * [Calendièr](#calendièr) - * [Contacte](#contacte) - * [Fichièrs partejats / Drive](#fichièrs-partejats) - * [Comunicacion instantanèa](#comunicacion-instantan-a) - * [Intranet / Basa de coneissenças](#intranet) - * [ERP / Comptabilitat](#erp-comptabilitat) -* Membres amb : - * [Site Web public amb accès privat e individual](#site-web-public) - * [Adhesion](#adhesion) - * [Inscripcions als eveniments](#inscriptions-als-eveniments) - * [Infoletras](#infoletras) - * [Forum](#forum) -* Public amb : - * [Site Web public](#site-web-public) - * [Infoletras](#newsletter-mailing) +- Conselh d'administracion / Comitat director / Benevòls amb : + - [Mails](#mails) + - [Calendièr](#calendièr) + - [Contacte](#contacte) + - [Fichièrs partejats / Drive](#fichièrs-partejats) + - [Comunicacion instantanèa](#comunicacion-instantan-a) + - [Intranet / Basa de coneissenças](#intranet) + - [ERP / Comptabilitat](#erp-comptabilitat) +- Membres amb : + - [Site Web public amb accès privat e individual](#site-web-public) + - [Adhesion](#adhesion) + - [Inscripcions als eveniments](#inscriptions-als-eveniments) + - [Infoletras](#infoletras) + - [Forum](#forum) +- Public amb : + - [Site Web public](#site-web-public) + - [Infoletras](#newsletter-mailing) ## Quand @@ -46,9 +46,10 @@ Quand l'organizacion sens tòca lucrativa es prèsta a passar lo pas. ## Ont Lo servidor YunoHost pòt èsser albergat a diferents endreches : -* Albergament en pròpri sus un servidor, un ordenador o Raspberry darrièr una connexion ADSL, SDSL o Fibra -* [Chatons](https://chatons.org), [librehosters](https://framagit.org/librehosters/awesome-librehosters) -* Servicis d'albergament comercial que fornís una maquina virtuala Debian + +- Albergament en pròpri sus un servidor, un ordenador o Raspberry darrièr una connexion ADSL, SDSL o Fibra +- [Chatons](https://chatons.org), [librehosters](https://framagit.org/librehosters/awesome-librehosters) +- Servicis d'albergament comercial que fornís una maquina virtuala Debian ## Perque @@ -63,20 +64,21 @@ YunoHost es una distribucion basada sus Debian GNU/Linux qu’automatiza l’ins ![](https://upload.wikimedia.org/wikipedia/commons/0/07/Yunohost_user_portal.png) YunoHost provesís sul pic: -* Un sistèma d'aplicacion -* Una interfàcia web -* Una interfàcia en linha de comanda (CLI) : Moulinette -* Un servidor Web : NGINX -* Un servidor DNS : Dnsmasq -* Una basa de donadas : MariaDB -* Un sistèma de salvagarda -* Un SSO: SSOwat -* OpenLDAP -* Corrièls : - * SMTP: Postfix - * IMAP & POP3 : Dovecot - * Un antispam : rspamd, rmilter -* Servidor XMPP de messatjariá instantanèa : Metronome IM + +- Un sistèma d'aplicacion +- Una interfàcia web +- Una interfàcia en linha de comanda (CLI) : Moulinette +- Un servidor Web : NGINX +- Un servidor DNS : Dnsmasq +- Una basa de donadas : MariaDB +- Un sistèma de salvagarda +- Un SSO: SSOwat +- OpenLDAP +- Corrièls : + - SMTP: Postfix + - IMAP & POP3 : Dovecot + - Un antispam : rspamd, rmilter +- Servidor XMPP de messatjariá instantanèa : Metronome IM ### Nom de domeni @@ -88,21 +90,24 @@ A la prima installacion YunoHost fornís un sistèma de messatjariá disponible Los comptes de messatjariá seràn gerits amb l'interfàcia Web o en linha de comanda. Los comptes creats seràn gardats dins l’OpenLDAP. De paquets suplementaris pòdon èsser installats per provesir mai de foncionalitats al sistèma de messatjariá YunoHost : -* un webmail en utilizant [Roundcube](https://github.com/YunoHost-Apps/roundcube_ynh), [Rainloop](https://github.com/YunoHost-Apps/rainloop_ynh) -* ActiveSync utilizant [Z-Push](https://github.com/YunoHost-Apps/z-push_ynh) -* Grop de distribucion intèrne en utilizant [Mailman](https://github.com/YunoHost-Apps/mailman_ynh) + +- un webmail en utilizant [Roundcube](https://github.com/YunoHost-Apps/roundcube_ynh), [Rainloop](https://github.com/YunoHost-Apps/rainloop_ynh) +- ActiveSync utilizant [Z-Push](https://github.com/YunoHost-Apps/z-push_ynh) +- Grop de distribucion intèrne en utilizant [Mailman](https://github.com/YunoHost-Apps/mailman_ynh) ### Calendièr Per fornir de calendièrs personals o partejats, vos calrà installar : -* [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh) -* [Baïkal](https://github.com/YunoHost-Apps/baikal_ynh) + +- [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh) +- [Baïkal](https://github.com/YunoHost-Apps/baikal_ynh) ### Contacte Per fornir un sistèma de contacte personal, vos caldrà installar : -* [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh) -* [Baikal](https://github.com/YunoHost-Apps/baikal_ynh) + +- [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh) +- [Baikal](https://github.com/YunoHost-Apps/baikal_ynh) ### Fichièrs partejats @@ -114,30 +119,35 @@ Las fichièrs seràn disponibles d’una interfàcia web estant o amb un client Tras l’installacion YunoHost fornís sul pic un servidor XMPP per lo qual podètz installar un client Web : [Jappix](https://github.com/YunoHost-Apps/jappix_ynh) Podètz tanben installar un servidor Matrix : -* Lo servidor: [Synapse](https://github.com/YunoHost-Apps/synapse_ynh) -* Un client web: [Riot](https://github.com/YunoHost-Apps/riot_ynh) + +- Lo servidor: [Synapse](https://github.com/YunoHost-Apps/synapse_ynh) +- Un client web: [Riot](https://github.com/YunoHost-Apps/riot_ynh) ### Intranet Per una organizacion sens tòca lucrativa, un bon biais de metre en plaça un intranet es de fornir un wiki que permet als utilizaires intèrne de legir, modificar e ajustar de contengut. Vaquí unes paquets per installar un wiki : -* [DokuWiki](https://github.com/YunoHost-Apps/docuwiki_ynh) utiliza la sintaxi wiki -* [Wiki.js](https://github.com/YunoHost-Apps/wikijs_ynh) utiliza la sintaxi markdown + +- [DokuWiki](https://github.com/YunoHost-Apps/docuwiki_ynh) utiliza la sintaxi wiki +- [Wiki.js](https://github.com/YunoHost-Apps/wikijs_ynh) utiliza la sintaxi markdown ### ERP / Comptabilitat Arriba un moment ont a l’organizacion sens tòca lucrativa li pòsca far besonh un sistèma de comptabilitat / ERP, vaquí doas proposicions : -* [OpenERP/Odoo](https://github.com/YunoHost-Apps/libreerp_ynh) -* [Dolibarr](https://github.com/YunoHost-Apps/dolibarr_ynh) + +- [OpenERP/Odoo](https://github.com/YunoHost-Apps/libreerp_ynh) +- [Dolibarr](https://github.com/YunoHost-Apps/dolibarr_ynh) ### Site Web Public Existís mantuns biaisses de construire un site Web public : -* Un simple site HTML, CSS, etc. en utilizant : [Custom Webapp](https://github.com/YunoHost-Apps/my_webapp_ynh) -* Utilizar un CMS (sistèma de gestion de contengut) coma [Wordpress](https://github.com/YunoHost-Apps/_ynh), [Drupal](https://github.com/YunoHost-Apps/drupal_ynh), [Grav](https://github.com/YunoHost-Apps/grav_ynh), [PluXml](https://github.com/YunoHost-Apps/pluxml_ynh) + +- Un simple site HTML, CSS, etc. en utilizant : [Custom Webapp](https://github.com/YunoHost-Apps/my_webapp_ynh) +- Utilizar un CMS (sistèma de gestion de contengut) coma [Wordpress](https://github.com/YunoHost-Apps/_ynh), [Drupal](https://github.com/YunoHost-Apps/drupal_ynh), [Grav](https://github.com/YunoHost-Apps/grav_ynh), [PluXml](https://github.com/YunoHost-Apps/pluxml_ynh) Mas prepausam quicòm de mai potent : [CiviCRM on Drupal 7](https://github.com/YunoHost-Apps/civicrm_drupal7_ynh) : -* Drupal qu’es un framework potent de gestion de contengut -* amb CiviCRM qu’es un CRM OpenSource a destinacion de las organizacions sens tòca lucrativa + +- Drupal qu’es un framework potent de gestion de contengut +- amb CiviCRM qu’es un CRM OpenSource a destinacion de las organizacions sens tòca lucrativa #### Adhesion @@ -161,40 +171,41 @@ YunoHost fornís son pròpri sistèma de salvagarda. Abans tota mesa a nivèl de Las salvagardas YunoHost son gardadas localament dins `/home/yunohost.backup/archives`. Mas per la produccion, la salvagarda gardada localament basta pas, vos cal emplegar d’estrategias de salvagarda suplementàrias : -* Salvagarda de la maquina virtuala se fornida pel sistèma d’albergament. -* [Archivist](https://github.com/YunoHost-Apps/archivist_ynh) es un sistèma de salvagarda automatic de vòstre servidor. Vòstras salvagardas pòdon èsser enviadas a mantun endreches, locals o alonhats. -* [Borg](https://github.com/YunoHost-Apps/borg_ynh) e [Borg Server](https://github.com/YunoHost-Apps/borgserver_ynh) permeton d’externalizar las salvagardas. -* [Fallback](https://github.com/YunoHost-Apps/fallback_ynh), se avètz dos servidors YunoHost, ajatz los mejans d’aver un servidor segondari que poiretz utilizar se lo primièr ven a foncionar pas mai. Aqueste servidor segondari vos permetrà de restablir una còpia de vòstre servidor per dire de corregir los problèmas de l’autre servidor YunoHost. + +- Salvagarda de la maquina virtuala se fornida pel sistèma d’albergament. +- [Archivist](https://github.com/YunoHost-Apps/archivist_ynh) es un sistèma de salvagarda automatic de vòstre servidor. Vòstras salvagardas pòdon èsser enviadas a mantun endreches, locals o alonhats. +- [Borg](https://github.com/YunoHost-Apps/borg_ynh) e [Borg Server](https://github.com/YunoHost-Apps/borgserver_ynh) permeton d’externalizar las salvagardas. +- [Fallback](https://github.com/YunoHost-Apps/fallback_ynh), se avètz dos servidors YunoHost, ajatz los mejans d’aver un servidor segondari que poiretz utilizar se lo primièr ven a foncionar pas mai. Aqueste servidor segondari vos permetrà de restablir una còpia de vòstre servidor per dire de corregir los problèmas de l’autre servidor YunoHost. ### Anar mai luènh #### Galariá de fotografias federada -* [Pixelfed](https://github.com/YunoHost-Apps/pixelfed_ynh) +- [Pixelfed](https://github.com/YunoHost-Apps/pixelfed_ynh) #### Galariá àudio federada -* [Reel2Bits](https://github.com/YunoHost-Apps/reel2bits_ynh) -* [Funkwhale](https://github.com/YunoHost-Apps/funkwhale_ynh) +- [Reel2Bits](https://github.com/YunoHost-Apps/reel2bits_ynh) +- [Funkwhale](https://github.com/YunoHost-Apps/funkwhale_ynh) #### Galariá vidèo federada -* [PeerTube](https://github.com/YunoHost-Apps/peertube_ynh) +- [PeerTube](https://github.com/YunoHost-Apps/peertube_ynh) #### Malhums socials federats -* [Mastodon](https://github.com/YunoHost-Apps/mastodon_ynh) -* [Pleroma](https://github.com/YunoHost-Apps/pleroma_ynh) -* [Mobilizon](https://github.com/YunoHost-Apps/mobilizon_ynh) +- [Mastodon](https://github.com/YunoHost-Apps/mastodon_ynh) +- [Pleroma](https://github.com/YunoHost-Apps/pleroma_ynh) +- [Mobilizon](https://github.com/YunoHost-Apps/mobilizon_ynh) #### Blog federats -* [Plume](https://github.com/YunoHost-Apps/plume_ynh) -* [Writefreely](https://github.com/YunoHost-Apps/writefreely_ynh) +- [Plume](https://github.com/YunoHost-Apps/plume_ynh) +- [Writefreely](https://github.com/YunoHost-Apps/writefreely_ynh) #### Chat -* [Mattermost](https://github.com/YunoHost-Apps/mattermost_ynh) +- [Mattermost](https://github.com/YunoHost-Apps/mattermost_ynh) ## Conclusion diff --git a/pages/04.applications/20.app_bundle/app_bundle.md b/pages/04.applications/20.app_bundle/app_bundle.md index 52d238b4..0d5fa4a5 100644 --- a/pages/04.applications/20.app_bundle/app_bundle.md +++ b/pages/04.applications/20.app_bundle/app_bundle.md @@ -9,4 +9,4 @@ routes: ! TODO: this page needs to be written -This page aims to list app bundles to answer to typical use cases. \ No newline at end of file +This page aims to list app bundles to answer to typical use cases. diff --git a/pages/05.community/10.chat_rooms/chat_rooms.es.md b/pages/05.community/10.chat_rooms/chat_rooms.es.md index 06331a9a..01509c6a 100644 --- a/pages/05.community/10.chat_rooms/chat_rooms.es.md +++ b/pages/05.community/10.chat_rooms/chat_rooms.es.md @@ -10,37 +10,43 @@ routes: El proyecto YunoHost utiliza salas de chat como medio de communicación. Puede unirse a una sala de chat utilizando : + - un [cliente IRC](https://es.wikipedia.org/wiki/Anexo:Clientes_IRC) por ejemplo [KiwiIRC](https://web.libera.chat/#yunohost) - un [cliente XMPP](https://es.wikipedia.org/wiki/Anexo:Comparaci%C3%B3n_de_clientes_de_mensajer%C3%ADa_instant%C3%A1nea) - un [cliente Matrix](https://matrix.org/docs/guides/faq.html#what-clients-are-available%3F) - #### Sala de chat de ayuda y soporte Existen salas publicas de chat de [soporte](/help) y ayuda para YunoHost: -- IRC: **#yunohost** on libera.chat ; -- Matrix: **[#yunohost:matrix.org](https://matrix.to/#/#yunohost:matrix.org)** ; -- XMPP: **[support@conference.yunohost.org](xmpp:support@conference.yunohost.org?join)** + +- IRC: **`#yunohost`** on libera.chat ; +- Matrix: **[`#yunohost:matrix.org`](https://matrix.to/#/#yunohost:matrix.org)** ; +- XMPP: **[`support@conference.yunohost.org`](xmpp:support@conference.yunohost.org?join)** #### sala de chat para desarrolladores Salas de chat para el desarollo de YunoHost: -- IRC: **#yunohost-dev** on libera.chat ; -- Matrix: **#[yunohost-dev:matrix.org](https://matrix.to/#/#yunohost-dev:libera.chat)** ; -- XMPP: **[dev@conference.yunohost.org](xmpp:dev@conference.yunohost.org?join)** + +- IRC: **`#yunohost-dev`** on libera.chat ; +- Matrix: **#[`yunohost-dev:matrix.org`](https://matrix.to/#/#yunohost-dev:libera.chat)** ; +- XMPP: **[`dev@conference.yunohost.org`](xmpp:dev@conference.yunohost.org?join)** Actualmente, la sala principal de chat para contribuciones en YunoHost -Para mas ayuda, vea la sala de chat **#yunohost** encima. +Para mas ayuda, vea la sala de chat **`#yunohost`** encima. #### Sala de chat para las integración de aplicaciones -Estos permite la ayuda mutua para los integradores de aplicaciones y también para conversar de evoluciones et de herramientas de integración continua. -- IRC: **#yunohost-apps** en libera.chat -- Matrix: **[#yunohost-apps:matrix.org](https://matrix.to/#/#yunohost-apps:matrix.org)** -- XMPP: **[apps@conference.yunohost.org](xmpp:apps@conference.yunohost.org?join)** -#### Sala de chat de Documentación +Estos permite la ayuda mutua para los integradores de aplicaciones y también para conversar de evoluciones et de herramientas de integración continua. + +- IRC: **`#yunohost-apps`** en libera.chat +- Matrix: **[`#yunohost-apps:matrix.org`](https://matrix.to/#/#yunohost-apps:matrix.org)** +- XMPP: **[`apps@conference.yunohost.org`](xmpp:apps@conference.yunohost.org?join)** + +#### Sala de chat de Documentación + Lugar donde la comunidad conversa sincroniza y mantiene actualisado la documentación en los aspectos varios como (backend, frontend, apps, proyecto, comunidad...) Puede tambien compartir sus materiales sobre YunoHost (videos, presentaciones, etc.). -- IRC: **#yunohost-doc** on libera.chat -- Matrix: **[#yunohost-doc:matrix.org](https://matrix.to/#/#yunohost-doc:matrix.org)** -- XMPP: **[doc@conference.yunohost.org](xmpp:doc@conference.yunohost.org?join)** + +- IRC: **`#yunohost-doc`** on libera.chat +- Matrix: **[`#yunohost-doc:matrix.org`](https://matrix.to/#/#yunohost-doc:matrix.org)** +- XMPP: **[`doc@conference.yunohost.org`](xmpp:doc@conference.yunohost.org?join)** diff --git a/pages/05.community/10.chat_rooms/chat_rooms.fr.md b/pages/05.community/10.chat_rooms/chat_rooms.fr.md index f91c5e50..d292c7c0 100644 --- a/pages/05.community/10.chat_rooms/chat_rooms.fr.md +++ b/pages/05.community/10.chat_rooms/chat_rooms.fr.md @@ -10,36 +10,44 @@ routes: Parmi d’autres outils, le projet YunoHost se sert de salons de discussions pour communiquer. Vous pouvez rejoindre ces salons avec : + - un [Client IRC](https://fr.wikipedia.org/wiki/Liste_de_clients_IRC) par exemple [KiwiIRC](https://web.libera.chat/#yunohost) - un [Client XMPP](https://fr.wikipedia.org/wiki/Clients_XMPP) - un [Client Matrix](https://linuxfr.org/news/matrix-pour-decentraliser-skype-whatsapp-signal-slack-et-discord) - #### Salon d'entraide et de support + Le salon d’[entraide](/help) est là pour permettre aux utilisateurs de YunoHost de s'aider mutuellement. -- IRC : **#yunohost** sur libera.chat (voir KiwiIRC ci-dessus) -- Matrix : **[#yunohost:matrix.org](https://matrix.to/#/#yunohost:matrix.org)** -- XMPP : **[support@conference.yunohost.org](xmpp:support@conference.yunohost.org?join)** + +- IRC : **`#yunohost`** sur libera.chat (voir KiwiIRC ci-dessus) +- Matrix : **[`#yunohost:matrix.org`](https://matrix.to/#/#yunohost:matrix.org)** +- XMPP : **[`support@conference.yunohost.org`](xmpp:support@conference.yunohost.org?join)** #### Développement + Salon de développement du cœur de YunoHost : -- IRC : **#yunohost-dev** sur libera.chat -- Matrix : **[#yunohost-dev:matrix.org](https://matrix.to/#/#yunohost-dev:matrix.org)** -- XMPP : **[dev@conference.yunohost.org](xmpp:dev@conference.yunohost.org?join)** + +- IRC : **`#yunohost-dev`** sur libera.chat +- Matrix : **[`#yunohost-dev:matrix.org`](https://matrix.to/#/#yunohost-dev:matrix.org)** +- XMPP : **[`dev@conference.yunohost.org`](xmpp:dev@conference.yunohost.org?join)** C'est le salon principal pour les contributions autour du projet. Pour chercher de l’aide, merci d'aller sur le salon d’entraide ci-dessus. #### Applications + Salon de développement du packaging d’application. Il permet aux packageurs de s’entraider. Il sert également à discuter de l’évolution du packaging, des outils d’intégration continue sur les applications. -- IRC : **#yunohost-apps** sur libera.chat -- Matrix : **[#yunohost-apps:matrix.org](https://matrix.to/#/#yunohost-apps:matrix.org)** -- XMPP : **[apps@conference.yunohost.org](xmpp:apps@conference.yunohost.org?join)** + +- IRC : **`#yunohost-apps`** sur libera.chat +- Matrix : **[`#yunohost-apps:matrix.org`](https://matrix.to/#/#yunohost-apps:matrix.org)** +- XMPP : **[`apps@conference.yunohost.org`](xmpp:apps@conference.yunohost.org?join)** #### Documentation + Le salon de documentation du projet YunoHost. Il permet aux contributeurs d'échanger, pour synchroniser et maintenir une documentation à jour sur les différents aspects du projet : backend, frontend, apps, projet, communauté... Vous pouvez aussi y partager vos communications au public à propos de YunoHost (présentations, vidéos...) pour permettre leur référencement dans la documentation. -- IRC : **#yunohost-doc** sur libera.chat -- Matrix : **[#yunohost-doc:matrix.org](https://matrix.to/#/#yunohost-doc:matrix.org)** -- XMPP : **[doc@conference.yunohost.org](xmpp:doc@conference.yunohost.org?join)** + +- IRC : **`#yunohost-doc`** sur libera.chat +- Matrix : **[`#yunohost-doc:matrix.org`](https://matrix.to/#/#yunohost-doc:matrix.org)** +- XMPP : **[`doc@conference.yunohost.org`](xmpp:doc@conference.yunohost.org?join)** diff --git a/pages/05.community/10.chat_rooms/chat_rooms.md b/pages/05.community/10.chat_rooms/chat_rooms.md index 72863030..3799f0ad 100644 --- a/pages/05.community/10.chat_rooms/chat_rooms.md +++ b/pages/05.community/10.chat_rooms/chat_rooms.md @@ -10,6 +10,7 @@ routes: Among other communication tools, YunoHost project use chat rooms to communicate. You could join those chat rooms using: + - an [IRC Client](https://en.wikipedia.org/wiki/Comparison_of_Internet_Relay_Chat_clients) for example [KiwiIRC](https://web.libera.chat/#yunohost) - an [XMPP client](https://en.wikipedia.org/wiki/Comparison_of_instant_messaging_clients) - a [Matrix client](https://matrix.org/docs/guides/faq.html#what-clients-are-available%3F) @@ -20,31 +21,36 @@ You could join those chat rooms using: There is a [support](/help) chat room for YunoHost users mutual support and help. -- IRC: **#yunohost** on libera.chat -- Matrix: **[#yunohost:matrix.org](https://matrix.to/#/#yunohost:matrix.org)** -- XMPP: **[support@conference.yunohost.org](xmpp:support@conference.yunohost.org?join)** +- IRC: **`#yunohost`** on libera.chat +- Matrix: **[`#yunohost:matrix.org`](https://matrix.to/#/#yunohost:matrix.org)** +- XMPP: **[`support@conference.yunohost.org`](xmpp:support@conference.yunohost.org?join)** #### Development chat room YunoHost core development chat room: -- IRC: **#yunohost-dev** on libera.chat -- Matrix: **[#yunohost-dev:matrix.org](https://matrix.to/#/#yunohost-dev:matrix.org)** -- XMPP: **[dev@conference.yunohost.org](xmpp:dev@conference.yunohost.org?join)** + +- IRC: **`#yunohost-dev`** on libera.chat +- Matrix: **[`#yunohost-dev:matrix.org`](https://matrix.to/#/#yunohost-dev:matrix.org)** +- XMPP: **[`dev@conference.yunohost.org`](xmpp:dev@conference.yunohost.org?join)** Currently, the main chat room for contributions on YunoHost project. -For help, please see **#yunohost** chat room above. +For help, please see **`#yunohost`** chat room above. #### Applications chat room + Application packaging development chat room. It allow packagers to help each other. It also allow to discuss packaging evolution, continuous integration tools: -- IRC: **#yunohost-apps** on libera.chat -- Matrix: **[#yunohost-apps:matrix.org](https://matrix.to/#/#yunohost-apps:matrix.org)** -- XMPP: **[apps@conference.yunohost.org](xmpp:apps@conference.yunohost.org?join)** + +- IRC: **`#yunohost-apps`** on libera.chat +- Matrix: **[`#yunohost-apps:matrix.org`](https://matrix.to/#/#yunohost-apps:matrix.org)** +- XMPP: **[`apps@conference.yunohost.org`](xmpp:apps@conference.yunohost.org?join)** #### Documentation chat room -YunoHost project documentation chat room. It allow people to discuss, synchronize and maintain + +YunoHost project documentation chat room. It allow people to discuss, synchronize and maintain an up-to-date documentation on the differents aspects of the project (backend, frontend, apps, project, community...). You may also share here your public communications about YunoHost (videos, presentations, etc.), to allow proper referencing. -- IRC: **#yunohost-doc** on libera.chat -- Matrix: **[#yunohost-doc:matrix.org](https://matrix.to/#/#yunohost-doc:matrix.org)** -- XMPP: **[doc@conference.yunohost.org](xmpp:doc@conference.yunohost.org?join)** + +- IRC: **`#yunohost-doc`** on libera.chat +- Matrix: **[`#yunohost-doc:matrix.org`](https://matrix.to/#/#yunohost-doc:matrix.org)** +- XMPP: **[`doc@conference.yunohost.org`](xmpp:doc@conference.yunohost.org?join)** diff --git a/pages/05.community/15.help/help.it.md b/pages/05.community/15.help/help.it.md index 54426b7c..6b6c0446 100644 --- a/pages/05.community/15.help/help.it.md +++ b/pages/05.community/15.help/help.it.md @@ -59,4 +59,3 @@ document.getElementById("goDevroom").onclick = function() { window.location.href = "https://web.libera.chat/#yunohost-dev"; } - diff --git a/pages/05.community/15.help/help.md b/pages/05.community/15.help/help.md index 35df1a73..b43d63b7 100644 --- a/pages/05.community/15.help/help.md +++ b/pages/05.community/15.help/help.md @@ -34,7 +34,7 @@ Please change your username, as we got legions of `ynhuser`s. !!! - IRC (`#yunohost` on libera.chat, [using kiwiirc](https://web.libera.chat/#yunohost)) !!! - XMPP (`support@conference.yunohost.org`) -## ... or ask on the forum ! +## ... or ask on the forum! Please follow the Support section post template. It helps everyone understand the context of your request. @@ -42,7 +42,7 @@ Please follow the Support section post template. It helps everyone understand th [[fa=comment /] Go to the forum](https://forum.yunohost.org/?target=_blank&classes=btn,btn-lg,btn-success) [/center] -## You've found a bug ? +## You've found a bug? !!!! Please report bugs on our bugtrackers or contact the developers diff --git a/pages/05.community/20.faq/faq.de.md b/pages/05.community/20.faq/faq.de.md index 5a066f24..739bf3af 100644 --- a/pages/05.community/20.faq/faq.de.md +++ b/pages/05.community/20.faq/faq.de.md @@ -15,7 +15,6 @@ YunoHost basiert auf Debian, also auch auf Lizenzen von Debian Bestandteilen. Die Anwendungen und Applikations-Pakete stehen unter ihren jeweiligen, eigenen Lizenzen. - #### Was ist das Ziel von YunoHost ? Wir glauben, dass Dezentralisierung sowie Kontrolle und Verantwortung über die eigenen Daten und Dienste ein wichtiger Bestandteil einer freien und demokratischen Gesellschaft ist. @@ -24,7 +23,6 @@ Das YunoHost Projekt zielt darauf ab, eigenverantwortliches Hosting zu demokrati Wir bieten eine Software an, die es für jeden möglichst einfach machen soll, einen eigenen Server zu betreiben und zu verwalten - mit einem minimalen Aufwand an Wissen und Zeit. - #### Aber was *macht* YunoHost überhaupt ? YunoHost könnte eine Distribution oder ein Betriebssystem genannt werden, aber es ist eigentlich "nur" eine Ebene, die über Debian betrieben wird und welche die meiste, schwierige Arbeit für Sie übernimmt. @@ -33,23 +31,19 @@ Zum Beispiel, wenn Sie Wordpress installieren möchten, müssten Sie einige Befe Mehr Informationen finden Sie [hier](/whatsyunohost) ! - #### Kann ich meine eigene, persönliche Internetseite mit YunoHost betreiben ? Ja ! Werfen Sie einen Blick auf die [Custom Web app](https://github.com/YunoHost-Apps/my_webapp_ynh). Dort erhalten Sie ein "leeres Gefäß" : nach der Installation, laden Sie einfach Ihre Dateien and den jeweiligen Ort hoch (via SSH/SCP or SFTP). PHP und eine SQL Datenbank steht Ihnen bei Bedarf zur Verfügung. - #### Kann ich viele voneinander unabhängige Internetseiten mit unterschiedlichen Domain-Namen betreiben ? Ja ! YunoHost ermöglicht das Anlegen mehrerer Benutzer und Domain-Namen. Manche Apllikationen wie *WordPress* oder *Web App Multi Custom* sind mehrinstanzenfähig und können mehrmals installiert werden. - #### Wieso kann ich Anwendungen nicht über die IP-Adresse erreichen ? Die [SSO](https://github.com/Kloadut/SSOwat/) (Single Sign-on) Technik kann Benutzer nicht richtig authentifizieren, wenn sie auf den Server nur über die IP zugreifen. Wenn Sie keine Möglichkeit haben, die DNS korrekt zu konfigurieren, können Sie als temporäre Notlösung [die `Hosts` Datei (letztes §)](/dns_local_network) auf Ihrem Computer modifizieren. - #### Was ist das Geschäftsmodell von YunoHost ? Momentan wird YunoHost nur von Freiwiligen betrieben, die in ihrer Freizeit an dem Projekt arbeiten. Im Grunde ist bisher kein Geld im Spiel (abgesehen von Serverkosten oder Stickern :P). @@ -58,7 +52,6 @@ Vor dem Hintergrund, dass einige Mitwirkende sehr viel zeit in das Projekt inves Dies könnte durch Spenden oder öffentliche Gelder erricht werden. Einige Mitwirkenden arbeiten an professionellen Angeboten in Zusammenhang mit YunoHost. - #### Kann ich für das Projekt spenden ? Ja, das können Sie ! YunoHost braucht Geld, um die Server und Domain-Namen zu bezahlen. Wir möchten außerdem erreichen, dass die Mitwirkenden weiterhin zum Projekt beitragen können und sich nicht nach anderen Jobs umschauen müssen. @@ -67,7 +60,6 @@ Sie können [auf Liberapay spenden](https://liberapay.com/yunohost). Wenn Ihnen das möglich ist, können Sie auch gerne Sachspenden leisten (ein Teil unserer Infrastruktur ist auf Server von Dritten angewiesen). - #### Wie kann ich zum Projekt beitragen ? Es gibt viele Wege [zum Projekt beizutragen](/contribute) :). @@ -76,12 +68,10 @@ Zögern Sie nicht, mit uns über Ihre Ideen zu sprechen! Es ist ein weit verbreitetes Missverständnis, dass Neulinge bei offenen Softwareprojekten nicht "ausreichend qualifiziert" sind. Wer ist das schon :) ? Was wirklich zählt, ist, [dass Sie mögen, was Sie tun](https://www.youtube.com/watch?v=zIbR5TAz2xQ&t=113s), nett zu anderen Menschen, geduldig und starrköpfig gegenüber Maschinen sind und etwas freie Zeit haben. Abgesehen davon ist einfach alles was Sie tun können, schon mehr als genug! - #### Was sind YunoHost organisatorische Grundsätze ? Das beschreiben wir in [diesem Dokument](/project_organization) :). - #### Werdet ihr YunoHosts für [Lieblingsdistribution hier einfügen] portieren ? Die kurze Antwort: Nein. Wir haben nicht die Energie dafür und es ist eh irrelevant. @@ -95,7 +85,6 @@ Die kurze Antwort: Nein. Wir haben nicht die Energie dafür und es ist eh irrele

Sollte Sie das nicht überzeugen, gibt es ausreichend andere Projekte für andere Distributionen mit einer anderen Philosophie dahinter.

- #### Ich hab gesehen, wie das Packen von Apps funktioniert? Warum erfindet ihr das Rad neu und benutzt nicht [hier bevorzugtes Paketformat einfügen] ? Kurze Antwort: Machen wir nicht. diff --git a/pages/05.community/20.faq/faq.fr.md b/pages/05.community/20.faq/faq.fr.md index f443438d..88a17047 100644 --- a/pages/05.community/20.faq/faq.fr.md +++ b/pages/05.community/20.faq/faq.fr.md @@ -15,7 +15,6 @@ YunoHost est basé sur Debian, donc sur les licences des éléments sur lesquels Les applications et leurs paquets ont leurs licences respectives. - #### Quel est l’objectif de YunoHost ? Nous pensons que la décentralisation d’Internet, et la reprise du contrôle et de la responsabilité des données et services par les personnes est un enjeu crucial pour garantir une société libre et démocratique. @@ -24,7 +23,6 @@ Le projet YunoHost cherche à démocratiser l’auto-hébergement. Nous fournissons un logiciel qui cherche à rendre simple le fait de gérer et d’administrer un serveur soi-même, en minimisant les compétences et le temps requis. - #### Mais qu’est-ce que ça fait *vraiment* ? YunoHost est à la fois une distribution, dans le sens où c'est une version de GNU/Linux-Debian dédié à un objectif précis et que YunoHost distribue un ensemble d'applications via son catalogue, mais c'est aussi un « simple » programme qui configure Debian de manière automatique, et gère les manipulations pénibles à votre place. @@ -33,13 +31,11 @@ Par exemple, pour installer un WordPress à la main, il vous faudrait taper tout Plus d’informations sur [cette page](/whatsyunohost) ! - #### Puis-je gérer mon propre site web avec YunoHost ? Oui ! Il faut regarder du côté de [cette app](https://github.com/YunoHost-Apps/my_webapp_ynh). Elle fournit une « coquille vide » : après l’installation, il suffit d’envoyer vos fichiers (via SSH/SCP ou SFTP) au bon endroit. Il est aussi possible d’avoir du PHP et une base de donnée SQL si besoin. - #### Peut-on héberger plusieurs sites indépendants avec des noms de domaines différents ? On peut tout à fait héberger plusieurs sites web car YunoHost est multi-domaine et que certaines applications de gestion de sites web, comme *WordPress* ou *My Webapp*, sont multi-instances, c’est-à-dire que l’application peut-être installée plusieurs fois. @@ -48,14 +44,12 @@ On peut tout à fait héberger plusieurs sites web car YunoHost est multi-domain Pour des raisons techniques, le [SSO](https://github.com/YunoHost/SSOwat/) ne permet pas aux utilisateurs de se connecter à l’espace utilisateur lorsque l’on accède au serveur uniquement avec l’IP. Si vous ne pouvez réellement pas configurer un nom de domaine, une solution temporaire peut être de modifier le [fichier `hosts` (dernier §)](/dns_local_network) de son ordinateur. - #### Quel est le modèle économique de YunoHost ? YunoHost est maintenu par une équipe de bénévoles travaillant pendant leur temps libre. Le projet reçoit régulièrement des dons qui financent principalement des frais de serveurs et de communication (stickers ;P). Le projet a reçu dans le passé (ou continue de recevoir) des subventions de la part d'organismes comme [NLnet](https://nlnet.nl/) ou [CodeLutin](https://www.codelutin.com/) pour financer des développements précis. Les dons au projet étant de plus en plus important, des initiatives sont en cours pour tenter de redistribuer l'argent aux contributeur·ice·s principales et ainsi aider à pérenniser le projet. Des contributeur·ice·s mènent par ailleurs des activités professionnelles basées partiellement sur YunoHost. - #### Puis-je faire un don au projet ? Oui, c'est possible ! YunoHost a besoin de payer des serveurs et noms de domaine, et nous souhaitons permettre aux contributeur·ice·s de continuer à développer YunoHost plutôt que de chercher un emploi ailleurs. @@ -64,7 +58,6 @@ Pour faire un don ça se passe via [notre interface de don](https://donate.yunoh Si vous le pouvez, vous pouvez aussi faire des contributions en nature (une partie de notre infrastructure vient d'associations qui nous fournissent des serveurs). - #### Comment puis-je contribuer au projet ? Il existe [plusieurs façons de contribuer](/contribute) :). @@ -77,7 +70,6 @@ Le syndrome de l'imposteur (ne pas se sentir « assez compétent·e ») est asse Elle est décrite dans [ce document](/project_organization) :). - #### Pouvez-vous porter YunoHost sur [ma distro préférée] ? Si vous vous préoccupez des guéguerres de distro, ou pensez que « Debian c’est sale », vous n’êtes pas le public de YunoHost. diff --git a/pages/05.community/20.faq/faq.it.md b/pages/05.community/20.faq/faq.it.md index 93e8a55a..81b90f6e 100644 --- a/pages/05.community/20.faq/faq.it.md +++ b/pages/05.community/20.faq/faq.it.md @@ -7,7 +7,7 @@ routes: default: '/faq' --- -#### Con quale licenza è rilasciato Yunohost? +#### Con quale licenza è rilasciato YunoHost? I pacchetti che si trovano in YunoHost sono rilasciati con licenza GNU AGPL v.3. @@ -15,7 +15,6 @@ YunoHost è basato sulla distribuzione Debian, quindi rispetta le licenze degli I programmi e i pacchetti hanno la loro propria licenza. - #### Quale obbiettivo si prefigge YunoHost? Siamo convinti che la decentralizzazione di Internet, e il riappropriarsi della responsabilità e del controllo dei nostri dati e servizi, sia una questione essenziale per garantire una società libera e democratica. @@ -24,7 +23,6 @@ Il progetto YunoHost cerca di democratizzare il self hosting. Mettiamo a disposizione un software che facilita la gestione e l'amministrazione, in proprio, di un server, riducendo le competenze necessarie e il tempo richiesto. - #### In pratica cosa *fa* YunoHost? YunoHost è contemporaneamente una distribuzione, cioè una versione di GNU/Linux-Debian dedicata ad uno scopo preciso e arricchita da un insieme di applicazioni che YunoHost contempla nel suo catalogo, sia un "semplice" programma che configura Debian in maniera automatica e gestisce per voi le configurazioni più difficili. @@ -41,12 +39,10 @@ Certamente! [Qui](https://github.com/YunoHost-Apps/my_webapp_ynh). trovate tutto Si è possibile ospitare più siti con domini diversi in quanto YunoHost accetta più nomi di dominio e alcuni programmi di gestione di siti web, come *Wordpress* o *My Webapp*, gestiscono più istanze, potendo quindi installarli più volte. - #### Perché non posso accedere alle mie applicazioni con l'indirizzo IP del server? Per motivi tecnici il [SSO](https://github.com/YunoHost/SSOwat/) (Single Sign On) non permette agli utilizzatori di connettersi alla propria dashboard quando si accede al server con il suo indirizzo IP. Se non potete configurare il DNS, una soluzione temporanea è quella di modificare il [file 'hosts' (ultimo §)](/dns_local_network) del proprio computer. - #### Su quale modello economico si basa YunoHost ? YunoHost è sviluppato da una comunità di volontari durante il loro tempo libero. Il progetto riceve regolarmente donazioni che finanziano principalmente le spese per i server e le spese di marketing (gli adesivi ;P). Il progetto ha ricevuto (o riceve attualmente) sovvenzioni da parte di organizzazioni quali [NLnet](https://nlnet.nl/) o [CodeLutin](https://www.codelutin.com/) al fine di finaziare lo sviluppo di parti ben definite. @@ -69,12 +65,10 @@ Fateci conoscere le vostre idee! Un malinteso comune per i nuovi arrivati nei progetti di software libero è quello di credere di "non essere abbastanza competenti". Nella realtà nessuno è "sufficientemente competente" :). Quello che veramente conta è: [piacere per quello che si fa](https://www.youtube.com/watch?v=zIbR5TAz2xQ&t=113s), essere empatici con le persone del progetto, essere pazienti e testardi con i computer, e avere tempo libero. Fare il possibile è già abbastanza! - #### Quale è lo progetto politico di YunoHost ? È spiegato in [questo documento](/project_organization) :). - #### Potete migrare YunoHost verso la mia [distro preferita] ? Se vi appassiona la guerriglia tra distribuzioni, o pensate che 'Debian fa schifo', YunoHost non fa per voi. @@ -83,7 +77,6 @@ YunoHost è rivolto ad un pubblico di semplici appassionati, che desiderano semp Se questo non vi convince, esistono altri progetti basati su altre distribuzioni e altre filosofie. - #### Ho studiato come funziona il packaging delle app. Perché reinventate [il mio formato preferito dei pacchetti]? Qualcuno ha cercato di paragonare il sistema di packaging di YunoHost con altri (come ad esempio il `.deb` di Debian) nonostante abbiano scopi diversi. I sistemi di packaging tradizionali sono pensati per installare gli elementi di basso livello come i files, comandi, programmi o servizi sul sistema. Spesso è poi delegato a voi il compito di configurarli opportunamente, semplicemente perché non esiste un ambiente standard. Normalmente le applicazioni web richiedono un importante lavoro di configurazione in quanto hanno bisogno di interfacciarsi con un server web e un database (e l'interfaccia di connessione unica / SSO). @@ -103,12 +96,13 @@ Se desiderate che la vostra app preferita sia implementata e documentata [aiutat La regola principale è includere nel catalogo ufficiale solo programmi distribuiti con una licenza di software libero. Tuttavia nello sviluppo di YunoHost sono apparsi alcuni casi dubbi a causa di programmi che potrebbero essere importanti per gli scopi e che coincidono con il suo spirito pur non essendo precisamente software libero. Sono situazioni come: + - programmi che promuovono l'uso di servizi centralizzati pensato proprio per evitarne l'uso diretto; - programmi che hanno dipendenze o altro non liberi; - "nuove" licenze post-open-source / etiche-ma-non-libere come ad esempio [ACSL](https://anticapitalist.software/), the [HL3](https://firstdonoharm.dev/) o [CoopCycle License](https://github.com/coopcycle/coopcycle-web/blob/master/LICENSE); - modelli "open-core", clausole di protezione di marchi o su licenze "business-related" (come ad esempio BSL) pensate per mantenere i progetti pur rimanendo eticamente accettabili. -Pur rimanendo convinti che i principi del software libero siano un passi essenziali per quelli che sono [gli obbiettivi di YunoHost](#what-s-yunohost-goal) pensiamo anche che questi siano mezzi e non fini. Rifiutiamo la visione purista secondo la quale il software è libero o proprietario e la premessa erronea che la tecnologia sia fondamentalmente neutrale. Crediamo che i programmi e la tecnologia possano e debbano esistere oltre la definizione di software libero pensata 40 anni fa (vedi anche: [Freedom isn't Free](https://logicmag.io/failure/freedom-isnt-free/) e [Post-Open Source](https://www.boringcactus.com/2020/08/13/post-open-source.html)). +Pur rimanendo convinti che i principi del software libero siano un passi essenziali per quelli che sono [gli obbiettivi di YunoHost](#what-s-yunohost-goal) pensiamo anche che questi siano mezzi e non fini. Rifiutiamo la visione purista secondo la quale il software è libero o proprietario e la premessa erronea che la tecnologia sia fondamentalmente neutrale. Crediamo che i programmi e la tecnologia possano e debbano esistere oltre la definizione di software libero pensata 40 anni fa (vedi anche: [Freedom isn't Free](https://logicmag.io/failure/freedom-isnt-free/) e [Post-Open Source](https://www.boringcactus.com/2020/08/13/post-open-source.html)). Di conseguenza il progetto permette l'inclusione nel catalogo ufficiale ***caso per caso*** di applicazioni che non si definiscono "software libero" ma considerati etici e degni di interesse per [gli obbiettivi di YunoHost](#what-s-yunohost-goal). Queste applicazioni sono segnalate nel catalogo e un messaggio apposito viene mostrato prima dell'installazione. @@ -119,6 +113,7 @@ Se usate YunoHost per la vostra iniziativa commerciale è vostra responsabilità ### Perché non includete la [caratteristica X]? YunoHost è pensata per utenti non particolarmente capaci tecnicamente e cerca di rimanere semplice nell'interfaccia. Allo stesso tempo, il progetto è tempi ed energie limitate per la manutenzione e lo sviluppo. Di conseguenza dobbiamo abbassare la priorità delle richieste di caratteristiche o anche di rifiutarle completamente basandosi sui seguenti criteri: + - è utile solo per utenti avanzati, fuori dallo scopo del progetto; - introduce troppe complicazioni nell'interfaccia; - copre solo problemi poco realistici; diff --git a/pages/05.community/20.faq/faq.md b/pages/05.community/20.faq/faq.md index 1fc73d7d..e909f529 100644 --- a/pages/05.community/20.faq/faq.md +++ b/pages/05.community/20.faq/faq.md @@ -15,7 +15,6 @@ YunoHost is based on Debian, so on Debian's components' licenses. Applications and applications packages have their own licenses. - #### What's YunoHost goal? We believe that decentralizing the Internet, and empowering people to take control and responsibility back over their own data and services, is a crucial issue to guarantee a free and democratic society. @@ -24,7 +23,6 @@ The YunoHost project aims to democratize self-hosting. It provides a software that aims to make it easy for people to run and administer their own server, with minimal knowledge and required time. - #### But what does YunoHost exactly *do*? YunoHost is a distribution, in the sense that it is a purpose-specific version of GNU/Linux-Debian and it distributes a set of application via its catalog, but it is also "just" a program that automatically configures Debian and does most of the hard work for you. @@ -41,12 +39,10 @@ Yes! Have a look at the [Custom Web app](https://github.com/YunoHost-Apps/my_web Yes! YunoHost is multi-user and multi-domain. Some applications like *WordPress* or *My webapp*, are multi-instances, which means that the application can be installed many times. - #### Why can't I access applications via the IP address? The [SSO](https://github.com/Kloadut/SSOwat/) (single sign-on) cannot properly authenticate users when they access your server with only its IP. If you really can't properly configure the DNS, you can temporarily work around it by [modifying the `hosts` file (last §)](/dns_local_network) on your computer. - #### What's YunoHost's business model? YunoHost is maintained by volunteers working on their free time. The project regularly receives donations which pay for the servers' bills and stickers. The project received (or continues to receive) grants from organization like [NLnet](https://nlnet.nl/) or [CodeLutin](https://www.codelutin.com/) to fund specific developments @@ -69,12 +65,10 @@ Don't hesitate to come talk to us about your ideas! A common misconception for newcomers in free software projects is to think that they are "not skilled enough". In practice, nobody is "skilled" :). What really matter is: [liking what you do](https://www.youtube.com/watch?v=zIbR5TAz2xQ&t=113s), being friendly with other human beings, being patient and stubborn with machines, and having some free time. Other than that, just doing what you can is already awesome! - #### How is the YunoHost project organized? It is described in [this document](/project_organization) :). - #### Will you port YunoHost to [insert favorite distro]? If you care about distrowars, or think 'Debian is dirty', then YunoHost is not for you. @@ -83,7 +77,6 @@ YunoHost is aimed at non-tech people who just want their server to work. Debian If this does not convince you, there are other projects running on other distributions or with different philosophies. - #### I checked how apps packaging work. Why are you reinventing [insert favorite package format]? People have been tempted to compare YunoHost packages to traditional package managers (such as Debian's `.deb`), which hold a different purpose. Traditional package managers are meant to install low-level purpose of installing files, commands, programs and services on the system. It is often your duty to configure them properly, simply because there is no standard server setup. Typically, web apps requires a lot of configuration because they rely on a web server and a database (and the single sign-on). @@ -103,9 +96,10 @@ If you really want to have a feature implemented or documented, or an app packag The rule of thumb is that we only include software licensed under a free-software license in the official app catalog. However, as YunoHost evolved, some gray-cases appeared with softwares that would be relevant for YunoHost's goal and match its spirit, while not being strictly-speaking free-software. Situations such as: + - software promoting the use of centralized services, though precisely to avoid their direct usage ; - software relying on non-free dependencies or assets ; -- "new" post-open-source / ethical-yet-not-free licenses such as the [ACSL](https://anticapitalist.software/), the [HL3](https://firstdonoharm.dev/) or the [CoopCycle License](https://github.com/coopcycle/coopcycle-web/blob/master/LICENSE) ; +- "new" post-open-source / ethical-yet-not-free licenses such as the [ACSL](https://anticapitalist.software/), the [HL3](https://firstdonoharm.dev/) or the [CoopCycle License](https://github.com/coopcycle/coopcycle-web/blob/master/LICENSE) ; - "open-core" models, trademark clauses, or business-related license clauses (such as the BSL) which are meant to ensure the project's sustainability while still remaining ethical. While we believe free software principles are an essential footstep towards [YunoHost's goal](#what-s-yunohost-goal), we believe they are a means and not an end. We reject the purist vision according to which software is either free or proprietary, and the flawed premise that technology is fundamentally neutral. We believe that ethical software and technology can and should exist beyond the definition of free software layed 40 years ago (see also: [Freedom isn't Free](https://logicmag.io/failure/freedom-isnt-free/) and [Post-Open Source](https://www.boringcactus.com/2020/08/13/post-open-source.html)). @@ -119,8 +113,9 @@ If you run YunoHost for your business, you are responsible for doing your due di ### Why won't you include [feature X] ? YunoHost is primarily designed for not-so-tech-savvy users and aims to remain relatively simple in terms of UI/UX. At the same time, the project has limited time and energy available to be maintained and developed. Therefore we may lower the priority of features, or refuse entirely the inclusion of features, based on the criteria that they: + - would only be meaningful for advanced / power-users stuff which is out of the scope of the project ; -- would introduce too much UI/UX bloat ; +- would introduce too much UI/UX bloat ; - would only cover unrealistic threat models ; - would be there only to satisfy purists ; -- or overall would not be worth it in terms of development/maintenance time/energy for what it brings to the project. \ No newline at end of file +- or overall would not be worth it in terms of development/maintenance time/energy for what it brings to the project. diff --git a/pages/05.community/30.project_sponsors/sponsors_partners.fr.md b/pages/05.community/30.project_sponsors/sponsors_partners.fr.md index e180c8a6..796c54f8 100644 --- a/pages/05.community/30.project_sponsors/sponsors_partners.fr.md +++ b/pages/05.community/30.project_sponsors/sponsors_partners.fr.md @@ -10,7 +10,8 @@ routes: Afin d'avancer et de faire fonctionner le projet, en plus du travail des bénévoles et des dons, YunoHost bénéficie du soutien de mécènes et de partenaires. Une liste des mécènes de YunoHost, fournissant l'infrastructure et des services aux projets : -- [GITOYEN](https://gitoyen.net) : association regroupant plusieurs entreprises et associations intervenant comme fournisseur d’infrastructure d’hébergement et d’accès à Internet. + +- [GITOYEN](https://gitoyen.net) : association regroupant plusieurs entreprises et associations intervenant comme fournisseur d’infrastructure d’hébergement et d’accès à Internet. - [GLOBENET](http://www.globenet.org) : association militante, au service de la liberté d’expression, proposant des services Internet. - [LDN-NET](https://ldn-fai.net/) : association pour la défense d’un Internet libre, neutre et décentralisé dont le moyen d’action principale est d’être un fournisseur d’accès à Internet (FAI) assocatif et local. - [NBS System](https://www.nbs-system.com/): société spécialisée dans l’hébergement, la sécurisation des Clouds, l’infogérance (Systèmes d’information, Applications SaaS, Plateformes web) et les services managés. @@ -18,5 +19,6 @@ Une liste des mécènes de YunoHost, fournissant l'infrastructure et des service - [TETANEUTRAL-NET](https://tetaneutral.net/) : fournisseur d'accès à Internet associatif opérant actuellement un réseau radio sur Toulouse et ses environs et un hébergeur. Une liste des partenaires de YunoHost : + - [FFDN](https://www.ffdn.org/) : La fédération FDN regroupe des fournisseurs d'accès à Internet associatifs se reconnaissant dans des valeurs communes : bénévolat, solidarité, fonctionnement démocratique et à but non lucratif ; défense et promotion de la neutralité du Net. - [Framasoft](https://framasoft.org/) : association d’éducation populaire, un groupe d’ami·es convaincu·es qu’un monde numérique émancipateur est possible, persuadé·es qu’il adviendra grâce à des actions concrètes sur le terrain et en ligne avec vous et pour vous ! diff --git a/pages/05.community/30.project_sponsors/sponsors_partners.md b/pages/05.community/30.project_sponsors/sponsors_partners.md index 7cb0e06e..2a33631e 100644 --- a/pages/05.community/30.project_sponsors/sponsors_partners.md +++ b/pages/05.community/30.project_sponsors/sponsors_partners.md @@ -10,6 +10,7 @@ routes: In order to advance and make the project works, in addition to the work of volunteers and donations, YunoHost benefits from the support of sponsors and partners. Here is a list of YunoHost sponsors, providing infrastructure and services to the project: + - [GITOYEN](https://gitoyen.net): association bringing together several companies and associations acting as a provider of hosting infrastructure and Internet access. - [GLOBENET](http://www.globenet.org): activist association, at the service of freedom of expression, offering internet services. - [LDN-NET](https://ldn-fai.net/) : association for the defense of a free, neutral and decentralized Internet whose main means of action is to be an Internet access provider associative and local. @@ -18,5 +19,6 @@ Here is a list of YunoHost sponsors, providing infrastructure and services to th - [TETANEUTRAL-NET](https://tetaneutral.net/): associative Internet access provider currently operating a radio network in Toulouse and its surroundings and a hoster. Here is a list of YunoHost partners: + - [FFDN](https://www.ffdn.org/): The FDN federation gathers associative Internet Access Providers who recognize themselves in common values: volunteering, solidarity, democratic functioning and non-profit; defense and promotion of net neutrality. - [Framasoft](https://framasoft.org/) : popular education association, a group of friends convinced that an emancipatory digital world is possible, convinced that it will happen thanks to concrete actions on the ground and online with you and for you! diff --git a/pages/05.community/35.project_budget/project_budget.fr.md b/pages/05.community/35.project_budget/project_budget.fr.md index b2b5a3c6..e8f2606e 100644 --- a/pages/05.community/35.project_budget/project_budget.fr.md +++ b/pages/05.community/35.project_budget/project_budget.fr.md @@ -11,32 +11,32 @@ routes: ## Revenus attendus -* Dons via Liberapay : 3000€ -* Subvention de NLNet : 20K€ +- Dons via Liberapay : 3000 € +- Subvention de NLNet : 20K € ## Dépenses prévues -* Developpement : 20K€ -* Location Serveur : ~500 € - * VPS Scaleway: 20.33*12: 243.96€/year - * VPS Digital O. (forum): 172.80€/year -* Noms de domaine : ~150 € - * nohost.me : 11.99 €HT/ans - * ynh.fr : 6.99 €HT/ans (doit être confirmé avec frju ?) - * noho.st : ~35 €TTC/ans - * yunohost.org : 13.99 €HT/ans - * yunohost.com : 9.99 €HT/ans - * labriqueinter.net : 12.49 €Ht/ans - * internetcu.be : 17.99 €HT/ans -* Communication : ~400 € - * Stickers : 100€ - * Tracts : 100€ - * T-shirt : 200€ -* Déplacements (ex. : aller aux conférences) : ~700 € - * AG FFDN 2020 : 225€ (en tout) - * Event colibris : 150€ - * FOSDEM ou autre conf : 300€ -* Compte bancaire fees : 7×12 € soit ~100 € -* Brique Camp : 500€ +- Developpement : 20K € +- Location Serveur : ~500 € + - VPS Scaleway: 20.33*12: 243.96 €/year + - VPS Digital O. (forum): 172.80 €/year +- Noms de domaine : ~150 € + - `nohost.me` : 11.99 €HT/ans + - `ynh.fr` : 6.99 €HT/ans (doit être confirmé avec frju ?) + - `noho.st` : ~35 €TTC/ans + - `yunohost.org` : 13.99 €HT/ans + - `yunohost.com` : 9.99 €HT/ans + - `labriqueinter.net` : 12.49 €Ht/ans + - `internetcu.be` : 17.99 €HT/ans +- Communication : ~400 € + - Stickers : 100 € + - Tracts : 100 € + - T-shirt : 200 € +- Déplacements (ex. : aller aux conférences) : ~700 € + - AG FFDN 2020 : 225 € (en tout) + - Event colibris : 150 € + - FOSDEM ou autre conf : 300 € +- Compte bancaire fees : 7×12 € soit ~100 € +- Brique Camp : 500 € **Balance 2020-2021** : +650 € diff --git a/pages/05.community/35.project_budget/project_budget.md b/pages/05.community/35.project_budget/project_budget.md index 19f4e059..8b74b688 100644 --- a/pages/05.community/35.project_budget/project_budget.md +++ b/pages/05.community/35.project_budget/project_budget.md @@ -11,29 +11,29 @@ routes: ## Expected revenues -* Donations: 3000€/year -* Grant from NLNet: 20K€ +- Donations: 3000€/year +- Grant from NLNet: 20K€ ## Expected expenses -* Development: 20K€ -* Server renting: 500€ - * VPS Scaleway: 20.33*12: 243.96€/year - * VPS Digital O. (forum): 172.80€/year -* Domain names: ~150€ - * nohost.me: 11.99€HT/year - * ynh.fr: 6.99€HT/year (to be confirmed with frju?) - * noho.st: ~35€ TTC/year - * YunoHost.org: 13.99€HT/year - * YunoHost.com: 9.99€HT/year - * labriqueinter.net: 12.49€HT/year - * internetcu.be: 17.99€HT/year -* Communication: ~400€ -* Travel (e.g. to go to conferences): ~700€ - * AG FFDN 2020: 225€ (en tout) - * Event colibris: 150€ - * FOSDEM ou autre conf: 300€ -* Bank account fees: 7x12€ => ~100€ -* Brique Camp: 500€ +- Development: 20K€ +- Server renting: 500€ + - VPS Scaleway: 20.33*12: 243.96€/year + - VPS Digital O. (forum): 172.80€/year +- Domain names: ~150€ + - `nohost.me`: 11.99€HT/year + - `ynh.fr`: 6.99€HT/year (to be confirmed with frju?) + - `noho.st`: ~35€ TTC/year + - `yunohost.org`: 13.99€HT/year + - `yunohost.com`: 9.99€HT/year + - `labriqueinter.net`: 12.49€HT/year + - `internetcu.be`: 17.99€HT/year +- Communication: ~400€ +- Travel (e.g. to go to conferences): ~700€ + - AG FFDN 2020: 225€ (en tout) + - Event colibris: 150€ + - FOSDEM ou autre conf: 300€ +- Bank account fees: 7x12€ => ~100€ +- Brique Camp: 500€ **Balance 2020-2021**: +650€ diff --git a/pages/05.community/35.security_team/security_team.fr.md b/pages/05.community/35.security_team/security_team.fr.md index 3186cffb..34278b75 100644 --- a/pages/05.community/35.security_team/security_team.fr.md +++ b/pages/05.community/35.security_team/security_team.fr.md @@ -20,4 +20,4 @@ uid YunoHost Security sub 4096R/446838AF 2016-07-01 ``` -Voyez https://gist.github.com/opi/4496024dc3ff29ab2e068fd57092ab7c et https://twitter.com/yunohost/status/748975105393459200 pour d'autres empreintes de confiance +Voyez et pour d'autres empreintes de confiance diff --git a/pages/05.community/35.security_team/security_team.md b/pages/05.community/35.security_team/security_team.md index fd97120b..d698ba4f 100644 --- a/pages/05.community/35.security_team/security_team.md +++ b/pages/05.community/35.security_team/security_team.md @@ -19,4 +19,4 @@ uid YunoHost Security sub 4096R/446838AF 2016-07-01 ``` -See https://gist.github.com/opi/4496024dc3ff29ab2e068fd57092ab7c or https://twitter.com/yunohost/status/748975105393459200 for other trustable fingerprints +See or for other trustable fingerprints diff --git a/pages/05.community/40.press_kit/press_kit.md b/pages/05.community/40.press_kit/press_kit.md index 871f93f9..91e61448 100644 --- a/pages/05.community/40.press_kit/press_kit.md +++ b/pages/05.community/40.press_kit/press_kit.md @@ -17,28 +17,29 @@ routes: ## Talks / conf - (EN) [BattleMeshV12 - YunoHost and the Internet Cube (Brique Internet)](https://www.battlemesh.org/BattleMeshV12/Events#YunoHost_and_the_Internet_Cube_.28Brique_Internet.29) -* (EN) [FOSDEM 2019 - The operating system to build the decentralized Internet](https://cinema.yunohost.support/videos/watch/1eb49594-0283-4a01-8691-3817a3cb31e6) ([slides](https://github.com/YunoHost/yunohost-fosdem-2019)) -* (FR) [Capitole du libre 2018 - YunoHost: un des chemins vers la décentralisation - Bram](https://www.youtube.com/watch?v=OEXEStoOYpw) ([slides](https://psycojoker.github.io/yunohost-cdl-2018/)) -* (FR) [Journées du logiciel libre 2018 - YunoHost : vers l’auto-hébergement et au-delà - Bram](https://www.videos-libr.es/videos/watch/45b48b1e-1b10-4e09-b29a-a404bd42c5d0) ([slides](https://psycojoker.github.io/yunohost-jdll-2018/)) -* (FR) Ubuntu Party Novembre 2017 - De Framasoft à YunoHost, réapproprions nous le cloud ([slides](https://blog.genma.fr/?De-Framasoft-a-Yunohost-reapproprions-nous-le-cloud)) -* (FR) [Capitole du libre 2017 - YunoHost : vers l'auto-hébergement et au-delà - JimboJoe](https://2017.capitoledulibre.org/programme/#yunohost-vers-lauto-hebergement-et-au-dela) ([slides](https://github.com/YunoHost/yunohost-cdl-2017/raw/master/YunoHost-CDL2017.pdf)) -* (FR) [PSES 2017 – Construire l’Internet du Futur avec YunoHost – Aleks, ljf](https://data.passageenseine.org/2017/aleks-ljf_internet-futur-yunohost.webm) ([slides](https://data.passageenseine.org/2017/aleks-ljf_internet-futur-yunohost.pdf)) -* (FR) [Université de technologie de compiègne 2017 – Agir pour un internet éthique – LJF](http://webtv.utc.fr/watch_video.php?v=O34AA7RBR1AH) -* (EN) [FOSDEM 2017 – Internet Cube – kload](https://archive.fosdem.org/2017/schedule/event/internet_cube/) -* (EN) [FOSDEM 2017 – YunoHost – Bram](https://archive.fosdem.org/2017/schedule/event/yunohost/) -* (FR) [Capitole du libre 2016 – 1 an et ½ de Brique Internet – Bram](https://toulibre.org/pub/2016-11-19-capitole-du-libre/videos/communaute-du-libre/bram-1-an-et-demi-de-brique-internet.mp4) -* (FR) [PSES 2015 - La Brique Internet](http://www.youtube.com/watch?v=NCRn0yRfkIE) -* (FR) [THSF 2015 – beudbeud](https://vimeo.com/128055751) -* (FR) [RMLL 2014 - Hébergez-vous ! – kload & beudbeud]() -* (FR) [Capitole du libre 2013 - L’auto-hébergement pour tous avec YunoHost - beudbeud](http://2013.capitoledulibre.org/conferences/internet-libre/lauto-hebergement-pour-tous-avec-yunohost.html) -* (EN) [FOSDEM 2013 — kload](https://www.youtube.com/watch?v=siN1OLAgGJk) +- (EN) [FOSDEM 2019 - The operating system to build the decentralized Internet](https://cinema.yunohost.support/videos/watch/1eb49594-0283-4a01-8691-3817a3cb31e6) ([slides](https://github.com/YunoHost/yunohost-fosdem-2019)) +- (FR) [Capitole du libre 2018 - YunoHost: un des chemins vers la décentralisation - Bram](https://www.youtube.com/watch?v=OEXEStoOYpw) ([slides](https://psycojoker.github.io/yunohost-cdl-2018/)) +- (FR) [Journées du logiciel libre 2018 - YunoHost : vers l’auto-hébergement et au-delà - Bram](https://www.videos-libr.es/videos/watch/45b48b1e-1b10-4e09-b29a-a404bd42c5d0) ([slides](https://psycojoker.github.io/yunohost-jdll-2018/)) +- (FR) Ubuntu Party Novembre 2017 - De Framasoft à YunoHost, réapproprions nous le cloud ([slides](https://blog.genma.fr/?De-Framasoft-a-Yunohost-reapproprions-nous-le-cloud)) +- (FR) [Capitole du libre 2017 - YunoHost : vers l'auto-hébergement et au-delà - JimboJoe](https://2017.capitoledulibre.org/programme/#yunohost-vers-lauto-hebergement-et-au-dela) ([slides](https://github.com/YunoHost/yunohost-cdl-2017/raw/master/YunoHost-CDL2017.pdf)) +- (FR) [PSES 2017 – Construire l’Internet du Futur avec YunoHost – Aleks, ljf](https://data.passageenseine.org/2017/aleks-ljf_internet-futur-yunohost.webm) ([slides](https://data.passageenseine.org/2017/aleks-ljf_internet-futur-yunohost.pdf)) +- (FR) [Université de technologie de compiègne 2017 – Agir pour un internet éthique – LJF](http://webtv.utc.fr/watch_video.php?v=O34AA7RBR1AH) +- (EN) [FOSDEM 2017 – Internet Cube – kload](https://archive.fosdem.org/2017/schedule/event/internet_cube/) +- (EN) [FOSDEM 2017 – YunoHost – Bram](https://archive.fosdem.org/2017/schedule/event/yunohost/) +- (FR) [Capitole du libre 2016 – 1 an et ½ de Brique Internet – Bram](https://toulibre.org/pub/2016-11-19-capitole-du-libre/videos/communaute-du-libre/bram-1-an-et-demi-de-brique-internet.mp4) +- (FR) [PSES 2015 - La Brique Internet](http://www.youtube.com/watch?v=NCRn0yRfkIE) +- (FR) [THSF 2015 – beudbeud](https://vimeo.com/128055751) +- (FR) [RMLL 2014 - Hébergez-vous ! – kload & beudbeud]() +- (FR) [Capitole du libre 2013 - L’auto-hébergement pour tous avec YunoHost - beudbeud](http://2013.capitoledulibre.org/conferences/internet-libre/lauto-hebergement-pour-tous-avec-yunohost.html) +- (EN) [FOSDEM 2013 — kload](https://www.youtube.com/watch?v=siN1OLAgGJk) ## Articles / Press review [![](image://Linuxfr.png?resize=180)](https://linuxfr.org/news/yunohost-2-0-l-auto-hebergement-a-portee-de-clic) [![](image://linux-pratique-96.jpg?resize=150)](https://www.linux-pratique.com/2016/07/et-si-vous-passiez-a-lauto-hebergement/) [![](image://linux-magazine-208.jpg?resize=150)](https://www.linux-magazine.com/Issues/2018/208/YunoHost) -* LinuxFr (french): + +- LinuxFr (french): - [YunoHost 2.0 : self hosting at click range](https://linuxfr.org/news/yunohost-2-0-l-auto-hebergement-a-portee-de-clic) - [Internet cube and YunoHost projects evolutions](https://linuxfr.org/news/evolutions-des-projets-la-brique-internet-et-yunohost-des-versions-2-2-2-4-et-2-5) - (FR) [Linux Pratique n°96 – YunoHost, l’auto-hébergement à portée de main – juillet 2016](http://connect.ed-diamond.com/Linux-Pratique/LP-096/YunoHost-l-auto-hebergement-a-portee-de-main) @@ -64,9 +65,9 @@ routes: - (EN) [35C3: Hands-on introduction to self-Hosting with YunoHos](https://events.ccc.de/congress/2018/wiki/index.php/Session:Hands-on_introduction_to_self-Hosting_with_YunoHost) - (FR) [Journées du Logiciel Libre 2019: l'auto-hébergement avec YunoHost](https://pretalx.jdll.org/jdll2019/talk/88GSPH/) -## YunoHost was cited in : +## YunoHost was cited in -* [EXPERIMENTA 2018](https://livestream.com/accounts/26482307/events/8034656/player?width=960&height=540&enableInfoAndActivity=true&defaultDrawer=&autoPlay=true&mute=false) at 57.47 (depuis https://www.experimenta.fr/direct/) -* [Capitole du libre 2017 - « Contributopia », Dégoogliser ne suffit pas](https://www.youtube.com/watch?v=ip6_VMkWpr8&feature=youtu.be&t=4793) -* [Contributopia - Essaimage (Framasoft)](https://contributopia.org/fr/essaimage/) +- [EXPERIMENTA 2018](https://livestream.com/accounts/26482307/events/8034656/player?width=960&height=540&enableInfoAndActivity=true&defaultDrawer=&autoPlay=true&mute=false) at 57.47 (depuis ) +- [Capitole du libre 2017 - « Contributopia », Dégoogliser ne suffit pas](https://www.youtube.com/watch?v=ip6_VMkWpr8&feature=youtu.be&t=4793) +- [Contributopia - Essaimage (Framasoft)](https://contributopia.org/fr/essaimage/) - (FR) [Triple A: Émission Underscore #144 du 19 mai 2019](https://www.triplea.fr/blog/podcast/emission-underscore-144-du-19-mai-2019/) diff --git a/pages/06.contribute/05.write_documentation/01.writing_documentation_guide/doc_writing_guide.fr.md b/pages/06.contribute/05.write_documentation/01.writing_documentation_guide/doc_writing_guide.fr.md index 296d25f1..2d68fcdf 100644 --- a/pages/06.contribute/05.write_documentation/01.writing_documentation_guide/doc_writing_guide.fr.md +++ b/pages/06.contribute/05.write_documentation/01.writing_documentation_guide/doc_writing_guide.fr.md @@ -9,26 +9,26 @@ routes: ## Page de documentation utilisateurs·rices / administrateurs⋅rices -Ajouter un bouton installer en un clic (comme par exemple : https://yunohost.org/app_piwigo) et un bouton sur le niveau d'intégration de l'application. +Ajouter un bouton installer en un clic (comme par exemple : ) et un bouton sur le niveau d'intégration de l'application. Classement des applications disponibles par tags (genre, Git, gestion associations, courriels, etc.). ## Quelques usages types et d'ordre général (trame de rédaction) - + Lorsqu'un lien renvoie vers une page qui n'est pas dans la langue de la page d'origine, il est d'usage d'ajouter `(en)`(Pour un lien qui pointe vers une page en anglais). - + renommer les images dans l'ordre suivant :`nomapplication_descriptif.ext` +- Lorsqu'un lien renvoie vers une page qui n'est pas dans la langue de la page d'origine, il est d'usage d'ajouter `(en)`(Pour un lien qui pointe vers une page en anglais). +- renommer les images dans l'ordre suivant : `nomapplication_descriptif.ext` ### Trame générale documentation applications 1. Logo (dimension 80 pixels de hauteur) + titre de niveau 1. - 1. Bouton installer en un clic, Niveau d'intégration pour chaque type de processeur. - 1. Un index en tête de documentation avec renvoi vers l'ensemble des chapitres de la documentation. - 1. Une présentation générale de l'application et de sa fonction. - 2. Une partie configuration de l'application. - 1. Une partie administration de l'application. - 1. Une partie sur les limitations liées à YunoHost. - 1. Une partie sur les clients desktop (s'il en existe). Lien vers différentes applications tierces s'il en existe plusieurs (lien possible avec le catalogue d'applications [framalibre.org](https://framalibre.org)) ou un lien vers la page concernant les applications desktop si des applications officielles sont fournies. - 1. Une partie avec : + 2. Bouton installer en un clic, Niveau d'intégration pour chaque type de processeur. + 3. Un index en tête de documentation avec renvoi vers l'ensemble des chapitres de la documentation. + 4. Une présentation générale de l'application et de sa fonction. + 5. Une partie configuration de l'application. + 6. Une partie administration de l'application. + 7. Une partie sur les limitations liées à YunoHost. + 8. Une partie sur les clients desktop (s'il en existe). Lien vers différentes applications tierces s'il en existe plusieurs (lien possible avec le catalogue d'applications [framalibre.org](https://framalibre.org)) ou un lien vers la page concernant les applications desktop si des applications officielles sont fournies. + 9. Une partie avec : - le lien vers le site officiel - le lien vers la documentation officielle - les liens vers le package de YunoHost et issues @@ -39,5 +39,5 @@ Trame pour la rédaction des pages de documentations : [ici](/app_writing_guide) 1. Documenter les applications. 1. Documenter les applications au travail (marqué : work) niveau 8/7/6. - 1. Traduire la page de documentation a minima en français et en anglais. - 1. Faire une PR sur le dépôt de l'application concernée vers la page de documentation. + 2. Traduire la page de documentation a minima en français et en anglais. + 3. Faire une PR sur le dépôt de l'application concernée vers la page de documentation. diff --git a/pages/06.contribute/05.write_documentation/01.writing_documentation_guide/doc_writing_guide.md b/pages/06.contribute/05.write_documentation/01.writing_documentation_guide/doc_writing_guide.md index b853e359..2f48e2c7 100644 --- a/pages/06.contribute/05.write_documentation/01.writing_documentation_guide/doc_writing_guide.md +++ b/pages/06.contribute/05.write_documentation/01.writing_documentation_guide/doc_writing_guide.md @@ -9,25 +9,25 @@ routes: ## Users / Administrators documentation pages -Add a one-click install button (such as https://yunohost.org/app_piwigo) and a button on the application integration level. +Add a one-click install button (such as ) and a button on the application integration level. Classification of available applications by tags (genre, Git, association management, e-mails, etc.). ## Some typical and general uses (writing framework) - + rename the images in the following order:`description_application.ext`. +- rename the images in the following order:`description_application.ext`. ### General frame application documentation 1. Logo (dimension 80 pixels high) + level 1 title. - 1. One-click install button, Integration level for each type of processor. - 1. An index at the top of the documentation with cross-references to all the chapters of the documentation. - 1. A general presentation of the application and its function. - 2. A configuration part of the application. - 1. An administration part of the application. - 1. A part on limitations related to YunoHost. - 1. A part on desktop clients (if any). A link to different third-party applications if there are several (possible link to the applications catalgue [framalibre.org](https://framalibre.org)) or a link to the page about desktop applications if official applications are provided. - 1. A part with: + 2. One-click install button, Integration level for each type of processor. + 3. An index at the top of the documentation with cross-references to all the chapters of the documentation. + 4. A general presentation of the application and its function. + 5. A configuration part of the application. + 6. An administration part of the application. + 7. A part on limitations related to YunoHost. + 8. A part on desktop clients (if any). A link to different third-party applications if there are several (possible link to the applications catalgue [framalibre.org](https://framalibre.org)) or a link to the page about desktop applications if official applications are provided. + 9. A part with: - the link to the official site - the link to the documentation - Links to the YunoHost package and issues @@ -38,5 +38,5 @@ Screen for writing documentation pages: [here](/app_writing_guide) 1. Document applications. 1. Document applications at work (marked: work) level 8/7/6. - 1. Translate the documentation page at least into French and English. - 1. Do a PR on the application repository + 2. Translate the documentation page at least into French and English. + 3. Do a PR on the application repository diff --git a/pages/06.contribute/05.write_documentation/02.markdown_guide/doc_markdown_guide.fr.md b/pages/06.contribute/05.write_documentation/02.markdown_guide/doc_markdown_guide.fr.md index 7ea595fb..631b3ff5 100644 --- a/pages/06.contribute/05.write_documentation/02.markdown_guide/doc_markdown_guide.fr.md +++ b/pages/06.contribute/05.write_documentation/02.markdown_guide/doc_markdown_guide.fr.md @@ -14,6 +14,7 @@ Markdown permet de formater du texte à l'aide de balises, il permet une lecture ## Les différents niveaux de titres En rédigeant des titres comme suit : + ```markdown # Titre de niveau 1 ## Titre de niveau 2 @@ -24,11 +25,17 @@ En rédigeant des titres comme suit : ``` Ils apparaissent comme cela : + # Titre de niveau 1 + ## Titre de niveau 2 + ### Titre de niveau 3 + #### Titre de niveau 4 + ##### Titre de niveau 5 + ###### Titre de niveau 6 ## Formatage dans les paragraphes @@ -61,6 +68,7 @@ s'affichera comme tel : [Texte à afficher](https://lelien.tld) C'est identique pour les pages de la documentation, excepté que le lien est interne. Le nom de la page est sa route par défault définie dans son *header*: + ```markdown [Page du wiki](/write_documentation) ``` @@ -71,6 +79,7 @@ Le lien renverra vers la page avec la bonne configuration de langue si la page e ! Notez qu'il ne faut donc pas préciser le code de langue au début des liens vers d'autres pages de la documentation : `/fr`, `/en`, etc. sont superflus. ### Créer des ancres + Une ancre permet de faire un lien vers un point précis dans une page, c'est comme ça que fonctionnent les index en haut de page. Pour créer une ancre, il faut insérer du code à l'endroit de l'ancre sous la forme suivante : ```markdown @@ -98,13 +107,15 @@ Pour afficher des images, le principe est identique aux liens, excepté l'ajout ```markdown ![Logo YunoHost](image://logo.png) ``` + ![Logo YunoHost](image://logo.png) - Il est possible de faire un lien avec une image, exemple : + ```markdown [![Logo YunoHost](image://logo.png)](/write_documentation) ``` + [![Logo YunoHost](image://logo.png)](/write_documentation) L'encart de *texte à afficher en cas d'impossibilité de chargement de l'image* entre les crochets dans le lien de l'image n'est pas obligatoire mais fortement recommandé. @@ -120,6 +131,7 @@ Les citations permettent de mettre en valeur un propos tenu par une autre person >> Et une seconde citation >> avec des doubles chevrons ``` + S'affichera : >Du texte de citation du premier niveau @@ -174,6 +186,7 @@ On obtient : Pour créer une liste non ordonnée, il faut utiliser les symboles `*`, `+` ou `*`. Cela ne changera pas l'apparence du marqueur dans la restitution du texte. C'est l'incrémentation de la liste qui définira le visuel. Pour une meilleure lecture du texte brut, il peut être pratique d'utiliser les différents symboles pour marquer l'incrémentation, mais ce sont bien les trois espaces avant la sous-liste qui désigneront l'incrémentation. Comme tel : + ```markdown + Liste 1 + Liste 2 @@ -192,20 +205,24 @@ Comme tel : ``` Ce qui affichera : -+ Liste 1 -+ Liste 2 -+ liste 3 - - Liste 3a - - Liste 3b - * Liste 3b1 - * Liste 3b2 - * Liste 3b3 - + Liste 1 - + Liste 2 - + liste 3 + +- Liste 1 +- Liste 2 +- liste 3 + - Liste 3a + - Liste 3b + - Liste 3b1 + - Liste 3b2 + - Liste 3b3 + - Liste 1 + - Liste 2 + - liste 3 + - Liste 4 -* Liste 5 -+ liste 6 + +- Liste 5 + +- liste 6 ## Les tableaux @@ -221,6 +238,7 @@ Pour créer un tableau, il faut utiliser la barre verticale `|` (appelé 'pipe') | Une ligne formatée | | Et du **texte en gras** | Ou en *italique* | | D'autres lignes | |![une image](image://cd.jpg) | [Ou un lien](/contributordoc) | ``` + Ce qui affichera ça : | **Un tableau** | Une colonne | Une seconde | Autant que l'on veut | @@ -244,17 +262,20 @@ Ce qui donnera au rendu : Soit inline, par exemple pour mettre en valeur une touche comme `Ctrl` ''' + ```markdown ou directement en bloc. La seule différence est dans la quantité d'accents graves : Minimum trois accents graves en ouverture et fermeture de bloc et deux accents graves qui encadrent le morceau de texte à formater dans une ligne ``` + ''' + ## Liens utiles - + La documentation du langage originel Markdown : [daringfireball.net/projects/markdown (en)](https://daringfireball.net/projects/markdown/) - + Tutoriel Markdown sur [markdowntutorial.com](https://markdowntutorial.com) +- La documentation du langage originel Markdown : [daringfireball.net/projects/markdown (en)](https://daringfireball.net/projects/markdown/) +- Tutoriel Markdown sur [markdowntutorial.com](https://markdowntutorial.com) ## Aller plus loin -De manière plus générale, pour comprendre comment est formaté un texte il suffit juste d'inspecter le document source avec une application note. Ce n'est pas pour autant que le wiki de YunoHost pourra l'exploiter. Il existe bien d'autres possibilités d'utiliser la syntaxe markdown, n'hésitez pas à ajouter des fonctionnalités manquantes. Si vous avez observé des manques et/ou que vous avez des questions, contactez-nous sur [le forum](https://forum.yunohost.org) ou par message direct sur le salon IRC : **#yunohost** sur [libera.chat](https://libera.chat). +De manière plus générale, pour comprendre comment est formaté un texte il suffit juste d'inspecter le document source avec une application note. Ce n'est pas pour autant que le wiki de YunoHost pourra l'exploiter. Il existe bien d'autres possibilités d'utiliser la syntaxe markdown, n'hésitez pas à ajouter des fonctionnalités manquantes. Si vous avez observé des manques et/ou que vous avez des questions, contactez-nous sur [le forum](https://forum.yunohost.org) ou par message direct sur le salon IRC : **#YunoHost** sur [libera.chat](https://libera.chat). diff --git a/pages/06.contribute/05.write_documentation/02.markdown_guide/doc_markdown_guide.md b/pages/06.contribute/05.write_documentation/02.markdown_guide/doc_markdown_guide.md index fdec1bf2..af7e87a7 100644 --- a/pages/06.contribute/05.write_documentation/02.markdown_guide/doc_markdown_guide.md +++ b/pages/06.contribute/05.write_documentation/02.markdown_guide/doc_markdown_guide.md @@ -14,6 +14,7 @@ Markdown allows text to be formatted using tags, it allows *human* reading of th ## The different levels of titles By writing titles as follows: + ```markdown # Level 1 title ## Level 2 title @@ -24,11 +25,17 @@ By writing titles as follows: ``` They appear like this: + # Level 1 title + ## Level 2 title + ### Level 3 title + #### Level 4 title + ##### Level 5 title + ###### Level 6 title ## Formatting in paragraphs @@ -61,6 +68,7 @@ will be displayed as such: [Text to display](https://lelien.tld) It is the same for the documentation pages, except that the link is internal. The page name is its default route, as defined in its page header: + ```markdown [Wiki Page](/write_documentation) ``` @@ -71,6 +79,7 @@ The link will return to the page with the correct language setting if the page e ! Note that language codes are thus not to be included at the beginning of the links to other documentation pages: `/en`, `/fr`, etc. are superfluous. ### Create anchors + An anchor allows you to make a link to a specific point in a page, that's how the indexes at the top of the page work. To create an anchor, you need to insert code at the anchor location in the following form : ```markdown @@ -98,13 +107,15 @@ To display images, the principle is the same as for links, except that a `!` is ```markdown ![YunoHost Logo](image://logo.png) ``` + ![YunoHost Logo](image://logo.png) - It is possible to make a link with an image, for example: + ```markdown [![YunoHost Logo](image://logo.png)](/write_documentation) ``` + [![YunoHost Logo](image://logo.png)](/write_documentation) The insert of *text to be displayed if the image cannot be loaded* between the brackets in the image link is not mandatory but strongly recommended. @@ -120,6 +131,7 @@ Quotes are used to highlight a statement made by another person, the wiki itself >> And a second quote >> with double rafters ``` + Will be displayed: >First level quotation text @@ -174,6 +186,7 @@ You get: To create an unordered list, use the symbols `*`, `+` or `*`. This will not change the appearance of the marker in the text output. It is the incrementing of the list that will define the visual. For a better reading of the plain text, it may be good to use the different symbols to mark the increment, but it is the three spaces before the sub-list that will indicate the increment. As such: + ```markdown + List 1 + List 2 @@ -192,20 +205,24 @@ As such: ``` This will read: -+ List 1 -+ List 2 -+ list 3 - - List 3a - - List 3b - * List 3b1 - * List 3b2 - * List 3b3 - + List 1 - + List 2 - + list 3 + +- List 1 +- List 2 +- list 3 + - List 3a + - List 3b + - List 3b1 + - List 3b2 + - List 3b3 + - List 1 + - List 2 + - list 3 + - List 4 -* List 5 -+ list 6 + +- List 5 + +- list 6 ## Tables @@ -221,6 +238,7 @@ To create an array, use the vertical bar `|` and dashes `--`. It is mandatory to | | And formatted line | | And bold text | | Or *italic* | | More lines | |![An image](image://cd.jpg) | [Or a link](/contributordoc) | ``` + Which would say this: | **One table** | One column | One second | As many as you want | @@ -230,7 +248,7 @@ Which would say this: ## Code block -To display plain text, `blocks of code' can be created using the grave accent `Alt Gr + è` : +To display plain text, `blocks of code' can be created using the grave accent`Alt Gr + è` : ```markdown Either inline, for example to highlight a key like `Ctrl`. @@ -244,18 +262,20 @@ Which will give the rendering: Either inline, for example to highlight a key like `Ctrl`. ''' + ```markdown or directly as a block. The only difference is in the amount of bass accents: At least three low pitched accents at the opening and closing of the block and two low pitched accents that frame the piece of text to be formatted in a line. ``` + ''' ## Useful links - + The documentation of the original Markdown language: [daringfireball.net/projects/markdown](https://daringfireball.net/projects/markdown/) - + Markdown Tutorial on [markdowntutorial.com](https://markdowntutorial.com) +- The documentation of the original Markdown language: [daringfireball.net/projects/markdown](https://daringfireball.net/projects/markdown/) +- Markdown Tutorial on [markdowntutorial.com](https://markdowntutorial.com) ## Going further -In a more general way, to understand how a text is formatted just inspect the source document with a note application. This does not mean that the YunoHost wiki will be able to exploit it. There are many other possibilities to use markdown syntax, feel free to add missing features. If you've noticed some missing features and/or have questions, please contact us on [the forum](https://forum.yunohost.org) or by direct message on the IRC room: **#yunohost** on [libera.chat](https://libera.chat). +In a more general way, to understand how a text is formatted just inspect the source document with a note application. This does not mean that the YunoHost wiki will be able to exploit it. There are many other possibilities to use markdown syntax, feel free to add missing features. If you've noticed some missing features and/or have questions, please contact us on [the forum](https://forum.yunohost.org) or by direct message on the IRC room: **#YunoHost** on [libera.chat](https://libera.chat). diff --git a/pages/06.contribute/05.write_documentation/03.git/doc_use_git.fr.md b/pages/06.contribute/05.write_documentation/03.git/doc_use_git.fr.md index ddcf1516..825fef71 100644 --- a/pages/06.contribute/05.write_documentation/03.git/doc_use_git.fr.md +++ b/pages/06.contribute/05.write_documentation/03.git/doc_use_git.fr.md @@ -7,14 +7,15 @@ routes: default: '/doc_use_git' --- -Il est bien sûr possible de contribuer directement sur la documentation de YunoHost, mais ce n’est pas la manière la plus pratique de le faire tant pour le·la contributeur·rice que pour la personne qui va injecter votre contribution dans la documentation. Voici un tutoriel pour comprendre et créer une contribution à la documentation de YunoHost en utilisant l’outil [Git (en)](https://git-scm.com/) et [github.com](http://github.com/) qui est le service de forge Git qui héberge et stocke le code source de YunoHost ainsi que sa documentation. +Il est bien sûr possible de contribuer directement sur la documentation de YunoHost, mais ce n’est pas la manière la plus pratique de le faire tant pour le·la contributeur·rice que pour la personne qui va injecter votre contribution dans la documentation. Voici un tutoriel pour comprendre et créer une contribution à la documentation de YunoHost en utilisant l’outil [Git (en)](https://git-scm.com/) et [GitHub.com](http://github.com/) qui est le service de forge Git qui héberge et stocke le code source de YunoHost ainsi que sa documentation. + +## Création d’un compte sur GitHub.com -## Création d’un compte sur github.com Pour pouvoir envoyer vos contributions via GitHub, il est nécessaire d’avoir un compte sur GitHub. Pour créer le compte vous aurez besoin d’une adresse e-mail valide à laquelle vous avez accès. GitHub est un outil puissant qui propose de nombreuses fonctionnalités, l’interface peut être un peu effrayante au début. Vous n’êtes pas obligé·e de donner vos noms et prénoms, vous pouvez utiliser un pseudonyme (lors de l’inscription `Username`). - ## Forker la documentation de YunoHost dans votre dépôt personnel + Forker le code source permet de créer une nouvelle branche de développement d’un code source de logiciel ou dans le cas présent, le code source de la documentation. En créant une nouvelle branche, cela vous permet de modifier le code et d’ajouter vos contributions sans altérer le code de la branche `master` qui est le rendu public de la documentation. Ce qui vous permet de ne pas devoir tout marquer mais le faire en plusieurs étapes. (Notamment pour les contributions demandant plus de temps de travail). Forker un projet sur GitHub est extrêmement simple, il suffit de cliquer sur le bouton Fork, cela créera un nouveau dépôt sur votre espace de GitHub. @@ -23,30 +24,35 @@ Forker un projet sur GitHub est extrêmement simple, il suffit de cliquer sur le Dans le titre du nouveau dépôt, vous verrez de quelle provenance vient le dépôt, dans le cas présent `YunoHost/doc` ![Capture d’écran titre et sous-titre du dépot](image://github_fork_title.png) -> **Point de vigilance !** - -> Si vous forkez le dépôt d’un·e autre contributeur·rice que YunoHost, vous aurez les mêmes fichiers. Sauf que quand vous enverrez vos modifications, elles seront envoyées au contributeur et non au dépôt YunoHost. L’avantage est que ça vous permet de développer une autre branche créée par le·la contributeur·rice et ainsi travailler avec une autre personne à une amélioration avant proposition au dépôt principal. -> Il n’est pas possible d’avoir un fork du dépot d’un·e contributeur·rice et le fork dépôt d’origine au même moment dans votre propre dépôt. +! **Point de vigilance !** +! Si vous forkez le dépôt d’un·e autre contributeur·rice que YunoHost, vous aurez les mêmes fichiers. Sauf que quand vous enverrez vos modifications, elles seront envoyées au contributeur et non au dépôt YunoHost. L’avantage est que ça vous permet de développer une autre branche créée par le·la contributeur·rice et ainsi travailler avec une autre personne à une amélioration avant proposition au dépôt principal. +! Il n’est pas possible d’avoir un fork du dépot d’un·e contributeur·rice et le fork dépôt d’origine au même moment dans votre propre dépôt. ## Modifier et ajouter votre contribution + Une fois le dépôt forké (copié), il faudra créer une nouvelle branche de développement au sein de votre dépôt. C’est à travers cette branche que vous allez modifier les fichiers et ainsi proposer des améliorations de la documentation. Le fait que ce soit une nouvelle branche vous permettra par la suite de faire une Pull Request, c’est à dire une demande d’ajout de vos contributions au sein de la branche `master` qui est la branche principale de la documentation. Les règles de développement sur GitHub changent selon les développeurs de chaque dépôt, certains ont une branche testing dans laquelle il faut proposer les contributions. Plus d’informations sur ce qu’est une branche sur git-scm.com : [Les branches avec Git - Ce qu’est une branche](https://git-scm.com/book/fr/v1/Les-branches-avec-Git-Ce-qu-est-une-branche). ## Envoyer votre contribution par une Pull Request + Faire une Pull Request correspond au moment où vous souhaitez partager votre travail avec le reste des contributeurs⋅rices et l’intégrer au dépot master (dépôt principal de YunoHost). Lors de la publication d’une Pull Request, couramment nommée PR, les contributeurs⋅rices pourront amender, commenter, ajouter, corriger votre contribution avant intégration complète au dépôt. ## Suivre votre contribution et prendre en compte les retours des contributeurs·trices + Lorsque vous avez déjà fait une PR (Pull Request), les modifications de votre branche de développement sur le dépôt Git se rajouteront automatiquement à la PR. Cela ne nécessite aucune action supplémentaire. Vous pouvez aussi intégrer les propositions de modifications de contributeurs, qui lorsqu’ils·elles auditeront le code, peuvent trouver des erreurs ou de nouvelles formulations plus adaptées. ## Faire remonter des erreurs et des souhaits par des issues -YunoHost dispose d’un dépôt Git spécifique pour le recueil des issues : [github.com/YunoHost/issues](https://github.com/YunoHost/issues) + +YunoHost dispose d’un dépôt Git spécifique pour le recueil des issues : [GitHub.com/YunoHost/issues](https://github.com/YunoHost/issues) Une issue aussi appelé ticket, est un problème identifié ou alors un souhait de développement ; dans le cas présent pour la documentation, mais c’est valable pour tout dépôt logiciel. Dans le cadre de la documentation de YunoHost il sera surtout proposé des issues pour le développement de la documentation, les problèmes identifiés étant facilement corrigeables. ## Aller plus loin avec Git et travailler sur son poste de travail + Utiliser la puissance de Git et ainsi travailler sur son ordinateur personnel, permet entre autres de ne pas avoir à créer de `commit` à chaque enregistrement intermédiaire des pages de documentations modifiées. Cela permet aussi d’utiliser des outils et logiciels qui permettent une distinction plus facile des codes utilisés dans une page de documentation. - Ressource en ligne : [docs.microsoft.com - Configurer un référentiel Git localement pour la documentation](https://docs.microsoft.com/fr-fr/contribute/get-started-setup-local) ## Quelques ressources ailleurs sur le net pour aller plus loin - - [Gérer son code avec Git et GitHub - openclassrooms.com](https://openclassrooms.com/fr/courses/2342361-gerez-votre-code-avec-git-et-github) - - [Interface utilisateurs·trices de Git - git-scm.com](https://git-scm.com/download/gui/linux) + +- [Gérer son code avec Git et GitHub - openclassrooms.com](https://openclassrooms.com/fr/courses/2342361-gerez-votre-code-avec-git-et-github) +- [Interface utilisateurs·trices de Git - git-scm.com](https://git-scm.com/download/gui/linux) diff --git a/pages/06.contribute/05.write_documentation/03.git/doc_use_git.md b/pages/06.contribute/05.write_documentation/03.git/doc_use_git.md index 82a37289..7ea7c220 100644 --- a/pages/06.contribute/05.write_documentation/03.git/doc_use_git.md +++ b/pages/06.contribute/05.write_documentation/03.git/doc_use_git.md @@ -7,13 +7,15 @@ routes: default: '/doc_use_git' --- -It is of course possible to contribute directly to the YunoHost documentation, but this is not the most convenient way to do so for both the contributor and the person who will inject your contribution into the documentation. Here is a tutorial to understand and create a contribution to the YunoHost documentation using [Git](https://git-scm.com/) and [github.com](http://github.com/) which is the Git forge service that hosts and stores the YunoHost source code and documentation. +It is of course possible to contribute directly to the YunoHost documentation, but this is not the most convenient way to do so for both the contributor and the person who will inject your contribution into the documentation. Here is a tutorial to understand and create a contribution to the YunoHost documentation using [Git](https://git-scm.com/) and [GitHub.com](http://github.com/) which is the Git forge service that hosts and stores the YunoHost source code and documentation. + +## Create an account on GitHub.com -## Create an account on github.com To be able to send your contributions via GitHub, you need to have an account on GitHub, to create the account you will need a valid email address that you have access to. GitHub is a powerful tool with many features, the interface can be a little scary at first. You don't have to give your first and last names, you can use a nickname (when you register `Username`). ## Fork the YunoHost documentation in your personal repository + To fork the source code allows you to create a new branch of development of a software source code or in this case the source code of the documentation. By creating a new branch, this allows you to modify the code and add your contributions without altering the code of the `master` branch, which is the public release of the documentation. This allows you not to have to write down everything at once, but to do it in several steps. (Especially for contributions that require more time). Forking a project on GitHub is extremely simple, just click on the Fork button, this will create a new repository on your GitHub account. @@ -21,29 +23,35 @@ Forking a project on GitHub is extremely simple, just click on the Fork button, In the title of the new repository, you will see where the repository comes from, in this case `YunoHost/doc`. ![Screenshots title and subtitle of the repository](image://github_fork_title.png) -> **Point of vigilance !** -> If you forge the repository of another contributor than yunohost, you'll get the same files. Except that when you send your changes, they will be sent to the contributor and not to the yunohost repository. The advantage is that it allows you to develop another branch created by the contributor and work with another person on an improvement before submitting it to the main repository. -> It is not possible to have a fork from a contributor's repository and the original repository fork at the same time in your own account. +! **Point of vigilance !** +! If you forge the repository of another contributor than YunoHost, you'll get the same files. Except that when you send your changes, they will be sent to the contributor and not to the YunoHost repository. The advantage is that it allows you to develop another branch created by the contributor and work with another person on an improvement before submitting it to the main repository. +! It is not possible to have a fork from a contributor's repository and the original repository fork at the same time in your own account. ## Modify and add your contribution + Once the repository is forked (copied), you will need to create a new development branch within your repository. It is through this branch that you will modify the files and thus propose improvements to the documentation. The fact that it is a new branch will allow you to make a Pull Request, i.e. a request to add your contributions to the `master` branch, which is the main documentation branch. The development rules on GitHub change depending on the developers of each repository, some have a testing branch in which to offer contributions. More information on what a branch on git-scm.com is: [Branching with Git - What a branch is](https://git-scm.com/book/fr/v1/Les-branches-avec-Git-Ce-qu-est-une-branche). ## Send your contribution by a Pull Request + Create a Pull Request when you want to share your work with the other contributors and integrate it into the master repository (YunoHost's main repository). When publishing a Pull Request, commonly called PR, contributors will be able to amend, comment, add, correct your contribution before it is fully integrated into the repository. ## Track your contribution and take into account feedback from contributors + When you've already create a Pull Request (PR), changes to your development branch in the Git repository will automatically be added to the PR. This doesn't require any additional action. You can also include proposed changes from contributors, who, when they audit the code, may find errors or new, better wording. ## Bringing up mistakes and wishes through issues -YunoHost has a specific Git repository to collect issues: [github.com/YunoHost/issues](https://github.com/YunoHost/issues) + +YunoHost has a specific Git repository to collect issues: [GitHub.com/YunoHost/issues](https://github.com/YunoHost/issues) An issue, also called a ticket, is an identified problem or a development wish; in this case for documentation, but it is valid for any software repository. Within the framework of the YunoHost documentation it will be mainly proposed issues for the development of the documentation, the identified problems being easily correctable. ## Going further with Git and working on your workstation + Using the power of Git to work on your personal computer means you don't have to create a `commit` each time you save modified documentation pages. It also allows you to use tools and software that make it easier to distinguish between tags used in a documentation page. - Online resource: [docs.microsoft.com - Setting up a Git repository locally for documentation](https://docs.microsoft.com/fr-fr/contribute/get-started-setup-local) ## Some resources elsewhere on the net to go further - - [Managing your code with Git and GitHub - openclassrooms.com](https://openclassrooms.com/fr/courses/2342361-gerez-votre-code-avec-git-et-github) - - [Git User Interface - git-scm.com](https://git-scm.com/download/gui/linux) + +- [Managing your code with Git and GitHub - openclassrooms.com](https://openclassrooms.com/fr/courses/2342361-gerez-votre-code-avec-git-et-github) +- [Git User Interface - git-scm.com](https://git-scm.com/download/gui/linux) diff --git a/pages/06.contribute/05.write_documentation/write_documentation.de.md b/pages/06.contribute/05.write_documentation/write_documentation.de.md index c3cf71c6..3c912c80 100644 --- a/pages/06.contribute/05.write_documentation/write_documentation.de.md +++ b/pages/06.contribute/05.write_documentation/write_documentation.de.md @@ -23,7 +23,7 @@ Unter der Haube wird die Dokumentation vom [Grav CMS](https://getgrav.org/?targe Die Struktur des Repositorys wird nachfolgend beschrieben: -```bash +```text + -- config + -- site.yaml + -- system.yaml @@ -48,15 +48,15 @@ Die Struktur des Repositorys wird nachfolgend beschrieben: # Enthält die Anweisungen, keine sensiblen # oder nutzlosen Dateien an das Git-Repository zu senden + -- README.md -``` +``` -!!!! Weitere Informationen zu den Funktionen von Grav finden Sie in der [Dokumentation](https://learn.getgrav.org?target=_blank). Der Rest dieser Seite zeigt Ihnen einige spezifische Anweisungen, die Sie zur Dokumentation von YunoHost beachten sollten.. +!!!! Weitere Informationen zu den Funktionen von Grav finden Sie in der [Dokumentation](https://learn.getgrav.org?target=_blank). Der Rest dieser Seite zeigt Ihnen einige spezifische Anweisungen, die Sie zur Dokumentation von YunoHost beachten sollten.. -## Grav-Header +## Grav-Header -Jede Seite beginnt mit einem Header, der Grav Anweisungen zur Verarbeitung gibt. Werfen wir einen Blick in die Kopfzeile dieser Seite: +Jede Seite beginnt mit einem Header, der Grav Anweisungen zur Verarbeitung gibt. Werfen wir einen Blick in die Kopfzeile dieser Seite: -``` +```text --- title: Dokumentation schreiben template: docs @@ -65,20 +65,22 @@ taxonomie: routes: default: '/write_documentation' --- -``` +``` + 1. Die Kopfzeile beginnt und endet mit einer Zeile, die `---` enthält 2. Der `title:` verwaltet die erste Titel-Überschrift der Seite, ihren Namen im Navigationsmenü links und den Namen des Browser-Tab`s -3. Die Punkte `template` und `taxonomie` sollten immer unverändert bleiben. Sie weisen Grav an, das richtige Theme zu verwenden und die Seiten richtig auf zu bauen. -4. Die Schlüssel `routes` und `default` machen die Seite standardmäßig unter `https://yunohost.org/docs/write_documentation` verfügbar, um sie nicht unter `https://yunohost.org/docs/contribute/write_documentation` aufrufen zu müssen, wo sie in der Verzeichnishierarchie gespeichert ist. +3. Die Punkte `template` und `taxonomie` sollten immer unverändert bleiben. Sie weisen Grav an, das richtige Theme zu verwenden und die Seiten richtig auf zu bauen. +4. Die Schlüssel `routes` und `default` machen die Seite standardmäßig unter `https://yunohost.org/docs/write_documentation` verfügbar, um sie nicht unter `https://yunohost.org/docs/contribute/write_documentation` aufrufen zu müssen, wo sie in der Verzeichnishierarchie gespeichert ist. -## Syntax +## Syntax Sie können die Markdown-Syntax verwenden. Weitere Informationen finden Sie in der [Dokumentation](/doc_markdown_guide). -! Beachten Sie, dass Sprachcodes nicht am Anfang der Links zu anderen Dokumentationsseiten stehen dürfen: `/en`,` /fr` usw. sind überflüssig. +! Beachten Sie, dass Sprachcodes nicht am Anfang der Links zu anderen Dokumentationsseiten stehen dürfen: `/en`,`/fr` usw. sind überflüssig. -Um die Markdown-Funktionen zu verbessern, werden zusätzliche Plugins in Grav installiert. In der eigenen Dokumentation auf GitHub erfahren Sie, wie Sie sie verwenden. -``` +Um die Markdown-Funktionen zu verbessern, werden zusätzliche Plugins in Grav installiert. In der eigenen Dokumentation auf GitHub erfahren Sie, wie Sie sie verwenden. + +```text anchors external_links flex-objects @@ -88,26 +90,27 @@ markdown-notices presentation presentation-deckset shortcode-core -``` +``` -## Sonderseiten +## Sonderseiten -Einige Seiten der Dokumentation werden automatisch oder dynamisch generiert. +Einige Seiten der Dokumentation werden automatisch oder dynamisch generiert. -| Seite | Pfad | Anmerkungen | +| Seite | Pfad | Anmerkungen | | --------------- | ------- | ------- | -| Apps-Katalog | `/pages/02.applications/01.catalog/apps.md` | Ruft [app.json](https://github.com/YunoHost/apps/blob/master/apps.json?target=_blank) ab und verarbeitet sie | -| Apps-Helfer | `pages/04.contribute/04.packaging_apps/11.helpers/package_apps_helpers.md` | Erstellt von diesem [Skript](https://github.com/YunoHost/yunohost/blob/dev/doc/generate_helper_doc.py?target=_blank) aus dieser [Vorlage](https://github.com/YunoHost/yunohost/blob/dev/doc/helper_doc_template.md?target=_blank) | -| Pro-App-Dokumentation | `pages/02.applications/02.docs/docs.md` | Listet die Unterseiten im selben Verzeichnis auf, deren Header `taxonomy.category: docs, apps` enthält +| Apps-Katalog | `/pages/02.applications/01.catalog/apps.md` | Ruft [app.json](https://github.com/YunoHost/apps/blob/master/apps.json?target=_blank) ab und verarbeitet sie | +| Apps-Helfer | `pages/04.contribute/04.packaging_apps/11.helpers/package_apps_helpers.md` | Erstellt von diesem [Skript](https://github.com/YunoHost/yunohost/blob/dev/doc/generate_helper_doc.py?target=_blank) aus dieser [Vorlage](https://github.com/YunoHost/yunohost/blob/dev/doc/helper_doc_template.md?target=_blank) | +| Pro-App-Dokumentation | `pages/02.applications/02.docs/docs.md` | Listet die Unterseiten im selben Verzeichnis auf, deren Header `taxonomy.category: docs, apps` enthält | ## Hosten Sie Ihre eigene Testdokumentation -! Diese Anweisungen müssen noch vollständig getestet werden. Bitte helfen Sie uns, indem Sie Probleme melden, die Sie möglicherweise mit ihnen haben. +! Diese Anweisungen müssen noch vollständig getestet werden. Bitte helfen Sie uns, indem Sie Probleme melden, die Sie möglicherweise mit ihnen haben. -0. Forken Sie das YunoHost Dokumentations Repository -1. Installieren Sie das YunoHost-Paket Grav : `yunohost app install grav` -2. Installieren Sie die folgenden Plugins durch das Grav Admin-Panel oder CLI: -``` +0. Forken Sie das YunoHost Dokumentations Repository +1. Installieren Sie das YunoHost-Paket Grav : `yunohost app install grav` +2. Installieren Sie die folgenden Plugins durch das Grav Admin-Panel oder CLI: + +```text anchors breadcrumbs external_links @@ -122,27 +125,28 @@ presentation presentation-deckset shortcode-core tntsearch -``` -3. Git Sync Plugin einrichten. +``` + +3. Git Sync Plugin einrichten. 1. Melden Sie sich mit Ihren Anmeldeinformationen auf GitHub an - 2. Legen Sie das Repo fest, z. B. `https://github.com/username/doc`. - 3. Kopieren Sie die URL des Webhooks, z. B. `https://grav.example/_git-sync-ca25c111f0de`. - 4. Grundeinstellungen> Ordner im Sync: `pages`` images` `themes` - 5. Git Repo-Einstellungen> Benutzer nicht erforderlich: Aktiviert - 6. Git Repo-Einstellungen> Web Hooks-Geheimnis: Aktiviert - 7. Erweiterte Einstellungen> Lokaler Branch:`master` + 2. Legen Sie das Repo fest, z. B. `https://github.com/username/doc`. + 3. Kopieren Sie die URL des Webhooks, z. B. `https://grav.example/_git-sync-ca25c111f0de`. + 4. Grundeinstellungen> Ordner im Sync: `pages`` images` `themes` + 5. Git Repo-Einstellungen> Benutzer nicht erforderlich: Aktiviert + 6. Git Repo-Einstellungen> Web Hooks-Geheimnis: Aktiviert + 7. Erweiterte Einstellungen> Lokaler Branch:`master` 8. Erweiterte Einstellungen> Remote Branch: `master` - (Sie können` master` ändern, wenn Sie an einem anderen Zweig arbeiten möchten, aber vergessen Sie nicht, ihn zuerst auf GitHub zu erstellen.) + (Sie können`master` ändern, wenn Sie an einem anderen Zweig arbeiten möchten, aber vergessen Sie nicht, ihn zuerst auf GitHub zu erstellen.) 9. Erweiterte Einstellungen> Committer-Name: Ihr GitHub-Benutzername - 10. Erweiterte Einstellungen> Committer-E-Mail : Ihre E-Mail auf GitHub + 10. Erweiterte Einstellungen> Committer-E-Mail : Ihre E-Mail auf GitHub 4. Lokale Kopie speichern und zurücksetzen -5. Konfigurieren Sie `commits` und `tree` in `config/theme/yunohost-docs.yaml`, so das sie auf Ihren Fork des Repositorys verweisen. -6. Stellen Sie sicher, dass die Verzeichnisse `user/pages/01.home` und `user/pages/02.typography` gelöscht werden. -7. Konfiguration> System: - 1. Sprache> Unterstützt: `en` `fr` `de` `es` `ar` - 2. Sprache> Standardsprache überschreiben:` en` - 3. Sprache> Sprache vom Browser einstellen: `Ja` - 4. HTTP-Header> Etag: `Ja` - 5. Erweitert> Blueprint-Kompatibilität:` Ja` - 6. Erweitert> YAML-Kompatibilität: `Ja` - 7. Erweitert> Twig-Kompatibilität:` Ja` +5. Konfigurieren Sie `commits` und `tree` in `config/theme/yunohost-docs.yaml`, so das sie auf Ihren Fork des Repositorys verweisen. +6. Stellen Sie sicher, dass die Verzeichnisse `user/pages/01.home` und `user/pages/02.typography` gelöscht werden. +7. Konfiguration> System: + 1. Sprache> Unterstützt: `en` `fr` `de` `es` `ar` + 2. Sprache> Standardsprache überschreiben:`en` + 3. Sprache> Sprache vom Browser einstellen: `Ja` + 4. HTTP-Header> Etag: `Ja` + 5. Erweitert> Blueprint-Kompatibilität:`Ja` + 6. Erweitert> YAML-Kompatibilität: `Ja` + 7. Erweitert> Twig-Kompatibilität:`Ja` diff --git a/pages/06.contribute/05.write_documentation/write_documentation.fr.md b/pages/06.contribute/05.write_documentation/write_documentation.fr.md index 7249951e..485cc5ff 100644 --- a/pages/06.contribute/05.write_documentation/write_documentation.fr.md +++ b/pages/06.contribute/05.write_documentation/write_documentation.fr.md @@ -23,7 +23,7 @@ Sous le capot, la documentation est déployée avec le [CMS Grav](https://getgra La structure du dépôt est décrite ici: -```bash +```text +-- config +-- site.yaml +-- system.yaml @@ -56,7 +56,7 @@ La structure du dépôt est décrite ici: Chaque page commence par un en-tête qui donne les instructions à Grav sur comment la traiter. Regardons l'en-tête de cette page : -``` +```text --- title: Rédaction de la documentation template: docs @@ -80,6 +80,7 @@ Vous pouvez utiliser la syntaxe Markdown, consultez la page de [documentation d ! Notez qu'il ne faut pas préciser le code de langue au début des liens vers d'autres pages de la documentation : `/fr`, `/en`, etc. sont superflus. Pour étendre les fonctionnalités de Markdown, des extensions ont été ajoutées à Grav. Vous pouvez consulter leur propre documentation sur GitHub pour découvrir comment vous en servir. + ```text anchors external_links @@ -109,6 +110,7 @@ Quelques pages de la documentation sont générées automatiquement ou dynamique 0. *Fork* le dépôt de la documentation YunoHost sur GitHub 1. Installez l'app Grav pour YunoHost : `yunohost app install grav` 2. Installez les extensions suivantes via l'admin ou la ligne de commande de Grav : + ```text anchors breadcrumbs @@ -125,6 +127,7 @@ presentation-deckset shortcode-core tntsearch ``` + 3. Paramétrez l'extension Git Sync. 1. Choisissez `GitHub` et vos identifiants GitHub 2. Entrez l'adresse de votre *fork*, par exemple `https://github.com/username/doc` @@ -136,9 +139,9 @@ tntsearch 8. "Advanced settings" > "remote branch" : `master` (vous pouvez changer `master` en une autre branche si vous le souhaitez, mais n'oubliez pas de la créer au préalable sur GitHub) 9. "Advanced settings" > "Committer Name" : votre nom d'utilisateur sur GitHub - 10. "Advanced settings" > "Committer Email" : votre email renseigné sur GitHub - 11. Enregistrez et cliquez sur "Reset Local Copy" - 12. Renseignez les adresses dans les clés `commits` et `tree` dans `config/themes/yunohost-docs.yaml` pour quelles pointent vers l'adresse de votre *fork* sur GitHub +10. "Advanced settings" > "Committer Email" : votre email renseigné sur GitHub +11. Enregistrez et cliquez sur "Reset Local Copy" +12. Renseignez les adresses dans les clés `commits` et `tree` dans `config/themes/yunohost-docs.yaml` pour quelles pointent vers l'adresse de votre *fork* sur GitHub 4. Assurez-vous que les dossiers `user/pages/01.home` et `user/pages/02.typography` sont supprimés. 5. Dans l'administration de Grav, dans "Configuration" > "System" : 1. "Language" > "Supported" : `en` `fr` `de` `es` `ar` diff --git a/pages/06.contribute/05.write_documentation/write_documentation.md b/pages/06.contribute/05.write_documentation/write_documentation.md index a1fbc4b2..ba9fb2d8 100644 --- a/pages/06.contribute/05.write_documentation/write_documentation.md +++ b/pages/06.contribute/05.write_documentation/write_documentation.md @@ -24,7 +24,7 @@ Under the hood, the documentation is served by the [Grav CMS](https://getgrav.or The structure of the repository is described below: -```bash +```text +-- config +-- site.yaml +-- system.yaml @@ -57,7 +57,7 @@ The structure of the repository is described below: Each page starts with a header that gives instructions to Grav on how to process them. Let us have a look into the header of this page: -``` +```text --- title: Write documentation template: docs @@ -81,6 +81,7 @@ You can use Markdown syntax, refer to the [documentation](/doc_markdown_guide) f ! Note that language codes are not to be included at the beginning of the links to other documentation pages: `/en`, `/fr`, etc. are superfluous. To improve Markdown capabilities, additional plugins are installed in Grav. You can refer to their own documentation on GitHub to see how to use them. + ```text anchors external_links @@ -110,6 +111,7 @@ Some pages of the documentation are automatically or dynamically generated. 0. Fork YunoHost documentation repository 1. Install Grav's YunoHost package: `yunohost app install grav` 2. Install the following plugins through Grav's admin panel or CLI: + ```text anchors breadcrumbs @@ -126,6 +128,7 @@ presentation-deckset shortcode-core tntsearch ``` + 3. Set-up Git Sync plugin. 1. Choose GitHub and your credentials on GitHub 2. Set the repo, e.g. `https://github.com/username/doc` @@ -137,9 +140,9 @@ tntsearch 8. Advanced settings > remote branch: `master` (you can change `master` if you want to work on another branch, but do not forget to create it on GitHub first) 9. Advanced settings > Committer Name: your GitHub username - 10. Advanced settings > Committer Email: your email saved on GitHub - 11. Save and Reset Local Copy - 12. Set `commits` and `tree` keys in `config/themes/yunohost-docs.yaml` to point to your fork's repository +10. Advanced settings > Committer Email: your email saved on GitHub +11. Save and Reset Local Copy +12. Set `commits` and `tree` keys in `config/themes/yunohost-docs.yaml` to point to your fork's repository 4. Make sure `user/pages/01.home` and `user/pages/02.typography` directories are deleted. 5. Configuration > System: 1. Language > Supported: `en` `fr` `de` `es` `ar` diff --git a/pages/06.contribute/10.packaging_apps/10.manifest/docs.md b/pages/06.contribute/10.packaging_apps/10.manifest/docs.md index 20abfbd2..c9563b87 100644 --- a/pages/06.contribute/10.packaging_apps/10.manifest/docs.md +++ b/pages/06.contribute/10.packaging_apps/10.manifest/docs.md @@ -33,7 +33,7 @@ maintainers = ["alexAubin"] - `name` (`str`) is the display name of the app, shown for example in the webadmin UI or user portal. It is limited to 22 chars (though not sure why this number?). - `description` (`dict` of `lang code`->`str`) contains *short*, *concise* descriptions of the app in different languages (at least `en`). It is limited to 150 chars. It will be displayed on the app catalog and should allow people to understand what this app is about at a glance. A more extensive description of the app can be provided in `doc/DESCRIPTION.md`. - `version` (`str`) is composed of the *upstream* version of the app shipped, and an `~ynhX` suffix. Changing this version is what effectively triggers an available upgrade for YunoHost instances which installed this package (hence no upgrade will be displayed as available if you forget to change it). The point of the `~ynhX` suffix is to have a way to increment the version when commiting changes unrelated to the upstream but still trigger an upgrade. -- `maintainers` (`list` or `str`) may allow to declare which person should be the referring person for this package (though packages are often maintained collectively and not really used in practice). This should contain a list of easily identifiable persons (eg your Github or Matrix username) +- `maintainers` (`list` or `str`) may allow to declare which person should be the referring person for this package (though packages are often maintained collectively and not really used in practice). This should contain a list of easily identifiable persons (eg your GitHub or Matrix username) ## Upstream section @@ -88,7 +88,7 @@ ram.runtime = "1M" This section is completely optional and, for most apps, doesn't exist at all. -Some applications have limitations, they might be due to non-free dependencies, arbitrary limitations, etc. Yunohost provides UI in the catalog to show such antifeatures. +Some applications have limitations, they might be due to non-free dependencies, arbitrary limitations, etc. YunoHost provides UI in the catalog to show such antifeatures. The declaration of antifeatures is a 3-steps process: @@ -104,7 +104,6 @@ The declaration of antifeatures is a 3-steps process: The format of this section is a `dict` where keys are antifeature IDs, and the values are translated strings (`dict` of `lang code`->`str`). - ## Install questions This section contains questions that should be asked to the admin prior to starting the actual install @@ -135,17 +134,17 @@ This section contains questions that should be asked to the admin prior to start ``` - `domain` and `path` (with `type = "domain"/"path"`) are classic questions to allow the admin to choose where the app is installed (in terms of web url endpoint) - - e.g. if the admin answers `domain.tld` and `/foobar`, the app will be available under `domain.tld/foobar` - - some webapp do require a full dedicated domain and do not support the "subpath" install scheme. In that case, you typically want to remove the `path` question entirely - - these questions are part of YunoHost's generic app questions and therefore you do not need to define the `ask.en` strings that contain the actual question displayed in the UI along the line of "Choose a domain to install this app on" + - e.g. if the admin answers `domain.tld` and `/foobar`, the app will be available under `domain.tld/foobar` + - some webapp do require a full dedicated domain and do not support the "subpath" install scheme. In that case, you typically want to remove the `path` question entirely + - these questions are part of YunoHost's generic app questions and therefore you do not need to define the `ask.en` strings that contain the actual question displayed in the UI along the line of "Choose a domain to install this app on" - `init_main_permission` is also a classic question (similar to `is_public` in v1 packaging) and define what user group will be able to access the app after it is installed. Typical answer are : `visitors` (= everybody including anonymous users, the app is "public"), `all_users` (= only people with a YunoHost account, the app is "private"), or any custom user group that may have been defined by the YunoHost admins prior to the install. - `prefered_pet` is a custom question: - - `ask.en` defines the human-readable question to be asked (at least the english version) - - `help.en` is an optional additional message to provide further info about this question - - `type` is the type of question, in this case `string` - - in this example, we don't want a free user input but choosing between `cat`, `dog` or `both` (with proper human-readable versions of these choices) - - this will later automatically create a yunohost app setting named `prefered_pet` - - .. and in the bash install script, the bash variable will automatically be available `$prefered_pet` with the chosen value + - `ask.en` defines the human-readable question to be asked (at least the english version) + - `help.en` is an optional additional message to provide further info about this question + - `type` is the type of question, in this case `string` + - in this example, we don't want a free user input but choosing between `cat`, `dog` or `both` (with proper human-readable versions of these choices) + - this will later automatically create a YunoHost app setting named `prefered_pet` + - .. and in the bash install script, the bash variable will automatically be available `$prefered_pet` with the chosen value ### Regarding install question types @@ -180,6 +179,7 @@ The resource section corresponds to recurring app needs that are to be provision ``` In this example: + - `sources.main`: the URL+checksum from which the app sources will be downloaded + validated - `system_user`: a system (unix) user will be created for this app, using the app id as username. - `install_dir`: an install dir will be initialized, named `/var/www/$app` by default. Additional `owner` and `group` property allow to change the owner/group and r/w/x permissions on the created folder. diff --git a/pages/06.contribute/10.packaging_apps/20.scripts/scripts.md b/pages/06.contribute/10.packaging_apps/20.scripts/scripts.md index 6901d3bc..69910348 100644 --- a/pages/06.contribute/10.packaging_apps/20.scripts/scripts.md +++ b/pages/06.contribute/10.packaging_apps/20.scripts/scripts.md @@ -59,7 +59,6 @@ ynh_add_nginx_config Note that the scripts are run with the `set -eu` options (except for the remove script), which means that any failing command or use of non-existing variable will trigger an error and stop the script execution. - ## Variables available in a script context Special variables are automatically defined in the context of a script: @@ -70,7 +69,6 @@ Special variables are automatically defined in the context of a script: - Note that some settings are automatically created/updated by app ressources. For example, the `install_dir` setting will automatically be available too and corresponds to typically `/var/www/$app` - In the `change_url` context, variables called `new_domain`, `new_path`, `old_domain`, `old_path` will be available, as well as `change_domain` and `change_path` equal to `0` (false) or `1` (true) depending if the domain / path changed - ## Setting system Application often need to store long term information in between scripts triggered by the admin. For this, YunoHost has a key-value store for each application called "setting" and is stored in `/etc/yunohost/apps/$app/settings.yml`. @@ -127,7 +125,6 @@ location __PATH__/ { } ``` - ## App sources App sources were historically defined in `conf/app.src` files containing the URL + checksum of assets to download. @@ -147,10 +144,17 @@ More infos on the `source` resource in [the resource system documentation](/pack ## Common operations (TODO/FIXME) #### installing/upgrading app sources + #### adding configurations + #### adding a systemd service + #### curl / automatizing install forms + #### classic stuff for nodejs apps + #### classic stuff for php apps + #### classic stuff for python apps + #### classic stuff for ??? apps diff --git a/pages/06.contribute/10.packaging_apps/30.doc/doc.md b/pages/06.contribute/10.packaging_apps/30.doc/doc.md index d65ec0de..68ed47cc 100644 --- a/pages/06.contribute/10.packaging_apps/30.doc/doc.md +++ b/pages/06.contribute/10.packaging_apps/30.doc/doc.md @@ -23,7 +23,7 @@ You can add subfolders such as `doc/screenshots/subfolder` to add pictures in yo You can also add translated versions of the `.md` file in, for example, `doc/DESCRIPTION_fr.md`, `_es.md`, `_it.md`, etc. -If your app repository is part of the YunoHost-Apps org, the provided description will be used to auto-regenerate the README.md of your github repo via `yunohost-bot`. +If your app repository is part of the YunoHost-Apps org, the provided description will be used to auto-regenerate the README.md of your GitHub repo via `yunohost-bot`. ## Specific notes for admins : `doc/ADMIN.md`, `doc/.md` diff --git a/pages/06.contribute/10.packaging_apps/40.testing/testing.md b/pages/06.contribute/10.packaging_apps/40.testing/testing.md index 9125bfe9..834040d8 100644 --- a/pages/06.contribute/10.packaging_apps/40.testing/testing.md +++ b/pages/06.contribute/10.packaging_apps/40.testing/testing.md @@ -22,11 +22,12 @@ It is pretty straightforward to run considering that you should only need Python ## Package check [Package check](https://github.com/YunoHost/package_check) is a more elaborate software that will tests many scenarios for you app such as: + - installing, removing and reinstalling your app + validating that the app can indeed be accessed on its URL endpoint (with no 404/502 error) - - when installing on a root domain (`domain.tld/`) - - when installing in a domain subpatch (`domain.tld/foobar`) - - installing in private mode - - installing multiple instances + - when installing on a root domain (`domain.tld/`) + - when installing in a domain subpatch (`domain.tld/foobar`) + - installing in private mode + - installing multiple instances - upgrading from the same version - upgrading from older versions - backup/restore @@ -60,19 +61,18 @@ While this definition may vary with time, the current definition as of February - level 7 (« All tests succeeded + No linter warning ») : Pass all test (including for example upgrade from past commits) and no warning reported by the linter - level 8 (« Maintained and long-term good quality ») : The app is not flagged as not-maintained / alpha / deprecated / obsolete in the catalog, and has been at least level 5 during the past ~year - ## Continous integration (CI) The YunoHost project also developed an interface called [`yunorunner`](https://github.com/YunoHost/yunorunner) which interfaces with `package_check`, handles a job queue, and automatically add jobs to the queue using some triggers. The two major ones are: + - [The "official" CI](https://ci-apps.yunohost.org/ci): This where the "official" quality level of each app comes from. Jobs are triggered after each commit on the repo's master branch. - [The "dev" CI](https://ci-apps-dev.yunohost.org/ci/): This is where people validate their pull request which is often more convenient than running `package_check` yourself, and has the advantage of the results being automatically public, which facilitates collective debugging. Members of the YunoHost-Apps organization can trigger jobs on the dev CI directly from a pull request simply by commenting something like `!testme` (cf for example [here](https://github.com/YunoHost-Apps/nextcloud_ynh/pull/532#issuecomment-1402751409)). A .png summary of the tests will be automatically displayed once the job completes (and you can click the link to see the entire job execution and debug it). - -#### Why create `package_check` + `yunorunner` rather than using well-known solutions like Gitlab-CI ? +### Why create `package_check` + `yunorunner` rather than using well-known solutions like Gitlab-CI ? Constrain 1 : Gitlab-CI or other similar solutions are mostly based around Docker, while we use LXC. In particular, we do want to reuse LXC snapshots of successful install during other tests (upgrade, backup/restore, ..) rather than reinstalling the app from scratch everytime, which drastically reduces the test time. We could do so using Gitlab artifacts, but such artifacts are automatically made public which is not convenient because they contain a full filesystem and their only use it to speed up the test process. Moreover, in the Gitlab-CI paradigm, jobs are not running on the same machine and they would need to download the snapshot which can be lengthy. The other mechanism, caching, is explicitly advertised as not reliable in Gitlab's-CI doc. What would be helpful would be some non-public artifact system (see similar discussion [here](https://gitlab.com/gitlab-org/gitlab-runner/-/issues/336)) diff --git a/pages/06.contribute/10.packaging_apps/50.publishing/publishing.md b/pages/06.contribute/10.packaging_apps/50.publishing/publishing.md index 2ffce557..baccfe79 100644 --- a/pages/06.contribute/10.packaging_apps/50.publishing/publishing.md +++ b/pages/06.contribute/10.packaging_apps/50.publishing/publishing.md @@ -11,6 +11,6 @@ The official YunoHost's app catalog is maintained [in this repository](https://g For your app to be made available to everybody, you should make a pull request that adds your app inside the `apps.toml` (see the [detailed instructions in the README](https://github.com/YunoHost/apps/#how-to-add-your-app-to-the-application-catalog)) -Note that the "real" catalog used by YunoHost servers is https://app.yunohost.org/default/v3/apps.json which is rebuilt every 4 hours. +Note that the "real" catalog used by YunoHost servers is which is rebuilt every 4 hours. NB: The `level` key is not to be set manually by maintainers. The `yunohost-bot` will [automatically create a pull request](https://github.com/YunoHost/apps/blob/master/tools/update_app_levels/update_app_levels.py) every Friday evening with results from the official CI, which are then to be manually reviewed and merged by the community. diff --git a/pages/06.contribute/10.packaging_apps/60.advanced/20.config_panels/config_panels.md b/pages/06.contribute/10.packaging_apps/60.advanced/20.config_panels/config_panels.md index c022bebf..7a52e2c0 100644 --- a/pages/06.contribute/10.packaging_apps/60.advanced/20.config_panels/config_panels.md +++ b/pages/06.contribute/10.packaging_apps/60.advanced/20.config_panels/config_panels.md @@ -20,6 +20,7 @@ To create configuration panels for apps, you should at least create a `config_pa The `config_panel.toml` describes one or several panels, containing sections, each containing questions generally binded to a params in the app's actual configuration files. Let's imagine that the upstream app is configured using this simple `config.yml` file stored in the app's install directory (typically `/var/www/$app/config.yml`): + ```yaml title: 'My dummy app' theme: 'white' @@ -28,6 +29,7 @@ max_age: 365 ``` We could for example create a simple configuration panel for it like this one, by following the syntax `[PANEL.SECTION.QUESTION]`: + ```toml version = "1.0" [main] @@ -61,10 +63,12 @@ Here we have created one `main` panel, containing the `main` and `limits` sectio ### Questions short keys have to be unique For performance reasons, questions short keys have to be unique in all the `config_panel.toml` file, not just inside its panel or its section. Hence it's not possible to have: + ```toml [manual.vpn.server_ip] [advanced.dns.server_ip] ``` + In which two questions have "real variable name" `is server_ip` and therefore conflict with each other. ! Some short keys are forbidden cause it can interfer with config scripts (`old`, `file_hash`, `types`, `binds`, `formats`, `changed`) and you probably should avoid to use common settings name to avoid to bind your question to this settings (e.g. `id`, `install_time`, `mysql_pwd`, `path`, `domain`, `port`, `db_name`, `current_revision`, `admin`) @@ -73,7 +77,6 @@ In which two questions have "real variable name" `is server_ip` and therefore co See [the full list of questions types and properties](/dev/forms) - ### Reading and writing values You can read and write values with 2 mechanisms: the `bind` property in the `config_panel.toml` and for complex use cases the getter/setter in a `config` script. @@ -99,6 +102,7 @@ bind = ":__INSTALL_DIR__/config.yml" In which case, YunoHost will look for something like a key/value, with the key being `theme`. If the question id in the config panel (here, `theme`) differs from the key in the actual conf file (let's say it's not `theme` but `css_theme`), then you can write: + ```toml [main.main.theme] # (other properties ommited) @@ -107,7 +111,8 @@ bind = "css_theme:__FINALPATH__/config.yml" !!!! Note: This mechanism is quasi language agnostic and will use regexes to find something that looks like a key=value or common variants. However, it does assume that the key and value are stored on the same line. It doesn't support multiline text or file in a variable with this method. If you need to save multiline content in a configuration variable, you should create a custom getter/setter (see below). -Nested syntax is also supported, which may be useful for example to remove ambiguities about stuff looking like: +Nested syntax is also supported, which may be useful for example to remove ambiguities about stuff looking like: + ```json { "foo": { @@ -119,7 +124,7 @@ Nested syntax is also supported, which may be useful for example to remove ambig } ``` -which we can `bind` to using: +which we can `bind` to using: ```toml bind = "foo>max:__INSTALL_DIR__/conf.json" @@ -128,6 +133,7 @@ bind = "foo>max:__INSTALL_DIR__/conf.json" #### Read / write an entire file Useful when using a question `file` or `text` for which you want to save the raw content directly as a file on the system. + ```toml [main.main.logo] # (other properties ommited) @@ -137,13 +143,14 @@ bind = "__INSTALL_DIR__/img/logo.png" ### Custom getter / setter Sometimes the `bind` mechanism is not enough: - * the config file format is not supported (e.g. xml, csv) - * the data is not contained in a config file (e.g. database, directory, web resources...) - * the data should be written but not read (e.g. password) - * the data should be read but not written (e.g. fetching status information) - * we want to change other things than the value (e.g. the choices list of a select) - * the question answer contains several values to dispatch in several places - * and so on + +- the config file format is not supported (e.g. xml, csv) +- the data is not contained in a config file (e.g. database, directory, web resources...) +- the data should be written but not read (e.g. password) +- the data should be read but not written (e.g. fetching status information) +- we want to change other things than the value (e.g. the choices list of a select) +- the question answer contains several values to dispatch in several places +- and so on You can create specific getter/setters functions inside the `scripts/config` of your app to customize how the information is read/written. @@ -161,9 +168,10 @@ ynh_app_config_run $1 #### Getter -A question's getter is the function used to read the current value/state. Custom getters are defined using bash functions called `getter__QUESTION_SHORT_KEY()` which returns data through stdout. +A question's getter is the function used to read the current value/state. Custom getters are defined using bash functions called `getter__QUESTION_SHORT_KEY()` which returns data through stdout. Stdout can generated using one of those formats: + 1) either a raw format, in which case the return is binded directly to the value of the question 2) or a yaml format, in this case you dynamically provide properties for your question (for example the `style` of an `alert`, the list of available `choices` of a `select`, etc.) @@ -184,11 +192,13 @@ get__timezone() { echo "$(cat /etc/timezone)" } ``` + [/details] [details summary="Basic example with yaml-formated stdout : Display a list of available plugins" class="helper-card-subtitle text-muted"] `config_panel.toml` + ```toml [main.plugins.plugins] ask = "Plugin to activate" @@ -238,6 +248,7 @@ EOF fi } ``` + [/details] #### Setter @@ -264,6 +275,7 @@ set__timezone() { ynh_print_info "The timezone has been changed to $timezone" } ``` + [/details] ## Validation @@ -271,12 +283,14 @@ set__timezone() { You will often need to validate data answered by the user before to save it somewhere. Validation can be made with regex through `pattern` argument + ```toml pattern.regexp = '^.+@.+$' pattern.error = 'An email is required for this field' ``` You can also restrict several types with a choices list. + ```toml choices.foo = "Foo (some explanation)" choices.bar = "Bar (moar explanation)" @@ -291,6 +305,7 @@ Some other type specific argument exist like | `boolean` | `yes` `no` | Finally, if you need specific or multi variable validation, you can use custom validators function: + ```bash validate__login_user() { if [[ "${#login_user}" -lt 4 ]]; then echo 'User login is too short, should be at least 4 chars'; fi @@ -330,10 +345,11 @@ ynh_app_config_apply() { ``` List of main configuration helpers - * `ynh_app_config_get` - * `ynh_app_config_show` - * `ynh_app_config_validate` - * `ynh_app_config_apply` - * `ynh_app_config_run` + +- `ynh_app_config_get` +- `ynh_app_config_show` +- `ynh_app_config_validate` +- `ynh_app_config_apply` +- `ynh_app_config_run` More info on this can be found by reading [vpnclient_ynh config script](https://github.com/YunoHost-Apps/vpnclient_ynh/blob/master/scripts/config) diff --git a/pages/06.contribute/10.packaging_apps/60.advanced/30.sso_ldap_integration/sso_ldap_integration.md b/pages/06.contribute/10.packaging_apps/60.advanced/30.sso_ldap_integration/sso_ldap_integration.md index 249a7311..7fd57c01 100644 --- a/pages/06.contribute/10.packaging_apps/60.advanced/30.sso_ldap_integration/sso_ldap_integration.md +++ b/pages/06.contribute/10.packaging_apps/60.advanced/30.sso_ldap_integration/sso_ldap_integration.md @@ -10,6 +10,7 @@ routes: One powerful aspect of YunoHost is that apps are meant to be integrated with the SSO/LDAP stack, such that users logged in on YunoHost's user portal can be directly logged in each app without having to create an account in each of them nor having to re-log in each app every time. It should be stressed that there are two different aspects here: + - the LDAP integration, meaning that the user accounts in the app are directly mapped to YunoHost user accounts - the SSO integration, meaning that a user logged in on the YunoHost user portal is automatically logged in on the app as well. @@ -44,10 +45,8 @@ fastcgi_param REMOTE_USER $remote_user; `$remote_user` being a special variable in NGINX that maps to the user provided in the HTTP Basic Auth headers. The PHP application will then use the `HTTP_REMOTE_USER` info in its code. - TODO/FIXME: moar explanations of how this is done for non-PHP apps? - ## Configuring SSOwat permissions for the app SSOwat permissions are configured using the 'permission' resource in your app's manifest.toml @@ -69,7 +68,6 @@ admin.allowed = "admins" # Initialize the access for the "admins" group ... Yo See the page about app resources for the full description of behavior and properties. - ## Logging out on the app vs. Logging out of YunoHost A common [known issue](https://github.com/YunoHost/issues/issues/501) is that sometimes, logging out of YunoHost apps will not log people out of every app. This is for example the case for [Nextcloud](https://github.com/YunoHost-Apps/nextcloud_ynh/issues/19), because it uses its own authentication cookies which are not cleared when people log out of YunoHost. This is not trivial to fix. diff --git a/pages/06.contribute/10.packaging_apps/60.advanced/50.hooks/packaging_apps_hooks.fr.md b/pages/06.contribute/10.packaging_apps/60.advanced/50.hooks/packaging_apps_hooks.fr.md index 5bbb3490..446fdddc 100644 --- a/pages/06.contribute/10.packaging_apps/60.advanced/50.hooks/packaging_apps_hooks.fr.md +++ b/pages/06.contribute/10.packaging_apps/60.advanced/50.hooks/packaging_apps_hooks.fr.md @@ -11,26 +11,32 @@ YunoHost comprend un mécanisme de hooks déclenchés lors de nombreuses opérat Le cas le plus évident est l'ajout d'un utilisateur. Si vous aviez un hook `post_user_create`, ce hook sera déclenché dès qu'un utilisateur sera ajouté. ## Comment ajouter un hook personnalisé sur une instance spécifique + !!! Nous imaginons ci-dessous que nous voulons lancer une commande après chaque création d'utilisateur pour ajouter l'utilisateur à l'utilisateur samba. Vous devez créer un répertoire avec le nom des hooks dans `/etc/yunohost/hooks.d/` : -``` + +```bash mkdir -p /etc/yunohost/hooks.d/post_user_create ``` Créez ensuite un script bash à l'intérieur de ce répertoire, préfixé par 2 chiffres et un tiret : + ```bash nano /etc/yunohost/hooks.d/post_user_create/05-add-user-to-samba ``` ## Comment ajouter un hook dans un paquetage d'application + Si vous empaquetez une application, vous ne devez pas mettre vous-même le hook dans `/etc/yunohost/hooks.d` mais vous devez créer un répertoire hooks à la racine de votre paquet. -``` + +```text . ├─── conf ├─── hooks ├── scripts ``` + Dans le dossier des hooks, créer un script bash appelé avec le type de hook que vous voulez créer par exemple `post_create_user`. ## -> [Liste des hooks et leurs variables](https://yunohost.org/en/packaging_apps_hooks) diff --git a/pages/06.contribute/10.packaging_apps/60.advanced/50.hooks/packaging_apps_hooks.md b/pages/06.contribute/10.packaging_apps/60.advanced/50.hooks/packaging_apps_hooks.md index 4894506d..814dcc9b 100644 --- a/pages/06.contribute/10.packaging_apps/60.advanced/50.hooks/packaging_apps_hooks.md +++ b/pages/06.contribute/10.packaging_apps/60.advanced/50.hooks/packaging_apps_hooks.md @@ -12,28 +12,33 @@ YunoHost includes a hook mechanism triggered on a lot of operation changing the The most obvious case is adding a user. If you had a `post_user_create` hook, this hook will be triggered as soon as a user is added. ## How to add a custom hook on a specific instance + !!! Below we imagine we want to run a command after each user creation to add the user to samba user. You should create a directory with the name of the hooks into `/etc/yunohost/hooks.d/`: -``` + +```bash mkdir -p /etc/yunohost/hooks.d/post_user_create ``` - Next create a bash script inside this directory prefixed by 2 numbers and a dash: + ```bash nano /etc/yunohost/hooks.d/post_user_create/05-add-user-to-samba ``` By default, the directory must be readable and traversable by root, but if you notice your hook is not run at all by YunoHost, you can check permissions with `ls -l /etc/yunohost/hooks.d/` and apply these commands if needed: -``` + +```bash chown root:root /etc/yunohost/hooks.d/post_user_create chmod u+rx /etc/yunohost/hooks.d/post_user_create ``` ## How to add a hook in an app package + If you are packaging an app, you should not set by yourself the hook into `/etc/yunohost/hooks.d` instead you should create a hooks dir at the root of your package. -``` + +```text . ├── conf ├── hooks @@ -43,30 +48,34 @@ If you are packaging an app, you should not set by yourself the hook into `/etc/ In the hooks dir, create a bash script called with the type of hook you want to create for example `post_create_user`. ## Hooks referencies + ### User and permissions + #### post_user_create + [details summary="Triggered after user creation" class="helper-card-subtitle text-muted"] This hook is run at the end of the command `yunohost user create` or equivalent action in webadmin. ##### Environment variables - - YNH_USER_USERNAME: The username of the created user - - YNH_USER_MAIL: The mail of the created user - - YNH_USER_PASSWORD: The **clear** password of the created user - - YNH_USER_FIRSTNAME: The firstname of the created user ([should be removed in future](https://github.com/YunoHost/issues/issues/296)) - - YNH_USER_LASTNAME: The lastname of the created user ([should be removed in future](https://github.com/YunoHost/issues/issues/296)) +- YNH_USER_USERNAME: The username of the created user +- YNH_USER_MAIL: The mail of the created user +- YNH_USER_PASSWORD: The **clear** password of the created user +- YNH_USER_FIRSTNAME: The firstname of the created user ([should be removed in future](https://github.com/YunoHost/issues/issues/296)) +- YNH_USER_LASTNAME: The lastname of the created user ([should be removed in future](https://github.com/YunoHost/issues/issues/296)) ##### Positionnal arguments (deprecated) - - $1: The username of the created user - - $2: The mail of the created user +- $1: The username of the created user +- $2: The mail of the created user ##### No waited return ##### Examples ###### Send automatically a mail to new user + ```bash #!/bin/bash domain=$(cat /etc/hostname) @@ -80,11 +89,11 @@ The admin of $domain echo $message | mail -s "Welcome on $domain !" $YNH_USER_MAIL ``` + [/details] - - #### post_user_delete + [details summary="Triggered at the end of user deletion" class="helper-card-subtitle text-muted"] This hook is run at the end of the command `yunohost user delete` or equivalent action in webadmin. @@ -93,22 +102,23 @@ This hook is run at the end of the command `yunohost user delete` or equivalent ##### Positionnal arguments - - $1: The username of the user deleted - - $2: True if --purge option is used +- $1: The username of the user deleted +- $2: True if --purge option is used ##### No waited return ##### Examples -###### +###### + ```bash #!/bin/bash ``` + [/details] - - ### post_user_update + [details summary="Triggered at the end of the user update" class="helper-card-subtitle text-muted"] This hook is run at the end of the command `yunohost user update` or equivalent action in webadmin. @@ -116,13 +126,14 @@ This hook is run at the end of the command `yunohost user update` or equivalent ##### Environment variables ! Only arguments given to the cli/api are given as environment variable. - - YNH_USER_USERNAME: The username of the updated user - - YNH_USER_FIRSTNAME: The firstname of the updated user ([should be removed in future](https://github.com/YunoHost/issues/issues/296)) - - YNH_USER_LASTNAME: The lastname of the updated user ([should be removed in future](https://github.com/YunoHost/issues/issues/296)) - - YNH_USER_PASSWORD: The new password of the updated user - - YNH_USER_MAILS: The mail and mail aliases of the updated user seperated by comma - - YNH_USER_MAILFORWARDS: The list of forward mails of the updated user separated by comma - - YNH_USER_MAILQUOTA: The quota of the updated user (could be 0 or a number following by one of this unit: b, k, M, G or T) + +- YNH_USER_USERNAME: The username of the updated user +- YNH_USER_FIRSTNAME: The firstname of the updated user ([should be removed in future](https://github.com/YunoHost/issues/issues/296)) +- YNH_USER_LASTNAME: The lastname of the updated user ([should be removed in future](https://github.com/YunoHost/issues/issues/296)) +- YNH_USER_PASSWORD: The new password of the updated user +- YNH_USER_MAILS: The mail and mail aliases of the updated user seperated by comma +- YNH_USER_MAILFORWARDS: The list of forward mails of the updated user separated by comma +- YNH_USER_MAILQUOTA: The quota of the updated user (could be 0 or a number following by one of this unit: b, k, M, G or T) ##### No positionnal arguments @@ -131,6 +142,7 @@ This hook is run at the end of the command `yunohost user update` or equivalent ##### Examples ###### Send a mail on password changing + ```bash #!/bin/bash " @@ -143,11 +155,11 @@ If you have not asked for changing your password, you probably should contact th echo $message | mail -s "Your password has been changed on $domain !" $YNH_USER_USERNAME ``` + [/details] - - ### post_app_addaccess + [details summary="Triggered after adding a permission to users or groups " class="helper-card-subtitle text-muted"] This hook is run at the end of the command `yunohost user permission add` or equivalent action in webadmin. @@ -156,19 +168,19 @@ This hook is run at the end of the command `yunohost user permission add` or equ ##### Positionnal arguments (deprecated) - - $1: The app name - - $2: The list of users added separated by comma - - $3: The name of the sub permission (`main`, `admin`, etc.) - - $4: The list of groups added separated by comma +- $1: The app name +- $2: The list of users added separated by comma +- $3: The name of the sub permission (`main`, `admin`, etc.) +- $4: The list of groups added separated by comma ##### No waited return ##### Examples + [/details] - - ### post_app_removeaccess + [details summary="Triggered after removing a pemission to users or groups" class="helper-card-subtitle text-muted"] This hook is run at the end of the command `yunohost user permission remove` or equivalent action in webadmin. @@ -177,24 +189,21 @@ This hook is run at the end of the command `yunohost user permission remove` or ##### Positionnal arguments (deprecated) - - $1: The app name - - $2: The list of users removed from the permission separated by comma - - $3: The name of the sub permission (`main`, `admin`, etc.) - - $4: The list of groups removed from the permission separated by comma +- $1: The app name +- $2: The list of users removed from the permission separated by comma +- $3: The name of the sub permission (`main`, `admin`, etc.) +- $4: The list of groups removed from the permission separated by comma ##### No waited return ##### Examples + [/details] - - - - - - ## Domain, certificates and DNS + ### post_domain_add + [details summary="Triggered at the end of the domain add operation" class="helper-card-subtitle text-muted"] This hook is run at the end of the command `yunohost domain add` or equivalent action in webadmin. @@ -203,22 +212,22 @@ This hook is run at the end of the command `yunohost domain add` or equivalent a ##### Positionnal arguments (deprecated) - - $1: The domain added +- $1: The domain added ##### No waited return ##### Examples -###### +###### + ```bash ``` + [/details] - - - ### post_domain_remove + [details summary="Triggered after removing the domain" class="helper-card-subtitle text-muted"] This hook is run at the end of the command `yunohost domain remove` or equivalent action in webadmin. @@ -227,17 +236,16 @@ This hook is run at the end of the command `yunohost domain remove` or equivalen ##### Positionnal arguments (deprecated) - - $1: The domain removed +- $1: The domain removed ##### No waited return ##### Examples + [/details] - - - ### post_cert_update + [details summary="Triggered after Let's encrypt certificate update" class="helper-card-subtitle text-muted"] This hook is run at the end of the command `yunohost domain cert update` or equivalent action in webadmin. @@ -246,37 +254,39 @@ This hook is run at the end of the command `yunohost domain cert update` or equi ##### Positionnal arguments - - $1: The domain for which we have updated the certificate +- $1: The domain for which we have updated the certificate ##### No waited return ##### Examples ###### Restart a service after cert renewal + ```bash #!/bin/bash systemctl restart gemserv ``` + [/details] - - - ### custom_dns_rules + [details summary="Customized your DNS rules for your domains" class="helper-card-subtitle text-muted"] This hook is run at the end of the command `yunohost domain dns suggest` or equivalent action in webadmin. -Thanks to This hook you can customize +Thanks to This hook you can customize ##### No environment variable ##### Positionnal arguments - - $1: The base domain for which we want to build a DNS suggestion +- $1: The base domain for which we want to build a DNS suggestion ##### Waited return + The script should return a JSON array with dictionnary in this format: + ```json [ { @@ -288,10 +298,10 @@ The script should return a JSON array with dictionnary in this format: ] ``` - ##### Examples ###### Validate Let's Encrypt DNS challenge with a YunoHost DynDNS domain + ```bash #!/bin/bash if [[ "$1" == "XXXX.nohost.me" ]] ; then @@ -306,48 +316,49 @@ if [[ "$1" == "XXXX.nohost.me" ]] ; then fi ``` + [/details] - - - - ## Apps + ### post_app_change_url + [details summary="Triggered after an app has changed of URL" class="helper-card-subtitle text-muted"] This hook is run at the end of the command `yunohost app change-url` or equivalent action in webadmin. ##### Environment variables - - YNH_APP_OLD_DOMAIN: The old domain of the app - - YNH_APP_OLD_PATH: The old path of the app - - YNH_APP_NEW_DOMAIN: The new domain of the app - - YNH_APP_NEW_PATH: The new path of the app +- YNH_APP_OLD_DOMAIN: The old domain of the app +- YNH_APP_OLD_PATH: The old path of the app +- YNH_APP_NEW_DOMAIN: The new domain of the app +- YNH_APP_NEW_PATH: The new path of the app ##### No positionnal arguments ##### No waited return ##### Examples + [/details] ### post_app_upgrade + [details summary="Triggered on app upgrade" class="helper-card-subtitle text-muted"] This hook is run at the end of the command `yunohost app upgrade` or equivalent action in webadmin. ##### Environment variables - - YNH_APP_ID: The app id (for example nextcloud) - - YNH_APP_INSTANCE_NAME: The app instance name (for example nextcloud__2) - - YNH_APP_INSTANCE_NUMBER: The app instance number (for example 2) - - YNH_APP_MANIFEST_VERSION: The app manifest version (for example 1 or ?) - - YNH_ARCH: The arch as returned by `dpkg --print-architecture` - - YNH_APP_UPGRADE_TYPE: The type of upgrade (UPGRADE_PACKAGE, UPGRADE_APP, UPGRADE_FULL) - - YNH_APP_MANIFEST_VERSION: The version number - - YNH_APP_CURRENT_VERSION: The version number of the app (in the yunohost format) - - NO_BACKUP_UPGRADE: 1 if we don't want to backup else 0 +- YNH_APP_ID: The app id (for example nextcloud) +- YNH_APP_INSTANCE_NAME: The app instance name (for example nextcloud__2) +- YNH_APP_INSTANCE_NUMBER: The app instance number (for example 2) +- YNH_APP_MANIFEST_VERSION: The app manifest version (for example 1 or ?) +- YNH_ARCH: The arch as returned by `dpkg --print-architecture` +- YNH_APP_UPGRADE_TYPE: The type of upgrade (UPGRADE_PACKAGE, UPGRADE_APP, UPGRADE_FULL) +- YNH_APP_MANIFEST_VERSION: The version number +- YNH_APP_CURRENT_VERSION: The version number of the app (in the YunoHost format) +- NO_BACKUP_UPGRADE: 1 if we don't want to backup else 0 ##### No positionnal arguments @@ -356,6 +367,7 @@ This hook is run at the end of the command `yunohost app upgrade` or equivalent ##### Examples ###### Change a settings in an app config file (unmanaged by config panel) + ```bash #!/bin/bash @@ -368,71 +380,79 @@ if [[ "$app" == "etherpad_mypads" ]]; then fi ``` + [/details] ### post_app_install + [details summary="Triggered at the end of an app installation" class="helper-card-subtitle text-muted"] This hook is run at the end of the command `yunohost app install` or equivalent action in webadmin. ##### Environment variables - - YNH_APP_ID: The app id (for example nextcloud) - - YNH_APP_INSTANCE_NAME: The app instance name (for example nextcloud__2) - - YNH_APP_INSTANCE_NUMBER: The app instance number (for example 2) - - YNH_APP_MANIFEST_VERSION: The app manifest version (for example 1 or ?) - - YNH_ARCH: The arch as returned by `dpkg --print-architecture` - - YNH_APP_ARG_XXXXXXX: The argument of the manifest +- YNH_APP_ID: The app id (for example nextcloud) +- YNH_APP_INSTANCE_NAME: The app instance name (for example nextcloud__2) +- YNH_APP_INSTANCE_NUMBER: The app instance number (for example 2) +- YNH_APP_MANIFEST_VERSION: The app manifest version (for example 1 or ?) +- YNH_ARCH: The arch as returned by `dpkg --print-architecture` +- YNH_APP_ARG_XXXXXXX: The argument of the manifest ##### No positionnal arguments ##### No waited return ##### Examples + [/details] - ### post_app_remove + [details summary="Triggered after removing an app" class="helper-card-subtitle text-muted"] This hook is run at the end of the command `yunohost app remove` or equivalent action in webadmin. ##### Environment variables - - YNH_APP_ID: The app id (for example nextcloud) - - YNH_APP_INSTANCE_NAME: The app instance name (for example nextcloud__2) - - YNH_APP_INSTANCE_NUMBER: The app instance number (for example 2) - - YNH_APP_MANIFEST_VERSION: The app manifest version (for example 1 or ?) - - YNH_ARCH: The arch as returned by `dpkg --print-architecture` - - YNH_APP_PURGE: 1 if the --purge option has been activated +- YNH_APP_ID: The app id (for example nextcloud) +- YNH_APP_INSTANCE_NAME: The app instance name (for example nextcloud__2) +- YNH_APP_INSTANCE_NUMBER: The app instance number (for example 2) +- YNH_APP_MANIFEST_VERSION: The app manifest version (for example 1 or ?) +- YNH_ARCH: The arch as returned by `dpkg --print-architecture` +- YNH_APP_PURGE: 1 if the --purge option has been activated ##### No positionnal arguments ##### No waited return ##### Examples + [/details] ## Backup / Restore + ### backup + [details summary="Add some files to backup" class="helper-card-subtitle text-muted"] This hook is run at the end of the command `yunohost backup create` or equivalent action in webadmin. ##### Environment variables - - YNH_BACKUP_DIR: The work dir in which we can store temporary data to backup like database dump - - YNH_BACKUP_CSV: The CSV in which we add the things to backup. Don't use this directly and use ynh_backup helper instead. - - YNH_APP_BACKUP_DIR: To document +- YNH_BACKUP_DIR: The work dir in which we can store temporary data to backup like database dump +- YNH_BACKUP_CSV: The CSV in which we add the things to backup. Don't use this directly and use ynh_backup helper instead. +- YNH_APP_BACKUP_DIR: To document ##### Positionnal arguments - - $1: The work dir in which we can store temporary data to backup like database dump + +- $1: The work dir in which we can store temporary data to backup like database dump ##### No waited return ##### Examples ###### Backup some files in more (for example your custom hooks) + ```bash #!/bin/bash @@ -457,26 +477,30 @@ ynh_backup "/etc/yunohost/hooks.d/backup/99-conf_custom" ynh_backup "/etc/yunohost/hooks.d/restore/99-conf_custom" ``` + [/details] ### restore + [details summary="Restore some files" class="helper-card-subtitle text-muted"] This hook is run at the end of the command `yunohost backup restore` or equivalent action in webadmin. ##### Environment variables - - YNH_BACKUP_DIR: The work dir in which we can store temporary data to backup like database dump - - YNH_BACKUP_CSV: The CSV in which we add the things to backup. Don't use this directly and use ynh_backup helper instead. +- YNH_BACKUP_DIR: The work dir in which we can store temporary data to backup like database dump +- YNH_BACKUP_CSV: The CSV in which we add the things to backup. Don't use this directly and use ynh_backup helper instead. ##### Positionnal arguments - - $1: The work dir in which we can store temporary data to backup like database dump + +- $1: The work dir in which we can store temporary data to backup like database dump ##### No waited return ##### Examples ###### restore custom files + ```bash #!/bin/bash @@ -505,6 +529,7 @@ ynh_restore_file "/etc/yunohost/hooks.d/restore/99-conf_custom" [/details] ### backup_method + [details summary="Define a new way to backup and restore files" class="helper-card-subtitle text-muted"] This hook is run during the command `yunohost backup create` or equivalent action in webadmin. @@ -514,21 +539,20 @@ This hook is called several times with different action keywords. ##### No environment variables ##### Positionnal arguments - - - - $1: The action ("need_mount", "backup", "mount") - - $2: The work dir - - $3: The name of the backup - - $4: The repository in which the backup should be done - - $5: An estimation size of the files to backup - - $6: A description of the archive +- $1: The action ("need_mount", "backup", "mount") +- $2: The work dir +- $3: The name of the backup +- $4: The repository in which the backup should be done +- $5: An estimation size of the files to backup +- $6: A description of the archive ##### No waited return ##### Examples ###### A very simple backup on rotationnal disks + ```bash #!/bin/bash set -euo pipefail @@ -565,35 +589,40 @@ esac exit 0 ``` + [/details] ## Configuration and firewall + ### post_iptable_rules + [details summary="Triggered after reloaded the firewall rules" class="helper-card-subtitle text-muted"] This hook is run at the end of the command `yunohost firewall reload` or equivalent action in webadmin. ##### No environment variables - ##### Positionnal arguments - - $1: True if upnp has succeeded - - $2: True if ipv6 is available +- $1: True if upnp has succeeded +- $2: True if ipv6 is available ##### No waited return ##### Examples ###### Forbid completely the outgoing 25 port except for postfix user + ```bash #!/bin/bash iptables -A OUTPUT -p tcp --dport 25 -m owner --uid-owner postfix -j ACCEPT iptables -A OUTPUT -p tcp --dport 25 -m tcp -j REJECT --reject-with icmp-port-unreachable ``` + [/details] ### conf_regen + [details summary="Change configuration suggested as default config in regen-conf mechanism" class="helper-card-subtitle text-muted"] This hook is run during the command `yunohost tools regen-conf` or equivalent action in webadmin. @@ -602,21 +631,22 @@ This hook is called several times with different actions keywords (pre and post ##### Environment variables - - YNH_DOMAINS: The list of domains managed by YunoHost separated by comma - - YNH_MAIN_DOMAINS: The list of main domains separated by comma +- YNH_DOMAINS: The list of domains managed by YunoHost separated by comma +- YNH_MAIN_DOMAINS: The list of main domains separated by comma ##### Positionnal arguments - - $1: The pre or post action - - $2: Empty string due to legacy - - $3: Empty string due to legacy - - $4: In post mode the list of file which should be modified. In pre mode the dir in which we store pending configuration +- $1: The pre or post action +- $2: Empty string due to legacy +- $3: Empty string due to legacy +- $4: In post mode the list of file which should be modified. In pre mode the dir in which we store pending configuration ##### No waited return ##### Examples ###### Fix the warning about postfix compatibility mode in postfix logs + ```bash #!/bin/bash @@ -629,5 +659,5 @@ postfix_conf=$pending_dir/../postfix/etc/postfix/main.cf echo ' compatibility_level = 2' >> $postfix_conf ``` -[/details] +[/details] diff --git a/pages/06.contribute/10.packaging_apps/60.advanced/60.advanced_packagers/advanced_packagers.md b/pages/06.contribute/10.packaging_apps/60.advanced/60.advanced_packagers/advanced_packagers.md index 325a502e..c8b5def6 100644 --- a/pages/06.contribute/10.packaging_apps/60.advanced/60.advanced_packagers/advanced_packagers.md +++ b/pages/06.contribute/10.packaging_apps/60.advanced/60.advanced_packagers/advanced_packagers.md @@ -8,6 +8,7 @@ routes: --- Here comes the time: + - you masterise [apps packaging](/packaging_apps), [package_check](https://github.com/YunoHost/package_check), [example_ynh](https://github.com/YunoHost/example_ynh) and [experimental helpers](https://github.com/YunoHost-Apps/Experimental_helpers) - you have integrated the [YunoHost Apps Group](https://yunohost.org/#/project_organization) - you know what means `¯\_(ツ)_/¯` @@ -16,6 +17,7 @@ Here comes the time: Here are few ideas that could help you to improve YunoHost apps packaging. Usually, there are things that slow you down: + - Installing your freshly done package because of dependencies installation or npm/rust/elixir/composer builds - Waiting a package_check to see the level of your package - etc... @@ -23,19 +25,22 @@ Usually, there are things that slow you down: The idea is to use YunoHost stuffs to help you improve this lost time. ## Building your infrastructure + First idea is to build several VMs, LXCs or VirtualBoxs with YunoHost to let you parallelize actions, like having the first one installing an app, the second installing another app, the third one debugging an app upgrade, etc... After first installation of those VMs/LXCs, each one has to be reacheable with its domain name, like for example: + - ynh1.mydomain.org - ynh2.mydomain.org - ynh3.mydomain.org -For that you will need a public IP for each one or reverse proxy... +For that you will need a public IP for each one or reverse proxy... If your are lucky enough to have IPV6 and a /64 IPV6 scope, it won't be a problem to assign a public IPV6 to each YunoHost. Another way the DNS stuff is to simply use an hosts file. In addition, it's helpfull to have several domains names for each YunoHost, for example: + - ynh1.mydomain.org - test11.mydomain.org - test12.mydomain.org @@ -49,7 +54,7 @@ In addition, it's helpfull to have several domains names for each YunoHost, for - test32.mydomain.org - test33.mydomain.org -With that you will be able to install two apps on the same YunoHost first one at https://test11.mydomain.org and a second app at https://test12.mydomain.org (let say the first app is nextcloud_ynh the second one is collabora_ynh or onlyoffice_ynh) +With that you will be able to install two apps on the same YunoHost first one at and a second app at (let say the first app is nextcloud_ynh the second one is collabora_ynh or onlyoffice_ynh) When your infrastructure is up and ready, you will have to do snapshots of each VMs/LXCs. Doing that, you will be able to revert back to an happy and healthy YunoHost after doing install/backup/restore/upgrade of and app... @@ -57,7 +62,7 @@ Don't forget to regularly upgrade your YunoHosts VMs/LXCs to the last release do Example of a script to upgrade a master VirtualBox VM -``` +```bash #!/bin/bash # printers @@ -67,7 +72,7 @@ white="\e[97m" blue="\e[34m" echo_info() { - echo -e "[${bold}${blue}INFO${normal}] ${bold}${white}$1${normal}" + echo -e "[${bold}${blue}INFO${normal}] ${bold}${white}$1${normal}" } echo_info "### Update host" @@ -94,7 +99,7 @@ echo_info "### Run 'VBoxManage modifyhd --compact file.vdi' to reduce the size o Example of a script to customize a cloned VM -``` +```bash #!/bin/bash master_domain=domain1.fr @@ -117,6 +122,7 @@ sudo reboot Doing that you will have all the time a full/ready to go YunoHosts infrastructure for advanced packagers. And if require, you can have some VMs/LXCs runnning the YunoHost testing or YunoHost next Debian main version. ## Having your packages/commits available in each VMs/LXCs + There are several ways to have your freshly created package available from each VMs/LXCs 1- Do an ssh from the YunoHost VM/LXC to a central repository on your computer 2- Having a shared directory available from each VMs, LXCs VirtualBoxs @@ -125,7 +131,7 @@ There are several ways to have your freshly created package available from each Example of a script to mount as shared directory a packaging directory into a VirtualBox VM -``` +```bash #!/bin/bash shared_folder=my_directory @@ -137,7 +143,7 @@ white="\e[97m" blue="\e[34m" echo_info() { - echo -e "[${bold}${blue}INFO${normal}] ${bold}${white}$1${normal}" + echo -e "[${bold}${blue}INFO${normal}] ${bold}${white}$1${normal}" } # Create the main directory for the mount @@ -149,6 +155,7 @@ sudo mount -o defaults -t vboxsf $shared_folder "./$shared_folder" ``` ## Shortcuts + Use and abuse of `yunohost app install` `--args` argument You can do ugly thing considering mynewapp is the name/REPLACEBYYOURAPP of your app @@ -186,8 +193,6 @@ To upgrade your mynewapp ```bash YNHAPP=mynewapp yunohost app upgrade ${YNHAPP} -f /mycentralrepo/${YNHAPP}_ynh/ --debug - - ``` With that, you will be able to launch different actions on differents YunoHost VMs/LXCs @@ -200,5 +205,6 @@ With advanced packaging comes [CI_package_check](https://github.com/YunoHost/CI_ When you do several things at the same time, sometimes you don't remember what is the next step for this or that app. A good tool to keep your TODO list organized is to use a kaban like apps: + - [Kanboard](https://github.com/YunoHost-Apps/kanboard_ynh) - [Wekan](https://github.com/YunoHost-Apps/wekan_ynh) diff --git a/pages/06.contribute/10.packaging_apps/60.advanced/70.notes_about_new_packaging_v2/docs.md b/pages/06.contribute/10.packaging_apps/60.advanced/70.notes_about_new_packaging_v2/docs.md index a9fa9cf2..1ea9183d 100644 --- a/pages/06.contribute/10.packaging_apps/60.advanced/70.notes_about_new_packaging_v2/docs.md +++ b/pages/06.contribute/10.packaging_apps/60.advanced/70.notes_about_new_packaging_v2/docs.md @@ -10,9 +10,10 @@ routes: Packaging v2 is a major improvement for the packaging introduced in YunoHost 11.1 -### Motivation +### Motivation The motivations for this new format is: + - to get rid of some boring or unecessarily complex or duplicateds stuff such as saving/loading settings, creating a system user, etc.. during the install/upgrade/restore script, which are common things accross many apps. - to get rid of funky historical, not-super-semantic stuff such as `__FINALPATH__` being replaced by `$final_path` (with underscore), or `__PATH__` being replaced by `$path_url`, etc. - formalize some aspects such as the existence of the install dir, data dir, apt dependencies, database, etc. which in turn unlock possible future developments such as computing the space used by an app at one given moment, auto-upgrading apt dependencies during Debian major migration, etc. @@ -20,10 +21,10 @@ The motivations for this new format is: However, this "v2" is not the end of the story and should be seen as an intermediate stage before a "v3" packaging. In particular this "v3" packaging should also formalize the handling of the system and app configurations files and ultimately rework the entire paradigm of the install/remove/upgrade/backup/restore scripts. - ### Adapting a v1 app to v2 A script is available in and will attempt to convert what it can from the v1 format to the v2 format, in particular: + - initializing a `manifest.toml` and prefilling it with info scrapped from the various scripts - comment out now-unecessary lines in the various scripts @@ -36,36 +37,36 @@ This will edit the file in place and you should then carefully review and iterat The [example repo](https://github.com/YunoHost/example_ynh) illustrates the below. - **The manifest is now written as toml (`manifest.toml`)** instead of json (`manifest.json`). The structure of the manifest itself has been reworked and now include: - - The `upstream` section (now mandatory) - - An `integration` section meant to formalize what minimum YunoHost version is required, the list of supported architectures, declare if SSO/LDAP is supported, typical resource usage. This is meant to be displayed both in the catalog (similar to app stores) and on the app info page after installing the app - though this is still work in progress. - - A `resource` section (detailed below) + - The `upstream` section (now mandatory) + - An `integration` section meant to formalize what minimum YunoHost version is required, the list of supported architectures, declare if SSO/LDAP is supported, typical resource usage. This is meant to be displayed both in the catalog (similar to app stores) and on the app info page after installing the app - though this is still work in progress. + - A `resource` section (detailed below) - **Install questions are now automatically saved as settings** (except user-provided password and other specific infos) - **All settings are now automatically loaded in app script environments** (so e.g. directly define `$domain`, etc.) - **Auto-enable `set -eu`** a.k.a. `ynh_abort_if_errors` in appropriate scripts - **The safety-backup-before-upgrade is now automatically handled by the core** - **Simplify writing change-url scripts**: old the `new`/`old`/`change` `domain`/`path` are now automatically available in the context and a new helper `ynh_change_url_nginx_config` takes care of tweaking the nginx conf. Your script should essentially just call that helper and possibly tweak the app's conf and possibly restart the app's service - **Introduce a new `resource` mechanism** - - Resources are declared in the `manifest.toml`. - - They are meant to formalize recurring app needs that are to be provisioned/deprovisioned by the core. - - They include for example: system user, apt dependencies, install dir, data dir, port, permissions, SQL database... - - Each resource is to be provisioned *before* running the install script, deprovisioned *after* the remove script, and automatically upgraded if needed before running the upgrade script (or provisionned if introduced in the new app version, or deprovisioned if removed w.r.t. the previous app version) - - More infos about resources and their options and behavior are available in the dedicated doc page + - Resources are declared in the `manifest.toml`. + - They are meant to formalize recurring app needs that are to be provisioned/deprovisioned by the core. + - They include for example: system user, apt dependencies, install dir, data dir, port, permissions, SQL database... + - Each resource is to be provisioned *before* running the install script, deprovisioned *after* the remove script, and automatically upgraded if needed before running the upgrade script (or provisionned if introduced in the new app version, or deprovisioned if removed w.r.t. the previous app version) + - More infos about resources and their options and behavior are available in the dedicated doc page - **Permissions are automatically initialized using the answer to the `init_main_permission` install question** (replacing the `is_public` question). No need to write a boring `if $is_public ...` in the install script to add visitors anymore ! There is a similar mechanism to init other permissions, eg `init_admin_permission` (cf also the doc about the `permission` resource) - **The content of the `doc/` folder is now meant to be integrated in the webadmin** (though this is still WIP as of writing this). In particular: - - `DESCRIPTION.md` and the `screenshots/` folder are expected to be displayed prior to the app install form (similar to app stores on mobile) - - `ADMIN.md` is expected to be made available somewhere in the info page and should contain technical admin notes. Other pages can be defined (just name it `WHATEVER.md`). Lang codes are also supported following the existing scheme for the README, eg `README_fr.md` is the French version, hence you can create `ADMIN_fr.md`, etc. - - Note that the `ADMIN.md` page supports the `__FOOBAR__` notation that will be automatically replaced with the app's `foobar` setting -- **Special files called 'notifications' are meant to replace the `ynh_send_readme_to_admin` mechanics**. They are also to be added to the `doc` folder: - - `doc/PRE_INSTALL.md`: a note to be displayed prior to the app install. Typically to warn of something unusual, such as "the app install will automatically add 1GB swap to the system". - - `doc/POST_INSTALL.md`: a note to be displayed after the app install. Typically to explain post-install operations to be performed manually by the admin and that cannot be automated. - - `doc/PRE_UPGRADE.md`: a note to be displayed prior to any upgrade of this app. - - `doc/PRE_UPGRADE.d/{version}.md`: a note to be displayed prior to a specific version upgrade. - - `doc/POST_UPGRADE.md`: a note to be displayed after the app upgrade. For example in the context of Nextcloud, the fact that you may need to re-enable custom modules manually? - - Note that the notifications, like `ADMIN.md`, supports the `__FOOBAR__` notation that will be automatically replaced with the app's `foobar` setting - - **Replace some historical names with more sensible ones**, or homogenize some practices: - - `final_path` is now `install_dir` (this migration should be automatically handled by the core and the `convert_app_to_packaging_v2.py` script) - - `datadir` is now `data_dir` to be consistent with `install_dir` (this migration should be automatically handled by the core and the `convert_app_to_packaging_v2.py` script) - - `path` is now always loaded as `$path`, no funky `$path_url`-but-it-is-saved-as-`path` anymore (this migration should be automatically handled by the core and the `convert_app_to_packaging_v2.py` script) - - `mysqldbpwd` and `psqlpwd` or whatever are now always saved as `db_pwd` (cf the `database` resource) (this migration should be automatically handled by the core and the `convert_app_to_packaging_v2.py` script) - - ports settings are now always named either `$port` or `$port_foo_bar` instead of `$foo_bar_port` (cf the `port` resource) (this migration should be automatically handled by the core and the `convert_app_to_packaging_v2.py` script) - - the install dir is to be set to `/var/www/$app` by default for web apps (or can be changed to `/opt/????` for non-webapps). Note that YunoHost will **automatically move** the old install dir to the new `install_dir` during the corresponding upgrade. + - `DESCRIPTION.md` and the `screenshots/` folder are expected to be displayed prior to the app install form (similar to app stores on mobile) + - `ADMIN.md` is expected to be made available somewhere in the info page and should contain technical admin notes. Other pages can be defined (just name it `WHATEVER.md`). Lang codes are also supported following the existing scheme for the README, eg `README_fr.md` is the French version, hence you can create `ADMIN_fr.md`, etc. + - Note that the `ADMIN.md` page supports the `__FOOBAR__` notation that will be automatically replaced with the app's `foobar` setting +- **Special files called 'notifications' are meant to replace the `ynh_send_readme_to_admin` mechanics**. They are also to be added to the `doc` folder: + - `doc/PRE_INSTALL.md`: a note to be displayed prior to the app install. Typically to warn of something unusual, such as "the app install will automatically add 1GB swap to the system". + - `doc/POST_INSTALL.md`: a note to be displayed after the app install. Typically to explain post-install operations to be performed manually by the admin and that cannot be automated. + - `doc/PRE_UPGRADE.md`: a note to be displayed prior to any upgrade of this app. + - `doc/PRE_UPGRADE.d/{version}.md`: a note to be displayed prior to a specific version upgrade. + - `doc/POST_UPGRADE.md`: a note to be displayed after the app upgrade. For example in the context of Nextcloud, the fact that you may need to re-enable custom modules manually? + - Note that the notifications, like `ADMIN.md`, supports the `__FOOBAR__` notation that will be automatically replaced with the app's `foobar` setting +- **Replace some historical names with more sensible ones**, or homogenize some practices: + - `final_path` is now `install_dir` (this migration should be automatically handled by the core and the `convert_app_to_packaging_v2.py` script) + - `datadir` is now `data_dir` to be consistent with `install_dir` (this migration should be automatically handled by the core and the `convert_app_to_packaging_v2.py` script) + - `path` is now always loaded as `$path`, no funky `$path_url`-but-it-is-saved-as-`path` anymore (this migration should be automatically handled by the core and the `convert_app_to_packaging_v2.py` script) + - `mysqldbpwd` and `psqlpwd` or whatever are now always saved as `db_pwd` (cf the `database` resource) (this migration should be automatically handled by the core and the `convert_app_to_packaging_v2.py` script) + - ports settings are now always named either `$port` or `$port_foo_bar` instead of `$foo_bar_port` (cf the `port` resource) (this migration should be automatically handled by the core and the `convert_app_to_packaging_v2.py` script) + - the install dir is to be set to `/var/www/$app` by default for web apps (or can be changed to `/opt/????` for non-webapps). Note that YunoHost will **automatically move** the old install dir to the new `install_dir` during the corresponding upgrade. diff --git a/pages/06.contribute/10.packaging_apps/80.resources/03.git/packaging_apps_git.fr.md b/pages/06.contribute/10.packaging_apps/80.resources/03.git/packaging_apps_git.fr.md index 829a8f5d..a7594c24 100644 --- a/pages/06.contribute/10.packaging_apps/80.resources/03.git/packaging_apps_git.fr.md +++ b/pages/06.contribute/10.packaging_apps/80.resources/03.git/packaging_apps_git.fr.md @@ -19,7 +19,7 @@ Commençons par la partie facile, GitHub est livré avec une interface web "faci *Tout d'abord et malheureusement, il n'y a pas moyen de contourner ça, vous devez avoir un compte sur GitHub.* -#### Branches +### Branches Ensuite, et c'est probablement l'une des choses les plus importantes, **ne travaillez pas directement sur la branche master**. Désolé, il fallait que ce soit dit ! @@ -32,7 +32,7 @@ La bonne habitude à prendre est de travailler à partir de la branche testing, Pour voir et modifier la branche actuelle, utilisez ce bouton : ![](image://github_branch.png) -#### Modifier un fichier +### Modifier un fichier Maintenant que vous êtes sur la bonne branche, voyons comment éditer un fichier sur GitHub. @@ -42,7 +42,7 @@ Vous pouvez éditer n'importe quel fichier en utilisant l'icône du petit crayon Si vous n'avez pas la permission d'écrire sur le dépôt, vous verrez (comme sur l'image) que vous allez créer un fork (nous verrons plus loin ce qu'est un fork). Si vous avez la permission d'écrire, vous allez simplement modifier le fichier, sans forker. -#### Validez vos modifications +### Validez vos modifications Lorsque vous avez fini de modifier le fichier, vous pouvez faire un commit de vos modifications. Derrière ce mot, l'idée est assez simple, vous allez juste enregistrer vos modifications... @@ -54,7 +54,7 @@ Le deuxième champ est un champ plus grand pour une explication plus complète, Enfin, si vous modifiez un dépôt sur lequel vous avez la permission d'écrire, vous pouvez soit faire un commit directement sur la branche en cours, soit créer une nouvelle branche. Il est généralement préférable de créer une nouvelle branche, de cette façon vous gardez vos modifications sur une version *parallèle* du dépôt. Vos modifications seront discutées dans une pull request (expliquée ci-dessous) puis finalement fusionnées dans la branche d'origine. -#### Forker ou ne pas forker +### Forker ou ne pas forker Un fork est une copie d'un dépôt sur votre propre compte. Nous avons déjà vu que si vous n'avez pas l'autorisation d'écrire dans un dépôt, la modification d'un fichier créera automatiquement un fork. @@ -69,7 +69,7 @@ Nous avons vu comment éditer un fichier, et comment cela peut forker l'applicat Mais, lorsque vous voulez éditer plusieurs fichiers, l'interface GitHub n'est pas vraiment la meilleure solution. Dans une telle situation, vous préférerez cloner le dépôt et travailler sur un dépôt local. Il se peut que vous deviez tout de même forker sur votre propre compte pour pouvoir enregistrer vos modifications si vous n'avez pas les autorisations sur le dépôt distant. -#### Pull request +### Pull request Après avoir effectué vos commits, que ce soit sur une branche ou un fork, vous souhaitez proposer vos modifications pour qu'elles soient intégrées dans le dépôt principal, ou dans la branche d'origine. Pour ce faire, vous allez créer une pull request. GitHub vous demande généralement directement si vous souhaitez le faire. @@ -78,7 +78,7 @@ Sinon, vous trouverez le bouton de création d'une pull request juste ici : Lors de la création d'une pull request à partir d'un fork, pour faciliter le travail de révision du code, **ne jamais** décocher la case *Allow edits from maintainers*. Cette option permet simplement aux mainteneurs du dépôt d'origine de modifier directement votre travail. -#### Organisation YunoHost-Apps +### Organisation YunoHost-Apps Conformément au [guide de création d'applications dans YunoHost](/packaging_apps_intro), votre application doit être intégrée à l'organisation YunoHost-Apps, mais si vous n'avez jamais contribué à une application auparavant ou si vous n'avez jamais eu d'application dans cette organisation, vous n'en aurez peut-être pas l'autorisation. @@ -89,7 +89,6 @@ En bas de la page, vous trouverez *Transfer ownership*. Dans le champ *New owner’s GitHub username or organization name*, tapez *YunoHost-Apps*. Votre dépôt sera déplacé dans l'organisation, vous n'avez pas besoin de supprimer le dépôt d'origine. - ## Travailler avec Git en local Comme nous l'avons vu, vous pouvez faire beaucoup de choses directement sur GitHub. @@ -97,7 +96,7 @@ Mais lorsque vous devez modifier plusieurs fichiers, ou lorsque vous devez trava Avant d'aller dans la partie infernale de Git, voyons 2 façons différentes de commencer à travailler avec Git. -#### Premier cas : Créer un nouveau package +### Premier cas : Créer un nouveau package Vous avez découvert, choqué, que la merveilleuse application que vous aimez utiliser tous les jours n'a pas encore son package YunoHost. Et parce que vous êtes sympa, vous avez décidé de créer vous-même le package, pour que tout le monde puisse apprécier cette application. Quelle bonne idée ! @@ -105,19 +104,21 @@ Quelle bonne idée ! Le mieux est de commencer par l'[application d'exemple](https://github.com/YunoHost/example_ynh). Mais comme nous l'avons déjà expliqué, vous ne voulez pas forker, parce que si vous le faites, vous allez garder ce lien vers l'application d'exemple et c'est vraiment ennuyeux. Donc, vous allez le faire différemment. Vous allez cloner ! -##### `git clone` +#### `git clone` Pour cloner, vous allez faire : + ```bash git clone https://github.com/YunoHost/example_ynh ``` + `git clone` téléchargera une copie du dépôt. Vous aurez le dépôt complet, avec ses branches, ses commits, et tout le reste (dans cet apparent petit répertoire `.git`). git clone est généralement le point de départ de tout travail local avec Git. *Toutefois, si vous comptez envoyer vos modifications sur le dépôt distant sur GitHub, assurez-vous d'avoir les droits d'écriture sur ce dépôt. Sinon, forkez avant et clonez votre fork, pour lequel vous avez la permission.* -##### Mon nouveau package, suite +#### Mon nouveau package, suite Dans le contexte d'un nouveau package, vous devrez également créer un dépôt sur GitHub pour y mettre votre package. Ce qui n'est pas plus compliqué qu'un gros bouton vert *New*. @@ -132,27 +133,29 @@ Copiez tous les fichiers de l'application example_ynh, **excepté le répertoire Vous êtes prêt à travailler sur votre nouveau package ! -#### Deuxième cas : Travailler localement sur un dépôt +### Deuxième cas : Travailler localement sur un dépôt Vous disposez déjà d'un dépôt, mais ce que vous voulez, c'est travailler localement, de sorte que vous puissiez modifier plusieurs fichiers. Il vous suffit de cloner le dépôt, le répertoire .git est le lien vers le dépôt distant. Rien d'autre à faire qu'un `git clone`. -#### Branches +### Branches Vous avez bien votre copie local du dépôt, mais comme vous avez lu attentivement cette documentation jusque-là, vous savez que vous devez vous assurer d'être sur la branche testing avant de commencer à travailler. Pour voir les branches, et savoir sur quelle branche vous êtes réellement, alors que vous êtes dans le répertoire de votre dépôt, tapez `git branch`. La branche courante est mise en évidence et précédée d'un "\*". -#### `git checkout` +### `git checkout` S'il apparaît que vous n'êtes pas sur la branche où vous vouliez être, ou que vous êtes en fait sur master (ce qui est mal !), vous pouvez passer à une autre branche avec `git checkout`. + ```bash git checkout testing ``` + *Lisez attentivement ce que Git dit quand vous validez une commande, n'oubliez jamais que Git est sournois...* -#### `git pull` avant tout +### `git pull` avant tout Vous êtes enfin dans la bonne branche, et prêt à travailler. **Attendez ! Un vilain piège vous attend...** @@ -161,17 +164,20 @@ Avant de vous retrouver dans une situation inextricable. Commencez par un `git p *Parfois, vous rencontrerez une situation impossible où Git vous dira que vous ne pouvez pas pull parce que vous avez des changements locaux. Mais vous ne vous souciez pas de ces modifications locales, vous voulez juste obtenir la dernière version de la branche distante. Mais Git ne se soucie pas de ce que VOUS voulez...* *Je dois admettre que ma seule solution est aussi efficace que sale... Un bon vieux `rm -r` du dépôt et un `git clone`* -#### Il est temps de travailler +### Il est temps de travailler Vous pouvez finalement travailler sur votre code. Lorsque vous êtes enfin d'accord avec ce que vous avez fait, il est temps de valider votre travail. La première étape consiste à informer Git sur le(s) fichier(s) à valider. Pour ce faire, nous utiliserons `git add`. + ```bash git add mon_fichier ajouter mon_autre_fichier et_aussi_celui_ci ``` + Si vous souhaitez valider l'ensemble de votre travail, vous pouvez aussi simplement faire + ```bash git add --all ``` @@ -179,14 +185,14 @@ git add --all Pour vérifier l'état actuel de votre validation, vous pouvez utiliser `git status`. Il vous montrera quels fichiers seront inclus dans votre commit, et quels fichiers sont modifiés, mais pas encore inclus. `git status -v` vous indiquera également quelle partie des fichiers est modifiée. Une bonne façon de s'assurer que vous n'avez pas fait d'erreur avant de faire un commit. -#### `git checkout -b` +### `git checkout -b` Avant de faire un commit, ou après, ou avant de commencer à travailler. Quand vous en avez envie ! Vous devriez envisager d'ajouter votre travail à une branche séparée, de cette façon, il sera facile de créer une pull request dans la branche testing et de discuter avec les autres packagers de ce que vous suggérez de changer. Pour créer une nouvelle branche et passer à cette branche, vous pouvez utiliser `git checkout -b my_new_branch`. -#### `git commit` +### `git commit` Faire un commit, c'est simplement valider son travail dans Git. Comme vous pouvez le faire dans GitHub. Pour avoir les mêmes champs que vous aviez sur GitHub, avec le nom du commit, et une explication plus longue. Vous pouvez simplement utiliser `git commit`. @@ -194,15 +200,17 @@ La première ligne, avant les commentaires, est pour le nom du commit. Après tous les commentaires, vous pouvez ajouter une explication si vous le souhaitez. Si vous voulez faire un commit avec seulement un nom pour votre commit, vous pouvez utiliser une simple commande : + ```bash git commit -m "My commit name" ``` -#### `git push` vers le dépôt distant +### `git push` vers le dépôt distant Vos modifications sont validées, mais uniquement sur votre clone local du dépôt. Maintenant, vous devez renvoyer ces modifications sur le dépôt distant sur GitHub. Pour ce faire, vous devez savoir quelle est votre branche actuelle. (Si vous ne le savez pas, `git branch` vous donnera cette information). Ensuite, vous pouvez git push + ```bash git push -u origin BRANCH_NAME ``` diff --git a/pages/06.contribute/10.packaging_apps/80.resources/03.git/packaging_apps_git.md b/pages/06.contribute/10.packaging_apps/80.resources/03.git/packaging_apps_git.md index 7a6f5852..8df77e68 100644 --- a/pages/06.contribute/10.packaging_apps/80.resources/03.git/packaging_apps_git.md +++ b/pages/06.contribute/10.packaging_apps/80.resources/03.git/packaging_apps_git.md @@ -19,7 +19,7 @@ Let's go first for the easy part, GitHub comes with an "easy" web interface to d *First things first, unfortunately there's no way around, you need an account on GitHub.* -#### Branches +### Branches Then, probably one of the most important thing, **do not work directly on the master branch**. Sorry, it has to be said ! @@ -32,7 +32,7 @@ The usual thing to do is to work from the testing branch, and when everything is To see and change the current branch, use this button: ![](image://github_branch.png) -#### Edit a file +### Edit a file Now that you're on the right branch, let's see how to edit a file on GitHub. @@ -42,7 +42,7 @@ You can edit any file by using the small pencil icon: If you don't have the permission to write on the repository, you will see (as on the picture) that you're going to create a fork (we'll see below what a fork is). If you have the permission to write, you will just edit the file, without forking. -#### Commit your changes +### Commit your changes When you're done with your modification on the file, you can commit your changes. Behind that word, the idea is quite simple, you're just going to save your changes... @@ -54,7 +54,7 @@ The second field is a large one for a more complete explanation, if you need it. Finally, if you're editing a repository on which you have permission to write, you can either commit directly to the current branch or create a new branch. It's usually better to create a new branch, that way you keep your modifications on a *parallel* version of the repository. Your modifications will be discussed in a pull request (explained below) then finally merged into the original branch. -#### To fork or not to fork +### To fork or not to fork A fork is a copy of a repository into your own account. We have seen before that if you don't have permission to write into a repository, editing a file will automatically create a fork. @@ -69,7 +69,7 @@ We have seen how to edit a file, and how this could fork the app. But, when you want to edit multiple files, the GitHub interface isn't really the best way. In such situation, you would rather clone the repository and work on a local repository. You may still need to fork on your own account to be able to save your modifications if you don't have the permission on the distant repository. -#### Pull request +### Pull request After you have committed your changes, whether on a branch or a fork, you want to propose your modifications to be integrated into the main repository, or the original branch. To do so, you're going to *create a pull request*. GitHub usually ask you directly if you want to do so. @@ -78,7 +78,7 @@ Otherwise, you'll find the button to create a pull request just here: When creating a pull request from a fork, to ease the work of the reviewers, **do never** uncheck the checkbox *Allow edits from maintainers*. That option simply allow the maintainers of the original repository to edit directly your work. -#### YunoHost-Apps organization +### YunoHost-Apps organization Following the [guide for packaging application within YunoHost](/packaging_apps_intro), your app has to be into the YunoHost-Apps organization, but if you have never contributed to an app before or never had any app into this organization you may not have the permission. @@ -89,7 +89,6 @@ At the bottom of the page, you will find *Transfer ownership*. Into the field *New owner’s GitHub username or organization name*, type *YunoHost-Apps*. Your repo will be moved into the organization, you don't have to remove the original repository. - ## Working with Git locally As we have seen, you can do a lot of things directly on GitHub. @@ -97,7 +96,7 @@ But when you need to edit multiple files, or when you need to work on your code Before going to the hellish part of Git, let's see two different ways to start working with Git. -#### First case: Creating a new package +### First case: Creating a new package You have shockingly discovered that the wonderful app you love to use everyday does not yet have its YunoHost package. And because you're nice, you decided to create yourself the package, so everyone will enjoy that app the way you do. What a good idea! @@ -105,19 +104,21 @@ What a good idea! The best is to start from the [example app](https://github.com/YunoHost/example_ynh). But as we have explained before, you don't want to fork, because if you do so, you're going to keep that link to the example app and it's really annoying. So, you're going to do it differently. You're going to clone! -##### git clone +#### git clone To clone, you're going to do: + ```bash git clone https://github.com/YunoHost/example_ynh ``` + `git clone` will download a copy of the repository. You will have the complete repository, with its branches, commits, and everything (into that apparently little `.git` directory). To git clone is usually the starting point of any local work with Git. *A side note though, if you expect to send your modifications back to the distant repository on GitHub, be sure to have the permission to write on this repository. Otherwise, fork before and clone your fork, on which you do have the permission.* -##### My brand new package, continued +#### My brand new package, continued In the context of a new package, you will also need to create a repository on GitHub to nest your package. Which is as simple as a big green *New* button. @@ -132,27 +133,29 @@ Copy all the files from the example_ynh app, **except the .git directory** (You You're ready to work on your new package ! -#### Second case: Working locally on a repository +### Second case: Working locally on a repository You already have a repository, but what you want is just to work locally, so you can modify multiple files. Simply clone the repository, the .git directory is the link to the distant repository. Nothing else to do than a `git clone`. -#### Branches +### Branches You do have your local copy of the repository, but because you have read carefully this documentation until then, you know that you should be sure to be on the testing branch before starting to work. To see the branches, and to know on which you actually are, while into the directory of your repository, type `git branch`. The current branch is highlighted and preceded by a `*`. -#### `git checkout` +### `git checkout` If it appears that you're not on the branch you wanted to be, or you're actually on master (which is bad !), you can move to another branch with `git checkout` + ```bash git checkout testing ``` + *Read carefully what Git says when you validate a command, do never forget that Git is sneaky...* -#### `git pull` before anything else +### `git pull` before anything else You're finally on the right branch, and ready to work. **Wait ! A nasty trap is waiting for you...** @@ -161,17 +164,20 @@ Before ending up in an inextricable situation. Start with a `git pull` to update *Sometimes, you will encounter an impossible situation where Git is saying that you can't pull because you have local changes. But you don't care of those local modifications, you just want to get the last version of the distant branch. But Git don't care about what YOU want...* *I have to admit that my only solution is as highly efficient as dirty... A good old `rm -r` of the repository and a `git clone`* -#### Let's work +### Let's work Eventually, you can work on your code. When you are finally ok with what you have done, it's time to validate your work. The first step is to inform Git about which file(s) to validate. To do so, we'll use `git add` + ```bash git add my_file git add my_other_file and_also_this_one ``` + If you want to validate all your work, you can also simply do + ```bash git add --all ``` @@ -179,14 +185,14 @@ git add --all To check the current status of your validation, you can use `git status`. It will show you which files will be included into your commit, and which files are modified, but not yet included. `git status -v` will show also which part of the files are modified. A good way to be sure that you didn't make a mistake before committing. -#### `git checkout -b` +### `git checkout -b` Before committing, or after, or before starting to work. Whenever you feel like it ! You should consider adding your work to a separate branch, that way, it will be easy to create a pull request to merge into the testing branch and discuss with the other packagers what you suggest to change. To create a new branch and move to this branch, you can use `git checkout -b my_new_branch`. -#### `git commit` +### `git commit` To commit is simply to validate your work in Git. As you can do in GitHub. To have the same fields that you had on GitHub, with the name of the commit, and a longer explanation. You can simply use `git commit`. @@ -194,15 +200,17 @@ The first line, before the comments, is for the name of the commit. After all the comments, you can add an explanation if you want to. If you want to commit with only a name for your commit, you can use a simple command: + ```bash git commit -m "My commit name" ``` -#### Push to the distant repository +### Push to the distant repository Your changes are validated, but only on your local clone of the repository. Now, you have to send those modifications back to the distant repository on GitHub. In order to do that, you need to know what is your current branch. (If you don't know, `git branch` will give you that info). Then you can git push + ```bash git push -u origin BRANCH_NAME ``` diff --git a/pages/06.contribute/10.packaging_apps/80.resources/04.virtualbox/packaging_apps_virtualbox.fr.md b/pages/06.contribute/10.packaging_apps/80.resources/04.virtualbox/packaging_apps_virtualbox.fr.md index d132ab69..379cb0dd 100644 --- a/pages/06.contribute/10.packaging_apps/80.resources/04.virtualbox/packaging_apps_virtualbox.fr.md +++ b/pages/06.contribute/10.packaging_apps/80.resources/04.virtualbox/packaging_apps_virtualbox.fr.md @@ -20,7 +20,7 @@ Nous parlerons ici de VirtualBox, pour son approche graphique facile à utiliser ## Installer VirtualBox -Depuis un système GNU/Linux, installer simplement le paquet `virtualbox-qt`. +Depuis un système GNU/Linux, installer simplement le paquet `virtualbox-qt`. Depuis un système Windows ou macOS, il faudra se référer à la page de [téléchargement de VirtualBox](https://www.virtualbox.org/wiki/Downloads) pour récupérer le fichier d'installation adéquat. Le paquet virtualbox est déprécié depuis Debian 9, un fichier d'installation `.deb` est disponible sur la même page. Quel que soit votre système, il ne devrait pas être nécessaire d'installer l'extension pack ou les additions invités. @@ -41,7 +41,7 @@ Votre serveur virtuel est à présent installé. Avant de commencer à l'utilise VirtualBox prend tout son intérêt avec l'usage des instantanés, qui permettent d'enregistrer l'état de la machine à un moment donné et d'y revenir rapidement. Nous verrons également par la suite comment utiliser plusieurs branches d'instantanés pour travailler sur des apps différentes sur une même machine. -#### Tout d'abord, créons un premier instantané +### Tout d'abord, créons un premier instantané Avant de commencer à jouer avec la machine virtuelle, il convient de faire un premier instantané, pour ne pas avoir à recommencer le processus d'installation à chaque fois. Arrêtez la machine virtuelle avant tout. @@ -60,7 +60,7 @@ Dans cet exemple, on pourra facilement revenir en arrière, après avoir testé Et lorsque le package sera pleinement fonctionnel, il suffira de supprimer les instantanés liés à ce package pour revenir à l'état initial de la machine virtuelle. Nous disposerons ainsi d'un serveur YunoHost vierge de toute installation d'application pour notre prochain test. -#### Utiliser plusieurs branches d'instantanés +### Utiliser plusieurs branches d'instantanés En plus de l'usage d'instantanés successifs, il est également possible de dériver un nouvel état actuel et de nouveaux instantanés depuis un instantané plus ancien que le dernier. @@ -83,7 +83,8 @@ On se connecte à la machine virtuelle comme à n'importe quel serveur YunoHost, ```bash ssh admin@mon.domain ``` -Ou, si le domaine n'a pas été ajouté dans le hosts, en utilisant son ip. + +Ou, si le domaine n'a pas été ajouté dans le hosts, en utilisant son IP. ```bash ssh admin@11.22.33.44 diff --git a/pages/06.contribute/10.packaging_apps/80.resources/04.virtualbox/packaging_apps_virtualbox.md b/pages/06.contribute/10.packaging_apps/80.resources/04.virtualbox/packaging_apps_virtualbox.md index 4a3c12af..4f17353a 100644 --- a/pages/06.contribute/10.packaging_apps/80.resources/04.virtualbox/packaging_apps_virtualbox.md +++ b/pages/06.contribute/10.packaging_apps/80.resources/04.virtualbox/packaging_apps_virtualbox.md @@ -41,7 +41,7 @@ Your virtual server is now installed. Before starting to use it, we'll see how t VirtualBox becomes even more interesting with its snapshotting feature, which allow to store the virtualized machine state and restore it quickly. We'll also see how to use multiple snapshot branches to work on different apps on the same machine. -#### Now, let's create a first snapshot +### Now, let's create a first snapshot Before starting to play with the virtual machine, now is a good time to take a first snapshot, so that we don't have to redo the full install process every time. First, stop the virtual machine. @@ -60,7 +60,7 @@ In this example, after having validated our particular package removal works fin Once the package will be fully functional, it will just be a matter of deleting the snaphots associated with this package work to get the virtual machine back to its initial state. For our next test, we will then be back to a freshly installed YunoHost serveur, without any trace of package installation. -#### Using multiple snapshot branches +### Using multiple snapshot branches In addition to successive snapshots, it is also possible to create a new machine state and additional snapshots from an older machine snapshot/state. @@ -82,6 +82,7 @@ Virtual machine connection is similar to any YunoHost server connection, that is ```bash ssh admin@my.domain ``` + Or, if the domain has not been added to the `hosts` file, via its IP address. ```bash diff --git a/pages/06.contribute/10.packaging_apps/80.resources/11.helpers/packaging_apps_helpers.md b/pages/06.contribute/10.packaging_apps/80.resources/11.helpers/packaging_apps_helpers.md index b21bc6ee..9f759b4d 100644 --- a/pages/06.contribute/10.packaging_apps/80.resources/11.helpers/packaging_apps_helpers.md +++ b/pages/06.contribute/10.packaging_apps/80.resources/11.helpers/packaging_apps_helpers.md @@ -9,27 +9,27 @@ routes: Doc auto-generated by [this script](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/doc/generate_helper_doc.py) on 01/03/2024 (YunoHost version 11.2.10.3) - ## APPS #### ynh_install_apps + [details summary="Install others YunoHost apps" class="helper-card-subtitle text-muted"] **Usage**: `ynh_install_apps --apps="appfoo?domain=domain.foo&path=/foo appbar?domain=domain.bar&path=/bar&admin=USER&language=fr&is_public=1&pass?word=pass&port=666"` **Arguments**: + - `-a`, `--apps=`: apps to install **Details**:
Requires YunoHost version *.*.* or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/apps#L9) [/details] ---------------- #### ynh_remove_apps + [details summary="Remove other YunoHost apps" class="helper-card-subtitle text-muted"] **Usage**: `ynh_remove_apps` @@ -39,28 +39,22 @@ Other YunoHost apps will be removed only if no other apps need them. Requires YunoHost version *.*.* or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/apps#L65) [/details] ---------------- #### ynh_spawn_app_shell + [details summary="Spawn a Bash shell with the app environment loaded" class="helper-card-subtitle text-muted"] **Usage**: `ynh_spawn_app_shell --app="app" | arg: -a, --app= - the app ID` **Examples**: - - -- ` ynh_spawn_app_shell --app="APP" <<< 'echo "$USER"'` - - - -- ` ynh_spawn_app_shell --app="APP" < /tmp/some_script.bash` - - + +- `ynh_spawn_app_shell --app="APP" <<< 'echo "$USER"'` + +- `ynh_spawn_app_shell --app="APP" < /tmp/some_script.bash` **Details**:
Requires YunoHost version 11.0.* or higher, and that the app relies on packaging v2 or higher. @@ -68,21 +62,20 @@ The spawned shell will have environment variables loaded and environment files s from the app's service configuration file (defaults to $app.service, overridable by the packager with `service` setting). If the app relies on a specific PHP version, then `php` will be aliased that version. The PHP command will also be appended with the `phpflags` settings. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/apps#L128) [/details] ---------------- - ## APT #### ynh_package_is_installed + [details summary="Check either a package is installed or not" class="helper-card-subtitle text-muted"] **Usage**: `ynh_package_is_installed --package=name` **Arguments**: + - `-p`, `--package=`: the package name to check **Returns**: 0 if the package is installed, 1 else. @@ -92,18 +85,18 @@ If the app relies on a specific PHP version, then `php` will be aliased that ver **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/apt#L53) [/details] ---------------- #### ynh_package_version + [details summary="Get the version of an installed package" class="helper-card-subtitle text-muted"] **Usage**: `ynh_package_version --package=name` **Arguments**: + - `-p`, `--package=`: the package name to get version **Returns**: the version or an empty string @@ -113,13 +106,12 @@ Requires YunoHost version 2.2.4 or higher. **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/apt#L75) [/details] ---------------- #### ynh_package_update + [details summary="Update package index files" class="helper-card-subtitle text-muted"] **Usage**: `ynh_package_update` @@ -127,86 +119,86 @@ Requires YunoHost version 2.2.4 or higher. **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/apt#L107) [/details] ---------------- #### ynh_package_install + [details summary="Install package(s)" class="helper-card-subtitle text-muted"] **Usage**: `ynh_package_install name [name [...]]` **Arguments**: + - `name`: the package name to install **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/apt#L117) [/details] ---------------- #### ynh_package_remove + [details summary="Remove package(s)" class="helper-card-subtitle text-muted"] **Usage**: `ynh_package_remove name [name [...]]` **Arguments**: + - `name`: the package name to remove **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/apt#L128) [/details] ---------------- #### ynh_package_autoremove + [details summary="Remove package(s) and their uneeded dependencies" class="helper-card-subtitle text-muted"] **Usage**: `ynh_package_autoremove name [name [...]]` **Arguments**: + - `name`: the package name to remove **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/apt#L138) [/details] ---------------- #### ynh_package_autopurge + [details summary="Purge package(s) and their uneeded dependencies" class="helper-card-subtitle text-muted"] **Usage**: `ynh_package_autopurge name [name [...]]` **Arguments**: + - `name`: the package name to autoremove and purge **Details**:
Requires YunoHost version 2.7.2 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/apt#L148) [/details] ---------------- #### ynh_install_app_dependencies + [details summary="Define and install dependencies with a equivs control file" class="helper-card-subtitle text-muted"] **Usage**: `ynh_install_app_dependencies dep [dep [...]]` **Arguments**: + - `dep`: the package name to install in dependence. - `"dep1|dep2|…"`: You can specify alternatives. It will require to install (dep1 or dep2, etc). @@ -217,30 +209,29 @@ example : ynh_install_app_dependencies dep1 dep2 "dep3|dep4|dep5" Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/apt#L225) [/details] ---------------- #### ynh_add_app_dependencies + [details summary="Add dependencies to install with ynh_install_app_dependencies" class="helper-card-subtitle text-muted"] **Usage**: `ynh_add_app_dependencies --package=phpversion [--replace]` **Arguments**: + - `-p`, `--package=`: Packages to add as dependencies for the app. **Details**:
Requires YunoHost version 3.8.1 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/apt#L338) [/details] ---------------- #### ynh_remove_app_dependencies + [details summary="Remove fake package and its dependencies" class="helper-card-subtitle text-muted"] **Usage**: `ynh_remove_app_dependencies` @@ -250,18 +241,18 @@ Dependencies will removed only if no other package need them. Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/apt#L357) [/details] ---------------- #### ynh_install_extra_app_dependencies + [details summary="Install packages from an extra repository properly." class="helper-card-subtitle text-muted"] **Usage**: `ynh_install_extra_app_dependencies --repo="repo" --package="dep1 dep2" [--key=key_url] [--name=name]` **Arguments**: + - `-r`, `--repo=`: Complete url of the extra repository. - `-p`, `--package=`: The packages to install from this extra repository - `-k`, `--key=`: url to get the public key. @@ -270,21 +261,20 @@ Requires YunoHost version 2.6.4 or higher. **Details**:
Requires YunoHost version 3.8.1 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/apt#L391) [/details] ---------------- - ## BACKUP #### ynh_backup + [details summary="Add a file or a directory to the list of paths to backup" class="helper-card-subtitle text-muted"] **Usage**: `ynh_backup --src_path=src_path [--dest_path=dest_path] [--is_big] [--not_mandatory]` **Arguments**: + - `-s`, `--src_path=`: file or directory to bind or symlink or copy. it shouldn't be in the backup dir. - `-d`, `--dest_path=`: destination file or directory inside the backup dir - `-b`, `--is_big`: Indicate data are big (mail, video, image ...) @@ -299,6 +289,7 @@ creates the parent destination directory If `dest_path` is ended by a slash it complete this path with the basename of `src_path`. Example in the context of a wordpress app : + ``` ynh_backup "/etc/nginx/conf.d/$domain.d/$app.conf" # => This line will be added into CSV file @@ -343,13 +334,12 @@ all backups for this app until the setting is removed. Requires YunoHost version 2.4.0 or higher. Requires YunoHost version 3.5.0 or higher for the argument `--not_mandatory` - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/backup#L64) [/details] ---------------- #### ynh_restore + [details summary="Restore all files that were previously backuped in a core backup script or app backup script" class="helper-card-subtitle text-muted"] **Usage**: `ynh_restore` @@ -357,36 +347,29 @@ Requires YunoHost version 3.5.0 or higher for the argument `--not_mandatory` **Details**:
Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/backup#L179) [/details] ---------------- #### ynh_restore_file + [details summary="Restore a file or a directory" class="helper-card-subtitle text-muted"] **Usage**: `ynh_restore_file --origin_path=origin_path [--dest_path=dest_path] [--not_mandatory]` **Arguments**: + - `-o`, `--origin_path=`: Path where was located the file or the directory before to be backuped or relative path to $YNH_CWD where it is located in the backup archive - `-d`, `--dest_path=`: Path where restore the file or the dir. If unspecified, the destination will be `ORIGIN_PATH` or if the `ORIGIN_PATH` doesn't exist in the archive, the destination will be searched into `backup.csv` - `-m`, `--not_mandatory`: Indicate that if the file is missing, the restore process can ignore it. **Examples**: - - -- ` ynh_restore_file -o "/etc/nginx/conf.d/$domain.d/$app.conf"` - - - + +- `ynh_restore_file -o "/etc/nginx/conf.d/$domain.d/$app.conf"` + - `You can also use relative paths:` - - - -- ` ynh_restore_file -o "conf/nginx.conf"` - - + +- `ynh_restore_file -o "conf/nginx.conf"` **Details**:
Use the registered path in backup_list by ynh_backup to restore the file at the right place. @@ -402,18 +385,18 @@ if no, search for a match in the csv (eg: conf/nginx.conf) and restore it into Requires YunoHost version 2.6.4 or higher. Requires YunoHost version 3.5.0 or higher for the argument --not_mandatory - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/backup#L238) [/details] ---------------- #### ynh_store_file_checksum + [details summary="Calculate and store a file checksum into the app settings" class="helper-card-subtitle text-muted"] **Usage**: `ynh_store_file_checksum --file=file` **Arguments**: + - `-f`, `--file=`: The file on which the checksum will performed, then stored. **Details**:
@@ -421,18 +404,18 @@ $app should be defined when calling this helper Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/backup#L306) [/details] ---------------- #### ynh_backup_if_checksum_is_different + [details summary="Verify the checksum and backup the file if it's different" class="helper-card-subtitle text-muted"] **Usage**: `ynh_backup_if_checksum_is_different --file=file` **Arguments**: + - `-f`, `--file=`: The file on which the checksum test will be perfomed. **Returns**: the name of a backup file, or nothing @@ -443,18 +426,18 @@ modified config files. Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/backup#L357) [/details] ---------------- #### ynh_delete_file_checksum + [details summary="Delete a file checksum from the app settings" class="helper-card-subtitle text-muted"] **Usage**: `ynh_delete_file_checksum --file=file` **Arguments**: + - `-f`, `--file=`: The file for which the checksum will be deleted **Details**:
@@ -462,19 +445,19 @@ $app should be defined when calling this helper Requires YunoHost version 3.3.1 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/backup#L397) [/details] ---------------- #### ynh_backup_before_upgrade + [details summary="Make a backup in case of failed upgrade" class="helper-card-subtitle text-muted"] **Usage**: `ynh_backup_before_upgrade` **Details**:
Usage in a package script: + ``` ynh_backup_before_upgrade ynh_clean_setup () { @@ -485,19 +468,19 @@ Usage in a package script: Requires YunoHost version 2.7.2 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/backup#L432) [/details] ---------------- #### ynh_restore_upgradebackup + [details summary="Restore a previous backup if the upgrade process failed" class="helper-card-subtitle text-muted"] **Usage**: `ynh_restore_upgradebackup` **Details**:
Usage in a package script: + ``` ynh_backup_before_upgrade ynh_clean_setup () { @@ -508,25 +491,23 @@ Usage in a package script: Requires YunoHost version 2.7.2 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/backup#L480) [/details] ---------------- - ## CONFIG - ## FAIL2BAN #### ynh_add_fail2ban_config + [details summary="Create a dedicated fail2ban config (jail and filter conf files)" class="helper-card-subtitle text-muted"] **Usage**: `1: ynh_add_fail2ban_config --logpath=log_file --failregex=filter [--max_retry=max_retry] [--ports=ports] 2: ynh_add_fail2ban_config --use_template` **Arguments**: + - `-l`, `--logpath=`: Log file to be checked by fail2ban - `-r`, `--failregex=`: Failregex to be looked for by fail2ban - `-m`, `--max_retry=`: Maximum number of retries allowed before banning IP address - default: 3 @@ -541,6 +522,7 @@ See the documentation of `ynh_add_config` for a description of the template format and how placeholders are replaced with actual variables. Generally your template will look like that by example (for synapse): + ``` f2b_jail.conf: [__APP__] @@ -550,6 +532,7 @@ f2b_jail.conf: logpath = /var/log/__APP__/logfile.log maxretry = 3 ``` + ``` f2b_filter.conf: [INCLUDES] @@ -574,22 +557,22 @@ matched by a group named "`host`". The tag "``" can be used for standard IP/hostname matching and is only an alias for `(?:::f{4,6}:)?(?P[\w\-.^_]+)` You can find some more explainations about how to make a regex here : -https://www.fail2ban.org/wiki/index.php/MANUAL_0_8#Filters + To validate your regex you can test with this command: + ``` fail2ban-regex /var/log/YOUR_LOG_FILE_PATH /etc/fail2ban/filter.d/YOUR_APP.conf ``` Requires YunoHost version 4.1.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/fail2ban#L62) [/details] ---------------- #### ynh_remove_fail2ban_config + [details summary="Remove the dedicated fail2ban config (jail and filter conf files)" class="helper-card-subtitle text-muted"] **Usage**: `ynh_remove_fail2ban_config` @@ -597,24 +580,22 @@ Requires YunoHost version 4.1.0 or higher. **Details**:
Requires YunoHost version 3.5.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/fail2ban#L134) [/details] ---------------- - ## GETOPTS - ## HARDWARE #### ynh_get_ram + [details summary="Get the total or free amount of RAM+swap on the system" class="helper-card-subtitle text-muted"] **Usage**: `ynh_get_ram [--free|--total] [--ignore_swap|--only_swap]` **Arguments**: + - `-f`, `--free`: Count free RAM+swap - `-t`, `--total`: Count total RAM+swap - `-s`, `--ignore_swap`: Ignore swap, consider only real RAM @@ -625,18 +606,18 @@ Requires YunoHost version 3.5.0 or higher. **Details**:
Requires YunoHost version 3.8.1 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/hardware#L13) [/details] ---------------- #### ynh_require_ram + [details summary="Return 0 or 1 depending if the system has a given amount of RAM+swap free or total" class="helper-card-subtitle text-muted"] **Usage**: `ynh_require_ram --required=RAM [--free|--total] [--ignore_swap|--only_swap]` **Arguments**: + - `-r`, `--required=`: The amount to require, in MB - `-f`, `--free`: Count free RAM+swap - `-t`, `--total`: Count total RAM+swap @@ -648,90 +629,89 @@ Requires YunoHost version 3.8.1 or higher. **Details**:
Requires YunoHost version 3.8.1 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/hardware#L75) [/details] ---------------- - ## LOGGING #### ynh_die + [details summary="Print a message to stderr and exit" class="helper-card-subtitle text-muted"] **Usage**: `ynh_die --message=MSG [--ret_code=RETCODE]` **Arguments**: + - `-m`, `--message=`: Message to display - `-c`, `--ret_code=`: Exit code to exit with **Details**:
Requires YunoHost version 2.4.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/logging#L10) [/details] ---------------- #### ynh_print_info + [details summary="Display a message in the 'INFO' logging category" class="helper-card-subtitle text-muted"] **Usage**: `ynh_print_info --message="Some message"` **Arguments**: + - `-m`, `--message=`: Message to display **Details**:
Requires YunoHost version 3.2.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/logging#L30) [/details] ---------------- #### ynh_print_warn + [details summary="Print a warning on stderr" class="helper-card-subtitle text-muted"] **Usage**: `ynh_print_warn --message="Text to print"` **Arguments**: + - `-m`, `--message=`: The text to print **Details**:
Requires YunoHost version 3.2.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/logging#L56) [/details] ---------------- #### ynh_print_err + [details summary="Print an error on stderr" class="helper-card-subtitle text-muted"] **Usage**: `ynh_print_err --message="Text to print"` **Arguments**: + - `-m`, `--message=`: The text to print **Details**:
Requires YunoHost version 3.2.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/logging#L73) [/details] ---------------- #### ynh_exec_err + [details summary="Execute a command and print the result as an error" class="helper-card-subtitle text-muted"] **Usage**: `ynh_exec_err your command and args` **Arguments**: + - `command`: command to execute **Details**:
@@ -739,18 +719,18 @@ Note that you should NOT quote the command but only prefix it with ynh_exec_err Requires YunoHost version 3.2.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/logging#L92) [/details] ---------------- #### ynh_exec_warn + [details summary="Execute a command and print the result as a warning" class="helper-card-subtitle text-muted"] **Usage**: `ynh_exec_warn your command and args` **Arguments**: + - `command`: command to execute **Details**:
@@ -758,18 +738,18 @@ Note that you should NOT quote the command but only prefix it with ynh_exec_warn Requires YunoHost version 3.2.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/logging#L113) [/details] ---------------- #### ynh_exec_warn_less + [details summary="Execute a command and force the result to be printed on stdout" class="helper-card-subtitle text-muted"] **Usage**: `ynh_exec_warn_less your command and args` **Arguments**: + - `command`: command to execute **Details**:
@@ -777,18 +757,18 @@ Note that you should NOT quote the command but only prefix it with ynh_exec_warn Requires YunoHost version 3.2.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/logging#L134) [/details] ---------------- #### ynh_exec_quiet + [details summary="Execute a command and redirect stdout in /dev/null" class="helper-card-subtitle text-muted"] **Usage**: `ynh_exec_quiet your command and args` **Arguments**: + - `command`: command to execute **Details**:
@@ -796,18 +776,18 @@ Note that you should NOT quote the command but only prefix it with ynh_exec_warn Requires YunoHost version 3.2.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/logging#L155) [/details] ---------------- #### ynh_exec_fully_quiet + [details summary="Execute a command and redirect stdout and stderr in /dev/null" class="helper-card-subtitle text-muted"] **Usage**: `ynh_exec_quiet your command and args` **Arguments**: + - `command`: command to execute **Details**:
@@ -815,18 +795,18 @@ Note that you should NOT quote the command but only prefix it with ynh_exec_quie Requires YunoHost version 3.2.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/logging#L176) [/details] ---------------- #### ynh_exec_and_print_stderr_only_if_error + [details summary="Execute a command and redirect stderr in /dev/null. Print stderr on error." class="helper-card-subtitle text-muted"] **Usage**: `ynh_exec_and_print_stderr_only_if_error your command and args` **Arguments**: + - `command`: command to execute **Details**:
@@ -834,18 +814,18 @@ Note that you should NOT quote the command but only prefix it with ynh_exec_and_ Requires YunoHost version 11.2 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/logging#L197) [/details] ---------------- #### ynh_script_progression + [details summary="Print a progress bar showing the progression of an app script" class="helper-card-subtitle text-muted"] **Usage**: `ynh_script_progression --message=message [--weight=weight] [--time]` **Arguments**: + - `-m`, `--message=`: The text to print - `-w`, `--weight=`: The weight for this progression. This value is 1 by default. Use a bigger value for a longer part of the script. - `-t`, `--time`: Print the execution time since the last call to this helper. Especially usefull to define weights. The execution time is given for the duration since the previous call. So the weight should be applied to this previous call. @@ -854,13 +834,12 @@ Requires YunoHost version 11.2 or higher. **Details**:
Requires YunoHost version 3.5.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/logging#L257) [/details] ---------------- #### ynh_return + [details summary="Return data to the YunoHost core for later processing (to be used by special hooks like app config panel and core diagnosis)" class="helper-card-subtitle text-muted"] @@ -869,21 +848,20 @@ Requires YunoHost version 3.5.0 or higher. **Details**:
Requires YunoHost version 3.6.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/logging#L345) [/details] ---------------- - ## LOGROTATE #### ynh_use_logrotate + [details summary="Use logrotate to manage the logfile" class="helper-card-subtitle text-muted"] **Usage**: `ynh_use_logrotate [--logfile=/log/file] [--specific_user=user/group]` **Arguments**: + - `-l`, `--logfile=`: absolute path of logfile - `-u`, `--specific_user=`: run logrotate as the specified user and group. If not specified logrotate is runned as root. @@ -893,13 +871,12 @@ If no `--logfile` is provided, `/var/log/$app` will be used as default. Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/logrotate#L15) [/details] ---------------- #### ynh_remove_logrotate + [details summary="Remove the app's logrotate config." class="helper-card-subtitle text-muted"] **Usage**: `ynh_remove_logrotate` @@ -907,16 +884,14 @@ Requires YunoHost version 2.6.4 or higher. **Details**:
Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/logrotate#L99) [/details] ---------------- - ## MULTIMEDIA #### ynh_multimedia_build_main_dir + [details summary="Initialize the multimedia directory system" class="helper-card-subtitle text-muted"] **Usage**: `ynh_multimedia_build_main_dir` @@ -924,124 +899,118 @@ Requires YunoHost version 2.6.4 or higher. **Details**:
Requires YunoHost version 4.2 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/multimedia#L11) [/details] ---------------- #### ynh_multimedia_addfolder -[details summary="Add a directory in yunohost.multimedia" class="helper-card-subtitle text-muted"] + +[details summary="Add a directory in YunoHost.multimedia" class="helper-card-subtitle text-muted"] **Usage**: `ynh_multimedia_addfolder --source_dir="source_dir" --dest_dir="dest_dir"` **Arguments**: + - `-s`, `--source_dir=`: Source directory - The real directory which contains your medias. -- `-d`, `--dest_dir=`: Destination directory - The name and the place of the symbolic link, relative to "/home/yunohost.multimedia" +- `-d`, `--dest_dir=`: Destination directory - The name and the place of the symbolic link, relative to "/home/YunoHost.multimedia" **Details**:
This "directory" will be a symbolic link to a existing directory. Requires YunoHost version 4.2 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/multimedia#L64) [/details] ---------------- #### ynh_multimedia_addaccess + [details summary="Allow an user to have an write authorisation in multimedia directories" class="helper-card-subtitle text-muted"] **Usage**: `ynh_multimedia_addaccess user_name` **Arguments**: + - `-u`, `--user_name=`: The name of the user which gain this access. **Details**:
Requires YunoHost version 4.2 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/multimedia#L93) [/details] ---------------- - ## MYSQL #### ynh_mysql_connect_as + [details summary="Open a connection as a user" class="helper-card-subtitle text-muted"] **Usage**: `ynh_mysql_connect_as --user=user --password=password [--database=database]` **Arguments**: + - `-u`, `--user=`: the user name to connect as - `-p`, `--password=`: the user password - `-d`, `--database=`: the database to connect to **Examples**: - - -- ` ynh_mysql_connect_as --user="user" --password="pass" <<< "UPDATE ...;"` - - - -- ` ynh_mysql_connect_as --user="user" --password="pass" < /path/to/file.sql` - - + +- `ynh_mysql_connect_as --user="user" --password="pass" <<< "UPDATE ...;"` + +- `ynh_mysql_connect_as --user="user" --password="pass" < /path/to/file.sql` **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/mysql#L15) [/details] ---------------- #### ynh_mysql_execute_as_root + [details summary="Execute a command as root user" class="helper-card-subtitle text-muted"] **Usage**: `ynh_mysql_execute_as_root --sql=sql [--database=database]` **Arguments**: + - `-s`, `--sql=`: the SQL command to execute - `-d`, `--database=`: the database to connect to **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/mysql#L36) [/details] ---------------- #### ynh_mysql_execute_file_as_root + [details summary="Execute a command from a file as root user" class="helper-card-subtitle text-muted"] **Usage**: `ynh_mysql_execute_file_as_root --file=file [--database=database]` **Arguments**: + - `-f`, `--file=`: the file containing SQL commands - `-d`, `--database=`: the database to connect to **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/mysql#L60) [/details] ---------------- #### ynh_mysql_dump_db + [details summary="Dump a database" class="helper-card-subtitle text-muted"] **Usage**: `ynh_mysql_dump_db --database=database` **Arguments**: + - `-d`, `--database=`: the database name to dump **Returns**: The mysqldump output @@ -1051,18 +1020,18 @@ Requires YunoHost version 2.2.4 or higher. **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/mysql#L128) [/details] ---------------- #### ynh_mysql_user_exists + [details summary="Check if a mysql user exists" class="helper-card-subtitle text-muted"] **Usage**: `ynh_mysql_user_exists --user=user` **Arguments**: + - `-u`, `--user=`: the user for which to check existence **Returns**: 0 if the user exists, 1 otherwise. @@ -1070,18 +1039,18 @@ Requires YunoHost version 2.2.4 or higher. **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/mysql#L160) [/details] ---------------- #### ynh_mysql_setup_db + [details summary="Create a database, an user and its password. Then store the password in the app's config" class="helper-card-subtitle text-muted"] **Usage**: `ynh_mysql_setup_db --db_user=user --db_name=name [--db_pwd=pwd]` **Arguments**: + - `-u`, `--db_user=`: Owner of the database - `-n`, `--db_name=`: Name of the database - `-p`, `--db_pwd=`: Password of the database. If not provided, a password will be generated @@ -1092,39 +1061,38 @@ It will also be stored as "`mysqlpwd`" into the app settings. Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/mysql#L198) [/details] ---------------- #### ynh_mysql_remove_db + [details summary="Remove a database if it exists, and the associated user" class="helper-card-subtitle text-muted"] **Usage**: `ynh_mysql_remove_db --db_user=user --db_name=name` **Arguments**: + - `-u`, `--db_user=`: Owner of the database - `-n`, `--db_name=`: Name of the database **Details**:
Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/mysql#L224) [/details] ---------------- - ## NETWORK #### ynh_find_port + [details summary="Find a free port and return it" class="helper-card-subtitle text-muted"] **Usage**: `ynh_find_port --port=begin_port` **Arguments**: + - `-p`, `--port=`: port to start to search **Returns**: the port number @@ -1134,18 +1102,18 @@ Requires YunoHost version 2.6.4 or higher. **Details**:
Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/network#L12) [/details] ---------------- #### ynh_port_available + [details summary="Test if a port is available" class="helper-card-subtitle text-muted"] **Usage**: `ynh_find_port --port=XYZ` **Arguments**: + - `-p`, `--port=`: port to check **Returns**: 0 if the port is available, 1 if it is already used by another process. @@ -1155,18 +1123,18 @@ Requires YunoHost version 2.6.4 or higher. **Details**:
Requires YunoHost version 3.8.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/network#L36) [/details] ---------------- #### ynh_validate_ip4 + [details summary="Validate an IPv4 address" class="helper-card-subtitle text-muted"] **Usage**: `ynh_validate_ip4 --ip_address=ip_address` **Arguments**: + - `-i`, `--ip_address=`: the ipv4 address to check **Returns**: 0 for valid ipv4 addresses, 1 otherwise @@ -1176,18 +1144,18 @@ Requires YunoHost version 3.8.0 or higher. **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/network#L99) [/details] ---------------- #### ynh_validate_ip6 + [details summary="Validate an IPv6 address" class="helper-card-subtitle text-muted"] **Usage**: `ynh_validate_ip6 --ip_address=ip_address` **Arguments**: + - `-i`, `--ip_address=`: the ipv6 address to check **Returns**: 0 for valid ipv6 addresses, 1 otherwise @@ -1197,16 +1165,14 @@ Requires YunoHost version 2.2.4 or higher. **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/network#L119) [/details] ---------------- - ## NGINX #### ynh_add_nginx_config + [details summary="Create a dedicated nginx config" class="helper-card-subtitle text-muted"] **Usage**: `ynh_add_nginx_config` @@ -1217,6 +1183,7 @@ See the documentation of `ynh_add_config` for a description of the template format and how placeholders are replaced with actual variables. Additionally, ynh_add_nginx_config will replace: + - `#sub_path_only` by empty string if `path_url` is not `'/'` - `#root_path_only` by empty string if `path_url` *is* `'/'` @@ -1225,13 +1192,12 @@ location Requires YunoHost version 4.1.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/nginx#L19) [/details] ---------------- #### ynh_remove_nginx_config + [details summary="Remove the dedicated nginx config" class="helper-card-subtitle text-muted"] **Usage**: `ynh_remove_nginx_config` @@ -1239,13 +1205,12 @@ Requires YunoHost version 4.1.0 or higher. **Details**:
Requires YunoHost version 2.7.2 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/nginx#L41) [/details] ---------------- #### ynh_change_url_nginx_config + [details summary="Regen the nginx config in a change url context" class="helper-card-subtitle text-muted"] **Usage**: `ynh_change_url_nginx_config` @@ -1253,16 +1218,14 @@ Requires YunoHost version 2.7.2 or higher. **Details**:
Requires YunoHost version 11.1.9 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/nginx#L52) [/details] ---------------- - ## NODEJS #### ynh_use_nodejs + [details summary="Load the version of node for an app, and set variables." class="helper-card-subtitle text-muted"] **Usage**: `ynh_use_nodejs` @@ -1289,36 +1252,41 @@ Exemple: $ynh_node_load_PATH $final_path/script_that_use_npm.sh` Finally, to start a nodejs service with the correct version, 2 solutions Either the app is dependent of node or npm, but does not called it directly. In such situation, you need to load PATH : + ``` Environment="__NODE_ENV_PATH__" ExecStart=__FINALPATH__/my_app ``` -You will replace __NODE_ENV_PATH__ with $ynh_node_load_PATH. + +You will replace **NODE_ENV_PATH** with $ynh_node_load_PATH. Or node start the app directly, then you don't need to load the PATH variable + ``` ExecStart=__YNH_NODE__ my_app run ``` -You will replace __YNH_NODE__ with $ynh_node + +You will replace **YNH_NODE** with $ynh_node 2 other variables are also available - - $nodejs_path: The absolute path to node binaries for the chosen version. - - $nodejs_version: Just the version number of node for this app. Stored as 'nodejs_version' in settings.yml. + +- $nodejs_path: The absolute path to node binaries for the chosen version. +- $nodejs_version: Just the version number of node for this app. Stored as 'nodejs_version' in settings.yml. Requires YunoHost version 2.7.12 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/nodejs#L52) [/details] ---------------- #### ynh_install_nodejs + [details summary="Install a specific version of nodejs" class="helper-card-subtitle text-muted"] **Usage**: `ynh_install_nodejs --nodejs_version=nodejs_version` **Arguments**: + - `-n`, `--nodejs_version=`: Version of node to install. When possible, your should prefer to use major version number (e.g. 8 instead of 8.10.0). The crontab will then handle the update of minor versions when needed. **Details**:
@@ -1331,34 +1299,32 @@ Refer to `ynh_use_nodejs` for more information about available commands and vari Requires YunoHost version 2.7.12 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/nodejs#L92) [/details] ---------------- #### ynh_remove_nodejs + [details summary="Remove the version of node used by the app." class="helper-card-subtitle text-muted"] **Usage**: `ynh_remove_nodejs` **Details**:
This helper will check if another app uses the same version of node. + - If not, this version of node will be removed. - If no other app uses node, n will be also removed. Requires YunoHost version 2.7.12 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/nodejs#L165) [/details] ---------------- - ## PERMISSION #### ynh_permission_create + [details summary="Create a new permission for the app" class="helper-card-subtitle text-muted"] **Usage**: `ynh_permission_create --permission="permission" [--url="url"] [--additional_urls="second-url" [ "third-url" ]] [--auth_header=true|false] @@ -1366,6 +1332,7 @@ Requires YunoHost version 2.7.12 or higher. [--protected=true|false]` **Arguments**: + - `-p`, `--permission=`: the name for the permission (by default a permission named "main" already exist) - `-u`, `--url=`: (optional) URL for which access will be allowed/forbidden. Note that if 'show_tile' is enabled, this URL will be the URL of the tile. - `-A`, `--additional_urls=`: (optional) List of additional URL for which access will be allowed/forbidden @@ -1380,6 +1347,7 @@ Example 1: `ynh_permission_create --permission=admin --url=/admin --additional_u --label="My app admin" --show_tile=true` This example will create a new permission permission with this following effect: + - A tile named "My app admin" in the SSO will be available for the users alice and bob. This tile will point to the relative url '/admin'. - Only the user alice and bob will have the access to theses following url: /admin, domain.tld/admin, /superadmin @@ -1408,6 +1376,7 @@ For example: re:domain.tld/app/api/[A-Z]*$ -> domain.tld/app/api/[A-Z]*$ Note that globally the parameter 'url' and 'additional_urls' are same. The only difference is: + - 'url' is only one url, 'additional_urls' can be a list of urls. There are no limitation of 'additional_urls' - 'url' is used for the url of tile in the SSO (if enabled with the 'show_tile' parameter) @@ -1418,22 +1387,22 @@ The SSO pass (by default) to the application theses following HTTP header (linke - "Email": user email Generally this feature is usefull to authenticate automatically the user in the application but in some case the application don't work with theses header and theses header need to be disabled to have the application to work correctly. -See https://github.com/YunoHost/issues/issues/1420 for more informations +See for more informations Requires YunoHost version 3.7.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/permission#L66) [/details] ---------------- #### ynh_permission_delete + [details summary="Remove a permission for the app (note that when the app is removed all permission is automatically removed)" class="helper-card-subtitle text-muted"] **Usage**: `ynh_permission_delete --permission="permission"` **Arguments**: + - `-p`, `--permission=`: the name for the permission (by default a permission named "main" is removed automatically when the app is removed) **Example**: `ynh_permission_delete --permission=editors` @@ -1441,37 +1410,37 @@ Requires YunoHost version 3.7.0 or higher. **Details**:
Requires YunoHost version 3.7.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/permission#L152) [/details] ---------------- #### ynh_permission_exists + [details summary="Check if a permission exists" class="helper-card-subtitle text-muted"] **Usage**: `ynh_permission_exists --permission=permission | exit: Return 1 if the permission doesn't exist, 0 otherwise` **Arguments**: + - `-p`, `--permission=`: the permission to check **Details**:
Requires YunoHost version 3.7.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/permission#L169) [/details] ---------------- #### ynh_permission_url + [details summary="Redefine the url associated to a permission" class="helper-card-subtitle text-muted"] **Usage**: `ynh_permission_url --permission "permission" [--url="url"] [--add_url="new-url" [ "other-new-url" ]] [--remove_url="old-url" [ "other-old-url" ]] [--auth_header=true|false] [--clear_urls]` **Arguments**: + - `-p`, `--permission=`: the name for the permission (by default a permission named "main" is removed automatically when the app is removed) - `-u`, `--url=`: (optional) URL for which access will be allowed/forbidden. Note that if you want to remove url you can pass an empty sting as arguments (""). - `-a`, `--add_url=`: (optional) List of additional url to add for which access will be allowed/forbidden. @@ -1482,19 +1451,19 @@ Requires YunoHost version 3.7.0 or higher. **Details**:
Requires YunoHost version 3.7.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/permission#L192) [/details] ---------------- #### ynh_permission_update + [details summary="Update a permission for the app" class="helper-card-subtitle text-muted"] **Usage**: `ynh_permission_update --permission "permission" [--add="group" ["group" ...]] [--remove="group" ["group" ...]] [--label="label"] [--show_tile=true|false] [--protected=true|false]` **Arguments**: + - `-p`, `--permission=`: the name for the permission (by default a permission named "main" already exist) - `-a`, `--add=`: the list of group or users to enable add to the permission - `-r`, `--remove=`: the list of group or users to remove from the permission @@ -1505,19 +1474,19 @@ Requires YunoHost version 3.7.0 or higher. **Details**:
Requires YunoHost version 3.7.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/permission#L260) [/details] ---------------- #### ynh_permission_has_user + [details summary="Check if a permission has an user" class="helper-card-subtitle text-muted"] **Usage**: `ynh_permission_has_user --permission=permission --user=user | exit: Return 1 if the permission doesn't have that user or doesn't exist, 0 otherwise` **Arguments**: + - `-p`, `--permission=`: the permission to check - `-u`, `--user=`: the user seek in the permission @@ -1526,13 +1495,12 @@ Requires YunoHost version 3.7.0 or higher. **Details**:
Requires YunoHost version 3.7.1 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/permission#L329) [/details] ---------------- #### ynh_legacy_permissions_exists + [details summary="Check if a legacy permissions exist" class="helper-card-subtitle text-muted"] **Usage**: `ynh_legacy_permissions_exists @@ -1541,13 +1509,12 @@ Requires YunoHost version 3.7.1 or higher. **Details**:
Requires YunoHost version 4.1.2 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/permission#L359) [/details] ---------------- #### ynh_legacy_permissions_delete_all + [details summary="Remove all legacy permissions" class="helper-card-subtitle text-muted"] **Usage**: `ynh_legacy_permissions_delete_all` @@ -1558,10 +1525,10 @@ Requires YunoHost version 4.1.2 or higher. [/details] ---------------- - ## PHP #### ynh_add_fpm_config + [details summary="Create a dedicated PHP-FPM config" class="helper-card-subtitle text-muted"] **Usage**: `ynh_add_fpm_config` @@ -1586,7 +1553,7 @@ Otherwise, if you want the user to have control over these, we encourage to crea Case 2 (deprecate) : you provided an entire conf/php-fpm.conf -The configuration will be hydrated, replacing __FOOBAR__ placeholders with $foobar values, etc. +The configuration will be hydrated, replacing **FOOBAR** placeholders with $foobar values, etc. The resulting configuration will be deployed to the appropriate place, /etc/php/$phpversion/fpm/pool.d/$app.conf @@ -1626,13 +1593,12 @@ Set as 'high', the process manager will be set at 'static'. There will be always Requires YunoHost version 4.1.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/php#L70) [/details] ---------------- #### ynh_remove_fpm_config + [details summary="Remove the dedicated PHP-FPM config" class="helper-card-subtitle text-muted"] **Usage**: `ynh_remove_fpm_config` @@ -1640,18 +1606,18 @@ Requires YunoHost version 4.1.0 or higher. **Details**:
Requires YunoHost version 2.7.2 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/php#L284) [/details] ---------------- #### ynh_composer_exec + [details summary="Execute a command with Composer" class="helper-card-subtitle text-muted"] **Usage**: `ynh_composer_exec [--phpversion=phpversion] [--workdir=$install_dir] --commands="commands"` **Arguments**: + - `-v`, `--phpversion`: PHP version to use with composer - `-w`, `--workdir`: The directory from where the command will be executed. Default $install_dir or $final_path - `-c`, `--commands`: Commands to execute. @@ -1659,18 +1625,18 @@ Requires YunoHost version 2.7.2 or higher. **Details**:
Requires YunoHost version 4.2 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/php#L517) [/details] ---------------- #### ynh_install_composer + [details summary="Install and initialize Composer in the given directory" class="helper-card-subtitle text-muted"] **Usage**: `ynh_install_composer [--phpversion=phpversion] [--workdir=$install_dir] [--install_args="--optimize-autoloader"] [--composerversion=composerversion]` **Arguments**: + - `-v`, `--phpversion`: PHP version to use with composer - `-w`, `--workdir`: The directory from where the command will be executed. Default $install_dir. - `-a`, `--install_args`: Additional arguments provided to the composer install. Argument --no-dev already include @@ -1679,87 +1645,81 @@ Requires YunoHost version 4.2 or higher. **Details**:
Requires YunoHost version 4.2 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/php#L549) [/details] ---------------- - ## POSTGRESQL #### ynh_psql_connect_as + [details summary="Open a connection as a user" class="helper-card-subtitle text-muted"] **Usage**: `ynh_psql_connect_as --user=user --password=password [--database=database]` **Arguments**: + - `-u`, `--user=`: the user name to connect as - `-p`, `--password=`: the user password - `-d`, `--database=`: the database to connect to **Examples**: - - -- ` ynh_psql_connect_as 'user' 'pass' <<< "UPDATE ...;"` - - - -- ` ynh_psql_connect_as 'user' 'pass' < /path/to/file.sql` - - + +- `ynh_psql_connect_as 'user' 'pass' <<< "UPDATE ...;"` + +- `ynh_psql_connect_as 'user' 'pass' < /path/to/file.sql` **Details**:
Requires YunoHost version 3.5.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/postgresql#L18) [/details] ---------------- #### ynh_psql_execute_as_root + [details summary="Execute a command as root user" class="helper-card-subtitle text-muted"] **Usage**: `ynh_psql_execute_as_root --sql=sql [--database=database]` **Arguments**: + - `-s`, `--sql=`: the SQL command to execute - `-d`, `--database=`: the database to connect to **Details**:
Requires YunoHost version 3.5.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/postgresql#L39) [/details] ---------------- #### ynh_psql_execute_file_as_root + [details summary="Execute a command from a file as root user" class="helper-card-subtitle text-muted"] **Usage**: `ynh_psql_execute_file_as_root --file=file [--database=database]` **Arguments**: + - `-f`, `--file=`: the file containing SQL commands - `-d`, `--database=`: the database to connect to **Details**:
Requires YunoHost version 3.5.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/postgresql#L64) [/details] ---------------- #### ynh_psql_dump_db + [details summary="Dump a database" class="helper-card-subtitle text-muted"] **Usage**: `ynh_psql_dump_db --database=database` **Arguments**: + - `-d`, `--database=`: the database name to dump **Returns**: the psqldump output @@ -1769,54 +1729,54 @@ Requires YunoHost version 3.5.0 or higher. **Details**:
Requires YunoHost version 3.5.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/postgresql#L135) [/details] ---------------- #### ynh_psql_user_exists + [details summary="Check if a psql user exists" class="helper-card-subtitle text-muted"] **Usage**: `ynh_psql_user_exists --user=user | exit: Return 1 if the user doesn't exist, 0 otherwise` **Arguments**: + - `-u`, `--user=`: the user for which to check existence **Details**:
Requires YunoHost version 3.5.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/postgresql#L168) [/details] ---------------- #### ynh_psql_database_exists + [details summary="Check if a psql database exists" class="helper-card-subtitle text-muted"] **Usage**: `ynh_psql_database_exists --database=database | exit: Return 1 if the database doesn't exist, 0 otherwise` **Arguments**: + - `-d`, `--database=`: the database for which to check existence **Details**:
Requires YunoHost version 3.5.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/postgresql#L190) [/details] ---------------- #### ynh_psql_setup_db + [details summary="Create a database, an user and its password. Then store the password in the app's config" class="helper-card-subtitle text-muted"] **Usage**: `ynh_psql_setup_db --db_user=user --db_name=name [--db_pwd=pwd]` **Arguments**: + - `-u`, `--db_user=`: Owner of the database - `-n`, `--db_name=`: Name of the database - `-p`, `--db_pwd=`: Password of the database. If not provided, a password will be generated @@ -1827,57 +1787,56 @@ It will also be stored as "psqlpwd" into the app settings. Requires YunoHost version 2.7.13 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/postgresql#L234) [/details] ---------------- #### ynh_psql_remove_db + [details summary="Remove a database if it exists, and the associated user" class="helper-card-subtitle text-muted"] **Usage**: `ynh_psql_remove_db --db_user=user --db_name=name` **Arguments**: + - `-u`, `--db_user=`: Owner of the database - `-n`, `--db_name=`: Name of the database **Details**:
Requires YunoHost version 2.7.13 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/postgresql#L265) [/details] ---------------- - ## SETTING #### ynh_app_setting_get + [details summary="Get an application setting" class="helper-card-subtitle text-muted"] **Usage**: `ynh_app_setting_get --app=app --key=key` **Arguments**: + - `-a`, `--app=`: the application id - `-k`, `--key=`: the setting to get **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/setting#L10) [/details] ---------------- #### ynh_app_setting_set + [details summary="Set an application setting" class="helper-card-subtitle text-muted"] **Usage**: `ynh_app_setting_set --app=app --key=key --value=value` **Arguments**: + - `-a`, `--app=`: the application id - `-k`, `--key=`: the setting name to set - `-v`, `--value=`: the setting value to set @@ -1885,36 +1844,36 @@ Requires YunoHost version 2.2.4 or higher. **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/setting#L36) [/details] ---------------- #### ynh_app_setting_delete + [details summary="Delete an application setting" class="helper-card-subtitle text-muted"] **Usage**: `ynh_app_setting_delete --app=app --key=key` **Arguments**: + - `-a`, `--app=`: the application id - `-k`, `--key=`: the setting to delete **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/setting#L62) [/details] ---------------- #### ynh_webpath_available + [details summary="Check availability of a web path" class="helper-card-subtitle text-muted"] **Usage**: `ynh_webpath_available --domain=domain --path_url=path` **Arguments**: + - `-d`, `--domain=`: the domain/host of the url - `-p`, `--path_url=`: the web path to check the availability of @@ -1923,18 +1882,18 @@ Requires YunoHost version 2.2.4 or higher. **Details**:
Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/setting#L123) [/details] ---------------- #### ynh_webpath_register + [details summary="Register/book a web path for an app" class="helper-card-subtitle text-muted"] **Usage**: `ynh_webpath_register --app=app --domain=domain --path_url=path` **Arguments**: + - `-a`, `--app=`: the app for which the domain should be registered - `-d`, `--domain=`: the domain/host of the web path - `-p`, `--path_url=`: the web path to be registered @@ -1944,21 +1903,20 @@ Requires YunoHost version 2.6.4 or higher. **Details**:
Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/setting#L145) [/details] ---------------- - ## STRING #### ynh_string_random + [details summary="Generate a random string" class="helper-card-subtitle text-muted"] **Usage**: `ynh_string_random [--length=string_length]` **Arguments**: + - `-l`, `--length=`: the string length to generate (default: 24) - `-f`, `--filter=`: the kind of characters accepted in the output (default: 'A-Za-z0-9') @@ -1969,18 +1927,18 @@ Requires YunoHost version 2.6.4 or higher. **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/string#L13) [/details] ---------------- #### ynh_replace_string + [details summary="Substitute/replace a string (or expression) by another in a file" class="helper-card-subtitle text-muted"] **Usage**: `ynh_replace_string --match_string=match_string --replace_string=replace_string --target_file=target_file` **Arguments**: + - `-m`, `--match_string=`: String to be searched and replaced in the file - `-r`, `--replace_string=`: String that will replace matches - `-f`, `--target_file=`: File in which the string will be replaced. @@ -1991,18 +1949,18 @@ sub-expressions can be used (see sed manual page for more information) Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/string#L40) [/details] ---------------- #### ynh_replace_special_string + [details summary="Substitute/replace a special string by another in a file" class="helper-card-subtitle text-muted"] **Usage**: `ynh_replace_special_string --match_string=match_string --replace_string=replace_string --target_file=target_file` **Arguments**: + - `-m`, `--match_string=`: String to be searched and replaced in the file - `-r`, `--replace_string=`: String that will replace matches - `-t`, `--target_file=`: File in which the string will be replaced. @@ -2013,18 +1971,18 @@ characters, you can't use some regular expressions and sub-expressions. Requires YunoHost version 2.7.7 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/string#L71) [/details] ---------------- #### ynh_sanitize_dbid + [details summary="Sanitize a string intended to be the name of a database" class="helper-card-subtitle text-muted"] **Usage**: `ynh_sanitize_dbid --db_name=name` **Arguments**: + - `-n`, `--db_name=`: name to correct/sanitize **Returns**: the corrected name @@ -2036,21 +1994,20 @@ Underscorify the string (replace - and . by _) Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/string#L103) [/details] ---------------- - ## SYSTEMD #### ynh_add_systemd_config + [details summary="Create a dedicated systemd config" class="helper-card-subtitle text-muted"] **Usage**: `ynh_add_systemd_config [--service=service] [--template=template]` **Arguments**: + - `-s`, `--service=`: Service name (optionnal, `$app` by default) - `-t`, `--template=`: Name of template file (optionnal, this is 'systemd' by default, meaning `../conf/systemd.service` will be used as template) @@ -2062,35 +2019,35 @@ format and how placeholders are replaced with actual variables. Requires YunoHost version 4.1.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/systemd#L15) [/details] ---------------- #### ynh_remove_systemd_config + [details summary="Remove the dedicated systemd config" class="helper-card-subtitle text-muted"] **Usage**: `ynh_remove_systemd_config [--service=service]` **Arguments**: + - `-s`, `--service=`: Service name (optionnal, $app by default) **Details**:
Requires YunoHost version 2.7.2 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/systemd#L38) [/details] ---------------- #### ynh_systemd_action + [details summary="Start (or other actions) a service, print a log in case of failure and optionnaly wait until the service is completely started" class="helper-card-subtitle text-muted"] **Usage**: `ynh_systemd_action [--service_name=service_name] [--action=action] [ [--line_match="line to match"] [--log_path=log_path] [--timeout=300] [--length=20] ]` **Arguments**: + - `-n`, `--service_name=`: Name of the service to start. Default : `$app` - `-a`, `--action=`: Action to perform with systemctl. Default: start - `-l`, `--line_match=`: Line to match - The line to find in the log to attest the service have finished to boot. If not defined it don't wait until the service is completely started. @@ -2101,21 +2058,20 @@ Requires YunoHost version 2.7.2 or higher. **Details**:
Requires YunoHost version 3.5.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/systemd#L67) [/details] ---------------- - ## USER #### ynh_user_exists + [details summary="Check if a YunoHost user exists" class="helper-card-subtitle text-muted"] **Usage**: `ynh_user_exists --username=username` **Arguments**: + - `-u`, `--username=`: the username to check **Returns**: 0 if the user exists, 1 otherwise. @@ -2125,18 +2081,18 @@ Requires YunoHost version 3.5.0 or higher. **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/user#L12) [/details] ---------------- #### ynh_user_get_info + [details summary="Retrieve a YunoHost user information" class="helper-card-subtitle text-muted"] **Usage**: `ynh_user_get_info --username=username --key=key` **Arguments**: + - `-u`, `--username=`: the username to retrieve info from - `-k`, `--key=`: the key to retrieve @@ -2147,13 +2103,12 @@ Requires YunoHost version 2.2.4 or higher. **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/user#L33) [/details] ---------------- #### ynh_user_list + [details summary="Get the list of YunoHost users" class="helper-card-subtitle text-muted"] **Usage**: `ynh_user_list` @@ -2165,18 +2120,18 @@ Requires YunoHost version 2.2.4 or higher. **Details**:
Requires YunoHost version 2.4.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/user#L53) [/details] ---------------- #### ynh_system_user_exists + [details summary="Check if a user exists on the system" class="helper-card-subtitle text-muted"] **Usage**: `ynh_system_user_exists --username=username` **Arguments**: + - `-u`, `--username=`: the username to check **Returns**: 0 if the user exists, 1 otherwise. @@ -2184,18 +2139,18 @@ Requires YunoHost version 2.4.0 or higher. **Details**:
Requires YunoHost version 2.2.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/user#L64) [/details] ---------------- #### ynh_system_group_exists + [details summary="Check if a group exists on the system" class="helper-card-subtitle text-muted"] **Usage**: `ynh_system_group_exists --group=group` **Arguments**: + - `-g`, `--group=`: the group to check **Returns**: 0 if the group exists, 1 otherwise. @@ -2203,18 +2158,18 @@ Requires YunoHost version 2.2.4 or higher. **Details**:
Requires YunoHost version 3.5.0.2 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/user#L82) [/details] ---------------- #### ynh_system_user_create + [details summary="Create a system user" class="helper-card-subtitle text-muted"] **Usage**: `ynh_system_user_create --username=user_name [--home_dir=home_dir] [--use_shell] [--groups="group1 group2"]` **Arguments**: + - `-u`, `--username=`: Name of the system user that will be create - `-h`, `--home_dir=`: Path of the home dir for the user. Usually the final path of the app. If this argument is omitted, the user will be created without home - `-s`, `--use_shell`: Create a user using the default login shell if present. If this argument is omitted, the user will be created with /usr/sbin/nologin shell @@ -2222,40 +2177,42 @@ Requires YunoHost version 3.5.0.2 or higher. **Details**:
Create a nextcloud user with no home directory and /usr/sbin/nologin login shell (hence no login capability) : + ``` ynh_system_user_create --username=nextcloud ``` + Create a discourse user using /var/www/discourse as home directory and the default login shell : + ``` ynh_system_user_create --username=discourse --home_dir=/var/www/discourse --use_shell ``` Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/user#L111) [/details] ---------------- #### ynh_system_user_delete + [details summary="Delete a system user" class="helper-card-subtitle text-muted"] **Usage**: `ynh_system_user_delete --username=user_name` **Arguments**: + - `-u`, `--username=`: Name of the system user that will be create **Details**:
Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/user#L153) [/details] ---------------- #### ynh_exec_as + [details summary="Execute a command as another user" class="helper-card-subtitle text-muted"] **Usage**: `ynh_exec_as $USER COMMAND [ARG ...]` @@ -2263,16 +2220,14 @@ Requires YunoHost version 2.6.4 or higher. **Details**:
Requires YunoHost version 4.1.7 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/user#L179) [/details] ---------------- - ## UTILS #### ynh_abort_if_errors + [details summary="Exits if an error occurs during the execution of the script." class="helper-card-subtitle text-muted"] **Usage**: `ynh_abort_if_errors` @@ -2284,24 +2239,25 @@ and a call to `ynh_clean_setup` is triggered if it has been defined by your scri Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/utils#L61) [/details] ---------------- #### ynh_setup_source + [details summary="Download, check integrity, uncompress and patch the source from app.src" class="helper-card-subtitle text-muted"] **Usage**: `ynh_setup_source --dest_dir=dest_dir [--source_id=source_id] [--keep="file1 file2"] [--full_replace]` **Arguments**: + - `-d`, `--dest_dir=`: Directory where to setup sources - `-s`, `--source_id=`: Name of the source, defaults to `main` (when the sources resource exists in manifest.toml) or (legacy) `app` otherwise - `-k`, `--keep=`: Space-separated list of files/folders that will be backup/restored in $dest_dir, such as a config file you don't want to overwrite. For example 'conf.json secrets.json logs' (no trailing `/` for folders) - `-r`, `--full_replace=`: Remove previous sources before installing new sources **Details**:
+ #### New 'sources' resources (See also the resources documentation which may be more complete?) @@ -2337,6 +2293,7 @@ platform = "linux/amd64" # (defaults to "linux/$YNH_ARCH") to be used ``` You may also define assets url and checksum per-architectures such as: + ```toml [resources.sources] [resources.sources.main] @@ -2348,13 +2305,12 @@ You may also define assets url and checksum per-architectures such as: In which case ynh_setup_source --dest_dir="$install_dir" will automatically pick the appropriate source depending on the arch - - #### Legacy format '.src' This helper will read `conf/${source_id}.src`, download and install the sources. The src file need to contains: + ``` SOURCE_URL=Address to download the app archive SOURCE_SUM=Sha256 sum @@ -2366,6 +2322,7 @@ SOURCE_PLATFORM=linux/arm64/v8 ``` The helper will: + - Download the specific URL if there is no local archive - Check the integrity with the specific sha256 sum - Uncompress the archive to `$dest_dir`. @@ -2376,18 +2333,18 @@ The helper will: Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/utils#L154) [/details] ---------------- #### ynh_local_curl + [details summary="Curl abstraction to help with POST requests to local pages (such as installation forms)" class="helper-card-subtitle text-muted"] **Usage**: `ynh_local_curl "page_uri" "key1=value1" "key2=value2" ...` **Arguments**: + - `page_uri`: Path (relative to `$path_url`) of the page where POST data will be sent - `key1=value1`: (Optionnal) POST key and corresponding value - `key2=value2`: (Optionnal) Another POST key and corresponding value @@ -2402,31 +2359,26 @@ For multiple calls, cookies are persisted between each call for the same app Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/utils#L404) [/details] ---------------- #### ynh_add_config + [details summary="Create a dedicated config file from a template" class="helper-card-subtitle text-muted"] **Usage**: `ynh_add_config --template="template" --destination="destination"` **Arguments**: + - `-t`, `--template=`: Template config file to use - `-d`, `--destination=`: Destination of the config file **Examples**: - - -- ` ynh_add_config --template=".env" --destination="$install_dir/.env" use the template file "../conf/.env"` - - - -- ` ynh_add_config --template="/etc/nginx/sites-available/default" --destination="etc/nginx/sites-available/mydomain.conf"` - - + +- `ynh_add_config --template=".env" --destination="$install_dir/.env" use the template file "../conf/.env"` + +- `ynh_add_config --template="/etc/nginx/sites-available/default" --destination="etc/nginx/sites-available/mydomain.conf"` **Details**:
The template can be by default the name of a file in the conf directory @@ -2435,6 +2387,7 @@ of a YunoHost Package, a relative path or an absolute path. The helper will use the template `template` to generate a config file `destination` by replacing the following keywords with global variables that should be defined before calling this helper : + ``` __PATH__ by $path_url __NAME__ by $app @@ -2444,7 +2397,9 @@ that should be defined before calling this helper : __PHPVERSION__ by $YNH_PHP_VERSION (packaging v1 only, packaging v2 uses phpversion setting implicitly set by apt resource) __YNH_NODE_LOAD_PATH__ by $ynh_node_load_PATH ``` + And any dynamic variables that should be defined before calling this helper like: + ``` __DOMAIN__ by $domain __APP__ by $app @@ -2460,18 +2415,18 @@ into the app settings when configuration is done. Requires YunoHost version 4.1.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/utils#L488) [/details] ---------------- #### ynh_read_var_in_file + [details summary="Get a value from heterogeneous file (yaml, json, php, python...)" class="helper-card-subtitle text-muted"] **Usage**: `ynh_read_var_in_file --file=PATH --key=KEY` **Arguments**: + - `-f`, `--file=`: the path to the file - `-k`, `--key=`: the key to get - `-a`, `--after=`: the line just before the key (in case of multiple lines with the name of the key in the file) @@ -2485,7 +2440,7 @@ if you have several identical keys in your files Example of line this helpers can managed correctly .yml title: YunoHost documentation - email: 'yunohost@yunohost.org' + email: '' .json "theme": "colib'ris", "port": 8102 @@ -2500,23 +2455,23 @@ Example of line this helpers can managed correctly user => 20 .py USER = 8102 - user = 'https://donate.local' + user = '' CUSTOM['user'] = 'YunoHost' Requires YunoHost version 4.3 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/utils#L646) [/details] ---------------- #### ynh_write_var_in_file + [details summary="Set a value into heterogeneous file (yaml, json, php, python...)" class="helper-card-subtitle text-muted"] **Usage**: `ynh_write_var_in_file --file=PATH --key=KEY --value=VALUE` **Arguments**: + - `-f`, `--file=`: the path to the file - `-k`, `--key=`: the key to set - `-v`, `--value=`: the value to set @@ -2525,13 +2480,12 @@ Requires YunoHost version 4.3 or higher. **Details**:
Requires YunoHost version 4.3 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/utils#L724) [/details] ---------------- #### ynh_get_debian_release + [details summary="Fetch the Debian release codename" class="helper-card-subtitle text-muted"] **Usage**: `ynh_get_debian_release` @@ -2541,35 +2495,35 @@ Requires YunoHost version 4.3 or higher. **Details**:
Requires YunoHost version 2.7.12 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/utils#L839) [/details] ---------------- #### ynh_secure_remove + [details summary="Remove a file or a directory securely" class="helper-card-subtitle text-muted"] **Usage**: `ynh_secure_remove --file=path_to_remove` **Arguments**: + - `-f`, `--file=`: File or directory to remove **Details**:
Requires YunoHost version 2.6.4 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/utils#L870) [/details] ---------------- #### ynh_read_manifest + [details summary="Read the value of a key in a ynh manifest file" class="helper-card-subtitle text-muted"] **Usage**: `ynh_read_manifest --manifest="manifest.json" --key="key"` **Arguments**: + - `-m`, `--manifest=`: Path of the manifest to read - `-k`, `--key=`: Name of the key to find @@ -2578,18 +2532,18 @@ Requires YunoHost version 2.6.4 or higher. **Details**:
Requires YunoHost version 3.5.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/utils#L904) [/details] ---------------- #### ynh_app_upstream_version + [details summary="Read the upstream version from the manifest or `$YNH_APP_MANIFEST_VERSION`" class="helper-card-subtitle text-muted"] **Usage**: `ynh_app_upstream_version [--manifest="manifest.json"]` **Arguments**: + - `-m`, `--manifest=`: Path of the manifest to read **Returns**: the version number of the upstream app @@ -2603,18 +2557,18 @@ For example, if the manifest contains `4.3-2~ynh3` the function will return `4.3 Requires YunoHost version 3.5.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/utils#L947) [/details] ---------------- #### ynh_app_package_version + [details summary="Read package version from the manifest" class="helper-card-subtitle text-muted"] **Usage**: `ynh_app_package_version [--manifest="manifest.json"]` **Arguments**: + - `-m`, `--manifest=`: Path of the manifest to read **Returns**: the version number of the package @@ -2626,13 +2580,12 @@ For example, if the manifest contains `4.3-2~ynh3` the function will return `3` Requires YunoHost version 3.5.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/utils#L976) [/details] ---------------- #### ynh_check_app_version_changed + [details summary="Checks the app version to upgrade with the existing app version and returns:" class="helper-card-subtitle text-muted"] **Usage**: `ynh_check_app_version_changed` @@ -2645,20 +2598,20 @@ of it, when it's not needed Requires YunoHost version 3.5.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/utils#L997) [/details] ---------------- #### ynh_compare_current_package_version + [details summary="Compare the current package version against another version given as an argument." class="helper-card-subtitle text-muted"] **Usage**: `ynh_compare_current_package_version --comparison (lt|le|eq|ne|ge|gt) --version ` **Arguments**: + - `--comparison`: Comparison type. Could be : `lt` (lower than), `le` (lower or equal), `eq` (equal), `ne` (not equal), `ge` (greater or equal), `gt` (greater than) -- `--version`: The version to compare. Need to be a version in the yunohost package version type (like `2.3.1~ynh4`) +- `--version`: The version to compare. Need to be a version in the YunoHost package version type (like `2.3.1~ynh4`) **Returns**: 0 if the evaluation is true, 1 if false. @@ -2668,6 +2621,7 @@ Requires YunoHost version 3.5.0 or higher. This helper is usually used when we need to do some actions only for some old package versions. Generally you might probably use it as follow in the upgrade script : + ``` if ynh_compare_current_package_version --comparison lt --version 2.3.2~ynh1 then @@ -2677,9 +2631,6 @@ fi Requires YunoHost version 3.8.0 or higher. - - [Dude, show me the code!](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/helpers/utils#L1027) [/details] ---------------- - diff --git a/pages/06.contribute/10.packaging_apps/80.resources/15.appresources/packaging_apps_resources.md b/pages/06.contribute/10.packaging_apps/80.resources/15.appresources/packaging_apps_resources.md index 541eae2d..e1a80b99 100644 --- a/pages/06.contribute/10.packaging_apps/80.resources/15.appresources/packaging_apps_resources.md +++ b/pages/06.contribute/10.packaging_apps/80.resources/15.appresources/packaging_apps_resources.md @@ -9,7 +9,6 @@ routes: Doc auto-generated by [this script](https://github.com/YunoHost/yunohost/blob/4759ff66a7c93df2f654c11086585131744ad61d/doc/generate_resource_doc.py) on 01/03/2024 (YunoHost version 11.2.10.3) - ---------------- ## Apt @@ -17,6 +16,7 @@ Doc auto-generated by [this script](https://github.com/YunoHost/yunohost/blob/47 Create a virtual package in apt, depending on the list of specified packages that the app needs. The virtual packages is called `$app-ynh-deps` (with `_` being replaced by `-` in the app name, see `ynh_install_app_dependencies`) ##### Example + ```toml [resources.apt] packages = ["nyancat", "lolcat", "sl"] @@ -28,15 +28,18 @@ extras.yarn.packages = ["yarn"] ``` ##### Properties + - `packages`: List of packages to be installed via `apt` - `packages_from_raw_bash`: A multi-line bash snippet (using triple quotes as open/close) which should echo additional packages to be installed. Meant to be used for packages to be conditionally installed depending on architecture, debian version, install questions, or other logic. - `extras`: A dict of (repo, key, packages) corresponding to "extra" repositories to fetch dependencies from ##### Provision/Update + - The code literally calls the bash helpers `ynh_install_app_dependencies` and `ynh_install_extra_app_dependencies`, similar to what happens in v1. - Note that when `packages` contains some phpX.Y-foobar dependencies, this will automagically define a `phpversion` setting equal to `X.Y` which can therefore be used in app scripts ($phpversion) or templates (`__PHPVERSION__`) ##### Deprovision + - The code literally calls the bash helper `ynh_remove_app_dependencies` ---------------- @@ -46,18 +49,21 @@ extras.yarn.packages = ["yarn"] Creates a directory to be used by the app as the data store directory, typically where the app multimedia or large assets added by users are located. The corresponding path is stored in the settings as `data_dir`. This resource behaves very similarly to install_dir. ##### Example + ```toml [resources.data_dir] # (empty - defaults are usually okay) ``` ##### Properties + - `dir`: (default: `/home/yunohost.app/__APP__`) The full path of the data dir - `subdirs`: (default: empty list) A list of subdirs to initialize inside the data dir. For example, `['foo', 'bar']` - `owner`: (default: `__APP__:rwx`) The owner (and owner permissions) for the data dir - `group`: (default: `__APP__:rx`) The group (and group permissions) for the data dir ##### Provision/Update + - if the dir path changed and a folder exists at the old location, the folder will be `mv`'ed to the new location - otherwise, creates the directory if it doesn't exists yet - create each subdir declared and which do not exist already @@ -65,10 +71,12 @@ Creates a directory to be used by the app as the data store directory, typically - save the value of `dir` as `data_dir` in the app's settings, which can be then used by the app scripts (`$data_dir`) and conf templates (`__DATA_DIR__`) ##### Deprovision + - (only if the purge option is chosen by the user) recursively deletes the directory if it exists - also delete the corresponding setting ##### Legacy management + - In the past, the setting may have been called `datadir`. The code will automatically rename it as `data_dir`. - As explained in the 'Provision/Update' section, the folder will also be moved if the location changed @@ -83,24 +91,29 @@ NB: only one DB can be handled in such a way (is there really an app that would NB2: no automagic migration will happen in an suddenly change `type` from `mysql` to `postgresql` or viceversa in its life ##### Example + ```toml [resources.database] type = "mysql" # or : "postgresql". Only these two values are supported ``` ##### Properties + - `type`: The database type, either `mysql` or `postgresql` ##### Provision/Update + - (Re)set the `$db_name` and `$db_user` settings with the sanitized app name (replacing `-` and `.` with `_`) - If `$db_pwd` doesn't already exists, pick a random database password and store it in that setting - If the database doesn't exists yet, create the SQL user and DB using `ynh_mysql_create_db` or `ynh_psql_create_db`. ##### Deprovision + - Drop the DB using `ynh_mysql_remove_db` or `ynh_psql_remove_db` - Deletes the `db_name`, `db_user` and `db_pwd` settings ##### Legacy management + - In the past, the sql passwords may have been named `mysqlpwd` or `psqlpwd`, in which case it will automatically be renamed as `db_pwd` ---------------- @@ -110,17 +123,20 @@ type = "mysql" # or : "postgresql". Only these two values are supported Creates a directory to be used by the app as the installation directory, typically where the app sources and assets are located. The corresponding path is stored in the settings as `install_dir` ##### Example + ```toml [resources.install_dir] # (empty - defaults are usually okay) ``` ##### Properties + - `dir`: (default: `/var/www/__APP__`) The full path of the install dir - `owner`: (default: `__APP__:rwx`) The owner (and owner permissions) for the install dir - `group`: (default: `__APP__:rx`) The group (and group permissions) for the install dir ##### Provision/Update + - during install, the folder will be deleted if it already exists (FIXME: is this what we want?) - if the dir path changed and a folder exists at the old location, the folder will be `mv`'ed to the new location - otherwise, creates the directory if it doesn't exists yet @@ -128,9 +144,11 @@ Creates a directory to be used by the app as the installation directory, typical - save the value of `dir` as `install_dir` in the app's settings, which can be then used by the app scripts (`$install_dir`) and conf templates (`__INSTALL_DIR__`) ##### Deprovision + - recursively deletes the directory if it exists ##### Legacy management + - In the past, the setting was called `final_path`. The code will automatically rename it as `install_dir`. - As explained in the 'Provision/Update' section, the folder will also be moved if the location changed @@ -145,6 +163,7 @@ Additional permissions can be created, typically to have a specific tile and/or The list of allowed user/groups may be initialized using the content of the `init_{perm}_permission` question from the manifest, hence `init_main_permission` replaces the `is_public` question and shall contain a group name (typically, `all_users` or `visitors`). ##### Example + ```toml [resources.permissions] main.url = "/" @@ -156,6 +175,7 @@ admin.allowed = "admins" # Assuming the "admins" group exists (cf future devel ``` ##### Properties (for each perm name) + - `url`: The relative URI corresponding to this permission. Typically `/` or `/something`. This property may be omitted for non-web permissions. - `show_tile`: (default: `true` if `url` is defined) Wether or not a tile should be displayed for that permission in the user portal - `allowed`: (default: nobody) The group initially allowed to access this perm, if `init_{perm}_permission` is not defined in the manifest questions. Note that the admin may tweak who is allowed/unallowed on that permission later on, this is only meant to **initialize** the permission. @@ -164,13 +184,16 @@ admin.allowed = "admins" # Assuming the "admins" group exists (cf future devel - `additional_urls`: (default: none) List of additional URL for which access will be allowed/forbidden ##### Provision/Update + - Delete any permissions that may exist and be related to this app yet is not declared anymore - Loop over the declared permissions and create them if needed or update them with the new values ##### Deprovision + - Delete all permission related to this app ##### Legacy management + - Legacy `is_public` setting will be deleted if it exists ---------------- @@ -182,6 +205,7 @@ Book port(s) to be used by the app, typically to be used to the internal reverse Note that because multiple ports can be booked, each properties is prefixed by the name of the port. `main` is a special name and will correspond to the setting `$port`, whereas for example `xmpp_client` will correspond to the setting `$port_xmpp_client`. ##### Example + ```toml [resources.ports] # (empty should be fine for most apps... though you can customize stuff if absolutely needed) @@ -194,20 +218,24 @@ xmpp_client.exposed = "TCP" # here, we're telling that the port needs to be publ ``` ##### Properties (for every port name) + - `default`: The prefered value for the port. If this port is already being used by another process right now, or is booked in another app's setting, the code will increment the value until it finds a free port and store that value as the setting. If no value is specified, a random value between 10000 and 60000 is used. - `exposed`: (default: `false`) Wether this port should be opened on the firewall and be publicly reachable. This should be kept to `false` for the majority of apps than only need a port for internal reverse-proxying! Possible values: `false`, `true`(=`Both`), `Both`, `TCP`, `UDP`. This will result in the port being opened on the firewall, and the diagnosis checking that a program answers on that port. - `fixed`: (default: `false`) Tells that the app absolutely needs the specific value provided in `default`, typically because it's needed for a specific protocol ##### Provision/Update (for every port name) + - If not already booked, look for a free port, starting with the `default` value (or a random value between 10000 and 60000 if no `default` set) - If `exposed` is not `false`, open the port in the firewall accordingly - otherwise make sure it's closed. - The value of the port is stored in the `$port` setting for the `main` port, or `$port_NAME` for other `NAME`s ##### Deprovision + - Close the ports on the firewall if relevant - Deletes all the port settings ##### Legacy management + - In the past, some settings may have been named `NAME_port` instead of `port_NAME`, in which case the code will automatically rename the old setting. ---------------- @@ -263,14 +291,14 @@ Or more complex examples with several element, including one with asset that dep - `prefetch` : `true` (default) or `false`, wether or not to pre-fetch this asset during the provisioning phase of the resource. If several arch-dependent url are provided, YunoHost will only prefetch the one for the current system architecture. - `url` : the asset's URL - - If the asset's URL depend on the architecture, you may instead provide `amd64.url`, `i386.url`, `armhf.url` and `arm64.url` (depending on what architectures are supported), using the same `dpkg --print-architecture` nomenclature as for the supported architecture key in the manifest + - If the asset's URL depend on the architecture, you may instead provide `amd64.url`, `i386.url`, `armhf.url` and `arm64.url` (depending on what architectures are supported), using the same `dpkg --print-architecture` nomenclature as for the supported architecture key in the manifest - `sha256` : the asset's sha256sum. This is used both as an integrity check, and as a layer of security to protect against malicious actors which could have injected malicious code inside the asset... - - Same as `url` : if the asset's URL depend on the architecture, you may instead provide `amd64.sha256`, `i386.sha256`, ... + - Same as `url` : if the asset's URL depend on the architecture, you may instead provide `amd64.sha256`, `i386.sha256`, ... - `format` : The "format" of the asset. It is typically automatically guessed from the extension of the URL (or the mention of "tarball", "zipball" in the URL), but can be set explicitly: - - `tar.gz`, `tar.xz`, `tar.bz2` : will use `tar` to extract the archive - - `zip` : will use `unzip` to extract the archive - - `docker` : useful to extract files from an already-built docker image (instead of rebuilding them locally). Will use `docker-image-extract` - - `whatever`: whatever arbitrary value, not really meaningful except to imply that the file won't be extracted (eg because it's a .deb to be manually installed with dpkg/apt, or a script, or ...) + - `tar.gz`, `tar.xz`, `tar.bz2` : will use `tar` to extract the archive + - `zip` : will use `unzip` to extract the archive + - `docker` : useful to extract files from an already-built docker image (instead of rebuilding them locally). Will use `docker-image-extract` + - `whatever`: whatever arbitrary value, not really meaningful except to imply that the file won't be extracted (eg because it's a .deb to be manually installed with dpkg/apt, or a script, or ...) - `in_subdir`: `true` (default) or `false`, depending on if there's an intermediate subdir in the archive before accessing the actual files. Can also be `N` (an integer) to handle special cases where there's `N` level of subdir to get rid of to actually access the files - `extract` : `true` or `false`. Defaults to `true` for archives such as `zip`, `tar.gz`, `tar.bz2`, ... Or defaults to `false` when `format` is not something that should be extracted. When `extract = false`, the file will only be `mv`ed to the location, possibly renamed using the `rename` value - `rename`: some string like `whatever_your_want`, to be used for convenience when `extract` is `false` and the default name of the file is not practical @@ -278,7 +306,7 @@ Or more complex examples with several element, including one with asset that dep ###### Regarding `autoupdate` -Strictly speaking, this has nothing to do with the actual app install. `autoupdate` is expected to contain metadata for automatic maintenance / update of the app sources info in the manifest. It is meant to be a simpler replacement for "autoupdate" Github workflow mechanism. +Strictly speaking, this has nothing to do with the actual app install. `autoupdate` is expected to contain metadata for automatic maintenance / update of the app sources info in the manifest. It is meant to be a simpler replacement for "autoupdate" GitHub workflow mechanism. The infos are used by this script : which is ran by the YunoHost infrastructure periodically and will create the corresponding pull request automatically. @@ -298,7 +326,7 @@ And choose one strategy in the following ones: - `autoupdate.asset = "some regex"` (when there's only one asset to use). The regex is used to find the appropriate asset among the list of all assets - or several `autoupdate.asset.$arch = "some_regex"` (when the asset is arch-specific). The regex is used to find the appropriate asset for the specific arch among the list of assets - `latest__tag` : look for the latest tag (by sorting tags and finding the "largest" version). Then using the corresponding tar.gz url. Tags containing `rc`, `beta`, `alpha`, `start` are ignored, and actually any tag which doesn't look like `x.y.z` or `vx.y.z` -- `latest__commit` : will use the latest commit on github, and the corresponding tarball. If this is used for the 'main' source, it will also assume that the version is YYYY.MM.DD corresponding to the date of the commit. +- `latest__commit` : will use the latest commit on GitHub, and the corresponding tarball. If this is used for the 'main' source, it will also assume that the version is YYYY.MM.DD corresponding to the date of the commit. It is also possible to define `autoupdate.upstream` to use a different Git repository instead of the code repository from the upstream section of the manifest. This can be useful when, for example, the app uses other assets such as plugin from a different repository. @@ -312,9 +340,11 @@ autoupdate.version_regex = "^release-v(.*)$" And the autoupdater will use the matched group (here: `4.1`) as the version. ##### Provision/Update + - For elements with `prefetch = true`, will download the asset (for the appropriate architecture) and store them in `/var/cache/yunohost/download/$app/$source_id`, to be later picked up by `ynh_setup_source`. (NB: this only happens during install and upgrade, not restore) ##### Deprovision + - Nothing (just cleanup the cache) ---------------- @@ -324,21 +354,24 @@ And the autoupdater will use the matched group (here: `4.1`) as the version. Provision a system user to be used by the app. The username is exactly equal to the app id ##### Example + ```toml [resources.system_user] # (empty - defaults are usually okay) ``` ##### Properties + - `allow_ssh`: (default: False) Adds the user to the ssh.app group, allowing SSH connection via this user - `allow_sftp`: (default: False) Adds the user to the sftp.app group, allowing SFTP connection via this user - `allow_email`: (default: False) Enable authentication on the mail stack for the system user and send mail using `__APP__@__DOMAIN__`. A `mail_pwd` setting is automatically defined (similar to `db_pwd` for databases). You can then configure the app to use `__APP__` and `__MAIL_PWD__` as SMTP credentials (with host 127.0.0.1). You can also tweak the user-part of the domain-part of the email used by manually defining a custom setting `mail_user` or `mail_domain` - `home`: (default: `/var/www/__APP__`) Defines the home property for this user. NB: unfortunately you can't simply use `__INSTALL_DIR__` or `__DATA_DIR__` for now ##### Provision/Update + - will create the system user if it doesn't exists yet - will add/remove the ssh/sftp.app groups ##### Deprovision -- deletes the user and group +- deletes the user and group diff --git a/pages/06.contribute/10.packaging_apps/80.resources/20.bash_tips/shell_variables_scope.fr.md b/pages/06.contribute/10.packaging_apps/80.resources/20.bash_tips/shell_variables_scope.fr.md index 7226dd7b..a7e43a92 100644 --- a/pages/06.contribute/10.packaging_apps/80.resources/20.bash_tips/shell_variables_scope.fr.md +++ b/pages/06.contribute/10.packaging_apps/80.resources/20.bash_tips/shell_variables_scope.fr.md @@ -11,6 +11,7 @@ Les variables existent pour le shell courant et ses enfants uniquement. Un script exécuté depuis le script n'est pas un enfant, c'est un autre shell qui n'héritera que des variables d'environnement du script appelant, pas des variables globales ou locales. Lors de l'appel d'un script, il n'est pas démarré dans le shell courant, mais dans une nouvelle instance de bash qui hérite des variables d'environnements de son parent. + ```bash var1=value1 export var2=value2 @@ -29,30 +30,33 @@ chmod +x other_script.sh # Ici, var1 n'existe pas, seul var2 existe encore. # Car c'est une variable d'environnement. ``` + Dans le shell courant, d'où le script est appelé, faite + ```bash echo $var1 - $var2 ``` -Aucune des 2 variables n'existent, car leur portée se limite au script appelé. Jamais au parent. +Aucune des 2 variables n'existent, car leur portée se limite au script appelé. Jamais au parent. ### Les fonctions dans un script Utiliser une fonction ne change pas la portée des variables. + ```bash var1=value1 export var2=value2 set_variable () { - var3=value3 - export var4=value4 + var3=value3 + export var4=value4 - echo "$var1" - echo "$var2" - echo "$var3" - echo "$var4" - # Toutes les variables existent ici - # car la fonction hérite des variables du script. + echo "$var1" + echo "$var2" + echo "$var3" + echo "$var4" + # Toutes les variables existent ici + # car la fonction hérite des variables du script. } set_variable @@ -80,22 +84,23 @@ chmod +x other_script.sh ### L'usage des variables locales Les variables locales sont limitées à une fonction et ses enfants + ```bash var1=value1 export var2=value2 set_variable () { - var3=value3 - export var4=value4 - local var5=value5 + var3=value3 + export var4=value4 + local var5=value5 - echo "$var1" - echo "$var2" - echo "$var3" - echo "$var4" - echo "$var5" - # Toutes les variables existent ici - # car la fonction hérite des variables du script. + echo "$var1" + echo "$var2" + echo "$var3" + echo "$var4" + echo "$var5" + # Toutes les variables existent ici + # car la fonction hérite des variables du script. } set_variable @@ -127,25 +132,26 @@ chmod +x other_script.sh L'intérêt d'utiliser une variable locale est donc de limiter cette variable à la seule fonction qui l'a déclaré. Et donc ne pas polluer le script dans sa globalité avec des variables inutile pour ce dernier. Il existe également un second avantage à l'usage d'une variable locale, c'est de ne pas modifier le contenu d'une variable globale. + ```bash var1=value1 var2=value2 var3=value3 set_variable () { - echo "$var1" - echo "$var2" - echo "$var3" + echo "$var1" + echo "$var2" + echo "$var3" - echo "-" + echo "-" - var2=new_value2 - local var3=new_value3 + var2=new_value2 + local var3=new_value3 - echo "$var1" - echo "$var2" - echo "$var3" - # La valeurs de var2 et var3 sont modifiées dans la fonction + echo "$var1" + echo "$var2" + echo "$var3" + # La valeurs de var2 et var3 sont modifiées dans la fonction } set_variable @@ -163,42 +169,43 @@ echo "$var3" Comme vu précédemment, les variables modifiée ou créée dans la fonction affecte le script car la fonction est exécutée dans le même shell que celui-ci. Cela change si on exécute la fonction dans un sous-shell, la fonction devient un enfant qui hérite de son parent uniquement. + ```bash var1=value1 var2=value2 var3=value3 fonction2 () { - echo "-" - echo "var1=$var1" - echo "var2=$var2" - echo "var3=$var3" - echo "var4=$var4" - echo "var5=$var5" - # Même var3, qui est locale, est héritée par la fonction enfant. + echo "-" + echo "var1=$var1" + echo "var2=$var2" + echo "var3=$var3" + echo "var4=$var4" + echo "var5=$var5" + # Même var3, qui est locale, est héritée par la fonction enfant. } set_variable () { - echo "var1=$var1" - echo "var2=$var2" - echo "var3=$var3" - # Les variables sont héritées du parent. + echo "var1=$var1" + echo "var2=$var2" + echo "var3=$var3" + # Les variables sont héritées du parent. - echo "-" + echo "-" - var2=new_value2 - local var3=new_value3 - var4=new_value4 - export var5=new_value5 + var2=new_value2 + local var3=new_value3 + var4=new_value4 + export var5=new_value5 - echo "var1=$var1" - echo "var2=$var2" - echo "var3=$var3" - echo "var4=$var4" - echo "var5=$var5" - # La valeurs de var2 et var3 sont modifiées dans la fonction + echo "var1=$var1" + echo "var2=$var2" + echo "var3=$var3" + echo "var4=$var4" + echo "var5=$var5" + # La valeurs de var2 et var3 sont modifiées dans la fonction - (fonction2) + (fonction2) } (set_variable) diff --git a/pages/06.contribute/10.packaging_apps/80.resources/20.bash_tips/shell_variables_scope.md b/pages/06.contribute/10.packaging_apps/80.resources/20.bash_tips/shell_variables_scope.md index c32b5515..667c3aea 100644 --- a/pages/06.contribute/10.packaging_apps/80.resources/20.bash_tips/shell_variables_scope.md +++ b/pages/06.contribute/10.packaging_apps/80.resources/20.bash_tips/shell_variables_scope.md @@ -11,6 +11,7 @@ Variables exists for the current shell and its children only. Another script executed from the script is not a child, it's another shell which herited only the environment variables from its caller script, not its globals or locals variables. When a script is called, it isn't started in the current shell, but in a new instance of bash which herite environment variables from its parent. + ```bash var1=value1 export var2=value2 @@ -29,30 +30,33 @@ chmod +x other_script.sh # Here, var1 doesn't exist, only var2 still exists. # Because it's an environment variable. ``` + In your current shell, where you launch this script, try + ```bash echo $var1 - $var2 ``` -None of this 2 variables exists, because their scope is limited to the script itself. Never its parent. +None of this 2 variables exists, because their scope is limited to the script itself. Never its parent. ### Functions inside a script Use a function would not change the scope of variables. + ```bash var1=value1 export var2=value2 set_variable () { - var3=value3 - export var4=value4 + var3=value3 + export var4=value4 - echo "$var1" - echo "$var2" - echo "$var3" - echo "$var4" - # All variables exists here - # Because the function inherite its variables from the script. + echo "$var1" + echo "$var2" + echo "$var3" + echo "$var4" + # All variables exists here + # Because the function inherite its variables from the script. } set_variable @@ -80,22 +84,23 @@ chmod +x other_script.sh ### The usage of locales variables Locales variables are limited to the function and its children. + ```bash var1=value1 export var2=value2 set_variable () { - var3=value3 - export var4=value4 - local var5=value5 + var3=value3 + export var4=value4 + local var5=value5 - echo "$var1" - echo "$var2" - echo "$var3" - echo "$var4" - echo "$var5" - # All variables exists here - # Because the function inherite its variables from the script. + echo "$var1" + echo "$var2" + echo "$var3" + echo "$var4" + echo "$var5" + # All variables exists here + # Because the function inherite its variables from the script. } set_variable @@ -127,25 +132,26 @@ chmod +x other_script.sh Using a local variable is usefull for limit it scope to the function only. And not bother the script in its globality with useless variables. But there's also another advantage with local variable, do not modify the content of a global variable. + ```bash var1=value1 var2=value2 var3=value3 set_variable () { - echo "$var1" - echo "$var2" - echo "$var3" + echo "$var1" + echo "$var2" + echo "$var3" - echo "-" + echo "-" - var2=new_value2 - local var3=new_value3 + var2=new_value2 + local var3=new_value3 - echo "$var1" - echo "$var2" - echo "$var3" - # Values of var2 and var3 are modified in the function. + echo "$var1" + echo "$var2" + echo "$var3" + # Values of var2 and var3 are modified in the function. } set_variable @@ -163,42 +169,43 @@ echo "$var3" As seen previously, modified or created variables in a function can affect the main script because the function is executed in the same shell. But, the things are different if the function is executed in a sub shell, the function become a child which only inherite from its parent. + ```bash var1=value1 var2=value2 var3=value3 fonction2 () { - echo "-" - echo "var1=$var1" - echo "var2=$var2" - echo "var3=$var3" - echo "var4=$var4" - echo "var5=$var5" - # Even var3, which is local, is inherited from the parent function. + echo "-" + echo "var1=$var1" + echo "var2=$var2" + echo "var3=$var3" + echo "var4=$var4" + echo "var5=$var5" + # Even var3, which is local, is inherited from the parent function. } set_variable () { - echo "var1=$var1" - echo "var2=$var2" - echo "var3=$var3" - # Variables are inherited from the parent. + echo "var1=$var1" + echo "var2=$var2" + echo "var3=$var3" + # Variables are inherited from the parent. - echo "-" + echo "-" - var2=new_value2 - local var3=new_value3 - var4=new_value4 - export var5=new_value5 + var2=new_value2 + local var3=new_value3 + var4=new_value4 + export var5=new_value5 - echo "var1=$var1" - echo "var2=$var2" - echo "var3=$var3" - echo "var4=$var4" - echo "var5=$var5" - # Values of var2 and var3 are modified in the function. + echo "var1=$var1" + echo "var2=$var2" + echo "var3=$var3" + echo "var4=$var4" + echo "var5=$var5" + # Values of var2 and var3 are modified in the function. - (fonction2) + (fonction2) } (set_variable) diff --git a/pages/06.contribute/10.packaging_apps/packaging_apps_intro.de.md b/pages/06.contribute/10.packaging_apps/packaging_apps_intro.de.md index a5671b8c..00c0fcad 100644 --- a/pages/06.contribute/10.packaging_apps/packaging_apps_intro.de.md +++ b/pages/06.contribute/10.packaging_apps/packaging_apps_intro.de.md @@ -1,11 +1,11 @@ --- -Titel: Einführung in die Paketierung -Template: docs -Taxonomie: - Kategorie: docs -Routen: - Standard: '/packaging_apps_intro' - Aliases: +title: Einführung in die Paketierung +template: docs +taxonomy: + category: docs +routes: + default: '/packaging_apps_intro' + aliases: - '/packaging_apps' --- @@ -13,7 +13,6 @@ In dieser Dokumentation findest du alle grundlegenden Konzepte und Vokabeln, die Wir werden detailliert beschreiben, was ein YunoHost-Anwendungspaket ist, wie es funktioniert, wie du dein eigenes Paket erstellst und wie du Hilfe findest, wenn du diese benötigst. - ## 1. Paketierungs-Philosophie Die Möglichkeit, Anwendungen einfach aus einem Katalog zu installieren, ist eine Schlüsselfunktion von YunoHost. Während du in den Prozess der YunoHost-Anwendungspaketierung eintauchst, solltest du dich an diese Schlüsselprinzipien erinnern: @@ -26,7 +25,6 @@ Die Möglichkeit, Anwendungen einfach aus einem Katalog zu installieren, ist ein - Bei der Paketierung von YunoHost-Apps geht es **nicht nur um die Installation** von Quellen und Abhängigkeiten: Es geht auch um Wartung (Upgrade, Backup...) und die Integration der App in das YunoHost-Ökosystem (NGINX, SSO/LDAP, Fail2Ban, Anwendungskatalog, UI/UX...) - ## 2. Voraussetzungen In dieser Dokumentation wird vorausgesetzt, dass: @@ -52,34 +50,34 @@ Verschiedene Tools wurden implementiert, um die Anwendung zu testen und ihr Verh Nach einer Weile bildete sich eine Reihe von gemeinsamen Praktiken und Konventionen heraus, die sich in der `example_ynh`-Vorlagenanwendung widerspiegeln und erhalten. Während es für Entwickler verlockend ist, die Namensschemata von Variablen zu ändern oder die Struktur von Skripten zu refaktorisieren, stellt sich heraus, dass es sogar noch wichtiger ist, sich an die gemeinsamen Praktiken zu halten (auch wenn sie willkürlich und nicht elegant sind), um die Wartung aller Anwendungen durch jedes Mitglied der Paketierungsgemeinschaft über alle Repos hinweg zu erleichtern! -Nichtsdestotrotz war die inhärente Struktur von Anwendungen, auch wenn es Helfer gab, schwer und langweilig zu warten, da sie zu viele redundante Codestücke enthielt oder mit seltsamen historischen Konventionen gefüllt war. **Ein neues v2-Format** [wurde entworfen und zu YunoHost 11.1 Anfang 2023 hinzugefügt] (https://github.com/YunoHost/yunohost/pull/1289) in der Hoffnung, das App-Packaging zu modernisieren und zu vereinfachen und die UI/UX von YunoHost zu verbessern. +Nichtsdestotrotz war die inhärente Struktur von Anwendungen, auch wenn es Helfer gab, schwer und langweilig zu warten, da sie zu viele redundante Codestücke enthielt oder mit seltsamen historischen Konventionen gefüllt war. **Ein neues v2-Format** [wurde entworfen und zu YunoHost 11.1 Anfang 2023 hinzugefügt] () in der Hoffnung, das App-Packaging zu modernisieren und zu vereinfachen und die UI/UX von YunoHost zu verbessern. Es wird jedoch [**ein zukünftiges v3-Format**](https://github.com/YunoHost/issues/issues/2136) geben, um die Paketierung von Anwendungen weiter zu vereinfachen (z.B. durch die Übernahme von NGINX/systemd/... Konfigurationen, die Beseitigung der Notwendigkeit, Skripte zum Entfernen/Backup/Wiederherstellen manuell zu schreiben, usw.) - ## 4. Allgemeiner Überblick über die Struktur einer YunoHost-App Eine YunoHost-Anwendung besteht aus einem Git-Repository. Wir empfehlen dir, einen Blick auf diese Code-Repositories zu werfen, um dich mit der Struktur der App-Repositories vertraut zu machen: + - [die `helloworld_ynh` App](https://github.com/YunoHost-Apps/helloworld_ynh) - [die `example_ynh` app](https://github.com/YunoHost/example_ynh), die alle gängigen Funktionen und empfohlenen Formatierungen veranschaulicht - Deine bevorzugte "Real-Life"-App in der [YunoHost-Apps-Organisation](https://github.com/orgs/YunoHost-Apps/repositories) -Unter den in einem Paket enthaltenen Dateien sind die wichtigsten: +Unter den in einem Paket enthaltenen Dateien sind die wichtigsten: - das **Anwendungsmanifest** `manifest.toml` (oder `.json` in der Vergangenheit) - - Dies kann als der Ausweis der Anwendung angesehen werden, der verschiedene Metadaten enthält. - - Sie enthält auch die Fragen, die bei der Installation der Anwendung gestellt werden. - - und eine Reihe von "Ressourcen" zum Initialisieren, wie z.B. herunterzuladende Quellen oder zu installierende apt-Abhängigkeiten + - Dies kann als der Ausweis der Anwendung angesehen werden, der verschiedene Metadaten enthält. + - Sie enthält auch die Fragen, die bei der Installation der Anwendung gestellt werden. + - und eine Reihe von "Ressourcen" zum Initialisieren, wie z.B. herunterzuladende Quellen oder zu installierende apt-Abhängigkeiten - **scripts/** enthält eine Reihe von Bash-Skripten, die den in YunoHost angebotenen Aktionen entsprechen - - `_common.sh`: gemeinsame Variablen oder eigene Funktionen, die in anderen Skripten enthalten sind - - `install`/`remove`: die Installations- und Deinstallationsprozedur - - `upgrade`: die Upgrade-Prozedur - - `backup`/`restore`: die Sicherungs-/Wiederherstellungsprozeduren - - (`change_url`): Ändern des Ortes, an dem die Anwendung in Bezug auf die Webzugriffsurl installiert ist + - `_common.sh`: gemeinsame Variablen oder eigene Funktionen, die in anderen Skripten enthalten sind + - `install`/`remove`: die Installations- und Deinstallationsprozedur + - `upgrade`: die Upgrade-Prozedur + - `backup`/`restore`: die Sicherungs-/Wiederherstellungsprozeduren + - (`change_url`): Ändern des Ortes, an dem die Anwendung in Bezug auf die Webzugriffsurl installiert ist - **conf/** enthält eine Reihe von Konfigurationsvorlagen, die bei der Installation der Anwendung verwendet werden. Hier sind einige Beispiele für häufig vorkommende Dateien: - - `nginx.conf`: die NGINX (=Webserver) Konfigurationsvorlage für diese Anwendung - - systemd.service": die Konfigurationsvorlage für den systemd-Dienst für diese Anwendung - - config.json/yaml/???`: die Konfigurationsvorlage für die Anwendung + - `nginx.conf`: die NGINX (=Webserver) Konfigurationsvorlage für diese Anwendung + - systemd.service": die Konfigurationsvorlage für den systemd-Dienst für diese Anwendung + - config.json/yaml/???`: die Konfigurationsvorlage für die Anwendung Grob gesagt besteht die Installation selbst im Allgemeinen aus den folgenden Vorgängen (die jedoch je nach Komplexität und von der App verwendeten Technologien variieren können) - nicht unbedingt in dieser genauen Reihenfolge: @@ -87,27 +85,30 @@ Grob gesagt besteht die Installation selbst im Allgemeinen aus den folgenden Vor 2. YunoHost stellt dem Administrator die in `manifest.toml` definierten Fragen zur Installation 3. Der Administrator füllt das Formular aus und startet die Installation 4. YunoHost stellt eine Reihe von technischen Voraussetzungen (genannt 'Ressourcen') bereit, wie z.B.: - - Initialisierung des Schlüssel/Wertspeichers der Anwendung `settings.yml` mit den Antworten des Administrators auf das Installationsformular - - legt einen UNIX-Systembenutzer für diese Anwendung an - - installiert apt-Abhängigkeiten, die für diese Anwendung benötigt werden - - wählt einen Port für internes Reverse-Proxying aus - - initialisiert eine leere SQL-Datenbank - - konfiguriert SSOwat-Berechtigungen - - ... + +- Initialisierung des Schlüssel/Wertspeichers der Anwendung `settings.yml` mit den Antworten des Administrators auf das Installationsformular +- legt einen UNIX-Systembenutzer für diese Anwendung an +- installiert apt-Abhängigkeiten, die für diese Anwendung benötigt werden +- wählt einen Port für internes Reverse-Proxying aus +- initialisiert eine leere SQL-Datenbank +- konfiguriert SSOwat-Berechtigungen +- ... + 5. Das eigentliche Skript `Install` wird ausgeführt und erledigt in der Regel: - - Holen und Bereitstellen der App-Quellen - - die App konfigurieren (typischerweise DB-Anmeldedaten, interner Reverse-Proxy-Port...) - - Hinzufügen der NGINX-Konfiguration - - Hinzufügen der systemd-Konfiguration für den Daemon der Anwendung - - Startet den Daemon der Anwendung - - verschiedene Feinabstimmungen zur Fertigstellung + +- Holen und Bereitstellen der App-Quellen +- die App konfigurieren (typischerweise DB-Anmeldedaten, interner Reverse-Proxy-Port...) +- Hinzufügen der NGINX-Konfiguration +- Hinzufügen der systemd-Konfiguration für den Daemon der Anwendung +- Startet den Daemon der Anwendung +- verschiedene Feinabstimmungen zur Fertigstellung + 6. ??? 7. Die Anwendung ist einsatzbereit! - ## 5. Erstellen deines allerersten YunoHost-Pakets -Wenn du nicht wirklich bei Null anfangen willst oder von [`example_ynh`](https://github.com/YunoHost/example_ynh), ist eine gängige Praxis, eine Anwendung zu identifizieren, die derjenigen ähnlich ist, die du zu paketieren versuchst - typischerweise, weil du dich auf die gleichen Technologien stützt -, das entsprechende Code-Repository zu klonen und die verschiedenen Dateien anzupassen. +Wenn du nicht wirklich bei Null anfangen willst oder von [`example_ynh`](https://github.com/YunoHost/example_ynh), ist eine gängige Praxis, eine Anwendung zu identifizieren, die derjenigen ähnlich ist, die du zu paketieren versuchst - typischerweise, weil du dich auf die gleichen Technologien stützt -, das entsprechende Code-Repository zu klonen und die verschiedenen Dateien anzupassen. TODO/FIXME : hier sollten wir eine Reihe von bekannten Anwendungen für klassische Technologien auflisten diff --git a/pages/06.contribute/10.packaging_apps/packaging_apps_intro.fr.md b/pages/06.contribute/10.packaging_apps/packaging_apps_intro.fr.md index d3840331..cd3591ee 100644 --- a/pages/06.contribute/10.packaging_apps/packaging_apps_intro.fr.md +++ b/pages/06.contribute/10.packaging_apps/packaging_apps_intro.fr.md @@ -13,7 +13,6 @@ Cette documentation a pour but de fournir tous les concepts de base et le vocabu Nous détaillerons ce qu'est un paquet d'applications YunoHost, comment il fonctionne, comment créer votre propre paquet et comment trouver de l'aide si vous en avez besoin. - ## 1. La Philosophie du Packaging La possibilité d'installer facilement des applications à partir d'un catalogue est une caractéristique clé de YunoHost. Alors que vous vous plongez dans le processus de packaging d'applications de YunoHost, vous devez vous souvenir de ces principes clés : @@ -26,7 +25,6 @@ La possibilité d'installer facilement des applications à partir d'un catalogue - Le packaging d'une application YunoHost **ne se limite pas à l'installation** des sources et des dépendances : il concerne également la maintenance (mise à jour, sauvegarde...) et l'intégration de l'application dans l'écosystème YunoHost (NGINX, SSO/LDAP, Fail2Ban, catalogue d'applications, UI/UX...). - ## 2. Prérequis Avant d'entrer dans le vif du sujet, cette documentation part du principe que : @@ -56,30 +54,30 @@ Néanmoins, même si les aides existaient, la structure inhérente des applicati Cependant, [**un futur format v3** est encore à venir](https://github.com/YunoHost/issues/issues/2136) pour simplifier davantage l'empaquetage des applications (comme la prise en charge des configurations NGINX/systemd/..., l'élimination du besoin d'écrire manuellement des scripts de suppression/sauvegarde/restauration, etc.) - ## 4. Aperçu général de la structure d'une application YunoHost Une application YunoHost est construite dans un dépôt Git. Nous vous encourageons à jeter un coup d'oeil à ces dépôts de code pour vous familiariser avec les structures des dépôts d'applications : -- [l'application `helloworld_ynh`](https://github.com/YunoHost-Apps/helloworld_ynh) + +- [l'application `helloworld_ynh`](https://github.com/YunoHost-Apps/helloworld_ynh) - [l'application `example_ynh`](https://github.com/YunoHost/example_ynh) qui contient toutes les fonctionnalités générales et le formattage recommandé - votre application "réelle" préférée dans la liste des dépots [YunoHost-Apps](https://github.com/orgs/YunoHost-Apps/repositories) Parmi les fichiers contenus dans un paquet, les plus importants sont les suivants : - le **manifeste de l'application** `manifest.toml` (ou `.json` dans le passé) - - Il peut être considéré comme la carte d'identité de l'application, contenant diverses métadonnées. - - Il contient également les questions posées lors de l'installation de l'application. - - ainsi qu'un ensemble de "ressource" à initialiser, telles que les sources de l'app à télécharger ou les dépendances apt à installer + - Il peut être considéré comme la carte d'identité de l'application, contenant diverses métadonnées. + - Il contient également les questions posées lors de l'installation de l'application. + - ainsi qu'un ensemble de "ressource" à initialiser, telles que les sources de l'app à télécharger ou les dépendances apt à installer - **scripts/** contient un ensemble de scripts bash correspondant aux actions exposées dans YunoHost - - `_common.sh`: common variables or custom functions included in other scripts - - `install`/`remove` : la procédure d'installation et de suppression - - `upgrade` : la procédure de mise à niveau - - `backup`/`restore` : les procédures de sauvegarde/restauration - - (`change_url`) : changer l'endroit où l'application est installée en termes de son url d'accès web + - `_common.sh`: common variables or custom functions included in other scripts + - `install`/`remove` : la procédure d'installation et de suppression + - `upgrade` : la procédure de mise à niveau + - `backup`/`restore` : les procédures de sauvegarde/restauration + - (`change_url`) : changer l'endroit où l'application est installée en termes de son url d'accès web - **conf/** contient un ensemble de modèles de configuration utilisés lors de l'installation de l'application. Voici quelques exemples de fichiers couramment trouvés : - - `nginx.conf` : le modèle de configuration de NGINX (=serveur web) pour cette application - - `systemd.service` : le modèle de configuration du service systemd pour cette application - - `config.json/yaml/???` : le modèle de configuration de l'application + - `nginx.conf` : le modèle de configuration de NGINX (=serveur web) pour cette application + - `systemd.service` : le modèle de configuration du service systemd pour cette application + - `config.json/yaml/???` : le modèle de configuration de l'application Grosso modo, l'installation proprement dite se compose généralement des opérations suivantes (qui peuvent toutefois varier en fonction de la complexité et des technologies utilisées par l'application) - pas nécessairement dans cet ordre exact : @@ -87,24 +85,27 @@ Grosso modo, l'installation proprement dite se compose généralement des opéra 2. YunoHost pose à l'administrateur les questions d'installation définies dans `manifest.toml`. 3. L'administrateur remplit le formulaire et démarre l'installation. 4. YunoHost fournit un ensemble de pré-requis techniques (appelés 'ressources') tels que : - - initialise le magasin de clés/valeurs de l'application `settings.yml` avec les réponses de l'administrateur au formulaire d'installation - - crée un utilisateur UNIX pour cette application - - installe les dépendances apt nécessaires à cette application - - choisit un port pour le reverse-proxying interne - - initialise une base de données SQL vide - - configure les permissions SSOwat - - ... + +- initialise le magasin de clés/valeurs de l'application `settings.yml` avec les réponses de l'administrateur au formulaire d'installation +- crée un utilisateur UNIX pour cette application +- installe les dépendances apt nécessaires à cette application +- choisit un port pour le reverse-proxying interne +- initialise une base de données SQL vide +- configure les permissions SSOwat +- ... + 5. Le script `install` de l'application est exécuté et ses fonctions typiques sont de : - - récupérer et déployer les sources de l'application - - configurer l'application (typiquement les identifiants de la base de données, le port interne du reverse-proxy...) - - ajouter la configuration de NGINX - - ajoute la configuration systemd du daemon de l'application - - démarre le daemon de l'application - - divers réglages de finalisation + +- récupérer et déployer les sources de l'application +- configurer l'application (typiquement les identifiants de la base de données, le port interne du reverse-proxy...) +- ajouter la configuration de NGINX +- ajoute la configuration systemd du daemon de l'application +- démarre le daemon de l'application +- divers réglages de finalisation + 6. ??? 7. L'application est prête à l'emploi ! - ## 5. Créer votre tout premier paquet YunoHost A moins que vous ne souhaitiez vraiment partir de zéro ou de [`example_ynh`](https://github.com/YunoHost/example_ynh), une pratique courante consiste à identifier une application similaire à celle que vous essayez d'empaqueter - typiquement parce qu'elle repose sur les mêmes technologies - à cloner le dépôt de code correspondant, et à adapter les différents fichiers. diff --git a/pages/06.contribute/10.packaging_apps/packaging_apps_intro.md b/pages/06.contribute/10.packaging_apps/packaging_apps_intro.md index 59df3dc4..4175018e 100644 --- a/pages/06.contribute/10.packaging_apps/packaging_apps_intro.md +++ b/pages/06.contribute/10.packaging_apps/packaging_apps_intro.md @@ -13,7 +13,6 @@ This documentation is here to provide all the basic concepts and vocabulary need We will detail what a YunoHost application package is, how it works, how to make your own package and how to find help if you need it. - ## 1. Packaging philosophy The ability to easily install applications from a catalog is a key feature of YunoHost. While you dive in the process of YunoHost application packaging, you should remember these key principles: @@ -26,7 +25,6 @@ The ability to easily install applications from a catalog is a key feature of Yu - YunoHost app packaging is **not just about installing** sources and dependencies: it's also about maintenance (upgrade, backup...) and integrating the app in the YunoHost ecosystem (NGINX, SSO/LDAP, Fail2Ban, application catalog, UI/UX...) - ## 2. Prerequisites Before diving in, this documentation assumes that: @@ -56,30 +54,30 @@ Nevertheless, even though helpers existed, the inherent structure of apps was ha However, [**a future v3 format** has yet to come](https://github.com/YunoHost/issues/issues/2136) to further simplify app packaging (such as taking care of NGINX/systemd/... configurations, removing the need to manually write remove/backup/restore scripts, etc.) - ## 4. General overview of a YunoHost app structure A YunoHost app consists in a Git repository. We encourage you to have a look at those code repository to get familiar witch app repository structures: + - [the `helloworld_ynh` app](https://github.com/YunoHost-Apps/helloworld_ynh) - [the `example_ynh` app](https://github.com/YunoHost/example_ynh) which illustrates all common features and recommended formatting - your favourite "real-life" app in the [YunoHost-Apps organization](https://github.com/orgs/YunoHost-Apps/repositories) -Among the file contained in a package, the most important ones are: +Among the file contained in a package, the most important ones are: - the **app manifest** `manifest.toml` (or `.json` in the past) - - this can be seen as the ID card of the application, containing various metadatas. - - it also contains the questions asked during the installation of the app. - - and a bunch of "resources" to initialize, such as sources to download or apt dependencies to install + - this can be seen as the ID card of the application, containing various metadatas. + - it also contains the questions asked during the installation of the app. + - and a bunch of "resources" to initialize, such as sources to download or apt dependencies to install - **scripts/** contains a bunch of bash scripts corresponding to actions exposed in YunoHost - - `_common.sh`: common variables or custom functions included in other scripts - - `install`/`remove`: the install and remove procedure - - `upgrade`: the upgrade procedure - - `backup`/`restore`: the backup/restore procedures - - (`change_url`): changing where the app is installed in terms of web access url + - `_common.sh`: common variables or custom functions included in other scripts + - `install`/`remove`: the install and remove procedure + - `upgrade`: the upgrade procedure + - `backup`/`restore`: the backup/restore procedures + - (`change_url`): changing where the app is installed in terms of web access url - **conf/** contains a bunch of configuration templates used when installing the app. Here are some example of commonly found files: - - `nginx.conf`: the NGINX (=web server) configuration template for this app - - `systemd.service`: the systemd service configuration template for this app - - `config.json/yaml/???`: the app's configuration template + - `nginx.conf`: the NGINX (=web server) configuration template for this app + - `systemd.service`: the systemd service configuration template for this app + - `config.json/yaml/???`: the app's configuration template Roughly speaking, the install itself generally consists of the following operations (though these may vary depending on the complexity and technologies used by the app) - not necessarily in that exact order: @@ -87,27 +85,30 @@ Roughly speaking, the install itself generally consists of the following operati 2. YunoHost asks to the admin the install questions defined in `manifest.toml` 3. The admin fills the form and starts the install 4. YunoHost provisions a bunch of technical prerequisites (called 'resources') such as: - - initializes the app'skey/value store `settings.yml` with the admin's answers to the install form - - creates a UNIX system user for this app - - install apt dependencies needed for this app - - picks up a port for internal reverse-proxying - - initializes an empty SQL database - - configures SSOwat permissions - - ... + +- initializes the app'skey/value store `settings.yml` with the admin's answers to the install form +- creates a UNIX system user for this app +- install apt dependencies needed for this app +- picks up a port for internal reverse-proxying +- initializes an empty SQL database +- configures SSOwat permissions +- ... + 5. The actual app's `install` script is ran and typically does: - - fetch and deploy the app sources - - configure the app (typically DB credentials, internal reverse-proxy port...) - - add the NGINX configuration - - add the systemd configuration the app's daemon - - starts the app daemon - - various finialization tweaks + +- fetch and deploy the app sources +- configure the app (typically DB credentials, internal reverse-proxy port...) +- add the NGINX configuration +- add the systemd configuration the app's daemon +- starts the app daemon +- various finialization tweaks + 6. ??? 7. Application is ready to use! - ## 5. Creating your very first YunoHost package -Unless you really want to start from scratch or from [`example_ynh`](https://github.com/YunoHost/example_ynh), one common practice is to identify an app similar to the one you're trying to package - typically because it relies on the same technologies - clone the corresponding code repository, and adapt the various files. +Unless you really want to start from scratch or from [`example_ynh`](https://github.com/YunoHost/example_ynh), one common practice is to identify an app similar to the one you're trying to package - typically because it relies on the same technologies - clone the corresponding code repository, and adapt the various files. TODO/FIXME : here we should list a bunch of well-knowh apps for classic technologies diff --git a/pages/06.contribute/15.dev/02.maindomain/maindomain.md b/pages/06.contribute/15.dev/02.maindomain/maindomain.md index 9f06c209..a9ffe8d3 100644 --- a/pages/06.contribute/15.dev/02.maindomain/maindomain.md +++ b/pages/06.contribute/15.dev/02.maindomain/maindomain.md @@ -8,15 +8,16 @@ routes: --- Here is a list of situations in which we use the main domain concept: + - to expose the web portal: currently the web portal is only reachable through the main domain address (could be changed for multi tenant support in future) - to define the hostname of the machine: we believe we do this to avoid some sudo errors (may be it's not relvant anymore or could be made in /etc/hosts) - to TLS encrypt SMTP and dovecot: so user should define the main domain in their email client to avoid TLS warning -- To be able to do mail forwarding using the main domain as Sender Rewriting Scheme Domain see: https://en.wikipedia.org/wiki/Sender_Rewriting_Scheme +- To be able to do mail forwarding using the main domain as Sender Rewriting Scheme Domain see: - to define default email as (root@ abuse@) but we probably should do it on all parent domain instead -- to define `myhostname` in postfix config, used as EHLO and reverseDNS (refering to https://mxtoolbox.com/emailhealth test it should be a FQDN, so a subdomain) +- to define `myhostname` in postfix config, used as EHLO and reverseDNS (refering to test it should be a FQDN, so a subdomain) - to generate the self-signed Local Authority: having just one allow to upload it in a browser and get an x509 authenticated https connexion. - to define default xmpp DNS field: dns field are only set on the main domain by default -Finally we can imagine some apps use the main domain too, see -https://github.com/search?q=org%3AYunoHost-Apps+main_domain&type=code -https://github.com/search?q=org%3AYunoHost-Apps+current_host&type=code +Finally we can imagine some apps use the main domain too, see + + diff --git a/pages/06.contribute/15.dev/03.forms/forms.md b/pages/06.contribute/15.dev/03.forms/forms.md index b7cdd191..b2df7d0f 100644 --- a/pages/06.contribute/15.dev/03.forms/forms.md +++ b/pages/06.contribute/15.dev/03.forms/forms.md @@ -12,6 +12,7 @@ routes: YunoHost uses a lot of forms. You can found here information on supported types question and properties. ## Questions + !!! Questions are called `Options` in the code. ### Generic properties @@ -19,7 +20,7 @@ YunoHost uses a lot of forms. You can found here information on supported types | Property | Scope | Description | Example | |----------|--------------|-------------|---------| | `type` | Everywhere | Specify the type of the question (see bellow for the list) | `type = "string"` | -| `ask` | Everywhere | The title of the question | `ask.en = "Cats or dogs ?"` | +| `ask` | Everywhere | The title of the question | `ask.en = "Cats or dogs ?"` | | `help` | Everywhere | An help message | `help.en = "Think carefully!"` | | `optional`| Everywhere | Set true if the question is not mandatory | `optional = true` | | `readonly`| Everywhere | Avoid user to be able to change the value | `readonly = true` | @@ -31,18 +32,20 @@ YunoHost uses a lot of forms. You can found here information on supported types | `visible` | ConfigPanel | A simple js expression based on other short keys questions to hide or display dynamically the question| `visible = "login && ! private_key"` | | `bind` | AppConfigPanel | See [App configuration panel doc](/packaging_config_panels) | `bind = "__INSTALL_DIR__/config.yml"` | - * `help`, `optional`, `readonly` and `visible` are also available on panels and sections entities. - * Long help messages could not to be correctly displayed for user using yunohost CLI - * For the moment `default` properties are not supported in app config panel and you have to initialize the value by yourself in config file or settings. - +- `help`, `optional`, `readonly` and `visible` are also available on panels and sections entities. +- Long help messages could not to be correctly displayed for user using YunoHost CLI +- For the moment `default` properties are not supported in app config panel and you have to initialize the value by yourself in config file or settings. ### `display_text` (readonly) + Display a simple text. ### `markdown` (readonly) + Display a markdown (if you don't use markdown features, prefer display_text) ### `alert` (readonly) + Display an alert box with different style. | Property | Description | Default | @@ -50,6 +53,7 @@ Display an alert box with different style. | `style` | Style of the alert box (success, info, warning, danger) | info | ### `button` + Display a button with different style (useful for custom actions). | Property | Description | Default | @@ -58,9 +62,11 @@ Display a button with different style (useful for custom actions). | `enabled` | Enable or disable the button | True | ### `string` + Input text monoline. ### `text` + Input text multilines | Property | Description | Default | @@ -68,12 +74,15 @@ Input text multilines | `redact` | Style of the alert box (success, info, warning, danger) | success| ### `password` + Password input. `{}` chars are forbidden and value is not added to logs. ### `color` + Hexadecimal color starting with # with a color picker. ### `number` + An integer. | Property | Description | Example | @@ -83,6 +92,7 @@ An integer. | `step` | Steps between each next possible value | | ### `range` + | Property | Description | Example | |----------|--------------|---------| | `min` | Minimal value | | @@ -90,25 +100,32 @@ An integer. | `step` | Steps between each next possible value | | ### `boolean` + | Property | Description | Example | |----------|--------------|---------| | `yes` | | | | `no` | | | ### `date` + A date picker with date in the format YYYY-MM-DD ### `time` + A time picker ### `email` + An email input ### `path` + ### `url` + By default it ask for a web URL but you can change the `pattern` if you want to. ### `file` + File question | Property | Description | Example | @@ -118,6 +135,7 @@ File question ! This file type is not made for big files transfer, it's just for small logo, or config files. ### `select` + Dropdown | Property | Description | Example | @@ -125,6 +143,7 @@ Dropdown | `choices` | list or dictionary of choices | | ### `tags` + Multi choices selection. | Property | Description | Example | @@ -132,13 +151,17 @@ Multi choices selection. | `choices` | List or dictionary of choices | | ### `domain` + List all added domains ### `app` + List all installed apps ### `user` + List all users ### `group` + List all groups diff --git a/pages/06.contribute/15.dev/dev.fr.md b/pages/06.contribute/15.dev/dev.fr.md index 66a674a9..4b040135 100644 --- a/pages/06.contribute/15.dev/dev.fr.md +++ b/pages/06.contribute/15.dev/dev.fr.md @@ -19,13 +19,13 @@ Si vous cherchez quelque chose à implémenter ou un bug à réparer, le bug tra - **Implémentez et testez votre fonctionnalité**. Suivant ce sur quoi vous voulez travailler : - - **Cœur Python/ligne de commande** : allez dans `/ynh-dev/yunohost/` - - **Webadmin** : allez dans `/ynh-dev/yunohost-admin/` - - Vous pouvez aussi travailler sur les autres projets liés sur lesquels s'appuie YunoHost (SSOwat, Moulinette) de façon similaire. + - **Cœur Python/ligne de commande** : allez dans `/ynh-dev/yunohost/` + - **Webadmin** : allez dans `/ynh-dev/yunohost-admin/` + - Vous pouvez aussi travailler sur les autres projets liés sur lesquels s'appuie YunoHost (SSOwat, Moulinette) de façon similaire. ### Vue d'ensemble des 4 morceaux principaux de YunoHost -##### Moulinette +#### Moulinette C'est un petit framework "fait maison". [Son rôle principal](https://moulinette.readthedocs.io/en/latest/actionsmap.html) est de permettre de construire une API Web et une API en ligne de commande à partir d'un même code Python et d'un schéma YAML que nous appelons [l'actionmap](https://github.com/YunoHost/yunohost/blob/dev/share/actionsmap.yml). @@ -33,28 +33,31 @@ Il prend en charge d'autres mécanismes tels que l'authentification, l'internati Moulinette dispose de sa propre documentation [ici](https://moulinette.readthedocs.io/en/latest/). -##### YunoHost +#### YunoHost C'est le cœur même de YunoHost. Il contient : + - [le code Python](https://github.com/YunoHost/yunohost/tree/dev/src) qui gère les utilisateurs, domaines, applications, services et autres - des [helpers bash](https://github.com/YunoHost/yunohost/tree/dev/helpers) principalement utilisés par les packageurs d'applications dans les scripts de ces applications - des [hooks](https://github.com/YunoHost/yunohost/tree/dev/hooks) et [templates](https://github.com/YunoHost/yunohost/tree/dev/conf) qui sont utilisés pour configurer les différents éléments de l'écosystème tels que NGINX, Postfix... - des [chaînes internationalisées](https://github.com/YunoHost/yunohost/tree/dev/locales) - des [tests](https://github.com/YunoHost/yunohost/tree/dev/tests) -##### SSOwat +#### SSOwat C'est le système de connexion unique (single sign-on) de YunoHost. Il contient principalement : + - [du code LUA](https://github.com/YunoHost/ssowat) interfacé directement avec NGINX et qui gère tous les aspects "techniques" de l'authentification et de la gestion des accès aux ressources. - le [portail web utilisateur](https://github.com/YunoHost/SSOwat/tree/dev/portal) qui est l'interface finale visible par les utilisateurs de YunoHost. SSOwat est configuré via `/etc/ssowat/conf.json` qui est généré par YunoHost. -##### YunoHost-admin +#### YunoHost-admin C'est une dépendance *optionnelle* de YunoHost et correspond à une interface pour l'API web créée par YunoHost et Moulinette (service `yunohost-api`). Il contient essentiellement : + - [des templates pour les vues](https://github.com/YunoHost/yunohost-admin/tree/dev/app/src/views) - les [contrôleurs JavaScript](https://github.com/YunoHost/yunohost-admin/tree/dev/src/js/yunohost/controllers) correspondants, qui interagissent avec l'API YunoHost - et ses [chaînes internationalisées](https://github.com/YunoHost/yunohost-admin/tree/dev/app/src/i18n/locales) @@ -69,7 +72,7 @@ Il contient essentiellement : - Moulinette va automatiquement faire le lien entre les commandes de l'actionsmap et les fonctions Python (ainsi que leurs arguments) dans `src/yunohost/`. Par exemple, `yunohost domain add some.domain.tld` déclenchera un appel de `domain_add(domainName)` dans `domain.py`, avec l'argument `domainName` qui vaudra `"some.domain.tld"`. -##### Helpers / style de code +#### Helpers / style de code - Pour gérer les exceptions, il existe un type `YunohostError()` @@ -94,14 +97,13 @@ Il contient essentiellement : - Pour l'internationalisation des messages, utilisez `y18n.t('some-string-code')` dans le JavaScript, ou `{{t 'some-string-code'}}` dans le template HTML, et mettez votre message dans `locales/en.json`. Ne modifiez pas de fichiers de locales autres que `en.json`, la traduction sera faite avec [Weblate](https://translate.yunohost.org/) ! -##### N'oubliez pas +#### N'oubliez pas - À chaque modification de l'actionsmap, il faut redémarrer l'API YunoHost : `service yunohost-api restart` (Il faudra retaper le mot de passe administrateur dans l'interface web) - Il faudra peut-être régulièrement forcer le rafraîchissement du cache navigateur pour propager correctement le JavaScript et/ou HTML (à chaque fois que l'on change quelque chose dans `js` ou `views`, donc). - -### Votre fonctionnalité est prête et vous souhaitez qu'elle soit intégrée dans YunoHost +### Votre fonctionnalité est prête et vous souhaitez qu'elle soit intégrée dans YunoHost - Forkez le dépôt correspondant sur GitHub, et commitez vos changements dans une nouvelle branche. Il est recommandé de nommer la branche avec la convention suivante : - Pour une nouvelle fonctionnalité ou amélioration : `enh-ISSUENUMBER-description-fonctionnalité` diff --git a/pages/06.contribute/15.dev/dev.md b/pages/06.contribute/15.dev/dev.md index b3d26255..db395ad2 100644 --- a/pages/06.contribute/15.dev/dev.md +++ b/pages/06.contribute/15.dev/dev.md @@ -9,9 +9,9 @@ routes: You wish to add a new feature in the YunoHost core, but don't know how to proceed? This guide takes you through the various steps of the development and -contribution process. +contribution process. -If you're looking for stuff to implement or fix, the bug-tracker is +If you're looking for stuff to implement or fix, the bug-tracker is [here](https://github.com/YunoHost/issues/issues)! **Come say hi to us in the [dev chat room](/chat_rooms)**! @@ -26,18 +26,18 @@ If you're looking for stuff to implement or fix, the bug-tracker is - **Implement and test your feature**. Depending on what you want to develop, you will want to: - - **Python/CLI core**: work in `/ynh-dev/yunohost/` - - **Web administration interface**: work in `/ynh-dev/yunohost-admin/` - - You can also work on the other projects on which YunoHost is built + - **Python/CLI core**: work in `/ynh-dev/yunohost/` + - **Web administration interface**: work in `/ynh-dev/yunohost-admin/` + - You can also work on the other projects on which YunoHost is built (SSOwat, Moulinette) in similar ways ### Overview of the 4 main pieces of YunoHost #### Moulinette -It is a small "homemade" framework. [Its major role](https://moulinette.readthedocs.io/en/latest/actionsmap.html) -is to allow us to build both a web API and a command-line API from the same -Python code thanks to a YAML schema which we call +It is a small "homemade" framework. [Its major role](https://moulinette.readthedocs.io/en/latest/actionsmap.html) +is to allow us to build both a web API and a command-line API from the same +Python code thanks to a YAML schema which we call [the actionmap](https://github.com/YunoHost/yunohost/blob/dev/share/actionsmap.yml). It handles other mechanisms like authentication, internationalization and @@ -48,6 +48,7 @@ Moulinette has its own documentation available [here](https://moulinette.readthe #### YunoHost This piece is the very core of YunoHost. It contains: + - [the Python code](https://github.com/YunoHost/yunohost/tree/dev/src) that manages users, domains, apps, services and other things - [bash helpers](https://github.com/YunoHost/yunohost/tree/dev/helpers) mainly used by application packagers to package applications - [hooks](https://github.com/YunoHost/yunohost/tree/dev/hooks) and [templates](https://github.com/YunoHost/yunohost/tree/dev/conf) that are used to configure the various pieces of the ecosystem such as NGINX, Postfix... @@ -57,6 +58,7 @@ This piece is the very core of YunoHost. It contains: #### SSOwat This is the single sign-on system of YunoHost. It both contains: + - [Lua scripts](https://github.com/YunoHost/ssowat) that are directly interfaced with NGINX and handle all the "technical" aspects of authentication and route accesses - the web [user portal](https://github.com/YunoHost/SSOwat/tree/dev/portal) which is the interface used by YunoHost's end users to log in and browse installed apps @@ -67,6 +69,7 @@ SSOwat is configured through `/etc/ssowat/conf.json` which is generated by YunoH It is an *optional* dependency of YunoHost and corresponds to an interface for the web API created by YunoHost and Moulinette (c.f. the `yunohost-api` service). It essentially contains: + - [view templates](https://github.com/YunoHost/yunohost-admin/tree/dev/app/src/views) - corresponding [JavaScript controllers](https://github.com/YunoHost/yunohost-admin/tree/dev/src/js/yunohost/controllers) that interact with the YunoHost API - and [internationalized strings](https://github.com/YunoHost/yunohost-admin/tree/dev/app/src/i18n/locales) @@ -78,7 +81,7 @@ It essentially contains: - Run `cd /ynh_dev/ && ./ynh-dev use-git yunohost`. - The actionsmap file (`data/actionsmap/yunohost.yml`) defines the various - categories, actions and arguments of the yunohost CLI. Define how you want + categories, actions and arguments of the YunoHost CLI. Define how you want users to use your feature, and add/edit the corresponding categories, actions and arguments. For example in `yunohost domain add some.domain.tld`, the category is `domain`, the action is `add`, and `some.domain.tld` is an @@ -90,7 +93,7 @@ It essentially contains: `domain_add(domainName)` in `domain.py`, with the argument `domainName` equal to `"some.domain.tld"`. -##### Helpers / coding style +#### Helpers / coding style - To handle exceptions, you should raise some `YunohostError()` @@ -108,8 +111,8 @@ It essentially contains: - Work in `/ynh-dev/yunohost-admin/src/`. -- Run `cd /ynh-dev && ./ynh-dev use-git yunohost-admin`. It launches gulp, such as each - time you modify sources, it recompiles the code and you can use it by +- Run `cd /ynh-dev && ./ynh-dev use-git yunohost-admin`. It launches gulp, such as each + time you modify sources, it recompiles the code and you can use it by refreshing (Ctrl+F5) your web administration. To stop the command, just do Ctrl+C. - The web interface uses the API to interact with YunoHost. The API @@ -138,16 +141,15 @@ It essentially contains: string in `locales/en.json`. Don't edit other locales files, this will be done using [Weblate](https://translate.yunohost.org/)! -##### Don't forget +#### Don't forget - Each time you edit the actionsmap or the Python code, you should restart the YunoHost api: `systemctl restart yunohost-api` (You'll need to retype your admin and password in the web interface) -- You might need to force-clear the cache of your browser sometimes to refresh +- You might need to force-clear the cache of your browser sometimes to refresh the JavaScript and/or HTML (so each time you edit something in `js` or `views`). - ### Your feature is ready and you want it to be integrated in YunoHost - Fork the relevant repo on GitHub, and commit stuff to a new branch. We recommend @@ -156,7 +158,7 @@ It essentially contains: - For a bugfix `fix-ISSUENUMBER-description-of-fix` - `ISSUENUMBER` is optional and is the id of a corresponding ticket on the bug tracker. -- Once you're ready, open a Pull Request (PR) on GitHub. Please include `[fix]` or +- Once you're ready, open a Pull Request (PR) on GitHub. Please include `[fix]` or `[enh]` at the beginning of the title of your PR. - After reviewing, testing and validation by other contributors, your branch diff --git a/pages/06.contribute/contribute.de.md b/pages/06.contribute/contribute.de.md index d26d9ee1..cc808454 100644 --- a/pages/06.contribute/contribute.de.md +++ b/pages/06.contribute/contribute.de.md @@ -23,7 +23,7 @@ YunoHost hängt ausschließlich von der Beteiligung von Leuten wie dir ab. [/center] [center] -Sprich mit Freunden, Verwandten und bei der Arbeit über Softwarefreiheit, [Selbsthosting](/selfhosting) und YunoHost. Wir verlassen uns auf Evangelisten der Datenfreiheit wie dich. <3 +Sprich mit Freunden, Verwandten und bei der Arbeit über Softwarefreiheit, [Selbsthosting](/selfhosting) und YunoHost. Wir verlassen uns auf Evangelisten der Datenfreiheit wie dich. <3 [/center] [/columns] @@ -37,7 +37,7 @@ Sprich mit Freunden, Verwandten und bei der Arbeit über Softwarefreiheit, [Selb [/center] [center] -Unsere Unterstützung basiert auf Mitwirkenden wie dir. Besuche einfach [den Support-Chatroom](/help) und hilf neuen Benutzern beim Einstieg oder suche dir eine Frage im Forum, bei der du helfen kannst.. +Unsere Unterstützung basiert auf Mitwirkenden wie dir. Besuche einfach [den Support-Chatroom](/help) und hilf neuen Benutzern beim Einstieg oder suche dir eine Frage im [Forum](https://forum.yunohost.org), bei der du helfen kannst.. [/center] [/columns] @@ -51,7 +51,7 @@ Unsere Unterstützung basiert auf Mitwirkenden wie dir. Besuche einfach [den Sup [/center] [center] -Verbessere die Dokumentation, indem du [neue Seiten schreibst](/write_documentation) oder vorhandene in deine Sprache übersetzt. +Verbessere die Dokumentation, indem du [neue Seiten schreibst](/write_documentation) oder vorhandene in deine Sprache übersetzt. [/center] [/columns] @@ -66,7 +66,7 @@ Verbessere die Dokumentation, indem du [neue Seiten schreibst](/write_documentat [center] Mach mit, indem du YunoHost-Schnittstellen in deiner Sprache verfügbar machst. -Leg los!! +[Leg los!](https://translate.yunohost.org/)! [/center] [/columns] @@ -81,7 +81,7 @@ Mach mit, indem du YunoHost-Schnittstellen in deiner Sprache verfügbar machst. [center] -Wir brauchen Leute, die YunoHost gründlich testen. Wenn du einen Fehler findest, versuche ihn zu identifizieren und melde ihn in unserem bug tracker. +Wir brauchen Leute, die YunoHost gründlich testen. Wenn du einen Fehler findest, versuche ihn zu identifizieren und melde ihn in unserem [bug tracker](https://github.com/YunoHost/issues/issues). [/center] [/columns] @@ -96,7 +96,7 @@ Wir brauchen Leute, die YunoHost gründlich testen. Wenn du einen Fehler findest [center] Erweitere den Funktionsumfang von YunoHost, indem du neue [Dienste und Webanwendungen in neue Pakete packst](/packaging_apps). -Schaue dir an, [was schon getan wurde](/apps)! +Schaue dir an, [was schon getan wurde](/apps)! [/center] [/columns] @@ -112,15 +112,16 @@ Schaue dir an, [was schon getan wurde](/apps)! [center] Du kannst dich, unabhängig von deinen Fähigkeiten, an der Entwicklung des YunoHost beteiligen. -Sysadmins, Webentwickler, Designer und Pythonisten sind herzlich willkommen! +Sysadmins, Webentwickler, Designer und Pythonisten [sind herzlich willkommen](https://github.com/YunoHost)!
-Erfahre im [Entwickler-Chatroom](xmpp:dev@conference.yunohost.org?join), wie du zum, Projekt [beitragen](/dev) kannst. +Erfahre im [Entwickler-Chatroom](xmpp:dev@conference.yunohost.org?join), wie du zum, Projekt [beitragen](/dev) kannst. [/center] [/columns] - --- [center] + ### Bitte komm auf jeden Fall mit uns in den [Entwickler-Chatroom](/chat_rooms) :-) + [/center] diff --git a/pages/06.contribute/contribute.fr.md b/pages/06.contribute/contribute.fr.md index c34cb505..199ca517 100644 --- a/pages/06.contribute/contribute.fr.md +++ b/pages/06.contribute/contribute.fr.md @@ -14,7 +14,6 @@ routes: YunoHost dépend entièrement de la participation de gens comme vous.

-
[columns] @@ -39,7 +38,7 @@ Parlez de logiciel libre, d’[auto-hébergement](/selfhosting), de YunoHost à [/center] [center] -Notre support est communautaire et s’appuie sur des contributeurices comme vous. Venez simplement sur le [salon d'aide](/help), ou tentez de répondre aux questions du Forum. +Notre support est communautaire et s’appuie sur des contributeurices comme vous. Venez simplement sur le [salon d'aide](/help), ou tentez de répondre aux questions du [Forum](https://forum.yunohost.org/). [/center] [/columns] @@ -67,7 +66,7 @@ Améliorez cette documentation en [proposant de nouvelles pages](/write_document [/center] [center] -Participez en rendant les interfaces de YunoHost disponibles dans votre langue. Lancez-vous ! +Participez en rendant les interfaces de YunoHost disponibles dans votre langue. [Lancez-vous](https://translate.yunohost.org/)! [/center] [/columns] @@ -81,7 +80,7 @@ Participez en rendant les interfaces de YunoHost disponibles dans votre langue. [/center] [center] -Nous avons besoin de tester YunoHost profondément. Si vous trouvez un bug, essayez de l’identifier, puis reportez-le sur notre bug tracker. +Nous avons besoin de tester YunoHost profondément. Si vous trouvez un bug, essayez de l’identifier, puis reportez-le sur notre [bug tracker](https://github.com/YunoHost/issues/issues/new). [/center] [/columns] @@ -109,12 +108,14 @@ Nous avons besoin de tester YunoHost profondément. Si vous trouvez un bug, essa [/center] [center] -Vous pouvez vous impliquer dans le développement de YunoHost peu importe votre niveau. Administrateurs système, développeurs web, designers et pythonistes sont les bienvenus. Découvrez [comment contribuer](/dev), et rejoignez-nous sur le [salon de discussion](xmpp:dev@conference.yunohost.org?join) ! +Vous pouvez vous impliquer dans le développement de YunoHost peu importe votre niveau. Administrateurs système, développeurs web, designers et pythonistes [sont les bienvenus](https://github.com/YunoHost). Découvrez [comment contribuer](/dev), et rejoignez-nous sur le [salon de discussion](xmpp:dev@conference.yunohost.org?join) ! [/center] [/columns] --- [center] + ### Dans tous les cas, venez discuter avec nous sur [le salon de développement](/chat_rooms) :-) + [/center] diff --git a/pages/06.contribute/contribute.md b/pages/06.contribute/contribute.md index 00a70704..c3e8be97 100644 --- a/pages/06.contribute/contribute.md +++ b/pages/06.contribute/contribute.md @@ -37,7 +37,7 @@ Talk about software freedom, [self-hosting](/selfhosting) and YunoHost to your r [/center] [center] -Our support relies on contributors like you. Just come to [the support chatroom](/help) and help new users getting started, or pick a question on the Forum. +Our support relies on contributors like you. Just come to [the support chatroom](/help) and help new users getting started, or pick a question on the [Forum](https://forum.yunohost.org/). [/center] [/columns] @@ -66,7 +66,7 @@ Improve this documentation by [writing new pages](/write_documentation) or trans [center] Get involved by making YunoHost interfaces available in your language -Get started! +[Get started](https://translate.yunohost.org/)! [/center] [/columns] @@ -80,7 +80,7 @@ Get involved by making YunoHost interfaces available in your language [/center] [center] -We need people able to test YunoHost deeply. If you find a bug, try to identify it, and report it on our bug tracker. +We need people able to test YunoHost deeply. If you find a bug, try to identify it, and report it on our [bug tracker](https://github.com/YunoHost/issues/issues). [/center] [/columns] @@ -110,14 +110,15 @@ Have a look of [what has been done yet](/apps)! [center] You can involve in the YunoHost's development regardless of your skill. -Sysadmins, web developers, designers and pythonists are welcome! +Sysadmins, web developers, designers and pythonists [are welcome](https://github.com/YunoHost)! Learn [how to contribute](/dev), and join us on the [development chat room](xmpp:dev@conference.yunohost.org?join). [/center] [/columns] - --- [center] + ### In any case, please come chat with us on [the dev chatroom](/chat_rooms) :-) + [/center]