aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore5
-rw-r--r--.postcss-sorting.json243
-rw-r--r--.stylelintrc397
-rw-r--r--.travis.yml6
-rw-r--r--build/build.xml6
-rw-r--r--gulpfile.js69
-rw-r--r--package-lock.json11019
-rw-r--r--package.json65
-rw-r--r--phpBB/adm/style/acp_ext_catalog.html130
-rw-r--r--phpBB/adm/style/acp_ext_list.html2
-rw-r--r--phpBB/adm/style/acp_storage.html97
-rw-r--r--phpBB/adm/style/admin.css1673
-rw-r--r--phpBB/adm/style/detailed_message_body.html14
-rw-r--r--phpBB/adm/style/overall_footer.html9
-rw-r--r--phpBB/assets/javascript/core.js6
-rwxr-xr-xphpBB/bin/phpbbcli.php5
-rw-r--r--phpBB/common.php15
-rw-r--r--phpBB/composer-ext.json0
-rw-r--r--phpBB/composer-ext.lock0
-rw-r--r--phpBB/composer.json2
-rw-r--r--phpBB/composer.lock641
-rw-r--r--phpBB/config/default/container/services.yml18
-rw-r--r--phpBB/config/default/container/services_attachment.yml6
-rw-r--r--phpBB/config/default/container/services_avatar.yml4
-rw-r--r--phpBB/config/default/container/services_console.yml45
-rw-r--r--phpBB/config/default/container/services_content.yml2
-rw-r--r--phpBB/config/default/container/services_db.yml10
-rw-r--r--phpBB/config/default/container/services_extensions.yml47
-rw-r--r--phpBB/config/default/container/services_files.yml33
-rw-r--r--phpBB/config/default/container/services_filesystem.yml9
-rw-r--r--phpBB/config/default/container/services_hook.yml7
-rw-r--r--phpBB/config/default/container/services_migrator.yml1
-rw-r--r--phpBB/config/default/container/services_routing.yml1
-rw-r--r--phpBB/config/default/container/services_storage.yml84
-rw-r--r--phpBB/config/default/container/services_twig.yml3
-rw-r--r--phpBB/config/default/container/services_twig_extensions.yml9
-rw-r--r--phpBB/config/default/container/tables.yml2
-rw-r--r--phpBB/config/development/config.yml4
-rw-r--r--phpBB/config/installer/container/services.yml2
-rw-r--r--phpBB/config/installer/container/services_install_database.yml1
-rw-r--r--phpBB/develop/adjust_avatars.php23
-rw-r--r--phpBB/develop/create_schema_files.php12
-rw-r--r--phpBB/docs/coding-guidelines.html1
-rw-r--r--phpBB/docs/lighttpd.sample.conf27
-rw-r--r--phpBB/docs/nginx.sample.conf8
-rw-r--r--phpBB/download/file.php51
-rw-r--r--phpBB/includes/acp/acp_attachments.php9
-rw-r--r--phpBB/includes/acp/acp_database.php224
-rw-r--r--phpBB/includes/acp/acp_extensions.php453
-rw-r--r--phpBB/includes/acp/acp_main.php24
-rw-r--r--phpBB/includes/acp/acp_storage.php339
-rw-r--r--phpBB/includes/acp/info/acp_extensions.php1
-rw-r--r--phpBB/includes/acp/info/acp_storage.php34
-rw-r--r--phpBB/includes/bbcode.php4
-rw-r--r--phpBB/includes/constants.php9
-rw-r--r--phpBB/includes/functions.php92
-rw-r--r--phpBB/includes/functions_acp.php7
-rw-r--r--phpBB/includes/functions_compatibility.php45
-rw-r--r--phpBB/includes/functions_content.php18
-rw-r--r--phpBB/includes/functions_convert.php2
-rw-r--r--phpBB/includes/functions_download.php148
-rw-r--r--phpBB/includes/functions_messenger.php4
-rw-r--r--phpBB/includes/functions_posting.php4
-rw-r--r--phpBB/includes/functions_privmsgs.php4
-rw-r--r--phpBB/includes/functions_user.php26
-rw-r--r--phpBB/includes/hooks/index.php250
-rw-r--r--phpBB/includes/ucp/ucp_groups.php4
-rw-r--r--phpBB/install/convert/convertor.php2
-rw-r--r--phpBB/install/convertors/convert_phpbb20.php3
-rwxr-xr-xphpBB/install/phpbbcli.php2
-rw-r--r--phpBB/install/schemas/schema_data.sql30
-rw-r--r--phpBB/language/en/acp/common.php19
-rw-r--r--phpBB/language/en/acp/database.php2
-rw-r--r--phpBB/language/en/acp/extensions.php50
-rw-r--r--phpBB/language/en/acp/permissions_phpbb.php1
-rw-r--r--phpBB/language/en/acp/storage.php71
-rw-r--r--phpBB/language/en/cli.php12
-rw-r--r--phpBB/language/en/common.php16
-rw-r--r--phpBB/language/en/install.php2
-rw-r--r--phpBB/phpbb/attachment/delete.php34
-rw-r--r--phpBB/phpbb/attachment/upload.php82
-rw-r--r--phpBB/phpbb/avatar/driver/gravatar.php2
-rw-r--r--phpBB/phpbb/avatar/driver/upload.php66
-rw-r--r--phpBB/phpbb/cache/service.php1
-rw-r--r--phpBB/phpbb/composer/exception/managed_with_clean_error_exception_exception.php35
-rw-r--r--phpBB/phpbb/composer/exception/managed_with_enable_error_exception.php35
-rw-r--r--phpBB/phpbb/composer/exception/managed_with_error_exception.php35
-rw-r--r--phpBB/phpbb/composer/exception/runtime_exception.php37
-rw-r--r--phpBB/phpbb/composer/extension_manager.php316
-rw-r--r--phpBB/phpbb/composer/installer.php716
-rw-r--r--phpBB/phpbb/composer/io/console_io.php40
-rw-r--r--phpBB/phpbb/composer/io/html_output_formatter.php86
-rw-r--r--phpBB/phpbb/composer/io/io_interface.php26
-rw-r--r--phpBB/phpbb/composer/io/null_io.php27
-rw-r--r--phpBB/phpbb/composer/io/translate_composer_trait.php245
-rw-r--r--phpBB/phpbb/composer/io/web_io.php37
-rw-r--r--phpBB/phpbb/composer/manager.php332
-rw-r--r--phpBB/phpbb/composer/manager_interface.php110
-rw-r--r--phpBB/phpbb/console/command/extension/install.php103
-rw-r--r--phpBB/phpbb/console/command/extension/list_available.php73
-rw-r--r--phpBB/phpbb/console/command/extension/manage.php99
-rw-r--r--phpBB/phpbb/console/command/extension/remove.php103
-rw-r--r--phpBB/phpbb/console/command/extension/update.php90
-rw-r--r--phpBB/phpbb/db/extractor/base_extractor.php14
-rw-r--r--phpBB/phpbb/db/migration/data/v400/acp_storage_module.php55
-rw-r--r--phpBB/phpbb/db/migration/data/v400/add_storage_permission.php49
-rw-r--r--phpBB/phpbb/db/migration/data/v400/dev.php36
-rw-r--r--phpBB/phpbb/db/migration/data/v400/extensions_composer.php53
-rw-r--r--phpBB/phpbb/db/migration/data/v400/extensions_composer_2.php40
-rw-r--r--phpBB/phpbb/db/migration/data/v400/remove_attachment_download_mode.php53
-rw-r--r--phpBB/phpbb/db/migration/data/v400/storage_adapter_local_subfolders.php54
-rw-r--r--phpBB/phpbb/db/migration/data/v400/storage_attachment.php41
-rw-r--r--phpBB/phpbb/db/migration/data/v400/storage_avatar.php41
-rw-r--r--phpBB/phpbb/db/migration/data/v400/storage_backup.php55
-rw-r--r--phpBB/phpbb/db/migration/data/v400/storage_track.php168
-rw-r--r--phpBB/phpbb/db/migration/migration.php7
-rw-r--r--phpBB/phpbb/db/migration/schema_generator.php20
-rw-r--r--phpBB/phpbb/db/migrator.php35
-rw-r--r--phpBB/phpbb/di/container_builder.php11
-rw-r--r--phpBB/phpbb/di/extension/container_configuration.php7
-rw-r--r--phpBB/phpbb/di/extension/core.php17
-rw-r--r--phpBB/phpbb/extension/di/extension_base.php4
-rw-r--r--phpBB/phpbb/extension/manager.php6
-rw-r--r--phpBB/phpbb/files/filespec_storage.php519
-rw-r--r--phpBB/phpbb/files/types/form.php9
-rw-r--r--phpBB/phpbb/files/types/form_storage.php128
-rw-r--r--phpBB/phpbb/files/types/local.php9
-rw-r--r--phpBB/phpbb/files/types/local_storage.php136
-rw-r--r--phpBB/phpbb/files/types/remote.php18
-rw-r--r--phpBB/phpbb/files/types/remote_storage.php204
-rw-r--r--phpBB/phpbb/filesystem/exception/filesystem_exception.php8
-rw-r--r--phpBB/phpbb/filesystem/filesystem.php211
-rw-r--r--phpBB/phpbb/filesystem/filesystem_interface.php8
-rw-r--r--phpBB/phpbb/filesystem/helper.php385
-rw-r--r--phpBB/phpbb/filesystem/temp.php54
-rw-r--r--phpBB/phpbb/finder.php9
-rw-r--r--phpBB/phpbb/hook/finder.php91
-rw-r--r--phpBB/phpbb/install/helper/database.php3
-rw-r--r--phpBB/phpbb/install/module/install_database/task/create_schema.php56
-rw-r--r--phpBB/phpbb/install/module/install_database/task/create_schema_file.php12
-rw-r--r--phpBB/phpbb/path_helper.php19
-rw-r--r--phpBB/phpbb/permissions.php1
-rw-r--r--phpBB/phpbb/routing/file_locator.php6
-rw-r--r--phpBB/phpbb/routing/helper.php12
-rw-r--r--phpBB/phpbb/session.php10
-rw-r--r--phpBB/phpbb/storage/adapter/adapter_interface.php103
-rw-r--r--phpBB/phpbb/storage/adapter/local.php440
-rw-r--r--phpBB/phpbb/storage/adapter_factory.php93
-rw-r--r--phpBB/phpbb/storage/exception/exception.php44
-rw-r--r--phpBB/phpbb/storage/file_info.php85
-rw-r--r--phpBB/phpbb/storage/provider/local.php58
-rw-r--r--phpBB/phpbb/storage/provider/provider_interface.php45
-rw-r--r--phpBB/phpbb/storage/storage.php495
-rw-r--r--phpBB/phpbb/storage/stream_interface.php39
-rw-r--r--phpBB/phpbb/template/asset.php13
-rw-r--r--phpBB/phpbb/template/base.php22
-rw-r--r--phpBB/phpbb/template/twig/extension/icon.php321
-rw-r--r--phpBB/phpbb/template/twig/loader.php18
-rw-r--r--phpBB/phpbb/template/twig/node/includeasset.php2
-rw-r--r--phpBB/phpbb/template/twig/twig.php6
-rw-r--r--phpBB/phpbb/user.php4
-rw-r--r--phpBB/phpbb/viewonline_helper.php12
-rw-r--r--phpBB/styles/all/imgs/svg/404.svg7
-rw-r--r--phpBB/styles/all/template/macros/icons/font.twig4
-rw-r--r--phpBB/styles/all/template/macros/icons/iconify.twig4
-rw-r--r--phpBB/styles/all/template/macros/icons/png.twig3
-rw-r--r--phpBB/styles/all/template/macros/icons/svg.twig9
-rw-r--r--phpBB/styles/prosilver/style.cfg4
-rw-r--r--phpBB/styles/prosilver/template/ajax.js10
-rw-r--r--phpBB/styles/prosilver/template/captcha_default.html2
-rw-r--r--phpBB/styles/prosilver/template/confirm_body.html8
-rw-r--r--phpBB/styles/prosilver/template/confirm_delete_body.html8
-rw-r--r--phpBB/styles/prosilver/template/display_options.html4
-rw-r--r--phpBB/styles/prosilver/template/forumlist_body.html14
-rw-r--r--phpBB/styles/prosilver/template/index_body.html2
-rw-r--r--phpBB/styles/prosilver/template/login_body.html4
-rw-r--r--phpBB/styles/prosilver/template/login_body_oauth.html2
-rw-r--r--phpBB/styles/prosilver/template/login_forum.html2
-rw-r--r--phpBB/styles/prosilver/template/mcp_approve.html8
-rw-r--r--phpBB/styles/prosilver/template/mcp_ban.html8
-rw-r--r--phpBB/styles/prosilver/template/mcp_forum.html2
-rw-r--r--phpBB/styles/prosilver/template/mcp_front.html4
-rw-r--r--phpBB/styles/prosilver/template/mcp_logs.html6
-rw-r--r--phpBB/styles/prosilver/template/mcp_move.html8
-rw-r--r--phpBB/styles/prosilver/template/mcp_notes_front.html4
-rw-r--r--phpBB/styles/prosilver/template/mcp_notes_user.html10
-rw-r--r--phpBB/styles/prosilver/template/mcp_post.html26
-rw-r--r--phpBB/styles/prosilver/template/mcp_queue.html10
-rw-r--r--phpBB/styles/prosilver/template/mcp_reports.html6
-rw-r--r--phpBB/styles/prosilver/template/mcp_topic.html4
-rw-r--r--phpBB/styles/prosilver/template/mcp_warn_front.html4
-rw-r--r--phpBB/styles/prosilver/template/mcp_warn_post.html4
-rw-r--r--phpBB/styles/prosilver/template/mcp_warn_user.html4
-rw-r--r--phpBB/styles/prosilver/template/memberlist_body.html4
-rw-r--r--phpBB/styles/prosilver/template/memberlist_email.html2
-rw-r--r--phpBB/styles/prosilver/template/memberlist_im.html2
-rw-r--r--phpBB/styles/prosilver/template/memberlist_search.html4
-rw-r--r--phpBB/styles/prosilver/template/memberlist_team.html2
-rw-r--r--phpBB/styles/prosilver/template/memberlist_view.html10
-rw-r--r--phpBB/styles/prosilver/template/navbar_header.html2
-rw-r--r--phpBB/styles/prosilver/template/notification_dropdown.html16
-rw-r--r--phpBB/styles/prosilver/template/overall_footer.html8
-rw-r--r--phpBB/styles/prosilver/template/overall_header.html8
-rw-r--r--phpBB/styles/prosilver/template/pagination.html2
-rw-r--r--phpBB/styles/prosilver/template/posting_attach_body.html12
-rw-r--r--phpBB/styles/prosilver/template/posting_editor.html8
-rw-r--r--phpBB/styles/prosilver/template/posting_pm_header.html12
-rw-r--r--phpBB/styles/prosilver/template/quickreply_editor.html4
-rw-r--r--phpBB/styles/prosilver/template/report_body.html4
-rw-r--r--phpBB/styles/prosilver/template/search_body.html4
-rw-r--r--phpBB/styles/prosilver/template/simple_footer.html10
-rw-r--r--phpBB/styles/prosilver/template/simple_header.html8
-rw-r--r--phpBB/styles/prosilver/template/timezone_option.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_agreement.html8
-rw-r--r--phpBB/styles/prosilver/template/ucp_attachments.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_auth_link_oauth.html4
-rw-r--r--phpBB/styles/prosilver/template/ucp_avatar_options.html4
-rw-r--r--phpBB/styles/prosilver/template/ucp_avatar_options_local.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_groups_manage.html8
-rw-r--r--phpBB/styles/prosilver/template/ucp_groups_membership.html4
-rw-r--r--phpBB/styles/prosilver/template/ucp_header.html4
-rw-r--r--phpBB/styles/prosilver/template/ucp_login_link.html4
-rw-r--r--phpBB/styles/prosilver/template/ucp_main_bookmarks.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_main_drafts.html6
-rw-r--r--phpBB/styles/prosilver/template/ucp_main_subscribed.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_notifications.html22
-rw-r--r--phpBB/styles/prosilver/template/ucp_pm_options.html24
-rw-r--r--phpBB/styles/prosilver/template/ucp_pm_viewfolder.html8
-rw-r--r--phpBB/styles/prosilver/template/ucp_pm_viewmessage.html266
-rw-r--r--phpBB/styles/prosilver/template/ucp_prefs_personal.html4
-rw-r--r--phpBB/styles/prosilver/template/ucp_prefs_post.html4
-rw-r--r--phpBB/styles/prosilver/template/ucp_prefs_view.html4
-rw-r--r--phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_profile_profile_info.html4
-rw-r--r--phpBB/styles/prosilver/template/ucp_profile_reg_details.html4
-rw-r--r--phpBB/styles/prosilver/template/ucp_profile_signature.html6
-rw-r--r--phpBB/styles/prosilver/template/ucp_register.html4
-rw-r--r--phpBB/styles/prosilver/template/ucp_resend.html2
-rw-r--r--phpBB/styles/prosilver/template/ucp_zebra_foes.html4
-rw-r--r--phpBB/styles/prosilver/template/ucp_zebra_friends.html4
-rw-r--r--phpBB/styles/prosilver/template/viewforum_body.html2
-rw-r--r--phpBB/styles/prosilver/template/viewtopic_body.html14
-rw-r--r--phpBB/styles/prosilver/theme/base.css57
-rw-r--r--phpBB/styles/prosilver/theme/bidi.css460
-rw-r--r--phpBB/styles/prosilver/theme/buttons.css92
-rw-r--r--phpBB/styles/prosilver/theme/colours.css1182
-rw-r--r--phpBB/styles/prosilver/theme/common.css728
-rw-r--r--phpBB/styles/prosilver/theme/content.css471
-rw-r--r--phpBB/styles/prosilver/theme/cp.css216
-rw-r--r--phpBB/styles/prosilver/theme/en/icon_user_online.gifbin423 -> 0 bytes
-rw-r--r--phpBB/styles/prosilver/theme/en/stylesheet.css3
-rw-r--r--phpBB/styles/prosilver/theme/forms.css240
-rw-r--r--phpBB/styles/prosilver/theme/icons.css76
-rw-r--r--phpBB/styles/prosilver/theme/images/loading.gifbin1320 -> 0 bytes
-rw-r--r--phpBB/styles/prosilver/theme/links.css68
-rw-r--r--phpBB/styles/prosilver/theme/normalize.css461
-rw-r--r--phpBB/styles/prosilver/theme/plupload.css41
-rw-r--r--phpBB/styles/prosilver/theme/print.css212
-rw-r--r--phpBB/styles/prosilver/theme/responsive.css487
-rw-r--r--phpBB/styles/prosilver/theme/stylesheet.css26
-rw-r--r--phpBB/styles/prosilver/theme/tweaks.css45
-rw-r--r--phpBB/styles/prosilver/theme/utilities.css65
-rw-r--r--phpBB/vendor-ext/.git-keep0
-rw-r--r--tests/attachment/delete_test.php38
-rw-r--r--tests/attachment/fixtures/resync.xml2
-rw-r--r--tests/attachment/upload_test.php55
-rw-r--r--tests/avatar/manager_test.php7
-rw-r--r--tests/console/cron/cron_list_test.php1
-rw-r--r--tests/console/cron/run_test.php3
-rw-r--r--tests/content_visibility/delete_post_test.php4
-rw-r--r--tests/controller/common_helper_route.php23
-rw-r--r--tests/controller/controller_test.php2
-rw-r--r--tests/cron/manager_test.php1
-rw-r--r--tests/dbal/migrator_test.php2
-rw-r--r--tests/di/fixtures/config/production/container/environment.yml5
-rw-r--r--tests/di/fixtures/config/test/container/environment.yml5
-rw-r--r--tests/di/fixtures/ext/vendor/enabled_4/di/extension.php4
-rw-r--r--tests/di/fixtures/other_config/production/container/environment.yml5
-rw-r--r--tests/email/email_parsing_test.php3
-rw-r--r--tests/extension/finder_test.php3
-rw-r--r--tests/extension/manager_test.php2
-rw-r--r--tests/extension/metadata_manager_test.php5
-rw-r--r--tests/feed/attachments_base_test.php1
-rw-r--r--tests/files/types_remote_test.php13
-rw-r--r--tests/filesystem/helper_clean_path_test.php52
-rw-r--r--tests/filesystem/helper_is_absolute_test.php64
-rw-r--r--tests/filesystem/helper_realpath_test.php83
-rw-r--r--tests/functional/fileupload_remote_test.php6
-rw-r--r--tests/functional/notification_test.php6
-rw-r--r--tests/functions/build_url_test.php1
-rw-r--r--tests/functions_user/delete_user_test.php5
-rw-r--r--tests/migrator/convert_timezones_test.php3
-rw-r--r--tests/migrator/get_callable_from_step_test.php1
-rw-r--r--tests/migrator/schema_generator_test.php2
-rw-r--r--tests/notification/convert_test.php3
-rw-r--r--tests/notification/group_request_test.php1
-rw-r--r--tests/notification/submit_post_base.php4
-rw-r--r--tests/pagination/pagination_test.php5
-rw-r--r--tests/path_helper/path_helper_test.php18
-rw-r--r--tests/privmsgs/delete_user_pms_test.php5
-rw-r--r--tests/security/redirect_test.php1
-rw-r--r--tests/storage/adapter/local_subfolders_test.php136
-rw-r--r--tests/storage/adapter/local_test.php113
-rw-r--r--tests/template/extension_test.php314
-rw-r--r--tests/template/includephp_test.php5
-rw-r--r--tests/template/template_allfolder_test.php3
-rw-r--r--tests/template/template_events_test.php3
-rw-r--r--tests/template/template_includecss_test.php3
-rw-r--r--tests/template/template_test_case.php3
-rw-r--r--tests/template/template_test_case_with_tree.php3
-rw-r--r--tests/template/templates/extension_icon_test.html1
-rw-r--r--tests/template/templates/svg/dirty.svg6
-rw-r--r--tests/template/templates/svg/pencil.svg1
-rw-r--r--tests/template/templates/svg/phone.svg1
-rw-r--r--tests/test_framework/phpbb_database_test_case.php24
-rw-r--r--tests/test_framework/phpbb_database_test_connection_manager.php5
-rw-r--r--tests/test_framework/phpbb_functional_test_case.php2
-rw-r--r--tests/test_framework/phpbb_session_test_case.php4
-rw-r--r--tests/test_framework/phpbb_ui_test_case.php2
-rwxr-xr-xtravis/check-stylesheet.sh24
320 files changed, 25964 insertions, 4739 deletions
diff --git a/.gitignore b/.gitignore
index c63fb6b02f..d1ea99b9c7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -20,7 +20,12 @@
!/phpBB/styles/prosilver/theme/en
!/phpBB/styles/prosilver/theme/images
!/phpBB/styles/all
+node_modules
/phpBB/vendor
+/phpBB/vendor-ext/*
+!/phpBB/vendor-ext/.git-keep
+/phpBB/composer-ext.json
+/phpBB/composer-ext.lock
/tests/phpbb_unit_tests.sqlite*
/tests/test_config*.php
/tests/tmp/*
diff --git a/.postcss-sorting.json b/.postcss-sorting.json
new file mode 100644
index 0000000000..11a55f3c3d
--- /dev/null
+++ b/.postcss-sorting.json
@@ -0,0 +1,243 @@
+{
+ "order": [
+ "custom-properties",
+ "dollar-variables",
+ {
+ "type": "at-rule",
+ "name": "include"
+ },
+ "declarations",
+ "rules",
+ {
+ "type": "at-rule",
+ "name": "media"
+ }
+ ],
+ "properties-order": [
+ {
+ "emptyLineBefore": false,
+ "properties": [
+ "font",
+ "font-family",
+ "font-size",
+ "font-weight",
+ "font-style",
+ "font-variant",
+ "font-size-adjust",
+ "font-stretch",
+ "font-effect",
+ "font-emphasize",
+ "font-emphasize-position",
+ "font-emphasize-style",
+ "font-smooth",
+ "font-smoothing",
+ "line-height",
+ "text-align",
+ "text-align-last",
+ "vertical-align",
+ "white-space",
+ "text-decoration",
+ "text-emphasis",
+ "text-emphasis-color",
+ "text-emphasis-style",
+ "text-emphasis-position",
+ "text-indent",
+ "text-justify",
+ "letter-spacing",
+ "word-spacing",
+ "writing-mode",
+ "text-outline",
+ "text-transform",
+ "text-size-adjust",
+ "text-wrap",
+ "text-overflow",
+ "text-overflow-ellipsis",
+ "text-overflow-mode",
+ "word-wrap",
+ "word-break",
+ "tab-size",
+ "hyphens"
+ ]
+ },
+ {
+ "emptyLineBefore": false,
+ "properties": [
+ "background",
+ "background-color",
+ "background-image",
+ "background-repeat",
+ "background-attachment",
+ "background-position",
+ "background-position-x",
+ "background-position-y",
+ "background-clip",
+ "background-origin",
+ "background-size",
+ "interpolation-mode",
+ "filter",
+ "border",
+ "border-width",
+ "border-style",
+ "border-color",
+ "border-top",
+ "border-top-width",
+ "border-top-style",
+ "border-top-color",
+ "border-right",
+ "border-right-width",
+ "border-right-style",
+ "border-right-color",
+ "border-bottom",
+ "border-bottom-width",
+ "border-bottom-style",
+ "border-bottom-color",
+ "border-left",
+ "border-left-width",
+ "border-left-style",
+ "border-left-color",
+ "border-radius",
+ "border-top-left-radius",
+ "border-top-right-radius",
+ "border-bottom-right-radius",
+ "border-bottom-left-radius",
+ "border-image",
+ "border-image-source",
+ "border-image-slice",
+ "border-image-width",
+ "border-image-outset",
+ "border-image-repeat",
+ "outline",
+ "outline-width",
+ "outline-style",
+ "outline-color",
+ "outline-offset",
+ "tap-highlight-color"
+ ]
+ },
+ {
+ "emptyLineBefore": false,
+ "properties": [
+ "box-decoration-break",
+ "box-shadow",
+ "text-shadow"
+ ]
+ },
+ {
+ "emptyLineBefore": false,
+ "properties": [
+ "color",
+ "opacity"
+ ]
+ },
+ {
+ "emptyLineBefore": false,
+ "properties": [
+ "position",
+ "z-index",
+ "top",
+ "right",
+ "bottom",
+ "left"
+ ]
+ },
+ {
+ "emptyLineBefore": false,
+ "properties": [
+ "display",
+ "visibility",
+ "float",
+ "clear",
+ "overflow",
+ "overflow-x",
+ "overflow-y",
+ "overflow-scrolling",
+ "clip",
+ "zoom",
+ "flex",
+ "flex-direction",
+ "flex-order",
+ "flex-pack",
+ "flex-align",
+ "flex-basis",
+ "flex-grow",
+ "flex-shrink",
+ "flex-wrap",
+ "justify-content",
+ "align-items",
+ "align-self"
+ ]
+ },
+ {
+ "emptyLineBefore": false,
+ "properties": [
+ "box-sizing",
+ "width",
+ "min-width",
+ "max-width",
+ "height",
+ "min-height",
+ "max-height",
+ "margin",
+ "margin-top",
+ "margin-right",
+ "margin-bottom",
+ "margin-left",
+ "padding",
+ "padding-top",
+ "padding-right",
+ "padding-bottom",
+ "padding-left"
+ ]
+ },
+ {
+ "emptyLineBefore": false,
+ "properties": [
+ "table-layout",
+ "empty-cells",
+ "caption-side",
+ "border-spacing",
+ "border-collapse",
+ "list-style",
+ "list-style-position",
+ "list-style-type",
+ "list-style-image"
+ ]
+ },
+ {
+ "emptyLineBefore": false,
+ "properties": [
+ "content",
+ "quotes",
+ "counter-reset",
+ "counter-increment",
+ "resize",
+ "cursor",
+ "touch-callout",
+ "touch-action",
+ "user-select",
+ "nav-index",
+ "nav-up",
+ "nav-right",
+ "nav-down",
+ "nav-left",
+ "transition",
+ "transition-delay",
+ "transition-timing-function",
+ "transition-duration",
+ "transition-property",
+ "transform",
+ "transform-origin",
+ "animation",
+ "animation-name",
+ "animation-duration",
+ "animation-play-state",
+ "animation-timing-function",
+ "animation-delay",
+ "animation-iteration-count",
+ "animation-direction",
+ "pointer-events"
+ ]
+ }
+ ],
+ "unspecified-properties-position": "bottomAlphabetical"
+}
diff --git a/.stylelintrc b/.stylelintrc
new file mode 100644
index 0000000000..f2590032b0
--- /dev/null
+++ b/.stylelintrc
@@ -0,0 +1,397 @@
+{
+ "plugins": [
+ "stylelint-order"
+ ],
+ "ignoreFiles": [
+ "./phpBB/styles/prosilver/theme/normalize.css"
+ ],
+ "rules": {
+ "at-rule-name-case": "lower",
+ "at-rule-name-newline-after": "always-multi-line",
+ "at-rule-name-space-after": "always-single-line",
+ "at-rule-no-vendor-prefix": true,
+ "at-rule-semicolon-newline-after": "always",
+
+ "block-closing-brace-newline-after": [
+ "always", {
+ "ignoreAtRules": ["if", "else"]
+ }
+ ],
+ "block-closing-brace-newline-before": "always-multi-line",
+ "block-closing-brace-space-before": "always-single-line",
+
+ "block-no-empty": true,
+
+ "block-opening-brace-newline-after": "always-multi-line",
+ "block-opening-brace-space-after": "always-single-line",
+ "block-opening-brace-space-before": "always",
+
+ "color-hex-case": "lower",
+ "color-hex-length": "long",
+ "color-named": "never",
+ "color-no-invalid-hex": true,
+
+ "comment-empty-line-before": [
+ "always", {
+ "except": ["first-nested"],
+ "ignore": ["stylelint-commands"]
+ }
+ ],
+ "comment-whitespace-inside": "always",
+
+ "declaration-bang-space-after": "never",
+ "declaration-bang-space-before": "always",
+
+ "declaration-block-no-shorthand-property-overrides": true,
+ "declaration-block-semicolon-newline-after": "always-multi-line",
+ "declaration-block-semicolon-newline-before": "never-multi-line",
+ "declaration-block-semicolon-space-after": "always-single-line",
+ "declaration-block-semicolon-space-before": "never",
+ "declaration-block-trailing-semicolon": "always",
+ "declaration-block-single-line-max-declarations": 1,
+ "declaration-block-no-duplicate-properties": [
+ true, {
+ "ignore": ["consecutive-duplicates-with-different-values"]
+ }
+ ],
+
+ "declaration-colon-newline-after": "always-multi-line",
+ "declaration-colon-space-after": "always-single-line",
+ "declaration-colon-space-before": "never",
+
+ "declaration-empty-line-before": "never",
+
+ "declaration-property-unit-blacklist": {
+ "line-height": ["rem", "em", "%"]
+ },
+ "declaration-property-unit-whitelist": {
+ "height": ["px", "%", "vh"],
+ "width": ["px", "%", "vw"],
+ "font-size": ["px", "rem", "%"],
+ "margin-left": ["px", "rem", "%"],
+ "margin-right": ["px", "rem", "%"],
+ "margin-top": ["px", "rem", "%"],
+ "margin-bottom": ["px", "rem", "%"],
+ "padding-left": ["px", "rem"],
+ "padding-right": ["px", "rem"],
+ "padding-top": ["px", "rem"],
+ "padding-bottom": ["px", "rem"],
+ "letter-spacing": ["em"],
+ "word-spacing": ["em"]
+ },
+
+ "font-family-name-quotes": "always-where-recommended",
+ "function-calc-no-unspaced-operator": true,
+
+ "function-comma-newline-after": "never-multi-line",
+ "function-comma-newline-before": "never-multi-line",
+ "function-comma-space-after": "always-single-line",
+ "function-comma-space-before": "never-single-line",
+
+ "function-linear-gradient-no-nonstandard-direction": true,
+ "function-max-empty-lines": 5,
+
+ "function-name-case": "lower",
+ "function-parentheses-newline-inside": "always-multi-line",
+ "function-parentheses-space-inside": "never-single-line",
+ "function-url-quotes": "always",
+ "function-whitespace-after": "always",
+
+ "indentation": "tab",
+
+ "length-zero-no-unit": true,
+
+ "max-empty-lines": 10,
+ "max-line-length": 180,
+ "max-nesting-depth": 4,
+
+ "media-feature-colon-space-after": "always",
+ "media-feature-colon-space-before": "never",
+ "media-feature-name-case": "lower",
+ "media-feature-parentheses-space-inside": "never",
+ "media-feature-range-operator-space-after": "always",
+ "media-feature-range-operator-space-before": "always",
+ "media-query-list-comma-newline-after": "always-multi-line",
+ "media-query-list-comma-newline-before": "never-multi-line",
+ "media-query-list-comma-space-after": "always-single-line",
+ "media-query-list-comma-space-before": "never",
+
+ "no-duplicate-selectors": true,
+ "no-empty-source": true,
+ "no-eol-whitespace": true,
+ "no-extra-semicolons": true,
+ "no-missing-end-of-source-newline": true,
+ "no-unknown-animations": true,
+
+ "number-leading-zero": "always",
+ "number-max-precision": 10,
+ "number-no-trailing-zeros": true,
+
+ "property-case": "lower",
+ "property-no-unknown": true,
+
+ "rule-empty-line-before": ["always-multi-line", {
+ "ignore": ["after-comment"],
+ "except": ["first-nested"]
+ }],
+
+ "selector-attribute-brackets-space-inside": "never",
+ "selector-attribute-operator-space-after": "never",
+ "selector-attribute-operator-space-before": "never",
+ "selector-attribute-quotes": "always",
+
+ "selector-combinator-space-after": "always",
+ "selector-combinator-space-before": "always",
+
+ "selector-list-comma-newline-after": "always",
+ "selector-list-comma-space-before": "never",
+
+ "selector-max-empty-lines": 5,
+ "selector-max-compound-selectors": 5,
+
+ "selector-pseudo-class-case": "lower",
+ "selector-pseudo-class-no-unknown": true,
+ "selector-pseudo-class-parentheses-space-inside": "never",
+
+ "selector-pseudo-element-case": "lower",
+ "selector-pseudo-element-colon-notation": "single",
+ "selector-pseudo-element-no-unknown": true,
+
+ "selector-type-case": "lower",
+ "selector-type-no-unknown": true,
+
+ "selector-descendant-combinator-no-non-space": true,
+ "selector-max-id": 0,
+ "selector-no-qualifying-type": [
+ true, {
+ "ignore": ["attribute"]
+ }
+ ],
+
+ "shorthand-property-no-redundant-values": true,
+
+ "string-no-newline": true,
+ "string-quotes": "double",
+
+ "unit-case": "lower",
+ "unit-no-unknown": true,
+
+ "value-list-comma-newline-after": "always-multi-line",
+ "value-list-comma-newline-before": "never-multi-line",
+ "value-list-comma-space-after": "always-single-line",
+ "value-list-comma-space-before": "never",
+ "order/order": [
+ "custom-properties",
+ "dollar-variables",
+ {
+ "type": "at-rule",
+ "name": "include",
+ "parameter": "type"
+ },
+ "declarations",
+ "rules",
+ {
+ "type": "at-rule",
+ "name": "include",
+ "parameter": "fluid"
+ },
+ {
+ "type": "at-rule",
+ "name": "media"
+ }
+ ],
+ "order/properties-order": [
+ [
+ "font",
+ "font-family",
+ "font-size",
+ "font-weight",
+ "font-style",
+ "font-variant",
+ "font-size-adjust",
+ "font-stretch",
+ "font-effect",
+ "font-emphasize",
+ "font-emphasize-position",
+ "font-emphasize-style",
+ "font-smooth",
+ "font-smoothing",
+ "line-height",
+ "text-align",
+ "text-align-last",
+ "vertical-align",
+ "white-space",
+ "text-decoration",
+ "text-emphasis",
+ "text-emphasis-color",
+ "text-emphasis-style",
+ "text-emphasis-position",
+ "text-indent",
+ "text-justify",
+ "letter-spacing",
+ "word-spacing",
+ "writing-mode",
+ "text-outline",
+ "text-transform",
+ "text-size-adjust",
+ "text-wrap",
+ "text-overflow",
+ "text-overflow-ellipsis",
+ "text-overflow-mode",
+ "word-wrap",
+ "word-break",
+ "tab-size",
+ "hyphens",
+
+ "background",
+ "background-color",
+ "background-image",
+ "background-repeat",
+ "background-attachment",
+ "background-position",
+ "background-position-x",
+ "background-position-y",
+ "background-clip",
+ "background-origin",
+ "background-size",
+ "interpolation-mode",
+ "filter",
+
+ "border",
+ "border-width",
+ "border-style",
+ "border-color",
+ "border-top",
+ "border-top-width",
+ "border-top-style",
+ "border-top-color",
+ "border-right",
+ "border-right-width",
+ "border-right-style",
+ "border-right-color",
+ "border-bottom",
+ "border-bottom-width",
+ "border-bottom-style",
+ "border-bottom-color",
+ "border-left",
+ "border-left-width",
+ "border-left-style",
+ "border-left-color",
+ "border-radius",
+ "border-top-left-radius",
+ "border-top-right-radius",
+ "border-bottom-right-radius",
+ "border-bottom-left-radius",
+ "border-image",
+ "border-image-source",
+ "border-image-slice",
+ "border-image-width",
+ "border-image-outset",
+ "border-image-repeat",
+ "outline",
+ "outline-width",
+ "outline-style",
+ "outline-color",
+ "outline-offset",
+ "tap-highlight-color",
+
+ "box-decoration-break",
+ "box-shadow",
+ "text-shadow",
+
+ "color",
+ "opacity",
+
+ "position",
+ "z-index",
+ "top",
+ "right",
+ "bottom",
+ "left",
+
+ "display",
+ "visibility",
+ "float",
+ "clear",
+ "overflow",
+ "overflow-x",
+ "overflow-y",
+ "overflow-scrolling",
+ "clip",
+ "zoom",
+ "flex",
+ "flex-direction",
+ "flex-order",
+ "flex-pack",
+ "flex-align",
+ "flex-basis",
+ "flex-grow",
+ "flex-shrink",
+ "flex-wrap",
+ "justify-content",
+ "align-items",
+ "align-self",
+
+ "box-sizing",
+ "width",
+ "min-width",
+ "max-width",
+ "height",
+ "min-height",
+ "max-height",
+ "margin",
+ "margin-top",
+ "margin-right",
+ "margin-bottom",
+ "margin-left",
+ "padding",
+ "padding-top",
+ "padding-right",
+ "padding-bottom",
+ "padding-left",
+
+ "table-layout",
+ "empty-cells",
+ "caption-side",
+ "border-spacing",
+ "border-collapse",
+ "list-style",
+ "list-style-position",
+ "list-style-type",
+ "list-style-image",
+
+ "content",
+ "quotes",
+ "counter-reset",
+ "counter-increment",
+ "resize",
+ "cursor",
+ "touch-callout",
+ "touch-action",
+ "user-select",
+ "nav-index",
+ "nav-up",
+ "nav-right",
+ "nav-down",
+ "nav-left",
+ "transition",
+ "transition-delay",
+ "transition-timing-function",
+ "transition-duration",
+ "transition-property",
+ "transform",
+ "transform-origin",
+ "animation",
+ "animation-name",
+ "animation-duration",
+ "animation-play-state",
+ "animation-timing-function",
+ "animation-delay",
+ "animation-iteration-count",
+ "animation-direction",
+ "pointer-events"
+ ],
+ { "unspecified": "bottomAlphabetical" }
+ ]
+ }
+}
diff --git a/.travis.yml b/.travis.yml
index 82ddd01158..d5ba5719e0 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -27,6 +27,11 @@ matrix:
- php: nightly
fast_finish: true
+addons:
+ apt:
+ sources:
+ - node
+
services:
- redis-server
- postgresql
@@ -46,6 +51,7 @@ script:
- travis/check-sami-parse-errors.sh $DB $TRAVIS_PHP_VERSION $NOTESTS
- travis/check-image-icc-profiles.sh $DB $TRAVIS_PHP_VERSION $NOTESTS
- travis/check-executable-files.sh $DB $TRAVIS_PHP_VERSION $NOTESTS ./
+ - travis/check-stylesheet.sh $NOTESTS
- sh -c "if [ '$SLOWTESTS' != '1' -a '$DB' = 'mysqli' ]; then phpBB/vendor/bin/phpunit tests/lint_test.php; fi"
- sh -c "if [ '$NOTESTS' != '1' -a '$SLOWTESTS' != '1' ]; then phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml --verbose --stop-on-error; fi"
- sh -c "if [ '$SLOWTESTS' = '1' ]; then phpBB/vendor/bin/phpunit --configuration travis/phpunit-$DB-travis.xml --group slow; fi"
diff --git a/build/build.xml b/build/build.xml
index 587eda9f5e..7917b840b6 100644
--- a/build/build.xml
+++ b/build/build.xml
@@ -2,9 +2,9 @@
<project name="phpBB" description="The phpBB forum software" default="all" basedir="../">
<!-- a few settings for the build -->
- <property name="newversion" value="3.3.0" />
- <property name="prevversion" value="3.2.9" />
- <property name="olderversions" value="3.1.0, 3.1.1, 3.1.2, 3.1.3, 3.1.4, 3.1.5, 3.1.6, 3.1.7, 3.1.7-pl1, 3.1.8, 3.1.9, 3.1.10, 3.1.11, 3.1.12, 3.2.0-a1, 3.2.0-a2, 3.2.0-b1, 3.2.0-b2, 3.2.0-RC1, 3.2.0-RC2, 3.2.0, 3.2.1, 3.2.2, 3.2.3, 3.2.4, 3.2.5, 3.2.6, 3.2.7, 3.2.8, 3.3.0-b1, 3.3.0-b2, 3.3.0-RC1" />
+ <property name="newversion" value="4.0.0-a1-dev" />
+ <property name="prevversion" value="3.3.0" />
+ <property name="olderversions" value="3.1.0, 3.1.1, 3.1.2, 3.1.3, 3.1.4, 3.1.5, 3.1.6, 3.1.7, 3.1.7-pl1, 3.1.8, 3.1.9, 3.1.10, 3.1.11, 3.1.12, 3.2.0-a1, 3.2.0-a2, 3.2.0-b1, 3.2.0-b2, 3.2.0-RC1, 3.2.0-RC2, 3.2.0, 3.2.1, 3.2.2, 3.2.3, 3.2.4, 3.2.5, 3.2.6, 3.2.7, 3.2.8, 3.2.9" />
<!-- no configuration should be needed beyond this point -->
<property name="oldversions" value="${olderversions}, ${prevversion}" />
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644
index 0000000000..0d0e8d7341
--- /dev/null
+++ b/gulpfile.js
@@ -0,0 +1,69 @@
+'use strict';
+
+const del = require('del');
+const gulp = require('gulp');
+const autoprefixer = require('gulp-autoprefixer');
+const sass = require('gulp-sass');
+const rename = require('gulp-rename');
+const sourcemaps = require('gulp-sourcemaps');
+const cssnano = require('cssnano');
+const postcss = require('gulp-postcss');
+const sorting = require('postcss-sorting');
+const atimport = require('postcss-import');
+const torem = require('postcss-pxtorem');
+const sortOrder = require('./.postcss-sorting.json');
+const pkg = require('./package.json');
+
+// Config
+const build = {
+ css: './phpBB/styles/prosilver/theme/',
+};
+
+const AUTOPREFIXER_BROWSERS = [
+ '> 1%',
+ 'last 2 versions'
+];
+
+gulp.task('css', () => {
+ const css = gulp
+ .src(build.css + '*.css')
+ .pipe(autoprefixer(AUTOPREFIXER_BROWSERS))
+ .pipe(
+ postcss([
+ sorting(sortOrder)
+ ])
+ )
+ .pipe(gulp.dest(build.css));
+
+ return css;
+});
+
+gulp.task('clean', () => {
+ del(['dist']);
+});
+
+gulp.task('minify', () => {
+ const css = gulp
+ .src(build.css + '/bidi.css')
+ .pipe(sourcemaps.init())
+ .pipe(
+ postcss([
+ atimport(),
+ cssnano()
+ ])
+ )
+ .pipe(rename({
+ suffix: '.min',
+ extname: '.css'
+ }))
+ .pipe(sourcemaps.write('./'))
+ .pipe(gulp.dest(build.css));
+
+ return css;
+});
+
+gulp.task('watch', () => {
+ gulp.watch('phpBB/styles/prosilver/theme/*.css', ['css']);
+});
+
+gulp.task('default', ['css', 'watch']);
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000000..d2d23b8c78
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,11019 @@
+{
+ "name": "phpbb",
+ "version": "3.3.0-dev",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.5.5",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz",
+ "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.0.0"
+ }
+ },
+ "@babel/core": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.6.2.tgz",
+ "integrity": "sha512-l8zto/fuoZIbncm+01p8zPSDZu/VuuJhAfA7d/AbzM09WR7iVhavvfNDYCNpo1VvLk6E6xgAoP9P+/EMJHuRkQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.5.5",
+ "@babel/generator": "^7.6.2",
+ "@babel/helpers": "^7.6.2",
+ "@babel/parser": "^7.6.2",
+ "@babel/template": "^7.6.0",
+ "@babel/traverse": "^7.6.2",
+ "@babel/types": "^7.6.0",
+ "convert-source-map": "^1.1.0",
+ "debug": "^4.1.0",
+ "json5": "^2.1.0",
+ "lodash": "^4.17.13",
+ "resolve": "^1.3.2",
+ "semver": "^5.4.1",
+ "source-map": "^0.5.0"
+ },
+ "dependencies": {
+ "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"
+ }
+ },
+ "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
+ }
+ }
+ },
+ "@babel/generator": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.6.2.tgz",
+ "integrity": "sha512-j8iHaIW4gGPnViaIHI7e9t/Hl8qLjERI6DcV9kEpAIDJsAOrcnXqRS7t+QbhL76pwbtqP+QCQLL0z1CyVmtjjQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.6.0",
+ "jsesc": "^2.5.1",
+ "lodash": "^4.17.13",
+ "source-map": "^0.5.0"
+ }
+ },
+ "@babel/helper-function-name": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
+ "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-get-function-arity": "^7.0.0",
+ "@babel/template": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "@babel/helper-get-function-arity": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
+ "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz",
+ "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.4.4"
+ }
+ },
+ "@babel/helpers": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.6.2.tgz",
+ "integrity": "sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.6.0",
+ "@babel/traverse": "^7.6.2",
+ "@babel/types": "^7.6.0"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz",
+ "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.0.0",
+ "esutils": "^2.0.2",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.6.2.tgz",
+ "integrity": "sha512-mdFqWrSPCmikBoaBYMuBulzTIKuXVPtEISFbRRVNwMWpCms/hmE2kRq0bblUHaNRKrjRlmVbx1sDHmjmRgD2Xg==",
+ "dev": true
+ },
+ "@babel/template": {
+ "version": "7.6.0",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.6.0.tgz",
+ "integrity": "sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "@babel/parser": "^7.6.0",
+ "@babel/types": "^7.6.0"
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.6.2",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.6.2.tgz",
+ "integrity": "sha512-8fRE76xNwNttVEF2TwxJDGBLWthUkHWSldmfuBzVRmEDWOtu4XdINTgN7TDWzuLg4bbeIMLvfMFD9we5YcWkRQ==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.5.5",
+ "@babel/generator": "^7.6.2",
+ "@babel/helper-function-name": "^7.1.0",
+ "@babel/helper-split-export-declaration": "^7.4.4",
+ "@babel/parser": "^7.6.2",
+ "@babel/types": "^7.6.0",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0",
+ "lodash": "^4.17.13"
+ },
+ "dependencies": {
+ "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"
+ }
+ },
+ "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
+ }
+ }
+ },
+ "@babel/types": {
+ "version": "7.6.1",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.6.1.tgz",
+ "integrity": "sha512-X7gdiuaCmA0uRjCmRtYJNAVCc/q+5xSgsfKJHqMN4iNLILX39677fJE1O40arPMh0TTtS9ItH67yre6c7k6t0g==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2",
+ "lodash": "^4.17.13",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "@gulp-sourcemaps/identity-map": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/identity-map/-/identity-map-1.0.2.tgz",
+ "integrity": "sha512-ciiioYMLdo16ShmfHBXJBOFm3xPC4AuwO4xeRpFeHz7WK9PYsWCmigagG2XyzZpubK4a3qNKoUBDhbzHfa50LQ==",
+ "dev": true,
+ "requires": {
+ "acorn": "^5.0.3",
+ "css": "^2.2.1",
+ "normalize-path": "^2.1.1",
+ "source-map": "^0.6.0",
+ "through2": "^2.0.3"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "5.7.3",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz",
+ "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==",
+ "dev": true
+ },
+ "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
+ }
+ }
+ },
+ "@gulp-sourcemaps/map-sources": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@gulp-sourcemaps/map-sources/-/map-sources-1.0.0.tgz",
+ "integrity": "sha1-iQrnxdjId/bThIYCFazp1+yUW9o=",
+ "dev": true,
+ "requires": {
+ "normalize-path": "^2.0.1",
+ "through2": "^2.0.3"
+ }
+ },
+ "@mrmlnc/readdir-enhanced": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
+ "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==",
+ "dev": true,
+ "requires": {
+ "call-me-maybe": "^1.0.1",
+ "glob-to-regexp": "^0.3.0"
+ }
+ },
+ "@nodelib/fs.scandir": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.2.tgz",
+ "integrity": "sha512-wrIBsjA5pl13f0RN4Zx4FNWmU71lv03meGKnqRUoCyan17s4V3WL92f3w3AIuWbNnpcrQyFBU5qMavJoB8d27w==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "2.0.2",
+ "run-parallel": "^1.1.9"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.2.tgz",
+ "integrity": "sha512-z8+wGWV2dgUhLqrtRYa03yDx4HWMvXKi1z8g3m2JyxAx8F7xk74asqPk5LAETjqDSGLFML/6CDl0+yFunSYicw==",
+ "dev": true
+ },
+ "@nodelib/fs.walk": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.3.tgz",
+ "integrity": "sha512-l6t8xEhfK9Sa4YO5mIRdau7XSOADfmh3jCr0evNHdY+HNkW6xuQhgMH7D73VV6WpZOagrW0UludvMTiifiwTfA==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.scandir": "2.1.2",
+ "fastq": "^1.6.0"
+ }
+ },
+ "@sindresorhus/is": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz",
+ "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==",
+ "dev": true
+ },
+ "@szmarczak/http-timer": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz",
+ "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==",
+ "dev": true,
+ "requires": {
+ "defer-to-connect": "^1.0.1"
+ }
+ },
+ "@types/events": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
+ "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
+ "dev": true
+ },
+ "@types/glob": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
+ "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
+ "dev": true,
+ "requires": {
+ "@types/events": "*",
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/minimatch": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+ "dev": true
+ },
+ "@types/node": {
+ "version": "12.7.8",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.8.tgz",
+ "integrity": "sha512-FMdVn84tJJdV+xe+53sYiZS4R5yn1mAIxfj+DVoNiQjTYz1+OYmjwEZr1ev9nU0axXwda0QDbYl06QHanRVH3A==",
+ "dev": true
+ },
+ "@types/normalize-package-data": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+ "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==",
+ "dev": true
+ },
+ "@types/q": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz",
+ "integrity": "sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==",
+ "dev": true
+ },
+ "@types/unist": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz",
+ "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==",
+ "dev": true
+ },
+ "@types/vfile": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/vfile/-/vfile-3.0.2.tgz",
+ "integrity": "sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "@types/unist": "*",
+ "@types/vfile-message": "*"
+ }
+ },
+ "@types/vfile-message": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@types/vfile-message/-/vfile-message-1.0.1.tgz",
+ "integrity": "sha512-mlGER3Aqmq7bqR1tTTIVHq8KSAFFRyGbrxuM8C/H82g6k7r2fS+IMEkIu3D7JHzG10NvPdR8DNx0jr0pwpp4dA==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "@types/unist": "*"
+ }
+ },
+ "abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "dev": true
+ },
+ "acorn": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz",
+ "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==",
+ "dev": true
+ },
+ "acorn-jsx": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.2.tgz",
+ "integrity": "sha512-tiNTrP1MP0QrChmD2DdupCr6HWSFeKVw5d/dHTu4Y7rkAkRhU/Dt7dphAfIUyxtHpl/eBVip5uTNSpQJHylpAw==",
+ "dev": true
+ },
+ "aggregate-error": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.0.tgz",
+ "integrity": "sha512-yKD9kEoJIR+2IFqhMwayIBgheLYbB3PS2OBhWae1L/ODTd/JF/30cW0bc9TqzRL3k4U41Dieu3BF4I29p8xesA==",
+ "dev": true,
+ "requires": {
+ "clean-stack": "^2.0.0",
+ "indent-string": "^3.2.0"
+ },
+ "dependencies": {
+ "indent-string": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
+ "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=",
+ "dev": true
+ }
+ }
+ },
+ "ajv": {
+ "version": "6.10.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
+ "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^2.0.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "alphanum-sort": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
+ "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
+ "dev": true
+ },
+ "amdefine": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+ "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
+ "dev": true
+ },
+ "ansi-align": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-3.0.0.tgz",
+ "integrity": "sha512-ZpClVKqXN3RGBmKibdfWzqCY4lnjEuoNzU5T0oEFpfd/z5qJHVarukridD4juLO2FXMiwUQxr9WqQtaYa8XRYw==",
+ "dev": true,
+ "requires": {
+ "string-width": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "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
+ },
+ "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
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "ansi-colors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz",
+ "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==",
+ "dev": true,
+ "requires": {
+ "ansi-wrap": "^0.1.0"
+ }
+ },
+ "ansi-escapes": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+ "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+ "dev": true
+ },
+ "ansi-gray": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
+ "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=",
+ "dev": true,
+ "requires": {
+ "ansi-wrap": "0.1.0"
+ }
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "ansi-wrap": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
+ "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
+ "dev": true
+ },
+ "anymatch": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+ "dev": true,
+ "requires": {
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
+ }
+ },
+ "append-buffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz",
+ "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=",
+ "dev": true,
+ "requires": {
+ "buffer-equal": "^1.0.0"
+ }
+ },
+ "aproba": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+ "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==",
+ "dev": true
+ },
+ "archy": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
+ "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
+ "dev": true
+ },
+ "are-we-there-yet": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
+ "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
+ "dev": true,
+ "requires": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.6"
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "arr-filter": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz",
+ "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=",
+ "dev": true,
+ "requires": {
+ "make-iterator": "^1.0.0"
+ }
+ },
+ "arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+ "dev": true
+ },
+ "arr-map": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz",
+ "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=",
+ "dev": true,
+ "requires": {
+ "make-iterator": "^1.0.0"
+ }
+ },
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+ "dev": true
+ },
+ "array-differ": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz",
+ "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==",
+ "dev": true
+ },
+ "array-each": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
+ "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=",
+ "dev": true
+ },
+ "array-find-index": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=",
+ "dev": true
+ },
+ "array-includes": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz",
+ "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.2",
+ "es-abstract": "^1.7.0"
+ }
+ },
+ "array-initial": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz",
+ "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=",
+ "dev": true,
+ "requires": {
+ "array-slice": "^1.0.0",
+ "is-number": "^4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+ "dev": true
+ }
+ }
+ },
+ "array-last": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz",
+ "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==",
+ "dev": true,
+ "requires": {
+ "is-number": "^4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+ "dev": true
+ }
+ }
+ },
+ "array-slice": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
+ "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
+ "dev": true
+ },
+ "array-sort": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz",
+ "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==",
+ "dev": true,
+ "requires": {
+ "default-compare": "^1.0.0",
+ "get-value": "^2.0.6",
+ "kind-of": "^5.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "array-union": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
+ "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
+ "dev": true
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "arrify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+ "dev": true
+ },
+ "asn1": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+ "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+ "dev": true,
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
+ "dev": true
+ },
+ "assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+ "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
+ },
+ "async-done": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.2.tgz",
+ "integrity": "sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.2",
+ "process-nextick-args": "^2.0.0",
+ "stream-exhaust": "^1.0.1"
+ }
+ },
+ "async-each": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz",
+ "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==",
+ "dev": true
+ },
+ "async-foreach": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
+ "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=",
+ "dev": true
+ },
+ "async-settle": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz",
+ "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=",
+ "dev": true,
+ "requires": {
+ "async-done": "^1.2.2"
+ }
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
+ "dev": true
+ },
+ "atob": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+ "dev": true
+ },
+ "autoprefixer": {
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.6.1.tgz",
+ "integrity": "sha512-aVo5WxR3VyvyJxcJC3h4FKfwCQvQWb1tSI5VHNibddCVWrcD1NvlxEweg3TSgiPztMnWfjpy2FURKA2kvDE+Tw==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.6.3",
+ "caniuse-lite": "^1.0.30000980",
+ "chalk": "^2.4.2",
+ "normalize-range": "^0.1.2",
+ "num2fraction": "^1.2.2",
+ "postcss": "^7.0.17",
+ "postcss-value-parser": "^4.0.0"
+ },
+ "dependencies": {
+ "postcss-value-parser": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz",
+ "integrity": "sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ==",
+ "dev": true
+ }
+ }
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
+ "dev": true
+ },
+ "aws4": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
+ "dev": true
+ },
+ "bach": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz",
+ "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=",
+ "dev": true,
+ "requires": {
+ "arr-filter": "^1.1.1",
+ "arr-flatten": "^1.0.1",
+ "arr-map": "^2.0.0",
+ "array-each": "^1.0.0",
+ "array-initial": "^1.0.0",
+ "array-last": "^1.1.1",
+ "async-done": "^1.2.2",
+ "async-settle": "^1.0.0",
+ "now-and-later": "^2.0.0"
+ }
+ },
+ "bail": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.4.tgz",
+ "integrity": "sha512-S8vuDB4w6YpRhICUDET3guPlQpaJl7od94tpZ0Fvnyp+MKW/HyDTcRDck+29C9g+d/qQHnddRH3+94kZdrW0Ww==",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "dev": true,
+ "requires": {
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ }
+ }
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+ "dev": true,
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "binary-extensions": {
+ "version": "1.13.1",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz",
+ "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==",
+ "dev": true
+ },
+ "block-stream": {
+ "version": "0.0.9",
+ "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
+ "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
+ "dev": true,
+ "requires": {
+ "inherits": "~2.0.0"
+ }
+ },
+ "boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
+ "dev": true
+ },
+ "boxen": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/boxen/-/boxen-3.2.0.tgz",
+ "integrity": "sha512-cU4J/+NodM3IHdSL2yN8bqYqnmlBTidDR4RC7nJs61ZmtGz8VZzM3HLQX0zY5mrSmPtR3xWwsq2jOUQqFZN8+A==",
+ "dev": true,
+ "requires": {
+ "ansi-align": "^3.0.0",
+ "camelcase": "^5.3.1",
+ "chalk": "^2.4.2",
+ "cli-boxes": "^2.2.0",
+ "string-width": "^3.0.0",
+ "term-size": "^1.2.0",
+ "type-fest": "^0.3.0",
+ "widest-line": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+ "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+ "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
+ },
+ "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
+ },
+ "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"
+ }
+ },
+ "type-fest": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz",
+ "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==",
+ "dev": true
+ }
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "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.6.6",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.6.tgz",
+ "integrity": "sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA==",
+ "dev": true,
+ "requires": {
+ "caniuse-lite": "^1.0.30000984",
+ "electron-to-chromium": "^1.3.191",
+ "node-releases": "^1.1.25"
+ },
+ "dependencies": {
+ "electron-to-chromium": {
+ "version": "1.3.235",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.235.tgz",
+ "integrity": "sha512-xNabEDbMIKPLQd6xgv4nyyeMaWXIKSJr6G51ZhUemHhbz6kjZAYcygA8CvfEcMF+Mt5eLmDWaLmfSOWdQxzBVQ==",
+ "dev": true
+ }
+ }
+ },
+ "buf-compare": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz",
+ "integrity": "sha1-/vKNqLgROgoNtEMLC2Rntpcws0o=",
+ "dev": true
+ },
+ "buffer-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz",
+ "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=",
+ "dev": true
+ },
+ "buffer-from": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+ "dev": true
+ },
+ "cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "dev": true,
+ "requires": {
+ "collection-visit": "^1.0.0",
+ "component-emitter": "^1.2.1",
+ "get-value": "^2.0.6",
+ "has-value": "^1.0.0",
+ "isobject": "^3.0.1",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ }
+ },
+ "cacheable-request": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz",
+ "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==",
+ "dev": true,
+ "requires": {
+ "clone-response": "^1.0.2",
+ "get-stream": "^5.1.0",
+ "http-cache-semantics": "^4.0.0",
+ "keyv": "^3.0.0",
+ "lowercase-keys": "^2.0.0",
+ "normalize-url": "^4.1.0",
+ "responselike": "^1.0.2"
+ },
+ "dependencies": {
+ "get-stream": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz",
+ "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "lowercase-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz",
+ "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==",
+ "dev": true
+ },
+ "normalize-url": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.4.1.tgz",
+ "integrity": "sha512-rjH3yRt0Ssx19mUwS0hrDUOdG9VI+oRLpLHJ7tXRdjcuQ7v7wo6qPvOZppHRrqfslTKr0L2yBhjj4UXd7c3cQg==",
+ "dev": true
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ }
+ }
+ },
+ "call-me-maybe": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
+ "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=",
+ "dev": true
+ },
+ "caller-callsite": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
+ "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
+ "dev": true,
+ "requires": {
+ "callsites": "^2.0.0"
+ }
+ },
+ "caller-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
+ "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
+ "dev": true,
+ "requires": {
+ "caller-callsite": "^2.0.0"
+ }
+ },
+ "callsites": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+ "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+ "dev": true
+ },
+ "camelcase-keys": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^2.0.0",
+ "map-obj": "^1.0.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+ "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
+ "dev": true
+ }
+ }
+ },
+ "caniuse-api": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz",
+ "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.0.0",
+ "caniuse-lite": "^1.0.0",
+ "lodash.memoize": "^4.1.2",
+ "lodash.uniq": "^4.5.0"
+ }
+ },
+ "caniuse-lite": {
+ "version": "1.0.30000989",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000989.tgz",
+ "integrity": "sha512-vrMcvSuMz16YY6GSVZ0dWDTJP8jqk3iFQ/Aq5iqblPwxSVVZI+zxDyTX0VPqtQsDnfdrBDcsmhgTEOh5R8Lbpw==",
+ "dev": true
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
+ "dev": true
+ },
+ "ccount": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.4.tgz",
+ "integrity": "sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w==",
+ "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"
+ }
+ },
+ "character-entities": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.3.tgz",
+ "integrity": "sha512-yB4oYSAa9yLcGyTbB4ItFwHw43QHdH129IJ5R+WvxOkWlyFnR5FAaBNnUq4mcxsTVZGh28bHoeTHMKXH1wZf3w==",
+ "dev": true
+ },
+ "character-entities-html4": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.3.tgz",
+ "integrity": "sha512-SwnyZ7jQBCRHELk9zf2CN5AnGEc2nA+uKMZLHvcqhpPprjkYhiLn0DywMHgN5ttFZuITMATbh68M6VIVKwJbcg==",
+ "dev": true
+ },
+ "character-entities-legacy": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.3.tgz",
+ "integrity": "sha512-YAxUpPoPwxYFsslbdKkhrGnXAtXoHNgYjlBM3WMXkWGTl5RsY3QmOyhwAgL8Nxm9l5LBThXGawxKPn68y6/fww==",
+ "dev": true
+ },
+ "character-reference-invalid": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.3.tgz",
+ "integrity": "sha512-VOq6PRzQBam/8Jm6XBGk2fNEnHXAdGd6go0rtd4weAGECBamHDwwCQSOT12TACIYUZegUXnV6xBXqUssijtxIg==",
+ "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
+ },
+ "chokidar": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz",
+ "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==",
+ "dev": true,
+ "requires": {
+ "anymatch": "^2.0.0",
+ "async-each": "^1.0.1",
+ "braces": "^2.3.2",
+ "fsevents": "^1.2.7",
+ "glob-parent": "^3.1.0",
+ "inherits": "^2.0.3",
+ "is-binary-path": "^1.0.0",
+ "is-glob": "^4.0.0",
+ "normalize-path": "^3.0.0",
+ "path-is-absolute": "^1.0.0",
+ "readdirp": "^2.2.1",
+ "upath": "^1.1.1"
+ },
+ "dependencies": {
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ }
+ },
+ "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
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ }
+ }
+ }
+ },
+ "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
+ },
+ "class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ }
+ },
+ "clean-regexp": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz",
+ "integrity": "sha1-jffHquUf02h06PjQW5GAvBGj/tc=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "clean-stack": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
+ "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
+ "dev": true
+ },
+ "cli-boxes": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-2.2.0.tgz",
+ "integrity": "sha512-gpaBrMAizVEANOpfZp/EEUixTXDyGt7DFzdK5hU+UbWt/J0lB0w20ncZj59Z9a93xHb9u12zF5BS6i9RKbtg4w==",
+ "dev": true
+ },
+ "cli-cursor": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^2.0.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": "3.2.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wrap-ansi": "^2.0.0"
+ }
+ },
+ "clone": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+ "dev": true
+ },
+ "clone-buffer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
+ "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=",
+ "dev": true
+ },
+ "clone-regexp": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz",
+ "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==",
+ "dev": true,
+ "requires": {
+ "is-regexp": "^2.0.0"
+ }
+ },
+ "clone-response": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz",
+ "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=",
+ "dev": true,
+ "requires": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "clone-stats": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+ "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
+ "dev": true
+ },
+ "cloneable-readable": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz",
+ "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "process-nextick-args": "^2.0.0",
+ "readable-stream": "^2.3.5"
+ }
+ },
+ "coa": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz",
+ "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==",
+ "dev": true,
+ "requires": {
+ "@types/q": "^1.5.1",
+ "chalk": "^2.4.1",
+ "q": "^1.1.2"
+ }
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=",
+ "dev": true
+ },
+ "collapse-white-space": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.5.tgz",
+ "integrity": "sha512-703bOOmytCYAX9cXYqoikYIx6twmFCXsnzRQheBcTG3nzKYBR4P/+wkYeH+Mvj7qUz8zZDtdyzbxfnEi/kYzRQ==",
+ "dev": true
+ },
+ "collection-map": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz",
+ "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=",
+ "dev": true,
+ "requires": {
+ "arr-map": "^2.0.2",
+ "for-own": "^1.0.0",
+ "make-iterator": "^1.0.0"
+ }
+ },
+ "collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "dev": true,
+ "requires": {
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ }
+ },
+ "color": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz",
+ "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.1",
+ "color-string": "^1.5.2"
+ }
+ },
+ "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
+ },
+ "color-string": {
+ "version": "1.5.3",
+ "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz",
+ "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==",
+ "dev": true,
+ "requires": {
+ "color-name": "^1.0.0",
+ "simple-swizzle": "^0.2.2"
+ }
+ },
+ "color-support": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+ "dev": true
+ },
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "commondir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz",
+ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=",
+ "dev": true
+ },
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+ "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=",
+ "dev": true
+ },
+ "concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "dev": true,
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "configstore": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-4.0.0.tgz",
+ "integrity": "sha512-CmquAXFBocrzaSM8mtGPMM/HiWmyIpr4CcJl/rgY2uCObZ/S7cKU0silxslqJejl+t/T9HS8E0PUNQD81JGUEQ==",
+ "dev": true,
+ "requires": {
+ "dot-prop": "^4.1.0",
+ "graceful-fs": "^4.1.2",
+ "make-dir": "^1.0.0",
+ "unique-string": "^1.0.0",
+ "write-file-atomic": "^2.0.0",
+ "xdg-basedir": "^3.0.0"
+ },
+ "dependencies": {
+ "make-dir": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+ "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+ "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
+ }
+ }
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=",
+ "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
+ },
+ "convert-source-map": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
+ "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+ "dev": true
+ },
+ "copy-props": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz",
+ "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==",
+ "dev": true,
+ "requires": {
+ "each-props": "^1.3.0",
+ "is-plain-object": "^2.0.1"
+ }
+ },
+ "core-assert": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz",
+ "integrity": "sha1-+F4s+b/tKPdzzIs/pcW2m9wC/j8=",
+ "dev": true,
+ "requires": {
+ "buf-compare": "^1.0.0",
+ "is-error": "^2.2.0"
+ }
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
+ "dev": true
+ },
+ "cosmiconfig": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+ "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+ "dev": true,
+ "requires": {
+ "import-fresh": "^2.0.0",
+ "is-directory": "^0.3.1",
+ "js-yaml": "^3.13.1",
+ "parse-json": "^4.0.0"
+ },
+ "dependencies": {
+ "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"
+ }
+ }
+ }
+ },
+ "cross-spawn": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
+ "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^4.0.1",
+ "which": "^1.2.9"
+ }
+ },
+ "crypto-random-string": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
+ "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
+ "dev": true
+ },
+ "css": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
+ "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "source-map": "^0.6.1",
+ "source-map-resolve": "^0.5.2",
+ "urix": "^0.1.0"
+ },
+ "dependencies": {
+ "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
+ }
+ }
+ },
+ "css-color-names": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz",
+ "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=",
+ "dev": true
+ },
+ "css-declaration-sorter": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz",
+ "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.1",
+ "timsort": "^0.3.0"
+ }
+ },
+ "css-select": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.0.2.tgz",
+ "integrity": "sha512-dSpYaDVoWaELjvZ3mS6IKZM/y2PMPa/XYoEfYNZePL4U/XgyxZNroHEHReDx/d+VgXh9VbCTtFqLkFbmeqeaRQ==",
+ "dev": true,
+ "requires": {
+ "boolbase": "^1.0.0",
+ "css-what": "^2.1.2",
+ "domutils": "^1.7.0",
+ "nth-check": "^1.0.2"
+ }
+ },
+ "css-select-base-adapter": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz",
+ "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==",
+ "dev": true
+ },
+ "css-tree": {
+ "version": "1.0.0-alpha.33",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.33.tgz",
+ "integrity": "sha512-SPt57bh5nQnpsTBsx/IXbO14sRc9xXu5MtMAVuo0BaQQmyf0NupNPPSoMaqiAF5tDFafYsTkfeH4Q/HCKXkg4w==",
+ "dev": true,
+ "requires": {
+ "mdn-data": "2.0.4",
+ "source-map": "^0.5.3"
+ }
+ },
+ "css-unit-converter": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/css-unit-converter/-/css-unit-converter-1.1.1.tgz",
+ "integrity": "sha1-2bkoGtz9jO2TW9urqDeGiX9k6ZY=",
+ "dev": true
+ },
+ "css-what": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz",
+ "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==",
+ "dev": true
+ },
+ "cssesc": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-2.0.0.tgz",
+ "integrity": "sha512-MsCAG1z9lPdoO/IUMLSBWBSVxVtJ1395VGIQ+Fc2gNdkQ1hNDnQdw3YhA71WJCBW1vdwA0cAnk/DnW6bqoEUYg==",
+ "dev": true
+ },
+ "cssnano": {
+ "version": "4.1.10",
+ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz",
+ "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==",
+ "dev": true,
+ "requires": {
+ "cosmiconfig": "^5.0.0",
+ "cssnano-preset-default": "^4.0.7",
+ "is-resolvable": "^1.0.0",
+ "postcss": "^7.0.0"
+ },
+ "dependencies": {
+ "cosmiconfig": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+ "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+ "dev": true,
+ "requires": {
+ "import-fresh": "^2.0.0",
+ "is-directory": "^0.3.1",
+ "js-yaml": "^3.13.1",
+ "parse-json": "^4.0.0"
+ }
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "cssnano-preset-default": {
+ "version": "4.0.7",
+ "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz",
+ "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==",
+ "dev": true,
+ "requires": {
+ "css-declaration-sorter": "^4.0.1",
+ "cssnano-util-raw-cache": "^4.0.1",
+ "postcss": "^7.0.0",
+ "postcss-calc": "^7.0.1",
+ "postcss-colormin": "^4.0.3",
+ "postcss-convert-values": "^4.0.1",
+ "postcss-discard-comments": "^4.0.2",
+ "postcss-discard-duplicates": "^4.0.2",
+ "postcss-discard-empty": "^4.0.1",
+ "postcss-discard-overridden": "^4.0.1",
+ "postcss-merge-longhand": "^4.0.11",
+ "postcss-merge-rules": "^4.0.3",
+ "postcss-minify-font-values": "^4.0.2",
+ "postcss-minify-gradients": "^4.0.2",
+ "postcss-minify-params": "^4.0.2",
+ "postcss-minify-selectors": "^4.0.2",
+ "postcss-normalize-charset": "^4.0.1",
+ "postcss-normalize-display-values": "^4.0.2",
+ "postcss-normalize-positions": "^4.0.2",
+ "postcss-normalize-repeat-style": "^4.0.2",
+ "postcss-normalize-string": "^4.0.2",
+ "postcss-normalize-timing-functions": "^4.0.2",
+ "postcss-normalize-unicode": "^4.0.1",
+ "postcss-normalize-url": "^4.0.1",
+ "postcss-normalize-whitespace": "^4.0.2",
+ "postcss-ordered-values": "^4.1.2",
+ "postcss-reduce-initial": "^4.0.3",
+ "postcss-reduce-transforms": "^4.0.2",
+ "postcss-svgo": "^4.0.2",
+ "postcss-unique-selectors": "^4.0.1"
+ }
+ },
+ "cssnano-util-get-arguments": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz",
+ "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=",
+ "dev": true
+ },
+ "cssnano-util-get-match": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz",
+ "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=",
+ "dev": true
+ },
+ "cssnano-util-raw-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz",
+ "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ }
+ },
+ "cssnano-util-same-parent": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz",
+ "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==",
+ "dev": true
+ },
+ "csso": {
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-3.5.1.tgz",
+ "integrity": "sha512-vrqULLffYU1Q2tLdJvaCYbONStnfkfimRxXNaGjxMldI0C7JPBC4rB1RyjhfdZ4m1frm8pM9uRPKH3d2knZ8gg==",
+ "dev": true,
+ "requires": {
+ "css-tree": "1.0.0-alpha.29"
+ },
+ "dependencies": {
+ "css-tree": {
+ "version": "1.0.0-alpha.29",
+ "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.29.tgz",
+ "integrity": "sha512-sRNb1XydwkW9IOci6iB2xmy8IGCj6r/fr+JWitvJ2JxQRPzN3T4AGGVWCMlVmVwM1gtgALJRmGIlWv5ppnGGkg==",
+ "dev": true,
+ "requires": {
+ "mdn-data": "~1.1.0",
+ "source-map": "^0.5.3"
+ }
+ },
+ "mdn-data": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-1.1.4.tgz",
+ "integrity": "sha512-FSYbp3lyKjyj3E7fMl6rYvUdX0FBXaluGqlFoYESWQlyUTq8R+wp0rkFxoYFqZlHCvsUXGjyJmLQSnXToYhOSA==",
+ "dev": true
+ }
+ }
+ },
+ "currently-unhandled": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+ "dev": true,
+ "requires": {
+ "array-find-index": "^1.0.1"
+ }
+ },
+ "d": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
+ "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
+ "dev": true,
+ "requires": {
+ "es5-ext": "^0.10.9"
+ }
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "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"
+ }
+ },
+ "debug-fabulous": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/debug-fabulous/-/debug-fabulous-1.1.0.tgz",
+ "integrity": "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg==",
+ "dev": true,
+ "requires": {
+ "debug": "3.X",
+ "memoizee": "0.4.X",
+ "object-assign": "4.X"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==",
+ "dev": true
+ }
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+ "dev": true
+ },
+ "decompress-response": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
+ "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
+ "dev": true,
+ "requires": {
+ "mimic-response": "^1.0.0"
+ }
+ },
+ "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==",
+ "dev": true
+ },
+ "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
+ },
+ "deep-strict-equal": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/deep-strict-equal/-/deep-strict-equal-0.2.0.tgz",
+ "integrity": "sha1-SgeBR6irV/ag1PVUckPNIvROtOQ=",
+ "dev": true,
+ "requires": {
+ "core-assert": "^0.2.0"
+ }
+ },
+ "default-compare": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz",
+ "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^5.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "default-resolution": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz",
+ "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=",
+ "dev": true
+ },
+ "defer-to-connect": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.0.2.tgz",
+ "integrity": "sha512-k09hcQcTDY+cwgiwa6PYKLm3jlagNzQ+RSvhjzESOGOx+MNOuXkxTfEvPrO1IOQ81tArCFYQgi631clB70RpQw==",
+ "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"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "del": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/del/-/del-5.1.0.tgz",
+ "integrity": "sha512-wH9xOVHnczo9jN2IW68BabcecVPxacIA3g/7z6vhSU/4stOKQzeCRK0yD0A24WiAAUJmmVpWqrERcTxnLo3AnA==",
+ "dev": true,
+ "requires": {
+ "globby": "^10.0.1",
+ "graceful-fs": "^4.2.2",
+ "is-glob": "^4.0.1",
+ "is-path-cwd": "^2.2.0",
+ "is-path-inside": "^3.0.1",
+ "p-map": "^3.0.0",
+ "rimraf": "^3.0.0",
+ "slash": "^3.0.0"
+ },
+ "dependencies": {
+ "graceful-fs": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.2.tgz",
+ "integrity": "sha512-IItsdsea19BoLC7ELy13q1iJFNmd7ofZH5+X/pJr90/nRoPEX0DJo1dHDbgtYWOhJhcCgMDTOw84RZ72q6lB+Q==",
+ "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"
+ }
+ },
+ "rimraf": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.0.tgz",
+ "integrity": "sha512-NDGVxTsjqfunkds7CqsOiEnxln4Bo7Nddl3XhS4pXg5OzwkLqJ971ZVAAnB+DDLnF76N+VnDEiBHaVV8I06SUg==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ }
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
+ "dev": true
+ },
+ "delegates": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+ "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=",
+ "dev": true
+ },
+ "detect-file": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+ "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
+ "dev": true
+ },
+ "detect-indent": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz",
+ "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=",
+ "dev": true
+ },
+ "detect-newline": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz",
+ "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=",
+ "dev": true
+ },
+ "dir-glob": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
+ "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
+ "dev": true,
+ "requires": {
+ "path-type": "^4.0.0"
+ },
+ "dependencies": {
+ "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
+ }
+ }
+ },
+ "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"
+ }
+ },
+ "dom-serializer": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.1.tgz",
+ "integrity": "sha512-sK3ujri04WyjwQXVoK4PU3y8ula1stq10GJZpqHIUgoGZdsGzAGu65BnU3d08aTVSvO7mGPZUc0wTEDL+qGE0Q==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^2.0.1",
+ "entities": "^2.0.0"
+ },
+ "dependencies": {
+ "domelementtype": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz",
+ "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==",
+ "dev": true
+ },
+ "entities": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz",
+ "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==",
+ "dev": true
+ }
+ }
+ },
+ "domelementtype": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+ "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
+ "dev": true
+ },
+ "domhandler": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
+ "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1"
+ }
+ },
+ "domutils": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz",
+ "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==",
+ "dev": true,
+ "requires": {
+ "dom-serializer": "0",
+ "domelementtype": "1"
+ }
+ },
+ "dot-prop": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
+ "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
+ "dev": true,
+ "requires": {
+ "is-obj": "^1.0.0"
+ }
+ },
+ "duplexer3": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+ "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+ "dev": true
+ },
+ "duplexify": {
+ "version": "3.7.1",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz",
+ "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.0",
+ "stream-shift": "^1.0.0"
+ }
+ },
+ "each-props": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz",
+ "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.1",
+ "object.defaults": "^1.1.0"
+ }
+ },
+ "ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+ "dev": true,
+ "requires": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "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==",
+ "dev": true
+ },
+ "end-of-stream": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+ "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "enhance-visitors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/enhance-visitors/-/enhance-visitors-1.0.0.tgz",
+ "integrity": "sha1-qpRdBdpGVnKh69OP7i7T2oUY6Vo=",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.13.1"
+ }
+ },
+ "entities": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+ "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
+ "dev": true
+ },
+ "env-editor": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/env-editor/-/env-editor-0.4.1.tgz",
+ "integrity": "sha512-suh+Vm00GnPQgXpmONTkcUT9LgBSL6sJrRnJxbykT0j+ONjzmIS+1U3ne467ArdZN/42/npp+GnhtwkLQ+vUjw==",
+ "dev": true
+ },
+ "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.13.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz",
+ "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==",
+ "dev": true,
+ "requires": {
+ "es-to-primitive": "^1.2.0",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "is-callable": "^1.1.4",
+ "is-regex": "^1.0.4",
+ "object-keys": "^1.0.12"
+ }
+ },
+ "es-to-primitive": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz",
+ "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==",
+ "dev": true,
+ "requires": {
+ "is-callable": "^1.1.4",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.2"
+ }
+ },
+ "es5-ext": {
+ "version": "0.10.48",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.48.tgz",
+ "integrity": "sha512-CdRvPlX/24Mj5L4NVxTs4804sxiS2CjVprgCmrgoDkdmjdY4D+ySHa7K3jJf8R40dFg0tIm3z/dk326LrnuSGw==",
+ "dev": true,
+ "requires": {
+ "es6-iterator": "~2.0.3",
+ "es6-symbol": "~3.1.1",
+ "next-tick": "1"
+ }
+ },
+ "es6-iterator": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "es6-symbol": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
+ "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14"
+ }
+ },
+ "es6-weak-map": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
+ "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.14",
+ "es6-iterator": "^2.0.1",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "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.4.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.4.0.tgz",
+ "integrity": "sha512-WTVEzK3lSFoXUovDHEbkJqCVPEPwbhCq4trDktNI6ygs7aO41d4cDT0JFAT5MivzZeVLWlg7vHL+bgrQv/t3vA==",
+ "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.2",
+ "eslint-visitor-keys": "^1.1.0",
+ "espree": "^6.1.1",
+ "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": "^11.7.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^6.4.1",
+ "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.2",
+ "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.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "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"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+ "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"
+ }
+ },
+ "glob-parent": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
+ "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ },
+ "dependencies": {
+ "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"
+ }
+ }
+ }
+ },
+ "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.1.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.1.0.tgz",
+ "integrity": "sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ==",
+ "dev": true,
+ "requires": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ }
+ },
+ "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
+ },
+ "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
+ },
+ "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-ast-utils": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-ast-utils/-/eslint-ast-utils-1.1.0.tgz",
+ "integrity": "sha512-otzzTim2/1+lVrlH19EfQQJEhVJSu0zOb9ygb3iapN6UlyaDtyRq4b5U1FuW0v1lRa9Fp/GJyHkSwm6NqABgCA==",
+ "dev": true,
+ "requires": {
+ "lodash.get": "^4.4.2",
+ "lodash.zip": "^4.2.0"
+ }
+ },
+ "eslint-config-prettier": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.3.0.tgz",
+ "integrity": "sha512-EWaGjlDAZRzVFveh2Jsglcere2KK5CJBhkNSa1xs3KfMUGdRiT7lG089eqPdvlzWHpAqaekubOsOMu8W8Yk71A==",
+ "dev": true,
+ "requires": {
+ "get-stdin": "^6.0.0"
+ },
+ "dependencies": {
+ "get-stdin": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
+ "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-config-xo": {
+ "version": "0.27.1",
+ "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.27.1.tgz",
+ "integrity": "sha512-os4vvQCSZb7WdUMar52z97c2q6j29oIDj/Kb9HeOZ/jW7gqx3JjUQdLm+nq9hHpwgbS0vUx+Hm4HD7lVUltBPw==",
+ "dev": true
+ },
+ "eslint-formatter-pretty": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-formatter-pretty/-/eslint-formatter-pretty-2.1.1.tgz",
+ "integrity": "sha512-gWfagucSWBn82WxzwFloBTLAcwYDgnpAfiV5pQfyAV5YpZikuLflRU8nc3Ts9wnNvLhwk4blzb42/C495Yw7BA==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^3.1.0",
+ "chalk": "^2.1.0",
+ "eslint-rule-docs": "^1.1.5",
+ "log-symbols": "^2.0.0",
+ "plur": "^3.0.1",
+ "string-width": "^2.0.0",
+ "supports-hyperlinks": "^1.0.1"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "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
+ },
+ "log-symbols": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
+ "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.0.1"
+ }
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "eslint-import-resolver-node": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz",
+ "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==",
+ "dev": true,
+ "requires": {
+ "debug": "^2.6.9",
+ "resolve": "^1.5.0"
+ }
+ },
+ "eslint-module-utils": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.1.tgz",
+ "integrity": "sha512-H6DOj+ejw7Tesdgbfs4jeS4YMFrT8uI8xwd1gtQqXssaR0EQ26L+2O/w6wkYFy2MymON0fTwHmXBvvfLNZVZEw==",
+ "dev": true,
+ "requires": {
+ "debug": "^2.6.8",
+ "pkg-dir": "^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"
+ }
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "eslint-plugin-ava": {
+ "version": "9.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-ava/-/eslint-plugin-ava-9.0.0.tgz",
+ "integrity": "sha512-mJqQ1wQ9pxBi5Pu+grrqjfuSLxiSSgnpa5p5vMdEpBqA9n9cUzSCv0xMZ/NkTMAj5ieOB3TWF8j+7C30Yiv4RA==",
+ "dev": true,
+ "requires": {
+ "deep-strict-equal": "^0.2.0",
+ "enhance-visitors": "^1.0.0",
+ "espree": "^6.0.0",
+ "espurify": "^2.0.0",
+ "import-modules": "^1.1.0",
+ "pkg-dir": "^4.2.0",
+ "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
+ }
+ }
+ },
+ "eslint-plugin-es": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-es/-/eslint-plugin-es-2.0.0.tgz",
+ "integrity": "sha512-f6fceVtg27BR02EYnBhgWLFQfK6bN4Ll0nQFrBHOlCsAyxeZkn0NHns5O0YZOPrV1B3ramd6cgFwaoFLcSkwEQ==",
+ "dev": true,
+ "requires": {
+ "eslint-utils": "^1.4.2",
+ "regexpp": "^3.0.0"
+ },
+ "dependencies": {
+ "regexpp": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz",
+ "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-plugin-eslint-comments": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-3.1.2.tgz",
+ "integrity": "sha512-QexaqrNeteFfRTad96W+Vi4Zj1KFbkHHNMMaHZEYcovKav6gdomyGzaxSDSL3GoIyUOo078wRAdYlu1caiauIQ==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5",
+ "ignore": "^5.0.5"
+ }
+ },
+ "eslint-plugin-import": {
+ "version": "2.18.2",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.18.2.tgz",
+ "integrity": "sha512-5ohpsHAiUBRNaBWAF08izwUGlbrJoJJ+W9/TBwsGoR1MnlgfwMIKrFeSjWbt6moabiXW9xNvtFz+97KHRfI4HQ==",
+ "dev": true,
+ "requires": {
+ "array-includes": "^3.0.3",
+ "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.0",
+ "has": "^1.0.3",
+ "minimatch": "^3.0.4",
+ "object.values": "^1.1.0",
+ "read-pkg-up": "^2.0.0",
+ "resolve": "^1.11.0"
+ },
+ "dependencies": {
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "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"
+ }
+ },
+ "resolve": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz",
+ "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==",
+ "dev": true,
+ "requires": {
+ "path-parse": "^1.0.6"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ }
+ }
+ },
+ "eslint-plugin-no-use-extend-native": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-no-use-extend-native/-/eslint-plugin-no-use-extend-native-0.4.1.tgz",
+ "integrity": "sha512-tDkHM0kvxU0M2TpLRKGfFrpWXctFdTDY7VkiDTLYDaX90hMSJKkr/FiWThEXvKV0Dvffut2Z0B9Y7+h/k6suiA==",
+ "dev": true,
+ "requires": {
+ "is-get-set-prop": "^1.0.0",
+ "is-js-type": "^2.0.0",
+ "is-obj-prop": "^1.0.0",
+ "is-proto-prop": "^2.0.0"
+ }
+ },
+ "eslint-plugin-node": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-node/-/eslint-plugin-node-10.0.0.tgz",
+ "integrity": "sha512-1CSyM/QCjs6PXaT18+zuAXsjXGIGo5Rw630rSKwokSs2jrYURQc4R5JZpoanNCqwNmepg+0eZ9L7YiRUJb8jiQ==",
+ "dev": true,
+ "requires": {
+ "eslint-plugin-es": "^2.0.0",
+ "eslint-utils": "^1.4.2",
+ "ignore": "^5.1.1",
+ "minimatch": "^3.0.4",
+ "resolve": "^1.10.1",
+ "semver": "^6.1.0"
+ },
+ "dependencies": {
+ "resolve": {
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz",
+ "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==",
+ "dev": true,
+ "requires": {
+ "path-parse": "^1.0.6"
+ }
+ },
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-plugin-prettier": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.1.tgz",
+ "integrity": "sha512-A+TZuHZ0KU0cnn56/9mfR7/KjUJ9QNVXUhwvRFSR7PGPe0zQR6PTkmyqg1AtUUEOzTqeRsUwyKFh0oVZKVCrtA==",
+ "dev": true,
+ "requires": {
+ "prettier-linter-helpers": "^1.0.0"
+ }
+ },
+ "eslint-plugin-promise": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-4.2.1.tgz",
+ "integrity": "sha512-VoM09vT7bfA7D+upt+FjeBO5eHIJQBUWki1aPvB+vbNiHS3+oGIJGIeyBtKQTME6UPXXy3vV07OL1tHd3ANuDw==",
+ "dev": true
+ },
+ "eslint-plugin-unicorn": {
+ "version": "12.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-12.0.1.tgz",
+ "integrity": "sha512-wusTPg8zgHyUBp6Gc/QyAgBMnwvYtKefkrPeZMESTfxd+j/zyODWMZ5UEG96PhTzXF/ILVypv7VWTHMNfthKLg==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0",
+ "clean-regexp": "^1.0.0",
+ "eslint-ast-utils": "^1.1.0",
+ "eslint-template-visitor": "^1.0.0",
+ "import-modules": "^1.1.0",
+ "lodash.camelcase": "^4.3.0",
+ "lodash.defaultsdeep": "^4.6.1",
+ "lodash.kebabcase": "^4.1.1",
+ "lodash.snakecase": "^4.1.1",
+ "lodash.topairs": "^4.3.0",
+ "lodash.upperfirst": "^4.3.1",
+ "read-pkg-up": "^6.0.0",
+ "regexpp": "^3.0.0",
+ "reserved-words": "^0.1.2",
+ "safe-regex": "^2.0.2",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.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==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "p-limit": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz",
+ "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==",
+ "dev": true,
+ "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==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.2.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "parse-json": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz",
+ "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1",
+ "lines-and-columns": "^1.1.6"
+ }
+ },
+ "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
+ },
+ "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": {
+ "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": "6.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-6.0.0.tgz",
+ "integrity": "sha512-odtTvLl+EXo1eTsMnoUHRmg/XmXdTkwXVxy4VFE9Kp6cCq7b3l7QMdBndND3eAFzrbSAXC/WCUOQQ9rLjifKZw==",
+ "dev": true,
+ "requires": {
+ "find-up": "^4.0.0",
+ "read-pkg": "^5.1.1",
+ "type-fest": "^0.5.0"
+ }
+ },
+ "regexpp": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz",
+ "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==",
+ "dev": true
+ },
+ "safe-regex": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-2.0.2.tgz",
+ "integrity": "sha512-rRALJT0mh4qVFIJ9HvfjKDN77F9vp7kltOpFFI/8e6oKyHFmmxz4aSkY/YVauRDe7U0RrHdw9Lsxdel3E19s0A==",
+ "dev": true,
+ "requires": {
+ "regexp-tree": "~0.1.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
+ }
+ }
+ },
+ "eslint-rule-docs": {
+ "version": "1.1.158",
+ "resolved": "https://registry.npmjs.org/eslint-rule-docs/-/eslint-rule-docs-1.1.158.tgz",
+ "integrity": "sha512-S4jQGXR245fsTtJXOwP7JLnXV0Nw+ZvWC1Vo9zILi/5CueV8yKi3Dr2eH4U8MXmBY90oMT32DyAVLymK2ioaog==",
+ "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-template-visitor": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-template-visitor/-/eslint-template-visitor-1.1.0.tgz",
+ "integrity": "sha512-Lmy6QVlmFiIGl5fPi+8ACnov3sare+0Ouf7deJAGGhmUfeWJ5fVarELUxZRpsZ9sHejiJUq8626d0dn9uvcZTw==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^1.1.0",
+ "espree": "^6.1.1",
+ "multimap": "^1.0.2"
+ }
+ },
+ "eslint-utils": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz",
+ "integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==",
+ "dev": true,
+ "requires": {
+ "eslint-visitor-keys": "^1.0.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.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.1.tgz",
+ "integrity": "sha512-EYbr8XZUhWbYCqQRW0duU5LxzL5bETN6AjKBGy1302qqzPaCH10QbRg3Wvco79Z8x9WbiE8HYB4e75xl6qUYvQ==",
+ "dev": true,
+ "requires": {
+ "acorn": "^7.0.0",
+ "acorn-jsx": "^5.0.2",
+ "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
+ },
+ "espurify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/espurify/-/espurify-2.0.1.tgz",
+ "integrity": "sha512-7w/dUrReI/QbJFHRwfomTlkQOXaB1NuCrBRn5Y26HXn5gvh18/19AgLbayVrNxXQfkckvgrJloWyvZDuJ7dhEA==",
+ "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
+ },
+ "event-emitter": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
+ "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "~0.10.14"
+ }
+ },
+ "execa": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+ "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^5.0.1",
+ "get-stream": "^3.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^4.0.1",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ }
+ }
+ },
+ "execall": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz",
+ "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==",
+ "dev": true,
+ "requires": {
+ "clone-regexp": "^2.1.0"
+ }
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ }
+ },
+ "expand-tilde": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+ "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+ "dev": true,
+ "requires": {
+ "homedir-polyfill": "^1.0.1"
+ }
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
+ "dev": true
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.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"
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ }
+ }
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
+ "dev": true
+ },
+ "fancy-log": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.3.tgz",
+ "integrity": "sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==",
+ "dev": true,
+ "requires": {
+ "ansi-gray": "^0.1.1",
+ "color-support": "^1.1.3",
+ "parse-node-version": "^1.0.0",
+ "time-stamp": "^1.0.0"
+ }
+ },
+ "fast-deep-equal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+ "dev": true
+ },
+ "fast-diff": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+ "dev": true
+ },
+ "fast-glob": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.0.4.tgz",
+ "integrity": "sha512-wkIbV6qg37xTJwqSsdnIphL1e+LaGz4AIQqr00mIubMaEhv1/HEmJ0uuCGZRNRUkZZmOB5mJKO0ZUTVq+SxMQg==",
+ "dev": true,
+ "requires": {
+ "@nodelib/fs.stat": "^2.0.1",
+ "@nodelib/fs.walk": "^1.2.1",
+ "glob-parent": "^5.0.0",
+ "is-glob": "^4.0.1",
+ "merge2": "^1.2.3",
+ "micromatch": "^4.0.2"
+ },
+ "dependencies": {
+ "glob-parent": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz",
+ "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==",
+ "dev": true,
+ "requires": {
+ "is-glob": "^4.0.1"
+ }
+ },
+ "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"
+ }
+ },
+ "micromatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+ "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.0.5"
+ }
+ }
+ }
+ },
+ "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
+ },
+ "fastq": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz",
+ "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==",
+ "dev": true,
+ "requires": {
+ "reusify": "^1.0.0"
+ }
+ },
+ "figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+ "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-cache-dir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.0.0.tgz",
+ "integrity": "sha512-t7ulV1fmbxh5G9l/492O1p5+EBbr3uwpt6odhFTMc+nWyhmbloe+ja9BZ8pIBtqFWhOmCWVjx+pTW4zDkFoclw==",
+ "dev": true,
+ "requires": {
+ "commondir": "^1.0.1",
+ "make-dir": "^3.0.0",
+ "pkg-dir": "^4.1.0"
+ }
+ },
+ "find-up": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+ "dev": true,
+ "requires": {
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "findup-sync": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz",
+ "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==",
+ "dev": true,
+ "requires": {
+ "detect-file": "^1.0.0",
+ "is-glob": "^4.0.0",
+ "micromatch": "^3.0.4",
+ "resolve-dir": "^1.0.1"
+ }
+ },
+ "fined": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fined/-/fined-1.2.0.tgz",
+ "integrity": "sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "^2.0.2",
+ "is-plain-object": "^2.0.3",
+ "object.defaults": "^1.1.0",
+ "object.pick": "^1.2.0",
+ "parse-filepath": "^1.0.1"
+ }
+ },
+ "flagged-respawn": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.1.tgz",
+ "integrity": "sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==",
+ "dev": true
+ },
+ "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
+ },
+ "flush-write-stream": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz",
+ "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.3.6"
+ }
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+ "dev": true
+ },
+ "for-own": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+ "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
+ "dev": true,
+ "requires": {
+ "for-in": "^1.0.1"
+ }
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
+ "dev": true
+ },
+ "form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "dev": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+ "dev": true,
+ "requires": {
+ "map-cache": "^0.2.2"
+ }
+ },
+ "fs-mkdirp-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz",
+ "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.11",
+ "through2": "^2.0.3"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "fsevents": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz",
+ "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "nan": "^2.12.1",
+ "node-pre-gyp": "^0.12.0"
+ },
+ "dependencies": {
+ "abbrev": {
+ "version": "1.1.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "aproba": {
+ "version": "1.2.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "are-we-there-yet": {
+ "version": "1.1.5",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.6"
+ }
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "chownr": {
+ "version": "1.1.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "debug": {
+ "version": "4.1.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "deep-extend": {
+ "version": "0.6.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "delegates": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "detect-libc": {
+ "version": "1.0.3",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "fs-minipass": {
+ "version": "1.2.5",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "minipass": "^2.2.1"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "gauge": {
+ "version": "2.7.4",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ }
+ },
+ "glob": {
+ "version": "7.1.3",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "ignore-walk": {
+ "version": "3.0.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "minimatch": "^3.0.4"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "ini": {
+ "version": "1.3.5",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "minipass": {
+ "version": "2.3.5",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.0"
+ }
+ },
+ "minizlib": {
+ "version": "1.2.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "minipass": "^2.2.1"
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "ms": {
+ "version": "2.1.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "needle": {
+ "version": "2.3.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "debug": "^4.1.0",
+ "iconv-lite": "^0.4.4",
+ "sax": "^1.2.4"
+ }
+ },
+ "node-pre-gyp": {
+ "version": "0.12.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "detect-libc": "^1.0.2",
+ "mkdirp": "^0.5.1",
+ "needle": "^2.2.1",
+ "nopt": "^4.0.1",
+ "npm-packlist": "^1.1.6",
+ "npmlog": "^4.0.2",
+ "rc": "^1.2.7",
+ "rimraf": "^2.6.1",
+ "semver": "^5.3.0",
+ "tar": "^4"
+ }
+ },
+ "nopt": {
+ "version": "4.0.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "abbrev": "1",
+ "osenv": "^0.1.4"
+ }
+ },
+ "npm-bundled": {
+ "version": "1.0.6",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "npm-packlist": {
+ "version": "1.4.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ignore-walk": "^3.0.1",
+ "npm-bundled": "^1.0.1"
+ }
+ },
+ "npmlog": {
+ "version": "4.1.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.7.3",
+ "set-blocking": "~2.0.0"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "once": {
+ "version": "1.4.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "osenv": {
+ "version": "0.1.5",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.0"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "process-nextick-args": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "rc": {
+ "version": "1.2.8",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.6",
+ "bundled": true,
+ "dev": true,
+ "optional": 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"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.3",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "glob": "^7.1.3"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "sax": {
+ "version": "1.2.4",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "semver": {
+ "version": "5.7.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "tar": {
+ "version": "4.4.8",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "chownr": "^1.1.1",
+ "fs-minipass": "^1.2.5",
+ "minipass": "^2.3.4",
+ "minizlib": "^1.1.1",
+ "mkdirp": "^0.5.0",
+ "safe-buffer": "^5.1.2",
+ "yallist": "^3.0.2"
+ }
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "wide-align": {
+ "version": "1.1.3",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "string-width": "^1.0.2 || 2"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "yallist": {
+ "version": "3.0.3",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ }
+ }
+ },
+ "fstream": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz",
+ "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "inherits": "~2.0.0",
+ "mkdirp": ">=0.5 0",
+ "rimraf": "2"
+ }
+ },
+ "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
+ },
+ "gauge": {
+ "version": "2.7.4",
+ "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+ "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+ "dev": true,
+ "requires": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ }
+ },
+ "gaze": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
+ "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
+ "dev": true,
+ "requires": {
+ "globule": "^1.0.0"
+ }
+ },
+ "get-caller-file": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
+ "dev": true
+ },
+ "get-set-props": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz",
+ "integrity": "sha1-mYR1wXhEVobQsyJG2l3428++jqM=",
+ "dev": true
+ },
+ "get-stdin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+ "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=",
+ "dev": true
+ },
+ "get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+ "dev": true
+ },
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+ "dev": true
+ },
+ "getpass": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+ "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "glob": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+ "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "dev": true,
+ "requires": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ },
+ "glob-stream": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz",
+ "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=",
+ "dev": true,
+ "requires": {
+ "extend": "^3.0.0",
+ "glob": "^7.1.1",
+ "glob-parent": "^3.1.0",
+ "is-negated-glob": "^1.0.0",
+ "ordered-read-streams": "^1.0.0",
+ "pumpify": "^1.3.5",
+ "readable-stream": "^2.1.5",
+ "remove-trailing-separator": "^1.0.1",
+ "to-absolute-glob": "^2.0.0",
+ "unique-stream": "^2.0.2"
+ }
+ },
+ "glob-to-regexp": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz",
+ "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=",
+ "dev": true
+ },
+ "glob-watcher": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.3.tgz",
+ "integrity": "sha512-8tWsULNEPHKQ2MR4zXuzSmqbdyV5PtwwCaWSGQ1WwHsJ07ilNeN1JB8ntxhckbnpSHaf9dXFUHzIWvm1I13dsg==",
+ "dev": true,
+ "requires": {
+ "anymatch": "^2.0.0",
+ "async-done": "^1.2.0",
+ "chokidar": "^2.0.0",
+ "is-negated-glob": "^1.0.0",
+ "just-debounce": "^1.0.0",
+ "object.defaults": "^1.1.0"
+ }
+ },
+ "global-dirs": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
+ "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
+ "dev": true,
+ "requires": {
+ "ini": "^1.3.4"
+ }
+ },
+ "global-modules": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
+ "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+ "dev": true,
+ "requires": {
+ "global-prefix": "^1.0.1",
+ "is-windows": "^1.0.1",
+ "resolve-dir": "^1.0.0"
+ }
+ },
+ "global-prefix": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+ "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "^2.0.2",
+ "homedir-polyfill": "^1.0.1",
+ "ini": "^1.3.4",
+ "is-windows": "^1.0.1",
+ "which": "^1.2.14"
+ }
+ },
+ "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
+ },
+ "globby": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.1.tgz",
+ "integrity": "sha512-sSs4inE1FB2YQiymcmTv6NWENryABjUNPeWhOvmn4SjtKybglsyPZxFB3U1/+L1bYi0rNZDqCLlHyLYDl1Pq5A==",
+ "dev": true,
+ "requires": {
+ "@types/glob": "^7.1.1",
+ "array-union": "^2.1.0",
+ "dir-glob": "^3.0.1",
+ "fast-glob": "^3.0.3",
+ "glob": "^7.1.3",
+ "ignore": "^5.1.1",
+ "merge2": "^1.2.3",
+ "slash": "^3.0.0"
+ }
+ },
+ "globjoin": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz",
+ "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=",
+ "dev": true
+ },
+ "globule": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz",
+ "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==",
+ "dev": true,
+ "requires": {
+ "glob": "~7.1.1",
+ "lodash": "~4.17.10",
+ "minimatch": "~3.0.2"
+ }
+ },
+ "glogg": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.2.tgz",
+ "integrity": "sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==",
+ "dev": true,
+ "requires": {
+ "sparkles": "^1.0.0"
+ }
+ },
+ "gonzales-pe": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.2.4.tgz",
+ "integrity": "sha512-v0Ts/8IsSbh9n1OJRnSfa7Nlxi4AkXIsWB6vPept8FDbL4bXn3FNuxjYtO/nmBGu7GDkL9MFeGebeSu6l55EPQ==",
+ "dev": true,
+ "requires": {
+ "minimist": "1.1.x"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.1.3.tgz",
+ "integrity": "sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag=",
+ "dev": true
+ }
+ }
+ },
+ "got": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz",
+ "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==",
+ "dev": true,
+ "requires": {
+ "@sindresorhus/is": "^0.14.0",
+ "@szmarczak/http-timer": "^1.1.2",
+ "cacheable-request": "^6.0.0",
+ "decompress-response": "^3.3.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^4.1.0",
+ "lowercase-keys": "^1.0.1",
+ "mimic-response": "^1.0.1",
+ "p-cancelable": "^1.0.0",
+ "to-readable-stream": "^1.0.0",
+ "url-parse-lax": "^3.0.0"
+ },
+ "dependencies": {
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ }
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.15",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
+ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==",
+ "dev": true
+ },
+ "gulp": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz",
+ "integrity": "sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==",
+ "dev": true,
+ "requires": {
+ "glob-watcher": "^5.0.3",
+ "gulp-cli": "^2.2.0",
+ "undertaker": "^1.2.1",
+ "vinyl-fs": "^3.0.0"
+ },
+ "dependencies": {
+ "gulp-cli": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.2.0.tgz",
+ "integrity": "sha512-rGs3bVYHdyJpLqR0TUBnlcZ1O5O++Zs4bA0ajm+zr3WFCfiSLjGwoCBqFs18wzN+ZxahT9DkOK5nDf26iDsWjA==",
+ "dev": true,
+ "requires": {
+ "ansi-colors": "^1.0.1",
+ "archy": "^1.0.0",
+ "array-sort": "^1.0.0",
+ "color-support": "^1.1.3",
+ "concat-stream": "^1.6.0",
+ "copy-props": "^2.0.1",
+ "fancy-log": "^1.3.2",
+ "gulplog": "^1.0.0",
+ "interpret": "^1.1.0",
+ "isobject": "^3.0.1",
+ "liftoff": "^3.1.0",
+ "matchdep": "^2.0.0",
+ "mute-stdout": "^1.0.0",
+ "pretty-hrtime": "^1.0.0",
+ "replace-homedir": "^1.0.0",
+ "semver-greatest-satisfied-range": "^1.1.0",
+ "v8flags": "^3.0.1",
+ "yargs": "^7.1.0"
+ }
+ }
+ }
+ },
+ "gulp-autoprefixer": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-autoprefixer/-/gulp-autoprefixer-7.0.0.tgz",
+ "integrity": "sha512-ZGMA/9iPF7kfZIVhznd3eylivBcyLCgcV32cWtvM7j2IjEQzoRg1XaKgCeO5ytutq8XW3Rip+iM4EsVbNshoZw==",
+ "dev": true,
+ "requires": {
+ "autoprefixer": "^9.6.1",
+ "fancy-log": "^1.3.2",
+ "plugin-error": "^1.0.1",
+ "postcss": "^7.0.17",
+ "through2": "^3.0.1",
+ "vinyl-sourcemaps-apply": "^0.2.1"
+ },
+ "dependencies": {
+ "through2": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-3.0.1.tgz",
+ "integrity": "sha512-M96dvTalPT3YbYLaKaCuwu+j06D/8Jfib0o/PxbVt6Amhv3dUAtW6rTV1jPgJSBG83I/e04Y6xkVdVhSRhi0ww==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "2 || 3"
+ }
+ }
+ }
+ },
+ "gulp-postcss": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-postcss/-/gulp-postcss-8.0.0.tgz",
+ "integrity": "sha512-Wtl6vH7a+8IS/fU5W9IbOpcaLqKxd5L1DUOzaPmlnCbX1CrG0aWdwVnC3Spn8th0m8D59YbysV5zPUe1n/GJYg==",
+ "dev": true,
+ "requires": {
+ "fancy-log": "^1.3.2",
+ "plugin-error": "^1.0.1",
+ "postcss": "^7.0.2",
+ "postcss-load-config": "^2.0.0",
+ "vinyl-sourcemaps-apply": "^0.2.1"
+ }
+ },
+ "gulp-rename": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/gulp-rename/-/gulp-rename-1.4.0.tgz",
+ "integrity": "sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg==",
+ "dev": true
+ },
+ "gulp-sass": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-4.0.2.tgz",
+ "integrity": "sha512-q8psj4+aDrblJMMtRxihNBdovfzGrXJp1l4JU0Sz4b/Mhsi2DPrKFYCGDwjIWRENs04ELVHxdOJQ7Vs98OFohg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.3.0",
+ "lodash.clonedeep": "^4.3.2",
+ "node-sass": "^4.8.3",
+ "plugin-error": "^1.0.1",
+ "replace-ext": "^1.0.0",
+ "strip-ansi": "^4.0.0",
+ "through2": "^2.0.0",
+ "vinyl-sourcemaps-apply": "^0.2.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "gulp-sourcemaps": {
+ "version": "2.6.5",
+ "resolved": "https://registry.npmjs.org/gulp-sourcemaps/-/gulp-sourcemaps-2.6.5.tgz",
+ "integrity": "sha512-SYLBRzPTew8T5Suh2U8jCSDKY+4NARua4aqjj8HOysBh2tSgT9u4jc1FYirAdPx1akUxxDeK++fqw6Jg0LkQRg==",
+ "dev": true,
+ "requires": {
+ "@gulp-sourcemaps/identity-map": "1.X",
+ "@gulp-sourcemaps/map-sources": "1.X",
+ "acorn": "5.X",
+ "convert-source-map": "1.X",
+ "css": "2.X",
+ "debug-fabulous": "1.X",
+ "detect-newline": "2.X",
+ "graceful-fs": "4.X",
+ "source-map": "~0.6.0",
+ "strip-bom-string": "1.X",
+ "through2": "2.X"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "5.7.3",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz",
+ "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==",
+ "dev": true
+ },
+ "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
+ }
+ }
+ },
+ "gulplog": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz",
+ "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=",
+ "dev": true,
+ "requires": {
+ "glogg": "^1.0.0"
+ }
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
+ "dev": true
+ },
+ "har-validator": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
+ "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.5.5",
+ "har-schema": "^2.0.0"
+ }
+ },
+ "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-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "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
+ },
+ "has-unicode": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+ "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=",
+ "dev": true
+ },
+ "has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.6",
+ "has-values": "^1.0.0",
+ "isobject": "^3.0.0"
+ }
+ },
+ "has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "kind-of": "^4.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "has-yarn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-2.1.0.tgz",
+ "integrity": "sha512-UqBRqi4ju7T+TqGNdqAO0PaSVGsDGJUBQvk9eUWNGRY1CFGDzYhLWoM7JQEemnlvVcv/YEmc2wNW8BC24EnUsw==",
+ "dev": true
+ },
+ "hex-color-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz",
+ "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==",
+ "dev": true
+ },
+ "homedir-polyfill": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+ "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+ "dev": true,
+ "requires": {
+ "parse-passwd": "^1.0.0"
+ }
+ },
+ "hosted-git-info": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
+ "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==",
+ "dev": true
+ },
+ "hsl-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz",
+ "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=",
+ "dev": true
+ },
+ "hsla-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz",
+ "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=",
+ "dev": true
+ },
+ "html-comment-regex": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz",
+ "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==",
+ "dev": true
+ },
+ "html-tags": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.1.0.tgz",
+ "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==",
+ "dev": true
+ },
+ "htmlparser2": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
+ "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^1.3.1",
+ "domhandler": "^2.3.0",
+ "domutils": "^1.5.1",
+ "entities": "^1.1.1",
+ "inherits": "^2.0.1",
+ "readable-stream": "^3.1.1"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
+ "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ }
+ }
+ },
+ "http-cache-semantics": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.0.3.tgz",
+ "integrity": "sha512-TcIMG3qeVLgDr1TEd2XvHaTnMPwYQUQMIBLy+5pLSDKYFc7UIqj39w8EGzZkaxoLv/l2K8HaI0t5AVA+YYgUew==",
+ "dev": true
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.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": "5.1.4",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
+ "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==",
+ "dev": true
+ },
+ "import-cwd": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz",
+ "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=",
+ "dev": true,
+ "requires": {
+ "import-from": "^2.1.0"
+ }
+ },
+ "import-fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
+ "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
+ "dev": true,
+ "requires": {
+ "caller-path": "^2.0.0",
+ "resolve-from": "^3.0.0"
+ }
+ },
+ "import-from": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz",
+ "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=",
+ "dev": true,
+ "requires": {
+ "resolve-from": "^3.0.0"
+ }
+ },
+ "import-lazy": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
+ "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
+ "dev": true
+ },
+ "import-modules": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-1.1.0.tgz",
+ "integrity": "sha1-dI23nFzEK7lwHvq0JPiU5yYA6dw=",
+ "dev": true
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "in-publish": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
+ "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=",
+ "dev": true
+ },
+ "indent-string": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
+ "dev": true,
+ "requires": {
+ "repeating": "^2.0.0"
+ }
+ },
+ "indexes-of": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
+ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
+ "dev": true
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "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=",
+ "dev": true
+ },
+ "ini": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+ "dev": true
+ },
+ "inquirer": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.5.2.tgz",
+ "integrity": "sha512-cntlB5ghuB0iuO65Ovoi8ogLHiWGs/5yNrtUcKjFhSSiVeAIVpD7koaSU9RM8mpXw5YDi9RdYXGQMaOURB7ycQ==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^3.2.0",
+ "chalk": "^2.4.2",
+ "cli-cursor": "^2.1.0",
+ "cli-width": "^2.0.0",
+ "external-editor": "^3.0.3",
+ "figures": "^2.0.0",
+ "lodash": "^4.17.12",
+ "mute-stream": "0.0.7",
+ "run-async": "^2.2.0",
+ "rxjs": "^6.4.0",
+ "string-width": "^2.1.0",
+ "strip-ansi": "^5.1.0",
+ "through": "^2.3.6"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "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
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.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"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ }
+ }
+ }
+ }
+ },
+ "interpret": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz",
+ "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==",
+ "dev": true
+ },
+ "invert-kv": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
+ "dev": true
+ },
+ "irregular-plurals": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-2.0.0.tgz",
+ "integrity": "sha512-Y75zBYLkh0lJ9qxeHlMjQ7bSbyiSqNW/UOPWDmzC7cXskL1hekSITh1Oc6JV0XCWWZ9DE8VYSB71xocLk3gmGw==",
+ "dev": true
+ },
+ "is-absolute": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
+ "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
+ "dev": true,
+ "requires": {
+ "is-relative": "^1.0.0",
+ "is-windows": "^1.0.1"
+ }
+ },
+ "is-absolute-url": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz",
+ "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=",
+ "dev": true
+ },
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ }
+ },
+ "is-alphabetical": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.3.tgz",
+ "integrity": "sha512-eEMa6MKpHFzw38eKm56iNNi6GJ7lf6aLLio7Kr23sJPAECscgRtZvOBYybejWDQ2bM949Y++61PY+udzj5QMLA==",
+ "dev": true
+ },
+ "is-alphanumeric": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz",
+ "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=",
+ "dev": true
+ },
+ "is-alphanumerical": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.3.tgz",
+ "integrity": "sha512-A1IGAPO5AW9vSh7omxIlOGwIqEvpW/TA+DksVOPM5ODuxKlZS09+TEM1E3275lJqO2oJ38vDpeAL3DCIiHE6eA==",
+ "dev": true,
+ "requires": {
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.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-binary-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+ "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+ "dev": true,
+ "requires": {
+ "binary-extensions": "^1.0.0"
+ }
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "is-callable": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz",
+ "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==",
+ "dev": true
+ },
+ "is-ci": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
+ "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^2.0.0"
+ }
+ },
+ "is-color-stop": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz",
+ "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=",
+ "dev": true,
+ "requires": {
+ "css-color-names": "^0.0.4",
+ "hex-color-regex": "^1.1.0",
+ "hsl-regex": "^1.0.0",
+ "hsla-regex": "^1.0.0",
+ "rgb-regex": "^1.0.1",
+ "rgba-regex": "^1.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ }
+ },
+ "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-decimal": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.3.tgz",
+ "integrity": "sha512-bvLSwoDg2q6Gf+E2LEPiklHZxxiSi3XAh4Mav65mKqTfCO1HM3uBs24TjEH8iJX3bbDdLXKJXBTmGzuTUuAEjQ==",
+ "dev": true
+ },
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
+ "is-directory": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+ "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
+ "dev": true
+ },
+ "is-error": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.2.tgz",
+ "integrity": "sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==",
+ "dev": true
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+ "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-finite": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "dev": true,
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "is-get-set-prop": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz",
+ "integrity": "sha1-JzGHfk14pqae3M5rudaLB3nnYxI=",
+ "dev": true,
+ "requires": {
+ "get-set-props": "^0.1.0",
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "is-glob": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
+ "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-hexadecimal": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.3.tgz",
+ "integrity": "sha512-zxQ9//Q3D/34poZf8fiy3m3XVpbQc7ren15iKqrTtLPwkPD/t3Scy9Imp63FujULGxuK0ZlCwoo5xNpktFgbOA==",
+ "dev": true
+ },
+ "is-installed-globally": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
+ "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
+ "dev": true,
+ "requires": {
+ "global-dirs": "^0.1.0",
+ "is-path-inside": "^1.0.0"
+ },
+ "dependencies": {
+ "is-path-inside": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
+ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
+ "dev": true,
+ "requires": {
+ "path-is-inside": "^1.0.1"
+ }
+ }
+ }
+ },
+ "is-js-type": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz",
+ "integrity": "sha1-c2FwBtZZtOtHKbunR9KHgt8PfiI=",
+ "dev": true,
+ "requires": {
+ "js-types": "^1.0.0"
+ }
+ },
+ "is-negated-glob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
+ "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=",
+ "dev": true
+ },
+ "is-npm": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-3.0.0.tgz",
+ "integrity": "sha512-wsigDr1Kkschp2opC4G3yA6r9EgVA6NjRpWzIi9axXqeIaAATPRJc4uLujXe3Nd9uO8KoDyA4MD6aZSeXTADhA==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ }
+ },
+ "is-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+ "dev": true
+ },
+ "is-obj-prop": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz",
+ "integrity": "sha1-s03nnEULjXxzqyzfZ9yHWtuF+A4=",
+ "dev": true,
+ "requires": {
+ "lowercase-keys": "^1.0.0",
+ "obj-props": "^1.0.0"
+ }
+ },
+ "is-path-cwd": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
+ "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
+ "dev": true
+ },
+ "is-path-inside": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.1.tgz",
+ "integrity": "sha512-CKstxrctq1kUesU6WhtZDbYKzzYBuRH0UYInAVrkc/EYdB9ltbfE0gOoayG9nhohG6447sOOVGhHqsdmBvkbNg==",
+ "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-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "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-proto-prop": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-2.0.0.tgz",
+ "integrity": "sha512-jl3NbQ/fGLv5Jhan4uX+Ge9ohnemqyblWVVCpAvtTQzNFvV2xhJq+esnkIbYQ9F1nITXoLfDDQLp7LBw/zzncg==",
+ "dev": true,
+ "requires": {
+ "lowercase-keys": "^1.0.0",
+ "proto-props": "^2.0.0"
+ }
+ },
+ "is-regex": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+ "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.1"
+ }
+ },
+ "is-regexp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz",
+ "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==",
+ "dev": true
+ },
+ "is-relative": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
+ "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+ "dev": true,
+ "requires": {
+ "is-unc-path": "^1.0.0"
+ }
+ },
+ "is-resolvable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+ "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "dev": true
+ },
+ "is-svg": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz",
+ "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==",
+ "dev": true,
+ "requires": {
+ "html-comment-regex": "^1.1.0"
+ }
+ },
+ "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-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
+ "dev": true
+ },
+ "is-unc-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
+ "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+ "dev": true,
+ "requires": {
+ "unc-path-regex": "^0.1.2"
+ }
+ },
+ "is-utf8": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=",
+ "dev": true
+ },
+ "is-valid-glob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz",
+ "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=",
+ "dev": true
+ },
+ "is-whitespace-character": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.3.tgz",
+ "integrity": "sha512-SNPgMLz9JzPccD3nPctcj8sZlX9DAMJSKH8bP7Z6bohCwuNgX8xbWr1eTAYXX9Vpi/aSn8Y1akL9WgM3t43YNQ==",
+ "dev": true
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true
+ },
+ "is-word-character": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.3.tgz",
+ "integrity": "sha512-0wfcrFgOOOBdgRNT9H33xe6Zi6yhX/uoc4U8NBZGeQQB0ctU1dnlNTyL9JM2646bHDTpsDm1Brb3VPoCIMrd/A==",
+ "dev": true
+ },
+ "is-wsl": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+ "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
+ "dev": true
+ },
+ "is-yarn-global": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/is-yarn-global/-/is-yarn-global-0.3.0.tgz",
+ "integrity": "sha512-VjSeb/lHmkoyd8ryPVIKvOCn4D1koMqY+vqyjjUfc3xyKtP4dYOxM44sZrnqQSzSds3xyOrUTLTC9LVCVgLngw==",
+ "dev": true
+ },
+ "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
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
+ "dev": true
+ },
+ "js-base64": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.5.1.tgz",
+ "integrity": "sha512-M7kLczedRMYX4L8Mdh4MzyAMM9O5osx+4FcOQuTvr3A9F2D9S5JXheN0ewNbrvK2UatkTRhL5ejGmGSjNMiZuw==",
+ "dev": true
+ },
+ "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-types": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz",
+ "integrity": "sha1-0kLmSU7Vcq08koCfyL7X92h8vwM=",
+ "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"
+ }
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
+ "dev": true
+ },
+ "jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true
+ },
+ "json-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz",
+ "integrity": "sha1-Wx85evx11ne96Lz8Dkfh+aPZqJg=",
+ "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-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
+ "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.1.0",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz",
+ "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.0"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ }
+ }
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
+ "just-debounce": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz",
+ "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=",
+ "dev": true
+ },
+ "keyv": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
+ "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==",
+ "dev": true,
+ "requires": {
+ "json-buffer": "3.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ },
+ "known-css-properties": {
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.15.0.tgz",
+ "integrity": "sha512-TS0RCcQfHYsA+59uIHhnsA71NBkpILbqi0W+hde4R5FtESdzur0tCJFoko/1Pbhx+8rmdUc0R1VE4ixnnD+9xw==",
+ "dev": true
+ },
+ "last-run": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz",
+ "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=",
+ "dev": true,
+ "requires": {
+ "default-resolution": "^2.0.0",
+ "es6-weak-map": "^2.0.1"
+ }
+ },
+ "latest-version": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz",
+ "integrity": "sha512-weT+r0kTkRQdCdYCNtkMwWXQTMEswKrFBkm4ckQOMVhhqhIMI1UT2hMj+1iigIhgSZm5gTmrRXBNoGUgaTY1xA==",
+ "dev": true,
+ "requires": {
+ "package-json": "^6.3.0"
+ }
+ },
+ "lazystream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
+ "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.5"
+ }
+ },
+ "lcid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+ "dev": true,
+ "requires": {
+ "invert-kv": "^1.0.0"
+ }
+ },
+ "lead": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz",
+ "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=",
+ "dev": true,
+ "requires": {
+ "flush-write-stream": "^1.0.2"
+ }
+ },
+ "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"
+ }
+ },
+ "liftoff": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-3.1.0.tgz",
+ "integrity": "sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==",
+ "dev": true,
+ "requires": {
+ "extend": "^3.0.0",
+ "findup-sync": "^3.0.0",
+ "fined": "^1.0.1",
+ "flagged-respawn": "^1.0.0",
+ "is-plain-object": "^2.0.4",
+ "object.map": "^1.0.0",
+ "rechoir": "^0.6.2",
+ "resolve": "^1.1.7"
+ }
+ },
+ "line-column-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/line-column-path/-/line-column-path-2.0.0.tgz",
+ "integrity": "sha512-nz3A+vi4bElhwd62E9+Qk/f9BDYLSzD/4Hy1rir0I4GnMxSTezSymzANyph5N1PgRZ3sSbA+yR5hOuXxc71a0Q==",
+ "dev": true,
+ "requires": {
+ "type-fest": "^0.4.1"
+ },
+ "dependencies": {
+ "type-fest": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.4.1.tgz",
+ "integrity": "sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==",
+ "dev": true
+ }
+ }
+ },
+ "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
+ },
+ "load-json-file": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0",
+ "strip-bom": "^2.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ }
+ }
+ },
+ "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"
+ },
+ "dependencies": {
+ "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
+ }
+ }
+ },
+ "lodash": {
+ "version": "4.17.15",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+ "dev": true
+ },
+ "lodash.camelcase": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
+ "dev": true
+ },
+ "lodash.clonedeep": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+ "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=",
+ "dev": true
+ },
+ "lodash.defaultsdeep": {
+ "version": "4.6.1",
+ "resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz",
+ "integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==",
+ "dev": true
+ },
+ "lodash.get": {
+ "version": "4.4.2",
+ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
+ "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=",
+ "dev": true
+ },
+ "lodash.isequal": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
+ "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
+ "dev": true
+ },
+ "lodash.kebabcase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
+ "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=",
+ "dev": true
+ },
+ "lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
+ "dev": true
+ },
+ "lodash.mergewith": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
+ "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
+ "dev": true
+ },
+ "lodash.snakecase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
+ "integrity": "sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40=",
+ "dev": true
+ },
+ "lodash.topairs": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.topairs/-/lodash.topairs-4.3.0.tgz",
+ "integrity": "sha1-O23qo31g+xFnE8RsXxfqGQ7EjWQ=",
+ "dev": true
+ },
+ "lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
+ "dev": true
+ },
+ "lodash.upperfirst": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz",
+ "integrity": "sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=",
+ "dev": true
+ },
+ "lodash.zip": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.zip/-/lodash.zip-4.2.0.tgz",
+ "integrity": "sha1-7GZi5IlkCO1KtsVCo5kLcswIACA=",
+ "dev": true
+ },
+ "log-symbols": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
+ "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.2"
+ }
+ },
+ "longest-streak": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.3.tgz",
+ "integrity": "sha512-9lz5IVdpwsKLMzQi0MQ+oD9EA0mIGcWYP7jXMTZVXP8D42PwuAk+M/HBFYQoxt1G5OR8m7aSIgb1UymfWGBWEw==",
+ "dev": true
+ },
+ "loud-rejection": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+ "dev": true,
+ "requires": {
+ "currently-unhandled": "^0.4.1",
+ "signal-exit": "^3.0.0"
+ }
+ },
+ "lowercase-keys": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+ "dev": true
+ },
+ "lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "lru-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz",
+ "integrity": "sha1-Jzi9nw089PhEkMVzbEhpmsYyzaM=",
+ "dev": true,
+ "requires": {
+ "es5-ext": "~0.10.2"
+ }
+ },
+ "make-dir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz",
+ "integrity": "sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==",
+ "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
+ }
+ }
+ },
+ "make-iterator": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
+ "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ }
+ }
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+ "dev": true
+ },
+ "map-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
+ "dev": true
+ },
+ "map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+ "dev": true,
+ "requires": {
+ "object-visit": "^1.0.0"
+ }
+ },
+ "markdown-escapes": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.3.tgz",
+ "integrity": "sha512-XUi5HJhhV5R74k8/0H2oCbCiYf/u4cO/rX8tnGkRvrqhsr5BRNU6Mg0yt/8UIx1iIS8220BNJsDb7XnILhLepw==",
+ "dev": true
+ },
+ "markdown-table": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz",
+ "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==",
+ "dev": true
+ },
+ "matchdep": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz",
+ "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=",
+ "dev": true,
+ "requires": {
+ "findup-sync": "^2.0.0",
+ "micromatch": "^3.0.4",
+ "resolve": "^1.4.0",
+ "stack-trace": "0.0.10"
+ },
+ "dependencies": {
+ "findup-sync": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
+ "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=",
+ "dev": true,
+ "requires": {
+ "detect-file": "^1.0.0",
+ "is-glob": "^3.1.0",
+ "micromatch": "^3.0.4",
+ "resolve-dir": "^1.0.1"
+ }
+ },
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ },
+ "mathml-tag-names": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.1.tgz",
+ "integrity": "sha512-pWB896KPGSGkp1XtyzRBftpTzwSOL0Gfk0wLvxt4f2mgzjY19o0LxJ3U25vNWTzsh7da+KTbuXQoQ3lOJZ8WHw==",
+ "dev": true
+ },
+ "mdast-util-compact": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.3.tgz",
+ "integrity": "sha512-nRiU5GpNy62rZppDKbLwhhtw5DXoFMqw9UNZFmlPsNaQCZ//WLjGKUwWMdJrUH+Se7UvtO2gXtAMe0g/N+eI5w==",
+ "dev": true,
+ "requires": {
+ "unist-util-visit": "^1.1.0"
+ }
+ },
+ "mdn-data": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz",
+ "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==",
+ "dev": true
+ },
+ "memoizee": {
+ "version": "0.4.14",
+ "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.14.tgz",
+ "integrity": "sha512-/SWFvWegAIYAO4NQMpcX+gcra0yEZu4OntmUdrBaWrJncxOqAziGFlHxc7yjKVK2uu3lpPW27P27wkR82wA8mg==",
+ "dev": true,
+ "requires": {
+ "d": "1",
+ "es5-ext": "^0.10.45",
+ "es6-weak-map": "^2.0.2",
+ "event-emitter": "^0.3.5",
+ "is-promise": "^2.1",
+ "lru-queue": "0.1",
+ "next-tick": "1",
+ "timers-ext": "^0.1.5"
+ }
+ },
+ "meow": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+ "dev": true,
+ "requires": {
+ "camelcase-keys": "^2.0.0",
+ "decamelize": "^1.1.2",
+ "loud-rejection": "^1.0.0",
+ "map-obj": "^1.0.1",
+ "minimist": "^1.1.3",
+ "normalize-package-data": "^2.3.4",
+ "object-assign": "^4.0.1",
+ "read-pkg-up": "^1.0.1",
+ "redent": "^1.0.0",
+ "trim-newlines": "^1.0.0"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ }
+ }
+ },
+ "merge2": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz",
+ "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==",
+ "dev": true
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ },
+ "dependencies": {
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+ "dev": true
+ }
+ }
+ },
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ }
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+ "dev": true
+ }
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ }
+ }
+ }
+ },
+ "mime-db": {
+ "version": "1.40.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
+ "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
+ "dev": true
+ },
+ "mime-types": {
+ "version": "2.1.24",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
+ "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
+ "dev": true,
+ "requires": {
+ "mime-db": "1.40.0"
+ }
+ },
+ "mimic-fn": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+ "dev": true
+ },
+ "mimic-response": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz",
+ "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
+ "dev": true
+ },
+ "minimist-options": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz",
+ "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==",
+ "dev": true,
+ "requires": {
+ "arrify": "^1.0.1",
+ "is-plain-obj": "^1.1.0"
+ }
+ },
+ "mixin-deep": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz",
+ "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==",
+ "dev": true,
+ "requires": {
+ "for-in": "^1.0.2",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "multimap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/multimap/-/multimap-1.0.2.tgz",
+ "integrity": "sha1-aqdvwyM5BbqUi75MdNwsOgNW6zY=",
+ "dev": true
+ },
+ "multimatch": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz",
+ "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==",
+ "dev": true,
+ "requires": {
+ "@types/minimatch": "^3.0.3",
+ "array-differ": "^3.0.0",
+ "array-union": "^2.1.0",
+ "arrify": "^2.0.1",
+ "minimatch": "^3.0.4"
+ },
+ "dependencies": {
+ "arrify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
+ "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
+ "dev": true
+ }
+ }
+ },
+ "mute-stdout": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz",
+ "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==",
+ "dev": true
+ },
+ "mute-stream": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
+ "dev": true
+ },
+ "nan": {
+ "version": "2.14.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
+ "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==",
+ "dev": true
+ },
+ "nanomatch": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "fragment-cache": "^0.2.1",
+ "is-windows": "^1.0.2",
+ "kind-of": "^6.0.2",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ }
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "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
+ },
+ "next-tick": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
+ "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-gyp": {
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
+ "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==",
+ "dev": true,
+ "requires": {
+ "fstream": "^1.0.0",
+ "glob": "^7.0.3",
+ "graceful-fs": "^4.1.2",
+ "mkdirp": "^0.5.0",
+ "nopt": "2 || 3",
+ "npmlog": "0 || 1 || 2 || 3 || 4",
+ "osenv": "0",
+ "request": "^2.87.0",
+ "rimraf": "2",
+ "semver": "~5.3.0",
+ "tar": "^2.0.0",
+ "which": "1"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+ "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=",
+ "dev": true
+ }
+ }
+ },
+ "node-releases": {
+ "version": "1.1.27",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.27.tgz",
+ "integrity": "sha512-9iXUqHKSGo6ph/tdXVbHFbhRVQln4ZDTIBJCzsa90HimnBYc5jw8RWYt4wBYFHehGyC3koIz5O4mb2fHrbPOuA==",
+ "dev": true,
+ "requires": {
+ "semver": "^5.3.0"
+ }
+ },
+ "node-sass": {
+ "version": "4.12.0",
+ "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.12.0.tgz",
+ "integrity": "sha512-A1Iv4oN+Iel6EPv77/HddXErL2a+gZ4uBeZUy+a8O35CFYTXhgA8MgLCWBtwpGZdCvTvQ9d+bQxX/QC36GDPpQ==",
+ "dev": true,
+ "requires": {
+ "async-foreach": "^0.1.3",
+ "chalk": "^1.1.1",
+ "cross-spawn": "^3.0.0",
+ "gaze": "^1.0.0",
+ "get-stdin": "^4.0.1",
+ "glob": "^7.0.3",
+ "in-publish": "^2.0.0",
+ "lodash": "^4.17.11",
+ "meow": "^3.7.0",
+ "mkdirp": "^0.5.1",
+ "nan": "^2.13.2",
+ "node-gyp": "^3.8.0",
+ "npmlog": "^4.0.0",
+ "request": "^2.88.0",
+ "sass-graph": "^2.2.4",
+ "stdout-stream": "^1.4.0",
+ "true-case-path": "^1.0.2"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "nopt": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1"
+ }
+ },
+ "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": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "dev": true,
+ "requires": {
+ "remove-trailing-separator": "^1.0.1"
+ }
+ },
+ "normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
+ "dev": true
+ },
+ "normalize-selector": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz",
+ "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=",
+ "dev": true
+ },
+ "normalize-url": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz",
+ "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==",
+ "dev": true
+ },
+ "now-and-later": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz",
+ "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.2"
+ }
+ },
+ "npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+ "dev": true,
+ "requires": {
+ "path-key": "^2.0.0"
+ }
+ },
+ "npmlog": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+ "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+ "dev": true,
+ "requires": {
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.7.3",
+ "set-blocking": "~2.0.0"
+ }
+ },
+ "nth-check": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
+ "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==",
+ "dev": true,
+ "requires": {
+ "boolbase": "~1.0.0"
+ }
+ },
+ "num2fraction": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
+ "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
+ "dev": true
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
+ "dev": true
+ },
+ "obj-props": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.2.0.tgz",
+ "integrity": "sha512-ZYpJyCe7O4rhNxB/2SZy8ADJww8RSRBdG36a4MWWq7JwILGJ1m61B90QJtxwDDNA0KzyR8V12Wikpjuux7Gl9Q==",
+ "dev": true
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=",
+ "dev": true
+ },
+ "object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+ "dev": true,
+ "requires": {
+ "copy-descriptor": "^0.1.0",
+ "define-property": "^0.2.5",
+ "kind-of": "^3.0.3"
+ }
+ },
+ "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
+ },
+ "object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.0"
+ }
+ },
+ "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.defaults": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
+ "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=",
+ "dev": true,
+ "requires": {
+ "array-each": "^1.0.1",
+ "array-slice": "^1.0.0",
+ "for-own": "^1.0.0",
+ "isobject": "^3.0.0"
+ }
+ },
+ "object.getownpropertydescriptors": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz",
+ "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.2",
+ "es-abstract": "^1.5.1"
+ }
+ },
+ "object.map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
+ "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=",
+ "dev": true,
+ "requires": {
+ "for-own": "^1.0.0",
+ "make-iterator": "^1.0.0"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "object.reduce": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz",
+ "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=",
+ "dev": true,
+ "requires": {
+ "for-own": "^1.0.0",
+ "make-iterator": "^1.0.0"
+ }
+ },
+ "object.values": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.0.tgz",
+ "integrity": "sha512-8mf0nKLAoFX6VlNVdhGj31SVYpaNFtUnuoOXWyFEstsWRgU837AK+JYM0iAxwkSzGRbwn8cbFmgbyxj1j4VbXg==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.3",
+ "es-abstract": "^1.12.0",
+ "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=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^1.0.0"
+ }
+ },
+ "open": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/open/-/open-6.4.0.tgz",
+ "integrity": "sha512-IFenVPgF70fSm1keSd2iDBIDIBZkroLeuffXq+wKTzTJlBpesFWojV9lb8mzOfaAzM1sr7HQHuO0vtV0zYekGg==",
+ "dev": true,
+ "requires": {
+ "is-wsl": "^1.1.0"
+ }
+ },
+ "open-editor": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/open-editor/-/open-editor-2.0.1.tgz",
+ "integrity": "sha512-B3KdD7Pl8jYdpBSBBbdYaqVUI3whQjLl1G1+CvhNc8+d7GzKRUq+VuCIx1thxGiqD2oBGRvsZz7QWrBsFP2yVA==",
+ "dev": true,
+ "requires": {
+ "env-editor": "^0.4.0",
+ "line-column-path": "^2.0.0",
+ "open": "^6.2.0"
+ }
+ },
+ "optionator": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+ "dev": true,
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.4",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "wordwrap": "~1.0.0"
+ }
+ },
+ "ordered-read-streams": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz",
+ "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.1"
+ }
+ },
+ "os-homedir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+ "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=",
+ "dev": true
+ },
+ "os-locale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+ "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+ "dev": true,
+ "requires": {
+ "lcid": "^1.0.0"
+ }
+ },
+ "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
+ },
+ "osenv": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
+ "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
+ "dev": true,
+ "requires": {
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.0"
+ }
+ },
+ "p-cancelable": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz",
+ "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==",
+ "dev": true
+ },
+ "p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+ "dev": true
+ },
+ "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-map": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz",
+ "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==",
+ "dev": true,
+ "requires": {
+ "aggregate-error": "^3.0.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
+ },
+ "package-json": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/package-json/-/package-json-6.5.0.tgz",
+ "integrity": "sha512-k3bdm2n25tkyxcjSKzB5x8kfVxlMdgsbPr0GkZcwHsLpba6cBjqCt1KlcChKEvxHIcTB1FVMuwoijZ26xex5MQ==",
+ "dev": true,
+ "requires": {
+ "got": "^9.6.0",
+ "registry-auth-token": "^4.0.0",
+ "registry-url": "^5.0.0",
+ "semver": "^6.2.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
+ }
+ }
+ },
+ "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"
+ },
+ "dependencies": {
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ }
+ }
+ },
+ "parse-entities": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz",
+ "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==",
+ "dev": true,
+ "requires": {
+ "character-entities": "^1.0.0",
+ "character-entities-legacy": "^1.0.0",
+ "character-reference-invalid": "^1.0.0",
+ "is-alphanumerical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-hexadecimal": "^1.0.0"
+ }
+ },
+ "parse-filepath": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
+ "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=",
+ "dev": true,
+ "requires": {
+ "is-absolute": "^1.0.0",
+ "map-cache": "^0.2.0",
+ "path-root": "^0.1.1"
+ }
+ },
+ "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"
+ }
+ },
+ "parse-node-version": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parse-node-version/-/parse-node-version-1.0.1.tgz",
+ "integrity": "sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==",
+ "dev": true
+ },
+ "parse-passwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+ "dev": true
+ },
+ "pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+ "dev": true
+ },
+ "path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+ "dev": true,
+ "requires": {
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "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=",
+ "dev": true
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+ "dev": true
+ },
+ "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.6",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
+ "dev": true
+ },
+ "path-root": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
+ "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=",
+ "dev": true,
+ "requires": {
+ "path-root-regex": "^0.1.0"
+ }
+ },
+ "path-root-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
+ "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=",
+ "dev": true
+ },
+ "path-type": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+ "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ }
+ }
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
+ "dev": true
+ },
+ "picomatch": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz",
+ "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==",
+ "dev": true
+ },
+ "pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "dev": true
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
+ "dev": true
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+ "dev": true,
+ "requires": {
+ "pinkie": "^2.0.0"
+ }
+ },
+ "pkg-conf": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-3.1.0.tgz",
+ "integrity": "sha512-m0OTbR/5VPNPqO1ph6Fqbj7Hv6QU7gR/tQW40ZqrL1rjgCU85W6C1bJn0BItuJqnR98PWzw7Z8hHeChD1WrgdQ==",
+ "dev": true,
+ "requires": {
+ "find-up": "^3.0.0",
+ "load-json-file": "^5.2.0"
+ },
+ "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"
+ }
+ },
+ "load-json-file": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-5.3.0.tgz",
+ "integrity": "sha512-cJGP40Jc/VXUsp8/OrnyKyTZ1y6v/dphm3bioS+RrKXjK2BB6wHUd6JptZEFDGgGahMT+InnZO5i1Ei9mpC8Bw==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.15",
+ "parse-json": "^4.0.0",
+ "pify": "^4.0.1",
+ "strip-bom": "^3.0.0",
+ "type-fest": "^0.3.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-limit": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz",
+ "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==",
+ "dev": true,
+ "requires": {
+ "p-try": "^2.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"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "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-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=",
+ "dev": true
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ },
+ "type-fest": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.3.1.tgz",
+ "integrity": "sha512-cUGJnCdr4STbePCgqNFbpVNCepa+kAVohJs1sLhxzdH+gnEoOd8VhbYa7pD3zZYGiURWM2xzEII3fQcRizDkYQ==",
+ "dev": true
+ }
+ }
+ },
+ "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"
+ },
+ "dependencies": {
+ "find-up": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+ "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+ "dev": true,
+ "requires": {
+ "locate-path": "^5.0.0",
+ "path-exists": "^4.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==",
+ "dev": true,
+ "requires": {
+ "p-locate": "^4.1.0"
+ }
+ },
+ "p-limit": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.1.tgz",
+ "integrity": "sha512-85Tk+90UCVWvbDavCLKPOLC9vvY8OwEX/RtKF+/1OADJMVlFfEHOiMTPVyxg7mk/dKa+ipdHm0OUkTvCpMTuwg==",
+ "dev": true,
+ "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==",
+ "dev": true,
+ "requires": {
+ "p-limit": "^2.2.0"
+ }
+ },
+ "p-try": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+ "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+ "dev": true
+ },
+ "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
+ }
+ }
+ },
+ "plugin-error": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz",
+ "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==",
+ "dev": true,
+ "requires": {
+ "ansi-colors": "^1.0.1",
+ "arr-diff": "^4.0.0",
+ "arr-union": "^3.1.0",
+ "extend-shallow": "^3.0.2"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "plur": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/plur/-/plur-3.1.1.tgz",
+ "integrity": "sha512-t1Ax8KUvV3FFII8ltczPn2tJdjqbd1sIzu6t4JL7nQ3EyeL/lTrj5PWKb06ic5/6XYDr65rQ4uzQEGN70/6X5w==",
+ "dev": true,
+ "requires": {
+ "irregular-plurals": "^2.0.0"
+ }
+ },
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.17",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.17.tgz",
+ "integrity": "sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.2",
+ "source-map": "^0.6.1",
+ "supports-color": "^6.1.0"
+ },
+ "dependencies": {
+ "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
+ },
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "postcss-calc": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.1.tgz",
+ "integrity": "sha512-oXqx0m6tb4N3JGdmeMSc/i91KppbYsFZKdH0xMOqK8V1rJlzrKlTdokz8ozUXLVejydRN6u2IddxpcijRj2FqQ==",
+ "dev": true,
+ "requires": {
+ "css-unit-converter": "^1.1.1",
+ "postcss": "^7.0.5",
+ "postcss-selector-parser": "^5.0.0-rc.4",
+ "postcss-value-parser": "^3.3.1"
+ },
+ "dependencies": {
+ "postcss-selector-parser": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-5.0.0.tgz",
+ "integrity": "sha512-w+zLE5Jhg6Liz8+rQOWEAwtwkyqpfnmsinXjXg6cY7YIONZZtgvE0v2O0uhQBs0peNomOJwWRKt6JBfTdTd3OQ==",
+ "dev": true,
+ "requires": {
+ "cssesc": "^2.0.0",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ }
+ }
+ },
+ "postcss-colormin": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz",
+ "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.0.0",
+ "color": "^3.0.0",
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ }
+ },
+ "postcss-convert-values": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz",
+ "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ }
+ },
+ "postcss-discard-comments": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz",
+ "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ }
+ },
+ "postcss-discard-duplicates": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz",
+ "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ }
+ },
+ "postcss-discard-empty": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz",
+ "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ }
+ },
+ "postcss-discard-overridden": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz",
+ "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ }
+ },
+ "postcss-html": {
+ "version": "0.36.0",
+ "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz",
+ "integrity": "sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==",
+ "dev": true,
+ "requires": {
+ "htmlparser2": "^3.10.0"
+ }
+ },
+ "postcss-import": {
+ "version": "12.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-import/-/postcss-import-12.0.1.tgz",
+ "integrity": "sha512-3Gti33dmCjyKBgimqGxL3vcV8w9+bsHwO5UrBawp796+jdardbcFl4RP5w/76BwNL7aGzpKstIfF9I+kdE8pTw==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.1",
+ "postcss-value-parser": "^3.2.3",
+ "read-cache": "^1.0.0",
+ "resolve": "^1.1.7"
+ }
+ },
+ "postcss-jsx": {
+ "version": "0.36.3",
+ "resolved": "https://registry.npmjs.org/postcss-jsx/-/postcss-jsx-0.36.3.tgz",
+ "integrity": "sha512-yV8Ndo6KzU8eho5mCn7LoLUGPkXrRXRjhMpX4AaYJ9wLJPv099xbtpbRQ8FrPnzVxb/cuMebbPR7LweSt+hTfA==",
+ "dev": true,
+ "requires": {
+ "@babel/core": ">=7.2.2"
+ }
+ },
+ "postcss-less": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz",
+ "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.14"
+ }
+ },
+ "postcss-load-config": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz",
+ "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==",
+ "dev": true,
+ "requires": {
+ "cosmiconfig": "^5.0.0",
+ "import-cwd": "^2.0.0"
+ },
+ "dependencies": {
+ "cosmiconfig": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+ "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+ "dev": true,
+ "requires": {
+ "import-fresh": "^2.0.0",
+ "is-directory": "^0.3.1",
+ "js-yaml": "^3.13.1",
+ "parse-json": "^4.0.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
+ },
+ "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"
+ }
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "postcss-markdown": {
+ "version": "0.36.0",
+ "resolved": "https://registry.npmjs.org/postcss-markdown/-/postcss-markdown-0.36.0.tgz",
+ "integrity": "sha512-rl7fs1r/LNSB2bWRhyZ+lM/0bwKv9fhl38/06gF6mKMo/NPnp55+K1dSTosSVjFZc0e1ppBlu+WT91ba0PMBfQ==",
+ "dev": true,
+ "requires": {
+ "remark": "^10.0.1",
+ "unist-util-find-all-after": "^1.0.2"
+ }
+ },
+ "postcss-media-query-parser": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz",
+ "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=",
+ "dev": true
+ },
+ "postcss-merge-longhand": {
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz",
+ "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==",
+ "dev": true,
+ "requires": {
+ "css-color-names": "0.0.4",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0",
+ "stylehacks": "^4.0.0"
+ },
+ "dependencies": {
+ "postcss-selector-parser": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz",
+ "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=",
+ "dev": true,
+ "requires": {
+ "dot-prop": "^4.1.1",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ },
+ "stylehacks": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz",
+ "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-selector-parser": "^3.0.0"
+ }
+ }
+ }
+ },
+ "postcss-merge-rules": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz",
+ "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.0.0",
+ "caniuse-api": "^3.0.0",
+ "cssnano-util-same-parent": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-selector-parser": "^3.0.0",
+ "vendors": "^1.0.0"
+ },
+ "dependencies": {
+ "postcss-selector-parser": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz",
+ "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=",
+ "dev": true,
+ "requires": {
+ "dot-prop": "^4.1.1",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ }
+ }
+ },
+ "postcss-minify-font-values": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz",
+ "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ }
+ },
+ "postcss-minify-gradients": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz",
+ "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==",
+ "dev": true,
+ "requires": {
+ "cssnano-util-get-arguments": "^4.0.0",
+ "is-color-stop": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ }
+ },
+ "postcss-minify-params": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz",
+ "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==",
+ "dev": true,
+ "requires": {
+ "alphanum-sort": "^1.0.0",
+ "browserslist": "^4.0.0",
+ "cssnano-util-get-arguments": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0",
+ "uniqs": "^2.0.0"
+ }
+ },
+ "postcss-minify-selectors": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz",
+ "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==",
+ "dev": true,
+ "requires": {
+ "alphanum-sort": "^1.0.0",
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-selector-parser": "^3.0.0"
+ },
+ "dependencies": {
+ "postcss-selector-parser": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz",
+ "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=",
+ "dev": true,
+ "requires": {
+ "dot-prop": "^4.1.1",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ }
+ }
+ },
+ "postcss-normalize-charset": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz",
+ "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ }
+ },
+ "postcss-normalize-display-values": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz",
+ "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==",
+ "dev": true,
+ "requires": {
+ "cssnano-util-get-match": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ }
+ },
+ "postcss-normalize-positions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz",
+ "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==",
+ "dev": true,
+ "requires": {
+ "cssnano-util-get-arguments": "^4.0.0",
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ }
+ },
+ "postcss-normalize-repeat-style": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz",
+ "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==",
+ "dev": true,
+ "requires": {
+ "cssnano-util-get-arguments": "^4.0.0",
+ "cssnano-util-get-match": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ }
+ },
+ "postcss-normalize-string": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz",
+ "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==",
+ "dev": true,
+ "requires": {
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ }
+ },
+ "postcss-normalize-timing-functions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz",
+ "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==",
+ "dev": true,
+ "requires": {
+ "cssnano-util-get-match": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ }
+ },
+ "postcss-normalize-unicode": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz",
+ "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ }
+ },
+ "postcss-normalize-url": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz",
+ "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==",
+ "dev": true,
+ "requires": {
+ "is-absolute-url": "^2.0.0",
+ "normalize-url": "^3.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ }
+ },
+ "postcss-normalize-whitespace": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz",
+ "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ }
+ },
+ "postcss-ordered-values": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz",
+ "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==",
+ "dev": true,
+ "requires": {
+ "cssnano-util-get-arguments": "^4.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ }
+ },
+ "postcss-pxtorem": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-pxtorem/-/postcss-pxtorem-4.0.1.tgz",
+ "integrity": "sha1-nGTQ7+SIVHPMHLAwXG/8PrtFsc0=",
+ "dev": true,
+ "requires": {
+ "object-assign": "^4.1.0",
+ "postcss": "^5.2.10"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.1.3",
+ "js-base64": "^2.1.9",
+ "source-map": "^0.5.6",
+ "supports-color": "^3.2.3"
+ }
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "dev": true,
+ "requires": {
+ "has-flag": "^1.0.0"
+ }
+ }
+ }
+ },
+ "postcss-reduce-initial": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz",
+ "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.0.0",
+ "caniuse-api": "^3.0.0",
+ "has": "^1.0.0",
+ "postcss": "^7.0.0"
+ }
+ },
+ "postcss-reduce-transforms": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz",
+ "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==",
+ "dev": true,
+ "requires": {
+ "cssnano-util-get-match": "^4.0.0",
+ "has": "^1.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0"
+ }
+ },
+ "postcss-reporter": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-6.0.1.tgz",
+ "integrity": "sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "lodash": "^4.17.11",
+ "log-symbols": "^2.2.0",
+ "postcss": "^7.0.7"
+ },
+ "dependencies": {
+ "log-symbols": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
+ "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.0.1"
+ }
+ }
+ }
+ },
+ "postcss-resolve-nested-selector": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz",
+ "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=",
+ "dev": true
+ },
+ "postcss-safe-parser": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.1.tgz",
+ "integrity": "sha512-xZsFA3uX8MO3yAda03QrG3/Eg1LN3EPfjjf07vke/46HERLZyHrTsQ9E1r1w1W//fWEhtYNndo2hQplN2cVpCQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ }
+ },
+ "postcss-sass": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.4.1.tgz",
+ "integrity": "sha512-YDdykeDHylqiD2CdXuP7K1aDz7hCflGVB6H6lqabWVab5mVOWhguUuWZYpFU22/E12AEGiMlOfZnLqr343zhVA==",
+ "dev": true,
+ "requires": {
+ "gonzales-pe": "^4.2.4",
+ "postcss": "^7.0.14"
+ }
+ },
+ "postcss-scss": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.0.0.tgz",
+ "integrity": "sha512-um9zdGKaDZirMm+kZFKKVsnKPF7zF7qBAtIfTSnZXD1jZ0JNZIxdB6TxQOjCnlSzLRInVl2v3YdBh/M881C4ug==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ }
+ },
+ "postcss-selector-parser": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz",
+ "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=",
+ "dev": true,
+ "requires": {
+ "dot-prop": "^4.1.1",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ },
+ "postcss-sorting": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-5.0.1.tgz",
+ "integrity": "sha512-Y9fUFkIhfrm6i0Ta3n+89j56EFqaNRdUKqXyRp6kvTcSXnmgEjaVowCXH+JBe9+YKWqd4nc28r2sgwnzJalccA==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.14",
+ "postcss": "^7.0.17"
+ },
+ "dependencies": {
+ "lodash": {
+ "version": "4.17.15",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
+ "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
+ "dev": true
+ }
+ }
+ },
+ "postcss-svgo": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz",
+ "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==",
+ "dev": true,
+ "requires": {
+ "is-svg": "^3.0.0",
+ "postcss": "^7.0.0",
+ "postcss-value-parser": "^3.0.0",
+ "svgo": "^1.0.0"
+ }
+ },
+ "postcss-syntax": {
+ "version": "0.36.2",
+ "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz",
+ "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==",
+ "dev": true
+ },
+ "postcss-unique-selectors": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz",
+ "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==",
+ "dev": true,
+ "requires": {
+ "alphanum-sort": "^1.0.0",
+ "postcss": "^7.0.0",
+ "uniqs": "^2.0.0"
+ }
+ },
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ },
+ "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
+ },
+ "prepend-http": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz",
+ "integrity": "sha1-6SQ0v6XqjBn0HN/UAddBo8gZ2Jc=",
+ "dev": true
+ },
+ "prettier": {
+ "version": "1.18.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.18.2.tgz",
+ "integrity": "sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==",
+ "dev": true
+ },
+ "prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "dev": true,
+ "requires": {
+ "fast-diff": "^1.1.2"
+ }
+ },
+ "pretty-hrtime": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
+ "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
+ "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
+ },
+ "proto-props": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/proto-props/-/proto-props-2.0.0.tgz",
+ "integrity": "sha512-2yma2tog9VaRZY2mn3Wq51uiSW4NcPYT1cQdBagwyrznrilKSZwIZ0UG3ZPL/mx+axEns0hE35T5ufOYZXEnBQ==",
+ "dev": true
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+ "dev": true
+ },
+ "psl": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.3.0.tgz",
+ "integrity": "sha512-avHdspHO+9rQTLbv1RO+MPYeP/SzsCoxofjVnHanETfQhTJrmB0HlDoW+EiN/R+C0BZ+gERab9NY0lPN2TxNag==",
+ "dev": true
+ },
+ "pump": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "pumpify": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+ "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+ "dev": true,
+ "requires": {
+ "duplexify": "^3.6.0",
+ "inherits": "^2.0.3",
+ "pump": "^2.0.0"
+ }
+ },
+ "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
+ },
+ "qs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
+ "dev": true
+ },
+ "quick-lru": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz",
+ "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=",
+ "dev": true
+ },
+ "rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "dev": true,
+ "requires": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+ "dev": true
+ }
+ }
+ },
+ "read-cache": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
+ "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
+ "dev": true,
+ "requires": {
+ "pify": "^2.3.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
+ "dev": true
+ }
+ }
+ },
+ "read-pkg": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^1.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^1.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+ "dev": true,
+ "requires": {
+ "find-up": "^1.0.0",
+ "read-pkg": "^1.0.0"
+ }
+ },
+ "readable-stream": {
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "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"
+ },
+ "dependencies": {
+ "process-nextick-args": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==",
+ "dev": true
+ }
+ }
+ },
+ "readdirp": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+ "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.11",
+ "micromatch": "^3.1.10",
+ "readable-stream": "^2.0.2"
+ }
+ },
+ "rechoir": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+ "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
+ "dev": true,
+ "requires": {
+ "resolve": "^1.1.6"
+ }
+ },
+ "redent": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
+ "dev": true,
+ "requires": {
+ "indent-string": "^2.1.0",
+ "strip-indent": "^1.0.1"
+ }
+ },
+ "regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "regexp-tree": {
+ "version": "0.1.14",
+ "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.14.tgz",
+ "integrity": "sha512-59v5A90TAh4cAMyDQEOzcnsu4q7Wb10RsyTjngEnJIZsWYM4siVGu+JmLT1WsxHvOWhiu4YS20XiTuxWMeVoHQ==",
+ "dev": true
+ },
+ "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
+ },
+ "registry-auth-token": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-4.0.0.tgz",
+ "integrity": "sha512-lpQkHxd9UL6tb3k/aHAVfnVtn+Bcs9ob5InuFLLEDqSqeq+AljB8GZW9xY0x7F+xYwEcjKe07nyoxzEYz6yvkw==",
+ "dev": true,
+ "requires": {
+ "rc": "^1.2.8",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "registry-url": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-5.1.0.tgz",
+ "integrity": "sha512-8acYXXTI0AkQv6RAOjE3vOaIXZkT9wo4LOFbBKYQEEnnMNBpKqdUrI6S4NT0KPIo/WVvJ5tE/X5LF/TQUf0ekw==",
+ "dev": true,
+ "requires": {
+ "rc": "^1.2.8"
+ }
+ },
+ "remark": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/remark/-/remark-10.0.1.tgz",
+ "integrity": "sha512-E6lMuoLIy2TyiokHprMjcWNJ5UxfGQjaMSMhV+f4idM625UjjK4j798+gPs5mfjzDE6vL0oFKVeZM6gZVSVrzQ==",
+ "dev": true,
+ "requires": {
+ "remark-parse": "^6.0.0",
+ "remark-stringify": "^6.0.0",
+ "unified": "^7.0.0"
+ }
+ },
+ "remark-parse": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-6.0.3.tgz",
+ "integrity": "sha512-QbDXWN4HfKTUC0hHa4teU463KclLAnwpn/FBn87j9cKYJWWawbiLgMfP2Q4XwhxxuuuOxHlw+pSN0OKuJwyVvg==",
+ "dev": true,
+ "requires": {
+ "collapse-white-space": "^1.0.2",
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-whitespace-character": "^1.0.0",
+ "is-word-character": "^1.0.0",
+ "markdown-escapes": "^1.0.0",
+ "parse-entities": "^1.1.0",
+ "repeat-string": "^1.5.4",
+ "state-toggle": "^1.0.0",
+ "trim": "0.0.1",
+ "trim-trailing-lines": "^1.0.0",
+ "unherit": "^1.0.4",
+ "unist-util-remove-position": "^1.0.0",
+ "vfile-location": "^2.0.0",
+ "xtend": "^4.0.1"
+ }
+ },
+ "remark-stringify": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-6.0.4.tgz",
+ "integrity": "sha512-eRWGdEPMVudijE/psbIDNcnJLRVx3xhfuEsTDGgH4GsFF91dVhw5nhmnBppafJ7+NWINW6C7ZwWbi30ImJzqWg==",
+ "dev": true,
+ "requires": {
+ "ccount": "^1.0.0",
+ "is-alphanumeric": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-whitespace-character": "^1.0.0",
+ "longest-streak": "^2.0.1",
+ "markdown-escapes": "^1.0.0",
+ "markdown-table": "^1.1.0",
+ "mdast-util-compact": "^1.0.0",
+ "parse-entities": "^1.0.2",
+ "repeat-string": "^1.5.4",
+ "state-toggle": "^1.0.0",
+ "stringify-entities": "^1.0.1",
+ "unherit": "^1.0.4",
+ "xtend": "^4.0.1"
+ }
+ },
+ "remove-bom-buffer": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz",
+ "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5",
+ "is-utf8": "^0.2.1"
+ }
+ },
+ "remove-bom-stream": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz",
+ "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=",
+ "dev": true,
+ "requires": {
+ "remove-bom-buffer": "^3.0.0",
+ "safe-buffer": "^5.1.0",
+ "through2": "^2.0.3"
+ }
+ },
+ "remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+ "dev": true
+ },
+ "repeat-element": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+ "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+ "dev": true
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+ "dev": true
+ },
+ "repeating": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+ "dev": true,
+ "requires": {
+ "is-finite": "^1.0.0"
+ }
+ },
+ "replace-ext": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
+ "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
+ "dev": true
+ },
+ "replace-homedir": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz",
+ "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=",
+ "dev": true,
+ "requires": {
+ "homedir-polyfill": "^1.0.1",
+ "is-absolute": "^1.0.0",
+ "remove-trailing-separator": "^1.1.0"
+ }
+ },
+ "request": {
+ "version": "2.88.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+ "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
+ "dev": true,
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.0",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.4.3",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "dev": true
+ },
+ "require-main-filename": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
+ "dev": true
+ },
+ "reserved-words": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/reserved-words/-/reserved-words-0.1.2.tgz",
+ "integrity": "sha1-AKCUD5jNUBrqqsMWQR2a3FKzGrE=",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz",
+ "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==",
+ "dev": true,
+ "requires": {
+ "path-parse": "^1.0.6"
+ }
+ },
+ "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-dir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
+ "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "^2.0.0",
+ "global-modules": "^1.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+ "dev": true
+ },
+ "resolve-options": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz",
+ "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=",
+ "dev": true,
+ "requires": {
+ "value-or-function": "^3.0.0"
+ }
+ },
+ "resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+ "dev": true
+ },
+ "responselike": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz",
+ "integrity": "sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec=",
+ "dev": true,
+ "requires": {
+ "lowercase-keys": "^1.0.0"
+ }
+ },
+ "restore-cursor": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+ "dev": true,
+ "requires": {
+ "onetime": "^2.0.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "dev": true
+ },
+ "reusify": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
+ "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
+ "dev": true
+ },
+ "rgb-regex": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz",
+ "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=",
+ "dev": true
+ },
+ "rgba-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz",
+ "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=",
+ "dev": true
+ },
+ "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-parallel": {
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz",
+ "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==",
+ "dev": true
+ },
+ "rxjs": {
+ "version": "6.5.3",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.3.tgz",
+ "integrity": "sha512-wuYsAYYFdWTAnAaPoKGNhfpWwKZbJW+HgAJ+mImp+Epl7BG8oNWBCTyRM8gba9k4lk8BgWdoYm21Mo/RYhhbgA==",
+ "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
+ },
+ "safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "dev": true,
+ "requires": {
+ "ret": "~0.1.10"
+ }
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "dev": true
+ },
+ "sass-graph": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
+ "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
+ "dev": true,
+ "requires": {
+ "glob": "^7.0.0",
+ "lodash": "^4.0.0",
+ "scss-tokenizer": "^0.2.3",
+ "yargs": "^7.0.0"
+ }
+ },
+ "sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
+ "dev": true
+ },
+ "scss-tokenizer": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
+ "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
+ "dev": true,
+ "requires": {
+ "js-base64": "^2.1.8",
+ "source-map": "^0.4.2"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "dev": true,
+ "requires": {
+ "amdefine": ">=0.0.4"
+ }
+ }
+ }
+ },
+ "semver": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
+ "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==",
+ "dev": true
+ },
+ "semver-diff": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
+ "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
+ "dev": true,
+ "requires": {
+ "semver": "^5.0.3"
+ }
+ },
+ "semver-greatest-satisfied-range": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz",
+ "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=",
+ "dev": true,
+ "requires": {
+ "sver-compat": "^1.5.0"
+ }
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+ "dev": true
+ },
+ "set-value": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz",
+ "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.3",
+ "split-string": "^3.0.1"
+ }
+ },
+ "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.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=",
+ "dev": true
+ },
+ "simple-swizzle": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz",
+ "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=",
+ "dev": true,
+ "requires": {
+ "is-arrayish": "^0.3.1"
+ },
+ "dependencies": {
+ "is-arrayish": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz",
+ "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==",
+ "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"
+ },
+ "dependencies": {
+ "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
+ }
+ }
+ },
+ "snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "dev": true,
+ "requires": {
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ }
+ },
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "dev": true,
+ "requires": {
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.0",
+ "snapdragon-util": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ }
+ }
+ },
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.2.0"
+ }
+ },
+ "sort-keys": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz",
+ "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=",
+ "dev": true,
+ "requires": {
+ "is-plain-obj": "^1.0.0"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ },
+ "source-map-resolve": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
+ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
+ "dev": true,
+ "requires": {
+ "atob": "^2.1.1",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ }
+ },
+ "source-map-url": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+ "dev": true
+ },
+ "sparkles": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz",
+ "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==",
+ "dev": true
+ },
+ "spdx-correct": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
+ "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
+ "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.3",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz",
+ "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==",
+ "dev": true
+ },
+ "specificity": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz",
+ "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==",
+ "dev": true
+ },
+ "split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ },
+ "sshpk": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+ "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+ "dev": true,
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ }
+ },
+ "stable": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz",
+ "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==",
+ "dev": true
+ },
+ "stack-trace": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+ "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=",
+ "dev": true
+ },
+ "state-toggle": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.2.tgz",
+ "integrity": "sha512-8LpelPGR0qQM4PnfLiplOQNJcIN1/r2Gy0xKB2zKnIW2YzPMt2sR4I/+gtPjhN7Svh9kw+zqEg2SFwpBO9iNiw==",
+ "dev": true
+ },
+ "static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+ "dev": true,
+ "requires": {
+ "define-property": "^0.2.5",
+ "object-copy": "^0.1.0"
+ }
+ },
+ "stdout-stream": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
+ "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.1"
+ }
+ },
+ "stream-exhaust": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz",
+ "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==",
+ "dev": true
+ },
+ "stream-shift": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
+ "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+ "dev": true,
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "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"
+ }
+ },
+ "stringify-entities": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz",
+ "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==",
+ "dev": true,
+ "requires": {
+ "character-entities-html4": "^1.0.0",
+ "character-entities-legacy": "^1.0.0",
+ "is-alphanumerical": "^1.0.0",
+ "is-hexadecimal": "^1.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+ "dev": true,
+ "requires": {
+ "is-utf8": "^0.2.0"
+ }
+ },
+ "strip-bom-string": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom-string/-/strip-bom-string-1.0.0.tgz",
+ "integrity": "sha1-5SEekiQ2n7uB1jOi8ABE3IztrZI=",
+ "dev": true
+ },
+ "strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+ "dev": true
+ },
+ "strip-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+ "dev": true,
+ "requires": {
+ "get-stdin": "^4.0.1"
+ }
+ },
+ "strip-json-comments": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz",
+ "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==",
+ "dev": true
+ },
+ "style-search": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz",
+ "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=",
+ "dev": true
+ },
+ "stylelint": {
+ "version": "11.0.0",
+ "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-11.0.0.tgz",
+ "integrity": "sha512-esKkG7CUXI5yr4jgCNuwjiiV6NJ4BpodB0e47oFvUBaHgpiXXHRPOajpb0IXL7Ucpk+X3dcrlPxVHpmJ5XUDwg==",
+ "dev": true,
+ "requires": {
+ "autoprefixer": "^9.5.1",
+ "balanced-match": "^1.0.0",
+ "chalk": "^2.4.2",
+ "cosmiconfig": "^5.2.0",
+ "debug": "^4.1.1",
+ "execall": "^2.0.0",
+ "file-entry-cache": "^5.0.1",
+ "get-stdin": "^7.0.0",
+ "global-modules": "^2.0.0",
+ "globby": "^9.2.0",
+ "globjoin": "^0.1.4",
+ "html-tags": "^3.0.0",
+ "ignore": "^5.0.6",
+ "import-lazy": "^4.0.0",
+ "imurmurhash": "^0.1.4",
+ "known-css-properties": "^0.15.0",
+ "leven": "^3.1.0",
+ "lodash": "^4.17.14",
+ "log-symbols": "^3.0.0",
+ "mathml-tag-names": "^2.1.0",
+ "meow": "^5.0.0",
+ "micromatch": "^4.0.0",
+ "normalize-selector": "^0.2.0",
+ "postcss": "^7.0.14",
+ "postcss-html": "^0.36.0",
+ "postcss-jsx": "^0.36.3",
+ "postcss-less": "^3.1.4",
+ "postcss-markdown": "^0.36.0",
+ "postcss-media-query-parser": "^0.2.3",
+ "postcss-reporter": "^6.0.1",
+ "postcss-resolve-nested-selector": "^0.1.1",
+ "postcss-safe-parser": "^4.0.1",
+ "postcss-sass": "^0.4.1",
+ "postcss-scss": "^2.0.0",
+ "postcss-selector-parser": "^3.1.0",
+ "postcss-syntax": "^0.36.2",
+ "postcss-value-parser": "^4.0.2",
+ "resolve-from": "^5.0.0",
+ "signal-exit": "^3.0.2",
+ "slash": "^3.0.0",
+ "specificity": "^0.4.1",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^5.2.0",
+ "style-search": "^0.1.0",
+ "sugarss": "^2.0.0",
+ "svg-tags": "^1.0.0",
+ "table": "^5.2.3",
+ "v8-compile-cache": "^2.1.0"
+ },
+ "dependencies": {
+ "@nodelib/fs.stat": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
+ "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ },
+ "array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "dev": true,
+ "requires": {
+ "array-uniq": "^1.0.1"
+ }
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ },
+ "camelcase-keys": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz",
+ "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^4.1.0",
+ "map-obj": "^2.0.0",
+ "quick-lru": "^1.0.0"
+ }
+ },
+ "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"
+ }
+ },
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ }
+ },
+ "dir-glob": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz",
+ "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==",
+ "dev": true,
+ "requires": {
+ "path-type": "^3.0.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "fast-glob": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz",
+ "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==",
+ "dev": true,
+ "requires": {
+ "@mrmlnc/readdir-enhanced": "^2.2.1",
+ "@nodelib/fs.stat": "^1.1.2",
+ "glob-parent": "^3.1.0",
+ "is-glob": "^4.0.0",
+ "merge2": "^1.2.3",
+ "micromatch": "^3.1.10"
+ },
+ "dependencies": {
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ }
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
+ "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"
+ }
+ },
+ "get-stdin": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz",
+ "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==",
+ "dev": true
+ },
+ "global-modules": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
+ "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
+ "dev": true,
+ "requires": {
+ "global-prefix": "^3.0.0"
+ }
+ },
+ "global-prefix": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
+ "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
+ "dev": true,
+ "requires": {
+ "ini": "^1.3.5",
+ "kind-of": "^6.0.2",
+ "which": "^1.3.1"
+ }
+ },
+ "globby": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz",
+ "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==",
+ "dev": true,
+ "requires": {
+ "@types/glob": "^7.1.1",
+ "array-union": "^1.0.2",
+ "dir-glob": "^2.2.2",
+ "fast-glob": "^2.2.6",
+ "glob": "^7.1.3",
+ "ignore": "^4.0.3",
+ "pify": "^4.0.1",
+ "slash": "^2.0.0"
+ },
+ "dependencies": {
+ "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
+ },
+ "slash": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+ "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+ "dev": true
+ }
+ }
+ },
+ "indent-string": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
+ "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=",
+ "dev": true
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "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==",
+ "dev": true
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ },
+ "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"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "map-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz",
+ "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=",
+ "dev": true
+ },
+ "meow": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz",
+ "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==",
+ "dev": true,
+ "requires": {
+ "camelcase-keys": "^4.0.0",
+ "decamelize-keys": "^1.0.0",
+ "loud-rejection": "^1.0.0",
+ "minimist-options": "^3.0.1",
+ "normalize-package-data": "^2.3.4",
+ "read-pkg-up": "^3.0.0",
+ "redent": "^2.0.0",
+ "trim-newlines": "^2.0.0",
+ "yargs-parser": "^10.0.0"
+ }
+ },
+ "micromatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+ "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.0.5"
+ },
+ "dependencies": {
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "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
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "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
+ },
+ "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"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "postcss-value-parser": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz",
+ "integrity": "sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ==",
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "redent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz",
+ "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=",
+ "dev": true,
+ "requires": {
+ "indent-string": "^3.0.0",
+ "strip-indent": "^2.0.0"
+ }
+ },
+ "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
+ },
+ "string-width": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz",
+ "integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^5.2.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"
+ }
+ },
+ "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-indent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz",
+ "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ }
+ },
+ "trim-newlines": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz",
+ "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=",
+ "dev": true
+ },
+ "yargs-parser": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz",
+ "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^4.1.0"
+ }
+ }
+ }
+ },
+ "stylelint-order": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-3.1.1.tgz",
+ "integrity": "sha512-4gP/r8j/6JGZ/LL41b2sYtQqfwZl4VSqTp7WeIwI67v/OXNQ08dnn64BGXNwAUSgb2+YIvIOxQaMzqMyQMzoyQ==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.15",
+ "postcss": "^7.0.17",
+ "postcss-sorting": "^5.0.1"
+ }
+ },
+ "sugarss": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz",
+ "integrity": "sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2"
+ }
+ },
+ "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": "1.0.1",
+ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz",
+ "integrity": "sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^2.0.0",
+ "supports-color": "^5.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ }
+ }
+ },
+ "sver-compat": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz",
+ "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=",
+ "dev": true,
+ "requires": {
+ "es6-iterator": "^2.0.1",
+ "es6-symbol": "^3.1.1"
+ }
+ },
+ "svg-tags": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
+ "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=",
+ "dev": true
+ },
+ "svgo": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.0.tgz",
+ "integrity": "sha512-MLfUA6O+qauLDbym+mMZgtXCGRfIxyQoeH6IKVcFslyODEe/ElJNwr0FohQ3xG4C6HK6bk3KYPPXwHVJk3V5NQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "coa": "^2.0.2",
+ "css-select": "^2.0.0",
+ "css-select-base-adapter": "^0.1.1",
+ "css-tree": "1.0.0-alpha.33",
+ "csso": "^3.5.1",
+ "js-yaml": "^3.13.1",
+ "mkdirp": "~0.5.1",
+ "object.values": "^1.1.0",
+ "sax": "~1.2.4",
+ "stable": "^0.1.8",
+ "unquote": "~1.1.1",
+ "util.promisify": "~1.0.0"
+ }
+ },
+ "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": {
+ "ajv": {
+ "version": "6.10.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz",
+ "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^2.0.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "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
+ },
+ "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
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "tar": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.2.tgz",
+ "integrity": "sha512-FCEhQ/4rE1zYv9rYXJw/msRqsnmlje5jHP6huWeBZ704jUTy02c5AZyWujpMR1ax6mVw9NyJMfuK2CMDWVIfgA==",
+ "dev": true,
+ "requires": {
+ "block-stream": "*",
+ "fstream": "^1.0.12",
+ "inherits": "2"
+ }
+ },
+ "term-size": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
+ "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=",
+ "dev": true,
+ "requires": {
+ "execa": "^0.7.0"
+ }
+ },
+ "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
+ },
+ "the-argv": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/the-argv/-/the-argv-1.0.0.tgz",
+ "integrity": "sha1-AIRwUAVzDdhNt1UlPJMa45jblSI=",
+ "dev": true
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "through2-filter": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz",
+ "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==",
+ "dev": true,
+ "requires": {
+ "through2": "~2.0.0",
+ "xtend": "~4.0.0"
+ }
+ },
+ "time-stamp": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz",
+ "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=",
+ "dev": true
+ },
+ "timers-ext": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.7.tgz",
+ "integrity": "sha512-b85NUNzTSdodShTIbky6ZF02e8STtVVfD+fu4aXXShEELpozH+bCpJLYMPZbsABN2wDH7fJpqIoXxJpzbf0NqQ==",
+ "dev": true,
+ "requires": {
+ "es5-ext": "~0.10.46",
+ "next-tick": "1"
+ }
+ },
+ "timsort": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz",
+ "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "to-absolute-glob": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
+ "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=",
+ "dev": true,
+ "requires": {
+ "is-absolute": "^1.0.0",
+ "is-negated-glob": "^1.0.0"
+ }
+ },
+ "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-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ }
+ },
+ "to-readable-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz",
+ "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==",
+ "dev": true
+ },
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "dev": true,
+ "requires": {
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ }
+ },
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ },
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "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"
+ },
+ "dependencies": {
+ "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
+ }
+ }
+ },
+ "to-through": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz",
+ "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=",
+ "dev": true,
+ "requires": {
+ "through2": "^2.0.3"
+ }
+ },
+ "tough-cookie": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+ "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
+ "dev": true,
+ "requires": {
+ "psl": "^1.1.24",
+ "punycode": "^1.4.1"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
+ "dev": true
+ }
+ }
+ },
+ "trim": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz",
+ "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=",
+ "dev": true
+ },
+ "trim-newlines": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+ "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=",
+ "dev": true
+ },
+ "trim-trailing-lines": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.2.tgz",
+ "integrity": "sha512-MUjYItdrqqj2zpcHFTkMa9WAv4JHTI6gnRQGPFLrt5L9a6tRMiDnIqYl8JBvu2d2Tc3lWJKQwlGCp0K8AvCM+Q==",
+ "dev": true
+ },
+ "trough": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.4.tgz",
+ "integrity": "sha512-tdzBRDGWcI1OpPVmChbdSKhvSVurznZ8X36AYURAcl+0o2ldlCY2XPzyXNNxwJwwyIU+rIglTCG4kxtNKBQH7Q==",
+ "dev": true
+ },
+ "true-case-path": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
+ "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.2"
+ }
+ },
+ "tslib": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
+ "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==",
+ "dev": true
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
+ "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-fest": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.5.2.tgz",
+ "integrity": "sha512-DWkS49EQKVX//Tbupb9TFa19c7+MK1XmzkrZUR8TAktmE/DizXoaoJV6TZ/tSIPXipqNiRI6CyAe7x69Jb6RSw==",
+ "dev": true
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+ "dev": true
+ },
+ "unc-path-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+ "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=",
+ "dev": true
+ },
+ "undertaker": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.1.tgz",
+ "integrity": "sha512-71WxIzDkgYk9ZS+spIB8iZXchFhAdEo2YU8xYqBYJ39DIUIqziK78ftm26eecoIY49X0J2MLhG4hr18Yp6/CMA==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.0.1",
+ "arr-map": "^2.0.0",
+ "bach": "^1.0.0",
+ "collection-map": "^1.0.0",
+ "es6-weak-map": "^2.0.1",
+ "last-run": "^1.1.0",
+ "object.defaults": "^1.0.0",
+ "object.reduce": "^1.0.0",
+ "undertaker-registry": "^1.0.0"
+ }
+ },
+ "undertaker-registry": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz",
+ "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=",
+ "dev": true
+ },
+ "unherit": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.2.tgz",
+ "integrity": "sha512-W3tMnpaMG7ZY6xe/moK04U9fBhi6wEiCYHUW5Mop/wQHf12+79EQGwxYejNdhEz2mkqkBlGwm7pxmgBKMVUj0w==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "xtend": "^4.0.1"
+ }
+ },
+ "unified": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/unified/-/unified-7.1.0.tgz",
+ "integrity": "sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "@types/vfile": "^3.0.0",
+ "bail": "^1.0.0",
+ "extend": "^3.0.0",
+ "is-plain-obj": "^1.1.0",
+ "trough": "^1.0.0",
+ "vfile": "^3.0.0",
+ "x-is-string": "^0.1.0"
+ }
+ },
+ "union-value": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz",
+ "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "get-value": "^2.0.6",
+ "is-extendable": "^0.1.1",
+ "set-value": "^2.0.1"
+ }
+ },
+ "uniq": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+ "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
+ "dev": true
+ },
+ "uniqs": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz",
+ "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=",
+ "dev": true
+ },
+ "unique-stream": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz",
+ "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==",
+ "dev": true,
+ "requires": {
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "through2-filter": "^3.0.0"
+ }
+ },
+ "unique-string": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
+ "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
+ "dev": true,
+ "requires": {
+ "crypto-random-string": "^1.0.0"
+ }
+ },
+ "unist-util-find-all-after": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-1.0.4.tgz",
+ "integrity": "sha512-CaxvMjTd+yF93BKLJvZnEfqdM7fgEACsIpQqz8vIj9CJnUb9VpyymFS3tg6TCtgrF7vfCJBF5jbT2Ox9CBRYRQ==",
+ "dev": true,
+ "requires": {
+ "unist-util-is": "^3.0.0"
+ }
+ },
+ "unist-util-is": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz",
+ "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==",
+ "dev": true
+ },
+ "unist-util-remove-position": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.3.tgz",
+ "integrity": "sha512-CtszTlOjP2sBGYc2zcKA/CvNdTdEs3ozbiJ63IPBxh8iZg42SCCb8m04f8z2+V1aSk5a7BxbZKEdoDjadmBkWA==",
+ "dev": true,
+ "requires": {
+ "unist-util-visit": "^1.1.0"
+ }
+ },
+ "unist-util-stringify-position": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz",
+ "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==",
+ "dev": true
+ },
+ "unist-util-visit": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz",
+ "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==",
+ "dev": true,
+ "requires": {
+ "unist-util-visit-parents": "^2.0.0"
+ }
+ },
+ "unist-util-visit-parents": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz",
+ "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==",
+ "dev": true,
+ "requires": {
+ "unist-util-is": "^3.0.0"
+ }
+ },
+ "unquote": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz",
+ "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=",
+ "dev": true
+ },
+ "unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+ "dev": true,
+ "requires": {
+ "has-value": "^0.3.1",
+ "isobject": "^3.0.0"
+ },
+ "dependencies": {
+ "has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.3",
+ "has-values": "^0.1.4",
+ "isobject": "^2.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+ "dev": true
+ }
+ }
+ },
+ "upath": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz",
+ "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==",
+ "dev": true
+ },
+ "update-notifier": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-3.0.1.tgz",
+ "integrity": "sha512-grrmrB6Zb8DUiyDIaeRTBCkgISYUgETNe7NglEbVsrLWXeESnlCSP50WfRSj/GmzMPl6Uchj24S/p80nP/ZQrQ==",
+ "dev": true,
+ "requires": {
+ "boxen": "^3.0.0",
+ "chalk": "^2.0.1",
+ "configstore": "^4.0.0",
+ "has-yarn": "^2.1.0",
+ "import-lazy": "^2.1.0",
+ "is-ci": "^2.0.0",
+ "is-installed-globally": "^0.1.0",
+ "is-npm": "^3.0.0",
+ "is-yarn-global": "^0.3.0",
+ "latest-version": "^5.0.0",
+ "semver-diff": "^2.0.0",
+ "xdg-basedir": "^3.0.0"
+ },
+ "dependencies": {
+ "import-lazy": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
+ "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=",
+ "dev": 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"
+ }
+ },
+ "urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+ "dev": true
+ },
+ "url-parse-lax": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz",
+ "integrity": "sha1-FrXK/Afb42dsGxmZF3gj1lA6yww=",
+ "dev": true,
+ "requires": {
+ "prepend-http": "^2.0.0"
+ }
+ },
+ "use": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+ "dev": true
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=",
+ "dev": true
+ },
+ "util.promisify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz",
+ "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==",
+ "dev": true,
+ "requires": {
+ "define-properties": "^1.1.2",
+ "object.getownpropertydescriptors": "^2.0.3"
+ }
+ },
+ "uuid": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
+ "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
+ },
+ "v8flags": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.3.tgz",
+ "integrity": "sha512-amh9CCg3ZxkzQ48Mhcb8iX7xpAfYJgePHxWMQCBWECpOSqJUXgY26ncA61UTV0BkPqfhcy6mzwCIoP4ygxpW8w==",
+ "dev": true,
+ "requires": {
+ "homedir-polyfill": "^1.0.1"
+ }
+ },
+ "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"
+ }
+ },
+ "value-or-function": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz",
+ "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=",
+ "dev": true
+ },
+ "vendors": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.3.tgz",
+ "integrity": "sha512-fOi47nsJP5Wqefa43kyWSg80qF+Q3XA6MUkgi7Hp1HQaKDQW4cQrK2D0P7mmbFtsV1N89am55Yru/nyEwRubcw==",
+ "dev": true
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "dev": true,
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "vfile": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-3.0.1.tgz",
+ "integrity": "sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^2.0.0",
+ "replace-ext": "1.0.0",
+ "unist-util-stringify-position": "^1.0.0",
+ "vfile-message": "^1.0.0"
+ },
+ "dependencies": {
+ "is-buffer": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz",
+ "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==",
+ "dev": true
+ }
+ }
+ },
+ "vfile-location": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.5.tgz",
+ "integrity": "sha512-Pa1ey0OzYBkLPxPZI3d9E+S4BmvfVwNAAXrrqGbwTVXWaX2p9kM1zZ+n35UtVM06shmWKH4RPRN8KI80qE3wNQ==",
+ "dev": true
+ },
+ "vfile-message": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz",
+ "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==",
+ "dev": true,
+ "requires": {
+ "unist-util-stringify-position": "^1.1.1"
+ }
+ },
+ "vinyl": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
+ "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
+ "dev": true,
+ "requires": {
+ "clone": "^2.1.1",
+ "clone-buffer": "^1.0.0",
+ "clone-stats": "^1.0.0",
+ "cloneable-readable": "^1.0.0",
+ "remove-trailing-separator": "^1.0.1",
+ "replace-ext": "^1.0.0"
+ }
+ },
+ "vinyl-fs": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz",
+ "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==",
+ "dev": true,
+ "requires": {
+ "fs-mkdirp-stream": "^1.0.0",
+ "glob-stream": "^6.1.0",
+ "graceful-fs": "^4.0.0",
+ "is-valid-glob": "^1.0.0",
+ "lazystream": "^1.0.0",
+ "lead": "^1.0.0",
+ "object.assign": "^4.0.4",
+ "pumpify": "^1.3.5",
+ "readable-stream": "^2.3.3",
+ "remove-bom-buffer": "^3.0.0",
+ "remove-bom-stream": "^1.2.0",
+ "resolve-options": "^1.1.0",
+ "through2": "^2.0.0",
+ "to-through": "^2.0.0",
+ "value-or-function": "^3.0.0",
+ "vinyl": "^2.0.0",
+ "vinyl-sourcemap": "^1.1.0"
+ }
+ },
+ "vinyl-sourcemap": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz",
+ "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=",
+ "dev": true,
+ "requires": {
+ "append-buffer": "^1.0.2",
+ "convert-source-map": "^1.5.0",
+ "graceful-fs": "^4.1.6",
+ "normalize-path": "^2.1.1",
+ "now-and-later": "^2.0.0",
+ "remove-bom-buffer": "^3.0.0",
+ "vinyl": "^2.0.0"
+ }
+ },
+ "vinyl-sourcemaps-apply": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz",
+ "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=",
+ "dev": true,
+ "requires": {
+ "source-map": "^0.5.1"
+ }
+ },
+ "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": "1.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+ "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=",
+ "dev": true
+ },
+ "wide-align": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+ "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.2 || 2"
+ }
+ },
+ "widest-line": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz",
+ "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==",
+ "dev": true,
+ "requires": {
+ "string-width": "^2.1.1"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "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
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "dev": true
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "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": "2.4.3",
+ "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz",
+ "integrity": "sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.11",
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "write-json-file": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-2.3.0.tgz",
+ "integrity": "sha1-K2TIozAE1UuGmMdtWFp3zrYdoy8=",
+ "dev": true,
+ "requires": {
+ "detect-indent": "^5.0.0",
+ "graceful-fs": "^4.1.2",
+ "make-dir": "^1.0.0",
+ "pify": "^3.0.0",
+ "sort-keys": "^2.0.0",
+ "write-file-atomic": "^2.0.0"
+ },
+ "dependencies": {
+ "make-dir": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+ "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+ "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
+ }
+ }
+ },
+ "write-pkg": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-3.2.0.tgz",
+ "integrity": "sha512-tX2ifZ0YqEFOF1wjRW2Pk93NLsj02+n1UP5RvO6rCs0K6R2g1padvf006cY74PQJKMGS2r42NK7FD0dG6Y6paw==",
+ "dev": true,
+ "requires": {
+ "sort-keys": "^2.0.0",
+ "write-json-file": "^2.2.0"
+ }
+ },
+ "x-is-string": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz",
+ "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=",
+ "dev": true
+ },
+ "xdg-basedir": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
+ "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=",
+ "dev": true
+ },
+ "xo": {
+ "version": "0.25.3",
+ "resolved": "https://registry.npmjs.org/xo/-/xo-0.25.3.tgz",
+ "integrity": "sha512-125on+kPp6oi+EfoAajJ58cGLxIurZqWrehhdqoApWXpano9GL5D0ElcSlbG7UeYAfmNSwKJGTxHoLsHLhrZqg==",
+ "dev": true,
+ "requires": {
+ "arrify": "^2.0.1",
+ "debug": "^4.1.0",
+ "eslint": "^6.4.0",
+ "eslint-config-prettier": "^6.3.0",
+ "eslint-config-xo": "^0.27.1",
+ "eslint-formatter-pretty": "^2.0.0",
+ "eslint-plugin-ava": "^9.0.0",
+ "eslint-plugin-eslint-comments": "^3.0.1",
+ "eslint-plugin-import": "^2.18.2",
+ "eslint-plugin-no-use-extend-native": "^0.4.0",
+ "eslint-plugin-node": "^10.0.0",
+ "eslint-plugin-prettier": "^3.1.1",
+ "eslint-plugin-promise": "^4.0.0",
+ "eslint-plugin-unicorn": "^12.0.0",
+ "find-cache-dir": "^3.0.0",
+ "get-stdin": "^7.0.0",
+ "globby": "^9.0.0",
+ "has-flag": "^4.0.0",
+ "lodash.isequal": "^4.5.0",
+ "lodash.mergewith": "^4.6.2",
+ "meow": "^5.0.0",
+ "multimatch": "^4.0.0",
+ "open-editor": "^2.0.1",
+ "path-exists": "^4.0.0",
+ "pkg-conf": "^3.1.0",
+ "prettier": "^1.15.2",
+ "resolve-cwd": "^3.0.0",
+ "resolve-from": "^5.0.0",
+ "semver": "^6.3.0",
+ "slash": "^3.0.0",
+ "update-notifier": "^3.0.1",
+ "xo-init": "^0.7.0"
+ },
+ "dependencies": {
+ "@nodelib/fs.stat": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
+ "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
+ "dev": true
+ },
+ "array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "dev": true,
+ "requires": {
+ "array-uniq": "^1.0.1"
+ }
+ },
+ "arrify": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
+ "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ },
+ "camelcase-keys": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz",
+ "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^4.1.0",
+ "map-obj": "^2.0.0",
+ "quick-lru": "^1.0.0"
+ }
+ },
+ "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"
+ }
+ },
+ "dir-glob": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz",
+ "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==",
+ "dev": true,
+ "requires": {
+ "path-type": "^3.0.0"
+ }
+ },
+ "fast-glob": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz",
+ "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==",
+ "dev": true,
+ "requires": {
+ "@mrmlnc/readdir-enhanced": "^2.2.1",
+ "@nodelib/fs.stat": "^1.1.2",
+ "glob-parent": "^3.1.0",
+ "is-glob": "^4.0.0",
+ "merge2": "^1.2.3",
+ "micromatch": "^3.1.10"
+ }
+ },
+ "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"
+ }
+ },
+ "get-stdin": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz",
+ "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==",
+ "dev": true
+ },
+ "globby": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz",
+ "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==",
+ "dev": true,
+ "requires": {
+ "@types/glob": "^7.1.1",
+ "array-union": "^1.0.2",
+ "dir-glob": "^2.2.2",
+ "fast-glob": "^2.2.6",
+ "glob": "^7.1.3",
+ "ignore": "^4.0.3",
+ "pify": "^4.0.1",
+ "slash": "^2.0.0"
+ },
+ "dependencies": {
+ "slash": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+ "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+ "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
+ },
+ "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
+ },
+ "indent-string": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
+ "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=",
+ "dev": true
+ },
+ "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"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "map-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz",
+ "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=",
+ "dev": true
+ },
+ "meow": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz",
+ "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==",
+ "dev": true,
+ "requires": {
+ "camelcase-keys": "^4.0.0",
+ "decamelize-keys": "^1.0.0",
+ "loud-rejection": "^1.0.0",
+ "minimist-options": "^3.0.1",
+ "normalize-package-data": "^2.3.4",
+ "read-pkg-up": "^3.0.0",
+ "redent": "^2.0.0",
+ "trim-newlines": "^2.0.0",
+ "yargs-parser": "^10.0.0"
+ }
+ },
+ "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
+ },
+ "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-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
+ },
+ "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"
+ },
+ "dependencies": {
+ "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"
+ }
+ },
+ "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"
+ }
+ },
+ "redent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz",
+ "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=",
+ "dev": true,
+ "requires": {
+ "indent-string": "^3.0.0",
+ "strip-indent": "^2.0.0"
+ }
+ },
+ "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
+ },
+ "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-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ },
+ "strip-indent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz",
+ "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=",
+ "dev": true
+ },
+ "trim-newlines": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz",
+ "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=",
+ "dev": true
+ },
+ "yargs-parser": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz",
+ "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^4.1.0"
+ }
+ }
+ }
+ },
+ "xo-init": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/xo-init/-/xo-init-0.7.0.tgz",
+ "integrity": "sha512-mrrCKMu52vz0u2tiOl8DoG709pBtnSp58bb4/j58a4jeXjrb1gV7dxfOBjOlXitYtfW2QnlxxxfAojoFcpynDg==",
+ "dev": true,
+ "requires": {
+ "arrify": "^1.0.0",
+ "execa": "^0.9.0",
+ "has-yarn": "^1.0.0",
+ "minimist": "^1.1.3",
+ "path-exists": "^3.0.0",
+ "read-pkg-up": "^3.0.0",
+ "the-argv": "^1.0.0",
+ "write-pkg": "^3.1.0"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^4.0.1",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "execa": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.9.0.tgz",
+ "integrity": "sha512-BbUMBiX4hqiHZUA5+JujIjNb6TyAlp2D5KLheMjMluwOuzcnylDL4AxZYLLn1n2AGB49eSWwyKvvEQoRpnAtmA==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^5.0.1",
+ "get-stream": "^3.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ }
+ },
+ "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"
+ }
+ },
+ "has-yarn": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-1.0.0.tgz",
+ "integrity": "sha1-ieJdtgS3Jcj1l2//Ct3JIbgopac=",
+ "dev": true
+ },
+ "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"
+ }
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "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-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-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"
+ }
+ },
+ "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"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ }
+ }
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+ "dev": true
+ },
+ "y18n": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
+ "dev": true
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
+ "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^3.0.0",
+ "cliui": "^3.2.0",
+ "decamelize": "^1.1.1",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^1.4.0",
+ "read-pkg-up": "^1.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^1.0.2",
+ "which-module": "^1.0.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^5.0.0"
+ }
+ },
+ "yargs-parser": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
+ "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^3.0.0"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000000..564551b29d
--- /dev/null
+++ b/package.json
@@ -0,0 +1,65 @@
+{
+ "name": "phpbb",
+ "version": "3.3.0-dev",
+ "description": "phpBB Forum Software application",
+ "main": " ",
+ "directories": {
+ "doc": "docs"
+ },
+ "xo": {
+ "rules": {
+ "quote-props": [
+ "error",
+ "always"
+ ]
+ },
+ "env": {
+ "es6": true,
+ "browser": true,
+ "node": true,
+ "jquery": true
+ }
+ },
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/phpbb/phpbb.git"
+ },
+ "browserslist": [
+ "> 1%",
+ "last 2 versions"
+ ],
+ "keywords": [
+ "phpBB",
+ "phpbb",
+ "forum",
+ "php",
+ "software",
+ "community"
+ ],
+ "author": "",
+ "license": "GPL-2.0",
+ "bugs": {
+ "url": "https://tracker.phpbb.com"
+ },
+ "homepage": "https://www.phpbb.com",
+ "devDependencies": {
+ "cssnano": "^4.1.10",
+ "del": "^5.1.0",
+ "gulp": "^4.0.2",
+ "gulp-autoprefixer": "^7.0.0",
+ "gulp-postcss": "^8.0.0",
+ "gulp-rename": "^1.4.0",
+ "gulp-sass": "^4.0.2",
+ "gulp-sourcemaps": "^2.6.5",
+ "postcss-import": "^12.0.1",
+ "postcss-pxtorem": "^4.0.1",
+ "postcss-sorting": "^5.0.1",
+ "stylelint": "^11.0.0",
+ "stylelint-order": "^3.1.1",
+ "xo": "^0.25.3"
+ },
+ "dependencies": {}
+}
diff --git a/phpBB/adm/style/acp_ext_catalog.html b/phpBB/adm/style/acp_ext_catalog.html
new file mode 100644
index 0000000000..1be94258e8
--- /dev/null
+++ b/phpBB/adm/style/acp_ext_catalog.html
@@ -0,0 +1,130 @@
+{% include('overall_header.html') %}
+
+<a id="maincontent"></a>
+
+<h1>{{ lang( 'EXTENSIONS_CATALOG') }}</h1>
+
+<p>{{ lang( 'EXTENSIONS_CATALOG_EXPLAIN') }}</p>
+
+<fieldset class="quick quick-left">
+ <span class="small"><a href="https://www.phpbb.com/go/customise/extensions/{{ PHPBB_MAJOR }}" target="_blank">{{ lang('BROWSE_EXTENSIONS_DATABASE') }}</a> &bull; <a href="javascript:phpbb.toggleDisplay('catalog_settings');">{{ lang('SETTINGS') }}</a></span>
+</fieldset>
+
+{% if pagination is defined %}
+ <div class="pagination top-pagination">
+ {% include('pagination.html') %}
+ </div>
+{% endif %}
+
+<form id="catalog_settings" method="post" action="{{ U_ACTION }}" style="display:none">
+ <fieldset style="clear: both;">
+ <legend>{{ lang('EXTENSIONS_CATALOG_SETTINGS') }}</legend>
+ <dl>
+ <dt><label for="enable_on_install">{{ lang('ENABLE_ON_INSTALL') }}{{ lang('COLON') }}</label></dt>
+ <dd>
+ <label><input type="radio" id="enable_on_install" name="enable_on_install" class="radio" value="1"{% if settings.enable_on_install %} checked="checked" {% endif %} /> {{ lang('YES') }}</label>
+ <label><input type="radio" name="enable_on_install" class="radio" value="0"{% if not settings.enable_on_install %} checked="checked" {% endif %} /> {{ lang('NO') }}</label>
+ </dd>
+ </dl>
+ <dl>
+ <dt><label for="purge_on_remove">{{ lang('PURGE_ON_REMOVE') }}{{ lang('COLON') }}</label></dt>
+ <dd>
+ <label><input type="radio" id="purge_on_remove" name="purge_on_remove" class="radio" value="1"{% if settings.purge_on_remove %} checked="checked" {% endif %} /> {{ lang('YES') }}</label>
+ <label><input type="radio" name="purge_on_remove" class="radio" value="0"{% if not settings.purge_on_remove %} checked="checked" {% endif %} /> {{ lang('NO') }}</label>
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <label for="repositories">{{ lang('COMPOSER_REPOSITORIES') }}{{ lang('COLON') }}</label><br />
+ <span class="explain">
+ {{ lang('COMPOSER_REPOSITORIES_EXPLAIN') }}
+ </span>
+ </dt>
+ <dd>
+ <textarea id="repositories" name="repositories" rows="5" cols="30">{{ settings.repositories|join('\n') }}</textarea>
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <label for="enable_packagist">{{ lang('ENABLE_PACKAGIST') }}{{ lang('COLON') }}</label><br />
+ <span class="explain">
+ <strong class="error">{{ lang('WARNING') }}{{ lang('COLON') }}</strong> {{ lang('ENABLE_PACKAGIST_EXPLAIN') }}
+ </span>
+ </dt>
+ <dd>
+ <label><input type="radio" id="enable_packagist" name="enable_packagist" class="radio" value="1"{% if settings.enable_packagist %} checked="checked" {% endif %} /> {{ lang('YES') }}</label>
+ <label><input type="radio" name="enable_packagist" class="radio" value="0"{% if not settings.enable_packagist %} checked="checked" {% endif %} /> {{ lang('NO') }}</label>
+ </dd>
+ </dl>
+ <dl>
+ <dt>
+ <label for="minimum_stability">{{ lang('COMPOSER_MINIMUM_STABILITY') }}{{ lang('COLON') }}</label><br />
+ <span class="explain">
+ <strong class="error">{{ lang('WARNING') }}{{ lang('COLON') }}</strong> {{ lang('COMPOSER_MINIMUM_STABILITY_EXPLAIN') }}
+ </span>
+ </dt>
+ <dd>
+ <select id="minimum_stability" name="minimum_stability">
+ {% for stability in settings.stabilities %}
+ <option value="{{ stability }}"{% if stability === settings.minimum_stability %} selected='selected'{% endif %}>{{ lang('STABILITY_' ~ stability|upper) }}</option>
+ {% endfor %}
+ </select>
+ </dd>
+ </dl>
+
+ <p class="submit-buttons">
+ <input class="button1" type="submit" name="update" value="{{ lang('SUBMIT') }}" />&nbsp;
+ <input class="button2" type="reset" name="reset" value="{{ lang('RESET') }}" />
+ <input type="hidden" name="action" value="set_catalog_settings" />
+ {{ S_FORM_TOKEN }}
+ </p>
+ </fieldset>
+</form>
+
+{% if extensions is empty %}
+<tr>
+ <td colspan="4"><div class="errorbox notice">{{ lang('NO_EXTENSION_AVAILABLE') }}</div></td>
+</tr>
+{% else %}
+<table class="table1">
+ <col class="row1" ><col class="row1" ><col class="row1" ><col class="row2" >
+<thead>
+ <tr>
+ <th style="width: 25%;">{{ lang("EXTENSION_NAME") }}</th>
+ <th style="text-align: center; width: 10%;">{{ lang("VERSION") }}</th>
+ <th>{{ lang("DESCRIPTION") }}</th>
+ <th style="text-align: center; width: 15%;">{{ lang("EXTENSION_ACTIONS") }}</th>
+ </tr>
+</thead>
+<tbody>
+{% for extension in extensions %}
+ <tr>
+ <td>
+ <strong>{{ extension.display_name }}</strong><br />
+ {{ extension.name }}
+ </td>
+ <td style="text-align: center">{{ extension.version }}</td>
+ <td>{{ extension.description }} &bull; <a href="{{ extension.url }}">{{ lang('HOMEPAGE') }}</a></td>
+ <td style="text-align: center">
+ {% if extension.name in managed_extensions %}
+ <span style="color: #228822;">{{ lang('INSTALLED') }}</span>
+ {% elseif extension.name in installed_extensions -%}
+ <span style="color: #BC2A4D;">{{ lang('INSTALLED_MANUALLY') }}</span>
+ (<a href="{{ U_ACTION }}&amp;action=manage&amp;extension={{ extension.composer_name|url_encode }}">{{ lang('MANAGE') }}</a>)
+ {% elseif not enabled -%}
+ <a href="{{ U_ACTION }}&amp;action=install&amp;extension={{ extension.composer_name|url_encode }}">{{ lang('INSTALL') }}</a>
+ {%- endif -%}
+ </td>
+ </tr>
+{% endfor %}
+</tbody>
+</table>
+{% endif %}
+
+{% if pagination is defined %}
+ <div class="pagination bottom-pagination">
+ {% include('pagination.html') %}
+ </div>
+{% endif %}
+
+{% include('overall_footer.html') %}
diff --git a/phpBB/adm/style/acp_ext_list.html b/phpBB/adm/style/acp_ext_list.html
index e5783124c6..f7d4b4f9d7 100644
--- a/phpBB/adm/style/acp_ext_list.html
+++ b/phpBB/adm/style/acp_ext_list.html
@@ -7,7 +7,7 @@
<p>{L_EXTENSIONS_EXPLAIN}</p>
<fieldset class="quick">
- <span class="small"><a href="https://www.phpbb.com/go/customise/extensions/3.3" target="_blank">{L_BROWSE_EXTENSIONS_DATABASE}</a> &bull; <a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE_ALL}</a> &bull; <a href="javascript:phpbb.toggleDisplay('version_check_settings');">{L_SETTINGS}</a></span>
+ <span class="small"><a href="{U_VERSIONCHECK_FORCE}">{L_VERSIONCHECK_FORCE_UPDATE_ALL}</a> &bull; <a href="javascript:phpbb.toggleDisplay('version_check_settings');">{L_SETTINGS}</a></span>
</fieldset>
<form id="version_check_settings" method="post" action="{U_ACTION}" style="display:none">
diff --git a/phpBB/adm/style/acp_storage.html b/phpBB/adm/style/acp_storage.html
new file mode 100644
index 0000000000..0a934cd325
--- /dev/null
+++ b/phpBB/adm/style/acp_storage.html
@@ -0,0 +1,97 @@
+{% include 'overall_header.html' %}
+
+<a id="maincontent"></a>
+
+<h1>{{ lang('STORAGE_TITLE') }}</h1>
+
+<p>{{ lang('STORAGE_TITLE_EXPLAIN') }}</p>
+
+<table class="table1 zebra-table">
+ <thead>
+ <tr>
+ <th>{{ lang('STORAGE_NAME') }}</th>
+ <th>{{ lang('STORAGE_NUM_FILES') }}</th>
+ <th>{{ lang('STORAGE_SIZE') }}</th>
+ <th>{{ lang('STORAGE_FREE') }}</th>
+ </tr>
+ </thead>
+ <tbody>
+ {% for storage in STORAGE_STATS %}
+ <tr>
+ <td>{{ storage.name }}</td>
+ <td>{{ storage.files }}</td>
+ <td>{{ storage.size }}</td>
+ <td>{{ storage.free_space }}</td>
+ </tr>
+ {% endfor %}
+ </tbody>
+</table>
+
+<form id="acp_storage" method="post" action="{{ U_ACTION }}">
+
+ {% for storage in STORAGES %}
+ <fieldset>
+ <legend>{{ lang('STORAGE_' ~ storage.get_name | upper ~ '_TITLE') }}</legend>
+ <dl>
+ <dt><label for="{{ storage.get_name }}">{{ lang('STORAGE_SELECT') }}{{ lang('COLON') }}</label><br /><span>{{ lang('STORAGE_SELECT_DESC') }}</span></dt>
+ <dd>
+ <select id="{{ storage.get_name }}" name="{{ storage.get_name }}[provider]" data-togglable-settings="true">
+ {% for provider in PROVIDERS if provider.is_available %}
+ <option value="{{ get_class(provider) }}"{{ attribute(config, 'storage\\' ~ storage.get_name ~ '\\provider') == get_class(provider) ? ' selected' : '' }} data-toggle-setting="#{{ storage.get_name }}_{{ provider.get_name }}_settings">
+ {{ lang('STORAGE_ADAPTER_' ~ provider.get_name | upper ~ '_NAME') }}
+ </option>
+ {% endfor %}
+ </select>
+ </dd>
+ </dl>
+ </fieldset>
+
+ {% for provider in PROVIDERS if provider.is_available %}
+ <fieldset id="{{ storage.get_name }}_{{ provider.get_name }}_settings">
+ <legend>{{ lang('STORAGE_' ~ storage.get_name | upper ~ '_TITLE') }} - {{ lang('STORAGE_ADAPTER_' ~ provider.get_name | upper ~ '_NAME') }}</legend>
+ {% for name, options in provider.get_options %}
+ {% set title = 'STORAGE_ADAPTER_' ~ provider.get_name | upper ~ '_OPTION_' ~ name | upper %}
+ {% set description = 'STORAGE_ADAPTER_' ~ provider.get_name | upper ~ '_OPTION_' ~ name | upper ~ '_EXPLAIN' %}
+ {% set input_id = storage.get_name ~ '_' ~ provider.get_name ~ '_' ~ name %}
+ {% set input_type = options['type'] %}
+ {% set input_name = storage.get_name ~ '[' ~ name ~ ']' %}
+ {% set input_value = attribute(config, 'storage\\' ~ storage.get_name ~ '\\config\\' ~ name) %}
+ <dl>
+ <dt>
+ <label for="{{ input_id }}}">{{ lang(title) }}{{ lang('COLON') }}</label>
+ {% if lang_defined(description) %}
+ <br /><span>{{ lang(description) }}</span>
+ {% endif %}
+ </dt>
+ <dd>
+ {% if input_type in ['text', 'password', 'email'] %}
+ <input id="{{ input_id }}" type="{{ input_type }}" name="{{ input_name }}" value="{{ input_value }}" maxlength="{{ options['maxlength'] ?: 255 }}" />
+ {% elseif input_type == 'textarea' %}
+ <textarea id="{{ input_id }}" name="{{ input_name }}">{{ input_value }}</textarea>
+ {% elseif input_type == 'radio' %}
+ {% for option_name, option_value in options['options'] %}
+ <input type="radio" name="{{ input_name }}" value="{{ option_value }}" class="radio"{% if loop.first %} id="{{ input_id }}"{% endif %}{{ (option_value == input_value) ? ' checked="checked"' }}> {{ lang(option_name) }}
+ {% endfor %}
+ {% elseif input_type == 'select' %}
+ <select name="{{ input_name }}" id="{{ input_id }}">
+ {% for option_name, option_value in options['options'] %}
+ <option value="{{ option_value }}"{{ (option_value == input_value) ? ' selected' }}>{{ lang(option_name) }}</option>
+ {% endfor %}
+ </select>
+ {% endif %}
+ </dd>
+ </dl>
+ {% endfor %}
+ </fieldset>
+ {% endfor %}
+ {% endfor %}
+
+ <fieldset class="submit-buttons">
+ <legend>{{ lang('SUBMIT') }}</legend>
+ <input class="button1" type="submit" id="submit" name="submit" value="{{ lang('SUBMIT') }}" />&nbsp;
+ <input class="button2" type="reset" id="reset" name="reset" value="{{ lang('RESET') }}" />
+ {{ S_FORM_TOKEN }}
+ </fieldset>
+</form>
+
+{% include 'overall_footer.html' %}
diff --git a/phpBB/adm/style/admin.css b/phpBB/adm/style/admin.css
index 3243d0eb24..f05083dc18 100644
--- a/phpBB/adm/style/admin.css
+++ b/phpBB/adm/style/admin.css
@@ -8,49 +8,70 @@
------------------------------------------------------------------------
*/
+/* stylelint-disable selector-max-id */
+/* stylelint-disable selector-max-compound-selectors */
+/* stylelint-disable selector-no-qualifying-type */
+/* stylelint-disable declaration-property-unit-blacklist */
+/* stylelint-disable declaration-property-unit-whitelist */
+
/* General markup styles
---------------------------------------- */
* {
/* Reset browsers default margin, padding and font sizes */
+ font-size: 100%;
margin: 0;
padding: 0;
- font-size: 100%;
}
abbr {
text-decoration: none;
}
-body, div, p, th, td, li, dd {
- font-size: x-small;
+body,
+div,
+p,
+th,
+td,
+li,
+dd {
+ font-size: small;
voice-family: "\"}\"";
voice-family: inherit;
- font-size: small;
}
-html>body, html>div, html>p, html>th, html>td, html>li, html>dd {
+html > body,
+html > div,
+html > p,
+html > th,
+html > td,
+html > li,
+html > dd {
font-size: small;
}
html {
+ word-wrap: break-word;
+ background: #dbd7d1;
color: #536482;
- background: #DBD7D1;
+
/* Always show a scrollbar for short pages - stops the jump when the scrollbar appears. non-ie browsers */
height: 100%;
margin-bottom: 1px;
- word-wrap: break-word;
}
body {
/* Text-Sizing with ems: http://www.clagnut.com/blog/348/ */
font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif;
+ font-size: 62.5%;
+ background: #dbd7d1;
color: #536482;
- background: #DBD7D1;
- font-size: 62.5%; /* This sets the default font size to be equivalent to 10px */
+
+ /* This sets the default font size to be equivalent to 10px */
margin: 10px 15px;
}
-code, samp {
+code,
+samp {
font-size: 1.2em;
}
@@ -60,41 +81,44 @@ img {
h1 {
font-family: "Trebuchet MS", Helvetica, sans-serif;
- font-size: 1.70em;
+ font-size: 1.7em;
font-weight: normal;
color: #333333;
}
-h2, caption {
+h2,
+caption {
font-family: "Trebuchet MS", Helvetica, sans-serif;
- font-size: 1.40em;
+ font-size: 1.4em;
font-weight: normal;
- color: #115098;
text-align: left;
+ color: #115098;
margin-top: 25px;
}
-.rtl h2, .rtl caption {
+.rtl h2,
+.rtl caption {
text-align: right;
}
-h3, h4 {
+h3,
+h4 {
font-family: "Trebuchet MS", Helvetica, sans-serif;
- font-size: 1.20em;
+ font-size: 1.2em;
+ line-height: 1.2em;
text-decoration: none;
- line-height: 1.20em;
margin-top: 25px;
}
p {
+ font-size: 0.9em;
+ line-height: 1.4em;
margin-bottom: 0.7em;
- line-height: 1.40em;
- font-size: 0.90em;
}
ul {
- list-style: disc;
margin: 0 0 1em 2em;
+ list-style: disc;
}
.rtl ul {
@@ -104,9 +128,9 @@ ul {
hr {
border: 0 none;
border-top: 1px dashed #999999;
+ height: 1px;
margin-bottom: 5px;
padding-bottom: 5px;
- height: 1px;
}
.centered-text {
@@ -129,51 +153,53 @@ hr {
display: none;
}
-@media only screen and (max-width: 800px), only screen and (max-device-width: 800px)
-{
+@media only screen and (max-width: 800px), only screen and (max-device-width: 800px) {
body {
margin: 5px 5px 0;
}
}
-@media only screen and (max-width: 700px), only screen and (max-device-width: 700px)
-{
- html, body {
+@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) {
+ html,
+ body {
height: auto;
margin: 0;
padding: 0;
}
}
-
/* General links */
-a:link, a:visited {
- color: #105289;
+a:link,
+a:visited {
text-decoration: none;
+ color: #105289;
}
a:hover {
- color: #BC2A4D;
text-decoration: underline;
+ color: #bc2a4d;
}
a:active {
- color: #368AD2;
text-decoration: none;
+ color: #368ad2;
}
.install-body p a {
font-weight: bold;
}
-a#maincontent, a#acl, a#assigned_to {
+a#maincontent,
+a#acl,
+a#assigned_to {
display: block;
}
/* List items */
-ul, ol {
- list-style-position: inside;
+ul,
+ol {
margin-left: 1em;
+ list-style-position: inside;
}
li {
@@ -181,19 +207,18 @@ li {
list-style-type: inherit;
}
-
/* Main blocks
---------------------------------------- */
#wrap {
- padding: 0 0 15px 0;
min-width: 615px;
+ padding: 0 0 15px;
}
#page-header {
+ font-size: 0.85em;
text-align: right;
background: url("../images/phpbb_logo.svg") top left no-repeat;
height: 54px;
- font-size: 0.85em;
margin-bottom: 10px;
}
@@ -203,14 +228,14 @@ li {
}
#page-header h1 {
+ font-family: "Trebuchet MS", Helvetica, sans-serif;
+ font-size: 1.7em;
color: #767676;
- font-family: "Trebuchet MS",Helvetica,sans-serif;
- font-size: 1.70em;
padding-top: 10px;
}
#page-header p {
- font-size: 1.00em;
+ font-size: 1em;
}
#page-header p#skip {
@@ -227,13 +252,13 @@ li {
}
#content {
- padding: 30px 10px 10px;
position: relative;
+ padding: 30px 10px 10px;
}
#content h1 {
- color: #115098;
line-height: 1.2em;
+ color: #115098;
margin-bottom: 0;
}
@@ -253,29 +278,30 @@ li {
}
.rtl .main {
- margin-left: 0;
margin-right: 210px;
+ margin-left: 0;
}
#page-body.simple-page-body {
+ min-width: 0;
padding: 0;
padding-right: 10px;
- min-width: 0;
}
-@media only screen and (max-width: 700px), only screen and (max-device-width: 700px)
-{
- #wrap, #page-body, #page-body.simple-page-body {
- padding: 0;
+@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) {
+ #wrap,
+ #page-body,
+ #page-body.simple-page-body {
min-width: 300px;
+ padding: 0;
}
#page-header {
- margin: 5px;
- padding-left: 160px;
+ overflow: hidden;
height: auto;
min-height: 54px;
- overflow: hidden;
+ margin: 5px;
+ padding-left: 160px;
}
.rtl #page-header {
@@ -286,22 +312,25 @@ li {
#page-header h1 {
font-size: 1.2em;
white-space: nowrap;
- overflow: hidden;
text-overflow: ellipsis;
+ overflow: hidden;
}
#page-header fieldset {
margin-top: 5px;
}
- #main, .rtl #main, .main, .rtl .main {
+ #main,
+ .rtl #main,
+ .main,
+ .rtl .main {
float: none;
width: auto;
margin: 0;
}
#content {
- background: #F3F3F3 url("../images/innerbox_bg.gif") repeat-x top;
+ background: #f3f3f3 url("../images/innerbox_bg.gif") repeat-x top;
padding: 5px;
}
@@ -310,12 +339,11 @@ li {
}
}
-@media only screen and (max-width: 400px), only screen and (max-device-width: 400px)
-{
+@media only screen and (max-width: 400px), only screen and (max-device-width: 400px) {
#page-header {
background-size: 76px 26.5px;
- padding-left: 80px;
min-height: 30px;
+ padding-left: 80px;
}
.rtl #page-header {
@@ -323,34 +351,33 @@ li {
}
#page-header h1 {
- padding-top: 0;
font-size: 1.1em;
+ padding-top: 0;
}
}
-
/* Tabbed menu
-----------------------------------------*/
+---------------------------------------- */
#tabs {
font-family: Arial, Helvetica, sans-serif;
line-height: normal;
- margin: 0 7px;
position: relative;
z-index: 2;
+ margin: 0 7px;
}
#tabs > ul {
- list-style: none;
margin: 0;
padding: 0;
+ list-style: none;
}
#tabs .tab {
- display: inline-block;
- float: left;
font-size: 0.85em;
font-weight: bold;
line-height: 14px;
+ display: inline-block;
+ float: left;
}
.rtl #tabs .tab {
@@ -358,47 +385,37 @@ li {
}
#tabs .tab > a {
- background: #D4D6DA;
- background: -moz-linear-gradient(top, #CACBCF 0%, #D4D6DA 100%);
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #CACBCF), color-stop(100%, #D4D6DA));
- background: -webkit-linear-gradient(top, #CACBCF 0%, #D4D6DA 100%);
- background: -o-linear-gradient(top, #CACBCF 0%, #D4D6DA 100%);
- background: -ms-linear-gradient(top, #CACBCF 0%, #D4D6DA 100%);
- background: linear-gradient(to bottom, #CACBCF 0%, #D4D6DA 100%);
- border: 1px solid #BBB;
+ font-weight: bold;
+ white-space: nowrap;
+ text-decoration: none;
+ text-transform: uppercase;
+ background: #d4d6da;
+ background: linear-gradient(to bottom, #cacbcf 0%, #d4d6da 100%);
+ border: 1px solid #bbbbbb;
border-bottom-width: 0;
border-radius: 5px 5px 0 0;
color: #767676;
+ position: relative;
display: block;
- font-weight: bold;
margin: 1px 1px 2px 0;
padding: 6px 9px 4px;
- position: relative;
- text-decoration: none;
- text-transform: uppercase;
- white-space: nowrap;
cursor: pointer;
}
#tabs .tab > a:hover {
- background: #F1F1EE;
- border-color: #C0BFBB;
- color: #BC2A4D;
+ background: #f1f1ee;
+ border-color: #c0bfbb;
+ color: #bc2a4d;
}
#tabs .activetab > a,
#tabs .activetab > a:hover {
- background: #DCDEE2;
- background: -moz-linear-gradient(top, #F2F2F2 0%, #DCDEE2 100%);
- background: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #F2F2F2), color-stop(100%, #DCDEE2));
- background: -webkit-linear-gradient(top, #F2F2F2 0%, #DCDEE2 100%);
- background: -o-linear-gradient(top, #F2F2F2 0%, #DCDEE2 100%);
- background: -ms-linear-gradient(top, #F2F2F2 0%, #DCDEE2 100%);
- background: linear-gradient(to bottom, #F2F2F2 0%, #DCDEE2 100%);
- border-color: #999;
- border-bottom: 2px solid #DCDEE2;
- box-shadow: 0 1px 1px #FFF inset;
- color: #23649F;
+ background: #dcdee2;
+ background: linear-gradient(to bottom, #f2f2f2 0%, #dcdee2 100%);
+ border-color: #999999;
+ border-bottom: 2px solid #dcdee2;
+ box-shadow: 0 1px 1px #ffffff inset;
+ color: #23649f;
margin: 0 1px 0 0;
padding: 7px 10px 4px;
}
@@ -408,49 +425,50 @@ li {
}
/* Responsive tabs
-----------------------------------------*/
+---------------------------------------- */
.responsive-tab {
position: relative;
}
.responsive-tab > a.responsive-tab-link {
- display: block;
font-size: 16px;
- position: relative;
- width: 16px;
line-height: 14px;
text-decoration: none;
- padding-left: 9px !important;
+ position: relative;
+ display: block;
+ width: 16px;
padding-right: 9px !important;
+ padding-left: 9px !important;
}
.responsive-tab .responsive-tab-link:before {
- content: '';
+ border-top: 0.375em double #767676;
+ border-bottom: 0.125em solid #767676;
position: absolute;
- left: 10px;
top: 7px;
- height: .125em;
+ left: 10px;
width: 14px;
- border-bottom: 0.125em solid #767676;
- border-top: 0.375em double #767676;
+ height: 0.125em;
+ content: "";
}
.responsive-tab .responsive-tab-link:hover:before {
- border-color: #BC2A4D;
+ border-color: #bc2a4d;
}
.responsive-tab.activetab .responsive-tab-link:before {
- border-color: #23649F;
+ border-color: #23649f;
}
.responsive-tab.activetab .responsive-tab-link:hover:before {
border-color: #115098;
}
-#tabs .dropdown, #minitabs .dropdown {
+#tabs .dropdown,
+#minitabs .dropdown {
+ font-weight: normal;
top: 20px;
margin-right: -2px;
- font-weight: normal;
}
#tabs .dropdown-right .dropdown {
@@ -458,12 +476,12 @@ li {
}
#tabs .dropdown-contents {
- list-style: none;
margin: 0;
+ list-style: none;
}
#tabs .dropdown li {
- border-bottom: 1px dotted #DCDCDC;
+ border-bottom: 1px dotted #dcdcdc;
}
#tabs .dropdown li:last-child {
@@ -471,23 +489,23 @@ li {
}
#tabs .dropdown a {
+ text-align: right;
display: block;
padding: 4px 8px;
- text-align: right;
}
/* Main Panel
---------------------------------------- */
#acp {
+ background: #f3f3f3 url("../images/innerbox_bg.gif") repeat-x top;
+ border: 1px #999999 solid;
+ border-radius: 5px;
+ box-shadow: #ffffff 0 0 0 1px inset;
position: relative;
top: -2px;
+ min-width: 550px;
margin: 0 0 2px;
padding: 3px 1px;
- min-width: 550px;
- background: #F3F3F3 url("../images/innerbox_bg.gif") repeat-x top;
- border: 1px #999999 solid;
- border-radius: 5px;
- box-shadow: #FFF 0 0 0 1px inset;
}
#acp:first-child {
@@ -495,22 +513,21 @@ li {
}
.panel {
- background: #F3F3F3 url("../images/innerbox_bg.gif") repeat-x top;
- padding: 5px 0;
+ background: #f3f3f3 url("../images/innerbox_bg.gif") repeat-x top;
border-radius: 5px;
overflow: hidden;
+ padding: 5px 0;
}
-@media only screen and (max-width: 700px), only screen and (max-device-width: 700px)
-{
+@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) {
#acp {
+ background: #ffffff;
+ border-width: 1px 0;
+ border-radius: 0;
+ box-shadow: none;
min-width: 0;
min-height: 0;
- border-radius: 0;
- border-width: 1px 0;
- background: #fff;
padding: 1px 0;
- box-shadow: none;
}
}
@@ -519,18 +536,18 @@ li {
/* Menu */
#menu {
+ font-size: 1em;
+ border-right: 1px solid #cccfd3;
+ position: relative;
float: left;
width: 200px;
- font-size: 1.00em;
padding: 0;
- border-right: 1px solid #CCCFD3;
- position: relative;
}
.rtl #menu {
- float: right;
border: none;
- border-left: 1px solid #CCCFD3;
+ border-left: 1px solid #cccfd3;
+ float: right;
}
#menu p {
@@ -538,104 +555,111 @@ li {
}
#menu ul {
- list-style: none;
+ word-wrap: normal;
margin: 0;
padding: 0;
- word-wrap: normal;
+ list-style: none;
}
/* Default list state */
-#menu li, #menu .header {
- padding: 0;
- margin: 0;
+#menu li,
+#menu .header {
font-size: 0.85em;
font-weight: bold;
display: block;
+ margin: 0;
+ padding: 0;
}
/* Link styles for the sub-section links */
#menu li span {
+ font-weight: normal;
+ text-decoration: none;
+ color: #138ecb;
display: block;
- padding: 3px 3px 3px 8px;
margin: 1px 0;
- text-decoration: none;
- font-weight: normal;
- color: #138ECB;
+ padding: 3px 3px 3px 8px;
}
.rtl #menu li span {
padding: 3px 8px 3px 3px;
}
-#menu li a:hover, #menu li a:hover span {
+#menu li a:hover,
+#menu li a:hover span {
text-decoration: none;
- background-color: #FFFFFF;
- color: #BC2A4D;
+ background-color: #ffffff;
+ color: #bc2a4d;
}
-#menu li a:active, #menu li a:active span {
- color: #F632A0;
+#menu li a:active,
+#menu li a:active span {
+ color: #f632a0;
}
#menu li#activemenu a span {
- text-decoration: none;
font-weight: bold;
- color: #1180B7;
+ text-decoration: none;
background: transparent url("../images/arrow_right.gif") 0% 50% no-repeat;
+ color: #1180b7;
}
.rtl #menu li#activemenu a span {
background: transparent url("../images/arrow_left.gif") 100% 50% no-repeat;
}
-#menu li#activemenu a:hover span, #menu li#activemenu span {
- text-decoration: none;
+#menu li#activemenu a:hover span,
+#menu li#activemenu span {
font-weight: bold;
- color: #BC2A4D;
- background: #FFFFFF url("../images/arrow_right.gif") 1% 50% no-repeat;
+ text-decoration: none;
+ background: #ffffff url("../images/arrow_right.gif") 1% 50% no-repeat;
+ color: #bc2a4d;
}
-.rtl #menu li#activemenu a:hover span, .rtl #menu li#activemenu span {
- background: #FFFFFF url("../images/arrow_left.gif") 99% 50% no-repeat;
+.rtl #menu li#activemenu a:hover span,
+.rtl #menu li#activemenu span {
+ background: #ffffff url("../images/arrow_left.gif") 99% 50% no-repeat;
}
-#menu li a:active, #menu li a:active span, #menu li#activemenu a:active span {
- color: #F632A0;
+#menu li a:active,
+#menu li a:active span,
+#menu li#activemenu a:active span {
+ color: #f632a0;
}
#menu li span.completed {
text-decoration: none;
- padding: 3px 3px 3px 12px;
background: url("../images/arrow_down.gif") 1% 50% no-repeat;
+ padding: 3px 3px 3px 12px;
}
.rtl #menu li span.completed {
text-decoration: none;
- padding: 3px 12px 3px 3px;
background: url("../images/arrow_down.gif") 99% 50% no-repeat;
+ padding: 3px 12px 3px 3px;
}
#menu .header {
font-family: Tahoma, Helvetica, sans-serif;
- display: block;
+ font-size: 0.75em;
font-weight: bold;
+ text-decoration: none;
+ text-transform: uppercase;
+ border-bottom: 1px solid #327aa5;
+ outline-style: none;
color: #115098;
- border-bottom: 1px solid #327AA5;
- padding: 4px 0 2px;
+ display: block;
margin-top: 15px;
- text-transform: uppercase;
- font-size: 0.75em;
- text-decoration: none;
+ padding: 4px 0 2px;
cursor: inherit;
- outline-style: none;
}
-@media only screen and (max-width: 700px), only screen and (max-device-width: 700px)
-{
- #menu, .rtl #menu {
+@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) {
+ #menu,
+ .rtl #menu {
+ border-width: 0;
float: none;
width: auto;
- border-width: 0;
max-width: 200px;
margin: 0 auto 10px;
}
@@ -645,10 +669,10 @@ li {
}
#menu .menu-block.active {
+ background: rgba(255, 255, 255, 0.5);
+ border-radius: 5px;
margin: 0 -5px;
padding: 0 5px 3px;
- background: rgba(255, 255, 255, .5);
- border-radius: 5px;
}
#menu .menu-block.no-header.active {
@@ -656,31 +680,35 @@ li {
}
#menu .menu-block .header {
- margin-top: 5px;
- cursor: pointer;
+ text-decoration: underline;
border-bottom-width: 0;
position: relative;
- text-decoration: underline;
+ margin-top: 5px;
+ cursor: pointer;
}
- #menu .menu-block .header:focus, #menu .menu-block.active .header {
- color: #D31141;
+ #menu .menu-block .header:focus,
+ #menu .menu-block.active .header {
text-decoration: none;
+ color: #d31141;
}
#menu .menu-block ul {
display: none;
}
- .nojs #menu .menu-block:hover ul, #menu .menu-block.active ul, #menu .menu-block.no-header ul {
+ .nojs #menu .menu-block:hover ul,
+ #menu .menu-block.active ul,
+ #menu .menu-block.no-header ul {
display: block;
}
#menu .menu-block li:last-child {
- border-bottom: 1px solid #327AA5;
+ border-bottom: 1px solid #327aa5;
}
- #menu .menu-block:last-child li:last-child, #menu .menu-block.active li:last-child {
+ #menu .menu-block:last-child li:last-child,
+ #menu .menu-block.active li:last-child {
border-bottom-width: 0;
}
@@ -689,36 +717,35 @@ li {
}
}
-
/* Table styles
---------------------------------------- */
-
table {
+ background-color: #ffffff;
+ border: 1px solid #cccfd3;
width: 100%;
- border: 1px solid #CCCFD3;
- background-color: #FFFFFF;
padding: 1px;
}
th {
- padding: 3px 4px;
- color: #FFFFFF;
- background: #70AED3 url("../images/gradient2b.gif") bottom left repeat-x;
- border-top: 1px solid #6DACD2;
- border-bottom: 1px solid #327AA5;
- text-align: left;
font-size: 0.75em;
+ text-align: left;
text-transform: uppercase;
+ background: #70aed3 url("../images/gradient2b.gif") bottom left repeat-x;
+ border-top: 1px solid #6dacd2;
+ border-bottom: 1px solid #327aa5;
+ color: #ffffff;
+ padding: 3px 4px;
}
td {
- text-align: left;
font-size: 0.85em;
+ line-height: 1.2em;
+ text-align: left;
padding: 4px;
- line-height: 1.20em;
}
-.rtl th, .rtl td {
+.rtl th,
+.rtl td {
text-align: right;
}
@@ -745,8 +772,8 @@ td {
}
dt#color_palette_placeholder table {
- margin-right: 5px;
width: 80px;
+ margin-right: 5px;
}
#color_palette_placeholder td {
@@ -754,34 +781,34 @@ dt#color_palette_placeholder table {
}
table.type2 {
- border: none;
background: none;
+ border: none;
padding: 0;
}
table.type2 th {
+ text-align: center;
background: none;
border-top: none;
- text-align: center;
color: #115098;
padding: 2px 0;
}
table.type2 td {
- padding: 0;
font-size: 1em;
+ padding: 0;
}
table.type2 td.name {
- padding: 2px;
vertical-align: middle;
+ padding: 2px;
}
-table.type3 {
+table.type3 {
+ background-color: transparent;
+ border: none;
float: right;
width: 300px;
- border: none;
- background-color: transparent;
padding: 0;
}
@@ -790,25 +817,25 @@ table.type3 {
}
table.type3 thead th {
+ font-size: 0.85em;
+ font-weight: normal;
+ text-align: center;
+ text-transform: none;
background-color: transparent;
border-top: none;
- text-align: center;
color: #115098;
padding: 0 3px;
- font-size: 0.85em;
- font-weight: normal;
- text-transform: none;
}
table.type3 tbody th {
- border-top: none;
+ font-size: 0.9em;
+ font-weight: normal;
text-align: left;
text-transform: none;
- padding: 0;
border: none;
- font-size: 0.90em;
- font-weight: normal;
+ border-top: none;
width: 100%;
+ padding: 0;
}
.rtl table.type3 tbody th {
@@ -830,8 +857,8 @@ th.name {
}
td.name {
- text-align: left;
font-weight: bold;
+ text-align: left;
}
.rtl td.name {
@@ -839,8 +866,8 @@ td.name {
}
.entry {
- text-align: left;
font-weight: normal;
+ text-align: left;
}
.rtl .entry {
@@ -848,96 +875,132 @@ td.name {
}
.row1 {
- background-color: #F9F9F9;
+ background-color: #f9f9f9;
}
table.zebra-table tbody tr:nth-child(odd) {
- background-color: #F9F9F9;
+ background-color: #f9f9f9;
}
.row2 {
word-break: break-all;
- background-color: #DCEBFE;
+ background-color: #dcebfe;
}
table.zebra-table tbody tr:nth-child(even) {
- background-color: #DCEBFE;
+ background-color: #dcebfe;
}
-.row3 { background-color: #DBDFE2; }
-.row4 { background-color: #E4E8EB; }
-.col1 { background-color: #DCEBFE; }
-.col2 { background-color: #F9F9F9; }
+.row3 {
+ background-color: #dbdfe2;
+}
+
+.row4 {
+ background-color: #e4e8eb;
+}
+
+.col1 {
+ background-color: #dcebfe;
+}
+
+.col2 {
+ background-color: #f9f9f9;
+}
/* 4 row background colours for trees */
-.row1a { background-color: #F9F9F9; }
-.row1b { background-color: #F6F6F6; }
-.row2a { background-color: #E7EEF4; }
-.row2b { background-color: #E3EBF2; }
+.row1a {
+ background-color: #f9f9f9;
+}
+
+.row1b {
+ background-color: #f6f6f6;
+}
+
+.row2a {
+ background-color: #e7eef4;
+}
+
+.row2b {
+ background-color: #e3ebf2;
+}
-tr.row-highlight:hover td { background-color: #DBDFE2; }
+tr.row-highlight:hover td {
+ background-color: #dbdfe2;
+}
.spacer {
- background-color: #DBDFE2;
- height: 1px;
line-height: 1px;
+ background-color: #dbdfe2;
+ height: 1px;
}
/* Deactivated row */
.row-inactive {
- color: #999;
+ color: #999999;
}
-.row-inactive a, .row-inactive strong {
- color: #888;
+
+.row-inactive a,
+.row-inactive strong {
+ color: #888888;
}
+
.row-inactive a:hover {
- color: #BC2A4D;
+ color: #bc2a4d;
}
/* Specific tables */
table.forums td.folder {
- width: 27px;
text-align: center;
+ width: 27px;
}
table td.actions {
- vertical-align: middle;
- width: 100px;
text-align: center;
+ vertical-align: middle;
white-space: nowrap;
+ width: 100px;
}
-table tr:first-child td.actions .up, table tr:last-child td.actions .down {
+table tr:first-child td.actions .up,
+table tr:last-child td.actions .down {
display: none;
}
-table tr:first-child td.actions .up-disabled, table tr:last-child td.actions .down-disabled {
+table tr:first-child td.actions .up-disabled,
+table tr:last-child td.actions .down-disabled {
display: inline !important;
}
-table.styles td.users, table td.mark {
+table.styles td.users,
+table td.mark {
text-align: center;
}
table.fixed-width-table {
- table-layout: fixed;
word-break: break-word;
+ table-layout: fixed;
}
-@media only screen and (max-width: 700px), only screen and (max-device-width: 700px)
-{
- table.responsive, table.responsive tbody, table.responsive tr, table.responsive td {
+@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) {
+ table.responsive,
+ table.responsive tbody,
+ table.responsive tr,
+ table.responsive td {
display: block;
}
- table.responsive thead, table.responsive th, table.responsive colgroup {
+ table.responsive thead,
+ table.responsive th,
+ table.responsive colgroup {
display: none;
}
- table.responsive.show-header thead, table.responsive.show-header th:first-child, table.responsive caption {
+ table.responsive.show-header thead,
+ table.responsive.show-header th:first-child,
+ table.responsive caption {
+ text-align: left !important;
display: block;
width: auto !important;
- text-align: left !important;
margin: 0;
}
@@ -948,45 +1011,76 @@ table.fixed-width-table {
}
table.responsive caption {
- padding: 3px 4px;
- color: #FFFFFF;
- background: #70AED3 url("../images/gradient2b.gif") bottom left repeat-x;
- border-top: 1px solid #6DACD2;
- border-bottom: 1px solid #327AA5;
- text-align: left;
font-size: 0.75em;
font-weight: bold;
+ text-align: left;
text-transform: uppercase;
+ background: #70aed3 url("../images/gradient2b.gif") bottom left repeat-x;
+ border-top: 1px solid #6dacd2;
+ border-bottom: 1px solid #327aa5;
+ color: #ffffff;
+ padding: 3px 4px;
}
- table.responsive.show-header th:first-child span.rank-img, table.responsive.no-caption caption, table.responsive.no-header thead {
+ table.responsive.show-header th:first-child span.rank-img,
+ table.responsive.no-caption caption,
+ table.responsive.no-header thead {
display: none;
}
table.responsive tr {
+ background-color: #ffffff;
+ border: 1px solid #cccfd3;
+ overflow: hidden;
margin: 2px 0;
- border: 1px solid #CCCFD3;
- background-color: #FFFFFF;
padding: 1px 1px 0;
- overflow: hidden;
}
- table.responsive tr.row1 td { background-color: #F9F9F9; }
- table.responsive tr.row2 td { background-color: #DCEBFE; }
- table.responsive tr.row3 td { background-color: #DBDFE2; }
- table.responsive tr.row4 td { background-color: #E4E8EB; }
- table.responsive tr.col1 td { background-color: #DCEBFE; }
- table.responsive tr.col2 td { background-color: #F9F9F9; }
- table.responsive tr.row1a td { background-color: #F9F9F9; }
- table.responsive tr.row1b td { background-color: #F6F6F6; }
- table.responsive tr.row2a td { background-color: #E7EEF4; }
- table.responsive tr.row2b td { background-color: #E3EBF2; }
+ table.responsive tr.row1 td {
+ background-color: #f9f9f9;
+ }
+
+ table.responsive tr.row2 td {
+ background-color: #dcebfe;
+ }
+
+ table.responsive tr.row3 td {
+ background-color: #dbdfe2;
+ }
+
+ table.responsive tr.row4 td {
+ background-color: #e4e8eb;
+ }
+
+ table.responsive tr.col1 td {
+ background-color: #dcebfe;
+ }
+
+ table.responsive tr.col2 td {
+ background-color: #f9f9f9;
+ }
+
+ table.responsive tr.row1a td {
+ background-color: #f9f9f9;
+ }
+
+ table.responsive tr.row1b td {
+ background-color: #f6f6f6;
+ }
+
+ table.responsive tr.row2a td {
+ background-color: #e7eef4;
+ }
+
+ table.responsive tr.row2b td {
+ background-color: #e3ebf2;
+ }
table.responsive td {
- width: auto !important;
text-align: left !important;
- padding: 4px;
+ width: auto !important;
margin-bottom: 1px;
+ padding: 4px;
}
.rtl table.responsive td {
@@ -1002,15 +1096,14 @@ table.fixed-width-table {
}
table.responsive td > dfn:after {
- content: ':';
padding-right: 5px;
+ content: ":";
}
table.responsive.two-columns td {
- width: 50% !important;
float: left;
- -moz-box-sizing: border-box;
box-sizing: border-box;
+ width: 50% !important;
}
.rtl table.responsive.two-columns td {
@@ -1032,28 +1125,29 @@ table.fixed-width-table {
/* Specific tables */
table.responsive.forums td.folder {
+ background: transparent;
float: left;
width: 27px;
- background: transparent;
}
+
.rtl table.responsive.forums td.folder {
float: right;
}
table.responsive.forums td.forum-desc {
- margin-left: 35px;
- min-height: 27px;
background: transparent;
+ min-height: 27px;
+ margin-left: 35px;
}
.rtl table.responsive.forums td.forum-desc {
- margin-left: 0;
margin-right: 35px;
+ margin-left: 0;
}
table.responsive td.actions {
- clear: both;
text-align: right !important;
+ clear: both;
}
.rtl table.responsive td.actions {
@@ -1061,15 +1155,17 @@ table.fixed-width-table {
}
table.responsive.styles tr.responsive-style-row td:first-child {
- padding-left: 4px !important;
padding-right: 4px !important;
+ padding-left: 4px !important;
}
- table.responsive.styles td:first-child > dfn, table.responsive td.actions > dfn {
+ table.responsive.styles td:first-child > dfn,
+ table.responsive td.actions > dfn {
display: none !important;
}
- .horizontal-palette td:nth-child(2n), .vertical-palette tr:nth-child(2n) {
+ .horizontal-palette td:nth-child(2n),
+ .vertical-palette tr:nth-child(2n) {
display: none;
}
@@ -1079,17 +1175,17 @@ table.fixed-width-table {
}
/* General form styles
-----------------------------------------*/
+---------------------------------------- */
fieldset {
+ background-color: #ffffff;
+ border-top: 1px solid #d7d7d7;
+ border-right: 1px solid #cccccc;
+ border-bottom: 1px solid #cccccc;
+ border-left: 1px solid #d7d7d7;
+ border-radius: 3px;
+ position: relative;
margin: 15px 0;
padding: 10px;
- border-top: 1px solid #D7D7D7;
- border-right: 1px solid #CCCCCC;
- border-bottom: 1px solid #CCCCCC;
- border-left: 1px solid #D7D7D7;
- background-color: #FFFFFF;
- position: relative;
- border-radius: 3px;
}
fieldset h2 {
@@ -1097,10 +1193,10 @@ fieldset h2 {
}
.rtl fieldset {
- border-top: 1px solid #D7D7D7;
- border-right: 1px solid #D7D7D7;
- border-bottom: 1px solid #CCCCCC;
- border-left: 1px solid #CCCCCC;
+ border-top: 1px solid #d7d7d7;
+ border-right: 1px solid #d7d7d7;
+ border-bottom: 1px solid #cccccc;
+ border-left: 1px solid #cccccc;
}
fieldset p {
@@ -1108,49 +1204,53 @@ fieldset p {
}
legend {
- padding: 1px 0;
- font-family: Tahoma,arial,Verdana,Sans-serif;
- font-size: .9em;
+ font-family: Tahoma, arial, Verdana, Sans-serif;
+ font-size: 0.9em;
font-weight: bold;
- color: #115098;
- margin-top: -.4em;
- position: relative;
- text-transform: none;
line-height: 1.2em;
- top: -.2em;
vertical-align: middle;
+ text-transform: none;
+ color: #115098;
+ position: relative;
+ top: -0.2em;
+ margin-top: -0.4em;
+ padding: 1px 0;
}
-input, textarea {
+input,
+textarea {
font-family: Verdana, Helvetica, Arial, sans-serif;
- font-size: 0.90em;
+ font-size: 0.9em;
font-weight: normal;
vertical-align: middle;
- padding: 2px;
+ background-color: #e3dfd8;
+ border-top: 1px solid #afaeaa;
+ border-right: 1px solid #d5d5c8;
+ border-bottom: 1px solid #d5d5c8;
+ border-left: 1px solid #afaeaa;
color: #111111;
- border-left: 1px solid #AFAEAA;
- border-top: 1px solid #AFAEAA;
- border-right: 1px solid #D5D5C8;
- border-bottom: 1px solid #D5D5C8;
- background-color: #E3DFD8;
+ padding: 2px;
}
-.rtl input, .rtl textarea {
- border-left: 1px solid #D5D5C8;
- border-top: 1px solid #AFAEAA;
- border-right: 1px solid #AFAEAA;
- border-bottom: 1px solid #D5D5C8;
+.rtl input,
+.rtl textarea {
+ border-top: 1px solid #afaeaa;
+ border-right: 1px solid #afaeaa;
+ border-bottom: 1px solid #d5d5c8;
+ border-left: 1px solid #d5d5c8;
}
-input:hover, textarea:hover {
- border-left: 1px solid #AFAEAA;
- border-top: 1px solid #AFAEAA;
- border-right: 1px solid #AFAEAA;
- border-bottom: 1px solid #AFAEAA;
- background-color: #E9E9E2;
+input:hover,
+textarea:hover {
+ background-color: #e9e9e2;
+ border-top: 1px solid #afaeaa;
+ border-right: 1px solid #afaeaa;
+ border-bottom: 1px solid #afaeaa;
+ border-left: 1px solid #afaeaa;
}
-input.langvalue, textarea.langvalue {
+input.langvalue,
+textarea.langvalue {
width: 90%;
}
@@ -1159,18 +1259,19 @@ input[type="number"] {
-moz-padding-end: 0;
}
-optgroup, select {
- background-color: #FAFAFA;
- border: 1px solid #666666;
+optgroup,
+select {
font-family: Verdana, Helvetica, Arial, sans-serif;
font-size: 0.85em;
font-weight: normal;
font-style: normal;
- cursor: pointer;
- padding: 1px;
vertical-align: middle;
+ background-color: #fafafa;
+ border: 1px solid #666666;
+ color: #000000;
width: auto;
- color: #000;
+ padding: 1px;
+ cursor: pointer;
}
select:focus {
@@ -1178,18 +1279,18 @@ select:focus {
}
optgroup {
- font-size: 1.00em;
+ font-size: 1em;
font-weight: bold;
}
optgroup.disabled-options {
+ background-color: #808080;
display: none;
- background-color: gray;
}
option {
+ color: #000000;
padding: 0 1em 0 0;
- color: #000;
}
option.disabled-option {
@@ -1216,9 +1317,9 @@ textarea {
}
label {
- cursor: pointer;
font-size: 0.85em;
padding: 0 5px 0 0;
+ cursor: pointer;
}
.rtl label {
@@ -1226,7 +1327,7 @@ label {
}
label input {
- font-size: 1.00em;
+ font-size: 1em;
vertical-align: middle;
}
@@ -1234,28 +1335,42 @@ label img {
vertical-align: middle;
}
-fieldset.quick, p.quick {
+fieldset.quick,
+p.quick {
+ text-align: right;
+ background-color: transparent;
+ border: none;
margin: 0 0 5px;
padding: 5px 0 0;
- border: none;
- background-color: transparent;
- text-align: right;
}
-.rtl fieldset.quick, .rtl p.quick {
+.rtl fieldset.quick,
+.rtl p.quick {
text-align: left;
}
+fieldset.quick-left,
+p.quick-left {
+ float: left;
+ margin: 15px 0 5px;
+ padding: 0;
+}
+
+.rtl fieldset.quick-left,
+.rtl p.quick-left {
+ float: right;
+}
+
fieldset.quick legend {
display: none;
}
fieldset.tabulated {
background: none;
+ border: 0;
margin: 0;
margin-top: 5px;
padding: 0;
- border: 0;
}
fieldset.tabulated legend {
@@ -1263,29 +1378,31 @@ fieldset.tabulated legend {
}
fieldset.nobg {
- margin: 15px 0 0 0;
- padding: 0;
- border: none;
background-color: transparent;
+ border: none;
+ margin: 15px 0 0;
+ padding: 0;
}
fieldset.display-options {
- margin: 15px 0 2px 0;
- padding: 0 0 4px 0;
- border: none;
- background-color: transparent;
- text-align: center;
font-size: 0.85em;
+ text-align: center;
+ background-color: transparent;
+ border: none;
+ margin: 15px 0 2px;
+ padding: 0 0 4px;
}
-fieldset.display-options select, fieldset.display-options input, fieldset.display-options label {
- font-size: 1.00em;
+fieldset.display-options select,
+fieldset.display-options input,
+fieldset.display-options label {
+ font-size: 1em;
vertical-align: middle;
}
select option.disabled {
- background-color: #bbb;
- color: #fff;
+ background-color: #bbbbbb;
+ color: #ffffff;
}
/* Special case inputs */
@@ -1294,15 +1411,15 @@ select#full_folder_action {
width: 95%;
}
-@media only screen and (max-width: 700px), only screen and (max-device-width: 700px)
-{
+@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) {
fieldset {
padding: 5px;
}
- fieldset.quick, p.quick {
- float: none !important;
+ fieldset.quick,
+ p.quick {
text-align: center;
+ float: none !important;
}
fieldset.display-options {
@@ -1315,7 +1432,7 @@ select#full_folder_action {
---------------------------------------- */
dl {
font-family: Verdana, Helvetica, Arial, sans-serif;
- font-size: 1.00em;
+ font-size: 1em;
}
dt {
@@ -1327,18 +1444,31 @@ dt {
float: right;
}
-dd { color: #666666;}
-dd + dd { padding-top: 5px;}
-dt span { padding: 0 5px 0 0;}
-.rtl dt span { padding: 0 0 0 5px;}
+dd {
+ color: #666666;
+}
+
+dd + dd {
+ padding-top: 5px;
+}
+
+dt span {
+ padding: 0 5px 0 0;
+}
-dt .explain { font-style: italic;}
+.rtl dt span {
+ padding: 0 0 0 5px;
+}
+
+dt .explain {
+ font-style: italic;
+}
dt label {
- font-size: 1.00em;
- text-align: left;
+ font-size: 1em;
font-weight: bold;
- color: #4A5A73;
+ text-align: left;
+ color: #4a5a73;
}
.rtl dt label {
@@ -1346,20 +1476,23 @@ dt label {
}
dd label {
- font-size: 1.00em;
+ font-size: 1em;
white-space: nowrap;
+ color: #4a5a73;
margin: 0 10px 0 0;
- color: #4A5A73;
}
.rtl dd label {
margin: 0 0 0 10px;
}
-html>body dd label input { vertical-align: text-bottom;} /* Tweak for Moz to align checkboxes/radio buttons nicely */
+html > body dd label input {
+ vertical-align: text-bottom;
+}
+/* Tweak for Moz to align checkboxes/radio buttons nicely */
dd input {
- font-size: 1.00em;
+ font-size: 1em;
max-width: 100%;
margin: 2px 0;
}
@@ -1373,27 +1506,27 @@ dd select {
}
dd textarea {
- font-size: 0.90em;
+ font-size: 0.9em;
width: 90%;
}
fieldset dl {
- margin-bottom: 10px;
font-size: 0.85em;
+ margin-bottom: 10px;
}
fieldset dt {
- width: 45%;
text-align: left;
border: none;
- border-right: 1px solid #CCCCCC;
+ border-right: 1px solid #cccccc;
+ width: 45%;
padding-top: 3px;
}
.rtl fieldset dt {
text-align: right;
border: none;
- border-left: 1px solid #CCCCCC;
+ border-left: 1px solid #cccccc;
}
fieldset #color_palette_placeholder {
@@ -1401,32 +1534,34 @@ fieldset #color_palette_placeholder {
}
fieldset dd {
+ font-size: 1em;
+ vertical-align: top;
+ border: none;
+ border-left: 1px solid #cccccc;
margin: 0 0 0 45%;
padding: 0 0 0 5px;
- border: none;
- border-left: 1px solid #CCCCCC;
- vertical-align: top;
- font-size: 1.00em;
}
.rtl fieldset dd {
+ border: none;
+ border-right: 1px solid #cccccc;
margin: 0 45% 0 0;
padding: 0 5px 0 0;
- border: none;
- border-right: 1px solid #CCCCCC;
}
-dd.full, .rtl dd.full {
- margin: 0;
+dd.full,
+.rtl dd.full {
+ text-align: center;
border: 0;
+ width: 95%;
+ margin: 0;
padding: 0;
padding-top: 3px;
- text-align: center;
- width: 95%;
}
/* Hover highlights for form rows */
-fieldset dl:hover dt, fieldset dl:hover dd {
+fieldset dl:hover dt,
+fieldset dl:hover dd {
border-color: #666666;
}
@@ -1435,35 +1570,39 @@ fieldset dl:hover dt label {
}
fieldset dl dd label:hover {
- color: #BC2A4D;
+ color: #bc2a4d;
}
-input:focus, textarea:focus {
- border: 1px solid #BC2A4D;
- background-color: #E9E9E2;
- color: #BC2A4D;
+input:focus,
+textarea:focus {
+ background-color: #e9e9e2;
+ border: 1px solid #bc2a4d;
outline-style: none;
+ color: #bc2a4d;
}
-@media only screen and (max-width: 700px), only screen and (max-device-width: 700px)
-{
+@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) {
fieldset dl {
+ border-bottom: 1px solid #e8e8e8;
margin-bottom: 5px;
padding-bottom: 5px;
- border-bottom: 1px solid #e8e8e8;
}
- fieldset > dl:last-child, fieldset > form:last-child > dl:last-child {
+ fieldset > dl:last-child,
+ fieldset > form:last-child > dl:last-child {
border-bottom-width: 0;
margin-bottom: 0;
}
- fieldset dt, .rtl fieldset dt, fieldset dd, .rtl fieldset dd {
+ fieldset dt,
+ .rtl fieldset dt,
+ fieldset dd,
+ .rtl fieldset dd {
border-width: 0;
- margin-left: 0;
- margin-right: 0;
float: none;
width: auto;
+ margin-right: 0;
+ margin-left: 0;
}
fieldset .responsive-columns dt {
@@ -1478,18 +1617,22 @@ input:focus, textarea:focus {
padding-right: 20px;
}
- select, dd select, dd input {
+ select,
+ dd select,
+ dd input {
max-width: 300px;
}
- input[type="number"], dd input[type="number"] {
+ input[type="number"],
+ dd input[type="number"] {
max-width: 70px;
}
}
-@media only screen and (max-width: 400px), only screen and (max-device-width: 400px)
-{
- select, dd select, dd input {
+@media only screen and (max-width: 400px), only screen and (max-device-width: 400px) {
+ select,
+ dd select,
+ dd input {
max-width: 240px;
}
}
@@ -1498,21 +1641,22 @@ input:focus, textarea:focus {
---------------------------------------- */
fieldset.submit-buttons {
text-align: center;
- border: none;
background-color: transparent;
+ border: none;
margin: 0;
- padding: 4px;
margin-top: -1px;
+ padding: 4px;
}
p.submit-buttons {
text-align: center;
margin: 0;
- padding: 4px;
margin-top: 10px;
+ padding: 4px;
}
-fieldset.submit-buttons input, p.submit-buttons input {
+fieldset.submit-buttons input,
+p.submit-buttons input {
padding: 3px 2px;
}
@@ -1520,8 +1664,7 @@ fieldset.submit-buttons legend {
display: none;
}
-@media only screen and (max-width: 700px), only screen and (max-device-width: 700px)
-{
+@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) {
p.submit-buttons {
margin-top: 0;
}
@@ -1529,11 +1672,12 @@ fieldset.submit-buttons legend {
/* Input field styles
---------------------------------------- */
-
-input.radio, input.checkbox, input.permissions-checkbox {
- width: auto !important;
+input.radio,
+input.checkbox,
+input.permissions-checkbox {
background-color: transparent;
border: none;
+ width: auto !important;
cursor: pointer;
}
@@ -1542,49 +1686,75 @@ textarea.full {
width: 99%;
}
-input.medium { width: 50%;}
-input.narrow { width: 25%;}
-input.tiny { width: 10%;}
-input.autowidth { width: auto !important;}
-.box2 .inputbox { background-color: #E9E9E9;}
+input.medium {
+ width: 50%;
+}
+
+input.narrow {
+ width: 25%;
+}
+
+input.tiny {
+ width: 10%;
+}
+
+input.autowidth {
+ width: auto !important;
+}
+
+.box2 .inputbox {
+ background-color: #e9e9e9;
+}
/* Form button styles
---------------------------------------- */
-a.button1, input.button1,
-a.button2, input.button2 {
- width: auto !important;
- padding: 1px 3px 0 3px;
+a.button1,
+input.button1,
+a.button2,
+input.button2 {
font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif;
- color: #000;
font-size: 0.85em;
- background: #EFEFEF url("../images/bg_button.gif") repeat-x top;
+ background: #efefef url("../images/bg_button.gif") repeat-x top;
+ color: #000000;
+ width: auto !important;
+ padding: 1px 3px 0;
cursor: pointer;
}
-a.button1, input.button1 {
+a.button1,
+input.button1 {
font-weight: bold;
border: 1px solid #666666;
}
/* Alternative button */
-a.button2, input.button2 {
+a.button2,
+input.button2 {
border: 1px solid #666666;
}
/* <a> button in the style of the form buttons */
-a.button1, a.button1:link, a.button1:visited, a.button1:active,
-a.button2, a.button2:link, a.button2:visited, a.button2:active {
+a.button1,
+a.button1:link,
+a.button1:visited,
+a.button1:active,
+a.button2,
+a.button2:link,
+a.button2:visited,
+a.button2:active {
text-decoration: none;
color: #000000;
padding: 4px 8px;
}
/* Hover states */
-a.button1:hover, input.button1:hover,
-a.button2:hover, input.button2:hover {
- border: 1px solid #BC2A4D;
- background: #EFEFEF url("../images/bg_button.gif") repeat bottom;
- color: #BC2A4D;
+a.button1:hover,
+input.button1:hover,
+a.button2:hover,
+input.button2:hover {
+ background: #efefef url("../images/bg_button.gif") repeat bottom;
+ border: 1px solid #bc2a4d;
+ color: #bc2a4d;
}
input.disabled {
@@ -1593,43 +1763,44 @@ input.disabled {
}
/* Focus states */
-input.button1:focus, input.button2:focus {
+input.button1:focus,
+input.button2:focus {
outline-style: none;
}
/* jQuery popups
---------------------------------------- */
.phpbb_alert {
- background-color: #FFFFFF;
+ background-color: #ffffff;
border: 1px solid #999999;
position: fixed;
- display: none;
+ z-index: 50;
top: 150px;
- left: 0;
right: 0;
+ left: 0;
+ display: none;
width: 620px;
margin: 0 auto;
- z-index: 50;
padding: 25px;
- padding: 0 25px 20px 25px;
+ padding: 0 25px 20px;
}
.phpbb_alert .alert_close {
+ text-decoration: none !important;
+ background: transparent url("../images/alert_close.png") 0 0 no-repeat;
display: block;
float: right;
+ overflow: hidden;
width: 16px;
height: 16px;
- overflow: hidden;
- text-decoration: none !important;
- background: transparent url("../images/alert_close.png") 0 0 no-repeat;
margin-top: -7px;
margin-right: -31px;
}
+
.phpbb_alert .alert_close:hover {
background-position: 0 -16px;
}
-
.phpbb_alert p {
margin: 8px 0;
padding-bottom: 8px;
@@ -1650,65 +1821,123 @@ input.button1:focus, input.button2:focus {
}
#darkenwrapper {
- display: none;
position: relative;
z-index: 44;
+ display: none;
}
#darken {
+ background-color: #000000;
+ opacity: 0.5;
position: fixed;
- left: 0;
+ z-index: 45;
top: 0;
+ left: 0;
width: 100%;
height: 100%;
- background-color: #000000;
- opacity: 0.5;
- z-index: 45;
}
-@media only screen and (max-height: 500px), only screen and (max-device-width: 500px)
-{
+@media only screen and (max-height: 500px), only screen and (max-device-width: 500px) {
.phpbb_alert {
top: 25px;
}
}
-@media only screen and (max-width: 700px), only screen and (max-device-width: 700px)
-{
+@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) {
.phpbb_alert {
width: auto;
margin: 0 25px;
}
}
-#loading_indicator {
- background: #000000 url("../images/loading.gif") center center no-repeat;
- border-radius: 5px;
- display: none;
- opacity: 0.8;
- margin-top: -50px;
- margin-left: -50px;
- height: 50px;
- width: 50px;
+.loading_indicator {
position: fixed;
- left: 50%;
- top: 50%;
z-index: 51;
+ top: 50%;
+ left: 50%;
+ display: none;
+}
+
+.loader {
+ width: 48px;
+ height: 48px;
+ padding: 12px;
+}
+
+.spinner {
+ animation: rotator 1s linear infinite;
+}
+
+.spinner-path {
+ transform-origin: center;
+ animation: dash 1s ease-in-out infinite, colors 4s ease-in-out infinite;
+ stroke-dasharray: 187;
+ stroke-dashoffset: 0;
+}
+
+@keyframes rotator {
+ 0% {
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ transform: rotate(270deg);
+ }
+}
+
+@keyframes dash {
+ 0% {
+ stroke-dashoffset: 187;
+ }
+
+ 50% {
+ transform: rotate(135deg);
+ stroke-dashoffset: 46.75;
+ }
+
+ 100% {
+ transform: rotate(450deg);
+ stroke-dashoffset: 187;
+ }
+}
+
+@keyframes colors {
+ 0% {
+ stroke: #4285f4;
+ }
+
+ 25% {
+ stroke: #de3e35;
+ }
+
+ 50% {
+ stroke: #f7c223;
+ }
+
+ 75% {
+ stroke: #1b9a59;
+ }
+
+ 100% {
+ stroke: #4285f4;
+ }
}
/* Pagination
---------------------------------------- */
.pagination {
- font-size: .85em;
- height: 1%; /* IE tweak (holly hack) */
- width: auto;
+ font-size: 0.85em;
text-align: right;
+
+ /* IE tweak (holly hack) */
+ width: auto;
+ height: 1%;
margin: 5px 0;
}
.top-pagination {
float: right;
- margin: 15px 0 5px 0;
+ margin: 15px 0 5px;
}
.rtl .pagination {
@@ -1726,71 +1955,85 @@ li.pagination {
.pagination ul {
display: inline-block;
- *display: inline; /* IE7 inline-block hack */
+ *display: inline;
+
+ /* IE7 inline-block hack */
*zoom: 1;
- margin-left: 0;
margin-bottom: 0;
+ margin-left: 0;
}
li.pagination ul {
- margin-top: -2px;
vertical-align: middle;
+ margin-top: -2px;
}
-.pagination ul li, dl .pagination ul li, dl.icon .pagination ul li {
- display: inline;
- padding: 0;
+.pagination ul li,
+dl .pagination ul li,
+dl.icon .pagination ul li {
font-size: 100%;
line-height: normal;
+ display: inline;
+ padding: 0;
}
-.pagination li a, .pagnation li span, li .pagination li a, li .pagnation li span, .pagination li.active span, .pagination li.ellipsis span {
+.pagination li a,
+.pagnation li span,
+li .pagination li a,
+li .pagnation li span,
+.pagination li.active span,
+.pagination li.ellipsis span {
+ font-size: 0.9em;
font-weight: normal;
+ line-height: 1.5em;
text-decoration: none;
- padding: 0 2px;
border: 1px solid transparent;
- font-size: 0.9em;
- line-height: 1.5em;
+ padding: 0 2px;
}
-.pagination li a, .pagination li a:link, .pagination li a:visited {
- color: #5C758C;
- background-color: #ECEDEE;
- border-color: #B4BAC0;
+.pagination li a,
+.pagination li a:link,
+.pagination li a:visited {
+ background-color: #ecedee;
+ border-color: #b4bac0;
+ color: #5c758c;
}
-.pagination li.ellipsis span {
+.pagination li.ellipsis span {
background-color: transparent;
color: #000000;
}
.pagination li.active span {
- color: #FFFFFF;
- background-color: #4692BF;
- border-color: #4692BF;
+ background-color: #4692bf;
+ border-color: #4692bf;
+ color: #ffffff;
}
-.pagination li a:hover, .pagination .active a:hover {
- color: #FFFFFF;
- background-color: #368AD2;
- border-color: #368AD2;
+.pagination li a:hover,
+.pagination .active a:hover {
+ background-color: #368ad2;
+ border-color: #368ad2;
+ color: #ffffff;
}
-.pagination li a:active, .pagination li.active a:active {
- color: #5C758C;
- background-color: #ECEDEE;
- border-color: #B4BAC0;
+.pagination li a:active,
+.pagination li.active a:active {
+ background-color: #ecedee;
+ border-color: #b4bac0;
+ color: #5c758c;
}
-@media only screen and (max-width: 700px), only screen and (max-device-width: 700px)
-{
- .pagination, .rtl .pagination {
- float: none;
+@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) {
+ .pagination,
+ .rtl .pagination {
text-align: center;
+ float: none;
margin: 5px 0;
}
- .pagination li a, .pagination li span {
+ .pagination li a,
+ .pagination li span {
display: inline-block;
min-width: 10px;
}
@@ -1798,12 +2041,14 @@ li.pagination ul {
/* Action Highlighting
---------------------------------------- */
-.successbox, .errorbox, .warningbox {
- padding: 8px;
- margin: 10px 0;
- color: #FFFFFF;
+.successbox,
+.errorbox,
+.warningbox {
text-align: center;
+ color: #ffffff;
clear: both;
+ margin: 10px 0;
+ padding: 8px;
}
.success {
@@ -1811,7 +2056,7 @@ li.pagination ul {
}
.error {
- color: #BC2A4D;
+ color: #bc2a4d;
}
.successbox {
@@ -1819,52 +2064,59 @@ li.pagination ul {
}
.errorbox {
- background-color: #BC2A4D;
+ background-color: #bc2a4d;
}
.warningbox {
background-color: #fca600;
}
-.successbox h3, .errorbox h3 {
- color: #FFFFFF;
+.successbox h3,
+.errorbox h3 {
+ font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif;
+ font-size: 1.1em;
+ color: #ffffff;
margin: 0 0 0.5em;
- font-size: 1.10em;
- font-family: "Lucida Grande",Verdana,Helvetica,Arial,sans-serif;
}
-.successbox p, .errorbox p {
- color: #FFFFFF;
+.successbox p,
+.errorbox p {
font-size: 0.85em;
+ color: #ffffff;
margin-bottom: 0;
}
-.errorbox a:link, .errorbox a:active, .errorbox a:visited,
-.successbox a:link, .successbox a:active, .successbox a:visited {
- color: #DBD7D1;
- text-decoration: underline;
+.errorbox a:link,
+.errorbox a:active,
+.errorbox a:visited,
+.successbox a:link,
+.successbox a:active,
+.successbox a:visited {
font-weight: bold;
+ text-decoration: underline;
+ color: #dbd7d1;
}
-.errorbox a:hover, .successbox a:hover {
- color: #FFFFFF;
- text-decoration: none;
+.errorbox a:hover,
+.successbox a:hover {
font-weight: bold;
+ text-decoration: none;
+ color: #ffffff;
}
#log-container {
+ background-color: #ffffff;
display: none;
- max-height: 300px;
- padding: 8px;
- margin: 10px 0;
clear: both;
overflow-y: auto;
- background-color: #FFFFFF;
+ max-height: 300px;
+ margin: 10px 0;
+ padding: 8px;
}
#log-container.show_log_container {
+ border: 1px solid #dbd7d1;
display: block;
- border: 1px solid #DBD7D1;
}
.log {
@@ -1872,11 +2124,11 @@ li.pagination ul {
}
.notice {
- background-color: #62A5CC;
+ background-color: #62a5cc;
}
.download-box {
- margin: 10px 0 10px 0;
+ margin: 10px 0;
}
/* Special cases for the error page */
@@ -1890,61 +2142,63 @@ li.pagination ul {
}
#errorpage #content h1 {
- color: #DF075C;
+ color: #df075c;
}
#errorpage #content h2 {
+ border-bottom: 1px solid #cccccc;
+ color: #333333;
margin-top: 20px;
margin-bottom: 5px;
- border-bottom: 1px solid #CCCCCC;
padding-bottom: 5px;
- color: #333333;
}
/* Tooltip for permission roles */
.tooltip {
- width: 200px;
- color: #000;
text-align: center;
- border: 1px solid #AAA;
+ border: 1px solid #aaaaaa;
+ color: #000000;
+ width: 200px;
}
.tooltip span.top {
- background: #EFEFEF;
font-weight: bold;
+ background: #efefef;
padding: 2px;
}
.tooltip span.bottom {
- padding: 5px;
+ background: #ffffff;
color: #000000;
- background: #FFFFFF;
+ padding: 5px;
}
/*
Format Buttons for signature editor
*/
#format-buttons {
- margin: 15px 0 2px 0;
+ margin: 15px 0 2px;
}
-#format-buttons input, #format-buttons select {
+#format-buttons input,
+#format-buttons select {
vertical-align: middle;
}
-.row, fieldset dl {
+.row,
+fieldset dl {
overflow: hidden;
}
/* Syntax Highlighting
---------------------------------------- */
.sourcenum {
- color: gray;
- font-family: Monaco, 'Courier New', monospace;
+ font-family: Monaco, "Courier New", monospace;
font-size: 1.25em;
font-weight: bold;
- line-height: 1.20em;
+ line-height: 1.2em;
text-align: right;
+ color: #808080;
padding: 0;
}
@@ -1953,22 +2207,22 @@ li.pagination ul {
}
.source {
- font-family: Monaco, 'Courier New', monospace;
+ font-family: Monaco, "Courier New", monospace;
font-size: 1.25em;
- line-height: 1.20em;
+ line-height: 1.2em;
padding: 0;
}
.syntaxbg {
- color: #FFFFFF;
+ color: #ffffff;
}
.syntaxcomment {
- color: #FF8000;
+ color: #ff8000;
}
.syntaxdefault {
- color: #0000BB;
+ color: #0000bb;
}
.syntaxhtml {
@@ -1980,18 +2234,19 @@ li.pagination ul {
}
.syntaxstring {
- color: #DD0000;
+ color: #dd0000;
}
/* Permission interface
---------------------------------------- */
-
-.column1, .column2 {
- width: 48%;
+.column1,
+.column2 {
float: left;
+ width: 48%;
}
-.ltr .column2, .rtl .column1 {
+.ltr .column2,
+.rtl .column1 {
float: right;
}
@@ -1999,7 +2254,7 @@ fieldset.permissions legend {
text-transform: none;
}
-fieldset.permissions legend input{
+fieldset.permissions legend input {
height: 1.1em;
}
@@ -2014,14 +2269,14 @@ fieldset.permissions .permissions-simple {
}
fieldset.permissions .permissions-advanced {
- padding: 10px 0 0 5px;
vertical-align: top;
clear: right;
+ padding: 10px 0 0 5px;
}
.rtl fieldset.permissions .permissions-advanced {
- padding: 10px 5px 0 0;
clear: left;
+ padding: 10px 5px 0 0;
}
fieldset.permissions .permissions-switch {
@@ -2032,12 +2287,9 @@ fieldset.permissions .permissions-switch {
float: left;
}
-fieldset.permissions .padding {
-}
-
.permissions-switch {
+ font-size: 0.9em;
margin-top: -6px;
- font-size: .9em;
}
.permissions-switch a {
@@ -2049,15 +2301,15 @@ fieldset.permissions .padding {
}
.permissions-reset a {
- font-size: .85em;
+ font-size: 0.85em;
}
/* Tabbed menu */
.permissions-category {
+ font-size: 0.85em;
line-height: normal;
- margin: 0 0 -1px 7px;
min-width: 570px;
- font-size: 0.85em;
+ margin: 0 0 -1px 7px;
}
.rtl .permissions-category {
@@ -2071,20 +2323,20 @@ fieldset.permissions .padding {
}
.permissions-category li {
+ font-size: 1em;
+ font-weight: bold;
display: inline;
margin: 0;
padding: 0;
- font-size: 1em;
- font-weight: bold;
}
.permissions-category a {
- float: left;
+ text-decoration: none;
background: url("../images/bg_tabs_alt1.gif") no-repeat 0% -35px;
+ position: relative;
+ float: left;
margin: 0 1px 0 0;
padding: 0 0 0 6px;
- text-decoration: none;
- position: relative;
}
.rtl .permissions-category a {
@@ -2092,24 +2344,28 @@ fieldset.permissions .padding {
}
.permissions-category a span.tabbg {
- float: left;
- display: block;
+ white-space: nowrap;
background: url("../images/bg_tabs_alt2.gif") no-repeat 100% -35px;
- padding: 7px 12px 6px 6px;
color: #536482;
- white-space: nowrap;
+ display: block;
+ float: left;
+ padding: 7px 12px 6px 6px;
}
.rtl .permissions-category a span.tabbg {
float: right;
}
-/* Commented Backslash Hack hides rule from IE5-Mac \*/
-.permissions-category a span.tabbg, .rtl .permissions-category a span.tabbg { float: none;}
-/* End hack */
+/* Commented Backslash Hack hides rule from IE5-Mac \ */
+.permissions-category a span.tabbg,
+.rtl .permissions-category a span.tabbg {
+ float: none;
+}
+/* End hack */
.permissions-category a:hover span.tabbg {
- color: #DD6900;
+ background-position: 100% -70px;
+ color: #dd6900;
}
.permissions-category .activetab a {
@@ -2118,21 +2374,17 @@ fieldset.permissions .padding {
.permissions-category .activetab a span.tabbg {
background-position: 100% 0;
- padding-bottom: 7px;
color: #333333;
+ padding-bottom: 7px;
}
.permissions-category a:hover {
background-position: 0 -70px;
}
-.permissions-category a:hover span.tabbg {
- background-position: 100% -70px;
-}
-
.permissions-category .activetab a:hover span.tabbg {
- color: #333333;
background-position: 100% 0;
+ color: #333333;
}
.permissions-category .activetab a:hover {
@@ -2154,13 +2406,12 @@ fieldset.permissions .padding {
margin: 0 0 0 5px;
}
*/
-
.permissions-category .activetab span.colour {
border-color: #333333;
}
.permissions-category a:hover span.colour {
- border-color: #DD6900;
+ border-color: #dd6900;
}
.permissions-category .activetab a:hover span.colour {
@@ -2170,30 +2421,30 @@ fieldset.permissions .padding {
/* Permission preset colours */
.permissions-preset-yes span.colour,
.yes {
- background-color: #86F786;
+ background-color: #86f786;
}
.permissions-preset-custom span.colour {
- background-color: #B2BBDD;
+ background-color: #b2bbdd;
}
.permissions-preset-never span.colour {
- background-color: #DD0000;
+ background-color: #dd0000;
}
.permissions-preset-no span.colour,
.never {
- background-color: #EFB0B2;
+ background-color: #efb0b2;
}
/* Permission panel
---------------------------------------- */
.permissions-panel {
- float: left;
- background-color: #CADCEB;
- width: 100%;
+ background-color: #cadceb;
border-radius: 5px;
+ float: left;
overflow: hidden;
+ width: 100%;
padding: 5px 0;
}
@@ -2221,8 +2472,8 @@ fieldset.permissions .padding {
.permissions-panel th.name {
text-align: left;
- width: auto;
text-transform: none;
+ width: auto;
}
.rtl .permissions-panel th.name {
@@ -2230,9 +2481,9 @@ fieldset.permissions .padding {
}
.permissions-panel th.permissions-name {
+ font-weight: normal;
border: none;
color: #536482;
- font-weight: normal;
}
.permissions-panel th.permissions-name a.trace {
@@ -2240,41 +2491,43 @@ fieldset.permissions .padding {
}
.permissions-panel th.row3 {
+ background-color: #d1d7dc;
background-image: none;
- background-color: #D1D7DC;
- color: #536482;
border: none;
+ color: #536482;
}
.permissions-panel th.row4 {
+ background-color: #e4e8eb;
background-image: none;
- background-color: #E4E8EB;
- color: #536482;
border: none;
+ color: #536482;
}
-.permissions-panel th a:link, .permissions-panel th a:hover, .permissions-panel th a:visited {
- display: block;
- color: #FFFFFF;
+.permissions-panel th a:link,
+.permissions-panel th a:hover,
+.permissions-panel th a:visited {
text-decoration: underline;
+ color: #ffffff;
+ display: block;
}
.permissions-panel td.permissions-yes label:hover {
- background-color: #86F786;
+ background-color: #86f786;
}
.permissions-panel td.permissions-no label:hover {
- background-color: #EFB0B2;
+ background-color: #efb0b2;
}
.permissions-panel td.permissions-never label:hover {
- background-color: #DD0000;
+ background-color: #dd0000;
}
.permissions-panel td {
- padding: 0;
text-align: center;
width: 10%;
+ padding: 0;
}
.permissions-panel td label {
@@ -2283,9 +2536,9 @@ fieldset.permissions .padding {
padding: 0;
}
-@media only screen and (max-width: 700px), only screen and (max-device-width: 700px)
-{
- .column1, .column2 {
+@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) {
+ .column1,
+ .column2 {
float: none !important;
width: auto;
}
@@ -2294,10 +2547,11 @@ fieldset.permissions .padding {
clear: both;
}
- .permissions-simple td, .permissions-simple dd {
+ .permissions-simple td,
+ .permissions-simple dd {
width: auto !important;
- margin-left: 0 !important;
margin-right: 0 !important;
+ margin-left: 0 !important;
}
.permissions-simple dd {
@@ -2313,23 +2567,24 @@ fieldset.permissions .padding {
margin: 0 !important;
}
- .permissions-category a, .permissions-category a span.tabbg {
+ .permissions-category a,
+ .permissions-category a span.tabbg {
+ background: transparent none;
display: block;
float: none !important;
- background: transparent none;
}
.permissions-category a {
+ text-decoration: underline;
background: #d9e5ee;
+ border-radius: 3px;
margin: 5px 0;
padding: 0 !important;
- border-radius: 3px;
- text-decoration: underline;
}
.permissions-category .activetab a {
background-color: #dd6900;
- color: #fff;
+ color: #ffffff;
}
.permissions-category a span.tabbg {
@@ -2339,7 +2594,7 @@ fieldset.permissions .padding {
}
.permissions-category .activetab span.colour {
- border-color: #fff;
+ border-color: #ffffff;
}
}
@@ -2347,40 +2602,40 @@ fieldset.permissions .padding {
---------------------------------------- */
#gallery {
display: block;
+ overflow: hidden;
margin: 0 -5px;
padding: 0;
- overflow: hidden;
}
#gallery li {
+ background: #ffffff;
+ border: 1px solid #cccccc;
+ border-radius: 2px;
display: block;
float: left;
- border: 1px solid #ccc;
- border-radius: 2px;
- background: #fff;
- padding: 5px;
margin: 5px;
+ padding: 5px;
}
#gallery li:hover {
- background-color: #eee;
+ background-color: #eeeeee;
}
#gallery li label {
- display: block;
text-align: center;
+ display: block;
padding: 0;
}
/* Dropdown menu
-----------------------------------------*/
+---------------------------------------- */
.dropdown {
- position: absolute;
- left: 0;
- top: 22px;
- z-index: 2;
border: 1px solid transparent;
border-radius: 5px;
+ position: absolute;
+ z-index: 2;
+ top: 22px;
+ left: 0;
padding: 9px 0 0;
}
@@ -2391,78 +2646,74 @@ fieldset.permissions .padding {
}
.dropdown-left .dropdown {
- left: auto;
right: 0;
+ left: auto;
}
-.dropdown .pointer, .dropdown .pointer-inner {
- position: absolute;
- width: 0;
- height: 0;
+.dropdown .pointer,
+.dropdown .pointer-inner {
border-top-width: 0;
+ border-right: 10px dashed transparent;
border-bottom: 10px solid transparent;
border-left: 10px dashed transparent;
- border-right: 10px dashed transparent;
- -webkit-transform: rotate(360deg); /* better anti-aliasing in webkit */
+ position: absolute;
+
+ /* better anti-aliasing in webkit */
display: block;
+ width: 0;
+ height: 0;
+ -webkit-transform: rotate(360deg);
}
-.dropdown-up .pointer, .dropdown-up .pointer-inner {
- border-bottom-width: 0;
+.dropdown-up .pointer,
+.dropdown-up .pointer-inner {
border-top: 10px solid transparent;
+ border-bottom-width: 0;
}
.dropdown .pointer {
+ border-color: #b9b9b9 transparent;
+ z-index: 3;
+ top: 0;
right: auto;
left: 10px;
- top: 0;
- z-index: 3;
}
.dropdown-up .pointer {
- bottom: 0;
top: auto;
+ bottom: 0;
}
.dropdown-left .dropdown .pointer {
- left: auto;
right: 10px;
+ left: auto;
}
.dropdown .pointer-inner {
+ border-color: #ffffff transparent;
top: auto;
bottom: -11px;
left: -10px;
}
.dropdown-up .pointer-inner {
- bottom: auto;
top: -11px;
-}
-
-.dropdown .pointer {
- border-color: #B9B9B9 transparent;
-}
-
-.dropdown .pointer-inner {
- border-color: #FFF transparent;
+ bottom: auto;
}
.dropdown .dropdown-contents {
- z-index: 2;
- overflow: hidden;
- overflow-y: auto;
- background: #fff;
+ background: #ffffff;
border: 1px solid #b9b9b9;
border-radius: 5px;
- padding: 5px;
+ box-shadow: 1px 3px 5px rgba(0, 0, 0, 0.2);
position: relative;
+ z-index: 2;
+ overflow: hidden;
+ overflow-y: auto;
+ box-sizing: border-box;
min-width: 40px;
max-height: 200px;
- box-shadow: 1px 3px 5px rgba(0, 0, 0, 0.2);
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
+ padding: 5px;
}
.dropdown-up .dropdown-contents {
@@ -2470,26 +2721,29 @@ fieldset.permissions .padding {
}
.dropdown li {
+ text-align: left;
+ white-space: nowrap;
float: none;
margin: 0;
- white-space: nowrap;
- text-align: left;
}
.rtl .dropdown li {
text-align: right;
}
-.wrap .dropdown li, .dropdown.wrap li {
+
+.wrap .dropdown li,
+.dropdown.wrap li {
white-space: normal;
}
-.dropdown li:before, .dropdown li:after {
+.dropdown li:before,
+.dropdown li:after {
display: none !important;
}
.roles-options > .dropdown {
- left: auto;
top: 3.2em;
+ left: auto;
width: 250px;
}
@@ -2498,25 +2752,25 @@ fieldset.permissions .padding {
}
.roles-options {
+ width: 250px;
-webkit-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
-o-user-select: none;
user-select: none;
- width: 250px;
}
.roles-options > span {
- border: 1px solid #DEDEDE;
+ background: url("../images/arrow_down.gif") no-repeat 245px 0.7em;
+ border: 1px solid #dedede;
border-radius: 3px;
- padding: 4px;
- width: 250px;
display: none;
- background: url('../images/arrow_down.gif') no-repeat 245px .7em;
+ width: 250px;
+ padding: 4px;
}
.rtl .roles-options > span {
- background: url('../images/arrow_down.gif') no-repeat 7px .7em;
+ background: url("../images/arrow_down.gif") no-repeat 7px 0.7em;
}
.roles-options li {
@@ -2525,19 +2779,17 @@ fieldset.permissions .padding {
.roles-highlight {
background-color: #1e90ff;
- color: #fff;
+ color: #ffffff;
}
-
/* Classes for additional tasks
---------------------------------------- */
-
.current-ext {
color: #228822;
}
.outdated-ext {
- color: #BC2A4D;
+ color: #bc2a4d;
}
.phpinfo {
@@ -2546,26 +2798,40 @@ fieldset.permissions .padding {
direction: ltr;
}
-.phpinfo td, .phpinfo th, .phpinfo h2, .phpinfo h1 {
+.phpinfo td,
+.phpinfo th,
+.phpinfo h2,
+.phpinfo h1 {
text-align: left;
}
.requirements_not_met {
+ background-color: #bc2a4d;
padding: 5px;
- background-color: #BC2A4D;
}
-.requirements_not_met dt label, .requirements_not_met dd p {
- color: #FFFFFF;
+.requirements_not_met dt label,
+.requirements_not_met dd p {
font-size: 1.4em;
+ color: #ffffff;
}
-@media only screen and (max-width: 700px), only screen and (max-device-width: 700px)
-{
- .responsive-hide { display: none !important; }
- .responsive-show { display: block !important; }
- .responsive-show-inline { display: inline !important; }
- .responsive-show-inline-block { display: inline-block !important; }
+@media only screen and (max-width: 700px), only screen and (max-device-width: 700px) {
+ .responsive-hide {
+ display: none !important;
+ }
+
+ .responsive-show {
+ display: block !important;
+ }
+
+ .responsive-show-inline {
+ display: inline !important;
+ }
+
+ .responsive-show-inline-block {
+ display: inline-block !important;
+ }
}
.clearfix {
@@ -2580,42 +2846,42 @@ fieldset.permissions .padding {
#tabs li:after,
#acp:after,
#content:after {
- content: '';
- clear: both;
display: block;
+ clear: both;
+ content: "";
}
#progress-bar {
+ text-align: center;
+ border: 1px solid #cecece;
position: relative;
width: 90%;
- text-align: center;
height: 25px;
margin: 20px auto;
- border: 1px solid #cecece;
}
#progress-bar #progress-bar-text {
+ color: #000000;
position: absolute;
top: 0;
width: 100%;
- color: #000;
}
#progress-bar #progress-bar-filler {
- display: block;
+ background-color: #3c84ad;
+ color: #ffffff;
position: relative;
top: 0;
left: 0;
- background-color: #3c84ad;
+ display: block;
+ overflow: hidden;
width: 0;
height: 25px;
- overflow: hidden;
- color: #fff;
}
#progress-bar p {
- line-height: 25px;
font-weight: bold;
+ line-height: 25px;
}
.send-stats-row {
@@ -2628,18 +2894,18 @@ fieldset.permissions .padding {
}
.send-stats-tile {
- position: relative;
- padding: 14px;
- margin-bottom: 20px;
background-color: #eff0f2;
border-radius: 6px;
- box-shadow: rgba(0,0,0,0.3) 1px 1px 5px;
+ box-shadow: rgba(0, 0, 0, 0.3) 1px 1px 5px;
+ position: relative;
+ margin-bottom: 20px;
+ padding: 14px;
}
.send-stats-tile h2 {
- margin-top: 0;
text-align: center;
- padding-bottom: 1em;
+ margin-top: 0;
+ padding-bottom: 1em;
}
.send-stats-tile i {
@@ -2653,12 +2919,12 @@ fieldset.permissions .padding {
.send-stats-data-row {
background: #f9f9f9;
- border-radius: 6px;
- border: #DEDEDE 1px solid;
- padding: 10px;
+ border: #dedede 1px solid;
border-top-width: 0;
- border-top-right-radius: 0;
+ border-radius: 6px;
border-top-left-radius: 0;
+ border-top-right-radius: 0;
+ padding: 10px;
}
.send-stats-data-hidden .configlist {
@@ -2666,26 +2932,27 @@ fieldset.permissions .padding {
}
.send-stats-data-only-row {
- border-radius: 6px !important;
border-bottom-width: 1px !important;
+ border-radius: 6px !important;
}
.send-stats-data-hidden {
- padding: 0;
border: none;
+ padding: 0;
}
.send-stats-row > .send-stats-data-row:first-child {
background-color: #d9edf7;
+ border-top-width: 1px;
border-bottom-width: 0;
- border-top-right-radius: 6px;
border-top-left-radius: 6px;
- border-top-width: 1px;
- border-bottom-left-radius: 0;
+ border-top-right-radius: 6px;
border-bottom-right-radius: 0;
+ border-bottom-left-radius: 0;
}
-.send-stats-settings dt, .send-stats-settings dd {
+.send-stats-settings dt,
+.send-stats-settings dd {
min-width: 25px;
}
@@ -2697,15 +2964,15 @@ fieldset.permissions .padding {
display: none;
}
-.send-stats-settings input[type=checkbox] + label:before {
- content: "\f096";
+.send-stats-settings input[type="checkbox"] + label:before {
font-family: FontAwesome;
font-size: 1.5em;
+ content: "\f096";
}
-.send-stats-settings input[type=checkbox]:checked + label:before {
- content: "\f14a";
+.send-stats-settings input[type="checkbox"]:checked + label:before {
color: #3c763d;
+ content: "\f14a";
}
.send-stats-data-row a:hover span {
@@ -2726,11 +2993,23 @@ fieldset.permissions .padding {
word-break: break-all;
}
-/* stylelint-disable declaration-property-unit-whitelist */
+
.emoji {
- min-height: 18px;
+ width: 1em;
min-width: 18px;
height: 1em;
- width: 1em;
+ min-height: 18px;
}
+
+.console-output {
+ font-family: monospace;
+ background-color: #2a2a2a;
+ color: #f1f1f1;
+ overflow-x: scroll;
+}
+
+/* stylelint-enable selector-max-id */
+/* stylelint-enable selector-max-compound-selectors */
+/* stylelint-enable selector-no-qualifying-type */
+/* stylelint-enable declaration-property-unit-blacklist */
/* stylelint-enable declaration-property-unit-whitelist */
diff --git a/phpBB/adm/style/detailed_message_body.html b/phpBB/adm/style/detailed_message_body.html
new file mode 100644
index 0000000000..bc904d7eb6
--- /dev/null
+++ b/phpBB/adm/style/detailed_message_body.html
@@ -0,0 +1,14 @@
+<!-- INCLUDE overall_header.html -->
+
+<div {% if S_USER_NOTICE %}class="successbox"{% else %}class="errorbox"{% endif %}>
+ <h3>{{ MESSAGE_TITLE }}</h3>
+ <p>{{ MESSAGE_TEXT }}</p>
+</div>
+
+<div>
+ <fieldset class="console-output">
+ <pre>{{ MESSAGE_DETAIL }}</pre>
+ </fieldset>
+</div>
+
+<!-- INCLUDE overall_footer.html -->
diff --git a/phpBB/adm/style/overall_footer.html b/phpBB/adm/style/overall_footer.html
index 7a5b620f48..2668e4a8ce 100644
--- a/phpBB/adm/style/overall_footer.html
+++ b/phpBB/adm/style/overall_footer.html
@@ -20,7 +20,14 @@
<div id="darkenwrapper" data-ajax-error-title="{L_AJAX_ERROR_TITLE}" data-ajax-error-text="{L_AJAX_ERROR_TEXT}" data-ajax-error-text-abort="{L_AJAX_ERROR_TEXT_ABORT}" data-ajax-error-text-timeout="{L_AJAX_ERROR_TEXT_TIMEOUT}" data-ajax-error-text-parsererror="{L_AJAX_ERROR_TEXT_PARSERERROR}">
<div id="darken">&nbsp;</div>
</div>
- <div id="loading_indicator"></div>
+ <div id="loading_indicator" class="loading_indicator">
+ <div class="loader">
+ <svg class="spinner" width="48px" height="48px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg" aria-labelledby="loader-title" role="img">
+ <title id="loader-title">{L_LOADING}</title>
+ <circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle>
+ </svg>
+ </div>
+ </div>
<div id="phpbb_alert" class="phpbb_alert" data-l-err="{L_ERROR}" data-l-timeout-processing-req="{L_TIMEOUT_PROCESSING_REQ}">
<a href="#" class="alert_close"></a>
diff --git a/phpBB/assets/javascript/core.js b/phpBB/assets/javascript/core.js
index bedbd23532..59d77e1d96 100644
--- a/phpBB/assets/javascript/core.js
+++ b/phpBB/assets/javascript/core.js
@@ -36,11 +36,7 @@ $.ajaxPrefilter(function(s) {
*/
phpbb.loadingIndicator = function() {
if (!$loadingIndicator) {
- $loadingIndicator = $('<div />', {
- 'id': 'loading_indicator',
- 'class': 'loading_indicator'
- });
- $loadingIndicator.appendTo('#page-footer');
+ $loadingIndicator = $('#loading_indicator');
}
if (!$loadingIndicator.is(':visible')) {
diff --git a/phpBB/bin/phpbbcli.php b/phpBB/bin/phpbbcli.php
index 5ae18334d9..33ab868522 100755
--- a/phpBB/bin/phpbbcli.php
+++ b/phpBB/bin/phpbbcli.php
@@ -71,6 +71,11 @@ require($phpbb_root_path . 'includes/compatibility_globals.' . $phpEx);
register_compatibility_globals();
+if (@is_file($phpbb_root_path . $config['exts_composer_vendor_dir'] . '/autoload.php'))
+{
+ require_once($phpbb_root_path . $config['exts_composer_vendor_dir'] . '/autoload.php');
+}
+
/** @var \phpbb\config\config $config */
$config = $phpbb_container->get('config');
diff --git a/phpBB/common.php b/phpBB/common.php
index e25274d3f4..af2a344de6 100644
--- a/phpBB/common.php
+++ b/phpBB/common.php
@@ -65,8 +65,7 @@ if (!defined('PHPBB_INSTALLED'))
// Eliminate . and .. from the path
require($phpbb_root_path . 'phpbb/filesystem.' . $phpEx);
- $phpbb_filesystem = new phpbb\filesystem\filesystem();
- $script_path = $phpbb_filesystem->clean_path($script_path);
+ $script_path = \phpbb\filesystem\helper::clean_path($script_path);
$url = (($secure) ? 'https://' : 'http://') . $server_name;
@@ -134,20 +133,14 @@ $phpbb_class_loader_ext->set_cache($phpbb_container->get('cache.driver'));
$phpbb_container->get('dbal.conn')->set_debug_sql_explain($phpbb_container->getParameter('debug.sql_explain'));
$phpbb_container->get('dbal.conn')->set_debug_load_time($phpbb_container->getParameter('debug.load_time'));
+
require($phpbb_root_path . 'includes/compatibility_globals.' . $phpEx);
register_compatibility_globals();
-// Add own hook handler
-require($phpbb_root_path . 'includes/hooks/index.' . $phpEx);
-$phpbb_hook = new phpbb_hook(array('exit_handler', 'phpbb_user_session_handler', 'append_sid', array('template', 'display')));
-
-/* @var $phpbb_hook_finder \phpbb\hook\finder */
-$phpbb_hook_finder = $phpbb_container->get('hook_finder');
-
-foreach ($phpbb_hook_finder->find() as $hook)
+if (@is_file($phpbb_root_path . $config['exts_composer_vendor_dir'] . '/autoload.php'))
{
- @include($phpbb_root_path . 'includes/hooks/' . $hook . '.' . $phpEx);
+ require_once($phpbb_root_path . $config['exts_composer_vendor_dir'] . '/autoload.php');
}
/**
diff --git a/phpBB/composer-ext.json b/phpBB/composer-ext.json
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/phpBB/composer-ext.json
diff --git a/phpBB/composer-ext.lock b/phpBB/composer-ext.lock
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/phpBB/composer-ext.lock
diff --git a/phpBB/composer.json b/phpBB/composer.json
index 57c7d7452d..5567fd65cf 100644
--- a/phpBB/composer.json
+++ b/phpBB/composer.json
@@ -28,6 +28,8 @@
"php": "^7.1.3",
"ext-json": "*",
"bantu/ini-get-wrapper": "~1.0",
+ "composer/composer": "^1.6",
+ "composer/installers": "^1.4",
"google/recaptcha": "~1.1",
"guzzlehttp/guzzle": "~6.3",
"lusitanian/oauth": "^0.8.1",
diff --git a/phpBB/composer.lock b/phpBB/composer.lock
index 54a79d13f3..7b31fc9bbd 100644
--- a/phpBB/composer.lock
+++ b/phpBB/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "bbbc187ca0c5d8f13e6358d529412446",
+ "content-hash": "7916f0f09f4c9582ea9bace35275f50a",
"packages": [
{
"name": "bantu/ini-get-wrapper",
@@ -37,6 +37,430 @@
"time": "2014-09-15T13:12:35+00:00"
},
{
+ "name": "composer/ca-bundle",
+ "version": "1.2.5",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/ca-bundle.git",
+ "reference": "62e8fc2dc550e5d6d8c9360c7721662670f58149"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/ca-bundle/zipball/62e8fc2dc550e5d6d8c9360c7721662670f58149",
+ "reference": "62e8fc2dc550e5d6d8c9360c7721662670f58149",
+ "shasum": ""
+ },
+ "require": {
+ "ext-openssl": "*",
+ "ext-pcre": "*",
+ "php": "^5.3.2 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8",
+ "psr/log": "^1.0",
+ "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\CaBundle\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
+ "keywords": [
+ "cabundle",
+ "cacert",
+ "certificate",
+ "ssl",
+ "tls"
+ ],
+ "time": "2019-12-11T14:44:42+00:00"
+ },
+ {
+ "name": "composer/composer",
+ "version": "1.9.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/composer.git",
+ "reference": "bb01f2180df87ce7992b8331a68904f80439dd2f"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/composer/zipball/bb01f2180df87ce7992b8331a68904f80439dd2f",
+ "reference": "bb01f2180df87ce7992b8331a68904f80439dd2f",
+ "shasum": ""
+ },
+ "require": {
+ "composer/ca-bundle": "^1.0",
+ "composer/semver": "^1.0",
+ "composer/spdx-licenses": "^1.2",
+ "composer/xdebug-handler": "^1.1",
+ "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0",
+ "php": "^5.3.2 || ^7.0",
+ "psr/log": "^1.0",
+ "seld/jsonlint": "^1.4",
+ "seld/phar-utils": "^1.0",
+ "symfony/console": "^2.7 || ^3.0 || ^4.0",
+ "symfony/filesystem": "^2.7 || ^3.0 || ^4.0",
+ "symfony/finder": "^2.7 || ^3.0 || ^4.0",
+ "symfony/process": "^2.7 || ^3.0 || ^4.0"
+ },
+ "conflict": {
+ "symfony/console": "2.8.38"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7",
+ "phpunit/phpunit-mock-objects": "^2.3 || ^3.0"
+ },
+ "suggest": {
+ "ext-openssl": "Enabling the openssl extension allows you to access https URLs for repositories and packages",
+ "ext-zip": "Enabling the zip extension allows you to unzip archives",
+ "ext-zlib": "Allow gzip compression of HTTP requests"
+ },
+ "bin": [
+ "bin/composer"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\": "src/Composer"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nils Adermann",
+ "email": "naderman@naderman.de",
+ "homepage": "http://www.naderman.de"
+ },
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "Composer helps you declare, manage and install dependencies of PHP projects. It ensures you have the right stack everywhere.",
+ "homepage": "https://getcomposer.org/",
+ "keywords": [
+ "autoload",
+ "dependency",
+ "package"
+ ],
+ "time": "2019-11-01T16:20:17+00:00"
+ },
+ {
+ "name": "composer/installers",
+ "version": "v1.7.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/installers.git",
+ "reference": "141b272484481432cda342727a427dc1e206bfa0"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/installers/zipball/141b272484481432cda342727a427dc1e206bfa0",
+ "reference": "141b272484481432cda342727a427dc1e206bfa0",
+ "shasum": ""
+ },
+ "require": {
+ "composer-plugin-api": "^1.0"
+ },
+ "replace": {
+ "roundcube/plugin-installer": "*",
+ "shama/baton": "*"
+ },
+ "require-dev": {
+ "composer/composer": "1.0.*@dev",
+ "phpunit/phpunit": "^4.8.36"
+ },
+ "type": "composer-plugin",
+ "extra": {
+ "class": "Composer\\Installers\\Plugin",
+ "branch-alias": {
+ "dev-master": "1.0-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\Installers\\": "src/Composer/Installers"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Kyle Robinson Young",
+ "email": "kyle@dontkry.com",
+ "homepage": "https://github.com/shama"
+ }
+ ],
+ "description": "A multi-framework Composer library installer",
+ "homepage": "https://composer.github.io/installers/",
+ "keywords": [
+ "Craft",
+ "Dolibarr",
+ "Eliasis",
+ "Hurad",
+ "ImageCMS",
+ "Kanboard",
+ "Lan Management System",
+ "MODX Evo",
+ "Mautic",
+ "Maya",
+ "OXID",
+ "Plentymarkets",
+ "Porto",
+ "RadPHP",
+ "SMF",
+ "Thelia",
+ "Whmcs",
+ "WolfCMS",
+ "agl",
+ "aimeos",
+ "annotatecms",
+ "attogram",
+ "bitrix",
+ "cakephp",
+ "chef",
+ "cockpit",
+ "codeigniter",
+ "concrete5",
+ "croogo",
+ "dokuwiki",
+ "drupal",
+ "eZ Platform",
+ "elgg",
+ "expressionengine",
+ "fuelphp",
+ "grav",
+ "installer",
+ "itop",
+ "joomla",
+ "known",
+ "kohana",
+ "laravel",
+ "lavalite",
+ "lithium",
+ "magento",
+ "majima",
+ "mako",
+ "mediawiki",
+ "modulework",
+ "modx",
+ "moodle",
+ "osclass",
+ "phpbb",
+ "piwik",
+ "ppi",
+ "puppet",
+ "pxcms",
+ "reindex",
+ "roundcube",
+ "shopware",
+ "silverstripe",
+ "sydes",
+ "symfony",
+ "typo3",
+ "wordpress",
+ "yawik",
+ "zend",
+ "zikula"
+ ],
+ "time": "2019-08-12T15:00:31+00:00"
+ },
+ {
+ "name": "composer/semver",
+ "version": "1.5.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/semver.git",
+ "reference": "46d9139568ccb8d9e7cdd4539cab7347568a5e2e"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/semver/zipball/46d9139568ccb8d9e7cdd4539cab7347568a5e2e",
+ "reference": "46d9139568ccb8d9e7cdd4539cab7347568a5e2e",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.2 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.5 || ^5.0.5",
+ "phpunit/phpunit-mock-objects": "2.3.0 || ^3.0"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\Semver\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nils Adermann",
+ "email": "naderman@naderman.de",
+ "homepage": "http://www.naderman.de"
+ },
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ },
+ {
+ "name": "Rob Bast",
+ "email": "rob.bast@gmail.com",
+ "homepage": "http://robbast.nl"
+ }
+ ],
+ "description": "Semver library that offers utilities, version constraint parsing and validation.",
+ "keywords": [
+ "semantic",
+ "semver",
+ "validation",
+ "versioning"
+ ],
+ "time": "2019-03-19T17:25:45+00:00"
+ },
+ {
+ "name": "composer/spdx-licenses",
+ "version": "1.5.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/spdx-licenses.git",
+ "reference": "7ac1e6aec371357df067f8a688c3d6974df68fa5"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/7ac1e6aec371357df067f8a688c3d6974df68fa5",
+ "reference": "7ac1e6aec371357df067f8a688c3d6974df68fa5",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.2 || ^7.0 || ^8.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 7"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Composer\\Spdx\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Nils Adermann",
+ "email": "naderman@naderman.de",
+ "homepage": "http://www.naderman.de"
+ },
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ },
+ {
+ "name": "Rob Bast",
+ "email": "rob.bast@gmail.com",
+ "homepage": "http://robbast.nl"
+ }
+ ],
+ "description": "SPDX licenses list and validation library.",
+ "keywords": [
+ "license",
+ "spdx",
+ "validator"
+ ],
+ "time": "2019-07-29T10:31:59+00:00"
+ },
+ {
+ "name": "composer/xdebug-handler",
+ "version": "1.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/composer/xdebug-handler.git",
+ "reference": "cbe23383749496fe0f373345208b79568e4bc248"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/cbe23383749496fe0f373345208b79568e4bc248",
+ "reference": "cbe23383749496fe0f373345208b79568e4bc248",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3.2 || ^7.0 || ^8.0",
+ "psr/log": "^1.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Composer\\XdebugHandler\\": "src"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "John Stevenson",
+ "email": "john-stevenson@blueyonder.co.uk"
+ }
+ ],
+ "description": "Restarts a process without Xdebug.",
+ "keywords": [
+ "Xdebug",
+ "performance"
+ ],
+ "time": "2019-11-06T16:40:04+00:00"
+ },
+ {
"name": "google/recaptcha",
"version": "1.2.3",
"source": {
@@ -273,6 +697,72 @@
"time": "2019-07-01T23:21:34+00:00"
},
{
+ "name": "justinrainbow/json-schema",
+ "version": "5.2.9",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/justinrainbow/json-schema.git",
+ "reference": "44c6787311242a979fa15c704327c20e7221a0e4"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/44c6787311242a979fa15c704327c20e7221a0e4",
+ "reference": "44c6787311242a979fa15c704327c20e7221a0e4",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3.3"
+ },
+ "require-dev": {
+ "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1",
+ "json-schema/json-schema-test-suite": "1.2.0",
+ "phpunit/phpunit": "^4.8.35"
+ },
+ "bin": [
+ "bin/validate-json"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "5.0.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "JsonSchema\\": "src/JsonSchema/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Bruno Prieto Reis",
+ "email": "bruno.p.reis@gmail.com"
+ },
+ {
+ "name": "Justin Rainbow",
+ "email": "justin.rainbow@gmail.com"
+ },
+ {
+ "name": "Igor Wiedler",
+ "email": "igor@wiedler.ch"
+ },
+ {
+ "name": "Robert Schönthal",
+ "email": "seroscho@googlemail.com"
+ }
+ ],
+ "description": "A library to validate a json schema.",
+ "homepage": "https://github.com/justinrainbow/json-schema",
+ "keywords": [
+ "json",
+ "schema"
+ ],
+ "time": "2019-09-25T14:49:45+00:00"
+ },
+ {
"name": "lusitanian/oauth",
"version": "v0.8.11",
"source": {
@@ -915,6 +1405,99 @@
"time": "2019-12-26T19:14:01+00:00"
},
{
+ "name": "seld/jsonlint",
+ "version": "1.7.2",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Seldaek/jsonlint.git",
+ "reference": "e2e5d290e4d2a4f0eb449f510071392e00e10d19"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/e2e5d290e4d2a4f0eb449f510071392e00e10d19",
+ "reference": "e2e5d290e4d2a4f0eb449f510071392e00e10d19",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^5.3 || ^7.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0"
+ },
+ "bin": [
+ "bin/jsonlint"
+ ],
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Seld\\JsonLint\\": "src/Seld/JsonLint/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be",
+ "homepage": "http://seld.be"
+ }
+ ],
+ "description": "JSON Linter",
+ "keywords": [
+ "json",
+ "linter",
+ "parser",
+ "validator"
+ ],
+ "time": "2019-10-24T14:27:39+00:00"
+ },
+ {
+ "name": "seld/phar-utils",
+ "version": "1.0.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/Seldaek/phar-utils.git",
+ "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/7009b5139491975ef6486545a39f3e6dad5ac30a",
+ "reference": "7009b5139491975ef6486545a39f3e6dad5ac30a",
+ "shasum": ""
+ },
+ "require": {
+ "php": ">=5.3"
+ },
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.x-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "Seld\\PharUtils\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "authors": [
+ {
+ "name": "Jordi Boggiano",
+ "email": "j.boggiano@seld.be"
+ }
+ ],
+ "description": "PHAR file format utilities, for when PHP phars you up",
+ "keywords": [
+ "phra"
+ ],
+ "time": "2015-10-13T18:44:15+00:00"
+ },
+ {
"name": "symfony/config",
"version": "v3.4.36",
"source": {
@@ -2337,62 +2920,6 @@
"time": "2019-12-05T12:48:12+00:00"
},
{
- "name": "composer/ca-bundle",
- "version": "1.2.5",
- "source": {
- "type": "git",
- "url": "https://github.com/composer/ca-bundle.git",
- "reference": "62e8fc2dc550e5d6d8c9360c7721662670f58149"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/composer/ca-bundle/zipball/62e8fc2dc550e5d6d8c9360c7721662670f58149",
- "reference": "62e8fc2dc550e5d6d8c9360c7721662670f58149",
- "shasum": ""
- },
- "require": {
- "ext-openssl": "*",
- "ext-pcre": "*",
- "php": "^5.3.2 || ^7.0 || ^8.0"
- },
- "require-dev": {
- "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8",
- "psr/log": "^1.0",
- "symfony/process": "^2.5 || ^3.0 || ^4.0 || ^5.0"
- },
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.x-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "Composer\\CaBundle\\": "src"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "MIT"
- ],
- "authors": [
- {
- "name": "Jordi Boggiano",
- "email": "j.boggiano@seld.be",
- "homepage": "http://seld.be"
- }
- ],
- "description": "Lets you find a path to the system CA bundle, and includes a fallback to the Mozilla CA bundle.",
- "keywords": [
- "cabundle",
- "cacert",
- "certificate",
- "ssl",
- "tls"
- ],
- "time": "2019-12-11T14:44:42+00:00"
- },
- {
"name": "doctrine/instantiator",
"version": "1.3.0",
"source": {
diff --git a/phpBB/config/default/container/services.yml b/phpBB/config/default/container/services.yml
index 2d4720029d..679d3d5eb0 100644
--- a/phpBB/config/default/container/services.yml
+++ b/phpBB/config/default/container/services.yml
@@ -8,11 +8,11 @@ imports:
- { resource: services_cron.yml }
- { resource: services_db.yml }
- { resource: services_event.yml }
+ - { resource: services_extensions.yml }
- { resource: services_feed.yml }
- { resource: services_files.yml }
- { resource: services_filesystem.yml }
- { resource: services_help.yml }
- - { resource: services_hook.yml }
- { resource: services_http.yml }
- { resource: services_language.yml }
- { resource: services_migrator.yml }
@@ -24,9 +24,11 @@ imports:
- { resource: services_profilefield.yml }
- { resource: services_report.yml }
- { resource: services_routing.yml }
+ - { resource: services_storage.yml }
- { resource: services_text_formatter.yml }
- { resource: services_text_reparser.yml }
- { resource: services_twig.yml }
+ - { resource: services_twig_extensions.yml }
- { resource: services_ucp.yml }
- { resource: services_user.yml }
@@ -99,25 +101,12 @@ services:
- '%core.root_path%'
- '@template'
- ext.manager:
- class: phpbb\extension\manager
- arguments:
- - '@service_container'
- - '@dbal.conn'
- - '@config'
- - '@filesystem'
- - '%tables.ext%'
- - '%core.root_path%'
- - '%core.php_ext%'
- - '@cache'
-
file_downloader:
class: phpbb\file_downloader
file_locator:
class: phpbb\routing\file_locator
arguments:
- - '@filesystem'
- '%core.root_path%'
group_helper:
@@ -147,7 +136,6 @@ services:
class: phpbb\path_helper
arguments:
- '@symfony_request'
- - '@filesystem'
- '@request'
- '%core.root_path%'
- '%core.php_ext%'
diff --git a/phpBB/config/default/container/services_attachment.yml b/phpBB/config/default/container/services_attachment.yml
index c56ced21f4..afabbd6f95 100644
--- a/phpBB/config/default/container/services_attachment.yml
+++ b/phpBB/config/default/container/services_attachment.yml
@@ -6,9 +6,8 @@ services:
- '@config'
- '@dbal.conn'
- '@dispatcher'
- - '@filesystem'
- '@attachment.resync'
- - '%core.root_path%'
+ - '@storage.attachment'
attachment.manager:
class: phpbb\attachment\manager
@@ -36,5 +35,6 @@ services:
- '@mimetype.guesser'
- '@dispatcher'
- '@plupload'
+ - '@storage.attachment'
+ - '@filesystem.temp'
- '@user'
- - '%core.root_path%'
diff --git a/phpBB/config/default/container/services_avatar.yml b/phpBB/config/default/container/services_avatar.yml
index d96aa6239a..1cbc44115d 100644
--- a/phpBB/config/default/container/services_avatar.yml
+++ b/phpBB/config/default/container/services_avatar.yml
@@ -62,11 +62,11 @@ services:
- '@config'
- '%core.root_path%'
- '%core.php_ext%'
- - '@filesystem'
+ - '@storage.avatar'
- '@path_helper'
- '@dispatcher'
- '@files.factory'
- - '@cache.driver'
+ - '@php_ini'
calls:
- [set_name, [avatar.driver.upload]]
tags:
diff --git a/phpBB/config/default/container/services_console.yml b/phpBB/config/default/container/services_console.yml
index b662102b35..10e0411f40 100644
--- a/phpBB/config/default/container/services_console.yml
+++ b/phpBB/config/default/container/services_console.yml
@@ -140,6 +140,33 @@ services:
tags:
- { name: console.command }
+ console.command.extension.install:
+ class: phpbb\console\command\extension\install
+ arguments:
+ - '@user'
+ - '@ext.composer.manager'
+ - '@language'
+ tags:
+ - { name: console.command }
+
+ console.command.extension.list_available:
+ class: phpbb\console\command\extension\list_available
+ arguments:
+ - '@user'
+ - '@ext.composer.manager'
+ - '@language'
+ tags:
+ - { name: console.command }
+
+ console.command.extension.manage:
+ class: phpbb\console\command\extension\manage
+ arguments:
+ - '@user'
+ - '@ext.composer.manager'
+ - '@language'
+ tags:
+ - { name: console.command }
+
console.command.extension.purge:
class: phpbb\console\command\extension\purge
arguments:
@@ -149,6 +176,15 @@ services:
tags:
- { name: console.command }
+ console.command.extension.remove:
+ class: phpbb\console\command\extension\remove
+ arguments:
+ - '@user'
+ - '@ext.composer.manager'
+ - '@language'
+ tags:
+ - { name: console.command }
+
console.command.extension.show:
class: phpbb\console\command\extension\show
arguments:
@@ -158,6 +194,15 @@ services:
tags:
- { name: console.command }
+ console.command.extension.update:
+ class: phpbb\console\command\extension\update
+ arguments:
+ - '@user'
+ - '@ext.composer.manager'
+ - '@language'
+ tags:
+ - { name: console.command }
+
console.command.fixup.update_hashes:
class: phpbb\console\command\fixup\update_hashes
arguments:
diff --git a/phpBB/config/default/container/services_content.yml b/phpBB/config/default/container/services_content.yml
index 6717c20337..dc5bf5bd5e 100644
--- a/phpBB/config/default/container/services_content.yml
+++ b/phpBB/config/default/container/services_content.yml
@@ -69,5 +69,3 @@ services:
viewonline_helper:
class: phpbb\viewonline_helper
- arguments:
- - '@filesystem'
diff --git a/phpBB/config/default/container/services_db.yml b/phpBB/config/default/container/services_db.yml
index d538177603..fe7d42937d 100644
--- a/phpBB/config/default/container/services_db.yml
+++ b/phpBB/config/default/container/services_db.yml
@@ -34,7 +34,7 @@ services:
class: phpbb\db\extractor\mssql_extractor
shared: false
arguments:
- - '%core.root_path%'
+ - '@filesystem.temp'
- '@request'
- '@dbal.conn.driver'
@@ -42,7 +42,7 @@ services:
class: phpbb\db\extractor\mysql_extractor
shared: false
arguments:
- - '%core.root_path%'
+ - '@filesystem.temp'
- '@request'
- '@dbal.conn.driver'
@@ -50,7 +50,7 @@ services:
class: phpbb\db\extractor\oracle_extractor
shared: false
arguments:
- - '%core.root_path%'
+ - '@filesystem.temp'
- '@request'
- '@dbal.conn.driver'
@@ -58,7 +58,7 @@ services:
class: phpbb\db\extractor\postgres_extractor
shared: false
arguments:
- - '%core.root_path%'
+ - '@filesystem.temp'
- '@request'
- '@dbal.conn.driver'
@@ -66,6 +66,6 @@ services:
class: phpbb\db\extractor\sqlite3_extractor
shared: false
arguments:
- - '%core.root_path%'
+ - '@filesystem.temp'
- '@request'
- '@dbal.conn.driver'
diff --git a/phpBB/config/default/container/services_extensions.yml b/phpBB/config/default/container/services_extensions.yml
new file mode 100644
index 0000000000..53e36f0fda
--- /dev/null
+++ b/phpBB/config/default/container/services_extensions.yml
@@ -0,0 +1,47 @@
+services:
+ ext.manager:
+ class: phpbb\extension\manager
+ arguments:
+ - '@service_container'
+ - '@dbal.conn'
+ - '@config'
+ - '%tables.ext%'
+ - '%core.root_path%'
+ - '%core.php_ext%'
+ - '@cache'
+
+ ext.composer.installer:
+ class: phpbb\composer\installer
+ arguments:
+ - '%core.root_path%'
+ - '@filesystem'
+ - '@request'
+ - '@config'
+
+ ext.composer.manager:
+ class: phpbb\composer\extension_manager
+ arguments:
+ - '@ext.composer.installer'
+ - '@cache.driver'
+ - '@ext.manager'
+ - '@filesystem'
+ - phpbb-extension
+ - EXTENSIONS_
+ - '%core.root_path%'
+ - '@config'
+
+ style.composer.manager:
+ class: phpbb\composer\manager
+ arguments:
+ - '@ext.composer.installer'
+ - '@cache.driver'
+ - phpbb-style
+ - STYLES_
+
+ lang.composer.manager:
+ class: phpbb\composer\manager
+ arguments:
+ - '@ext.composer.installer'
+ - '@cache.driver'
+ - phpbb-language
+ - LANGUAGES_
diff --git a/phpBB/config/default/container/services_files.yml b/phpBB/config/default/container/services_files.yml
index ba1fdb4c9a..d1114c9c68 100644
--- a/phpBB/config/default/container/services_files.yml
+++ b/phpBB/config/default/container/services_files.yml
@@ -16,6 +16,16 @@ services:
- '@mimetype.guesser'
- '@plupload'
+ files.filespec_storage:
+ class: phpbb\files\filespec_storage
+ shared: false
+ arguments:
+ - '@language'
+ - '@php_ini'
+ - '@upload_imagesize'
+ - '@mimetype.guesser'
+ - '@plupload'
+
files.upload:
class: phpbb\files\upload
shared: false
@@ -36,6 +46,16 @@ services:
- '@plupload'
- '@request'
+ files.types.form_storage:
+ class: phpbb\files\types\form_storage
+ shared: false
+ arguments:
+ - '@files.factory'
+ - '@language'
+ - '@php_ini'
+ - '@plupload'
+ - '@request'
+
files.types.local:
class: phpbb\files\types\local
shared: false
@@ -51,7 +71,18 @@ services:
arguments:
- '@config'
- '@files.factory'
+ - '@filesystem.temp'
+ - '@language'
+ - '@php_ini'
+ - '@request'
+
+ files.types.remote_storage:
+ class: phpbb\files\types\remote_storage
+ shared: false
+ arguments:
+ - '@config'
+ - '@files.factory'
+ - '@filesystem.temp'
- '@language'
- '@php_ini'
- '@request'
- - '%core.root_path%'
diff --git a/phpBB/config/default/container/services_filesystem.yml b/phpBB/config/default/container/services_filesystem.yml
index 828f9076dd..15206314b9 100644
--- a/phpBB/config/default/container/services_filesystem.yml
+++ b/phpBB/config/default/container/services_filesystem.yml
@@ -1,3 +1,12 @@
+parameters:
+ core.filesystem.cache_temp_dir: '%core.cache_dir%tmp/'
+
services:
filesystem:
class: phpbb\filesystem\filesystem
+
+ filesystem.temp:
+ class: phpbb\filesystem\temp
+ arguments:
+ - '@filesystem'
+ - '%core.filesystem.cache_temp_dir%'
diff --git a/phpBB/config/default/container/services_hook.yml b/phpBB/config/default/container/services_hook.yml
deleted file mode 100644
index 10a84184a0..0000000000
--- a/phpBB/config/default/container/services_hook.yml
+++ /dev/null
@@ -1,7 +0,0 @@
-services:
- hook_finder:
- class: phpbb\hook\finder
- arguments:
- - '%core.root_path%'
- - '%core.php_ext%'
- - '@cache.driver'
diff --git a/phpBB/config/default/container/services_migrator.yml b/phpBB/config/default/container/services_migrator.yml
index c63b087adb..3362598204 100644
--- a/phpBB/config/default/container/services_migrator.yml
+++ b/phpBB/config/default/container/services_migrator.yml
@@ -11,6 +11,7 @@ services:
- '%core.root_path%'
- '%core.php_ext%'
- '%core.table_prefix%'
+ - '%tables%'
- '@migrator.tool_collection'
- '@migrator.helper'
diff --git a/phpBB/config/default/container/services_routing.yml b/phpBB/config/default/container/services_routing.yml
index 0bf0a33ab4..cb397eab85 100644
--- a/phpBB/config/default/container/services_routing.yml
+++ b/phpBB/config/default/container/services_routing.yml
@@ -23,7 +23,6 @@ services:
- '@router'
- '@symfony_request'
- '@request'
- - '@filesystem'
- '%core.root_path%'
- '%core.php_ext%'
diff --git a/phpBB/config/default/container/services_storage.yml b/phpBB/config/default/container/services_storage.yml
new file mode 100644
index 0000000000..92f31779e6
--- /dev/null
+++ b/phpBB/config/default/container/services_storage.yml
@@ -0,0 +1,84 @@
+services:
+
+# Storages
+ storage.attachment:
+ class: phpbb\storage\storage
+ arguments:
+ - '@dbal.conn'
+ - '@cache.driver'
+ - '@storage.adapter.factory'
+ - 'attachment'
+ - '%tables.storage%'
+ tags:
+ - { name: storage }
+
+ storage.avatar:
+ class: phpbb\storage\storage
+ arguments:
+ - '@dbal.conn'
+ - '@cache.driver'
+ - '@storage.adapter.factory'
+ - 'avatar'
+ - '%tables.storage%'
+ tags:
+ - { name: storage }
+
+ storage.backup:
+ class: phpbb\storage\storage
+ arguments:
+ - '@dbal.conn'
+ - '@cache.driver'
+ - '@storage.adapter.factory'
+ - 'backup'
+ - '%tables.storage%'
+ tags:
+ - { name: storage }
+
+# Factory
+ storage.adapter.factory:
+ class: phpbb\storage\adapter_factory
+ arguments:
+ - '@config'
+ - '@storage.adapter_collection'
+ - '@storage.provider_collection'
+
+# Collections
+ storage.storage_collection:
+ class: phpbb\di\service_collection
+ arguments:
+ - '@service_container'
+ tags:
+ - { name: service_collection, tag: storage }
+
+ storage.adapter_collection:
+ class: phpbb\di\service_collection
+ arguments:
+ - '@service_container'
+ tags:
+ - { name: service_collection, tag: storage.adapter, class_name_aware: true }
+
+ storage.provider_collection:
+ class: phpbb\di\service_collection
+ arguments:
+ - '@service_container'
+ tags:
+ - { name: service_collection, tag: storage.provider, class_name_aware: true }
+
+# Adapters
+ storage.adapter.local:
+ class: phpbb\storage\adapter\local
+ shared: false
+ arguments:
+ - '@filesystem'
+ - '@upload_imagesize'
+ - '@mimetype.guesser'
+ - '%core.root_path%'
+ tags:
+ - { name: storage.adapter }
+
+# Providers
+ storage.provider.local:
+ class: phpbb\storage\provider\local
+ arguments:
+ tags:
+ - { name: storage.provider }
diff --git a/phpBB/config/default/container/services_twig.yml b/phpBB/config/default/container/services_twig.yml
index 6f70155295..24ee24484b 100644
--- a/phpBB/config/default/container/services_twig.yml
+++ b/phpBB/config/default/container/services_twig.yml
@@ -15,6 +15,7 @@ services:
- []
calls:
- [setLexer, ['@template.twig.lexer']]
+ - [addGlobal, ['config', '@config']]
template.twig.lexer:
class: phpbb\template\twig\lexer
@@ -24,8 +25,6 @@ services:
template.twig.loader:
class: phpbb\template\twig\loader
- arguments:
- - '@filesystem'
template.twig.extensions.collection:
class: phpbb\di\service_collection
diff --git a/phpBB/config/default/container/services_twig_extensions.yml b/phpBB/config/default/container/services_twig_extensions.yml
new file mode 100644
index 0000000000..115d3f1417
--- /dev/null
+++ b/phpBB/config/default/container/services_twig_extensions.yml
@@ -0,0 +1,9 @@
+# Twig extensions not needed by the installer
+
+services:
+ template.twig.extensions.icon:
+ class: phpbb\template\twig\extension\icon
+ arguments:
+ - '@user'
+ tags:
+ - { name: twig.extension }
diff --git a/phpBB/config/default/container/tables.yml b/phpBB/config/default/container/tables.yml
index 4aed35710b..f3c2282de9 100644
--- a/phpBB/config/default/container/tables.yml
+++ b/phpBB/config/default/container/tables.yml
@@ -8,6 +8,7 @@ parameters:
tables.auth_provider_oauth_token_storage: '%core.table_prefix%oauth_tokens'
tables.auth_provider_oauth_states: '%core.table_prefix%oauth_states'
tables.auth_provider_oauth_account_assoc: '%core.table_prefix%oauth_accounts'
+ tables.backups: '%core.table_prefix%backups'
tables.banlist: '%core.table_prefix%banlist'
tables.bbcodes: '%core.table_prefix%bbcodes'
tables.bookmarks: '%core.table_prefix%bookmarks'
@@ -59,6 +60,7 @@ parameters:
tables.sitelist: '%core.table_prefix%sitelist'
tables.smilies: '%core.table_prefix%smilies'
tables.sphinx: '%core.table_prefix%sphinx'
+ tables.storage: '%core.table_prefix%storage'
tables.styles: '%core.table_prefix%styles'
tables.styles_template: '%core.table_prefix%styles_template'
tables.styles_template_data: '%core.table_prefix%styles_template_data'
diff --git a/phpBB/config/development/config.yml b/phpBB/config/development/config.yml
index c782e7a45f..e3eb537806 100644
--- a/phpBB/config/development/config.yml
+++ b/phpBB/config/development/config.yml
@@ -17,5 +17,9 @@ core:
auto_reload: true
enable_debug_extension: true
+ extensions:
+ composer_debug: true
+ composer_verbose: true
+
session:
log_errors: true
diff --git a/phpBB/config/installer/container/services.yml b/phpBB/config/installer/container/services.yml
index 7203c0ab10..080b8a48e3 100644
--- a/phpBB/config/installer/container/services.yml
+++ b/phpBB/config/installer/container/services.yml
@@ -31,7 +31,6 @@ services:
file_locator:
class: phpbb\routing\file_locator
arguments:
- - '@filesystem'
- '%core.root_path%'
kernel_exception_subscriber:
@@ -50,7 +49,6 @@ services:
class: phpbb\path_helper
arguments:
- '@symfony_request'
- - '@filesystem'
- '@request'
- '%core.root_path%'
- '%core.php_ext%'
diff --git a/phpBB/config/installer/container/services_install_database.yml b/phpBB/config/installer/container/services_install_database.yml
index 33f596506d..bc35c6af4e 100644
--- a/phpBB/config/installer/container/services_install_database.yml
+++ b/phpBB/config/installer/container/services_install_database.yml
@@ -7,6 +7,7 @@ services:
- '@filesystem'
- '%core.root_path%'
- '%core.php_ext%'
+ - '%tables%'
tags:
- { name: install_database_install, order: 10 }
diff --git a/phpBB/develop/adjust_avatars.php b/phpBB/develop/adjust_avatars.php
index dc4ae88f37..a6b326109d 100644
--- a/phpBB/develop/adjust_avatars.php
+++ b/phpBB/develop/adjust_avatars.php
@@ -19,7 +19,7 @@ $auth->acl($user->data);
$user->setup();
$echos = 0;
-
+
if (!isset($config['avatar_salt']))
{
$cache->purge();
@@ -30,6 +30,11 @@ if (!isset($config['avatar_salt']))
die('database not up to date');
}
+if (!isset($config['storage\\avatar\\config\\path']) || $config['storage\\avatar\\config\\path'] !== 'phpbb\\storage\\provider\\local')
+{
+ die('use local provider');
+}
+
// let's start with the users using a group_avatar.
$sql = 'SELECT group_id, group_avatar
FROM ' . GROUPS_TABLE . '
@@ -46,16 +51,16 @@ while ($row = $db->sql_fetchrow($result))
{
$new_avatar_name = adjust_avatar($row['group_avatar'], 'g' . $row['group_id']);
$group_avatars[] = $new_avatar_name;
-
+
// failure is probably due to the avatar name already being adjusted
if ($new_avatar_name !== false)
{
$sql = 'UPDATE ' . USERS_TABLE . "
SET user_avatar = '" . $db->sql_escape($new_avatar_name) . "'
- WHERE user_avatar = '" . $db->sql_escape($row['group_avatar']) . "'
+ WHERE user_avatar = '" . $db->sql_escape($row['group_avatar']) . "'
AND user_avatar_type = " . AVATAR_UPLOAD;
$db->sql_query($sql);
-
+
$sql = 'UPDATE ' . GROUPS_TABLE . "
SET group_avatar = '" . $db->sql_escape($new_avatar_name) . "'
WHERE group_id = {$row['group_id']}";
@@ -80,8 +85,8 @@ while ($row = $db->sql_fetchrow($result))
$db->sql_freeresult($result);
$sql = 'SELECT user_id, username, user_avatar, user_avatar_type
- FROM ' . USERS_TABLE . '
- WHERE user_avatar_type = ' . AVATAR_UPLOAD . '
+ FROM ' . USERS_TABLE . '
+ WHERE user_avatar_type = ' . AVATAR_UPLOAD . '
AND ' . $db->sql_in_set('user_avatar', $group_avatars, true, true);
$result = $db->sql_query($sql);
@@ -108,7 +113,7 @@ while ($row = $db->sql_fetchrow($result))
$db->sql_query($sql);
echo '<br /> Failed updating user ' . $row['user_id'] . "\n";
}
-
+
if ($echos > 200)
{
echo '<br />' . "\n";
@@ -131,8 +136,8 @@ $db->sql_close();
function adjust_avatar($old_name, $midfix)
{
global $config, $phpbb_root_path;
-
- $avatar_path = $phpbb_root_path . $config['avatar_path'];
+
+ $avatar_path = $phpbb_root_path . $config['storage\\avatar\\config\\path'];
$extension = strtolower(substr(strrchr($old_name, '.'), 1));
$new_name = $config['avatar_salt'] . '_' . $midfix . '.' . $extension;
diff --git a/phpBB/develop/create_schema_files.php b/phpBB/develop/create_schema_files.php
index fdaa285f99..311b2fc94a 100644
--- a/phpBB/develop/create_schema_files.php
+++ b/phpBB/develop/create_schema_files.php
@@ -43,7 +43,7 @@ require($phpbb_root_path . 'phpbb/class_loader.' . $phpEx);
$phpbb_class_loader = new \phpbb\class_loader('phpbb\\', "{$phpbb_root_path}phpbb/", $phpEx);
$phpbb_class_loader->register();
-$finder = new \phpbb\finder(new \phpbb\filesystem\filesystem(), $phpbb_root_path);
+$finder = new \phpbb\finder($phpbb_root_path);
$classes = $finder->core_path('phpbb/')
->directory('/db/migration/data')
->get_classes();
@@ -52,7 +52,15 @@ $db = new \phpbb\db\driver\sqlite3();
$factory = new \phpbb\db\tools\factory();
$db_tools = $factory->get($db, true);
-$schema_generator = new \phpbb\db\migration\schema_generator($classes, new \phpbb\config\config(array()), $db, $db_tools, $phpbb_root_path, $phpEx, $table_prefix);
+$tables_data = \Symfony\Component\Yaml\Yaml::parseFile($phpbb_root_path . '/config/default/container/tables.yml');
+$tables = [];
+
+foreach ($tables_data['parameters'] as $parameter => $table)
+{
+ $tables[str_replace('tables.', '', $parameter)] = str_replace('%core.table_prefix%', $table_prefix, $table);
+}
+
+$schema_generator = new \phpbb\db\migration\schema_generator($classes, new \phpbb\config\config(array()), $db, $db_tools, $phpbb_root_path, $phpEx, $table_prefix, $tables);
$schema_data = $schema_generator->get_schema();
$fp = fopen($schema_path . 'schema.json', 'wb');
diff --git a/phpBB/docs/coding-guidelines.html b/phpBB/docs/coding-guidelines.html
index b2f6780e03..bcda452a7c 100644
--- a/phpBB/docs/coding-guidelines.html
+++ b/phpBB/docs/coding-guidelines.html
@@ -264,7 +264,6 @@ PHPBB_QA (Set board to QA-Mode, which means the updater also c
<li>{T_SUPER_TEMPLATE_PATH} - styles/xxx/template</li>
<li>{T_IMAGES_PATH} - images/</li>
<li>{T_SMILIES_PATH} - $config['smilies_path']/</li>
- <li>{T_AVATAR_PATH} - $config['avatar_path']/</li>
<li>{T_AVATAR_GALLERY_PATH} - $config['avatar_gallery_path']/</li>
<li>{T_ICONS_PATH} - $config['icons_path']/</li>
<li>{T_RANKS_PATH} - $config['ranks_path']/</li>
diff --git a/phpBB/docs/lighttpd.sample.conf b/phpBB/docs/lighttpd.sample.conf
index f5b509e002..e783c809fc 100644
--- a/phpBB/docs/lighttpd.sample.conf
+++ b/phpBB/docs/lighttpd.sample.conf
@@ -3,17 +3,8 @@
# from your system's lighttpd.conf.
# Tested with lighttpd 1.4.35
-# If you want to use the X-Sendfile feature,
-# uncomment the 'allow-x-send-file' for the fastcgi
-# server below and add the following to your config.php
-#
-# define('PHPBB_ENABLE_X_SENDFILE', true);
-#
-# See http://blog.lighttpd.net/articles/2006/07/02/x-sendfile
-# for the details on X-Sendfile.
-
# Load moules
-server.modules += (
+server.modules += (
"mod_access",
"mod_fastcgi",
"mod_rewrite",
@@ -32,11 +23,11 @@ $HTTP["host"] == "www.myforums.com" {
server.name = "www.myforums.com"
server.document-root = "/path/to/phpbb"
server.dir-listing = "disable"
-
+
index-file.names = ( "index.php", "index.htm", "index.html" )
accesslog.filename = "/var/log/lighttpd/access-www.myforums.com.log"
-
- # Deny access to internal phpbb files.
+
+ # Deny access to internal phpbb files.
$HTTP["url"] =~ "^/(config\.php|common\.php|cache|files|images/avatars/upload|includes|phpbb|store|vendor)" {
url.access-deny = ( "" )
}
@@ -45,12 +36,12 @@ $HTTP["host"] == "www.myforums.com" {
$HTTP["url"] =~ "/\.svn|/\.git" {
url.access-deny = ( "" )
}
-
+
# Deny access to apache configuration files.
$HTTP["url"] =~ "/\.htaccess|/\.htpasswd|/\.htgroups" {
url.access-deny = ( "" )
}
-
+
# The following 3 lines will rewrite URLs passed through the front controller
# to not require app.php in the actual URL. In other words, a controller is
# by default accessed at /app.php/my/controller, but can also be accessed at
@@ -58,14 +49,14 @@ $HTTP["host"] == "www.myforums.com" {
url.rewrite-if-not-file = (
"^/(.*)$" => "/app.php/$1"
)
-
- fastcgi.server = ( ".php" =>
+
+ fastcgi.server = ( ".php" =>
((
"bin-path" => "/usr/bin/php-cgi",
"socket" => "/tmp/php.socket",
"max-procs" => 4,
"idle-timeout" => 30,
- "bin-environment" => (
+ "bin-environment" => (
"PHP_FCGI_CHILDREN" => "10",
"PHP_FCGI_MAX_REQUESTS" => "10000"
),
diff --git a/phpBB/docs/nginx.sample.conf b/phpBB/docs/nginx.sample.conf
index 25363ad34d..9d2623c88b 100644
--- a/phpBB/docs/nginx.sample.conf
+++ b/phpBB/docs/nginx.sample.conf
@@ -7,14 +7,6 @@
#
# Replace example.com with your own domain name.
-# If you want to use the X-Accel-Redirect feature,
-# add the following to your config.php.
-#
-# define('PHPBB_ENABLE_X_ACCEL_REDIRECT', true);
-#
-# See http://wiki.nginx.org/XSendfile for the details
-# on X-Accel-Redirect.
-
# Sample FastCGI server configuration.
# Filename: /etc/nginx/conf.d/php.conf
#
diff --git a/phpBB/download/file.php b/phpBB/download/file.php
index 6d0796d2c4..6b0b577489 100644
--- a/phpBB/download/file.php
+++ b/phpBB/download/file.php
@@ -99,6 +99,11 @@ if (isset($_GET['avatar']))
/* @var $phpbb_avatar_manager \phpbb\avatar\manager */
$phpbb_avatar_manager = $phpbb_container->get('avatar.manager');
+ if (@is_file($phpbb_root_path . $config['exts_composer_vendor_dir'] . '/autoload.php'))
+ {
+ require_once($phpbb_root_path . $config['exts_composer_vendor_dir'] . '/autoload.php');
+ }
+
$filename = $request->variable('avatar', '');
$avatar_group = false;
$exit = false;
@@ -249,7 +254,6 @@ else
}
}
- $download_mode = (int) $extensions[$attachment['extension']]['download_mode'];
$display_cat = $extensions[$attachment['extension']]['display_cat'];
if (($display_cat == ATTACHMENT_CATEGORY_IMAGE || $display_cat == ATTACHMENT_CATEGORY_THUMB) && !$user->optionget('viewimg'))
@@ -257,6 +261,18 @@ else
$display_cat = ATTACHMENT_CATEGORY_NONE;
}
+ if ($thumbnail)
+ {
+ $attachment['physical_filename'] = 'thumb_' . $attachment['physical_filename'];
+ }
+ else if ($display_cat == ATTACHMENT_CATEGORY_NONE && !$attachment['is_orphan'] && !phpbb_http_byte_range($attachment['filesize']))
+ {
+ // Update download count
+ phpbb_increment_downloads($db, $attachment['attach_id']);
+ }
+
+ $redirect = '';
+
/**
* Event to modify data before sending file to browser
*
@@ -264,34 +280,25 @@ else
* @var int attach_id The attachment ID
* @var array attachment Array with attachment data
* @var int display_cat Attachment category
- * @var int download_mode File extension specific download mode
* @var array extensions Array with file extensions data
* @var string mode Download mode
* @var bool thumbnail Flag indicating if the file is a thumbnail
+ * @var string redirect Do a redirection instead of reading the file
* @since 3.1.6-RC1
* @changed 3.1.7-RC1 Fixing wrong name of a variable (replacing "extension" by "extensions")
+ * @changed 3.3.0-a1 Add redirect variable
*/
$vars = array(
'attach_id',
'attachment',
'display_cat',
- 'download_mode',
'extensions',
'mode',
'thumbnail',
+ 'redirect',
);
extract($phpbb_dispatcher->trigger_event('core.download_file_send_to_browser_before', compact($vars)));
- if ($thumbnail)
- {
- $attachment['physical_filename'] = 'thumb_' . $attachment['physical_filename'];
- }
- else if ($display_cat == ATTACHMENT_CATEGORY_NONE && !$attachment['is_orphan'] && !phpbb_http_byte_range($attachment['filesize']))
- {
- // Update download count
- phpbb_increment_downloads($db, $attachment['attach_id']);
- }
-
if ($display_cat == ATTACHMENT_CATEGORY_IMAGE && $mode === 'view' && (strpos($attachment['mimetype'], 'image') === 0) && (strpos(strtolower($user->browser), 'msie') !== false) && !phpbb_is_greater_ie_version($user->browser, 7))
{
wrap_img_in_html(append_sid($phpbb_root_path . 'download/file.' . $phpEx, 'id=' . $attachment['attach_id']), $attachment['real_filename']);
@@ -299,23 +306,15 @@ else
}
else
{
- // Determine the 'presenting'-method
- if ($download_mode == PHYSICAL_LINK)
+ if (!empty($redirect))
{
- // This presenting method should no longer be used
- if (!@is_dir($phpbb_root_path . $config['upload_path']))
- {
- send_status_line(500, 'Internal Server Error');
- trigger_error($user->lang['PHYSICAL_DOWNLOAD_NOT_POSSIBLE']);
- }
-
- redirect($phpbb_root_path . $config['upload_path'] . '/' . $attachment['physical_filename']);
- file_gc();
+ redirect($redirect, false, true);
}
else
{
- send_file_to_browser($attachment, $config['upload_path'], $display_cat);
- file_gc();
+ send_file_to_browser($attachment, $display_cat);
}
+
+ file_gc();
}
}
diff --git a/phpBB/includes/acp/acp_attachments.php b/phpBB/includes/acp/acp_attachments.php
index dfac246647..36522b9829 100644
--- a/phpBB/includes/acp/acp_attachments.php
+++ b/phpBB/includes/acp/acp_attachments.php
@@ -151,7 +151,6 @@ class acp_attachments
'allow_attachments' => array('lang' => 'ALLOW_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
'allow_pm_attach' => array('lang' => 'ALLOW_PM_ATTACHMENTS', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => false),
- 'upload_path' => array('lang' => 'UPLOAD_DIR', 'validate' => 'wpath', 'type' => 'text:25:100', 'explain' => true),
'display_order' => array('lang' => 'DISPLAY_ORDER', 'validate' => 'bool', 'type' => 'custom', 'method' => 'display_order', 'explain' => true),
'attachment_quota' => array('lang' => 'ATTACH_QUOTA', 'validate' => 'string', 'type' => 'custom', 'method' => 'max_filesize', 'explain' => true),
'max_filesize' => array('lang' => 'ATTACH_MAX_FILESIZE', 'validate' => 'string', 'type' => 'custom', 'method' => 'max_filesize', 'explain' => true),
@@ -228,9 +227,6 @@ class acp_attachments
{
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_CONFIG_ATTACH');
- // Check Settings
- $this->test_upload($error, $this->new_config['upload_path'], false);
-
if (!count($error))
{
trigger_error($user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
@@ -563,11 +559,6 @@ class acp_attachments
'allow_in_pm' => ($allow_in_pm) ? 1 : 0,
);
- if ($action == 'add')
- {
- $group_ary['download_mode'] = INLINE_LINK;
- }
-
$sql = ($action == 'add') ? 'INSERT INTO ' . EXTENSION_GROUPS_TABLE . ' ' : 'UPDATE ' . EXTENSION_GROUPS_TABLE . ' SET ';
$sql .= $db->sql_build_array((($action == 'add') ? 'INSERT' : 'UPDATE'), $group_ary);
$sql .= ($action == 'edit') ? " WHERE group_id = $group_id" : '';
diff --git a/phpBB/includes/acp/acp_database.php b/phpBB/includes/acp/acp_database.php
index c1c748832b..59a079bde9 100644
--- a/phpBB/includes/acp/acp_database.php
+++ b/phpBB/includes/acp/acp_database.php
@@ -21,16 +21,20 @@ if (!defined('IN_PHPBB'))
class acp_database
{
- var $db_tools;
- var $u_action;
+ protected $db_tools;
+ protected $temp;
+ public $u_action;
public $page_title;
function main($id, $mode)
{
global $cache, $db, $user, $template, $table_prefix, $request;
- global $phpbb_root_path, $phpbb_container, $phpbb_log;
+ global $phpbb_root_path, $phpbb_container, $phpbb_log, $table_prefix;
$this->db_tools = $phpbb_container->get('dbal.tools');
+ $this->temp = $phpbb_container->get('filesystem.temp');
+ /** @var \phpbb\storage\storage $storage */
+ $storage = $phpbb_container->get('storage.backup');
$user->add_lang('acp/database');
@@ -90,51 +94,111 @@ class acp_database
$filename = 'backup_' . $time . '_' . unique_id();
- /** @var phpbb\db\extractor\extractor_interface $extractor Database extractor */
- $extractor = $phpbb_container->get('dbal.extractor');
- $extractor->init_extractor($format, $filename, $time, false, $store);
+ try
+ {
+ /** @var phpbb\db\extractor\extractor_interface $extractor Database extractor */
+ $extractor = $phpbb_container->get('dbal.extractor');
+ $extractor->init_extractor($format, $filename, $time, false, $store);
- $extractor->write_start($table_prefix);
+ $extractor->write_start($table_prefix);
- foreach ($table as $table_name)
- {
- // Get the table structure
- if ($structure)
+ foreach ($table as $table_name)
{
- $extractor->write_table($table_name);
- }
- else
- {
- // We might wanna empty out all that junk :D
- switch ($db->get_sql_layer())
+ // Get the table structure
+ if ($structure)
{
- case 'sqlite3':
- $extractor->flush('DELETE FROM ' . $table_name . ";\n");
- break;
-
- case 'mssql_odbc':
- case 'mssqlnative':
- $extractor->flush('TRUNCATE TABLE ' . $table_name . "GO\n");
- break;
-
- case 'oracle':
- $extractor->flush('TRUNCATE TABLE ' . $table_name . "/\n");
- break;
-
- default:
- $extractor->flush('TRUNCATE TABLE ' . $table_name . ";\n");
- break;
+ // Add table structure to the backup
+ // This method also add a "drop the table if exists" after trying to write the table structure
+ $extractor->write_table($table_name);
+ }
+ else
+ {
+ // Add command to empty table before write data on it
+ switch ($db->get_sql_layer())
+ {
+ case 'sqlite3':
+ $extractor->flush('DELETE FROM ' . $table_name . ";\n");
+ break;
+
+ case 'mssql_odbc':
+ case 'mssqlnative':
+ $extractor->flush('TRUNCATE TABLE ' . $table_name . "GO\n");
+ break;
+
+ case 'oracle':
+ $extractor->flush('TRUNCATE TABLE ' . $table_name . "/\n");
+ break;
+
+ default:
+ $extractor->flush('TRUNCATE TABLE ' . $table_name . ";\n");
+ break;
+ }
+ }
+
+ // Write schema data if it exists
+ if ($schema_data)
+ {
+ $extractor->write_data($table_name);
}
}
- // Data
- if ($schema_data)
+ $extractor->write_end();
+ }
+ catch (\phpbb\exception\runtime_exception $e)
+ {
+ trigger_error($e->getMessage(), E_USER_ERROR);
+ }
+
+ try
+ {
+ if ($store)
{
- $extractor->write_data($table_name);
+ // Get file name
+ switch ($format)
+ {
+ case 'text':
+ $ext = '.sql';
+ break;
+ case 'bzip2':
+ $ext = '.sql.gz2';
+ break;
+ case 'gzip':
+ $ext = '.sql.gz';
+ break;
+ }
+
+ $file = $filename . $ext;
+
+ // Copy to storage using streams
+ $temp_dir = $this->temp->get_dir();
+
+ $fp = fopen($temp_dir . '/' . $file, 'rb');
+
+ if ($fp === false)
+ {
+ throw new \phpbb\exception\runtime_exception('CANNOT_OPEN_FILE');
+ }
+
+ $storage->write_stream($file, $fp);
+
+ if (is_resource($fp))
+ {
+ fclose($fp);
+ }
+
+ // Remove file from tmp
+ @unlink($temp_dir . '/' . $file);
+
+ // Save to database
+ $sql = "INSERT INTO " . $table_prefix . "backups (filename)
+ VALUES ('$file');";
+ $db->sql_query($sql);
}
}
-
- $extractor->write_end();
+ catch (\phpbb\exception\runtime_exception $e)
+ {
+ trigger_error($e->getMessage(), E_USER_ERROR);
+ }
$phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_BACKUP');
@@ -190,9 +254,9 @@ class acp_database
$delete = $request->variable('delete', '');
$file = $request->variable('file', '');
- $backup_info = $this->get_backup_file($phpbb_root_path . 'store/', $file);
+ $backup_info = $this->get_backup_file($db, $file);
- if (empty($backup_info) || !is_readable($backup_info['file_name']))
+ if (empty($backup_info))
{
trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
}
@@ -201,8 +265,24 @@ class acp_database
{
if (confirm_box(true))
{
- unlink($backup_info['file_name']);
- $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_DELETE');
+ try
+ {
+ // Delete from storage
+ $storage->delete($backup_info['file_name']);
+
+ // Add log entry
+ $phpbb_log->add('admin', $user->data['user_id'], $user->ip, 'LOG_DB_DELETE');
+
+ // Remove from database
+ $sql = "DELETE FROM " . $table_prefix . "backups
+ WHERE filename = '" . $db->sql_escape($backup_info['file_name']) . "';";
+ $db->sql_query($sql);
+ }
+ catch (\Exception $e)
+ {
+ trigger_error($user->lang['BACKUP_ERROR'] . adm_back_link($this->u_action), E_USER_WARNING);
+ }
+
trigger_error($user->lang['BACKUP_DELETE'] . adm_back_link($this->u_action));
}
else
@@ -212,10 +292,28 @@ class acp_database
}
else if (confirm_box(true))
{
+ // Copy file to temp folder to decompress it
+ $temp_file_name = $this->temp->get_dir() . '/' . $backup_info['file_name'];
+
+ try
+ {
+ $stream = $storage->read_stream($backup_info['file_name']);
+ $fp = fopen($temp_file_name, 'w+b');
+
+ stream_copy_to_stream($stream, $fp);
+
+ fclose($fp);
+ fclose($stream);
+ }
+ catch (\phpbb\storage\exception\exception $e)
+ {
+ trigger_error($user->lang['RESTORE_DOWNLOAD_FAIL'] . adm_back_link($this->u_action));
+ }
+
switch ($backup_info['extension'])
{
case 'sql':
- $fp = fopen($backup_info['file_name'], 'rb');
+ $fp = fopen($temp_file_name, 'rb');
$read = 'fread';
$seek = 'fseek';
$eof = 'feof';
@@ -224,7 +322,7 @@ class acp_database
break;
case 'sql.bz2':
- $fp = bzopen($backup_info['file_name'], 'r');
+ $fp = bzopen($temp_file_name, 'r');
$read = 'bzread';
$seek = '';
$eof = 'feof';
@@ -233,7 +331,7 @@ class acp_database
break;
case 'sql.gz':
- $fp = gzopen($backup_info['file_name'], 'rb');
+ $fp = gzopen($temp_file_name, 'rb');
$read = 'gzread';
$seek = 'gzseek';
$eof = 'gzeof';
@@ -242,6 +340,7 @@ class acp_database
break;
default:
+ @unlink($temp_file_name);
trigger_error($user->lang['BACKUP_INVALID'] . adm_back_link($this->u_action), E_USER_WARNING);
return;
}
@@ -314,6 +413,8 @@ class acp_database
$close($fp);
+ @unlink($temp_file_name);
+
// Purge the cache due to updated data
$cache->purge();
@@ -327,7 +428,7 @@ class acp_database
}
default:
- $backup_files = $this->get_file_list($phpbb_root_path . 'store/');
+ $backup_files = $this->get_file_list($db);
if (!empty($backup_files))
{
@@ -355,16 +456,16 @@ class acp_database
/**
* Get backup file from file hash
*
- * @param string $directory Relative path to directory
+ * @param \phpbb\db\driver\driver_interface $db Database driver
* @param string $file_hash Hash of selected file
*
* @return array Backup file data or empty array if unable to find file
*/
- protected function get_backup_file($directory, $file_hash)
+ protected function get_backup_file($db, $file_hash)
{
$backup_data = [];
- $file_list = $this->get_file_list($directory);
+ $file_list = $this->get_file_list($db);
$supported_extensions = $this->get_supported_extensions();
foreach ($file_list as $file)
@@ -373,7 +474,7 @@ class acp_database
if (sha1($file) === $file_hash && in_array($matches[2], $supported_extensions))
{
$backup_data = [
- 'file_name' => $directory . $file,
+ 'file_name' => $file,
'extension' => $matches[2],
];
break;
@@ -386,32 +487,31 @@ class acp_database
/**
* Get backup file list for directory
*
- * @param string $directory Relative path to backup directory
+ * @param \phpbb\db\driver\driver_interface $db Database driver
*
* @return array List of backup files in specified directory
*/
- protected function get_file_list($directory)
+ protected function get_file_list($db)
{
$supported_extensions = $this->get_supported_extensions();
- $dh = @opendir($directory);
-
$backup_files = [];
- if ($dh)
+ $sql = 'SELECT filename
+ FROM ' . BACKUPS_TABLE;
+ $result = $db->sql_query($sql);
+
+ while ($row = $db->sql_fetchrow($result))
{
- while (($file = readdir($dh)) !== false)
+ if (preg_match('#^backup_(\d{10,})_(?:[a-z\d]{16}|[a-z\d]{32})\.(sql(?:\.(?:gz|bz2))?)$#i', $row['filename'], $matches))
{
- if (preg_match('#^backup_(\d{10,})_(?:[a-z\d]{16}|[a-z\d]{32})\.(sql(?:\.(?:gz|bz2))?)$#i', $file, $matches))
+ if (in_array($matches[2], $supported_extensions))
{
- if (in_array($matches[2], $supported_extensions))
- {
- $backup_files[(int) $matches[1]] = $file;
- }
+ $backup_files[(int) $matches[1]] = $row['filename'];
}
}
- closedir($dh);
}
+ $db->sql_freeresult($result);
return $backup_files;
}
diff --git a/phpBB/includes/acp/acp_extensions.php b/phpBB/includes/acp/acp_extensions.php
index 86966541be..ac1c3965ed 100644
--- a/phpBB/includes/acp/acp_extensions.php
+++ b/phpBB/includes/acp/acp_extensions.php
@@ -24,25 +24,38 @@ if (!defined('IN_PHPBB'))
class acp_extensions
{
- var $u_action;
- var $tpl_name;
- var $page_title;
+ public $u_action;
+ private $db;
+
+ /** @var phpbb\config\config */
private $config;
+
+ /** @var \phpbb\template\twig\twig */
private $template;
private $user;
private $log;
+
+ /** @var \phpbb\request\request */
private $request;
private $phpbb_dispatcher;
+
+ /** @var \phpbb\extension\manager */
private $ext_manager;
+
private $phpbb_container;
private $php_ini;
+ private $u_catalog_action;
+
+ /** @var string */
+ private $phpbb_root_path;
function main($id, $mode)
{
// Start the page
- global $config, $user, $template, $request, $phpbb_extension_manager, $phpbb_root_path, $phpbb_log, $phpbb_dispatcher, $phpbb_container;
+ global $config, $user, $template, $request, $phpbb_extension_manager, $db, $phpbb_log, $phpbb_dispatcher, $phpbb_container, $phpbb_root_path;
+ $this->db = $db;
$this->config = $config;
$this->template = $template;
$this->user = $user;
@@ -52,8 +65,24 @@ class acp_extensions
$this->ext_manager = $phpbb_extension_manager;
$this->phpbb_container = $phpbb_container;
$this->php_ini = $this->phpbb_container->get('php_ini');
+ $this->phpbb_root_path = $phpbb_root_path;
+
+ $this->user->add_lang(['install', 'acp/extensions', 'migrator']);
+
+ switch ($mode)
+ {
+ case 'catalog':
+ $this->catalog_mode($id, $mode);
+ break;
+ default:
+ $this->main_mode($id, $mode);
+ break;
+ }
+ }
- $this->user->add_lang(array('install', 'acp/extensions', 'migrator'));
+ public function main_mode($id, $mode)
+ {
+ global $phpbb_extension_manager, $phpbb_container, $phpbb_admin_path, $phpEx;
$this->page_title = 'ACP_EXTENSIONS';
@@ -114,6 +143,8 @@ class acp_extensions
}
}
+ $this->u_catalog_action = append_sid("{$phpbb_admin_path}index.$phpEx", "i=$id&amp;mode=catalog");
+
// What are we doing?
switch ($action)
{
@@ -137,7 +168,7 @@ class acp_extensions
$this->config->set('extension_force_unstable', false);
trigger_error($this->user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
}
- break;
+ break;
case 'list':
default:
@@ -147,15 +178,27 @@ class acp_extensions
trigger_error($this->user->lang['CONFIG_UPDATED'] . adm_back_link($this->u_action));
}
- $this->list_enabled_exts();
- $this->list_disabled_exts();
- $this->list_available_exts();
+ /** @var \phpbb\composer\manager $composer_manager */
+ $composer_manager = $phpbb_container->get('ext.composer.manager');
+
+ $managed_packages = [];
+ if ($composer_manager->check_requirements())
+ {
+ $managed_packages = $composer_manager->get_managed_packages();
+ }
+
+ $this->list_enabled_exts($phpbb_extension_manager, $managed_packages);
+ $this->list_disabled_exts($phpbb_extension_manager, $managed_packages);
+ $this->list_available_exts($phpbb_extension_manager, $managed_packages);
$this->template->assign_vars(array(
'U_VERSIONCHECK_FORCE' => $this->u_action . '&amp;action=list&amp;versioncheck_force=1',
'FORCE_UNSTABLE' => $this->config['extension_force_unstable'],
'U_ACTION' => $this->u_action,
+ 'MANAGED_EXTENSIONS' => $managed_packages,
+ 'U_CATALOG_ACTION' => $this->u_catalog_action,
));
+ $this->request->disable_super_globals();
$this->tpl_name = 'acp_ext_list';
break;
@@ -228,7 +271,7 @@ class acp_extensions
'name' => 'adm',
'ext_path' => 'adm/style/',
),
- ), array($phpbb_root_path . 'adm/style'));
+ ), array($this->phpbb_root_path . 'adm/style'));
$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'LOG_EXT_ENABLE', time(), array($ext_name));
}
@@ -457,11 +500,340 @@ class acp_extensions
}
/**
- * Lists all the enabled extensions and dumps to the template
- *
- * @return null
- */
- public function list_enabled_exts()
+ * Handles the catalog mode of the extensions list
+ *
+ * @param string $id
+ * @param string $mode
+ */
+ public function catalog_mode($id, $mode)
+ {
+ global $phpbb_container;
+
+ $action = $this->request->variable('action', 'list');
+
+ /** @var \phpbb\language\language $language */
+ $language = $phpbb_container->get('language');
+
+ /** @var \phpbb\composer\manager $composer_manager */
+ $composer_manager = $phpbb_container->get('ext.composer.manager');
+
+ /** @var \phpbb\extension\manager $extensions_manager */
+ $extensions_manager = $phpbb_container->get('ext.manager');
+
+ if (!$composer_manager->check_requirements())
+ {
+ $this->page_title = 'ACP_EXTENSIONS_CATALOG';
+ $this->tpl_name = 'message_body';
+
+ $this->template->assign_vars([
+ 'MESSAGE_TITLE' => $language->lang('EXTENSIONS_CATALOG_NOT_AVAILABLE'),
+ 'MESSAGE_TEXT' => $language->lang('EXTENSIONS_COMPOSER_NOT_WRITABLE'),
+ ]);
+
+ return;
+ }
+
+ switch ($action)
+ {
+ case 'install':
+ $this->page_title = 'ACP_EXTENSIONS_INSTALL';
+
+ $extension = $this->request->variable('extension', '');
+
+ if (empty($extension))
+ {
+ redirect($this->u_action);
+ }
+
+ $formatter = new \phpbb\composer\io\html_output_formatter([
+ 'warning' => new \Symfony\Component\Console\Formatter\OutputFormatterStyle('black', 'yellow')
+ ]);
+
+ $composer_io = new \phpbb\composer\io\web_io($language, '', $phpbb_container->getParameter('extensions.composer.output'), $formatter);
+
+ try
+ {
+ $composer_manager->install((array) $extension, $composer_io);
+ }
+ catch (\phpbb\exception\runtime_exception $e)
+ {
+ $this->display_composer_exception($language, $e, $composer_io);
+ return;
+ }
+ $this->tpl_name = 'detailed_message_body';
+
+ $this->template->assign_vars(array(
+ 'MESSAGE_TITLE' => $language->lang('ACP_EXTENSIONS_INSTALL'),
+ 'MESSAGE_TEXT' => $language->lang('EXTENSIONS_INSTALLED') . adm_back_link($this->u_action),
+ 'MESSAGE_DETAIL' => $composer_io->getOutput(),
+ 'MESSAGE_DETAIL_LEGEND' => $language->lang('COMPOSER_OUTPUT'),
+ 'S_USER_NOTICE' => true,
+ )
+ );
+
+ break;
+ case 'remove':
+ $this->page_title = 'ACP_EXTENSIONS_REMOVE';
+
+ $extension = $this->request->variable('extension', '');
+
+ if (empty($extension))
+ {
+ redirect($this->u_action);
+ }
+
+ $formatter = new \phpbb\composer\io\html_output_formatter([
+ 'warning' => new \Symfony\Component\Console\Formatter\OutputFormatterStyle('black', 'yellow')
+ ]);
+
+ $composer_io = new \phpbb\composer\io\web_io($language, '', $phpbb_container->getParameter('extensions.composer.output'), $formatter);
+
+ try
+ {
+ $composer_manager->remove((array) $extension, $composer_io);
+ }
+ catch (\phpbb\exception\runtime_exception $e)
+ {
+ $this->display_composer_exception($language, $e, $composer_io);
+ return;
+ }
+ $this->tpl_name = 'detailed_message_body';
+
+ $this->template->assign_vars(array(
+ 'MESSAGE_TITLE' => $language->lang('ACP_EXTENSIONS_REMOVE'),
+ 'MESSAGE_TEXT' => $language->lang('EXTENSIONS_REMOVED') . adm_back_link($this->u_action),
+ 'MESSAGE_DETAIL' => $composer_io->getOutput(),
+ 'MESSAGE_DETAIL_LEGEND' => $language->lang('COMPOSER_OUTPUT'),
+ 'S_USER_NOTICE' => true,
+ )
+ );
+
+ break;
+ case 'update':
+ $this->page_title = 'ACP_EXTENSIONS_UPDATE';
+
+ $extension = $this->request->variable('extension', '');
+
+ if (empty($extension))
+ {
+ redirect($this->u_action);
+ }
+
+ $formatter = new \phpbb\composer\io\html_output_formatter([
+ 'warning' => new \Symfony\Component\Console\Formatter\OutputFormatterStyle('black', 'yellow')
+ ]);
+
+ $composer_io = new \phpbb\composer\io\web_io($language, '', $phpbb_container->getParameter('extensions.composer.output'), $formatter);
+
+ try
+ {
+ $composer_manager->update((array) $extension, $composer_io);
+ }
+ catch (\phpbb\exception\runtime_exception $e)
+ {
+ $this->display_composer_exception($language, $e, $composer_io);
+ return;
+ }
+ $this->tpl_name = 'detailed_message_body';
+
+ $this->template->assign_vars(array(
+ 'MESSAGE_TITLE' => $language->lang('ACP_EXTENSIONS_UPDATE'),
+ 'MESSAGE_TEXT' => $language->lang('EXTENSIONS_UPDATED') . adm_back_link($this->u_action),
+ 'MESSAGE_DETAIL' => $composer_io->getOutput(),
+ 'MESSAGE_DETAIL_LEGEND' => $language->lang('COMPOSER_OUTPUT'),
+ 'S_USER_NOTICE' => true,
+ )
+ );
+
+ break;
+ case 'manage':
+ $this->page_title = 'ACP_EXTENSIONS_MANAGE';
+
+ $extension = $this->request->variable('extension', '');
+
+ if (empty($extension))
+ {
+ redirect($this->u_action);
+ }
+
+ $formatter = new \phpbb\composer\io\html_output_formatter([
+ 'warning' => new \Symfony\Component\Console\Formatter\OutputFormatterStyle('black', 'yellow')
+ ]);
+
+ $composer_io = new \phpbb\composer\io\web_io($language, '', $phpbb_container->getParameter('extensions.composer.output'), $formatter);
+
+ try
+ {
+ $composer_manager->start_managing($extension, $composer_io);
+ }
+ catch (\phpbb\exception\runtime_exception $e)
+ {
+ $this->display_composer_exception($language, $e, $composer_io);
+ return;
+ }
+ $this->tpl_name = 'detailed_message_body';
+
+ $this->template->assign_vars(array(
+ 'MESSAGE_TITLE' => $language->lang('ACP_EXTENSIONS_MANAGE'),
+ 'MESSAGE_TEXT' => $language->lang('EXTENSION_MANAGED_SUCCESS', $extension) . adm_back_link($this->u_action),
+ 'MESSAGE_DETAIL' => $composer_io->getOutput(),
+ 'MESSAGE_DETAIL_LEGEND' => $language->lang('COMPOSER_OUTPUT'),
+ 'S_USER_NOTICE' => true,
+ )
+ );
+
+ break;
+ case 'list':
+ default:
+ if (!$this->config['exts_composer_packagist'] && $this->request->is_set('enable_packagist') && confirm_box(true))
+ {
+ $this->config->set('exts_composer_packagist', true);
+ $composer_manager->reset_cache();
+
+ trigger_error($language->lang('CONFIG_UPDATED') . adm_back_link($this->u_action));
+ }
+
+ $submit = $this->request->is_set('update');
+ if ($submit)
+ {
+ if (!check_form_key('catalog_settings'))
+ {
+ trigger_error($language->lang('FORM_INVALID') . adm_back_link($this->u_action), E_USER_WARNING);
+ }
+
+ $enable_packagist = $this->request->variable('enable_packagist', false);
+ $enable_on_install = $this->request->variable('enable_on_install', false);
+ $purge_on_remove = $this->request->variable('purge_on_remove', false);
+ $minimum_stability = $this->request->variable('minimum_stability', 'stable');
+ $repositories = array_unique(
+ array_filter(
+ array_map(
+ 'trim',
+ explode("\n", $this->request->variable('repositories', ''))
+ )
+ )
+ );
+
+ $previous_minimum_stability = $this->config['exts_composer_minimum_stability'];
+ $previous_repositories = $this->config['exts_composer_repositories'];
+ $previous_enable_packagist = $this->config['exts_composer_packagist'];
+
+ $this->config->set('exts_composer_enable_on_install', $enable_on_install);
+ $this->config->set('exts_composer_purge_on_remove', $purge_on_remove);
+ $this->config->set('exts_composer_minimum_stability', $minimum_stability);
+ $this->config->set('exts_composer_repositories', json_encode($repositories, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES));
+
+ if ($minimum_stability != $previous_minimum_stability
+ || $repositories != $previous_repositories
+ || $enable_packagist != $previous_enable_packagist)
+ {
+ $composer_manager->reset_cache();
+ }
+
+ if (!$this->config['exts_composer_packagist'] && $enable_packagist)
+ {
+ $s_hidden_fields = build_hidden_fields(array(
+ 'enable_packagist' => $enable_packagist
+ ));
+
+ confirm_box(false, $language->lang('ENABLE_PACKAGIST_CONFIRM'), $s_hidden_fields);
+ }
+ else
+ {
+ $this->config->set('exts_composer_packagist', $enable_packagist);
+ trigger_error($language->lang('CONFIG_UPDATED') . adm_back_link($this->u_action));
+ }
+ }
+
+ /** @var \phpbb\composer\extension_manager $manager */
+ $manager = $phpbb_container->get('ext.composer.manager');
+
+ /** @var \phpbb\pagination $pagination */
+ $pagination = $phpbb_container->get('pagination');
+
+ $start = $this->request->variable('start', 0);
+ $base_url = $this->u_action;
+
+ $available_extensions = $manager->get_available_packages();
+ $managed_packages = $manager->get_managed_packages();
+
+ $extensions = array_slice($available_extensions, $start, 20);
+
+ $pagination->generate_template_pagination($base_url, 'pagination', 'start', count($available_extensions), 20, $start);
+
+ $this->page_title = 'ACP_EXTENSIONS_CATALOG';
+ $this->tpl_name = 'acp_ext_catalog';
+
+ $this->template->assign_vars([
+ 'extensions' => $extensions,
+ 'managed_extensions' => array_keys($managed_packages),
+ 'installed_extensions' => array_keys($extensions_manager->all_available()),
+ 'U_ACTION' => $this->u_action,
+ 'settings' => [
+ 'enable_packagist' => $this->config['exts_composer_packagist'],
+ 'enable_on_install' => $this->config['exts_composer_enable_on_install'],
+ 'purge_on_remove' => $this->config['exts_composer_purge_on_remove'],
+ 'minimum_stability' => $this->config['exts_composer_minimum_stability'],
+ 'stabilities' => array_keys(\Composer\Package\BasePackage::$stabilities),
+ 'repositories' => json_decode($this->config['exts_composer_repositories'], true),
+ ],
+ ]);
+
+ add_form_key('catalog_settings');
+
+ break;
+ }
+ }
+
+ /**
+ * Display an exception raised by the composer manager
+ *
+ * @param \phpbb\language\language $language
+ * @param \phpbb\exception\runtime_exception $e
+ * @param \phpbb\composer\io\web_io $composer_io
+ */
+ private function display_composer_exception(\phpbb\language\language $language, \phpbb\exception\runtime_exception $e, \phpbb\composer\io\web_io $composer_io)
+ {
+ $this->tpl_name = 'detailed_message_body';
+
+ if ($e->getPrevious())
+ {
+ $message_title = $language->lang_array($e->getMessage(), $e->get_parameters());
+
+ if ($e->getPrevious() instanceof \phpbb\exception\exception_interface)
+ {
+ $message_text = $language->lang_array($e->getPrevious()->getMessage(), $e->getPrevious()->get_parameters()) . adm_back_link($this->u_action);
+ }
+ else
+ {
+ $message_text = $e->getPrevious()->getMessage() . adm_back_link($this->u_action);
+ }
+ }
+ else
+ {
+ $message_title = $language->lang('INFORMATION');
+ $message_text = $language->lang_array($e->getMessage(), $e->get_parameters()) . adm_back_link($this->u_action);
+ }
+
+ $this->template->assign_vars(array(
+ 'MESSAGE_TITLE' => $message_title,
+ 'MESSAGE_TEXT' => $message_text,
+ 'MESSAGE_DETAIL' => $composer_io->getOutput(),
+ 'MESSAGE_DETAIL_LEGEND' => $language->lang('COMPOSER_OUTPUT'),
+ 'S_USER_ERROR' => true,
+ )
+ );
+ }
+
+ /**
+ * Lists all the enabled extensions and dumps to the template
+ *
+ * @param \phpbb\extension\manager $phpbb_extension_manager An instance of the extension manager
+ * @param array $managed_packages List of managed packages
+ *
+ * @return null
+ */
+ public function list_enabled_exts(\phpbb\extension\manager $phpbb_extension_manager, array $managed_packages)
{
$enabled_extension_meta_data = array();
@@ -475,6 +847,7 @@ class acp_extensions
$enabled_extension_meta_data[$name] = array(
'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'),
'META_VERSION' => $meta['version'],
+ 'META_NAME' => $md_manager->get_metadata('name'),
);
if (isset($meta['extra']['version-check']))
@@ -524,15 +897,29 @@ class acp_extensions
$this->output_actions('enabled', array(
'DISABLE' => $this->u_action . '&amp;action=disable_pre&amp;ext_name=' . urlencode($name),
));
+
+ if (isset($managed_packages[$block_vars['META_NAME']]))
+ {
+ $this->output_actions('enabled', [
+ 'UPDATE' => $this->u_catalog_action . '&amp;action=update&amp;extension=' . urlencode($block_vars['META_NAME']),
+ 'REMOVE' => [
+ 'url' => $this->u_catalog_action . '&amp;action=remove&amp;extension=' . urlencode($block_vars['META_NAME']),
+ 'color' => '#BC2A4D;',
+ ]
+ ]);
+ }
}
}
/**
- * Lists all the disabled extensions and dumps to the template
- *
- * @return null
- */
- public function list_disabled_exts()
+ * Lists all the disabled extensions and dumps to the template
+ *
+ * @param \phpbb\extension\manager $phpbb_extension_manager An instance of the extension manager
+ * @param array $managed_packages List of managed packages
+ *
+ * @return null
+ */
+ public function list_disabled_exts(\phpbb\extension\manager $phpbb_extension_manager, array $managed_packages)
{
$disabled_extension_meta_data = array();
@@ -546,6 +933,7 @@ class acp_extensions
$disabled_extension_meta_data[$name] = array(
'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'),
'META_VERSION' => $meta['version'],
+ 'META_NAME' => $md_manager->get_metadata('name'),
);
if (isset($meta['extra']['version-check']))
@@ -593,15 +981,29 @@ class acp_extensions
'ENABLE' => $this->u_action . '&amp;action=enable_pre&amp;ext_name=' . urlencode($name),
'DELETE_DATA' => $this->u_action . '&amp;action=delete_data_pre&amp;ext_name=' . urlencode($name),
));
+
+ if (isset($managed_packages[$block_vars['META_NAME']]))
+ {
+ $this->output_actions('disabled', [
+ 'UPDATE' => $this->u_catalog_action . '&amp;action=update&amp;extension=' . urlencode($block_vars['META_NAME']),
+ 'REMOVE' => [
+ 'url' => $this->u_catalog_action . '&amp;action=remove&amp;extension=' . urlencode($block_vars['META_NAME']),
+ 'color' => '#BC2A4D;',
+ ]
+ ]);
+ }
}
}
/**
- * Lists all the available extensions and dumps to the template
- *
- * @return null
- */
- public function list_available_exts()
+ * Lists all the available extensions and dumps to the template
+ *
+ * @param \phpbb\extension\manager $phpbb_extension_manager An instance of the extension manager
+ * @param array $managed_packages List of managed packages
+ *
+ * @return null
+ */
+ public function list_available_exts(\phpbb\extension\manager $phpbb_extension_manager, array $managed_packages)
{
$uninstalled = array_diff_key($this->ext_manager->all_available(), $this->ext_manager->all_configured());
@@ -617,6 +1019,7 @@ class acp_extensions
$available_extension_meta_data[$name] = array(
'META_DISPLAY_NAME' => $md_manager->get_metadata('display-name'),
'META_VERSION' => $meta['version'],
+ 'META_NAME' => $md_manager->get_metadata('name'),
);
if (isset($meta['extra']['version-check']))
diff --git a/phpBB/includes/acp/acp_main.php b/phpBB/includes/acp/acp_main.php
index d2b44d553f..3f253b94a7 100644
--- a/phpBB/includes/acp/acp_main.php
+++ b/phpBB/includes/acp/acp_main.php
@@ -503,26 +503,8 @@ class acp_main
$upload_dir_size = get_formatted_filesize($config['upload_dir_size']);
- $avatar_dir_size = 0;
-
- if ($avatar_dir = @opendir($phpbb_root_path . $config['avatar_path']))
- {
- while (($file = readdir($avatar_dir)) !== false)
- {
- if ($file[0] != '.' && $file != 'CVS' && strpos($file, 'index.') === false)
- {
- $avatar_dir_size += filesize($phpbb_root_path . $config['avatar_path'] . '/' . $file);
- }
- }
- closedir($avatar_dir);
-
- $avatar_dir_size = get_formatted_filesize($avatar_dir_size);
- }
- else
- {
- // Couldn't open Avatar dir.
- $avatar_dir_size = $user->lang['NOT_AVAILABLE'];
- }
+ $storage_avatar = $phpbb_container->get('storage.avatar');
+ $avatar_dir_size = get_formatted_filesize($storage_avatar->get_size());
if ($posts_per_day > $total_posts)
{
@@ -658,7 +640,7 @@ class acp_main
}
// Warn if install is still present
- if (!defined('IN_INSTALL') && !$phpbb_container->getParameter('allow_install_dir') && file_exists($phpbb_root_path . 'install') && !is_file($phpbb_root_path . 'install'))
+ if (!$phpbb_container->getParameter('allow_install_dir') && file_exists($phpbb_root_path . 'install') && !is_file($phpbb_root_path . 'install'))
{
$template->assign_var('S_REMOVE_INSTALL', true);
}
diff --git a/phpBB/includes/acp/acp_storage.php b/phpBB/includes/acp/acp_storage.php
new file mode 100644
index 0000000000..12a4b45d67
--- /dev/null
+++ b/phpBB/includes/acp/acp_storage.php
@@ -0,0 +1,339 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+/**
+* @ignore
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+class acp_storage
+{
+ /** @var \phpbb\config $config */
+ protected $config;
+
+ /** @var \phpbb\language\language $lang */
+ protected $lang;
+
+ /** @var \phpbb\request\request */
+ protected $request;
+
+ /** @var \phpbb\template\template */
+ protected $template;
+
+ /** @var \phpbb\user */
+ protected $user;
+
+ /** @var \phpbb\di\service_collection */
+ protected $provider_collection;
+
+ /** @var \phpbb\di\service_collection */
+ protected $storage_collection;
+
+ /** @var string */
+ public $page_title;
+
+ /** @var string */
+ public $tpl_name;
+
+ /** @var string */
+ public $u_action;
+
+ /**
+ * @param string $id
+ * @param string $mode
+ */
+ public function main($id, $mode)
+ {
+ global $phpbb_container, $phpbb_dispatcher;
+
+ $this->config = $phpbb_container->get('config');
+ $this->lang = $phpbb_container->get('language');
+ $this->request = $phpbb_container->get('request');
+ $this->template = $phpbb_container->get('template');
+ $this->user = $phpbb_container->get('user');
+ $this->provider_collection = $phpbb_container->get('storage.provider_collection');
+ $this->storage_collection = $phpbb_container->get('storage.storage_collection');
+
+ // Add necesary language files
+ $this->lang->add_lang(['acp/storage']);
+
+ /**
+ * Add language strings
+ *
+ * @event core.acp_storage_load
+ * @since 3.3.0-a1
+ */
+ $phpbb_dispatcher->dispatch('core.acp_storage_load');
+
+ $this->overview($id, $mode);
+ }
+
+ /**
+ * @param string $id
+ * @param string $mode
+ */
+ public function overview($id, $mode)
+ {
+ $form_key = 'acp_storage';
+ add_form_key($form_key);
+
+ // Template from adm/style
+ $this->tpl_name = 'acp_storage';
+
+ // Set page title
+ $this->page_title = 'STORAGE_TITLE';
+
+ if ($this->request->is_set_post('submit'))
+ {
+ $modified_storages = [];
+ $messages = [];
+
+ if (!check_form_key($form_key))
+ {
+ $messages[] = $this->lang->lang('FORM_INVALID');
+ }
+
+ foreach ($this->storage_collection as $storage)
+ {
+ $storage_name = $storage->get_name();
+
+ $options = $this->get_provider_options($this->get_current_provider($storage_name));
+
+ $modified = false;
+
+ // Check if provider have been modified
+ if ($this->get_new_provider($storage_name) != $this->get_current_provider($storage_name))
+ {
+ $modified = true;
+ }
+
+ // Check if options have been modified
+ if (!$modified)
+ {
+ foreach (array_keys($options) as $definition)
+ {
+ if ($this->get_new_definition($storage_name, $definition) != $this->get_current_definition($storage_name, $definition))
+ {
+ $modified = true;
+ break;
+ }
+ }
+ }
+
+ // If the storage have been modified, validate options
+ if ($modified)
+ {
+ $modified_storages[] = $storage_name;
+ $this->validate_data($storage_name, $messages);
+ }
+ }
+
+ if (!empty($modified_storages))
+ {
+ if (empty($messages))
+ {
+ foreach ($modified_storages as $storage_name)
+ {
+ $this->update_storage_config($storage_name);
+ }
+
+ trigger_error($this->lang->lang('STORAGE_UPDATE_SUCCESSFUL') . adm_back_link($this->u_action), E_USER_NOTICE);
+ }
+ else
+ {
+ trigger_error(implode('<br />', $messages) . adm_back_link($this->u_action), E_USER_WARNING);
+ }
+ }
+
+ // If there is no changes
+ trigger_error($this->lang->lang('STORAGE_NO_CHANGES') . adm_back_link($this->u_action), E_USER_WARNING);
+ }
+
+ $storage_stats = [];
+ foreach ($this->storage_collection as $storage)
+ {
+ try
+ {
+ $free_space = get_formatted_filesize($storage->free_space());
+ }
+ catch (\phpbb\storage\exception\exception $e)
+ {
+ $free_space = $this->lang->lang('STORAGE_UNKNOWN');
+ }
+
+ $storage_stats[] = [
+ 'name' => $this->lang->lang('STORAGE_' . strtoupper($storage->get_name()) . '_TITLE'),
+ 'files' => $storage->get_num_files(),
+ 'size' => get_formatted_filesize($storage->get_size()),
+ 'free_space' => $free_space,
+ ];
+ }
+
+ $this->template->assign_vars(array(
+ 'STORAGES' => $this->storage_collection,
+ 'STORAGE_STATS' => $storage_stats,
+ 'PROVIDERS' => $this->provider_collection,
+ ));
+ }
+
+ /**
+ * Get the current provider from config
+ *
+ * @param string $storage_name Storage name
+ * @return string The current provider
+ */
+ protected function get_current_provider($storage_name)
+ {
+ return $this->config['storage\\' . $storage_name . '\\provider'];
+ }
+
+ /**
+ * Get the new provider from the request
+ *
+ * @param string $storage_name Storage name
+ * @return string The new provider
+ */
+ protected function get_new_provider($storage_name)
+ {
+ return $this->request->variable([$storage_name, 'provider'], '');
+ }
+
+ /**
+ * Get adapter definitions from a provider
+ *
+ * @param string $provider Provider class
+ * @return array Adapter definitions
+ */
+ protected function get_provider_options($provider)
+ {
+ return $this->provider_collection->get_by_class($provider)->get_options();
+ }
+
+ /**
+ * Get the current value of the definition of a storage from config
+ *
+ * @param string $storage_name Storage name
+ * @param string $definition Definition
+ * @return string Definition value
+ */
+ protected function get_current_definition($storage_name, $definition)
+ {
+ return $this->config['storage\\' . $storage_name . '\\config\\' . $definition];
+ }
+
+ /**
+ * Get the new value of the definition of a storage from the request
+ *
+ * @param string $storage_name Storage name
+ * @param string $definition Definition
+ * @return string Definition value
+ */
+ protected function get_new_definition($storage_name, $definition)
+ {
+ return $this->request->variable([$storage_name, $definition], '');
+ }
+
+ /**
+ * Validates data
+ *
+ * @param string $storage_name Storage name
+ * @param array $messages Reference to messages array
+ */
+ protected function validate_data($storage_name, &$messages)
+ {
+ $storage_title = $this->lang->lang('STORAGE_' . strtoupper($storage_name) . '_TITLE');
+
+ // Check if provider exists
+ try
+ {
+ $new_provider = $this->provider_collection->get_by_class($this->get_new_provider($storage_name));
+ }
+ catch (\Exception $e)
+ {
+ $messages[] = $this->lang->lang('STORAGE_PROVIDER_NOT_EXISTS', $storage_title);
+ return;
+ }
+
+ // Check if provider is available
+ if (!$new_provider->is_available())
+ {
+ $messages[] = $this->lang->lang('STORAGE_PROVIDER_NOT_AVAILABLE', $storage_title);
+ return;
+ }
+
+ // Check options
+ $new_options = $this->get_provider_options($this->get_new_provider($storage_name));
+
+ foreach ($new_options as $definition_key => $definition_value)
+ {
+ $provider = $this->provider_collection->get_by_class($this->get_new_provider($storage_name));
+ $definition_title = $this->lang->lang('STORAGE_ADAPTER_' . strtoupper($provider->get_name()) . '_OPTION_' . strtoupper($definition_key));
+
+ $value = $this->get_new_definition($storage_name, $definition_key);
+
+ switch ($definition_value['type'])
+ {
+ case 'email':
+ if (!filter_var($value, FILTER_VALIDATE_EMAIL))
+ {
+ $messages[] = $this->lang->lang('STORAGE_FORM_TYPE_EMAIL_INCORRECT_FORMAT', $definition_title, $storage_title);
+ }
+ case 'text':
+ case 'password':
+ $maxlength = isset($definition_value['maxlength']) ? $definition_value['maxlength'] : 255;
+ if (strlen($value) > $maxlength)
+ {
+ $messages[] = $this->lang->lang('STORAGE_FORM_TYPE_TEXT_TOO_LONG', $definition_title, $storage_title);
+ }
+ break;
+ case 'radio':
+ case 'select':
+ if (!in_array($value, array_values($definition_value['options'])))
+ {
+ $messages[] = $this->lang->lang('STORAGE_FORM_TYPE_SELECT_NOT_AVAILABLE', $definition_title, $storage_title);
+ }
+ break;
+ }
+ }
+ }
+
+ /**
+ * Updates an storage with the info provided in the form
+ *
+ * @param string $storage_name Storage name
+ */
+ protected function update_storage_config($storage_name)
+ {
+ $current_options = $this->get_provider_options($this->get_current_provider($storage_name));
+
+ // Remove old storage config
+ foreach (array_keys($current_options) as $definition)
+ {
+ $this->config->delete('storage\\' . $storage_name . '\\config\\' . $definition);
+ }
+
+ // Update provider
+ $this->config->set('storage\\' . $storage_name . '\\provider', $this->get_new_provider($storage_name));
+
+ // Set new storage config
+ $new_options = $this->get_provider_options($this->get_new_provider($storage_name));
+
+ foreach (array_keys($new_options) as $definition)
+ {
+ $this->config->set('storage\\' . $storage_name . '\\config\\' . $definition, $this->get_new_definition($storage_name, $definition));
+ }
+ }
+}
diff --git a/phpBB/includes/acp/info/acp_extensions.php b/phpBB/includes/acp/info/acp_extensions.php
index 9adcd543b9..f555d0fa8c 100644
--- a/phpBB/includes/acp/info/acp_extensions.php
+++ b/phpBB/includes/acp/info/acp_extensions.php
@@ -20,6 +20,7 @@ class acp_extensions_info
'title' => 'ACP_EXTENSION_MANAGEMENT',
'modes' => array(
'main' => array('title' => 'ACP_EXTENSIONS', 'auth' => 'acl_a_extensions', 'cat' => array('ACP_EXTENSION_MANAGEMENT')),
+ 'catalog' => array('title' => 'ACP_EXTENSIONS_CATALOG', 'auth' => 'acl_a_extensions', 'cat' => array('ACP_EXTENSION_MANAGEMENT')),
),
);
}
diff --git a/phpBB/includes/acp/info/acp_storage.php b/phpBB/includes/acp/info/acp_storage.php
new file mode 100644
index 0000000000..facec03c66
--- /dev/null
+++ b/phpBB/includes/acp/info/acp_storage.php
@@ -0,0 +1,34 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+class acp_storage_info
+{
+ function module()
+ {
+ return array(
+ 'filename' => 'acp_storage',
+ 'title' => 'ACP_STORAGE_SETTINGS',
+ 'modes' => array(
+ 'settings' => array('title' => 'ACP_STORAGE_SETTINGS', 'auth' => 'acl_a_storage', 'cat' => array('ACP_SERVER_CONFIGURATION')),
+ ),
+ );
+ }
+
+ function install()
+ {
+ }
+
+ function uninstall()
+ {
+ }
+}
diff --git a/phpBB/includes/bbcode.php b/phpBB/includes/bbcode.php
index 21c630d495..54442fb8bc 100644
--- a/phpBB/includes/bbcode.php
+++ b/phpBB/includes/bbcode.php
@@ -165,9 +165,7 @@ class bbcode
$phpbb_container->get('path_helper'),
$phpbb_container->getParameter('core.cache_dir'),
$phpbb_container->get('ext.manager'),
- new \phpbb\template\twig\loader(
- $phpbb_filesystem
- )
+ new \phpbb\template\twig\loader()
),
$phpbb_container->getParameter('core.cache_dir'),
$phpbb_container->get('user'),
diff --git a/phpBB/includes/constants.php b/phpBB/includes/constants.php
index 9508ce5cfc..9bf17dd817 100644
--- a/phpBB/includes/constants.php
+++ b/phpBB/includes/constants.php
@@ -28,7 +28,7 @@ if (!defined('IN_PHPBB'))
*/
// phpBB Version
-@define('PHPBB_VERSION', '3.3.0');
+@define('PHPBB_VERSION', '4.0.0-a1-dev');
// QA-related
// define('PHPBB_QA', 1);
@@ -157,11 +157,6 @@ define('FULL_FOLDER_NONE', -3);
define('FULL_FOLDER_DELETE', -2);
define('FULL_FOLDER_HOLD', -1);
-// Download Modes - Attachments
-define('INLINE_LINK', 1);
-// This mode is only used internally to allow modders extending the attachment functionality
-define('PHYSICAL_LINK', 2);
-
// Confirm types
define('CONFIRM_REG', 1);
define('CONFIRM_LOGIN', 2);
@@ -243,6 +238,7 @@ define('ACL_ROLES_DATA_TABLE', $table_prefix . 'acl_roles_data');
define('ACL_ROLES_TABLE', $table_prefix . 'acl_roles');
define('ACL_USERS_TABLE', $table_prefix . 'acl_users');
define('ATTACHMENTS_TABLE', $table_prefix . 'attachments');
+define('BACKUPS_TABLE', $table_prefix . 'backups');
define('BANLIST_TABLE', $table_prefix . 'banlist');
define('BBCODES_TABLE', $table_prefix . 'bbcodes');
define('BOOKMARKS_TABLE', $table_prefix . 'bookmarks');
@@ -291,6 +287,7 @@ define('SESSIONS_KEYS_TABLE', $table_prefix . 'sessions_keys');
define('SITELIST_TABLE', $table_prefix . 'sitelist');
define('SMILIES_TABLE', $table_prefix . 'smilies');
define('SPHINX_TABLE', $table_prefix . 'sphinx');
+define('STORAGE_TABLE', $table_prefix . 'storage');
define('STYLES_TABLE', $table_prefix . 'styles');
define('STYLES_TEMPLATE_TABLE', $table_prefix . 'styles_template');
define('STYLES_TEMPLATE_DATA_TABLE',$table_prefix . 'styles_template_data');
diff --git a/phpBB/includes/functions.php b/phpBB/includes/functions.php
index 9759eabb5a..7bde4dbc02 100644
--- a/phpBB/includes/functions.php
+++ b/phpBB/includes/functions.php
@@ -1481,7 +1481,6 @@ function tracking_unserialize($string, $max_depth = 3)
/**
* Append session id to url.
-* This function supports hooks.
*
* @param string $url The url the session id needs to be appended to (can have params)
* @param mixed $params String or array of additional url parameters
@@ -1502,7 +1501,7 @@ function tracking_unserialize($string, $max_depth = 3)
*/
function append_sid($url, $params = false, $is_amp = true, $session_id = false, $is_route = false)
{
- global $_SID, $_EXTRA_URL, $phpbb_hook, $phpbb_path_helper;
+ global $_SID, $_EXTRA_URL, $phpbb_path_helper;
global $phpbb_dispatcher;
if ($params === '' || (is_array($params) && empty($params)))
@@ -1549,18 +1548,6 @@ function append_sid($url, $params = false, $is_amp = true, $session_id = false,
return $append_sid_overwrite;
}
- // The following hook remains for backwards compatibility, though use of
- // the event above is preferred.
- // Developers using the hook function need to globalise the $_SID and $_EXTRA_URL on their own and also handle it appropriately.
- // They could mimic most of what is within this function
- if (!empty($phpbb_hook) && $phpbb_hook->call_hook(__FUNCTION__, $url, $params, $is_amp, $session_id))
- {
- if ($phpbb_hook->hook_return(__FUNCTION__))
- {
- return $phpbb_hook->hook_return_result(__FUNCTION__);
- }
- }
-
$params_is_array = is_array($params);
// Get anchor
@@ -3266,15 +3253,7 @@ function phpbb_filter_root_path($errfile)
if (empty($root_path))
{
- if ($phpbb_filesystem)
- {
- $root_path = $phpbb_filesystem->realpath(dirname(__FILE__) . '/../');
- }
- else
- {
- $filesystem = new \phpbb\filesystem\filesystem();
- $root_path = $filesystem->realpath(dirname(__FILE__) . '/../');
- }
+ $root_path = \phpbb\filesystem\helper::realpath(dirname(__FILE__) . '/../');
}
return str_replace(array($root_path, '\\'), array('[ROOT]', '/'), $errfile);
@@ -4112,23 +4091,14 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
$controller_helper = $phpbb_container->get('controller.helper');
$notification_mark_hash = generate_link_hash('mark_all_notifications_read');
+ $phpbb_version_parts = explode('.', PHPBB_VERSION, 3);
+ $phpbb_major = $phpbb_version_parts[0] . '.' . $phpbb_version_parts[1];
+
$s_login_redirect = build_hidden_fields(array('redirect' => $phpbb_path_helper->remove_web_root_path(build_url())));
// Add form token for login box, in case page is presenting a login form.
add_form_key('login', '_LOGIN');
- /**
- * Workaround for missing template variable in pre phpBB 3.2.6 styles.
- * @deprecated 3.2.7 (To be removed: 4.0.0-a1)
- */
- $form_token_login = $template->retrieve_var('S_FORM_TOKEN_LOGIN');
- if (!empty($form_token_login))
- {
- $s_login_redirect .= $form_token_login;
- // Remove S_FORM_TOKEN_LOGIN as it's already appended to S_LOGIN_REDIRECT
- $template->assign_var('S_FORM_TOKEN_LOGIN', '');
- }
-
// The following assigns all _common_ variables that may be used at any point in a template.
$template->assign_vars(array(
'SITENAME' => $config['sitename'],
@@ -4162,6 +4132,8 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
'SESSION_ID' => $user->session_id,
'ROOT_PATH' => $web_path,
'BOARD_URL' => $board_url,
+ 'PHPBB_VERSION' => PHPBB_VERSION,
+ 'PHPBB_MAJOR' => $phpbb_major,
'L_LOGIN_LOGOUT' => $l_login_logout,
'L_INDEX' => ($config['board_index_text'] !== '') ? $config['board_index_text'] : $user->lang['FORUM_INDEX'],
@@ -4238,11 +4210,9 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
'T_SUPER_TEMPLATE_PATH' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/template',
'T_IMAGES_PATH' => "{$web_path}images/",
'T_SMILIES_PATH' => "{$web_path}{$config['smilies_path']}/",
- 'T_AVATAR_PATH' => "{$web_path}{$config['avatar_path']}/",
'T_AVATAR_GALLERY_PATH' => "{$web_path}{$config['avatar_gallery_path']}/",
'T_ICONS_PATH' => "{$web_path}{$config['icons_path']}/",
'T_RANKS_PATH' => "{$web_path}{$config['ranks_path']}/",
- 'T_UPLOAD_PATH' => "{$web_path}{$config['upload_path']}/",
'T_STYLESHEET_LINK' => "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/stylesheet.css?assets_version=' . $config['assets_version'],
'T_STYLESHEET_LANG_LINK'=> "{$web_path}styles/" . rawurlencode($user->style['style_path']) . '/theme/' . $user->lang_name . '/stylesheet.css?assets_version=' . $config['assets_version'],
'T_FONT_AWESOME_LINK' => !empty($config['allow_cdn']) && !empty($config['load_font_awesome_url']) ? $config['load_font_awesome_url'] : "{$web_path}assets/css/font-awesome.min.css?assets_version=" . $config['assets_version'],
@@ -4256,11 +4226,9 @@ function page_header($page_title = '', $display_online_list = false, $item_id =
'T_SUPER_TEMPLATE_NAME' => rawurlencode((isset($user->style['style_parent_tree']) && $user->style['style_parent_tree']) ? $user->style['style_parent_tree'] : $user->style['style_path']),
'T_IMAGES' => 'images',
'T_SMILIES' => $config['smilies_path'],
- 'T_AVATAR' => $config['avatar_path'],
'T_AVATAR_GALLERY' => $config['avatar_gallery_path'],
'T_ICONS' => $config['icons_path'],
'T_RANKS' => $config['ranks_path'],
- 'T_UPLOAD' => $config['upload_path'],
'SITE_LOGO_IMG' => $user->img('site_logo'),
));
@@ -4536,20 +4504,33 @@ function garbage_collection()
/**
* Handler for exit calls in phpBB.
-* This function supports hooks.
*
* Note: This function is called after the template has been outputted.
+ *
+ * @return void
*/
function exit_handler()
{
- global $phpbb_hook;
+ global $phpbb_dispatcher;
- if (!empty($phpbb_hook) && $phpbb_hook->call_hook(__FUNCTION__))
+ $exit_handler_override = false;
+
+ /**
+ * This event can either supplement or override the exit_handler() function
+ *
+ * To override this function, the event must set $exit_handler_override to
+ * true to force it to exit directly after calling this event.
+ *
+ * @event core.exit_handler
+ * @var bool exit_handler_override Flag to signify exit is handled elsewhere
+ * @since 4.0.0-a1
+ */
+ $vars = ['exit_handler_override'];
+ extract($phpbb_dispatcher->trigger_event('core.exit_handler', compact($vars)));
+
+ if ($exit_handler_override)
{
- if ($phpbb_hook->hook_return(__FUNCTION__))
- {
- return $phpbb_hook->hook_return_result(__FUNCTION__);
- }
+ return;
}
// As a pre-caution... some setups display a blank page if the flush() is not there.
@@ -4559,25 +4540,6 @@ function exit_handler()
}
/**
-* Handler for init calls in phpBB. This function is called in \phpbb\user::setup();
-* This function supports hooks.
-*/
-function phpbb_user_session_handler()
-{
- global $phpbb_hook;
-
- if (!empty($phpbb_hook) && $phpbb_hook->call_hook(__FUNCTION__))
- {
- if ($phpbb_hook->hook_return(__FUNCTION__))
- {
- return $phpbb_hook->hook_return_result(__FUNCTION__);
- }
- }
-
- return;
-}
-
-/**
* Casts a numeric string $input to an appropriate numeric type (i.e. integer or float)
*
* @param string $input A numeric string.
diff --git a/phpBB/includes/functions_acp.php b/phpBB/includes/functions_acp.php
index 4926351461..a8b0df5476 100644
--- a/phpBB/includes/functions_acp.php
+++ b/phpBB/includes/functions_acp.php
@@ -66,6 +66,9 @@ function adm_page_header($page_title)
}
}
+ $phpbb_version_parts = explode('.', PHPBB_VERSION, 3);
+ $phpbb_major = $phpbb_version_parts[0] . '.' . $phpbb_version_parts[1];
+
$template->assign_vars(array(
'PAGE_TITLE' => $page_title,
'USERNAME' => $user->data['username'],
@@ -75,6 +78,8 @@ function adm_page_header($page_title)
'SESSION_ID' => $user->session_id,
'ROOT_PATH' => $phpbb_root_path,
'ADMIN_ROOT_PATH' => $phpbb_admin_path,
+ 'PHPBB_VERSION' => PHPBB_VERSION,
+ 'PHPBB_MAJOR' => $phpbb_major,
'U_LOGOUT' => append_sid("{$phpbb_root_path}ucp.$phpEx", 'mode=logout'),
'U_ADM_LOGOUT' => append_sid("{$phpbb_admin_path}index.$phpEx", 'action=admlogout'),
@@ -83,11 +88,9 @@ function adm_page_header($page_title)
'T_IMAGES_PATH' => "{$phpbb_root_path}images/",
'T_SMILIES_PATH' => "{$phpbb_root_path}{$config['smilies_path']}/",
- 'T_AVATAR_PATH' => "{$phpbb_root_path}{$config['avatar_path']}/",
'T_AVATAR_GALLERY_PATH' => "{$phpbb_root_path}{$config['avatar_gallery_path']}/",
'T_ICONS_PATH' => "{$phpbb_root_path}{$config['icons_path']}/",
'T_RANKS_PATH' => "{$phpbb_root_path}{$config['ranks_path']}/",
- 'T_UPLOAD_PATH' => "{$phpbb_root_path}{$config['upload_path']}/",
'T_FONT_AWESOME_LINK' => !empty($config['allow_cdn']) && !empty($config['load_font_awesome_url']) ? $config['load_font_awesome_url'] : "{$phpbb_root_path}assets/css/font-awesome.min.css?assets_version=" . $config['assets_version'],
'T_ASSETS_VERSION' => $config['assets_version'],
diff --git a/phpBB/includes/functions_compatibility.php b/phpBB/includes/functions_compatibility.php
index 92e24c055c..8d04787a04 100644
--- a/phpBB/includes/functions_compatibility.php
+++ b/phpBB/includes/functions_compatibility.php
@@ -87,7 +87,7 @@ function phpbb_check_hash($password, $hash)
/**
* Eliminates useless . and .. components from specified path.
*
-* Deprecated, use filesystem class instead
+* Deprecated, use storage helper class instead
*
* @param string $path Path to clean
* @return string Cleaned path
@@ -96,36 +96,7 @@ function phpbb_check_hash($password, $hash)
*/
function phpbb_clean_path($path)
{
- global $phpbb_path_helper, $phpbb_container;
-
- if (!$phpbb_path_helper && $phpbb_container)
- {
- /* @var $phpbb_path_helper \phpbb\path_helper */
- $phpbb_path_helper = $phpbb_container->get('path_helper');
- }
- else if (!$phpbb_path_helper)
- {
- global $phpbb_root_path, $phpEx;
-
- // The container is not yet loaded, use a new instance
- if (!class_exists('\phpbb\path_helper'))
- {
- require($phpbb_root_path . 'phpbb/path_helper.' . $phpEx);
- }
-
- $request = new phpbb\request\request();
- $phpbb_path_helper = new phpbb\path_helper(
- new phpbb\symfony_request(
- $request
- ),
- new phpbb\filesystem\filesystem(),
- $request,
- $phpbb_root_path,
- $phpEx
- );
- }
-
- return $phpbb_path_helper->clean_path($path);
+ return \phpbb\filesystem\helper::clean_path($path);
}
/**
@@ -463,25 +434,21 @@ function phpbb_is_writable($file)
* @param string $path Path to check absoluteness of
* @return boolean
*
- * @deprecated 3.2.0-dev use \phpbb\filesystem\filesystem::is_absolute_path() instead
+ * @deprecated 3.2.0-dev use \phpbb\filesystem\helper::is_absolute_path() instead
*/
function phpbb_is_absolute($path)
{
- global $phpbb_filesystem;
-
- return $phpbb_filesystem->is_absolute_path($path);
+ return \phpbb\filesystem\helper::is_absolute_path($path);
}
/**
* A wrapper for realpath
*
- * @deprecated 3.2.0-dev use \phpbb\filesystem\filesystem::realpath() instead
+ * @deprecated 3.2.0-dev use \phpbb\filesystem\helper::realpath() instead
*/
function phpbb_realpath($path)
{
- global $phpbb_filesystem;
-
- return $phpbb_filesystem->realpath($path);
+ return \phpbb\filesystem\helper::realpath($path);
}
/**
diff --git a/phpBB/includes/functions_content.php b/phpBB/includes/functions_content.php
index fd014c741e..6deb7eb8ad 100644
--- a/phpBB/includes/functions_content.php
+++ b/phpBB/includes/functions_content.php
@@ -1086,6 +1086,9 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a
global $template, $cache, $user, $phpbb_dispatcher;
global $extensions, $config, $phpbb_root_path, $phpEx;
+ global $phpbb_container;
+
+ $storage_attachment = $phpbb_container->get('storage.attachment');
//
$compiled_attachments = array();
@@ -1163,7 +1166,7 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a
// Some basics...
$attachment['extension'] = strtolower(trim($attachment['extension']));
- $filename = $phpbb_root_path . $config['upload_path'] . '/' . utf8_basename($attachment['physical_filename']);
+ $filename = utf8_basename($attachment['physical_filename']);
$upload_icon = '';
@@ -1219,16 +1222,15 @@ function parse_attachments($forum_id, &$message, &$attachments, &$update_count_a
{
if ($config['img_link_width'] || $config['img_link_height'])
{
- $dimension = @getimagesize($filename);
-
- // If the dimensions could not be determined or the image being 0x0 we display it as a link for safety purposes
- if ($dimension === false || empty($dimension[0]) || empty($dimension[1]))
+ try
{
- $display_cat = ATTACHMENT_CATEGORY_NONE;
+ $file_info = $storage_attachment->file_info($filename);
+
+ $display_cat = ($file_info->image_width <= $config['img_link_width'] && $file_info->image_height <= $config['img_link_height']) ? ATTACHMENT_CATEGORY_IMAGE : ATTACHMENT_CATEGORY_NONE;
}
- else
+ catch (\Exception $e)
{
- $display_cat = ($dimension[0] <= $config['img_link_width'] && $dimension[1] <= $config['img_link_height']) ? ATTACHMENT_CATEGORY_IMAGE : ATTACHMENT_CATEGORY_NONE;
+ $display_cat = ATTACHMENT_CATEGORY_NONE;
}
}
}
diff --git a/phpBB/includes/functions_convert.php b/phpBB/includes/functions_convert.php
index 96e108792d..e2e668c9cd 100644
--- a/phpBB/includes/functions_convert.php
+++ b/phpBB/includes/functions_convert.php
@@ -486,7 +486,7 @@ function import_attachment_files($category_name = '')
$sql = 'SELECT config_value AS upload_path
FROM ' . CONFIG_TABLE . "
- WHERE config_name = 'upload_path'";
+ WHERE config_name = 'storage\\attachment\\config\\path'";
$result = $db->sql_query($sql);
$config['upload_path'] = $db->sql_fetchfield('upload_path');
$db->sql_freeresult($result);
diff --git a/phpBB/includes/functions_download.php b/phpBB/includes/functions_download.php
index d2d3924dd8..df252f5c84 100644
--- a/phpBB/includes/functions_download.php
+++ b/phpBB/includes/functions_download.php
@@ -25,30 +25,27 @@ if (!defined('IN_PHPBB'))
*/
function send_avatar_to_browser($file, $browser)
{
- global $config, $phpbb_root_path;
+ global $config, $phpbb_container;
+
+ $storage = $phpbb_container->get('storage.avatar');
$prefix = $config['avatar_salt'] . '_';
- $image_dir = $config['avatar_path'];
+ $file_path = $prefix . $file;
- // Adjust image_dir path (no trailing slash)
- if (substr($image_dir, -1, 1) == '/' || substr($image_dir, -1, 1) == '\\')
+ if ($storage->exists($file_path) && !headers_sent())
{
- $image_dir = substr($image_dir, 0, -1) . '/';
- }
- $image_dir = str_replace(array('../', '..\\', './', '.\\'), '', $image_dir);
+ $file_info = $storage->file_info($file_path);
- if ($image_dir && ($image_dir[0] == '/' || $image_dir[0] == '\\'))
- {
- $image_dir = '';
- }
- $file_path = $phpbb_root_path . $image_dir . '/' . $prefix . $file;
-
- if ((@file_exists($file_path) && @is_readable($file_path)) && !headers_sent())
- {
header('Cache-Control: public');
- $image_data = @getimagesize($file_path);
- header('Content-Type: ' . image_type_to_mime_type($image_data[2]));
+ try
+ {
+ header('Content-Type: ' . $file_info->mimetype);
+ }
+ catch (\phpbb\storage\exception\exception $e)
+ {
+ // Just don't send this header
+ }
if ((strpos(strtolower($browser), 'msie') !== false) && !phpbb_is_greater_ie_version($browser, 7))
{
@@ -69,24 +66,26 @@ function send_avatar_to_browser($file, $browser)
header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 31536000) . ' GMT');
}
- $size = @filesize($file_path);
- if ($size)
+ try
{
- header("Content-Length: $size");
+ header('Content-Length: ' . $file_info->size);
}
-
- if (@readfile($file_path) == false)
+ catch (\phpbb\storage\exception\exception $e)
{
- $fp = @fopen($file_path, 'rb');
+ // Just don't send this header
+ }
- if ($fp !== false)
- {
- while (!feof($fp))
- {
- echo fread($fp, 8192);
- }
- fclose($fp);
- }
+ try
+ {
+ $fp = $storage->read_stream($file_path);
+ $output = fopen('php://output', 'w+b');
+ stream_copy_to_stream($fp, $output);
+ fclose($fp);
+ fclose($output);
+ }
+ catch (\Exception $e)
+ {
+ // Send nothing
}
flush();
@@ -122,13 +121,15 @@ function wrap_img_in_html($src, $title)
/**
* Send file to browser
*/
-function send_file_to_browser($attachment, $upload_dir, $category)
+function send_file_to_browser($attachment, $category)
{
- global $user, $db, $phpbb_dispatcher, $phpbb_root_path, $request;
+ global $user, $db, $phpbb_dispatcher, $request, $phpbb_container;
+
+ $storage = $phpbb_container->get('storage.attachment');
- $filename = $phpbb_root_path . $upload_dir . '/' . $attachment['physical_filename'];
+ $filename = $attachment['physical_filename'];
- if (!@file_exists($filename))
+ if (!$storage->exists($filename))
{
send_status_line(404, 'Not Found');
trigger_error('ERROR_NO_ATTACHMENT');
@@ -147,14 +148,21 @@ function send_file_to_browser($attachment, $upload_dir, $category)
}
// Now send the File Contents to the Browser
- $size = @filesize($filename);
+ try
+ {
+ $file_info = $storage->file_info($filename);
+ $size = $file_info->size;
+ }
+ catch (\Exception $e)
+ {
+ $size = 0;
+ }
/**
* Event to alter attachment before it is sent to browser.
*
* @event core.send_file_to_browser_before
* @var array attachment Attachment data
- * @var string upload_dir Relative path of upload directory
* @var int category Attachment category
* @var string filename Path to file, including filename
* @var int size File size
@@ -162,7 +170,6 @@ function send_file_to_browser($attachment, $upload_dir, $category)
*/
$vars = array(
'attachment',
- 'upload_dir',
'category',
'filename',
'size',
@@ -172,15 +179,8 @@ function send_file_to_browser($attachment, $upload_dir, $category)
// To correctly display further errors we need to make sure we are using the correct headers for both (unsetting content-length may not work)
// Check if headers already sent or not able to get the file contents.
- if (headers_sent() || !@file_exists($filename) || !@is_readable($filename))
+ if (headers_sent())
{
- // PHP track_errors setting On?
- if (!empty($php_errormsg))
- {
- send_status_line(500, 'Internal Server Error');
- trigger_error($user->lang['UNABLE_TO_DELIVER_FILE'] . '<br />' . sprintf($user->lang['TRACKED_PHP_ERROR'], $php_errormsg));
- }
-
send_status_line(500, 'Internal Server Error');
trigger_error('UNABLE_TO_DELIVER_FILE');
}
@@ -223,29 +223,8 @@ function send_file_to_browser($attachment, $upload_dir, $category)
}
}
- // Close the db connection before sending the file etc.
- file_gc(false);
-
if (!set_modified_headers($attachment['filetime'], $user->browser))
{
- // We make sure those have to be enabled manually by defining a constant
- // because of the potential disclosure of full attachment path
- // in case support for features is absent in the webserver software.
- if (defined('PHPBB_ENABLE_X_ACCEL_REDIRECT') && PHPBB_ENABLE_X_ACCEL_REDIRECT)
- {
- // X-Accel-Redirect - http://wiki.nginx.org/XSendfile
- header('X-Accel-Redirect: ' . $user->page['root_script_path'] . $upload_dir . '/' . $attachment['physical_filename']);
- exit;
- }
- else if (defined('PHPBB_ENABLE_X_SENDFILE') && PHPBB_ENABLE_X_SENDFILE && !phpbb_http_byte_range($size))
- {
- // X-Sendfile - http://blog.lighttpd.net/articles/2006/07/02/x-sendfile
- // Lighttpd's X-Sendfile does not support range requests as of 1.4.26
- // and always requires an absolute path.
- header('X-Sendfile: ' . dirname(__FILE__) . "/../$upload_dir/{$attachment['physical_filename']}");
- exit;
- }
-
if ($size)
{
header("Content-Length: $size");
@@ -254,40 +233,17 @@ function send_file_to_browser($attachment, $upload_dir, $category)
// Try to deliver in chunks
@set_time_limit(0);
- $fp = @fopen($filename, 'rb');
+ $fp = $storage->read_stream($filename);
+
+ // Close the db connection before sending the file etc.
+ file_gc(false);
if ($fp !== false)
{
- // Deliver file partially if requested
- if ($range = phpbb_http_byte_range($size))
- {
- fseek($fp, $range['byte_pos_start']);
-
- send_status_line(206, 'Partial Content');
- header('Content-Range: bytes ' . $range['byte_pos_start'] . '-' . $range['byte_pos_end'] . '/' . $range['bytes_total']);
- header('Content-Length: ' . $range['bytes_requested']);
-
- // First read chunks
- while (!feof($fp) && ftell($fp) < $range['byte_pos_end'] - 8192)
- {
- echo fread($fp, 8192);
- }
- // Then, read the remainder
- echo fread($fp, $range['bytes_requested'] % 8192);
- }
- else
- {
- while (!feof($fp))
- {
- echo fread($fp, 8192);
- }
- }
+ $output = fopen('php://output', 'w+b');
+ stream_copy_to_stream($fp, $output);
fclose($fp);
}
- else
- {
- @readfile($filename);
- }
flush();
}
diff --git a/phpBB/includes/functions_messenger.php b/phpBB/includes/functions_messenger.php
index ec297b536a..3e7a1c5253 100644
--- a/phpBB/includes/functions_messenger.php
+++ b/phpBB/includes/functions_messenger.php
@@ -742,9 +742,7 @@ class messenger
$phpbb_container->get('path_helper'),
$phpbb_container->getParameter('core.template.cache_path'),
$phpbb_container->get('ext.manager'),
- new \phpbb\template\twig\loader(
- $phpbb_container->get('filesystem')
- ),
+ new \phpbb\template\twig\loader(),
$phpbb_dispatcher,
array()
);
diff --git a/phpBB/includes/functions_posting.php b/phpBB/includes/functions_posting.php
index 45eda4ba17..034cbd1c51 100644
--- a/phpBB/includes/functions_posting.php
+++ b/phpBB/includes/functions_posting.php
@@ -1505,6 +1505,8 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll_ary, &$data
{
global $db, $auth, $user, $config, $phpEx, $phpbb_root_path, $phpbb_container, $phpbb_dispatcher, $phpbb_log, $request;
+ $attachment_storage = $phpbb_container->get('storage.attachment');
+
$poll = $poll_ary;
$data = $data_ary;
/**
@@ -2098,7 +2100,7 @@ function submit_post($mode, $subject, $username, $topic_type, &$poll_ary, &$data
else
{
// insert attachment into db
- if (!@file_exists($phpbb_root_path . $config['upload_path'] . '/' . utf8_basename($orphan_rows[$attach_row['attach_id']]['physical_filename'])))
+ if (!$attachment_storage->exists(utf8_basename($orphan_rows[$attach_row['attach_id']]['physical_filename'])))
{
continue;
}
diff --git a/phpBB/includes/functions_privmsgs.php b/phpBB/includes/functions_privmsgs.php
index 436b437cfa..43f8c8489c 100644
--- a/phpBB/includes/functions_privmsgs.php
+++ b/phpBB/includes/functions_privmsgs.php
@@ -1619,6 +1619,8 @@ function submit_pm($mode, $subject, &$data_ary, $put_in_outbox = true)
{
global $db, $auth, $config, $user, $phpbb_root_path, $phpbb_container, $phpbb_dispatcher, $request;
+ $attachment_storage = $phpbb_container->get('storage.attachment');
+
// We do not handle erasing pms here
if ($mode == 'delete')
{
@@ -1886,7 +1888,7 @@ function submit_pm($mode, $subject, &$data_ary, $put_in_outbox = true)
else
{
// insert attachment into db
- if (!@file_exists($phpbb_root_path . $config['upload_path'] . '/' . utf8_basename($orphan_rows[$attach_row['attach_id']]['physical_filename'])))
+ if (!$attachment_storage->exists(utf8_basename($orphan_rows[$attach_row['attach_id']]['physical_filename'])))
{
continue;
}
diff --git a/phpBB/includes/functions_user.php b/phpBB/includes/functions_user.php
index dc6e09268a..cb8e1c64bb 100644
--- a/phpBB/includes/functions_user.php
+++ b/phpBB/includes/functions_user.php
@@ -2215,7 +2215,9 @@ function phpbb_style_is_active($style_id)
*/
function avatar_delete($mode, $row, $clean_db = false)
{
- global $phpbb_root_path, $config;
+ global $config, $phpbb_container;
+
+ $storage = $phpbb_container->get('storage.avatar');
// Check if the users avatar is actually *not* a group avatar
if ($mode == 'user')
@@ -2232,11 +2234,16 @@ function avatar_delete($mode, $row, $clean_db = false)
}
$filename = get_avatar_filename($row[$mode . '_avatar']);
- if (file_exists($phpbb_root_path . $config['avatar_path'] . '/' . $filename))
+ try
{
- @unlink($phpbb_root_path . $config['avatar_path'] . '/' . $filename);
+ $storage->delete($filename);
+
return true;
}
+ catch (\phpbb\storage\exception\exception $e)
+ {
+ // Fail is covered by return statement below
+ }
return false;
}
@@ -2556,7 +2563,9 @@ function group_create(&$group_id, $type, $name, $desc, $group_attributes, $allow
*/
function group_correct_avatar($group_id, $old_entry)
{
- global $config, $db, $phpbb_root_path;
+ global $config, $db, $phpbb_container;
+
+ $storage = $phpbb_container->get('storage.avatar');
$group_id = (int) $group_id;
$ext = substr(strrchr($old_entry, '.'), 1);
@@ -2564,14 +2573,19 @@ function group_correct_avatar($group_id, $old_entry)
$new_filename = $config['avatar_salt'] . "_g$group_id.$ext";
$new_entry = 'g' . $group_id . '_' . substr(time(), -5) . ".$ext";
- $avatar_path = $phpbb_root_path . $config['avatar_path'];
- if (@rename($avatar_path . '/'. $old_filename, $avatar_path . '/' . $new_filename))
+ try
{
+ $this->storage->rename($old_filename, $new_filename);
+
$sql = 'UPDATE ' . GROUPS_TABLE . '
SET group_avatar = \'' . $db->sql_escape($new_entry) . "'
WHERE group_id = $group_id";
$db->sql_query($sql);
}
+ catch (\phpbb\storage\exception\exception $e)
+ {
+ // If rename fail, dont execute the query
+ }
}
diff --git a/phpBB/includes/hooks/index.php b/phpBB/includes/hooks/index.php
deleted file mode 100644
index 821242cbf4..0000000000
--- a/phpBB/includes/hooks/index.php
+++ /dev/null
@@ -1,250 +0,0 @@
-<?php
-/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
-
-/**
-* @ignore
-*/
-if (!defined('IN_PHPBB'))
-{
- exit;
-}
-
-/**
-* phpBB Hook Class
-*/
-class phpbb_hook
-{
- /**
- * Registered hooks
- */
- var $hooks = array();
-
- /**
- * Results returned by functions called
- */
- var $hook_result = array();
-
- /**
- * internal pointer
- */
- var $current_hook = NULL;
-
- /**
- * Initialize hook class.
- *
- * @param array $valid_hooks array containing the hookable functions/methods
- */
- function __construct($valid_hooks)
- {
- foreach ($valid_hooks as $_null => $method)
- {
- $this->add_hook($method);
- }
-
- if (function_exists('phpbb_hook_register'))
- {
- phpbb_hook_register($this);
- }
- }
-
- /**
- * Register function/method to be called within hook
- * This function is normally called by the modification/application to attach/register the functions.
- *
- * @param mixed $definition Declaring function (with __FUNCTION__) or class with array(__CLASS__, __FUNCTION__)
- * @param mixed $hook The replacement function/method to be called. Passing function name or array with object/class definition
- * @param string $mode Specify the priority/chain mode. 'normal' -> hook gets appended to the chain. 'standalone' -> only the specified hook gets called - later hooks are not able to overwrite this (E_NOTICE is triggered then). 'first' -> hook is called as the first one within the chain. 'last' -> hook is called as the last one within the chain.
- */
- function register($definition, $hook, $mode = 'normal')
- {
- $class = (!is_array($definition)) ? '__global' : $definition[0];
- $function = (!is_array($definition)) ? $definition : $definition[1];
-
- // Method able to be hooked?
- if (isset($this->hooks[$class][$function]))
- {
- switch ($mode)
- {
- case 'standalone':
- if (!isset($this->hooks[$class][$function]['standalone']))
- {
- $this->hooks[$class][$function] = array('standalone' => $hook);
- }
- else
- {
- trigger_error('Hook not able to be called standalone, previous hook already standalone.', E_NOTICE);
- }
- break;
-
- case 'first':
- case 'last':
- $this->hooks[$class][$function][$mode][] = $hook;
- break;
-
- case 'normal':
- default:
- $this->hooks[$class][$function]['normal'][] = $hook;
- break;
- }
- }
- }
-
- /**
- * Calling all functions/methods attached to a specified hook.
- * Called by the function allowing hooks...
- *
- * @param mixed $definition Declaring function (with __FUNCTION__) or class with array(__CLASS__, __FUNCTION__)
- * @return bool False if no hook got executed, true otherwise
- */
- function call_hook($definition)
- {
- $class = (!is_array($definition)) ? '__global' : $definition[0];
- $function = (!is_array($definition)) ? $definition : $definition[1];
-
- if (!empty($this->hooks[$class][$function]))
- {
- // Developer tries to call a hooked function within the hooked function...
- if ($this->current_hook !== NULL && $this->current_hook['class'] === $class && $this->current_hook['function'] === $function)
- {
- return false;
- }
-
- // Call the hook with the arguments attached and store result
- $arguments = func_get_args();
- $this->current_hook = array('class' => $class, 'function' => $function);
- $arguments[0] = &$this;
-
- // Call the hook chain...
- if (isset($this->hooks[$class][$function]['standalone']))
- {
- $this->hook_result[$class][$function] = call_user_func_array($this->hooks[$class][$function]['standalone'], $arguments);
- }
- else
- {
- foreach (array('first', 'normal', 'last') as $mode)
- {
- if (!isset($this->hooks[$class][$function][$mode]))
- {
- continue;
- }
-
- foreach ($this->hooks[$class][$function][$mode] as $hook)
- {
- $this->hook_result[$class][$function] = call_user_func_array($hook, $arguments);
- }
- }
- }
-
- $this->current_hook = NULL;
- return true;
- }
-
- $this->current_hook = NULL;
- return false;
- }
-
- /**
- * Get result from previously called functions/methods for the same hook
- *
- * @param mixed $definition Declaring function (with __FUNCTION__) or class with array(__CLASS__, __FUNCTION__)
- * @return mixed False if nothing returned if there is no result, else array('result' => ... )
- */
- function previous_hook_result($definition)
- {
- $class = (!is_array($definition)) ? '__global' : $definition[0];
- $function = (!is_array($definition)) ? $definition : $definition[1];
-
- if (!empty($this->hooks[$class][$function]) && isset($this->hook_result[$class][$function]))
- {
- return array('result' => $this->hook_result[$class][$function]);
- }
-
- return false;
- }
-
- /**
- * Check if the called functions/methods returned something.
- *
- * @param mixed $definition Declaring function (with __FUNCTION__) or class with array(__CLASS__, __FUNCTION__)
- * @return bool True if results are there, false if not
- */
- function hook_return($definition)
- {
- $class = (!is_array($definition)) ? '__global' : $definition[0];
- $function = (!is_array($definition)) ? $definition : $definition[1];
-
- if (!empty($this->hooks[$class][$function]) && isset($this->hook_result[$class][$function]))
- {
- return true;
- }
-
- return false;
- }
-
- /**
- * Give actual result from called functions/methods back.
- *
- * @param mixed $definition Declaring function (with __FUNCTION__) or class with array(__CLASS__, __FUNCTION__)
- * @return mixed The result
- */
- function hook_return_result($definition)
- {
- $class = (!is_array($definition)) ? '__global' : $definition[0];
- $function = (!is_array($definition)) ? $definition : $definition[1];
-
- if (!empty($this->hooks[$class][$function]) && isset($this->hook_result[$class][$function]))
- {
- $result = $this->hook_result[$class][$function];
- unset($this->hook_result[$class][$function]);
- return $result;
- }
-
- return;
- }
-
- /**
- * Add new function to the allowed hooks.
- *
- * @param mixed $definition Declaring function (with __FUNCTION__) or class with array(__CLASS__, __FUNCTION__)
- */
- function add_hook($definition)
- {
- if (!is_array($definition))
- {
- $definition = array('__global', $definition);
- }
-
- $this->hooks[$definition[0]][$definition[1]] = array();
- }
-
- /**
- * Remove function from the allowed hooks.
- *
- * @param mixed $definition Declaring function (with __FUNCTION__) or class with array(__CLASS__, __FUNCTION__)
- */
- function remove_hook($definition)
- {
- $class = (!is_array($definition)) ? '__global' : $definition[0];
- $function = (!is_array($definition)) ? $definition : $definition[1];
-
- if (isset($this->hooks[$class][$function]))
- {
- unset($this->hooks[$class][$function]);
-
- if (isset($this->hook_result[$class][$function]))
- {
- unset($this->hook_result[$class][$function]);
- }
- }
- }
-}
diff --git a/phpBB/includes/ucp/ucp_groups.php b/phpBB/includes/ucp/ucp_groups.php
index 6eba3a03a9..6c8e3b156c 100644
--- a/phpBB/includes/ucp/ucp_groups.php
+++ b/phpBB/includes/ucp/ucp_groups.php
@@ -440,8 +440,8 @@ class ucp_groups
'GROUP_DESC_DISP' => generate_text_for_display($group_row['group_desc'], $group_row['group_desc_uid'], $group_row['group_desc_bitfield'], $group_row['group_desc_options']),
'GROUP_TYPE' => $group_row['group_type'],
- 'AVATAR' => (empty($avatar) ? '<img src="' . $phpbb_admin_path . 'images/no_avatar.gif" alt="" />' : $avatar),
- 'AVATAR_IMAGE' => (empty($avatar) ? '<img src="' . $phpbb_admin_path . 'images/no_avatar.gif" alt="" />' : $avatar),
+ 'AVATAR' => (empty($avatar) ? '<img class="avatar" src="' . $phpbb_admin_path . 'images/no_avatar.gif" alt="" />' : $avatar),
+ 'AVATAR_IMAGE' => (empty($avatar) ? '<img class="avatar" src="' . $phpbb_admin_path . 'images/no_avatar.gif" alt="" />' : $avatar),
'AVATAR_WIDTH' => (isset($group_row['group_avatar_width'])) ? $group_row['group_avatar_width'] : '',
'AVATAR_HEIGHT' => (isset($group_row['group_avatar_height'])) ? $group_row['group_avatar_height'] : '',
));
diff --git a/phpBB/install/convert/convertor.php b/phpBB/install/convert/convertor.php
index 09088fe824..bf77215431 100644
--- a/phpBB/install/convert/convertor.php
+++ b/phpBB/install/convert/convertor.php
@@ -271,7 +271,7 @@ class convertor
$bad_folders = array();
$local_paths = array(
- 'avatar_path' => path($config['avatar_path']),
+ 'avatar_path' => path($config['storage\\avatar\\config\\path']),
'avatar_gallery_path' => path($config['avatar_gallery_path']),
'icons_path' => path($config['icons_path']),
'ranks_path' => path($config['ranks_path']),
diff --git a/phpBB/install/convertors/convert_phpbb20.php b/phpBB/install/convertors/convert_phpbb20.php
index 6da6e2eb22..d58ee6095a 100644
--- a/phpBB/install/convertors/convert_phpbb20.php
+++ b/phpBB/install/convertors/convert_phpbb20.php
@@ -38,7 +38,7 @@ $dbms = $phpbb_config_php_file->convert_30_dbms_to_31($dbms);
$convertor_data = array(
'forum_name' => 'phpBB 2.0.x',
'version' => '1.0.3',
- 'phpbb_version' => '3.3.0',
+ 'phpbb_version' => '4.0.0-a1-dev',
'author' => '<a href="https://www.phpbb.com/">phpBB Limited</a>',
'dbms' => $dbms,
'dbhost' => $dbhost,
@@ -439,7 +439,6 @@ if (!$get_info)
array('group_name', 'extension_groups.group_name', array('function1' => 'phpbb_set_encoding', 'function2' => 'utf8_htmlspecialchars')),
array('cat_id', 'extension_groups.cat_id', 'phpbb_attachment_category'),
array('allow_group', 'extension_groups.allow_group', ''),
- array('download_mode', 1, ''),
array('upload_icon', '', ''),
array('max_filesize', 'extension_groups.max_filesize', ''),
array('allowed_forums', 'extension_groups.forum_permissions', 'phpbb_attachment_forum_perms'),
diff --git a/phpBB/install/phpbbcli.php b/phpBB/install/phpbbcli.php
index cf8cfd18a3..b76f844005 100755
--- a/phpBB/install/phpbbcli.php
+++ b/phpBB/install/phpbbcli.php
@@ -23,7 +23,7 @@ if (php_sapi_name() !== 'cli')
define('IN_PHPBB', true);
define('IN_INSTALL', true);
define('PHPBB_ENVIRONMENT', 'production');
-define('PHPBB_VERSION', '3.3.0');
+define('PHPBB_VERSION', '4.0.0-a1-dev');
$phpbb_root_path = __DIR__ . '/../';
$phpEx = substr(strrchr(__FILE__, '.'), 1);
diff --git a/phpBB/install/schemas/schema_data.sql b/phpBB/install/schemas/schema_data.sql
index 1cc17f29b5..655c379fca 100644
--- a/phpBB/install/schemas/schema_data.sql
+++ b/phpBB/install/schemas/schema_data.sql
@@ -55,7 +55,6 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_max_height'
INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_max_width', '90');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_min_height', '20');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_min_width', '20');
-INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_path', 'images/avatars/upload');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('avatar_salt', 'phpbb_avatar');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_contact', 'contact@yourdomain.tld');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('board_contact_name', '');
@@ -278,11 +277,25 @@ INSERT INTO phpbb_config (config_name, config_value) VALUES ('teampage_forums',
INSERT INTO phpbb_config (config_name, config_value) VALUES ('topics_per_page', '25');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('tpl_allow_php', '0');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_icons_path', 'images/upload_icons');
-INSERT INTO phpbb_config (config_name, config_value) VALUES ('upload_path', 'files');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('use_system_cron', '0');
-INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '3.3.0');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('version', '4.0.0-a1-dev');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_expire_days', '90');
INSERT INTO phpbb_config (config_name, config_value) VALUES ('warnings_gc', '14400');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_repositories', '[]');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_packagist', '1');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_json_file', 'composer-ext.json');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_vendor_dir', 'vendor-ext/');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_enable_on_install', '0');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('exts_composer_purge_on_remove', '1');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\attachment\provider', 'phpbb\storage\provider\local');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\attachment\config\path', 'files');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\attachment\config\subfolders', '0');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\avatar\provider', 'phpbb\storage\provider\local');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\avatar\config\path', 'images/avatars/upload');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\avatar\config\subfolders', '0');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\backup\provider', 'phpbb\storage\provider\local');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\backup\config\path', 'store');
+INSERT INTO phpbb_config (config_name, config_value) VALUES ('storage\backup\config\subfolders', '0');
INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('cache_last_gc', '0', 1);
INSERT INTO phpbb_config (config_name, config_value, is_dynamic) VALUES ('cron_lock', '0', 1);
@@ -402,6 +415,7 @@ INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_reasons', 1);
INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_roles', 1);
INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_search', 1);
INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_server', 1);
+INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_storage', 1);
INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_styles', 1);
INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_switchperm', 1);
INSERT INTO phpbb_acl_options (auth_option, is_global) VALUES ('a_uauth', 1);
@@ -722,11 +736,11 @@ INSERT INTO phpbb_reports_reasons (reason_title, reason_description, reason_orde
INSERT INTO phpbb_reports_reasons (reason_title, reason_description, reason_order) VALUES ('other', '{L_REPORT_OTHER}', 4);
# -- extension_groups
-INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('IMAGES', 1, 1, 1, '', 0, '');
-INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('ARCHIVES', 0, 1, 1, '', 0, '');
-INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('PLAIN_TEXT', 0, 0, 1, '', 0, '');
-INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('DOCUMENTS', 0, 0, 1, '', 0, '');
-INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, download_mode, upload_icon, max_filesize, allowed_forums) VALUES ('DOWNLOADABLE_FILES', 0, 0, 1, '', 0, '');
+INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, upload_icon, max_filesize, allowed_forums) VALUES ('IMAGES', 1, 1, '', 0, '');
+INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, upload_icon, max_filesize, allowed_forums) VALUES ('ARCHIVES', 0, 1, '', 0, '');
+INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, upload_icon, max_filesize, allowed_forums) VALUES ('PLAIN_TEXT', 0, 0, '', 0, '');
+INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, upload_icon, max_filesize, allowed_forums) VALUES ('DOCUMENTS', 0, 0, '', 0, '');
+INSERT INTO phpbb_extension_groups (group_name, cat_id, allow_group, upload_icon, max_filesize, allowed_forums) VALUES ('DOWNLOADABLE_FILES', 0, 0, '', 0, '');
# -- extensions
INSERT INTO phpbb_extensions (group_id, extension) VALUES (1, 'gif');
diff --git a/phpBB/language/en/acp/common.php b/phpBB/language/en/acp/common.php
index 5ac4b445dc..e59471cdb0 100644
--- a/phpBB/language/en/acp/common.php
+++ b/phpBB/language/en/acp/common.php
@@ -88,6 +88,11 @@ $lang = array_merge($lang, array(
'ACP_EXTENSION_GROUPS' => 'Manage attachment extension groups',
'ACP_EXTENSION_MANAGEMENT' => 'Extension management',
'ACP_EXTENSIONS' => 'Manage extensions',
+ 'ACP_EXTENSIONS_CATALOG' => 'Extensions catalog',
+ 'ACP_EXTENSIONS_INSTALL' => 'Install extensions',
+ 'ACP_EXTENSIONS_REMOVE' => 'Remove extensions',
+ 'ACP_EXTENSIONS_UPDATE' => 'Update extensions',
+ 'ACP_EXTENSIONS_MANAGE' => 'Manage extension automatically',
'ACP_FORUM_BASED_PERMISSIONS' => 'Forum based permissions',
'ACP_FORUM_LOGS' => 'Forum logs',
@@ -173,6 +178,9 @@ $lang = array_merge($lang, array(
'ACP_SERVER_SETTINGS' => 'Server settings',
'ACP_SIGNATURE_SETTINGS' => 'Signature settings',
'ACP_SMILIES' => 'Smilies',
+
+ 'ACP_STORAGE_SETTINGS' => 'Storage settings',
+
'ACP_STYLE_MANAGEMENT' => 'Style management',
'ACP_STYLES' => 'Styles',
'ACP_STYLES_CACHE' => 'Purge Cache',
@@ -230,6 +238,17 @@ $lang = array_merge($lang, array(
'EXCEPTION' => 'Exception',
'COLOUR_SWATCH' => 'Web-safe colour swatch',
+
+ 'COMPOSER_UNSUPPORTED_OPERATION' => 'Operation unsupported for the package type “%s”.',
+ 'COMPOSER_UPDATING_DEPENDENCIES' => 'Updating packages',
+ 'COMPOSER_LOADING_REPOSITORIES' => 'Loading remote repositories with package information',
+ 'COMPOSER_ERROR_CONFLICT' => 'Your requirements could not be resolved to an installable set of packages.',
+ 'COMPOSER_REPOSITORY_UNAVAILABLE' => 'An error occurred while fetching the repository %s.',
+ 'COMPOSER_INSTALLING_PACKAGE' => ' - Installing %1$s (%2$s)',
+ 'COMPOSER_DELETING' => ' - Deleting %s',
+ 'COMPOSER_UPDATE_NOTHING' => 'Nothing to update',
+ 'COMPOSER_OUTPUT' => 'Composer output',
+
'CONFIG_UPDATED' => 'Configuration updated successfully.',
'CRON_LOCK_ERROR' => 'Could not obtain cron lock.',
'CRON_NO_SUCH_TASK' => 'Could not find cron task “%s”.',
diff --git a/phpBB/language/en/acp/database.php b/phpBB/language/en/acp/database.php
index 302aaee570..f437e8e2e6 100644
--- a/phpBB/language/en/acp/database.php
+++ b/phpBB/language/en/acp/database.php
@@ -43,6 +43,7 @@ $lang = array_merge($lang, array(
'BACKUP_DELETE' => 'The backup file has been deleted successfully.',
'BACKUP_INVALID' => 'The selected file to backup is invalid.',
+ 'BACKUP_ERROR' => 'Error while saving file.',
'BACKUP_NOT_SUPPORTED' => 'The selected backup is not supported',
'BACKUP_OPTIONS' => 'Backup options',
'BACKUP_SUCCESS' => 'The backup file has been created successfully.',
@@ -59,6 +60,7 @@ $lang = array_merge($lang, array(
'FILE_WRITE_FAIL' => 'Unable to write file to storage folder.',
'FULL_BACKUP' => 'Full',
+ 'RESTORE_DOWNLOAD_FAIL' => 'Error while copying file from storage to local temporary folder.',
'RESTORE_FAILURE' => 'The backup file may be corrupt.',
'RESTORE_OPTIONS' => 'Restore options',
'RESTORE_SELECTED_BACKUP' => 'Are you sure you want to restore the selected backup?',
diff --git a/phpBB/language/en/acp/extensions.php b/phpBB/language/en/acp/extensions.php
index a96a7a2a2b..c6eb147b86 100644
--- a/phpBB/language/en/acp/extensions.php
+++ b/phpBB/language/en/acp/extensions.php
@@ -35,6 +35,22 @@ if (empty($lang) || !is_array($lang))
// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine
$lang = array_merge($lang, array(
+
+ 'EXTENSION_ALREADY_INSTALLED' => 'The “%s” extension has already been installed.',
+ 'EXTENSION_ALREADY_INSTALLED_MANUALLY' => 'The “%s” extension has already been installed manually.',
+ 'EXTENSION_ALREADY_MANAGED' => 'The “%s” extension is already managed.',
+ 'EXTENSION_CANNOT_MANAGE_FILESYSTEM_ERROR' => 'The “%s” extension cannot be managed because the existing files could not be removed from the filesystem.',
+ 'EXTENSION_CANNOT_MANAGE_INSTALL_ERROR' => 'The “%s” extension could not be installed. The prior installation of this extension has been restored.',
+ 'EXTENSION_MANAGED_WITH_CLEAN_ERROR' => 'The “%1$s” extension has been installed but an error occurred and the old files could not be removed. You might want to delete the “%2$s” files manually.',
+ 'EXTENSION_MANAGED_WITH_ENABLE_ERROR' => 'The “%s” extension has been installed but an error occurred while enabling it.',
+ 'EXTENSION_NOT_INSTALLED' => 'The “%s” extension is not installed.',
+
+ 'ENABLING_EXTENSIONS' => 'Enabling extensions',
+ 'DISABLING_EXTENSIONS' => 'Disabling extensions',
+
+ 'EXTENSIONS_CATALOG' => 'Extensions Catalog',
+ 'EXTENSIONS_CATALOG_EXPLAIN' => 'Here you can browse all of the extensions available for your phpBB board. Extensions can easily be installed or removed with just a click. Adjust the settings to allow instant enabling and purging of extensions.',
+
'EXTENSION' => 'Extension',
'EXTENSIONS' => 'Extensions',
'EXTENSIONS_ADMIN' => 'Extensions Manager',
@@ -43,7 +59,6 @@ $lang = array_merge($lang, array(
'EXTENSION_NOT_AVAILABLE' => 'The selected extension is not available for this board, please verify your phpBB and PHP versions are allowed (see the details page).',
'EXTENSION_DIR_INVALID' => 'The selected extension has an invalid directory structure and cannot be enabled.',
'EXTENSION_NOT_ENABLEABLE' => 'The selected extension cannot be enabled, please verify the extension’s requirements.',
- 'EXTENSION_NOT_INSTALLED' => 'The extension %s is not available. Please check that you have installed it correctly.',
'DETAILS' => 'Details',
@@ -53,6 +68,8 @@ $lang = array_merge($lang, array(
'EXTENSION_DELETE_DATA' => 'Delete data',
'EXTENSION_DISABLE' => 'Disable',
'EXTENSION_ENABLE' => 'Enable',
+ 'EXTENSION_UPDATE' => 'Update',
+ 'EXTENSION_REMOVE' => 'Remove',
'EXTENSION_DELETE_DATA_EXPLAIN' => 'Deleting an extension’s data removes all of its data and settings. The extension files are retained so it can be enabled again.',
'EXTENSION_DISABLE_EXPLAIN' => 'Disabling an extension retains its files, data and settings but removes any functionality added by the extension.',
@@ -94,6 +111,9 @@ $lang = array_merge($lang, array(
'EXTENSION_ENABLE_CONFIRM' => 'Are you sure that you wish to enable the “%s” extension?',
'EXTENSION_FORCE_UNSTABLE_CONFIRM' => 'Are you sure that you wish to force the use of unstable version?',
+ 'INSTALLED' => 'Installed',
+ 'INSTALLED_MANUALLY' => 'Installed manually',
+
'RETURN_TO_EXTENSION_LIST' => 'Return to the extension list',
'EXT_DETAILS' => 'Extension Details',
@@ -130,4 +150,32 @@ $lang = array_merge($lang, array(
'META_FIELD_NOT_SET' => 'Required meta field %s has not been set.',
'META_FIELD_INVALID' => 'Meta field %s is invalid.',
+
+ 'EXTENSIONS_CATALOG_SETTINGS' => 'Extensions catalog settings',
+ 'ENABLE_ON_INSTALL' => 'Enable extensions while installing',
+ 'PURGE_ON_REMOVE' => 'Purge extensions while removing',
+ 'ENABLE_PACKAGIST' => 'Search packagist',
+ 'ENABLE_PACKAGIST_EXPLAIN' => 'Search packagist for phpBB extensions. Beware that packagist may contain extensions not validated by the phpBB Extension Customisations Team.',
+ 'ENABLE_PACKAGIST_CONFIRM' => 'Are you sure you want to search packagist?',
+ 'COMPOSER_REPOSITORIES' => 'Repositories',
+ 'COMPOSER_REPOSITORIES_EXPLAIN' => 'Add URLs to Composer repositories of phpBB extensions to search here, one per line (must be the base url of the packages.json file).',
+ 'NO_EXTENSION_AVAILABLE' => 'There are no extension available for your board',
+
+ 'EXTENSION_MANAGED_SUCCESS' => 'The extension %s is now being managed automatically.',
+ 'EXTENSIONS_INSTALLED' => 'Extensions successfully installed.',
+ 'EXTENSIONS_REMOVED' => 'Extensions successfully removed.',
+ 'EXTENSIONS_UPDATED' => 'Extensions successfully updated.',
+
+ 'EXTENSIONS_CATALOG_NOT_AVAILABLE' => 'The extensions catalog is not available',
+ 'EXTENSIONS_COMPOSER_NOT_WRITABLE' => 'In order to use the catalog, the following files and directories must be writable: ext/ vendor-ext/ composer-ext.json and composer-ext.lock',
+
+ 'STABILITY_STABLE' => 'stable',
+ 'STABILITY_RC' => 'RC',
+ 'STABILITY_BETA' => 'beta',
+ 'STABILITY_ALPHA' => 'alpha',
+ 'STABILITY_DEV' => 'dev',
+
+ 'COMPOSER_MINIMUM_STABILITY' => 'Minimum stability',
+ 'COMPOSER_MINIMUM_STABILITY_EXPLAIN' => 'Always use <samp>stable</samp> versions on a live forum. Non-stable versions may still be in development and could cause unexpected problems with your forum and should only be used for development purposes in local or staging environments.',
+
));
diff --git a/phpBB/language/en/acp/permissions_phpbb.php b/phpBB/language/en/acp/permissions_phpbb.php
index ab8939932b..cdf4820475 100644
--- a/phpBB/language/en/acp/permissions_phpbb.php
+++ b/phpBB/language/en/acp/permissions_phpbb.php
@@ -201,6 +201,7 @@ $lang = array_merge($lang, array(
'ACL_A_ROLES' => 'Can manage roles',
'ACL_A_SWITCHPERM' => 'Can use others permissions',
+ 'ACL_A_STORAGE' => 'Can manage storages',
'ACL_A_STYLES' => 'Can manage styles',
'ACL_A_EXTENSIONS' => 'Can manage extensions',
'ACL_A_VIEWLOGS' => 'Can view logs',
diff --git a/phpBB/language/en/acp/storage.php b/phpBB/language/en/acp/storage.php
new file mode 100644
index 0000000000..69faa58030
--- /dev/null
+++ b/phpBB/language/en/acp/storage.php
@@ -0,0 +1,71 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+/**
+* DO NOT CHANGE
+*/
+if (!defined('IN_PHPBB'))
+{
+ exit;
+}
+
+if (empty($lang) || !is_array($lang))
+{
+ $lang = array();
+}
+
+// DEVELOPERS PLEASE NOTE
+//
+// All language files should use UTF-8 as their encoding and the files must not contain a BOM.
+//
+// Placeholders can now contain order information, e.g. instead of
+// 'Page %s of %s' you can (and should) write 'Page %1$s of %2$s', this allows
+// translators to re-order the output of data while ensuring it remains correct
+//
+// You do not need this where single placeholders are used, e.g. 'Message %d' is fine
+// equally where a string contains only two placeholders which are used to wrap text
+// in a url you again do not need to specify an order e.g., 'Click %sHERE%s' is fine
+
+$lang = array_merge($lang, array(
+
+ // Template
+ 'STORAGE_TITLE' => 'Storage Settings',
+ 'STORAGE_TITLE_EXPLAIN' => 'Change storage providers for the file storage types of phpBB. Choose local or remote providers to store files added to or created by phpBB.',
+ 'STORAGE_SELECT' => 'Select storage',
+ 'STORAGE_SELECT_DESC' => 'Select a storage from the list.',
+ 'STORAGE_NAME' => 'Storage name',
+ 'STORAGE_NUM_FILES' => 'Number of files',
+ 'STORAGE_SIZE' => 'Size',
+ 'STORAGE_FREE' => 'Available space',
+ 'STORAGE_UNKNOWN' => 'Unknown',
+
+ // Storage names
+ 'STORAGE_ATTACHMENT_TITLE' => 'Attachments storage',
+ 'STORAGE_AVATAR_TITLE' => 'Avatars storage',
+ 'STORAGE_BACKUP_TITLE' => 'Backup storage',
+
+ // Local adapter
+ 'STORAGE_ADAPTER_LOCAL_NAME' => 'Local',
+ 'STORAGE_ADAPTER_LOCAL_OPTION_PATH' => 'Path',
+ 'STORAGE_ADAPTER_LOCAL_OPTION_SUBFOLDERS' => 'Organize in subfolders',
+ 'STORAGE_ADAPTER_LOCAL_OPTION_SUBFOLDERS_EXPLAIN' => 'Some web servers may have problems storing large number of files in a single directory. Enable this option to distribute files in different directories.',
+
+ // Form validation
+ 'STORAGE_UPDATE_SUCCESSFUL' => 'All storage types were successfully updated.',
+ 'STORAGE_NO_CHANGES' => 'No changes have been applied.',
+ 'STORAGE_PROVIDER_NOT_EXISTS' => 'Provider selected for %s doesn’t exist.',
+ 'STORAGE_PROVIDER_NOT_AVAILABLE' => 'Provider selected for %s is not available.',
+ 'STORAGE_FORM_TYPE_EMAIL_INCORRECT_FORMAT' => 'Incorrect email for %s of %s.',
+ 'STORAGE_FORM_TYPE_TEXT_TOO_LONG' => 'Text is too long for %s of %s.',
+ 'STORAGE_FORM_TYPE_SELECT_NOT_AVAILABLE' => 'Selected value is not available for %s of %s.',
+));
diff --git a/phpBB/language/en/cli.php b/phpBB/language/en/cli.php
index 122010d2cf..27bcdf1019 100644
--- a/phpBB/language/en/cli.php
+++ b/phpBB/language/en/cli.php
@@ -161,6 +161,18 @@ $lang = array_merge($lang, array(
1 => 'Re-cleaning complete. %d username was cleaned.',
2 => 'Re-cleaning complete. %d usernames were cleaned.',
],
+
+ 'CLI_DESCRIPTION_EXTENSION_MANAGE' => 'Manages an extension',
+ 'CLI_DESCRIPTION_EXTENSION_MANAGE_ARGUMENT' => 'Extension to manage',
+ 'CLI_DESCRIPTION_EXTENSION_INSTALL' => 'Install the specified extension(s).',
+ 'CLI_DESCRIPTION_EXTENSION_INSTALL_OPTION_ENABLE' => 'Enable extension(s) after installation',
+ 'CLI_DESCRIPTION_EXTENSION_INSTALL_ARGUMENT' => 'Extension(s) to install, e.g.: vendor/package',
+ 'CLI_DESCRIPTION_EXTENSION_LIST_AVAILABLE' => 'List extensions available for installation.',
+ 'CLI_DESCRIPTION_EXTENSION_REMOVE' => 'Remove the specified extension(s).',
+ 'CLI_DESCRIPTION_EXTENSION_REMOVE_OPTION_PURGE' => 'Purge extension(s) when removing them',
+ 'CLI_DESCRIPTION_EXTENSION_REMOVE_ARGUMENT' => 'Extension(s) to remove, e.g.: vendor/package',
+ 'CLI_DESCRIPTION_EXTENSION_UPDATE' => 'Update the specified extension(s).',
+ 'CLI_DESCRIPTION_EXTENSION_UPDATE_ARGUMENT' => 'Extension(s) to update, e.g.: vendor/package',
));
// Additional help for commands.
diff --git a/phpBB/language/en/common.php b/phpBB/language/en/common.php
index 0d83e6787e..676ed89ec8 100644
--- a/phpBB/language/en/common.php
+++ b/phpBB/language/en/common.php
@@ -385,7 +385,7 @@ $lang = array_merge($lang, array(
'LDAP_SEARCH_FAILED' => 'An error occurred while searching the LDAP directory.',
'LEGEND' => 'Legend',
'LIVE_SEARCHES_NOT_ALLOWED' => 'Live searches are not allowed.',
- 'LOADING' => 'Loading',
+ 'LOADING' => 'Loading...',
'LOCATION' => 'Location',
'LOCK_POST' => 'Lock post',
'LOCK_POST_EXPLAIN' => 'Prevent editing',
@@ -750,6 +750,20 @@ $lang = array_merge($lang, array(
'SUBJECT' => 'Subject',
'SUBMIT' => 'Submit',
+ 'STORAGE_ADAPTER_NOT_AVAILABLE' => 'Selected storage is not available.',
+ 'STORAGE_FILE_EXISTS' => 'File already exists.',
+ 'STORAGE_FILE_NO_EXIST' => 'File does not exist.',
+ 'STORAGE_CANNOT_WRITE_FILE' => 'Can not write to file.',
+ 'STORAGE_CANNOT_READ_FILE' => 'Can not read file.',
+ 'STORAGE_CANNOT_DELETE' => 'Can not delete file or folder.',
+ 'STORAGE_CANNOT_RENAME' => 'Can not rename file or folder.',
+ 'STORAGE_CANNOT_COPY' => 'Can not copy file or folder.',
+ 'STORAGE_CANNOT_COPY_RESOURCE' => 'Can not copy resource.',
+ 'STORAGE_CANNOT_CREATE_DIR' => 'Can not create directory.',
+ 'STORAGE_CANNOT_OPEN_FILE' => 'Can not open file.',
+ 'STORAGE_CANNOT_CREATE_FILE' => 'Can not create file.',
+ 'STORAGE_INVALID_RESOURCE' => 'Resource is invalid.',
+
'TB' => 'TB',
'TERMS_LINK' => 'Terms',
'TERMS_USE' => 'Terms of use',
diff --git a/phpBB/language/en/install.php b/phpBB/language/en/install.php
index 530c003026..d8adcd06d1 100644
--- a/phpBB/language/en/install.php
+++ b/phpBB/language/en/install.php
@@ -564,7 +564,7 @@ $lang = array_merge($lang, array(
// Finish conversion
'CONVERT_COMPLETE' => 'Conversion completed',
- 'CONVERT_COMPLETE_EXPLAIN' => 'You have now successfully converted your board to phpBB 3.3. You can now login and <a href="../">access your board</a>. Please ensure that the settings were transferred correctly before enabling your board by deleting the install directory. Remember that help on using phpBB is available online via the <a href="https://www.phpbb.com/support/docs/en/3.3/ug/">Documentation</a> and the <a href="https://www.phpbb.com/community/viewforum.php?f=661">support forums</a>.',
+ 'CONVERT_COMPLETE_EXPLAIN' => 'You have now successfully converted your board to phpBB 4.0. You can now login and <a href="../">access your board</a>. Please ensure that the settings were transferred correctly before enabling your board by deleting the install directory. Remember that help on using phpBB is available online via the <a href="https://www.phpbb.com/support/docs/en/3.3/ug/">Documentation</a> and the <a href="https://www.phpbb.com/community/viewforum.php?f=661">support forums</a>.',
'CONV_ERROR_ATTACH_FTP_DIR' => 'FTP upload for attachments is enabled at the old board. Please disable the FTP upload option and make sure a valid upload directory is specified, then copy all attachment files to this new web accessible directory. Once you have done this, restart the convertor.',
'CONV_ERROR_CONFIG_EMPTY' => 'There is no configuration information available for the conversion.',
diff --git a/phpBB/phpbb/attachment/delete.php b/phpBB/phpbb/attachment/delete.php
index 3c98e21587..ec89cd5218 100644
--- a/phpBB/phpbb/attachment/delete.php
+++ b/phpBB/phpbb/attachment/delete.php
@@ -16,7 +16,7 @@ namespace phpbb\attachment;
use \phpbb\config\config;
use \phpbb\db\driver\driver_interface;
use \phpbb\event\dispatcher;
-use \phpbb\filesystem\filesystem;
+use \phpbb\storage\storage;
/**
* Attachment delete class
@@ -32,14 +32,11 @@ class delete
/** @var dispatcher */
protected $dispatcher;
- /** @var filesystem */
- protected $filesystem;
-
/** @var resync */
protected $resync;
- /** @var string phpBB root path */
- protected $phpbb_root_path;
+ /** @var storage */
+ protected $storage;
/** @var array Attachement IDs */
protected $ids;
@@ -71,18 +68,16 @@ class delete
* @param config $config
* @param driver_interface $db
* @param dispatcher $dispatcher
- * @param filesystem $filesystem
* @param resync $resync
- * @param string $phpbb_root_path
+ * @param storage $storage
*/
- public function __construct(config $config, driver_interface $db, dispatcher $dispatcher, filesystem $filesystem, resync $resync, $phpbb_root_path)
+ public function __construct(config $config, driver_interface $db, dispatcher $dispatcher, resync $resync, storage $storage)
{
$this->config = $config;
$this->db = $db;
$this->dispatcher = $dispatcher;
- $this->filesystem = $filesystem;
$this->resync = $resync;
- $this->phpbb_root_path = $phpbb_root_path;
+ $this->storage = $storage;
}
/**
@@ -181,8 +176,8 @@ class delete
return 0;
}
- // Delete attachments from filesystem
- $this->remove_from_filesystem($mode, $ids, $resync);
+ // Delete attachments from storage
+ $this->remove_from_storage($mode, $ids, $resync);
// If we do not resync, we do not need to adjust any message, post, topic or user entries
if (!$resync)
@@ -360,9 +355,9 @@ class delete
}
/**
- * Delete attachments from filesystem
+ * Delete attachments from storage
*/
- protected function remove_from_filesystem($mode, $ids, $resync)
+ protected function remove_from_storage($mode, $ids, $resync)
{
$space_removed = $files_removed = 0;
@@ -436,7 +431,7 @@ class delete
}
/**
- * Delete attachment from filesystem
+ * Delete attachment from storage
*
* @param string $filename Filename of attachment
* @param string $mode Delete mode
@@ -460,17 +455,16 @@ class delete
}
$filename = ($mode == 'thumbnail') ? 'thumb_' . utf8_basename($filename) : utf8_basename($filename);
- $filepath = $this->phpbb_root_path . $this->config['upload_path'] . '/' . $filename;
try
{
- if ($this->filesystem->exists($filepath))
+ if ($this->storage->exists($filename))
{
- $this->filesystem->remove($this->phpbb_root_path . $this->config['upload_path'] . '/' . $filename);
+ $this->storage->delete($filename);
return true;
}
}
- catch (\phpbb\filesystem\exception\filesystem_exception $exception)
+ catch (\phpbb\storage\exception\exception $exception)
{
// Fail is covered by return statement below
}
diff --git a/phpBB/phpbb/attachment/upload.php b/phpBB/phpbb/attachment/upload.php
index b9d32058db..21be17ef22 100644
--- a/phpBB/phpbb/attachment/upload.php
+++ b/phpBB/phpbb/attachment/upload.php
@@ -20,6 +20,8 @@ use \phpbb\event\dispatcher;
use \phpbb\language\language;
use \phpbb\mimetype\guesser;
use \phpbb\plupload\plupload;
+use \phpbb\storage\storage;
+use \phpbb\filesystem\temp;
use \phpbb\user;
/**
@@ -51,6 +53,12 @@ class upload
/** @var plupload Plupload */
protected $plupload;
+ /** @var storage */
+ protected $storage;
+
+ /** @var temp */
+ protected $temp;
+
/** @var user */
protected $user;
@@ -76,10 +84,11 @@ class upload
* @param guesser $mimetype_guesser
* @param dispatcher $phpbb_dispatcher
* @param plupload $plupload
+ * @param storage $storage
+ * @param temp $temp
* @param user $user
- * @param $phpbb_root_path
*/
- public function __construct(auth $auth, service $cache, config $config, \phpbb\files\upload $files_upload, language $language, guesser $mimetype_guesser, dispatcher $phpbb_dispatcher, plupload $plupload, user $user, $phpbb_root_path)
+ public function __construct(auth $auth, service $cache, config $config, \phpbb\files\upload $files_upload, language $language, guesser $mimetype_guesser, dispatcher $phpbb_dispatcher, plupload $plupload, storage $storage, temp $temp, user $user)
{
$this->auth = $auth;
$this->cache = $cache;
@@ -89,8 +98,9 @@ class upload
$this->mimetype_guesser = $mimetype_guesser;
$this->phpbb_dispatcher = $phpbb_dispatcher;
$this->plupload = $plupload;
+ $this->storage = $storage;
+ $this->temp = $temp;
$this->user = $user;
- $this->phpbb_root_path = $phpbb_root_path;
}
/**
@@ -118,7 +128,7 @@ class upload
return $this->file_data;
}
- $this->file = ($local) ? $this->files_upload->handle_upload('files.types.local', $local_storage, $local_filedata) : $this->files_upload->handle_upload('files.types.form', $form_name);
+ $this->file = ($local) ? $this->files_upload->handle_upload('files.types.local_storage', $local_storage, $local_filedata) : $this->files_upload->handle_upload('files.types.form_storage', $form_name);
if ($this->file->init_error())
{
@@ -152,10 +162,6 @@ class upload
$this->file->clean_filename('unique', $this->user->data['user_id'] . '_');
- // Are we uploading an image *and* this image being within the image category?
- // Only then perform additional image checks.
- $this->file->move_file($this->config['upload_path'], false, !$is_image);
-
// Do we have to create a thumbnail?
$this->file_data['thumbnail'] = ($is_image && $this->config['img_create_thumbnail']) ? 1 : 0;
@@ -164,7 +170,7 @@ class upload
if (count($this->file->error))
{
- $this->file->remove();
+ $this->file->remove($this->storage);
$this->file_data['error'] = array_merge($this->file_data['error'], $this->file->error);
$this->file_data['post_attach'] = false;
@@ -194,12 +200,34 @@ class upload
// Check for attachment quota and free space
if (!$this->check_attach_quota() || !$this->check_disk_space())
{
+ $this->file->remove($this->storage);
return $this->file_data;
}
// Create Thumbnail
$this->create_thumbnail();
+ // Are we uploading an image *and* this image being within the image category?
+ // Only then perform additional image checks.
+ $this->file->move_file($this->storage, false, !$is_image);
+
+ if (count($this->file->error))
+ {
+ $this->file->remove($this->storage);
+
+ // Remove thumbnail if exists
+ $thumbnail_file = 'thumb_' . $this->file->get('realname');
+ if ($this->storage->exists($thumbnail_file))
+ {
+ $this->storage->delete($thumbnail_file);
+ }
+
+ $this->file_data['error'] = array_merge($this->file_data['error'], $this->file->error);
+ $this->file_data['post_attach'] = false;
+
+ return $this->file_data;
+ }
+
return $this->file_data;
}
@@ -212,10 +240,23 @@ class upload
{
if ($this->file_data['thumbnail'])
{
- $source = $this->file->get('destination_file');
- $destination = $this->file->get('destination_path') . '/thumb_' . $this->file->get('realname');
+ $source = $this->file->get('filename');
+ $destination_name = 'thumb_' . $this->file->get('realname');
+ $destination = $this->temp->get_dir() . '/' . $destination_name;
+
+ if (create_thumbnail($source, $destination, $this->file->get('mimetype')))
+ {
+ // Move the thumbnail from temp folder to the storage
+ $fp = fopen($destination, 'rb');
+
+ $this->storage->write_stream($destination_name, $fp);
- if (!create_thumbnail($source, $destination, $this->file->get('mimetype')))
+ if (is_resource($fp))
+ {
+ fclose($fp);
+ }
+ }
+ else
{
$this->file_data['thumbnail'] = 0;
}
@@ -253,7 +294,7 @@ class upload
// Make sure the image category only holds valid images...
if ($is_image && !$this->file->is_image())
{
- $this->file->remove();
+ $this->file->remove($this->storage);
if ($this->plupload && $this->plupload->is_active())
{
@@ -280,8 +321,6 @@ class upload
$this->file_data['error'][] = $this->language->lang('ATTACH_QUOTA_REACHED');
$this->file_data['post_attach'] = false;
- $this->file->remove();
-
return false;
}
}
@@ -292,12 +331,14 @@ class upload
/**
* Check if there is enough free space available on disk
*
- * @return bool True if disk space is available, false if not
+ * @return bool True if disk space is available or not limited, false if not
*/
protected function check_disk_space()
{
- if ($free_space = @disk_free_space($this->phpbb_root_path . $this->config['upload_path']))
+ try
{
+ $free_space = $this->storage->free_space();
+
if ($free_space <= $this->file->get('filesize'))
{
if ($this->auth->acl_get('a_'))
@@ -308,13 +349,16 @@ class upload
{
$this->file_data['error'][] = $this->language->lang('ATTACH_QUOTA_REACHED');
}
- $this->file_data['post_attach'] = false;
- $this->file->remove();
+ $this->file_data['post_attach'] = false;
return false;
}
}
+ catch (\phpbb\storage\exception\exception $e)
+ {
+ // Do nothing
+ }
return true;
}
diff --git a/phpBB/phpbb/avatar/driver/gravatar.php b/phpBB/phpbb/avatar/driver/gravatar.php
index 3e4e7ff98b..cbd8da90e2 100644
--- a/phpBB/phpbb/avatar/driver/gravatar.php
+++ b/phpBB/phpbb/avatar/driver/gravatar.php
@@ -40,7 +40,7 @@ class gravatar extends \phpbb\avatar\driver\driver
*/
public function get_custom_html($user, $row, $alt = '')
{
- return '<img src="' . $this->get_gravatar_url($row) . '" ' .
+ return '<img class="gravatar" src="' . $this->get_gravatar_url($row) . '" ' .
($row['avatar_width'] ? ('width="' . $row['avatar_width'] . '" ') : '') .
($row['avatar_height'] ? ('height="' . $row['avatar_height'] . '" ') : '') .
'alt="' . ((!empty($user->lang[$alt])) ? $user->lang[$alt] : $alt) . '" />';
diff --git a/phpBB/phpbb/avatar/driver/upload.php b/phpBB/phpbb/avatar/driver/upload.php
index a5b704b4ff..da1e78cb83 100644
--- a/phpBB/phpbb/avatar/driver/upload.php
+++ b/phpBB/phpbb/avatar/driver/upload.php
@@ -13,15 +13,18 @@
namespace phpbb\avatar\driver;
+use bantu\IniGetWrapper\IniGetWrapper;
+use \phpbb\storage\exception\exception as storage_exception;
+
/**
* Handles avatars uploaded to the board
*/
class upload extends \phpbb\avatar\driver\driver
{
/**
- * @var \phpbb\filesystem\filesystem_interface
+ * @var \phpbb\storage\storage
*/
- protected $filesystem;
+ protected $storage;
/**
* @var \phpbb\event\dispatcher_interface
@@ -34,27 +37,32 @@ class upload extends \phpbb\avatar\driver\driver
protected $files_factory;
/**
+ * @var IniGetWrapper
+ */
+ protected $php_ini;
+
+ /**
* Construct a driver object
*
* @param \phpbb\config\config $config phpBB configuration
* @param string $phpbb_root_path Path to the phpBB root
* @param string $php_ext PHP file extension
- * @param \phpbb\filesystem\filesystem_interface $filesystem phpBB filesystem helper
+ * @param \phpbb\storage\storage phpBB avatar storage
* @param \phpbb\path_helper $path_helper phpBB path helper
* @param \phpbb\event\dispatcher_interface $dispatcher phpBB Event dispatcher object
* @param \phpbb\files\factory $files_factory File classes factory
- * @param \phpbb\cache\driver\driver_interface $cache Cache driver
+ * @param IniGetWrapper $php_ini ini_get() wrapper
*/
- public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\path_helper $path_helper, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\files\factory $files_factory, \phpbb\cache\driver\driver_interface $cache = null)
+ public function __construct(\phpbb\config\config $config, $phpbb_root_path, $php_ext, \phpbb\storage\storage $storage, \phpbb\path_helper $path_helper, \phpbb\event\dispatcher_interface $dispatcher, \phpbb\files\factory $files_factory, IniGetWrapper $php_ini)
{
$this->config = $config;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
- $this->filesystem = $filesystem;
+ $this->storage = $storage;
$this->path_helper = $path_helper;
$this->dispatcher = $dispatcher;
$this->files_factory = $files_factory;
- $this->cache = $cache;
+ $this->php_ini = $php_ini;
}
/**
@@ -117,7 +125,7 @@ class upload extends \phpbb\avatar\driver\driver
if (!empty($upload_file['name']))
{
- $file = $upload->handle_upload('files.types.form', 'avatar_upload_file');
+ $file = $upload->handle_upload('files.types.form_storage', 'avatar_upload_file');
}
else if (!empty($this->config['allow_avatar_remote_upload']) && !empty($url))
{
@@ -158,7 +166,7 @@ class upload extends \phpbb\avatar\driver\driver
return false;
}
- $file = $upload->handle_upload('files.types.remote', $url);
+ $file = $upload->handle_upload('files.types.remote_storage', $url);
}
else
{
@@ -171,26 +179,11 @@ class upload extends \phpbb\avatar\driver\driver
// If there was an error during upload, then abort operation
if (count($file->error))
{
- $file->remove();
+ $file->remove($this->storage);
$error = $file->error;
return false;
}
- // Calculate new destination
- $destination = $this->config['avatar_path'];
-
- // Adjust destination path (no trailing slash)
- if (substr($destination, -1, 1) == '/' || substr($destination, -1, 1) == '\\')
- {
- $destination = substr($destination, 0, -1);
- }
-
- $destination = str_replace(array('../', '..\\', './', '.\\'), '', $destination);
- if ($destination && ($destination[0] == '/' || $destination[0] == "\\"))
- {
- $destination = '';
- }
-
$filedata = array(
'filename' => $file->get('filename'),
'filesize' => $file->get('filesize'),
@@ -206,7 +199,6 @@ class upload extends \phpbb\avatar\driver\driver
* @event core.avatar_driver_upload_move_file_before
* @var array filedata Array containing uploaded file data
* @var \phpbb\files\filespec file Instance of filespec class
- * @var string destination Destination directory where the file is going to be moved
* @var string prefix Prefix for the avatar filename
* @var array row Array with avatar row data
* @var array error Array of errors, if filled in by this event file will not be moved
@@ -217,7 +209,6 @@ class upload extends \phpbb\avatar\driver\driver
$vars = array(
'filedata',
'file',
- 'destination',
'prefix',
'row',
'error',
@@ -229,14 +220,14 @@ class upload extends \phpbb\avatar\driver\driver
if (!count($error))
{
// Move file and overwrite any existing image
- $file->move_file($destination, true);
+ $file->move_file($this->storage, true);
}
// If there was an error during move, then clean up leftovers
$error = array_merge($error, $file->error);
if (count($error))
{
- $file->remove();
+ $file->remove($this->storage);
return false;
}
@@ -262,7 +253,6 @@ class upload extends \phpbb\avatar\driver\driver
return array(
'allow_avatar_remote_upload'=> array('lang' => 'ALLOW_REMOTE_UPLOAD', 'validate' => 'bool', 'type' => 'radio:yes_no', 'explain' => true),
'avatar_filesize' => array('lang' => 'MAX_FILESIZE', 'validate' => 'int:0', 'type' => 'number:0', 'explain' => true, 'append' => ' ' . $user->lang['BYTES']),
- 'avatar_path' => array('lang' => 'AVATAR_STORAGE_PATH', 'validate' => 'rpath', 'type' => 'text:20:255', 'explain' => true),
);
}
@@ -273,37 +263,35 @@ class upload extends \phpbb\avatar\driver\driver
{
$error = array();
- $destination = $this->config['avatar_path'];
$prefix = $this->config['avatar_salt'] . '_';
$ext = substr(strrchr($row['avatar'], '.'), 1);
- $filename = $this->phpbb_root_path . $destination . '/' . $prefix . $row['id'] . '.' . $ext;
+ $filename = $prefix . $row['id'] . '.' . $ext;
/**
* Before deleting an existing avatar
*
* @event core.avatar_driver_upload_delete_before
- * @var string destination Destination directory where the file is going to be deleted
* @var string prefix Prefix for the avatar filename
* @var array row Array with avatar row data
* @var array error Array of errors, if filled in by this event file will not be deleted
* @since 3.1.6-RC1
+ * @changed 3.3.0-a1 Remove destination
*/
$vars = array(
- 'destination',
'prefix',
'row',
'error',
);
extract($this->dispatcher->trigger_event('core.avatar_driver_upload_delete_before', compact($vars)));
- if (!count($error) && $this->filesystem->exists($filename))
+ if (!count($error) && $this->storage->exists($filename))
{
try
{
- $this->filesystem->remove($filename);
+ $this->storage->delete($filename);
return true;
}
- catch (\phpbb\filesystem\exception\filesystem_exception $e)
+ catch (storage_exception $e)
{
// Fail is covered by return statement below
}
@@ -321,12 +309,12 @@ class upload extends \phpbb\avatar\driver\driver
}
/**
- * Check if user is able to upload an avatar
+ * Check if user is able to upload an avatar to a temporary folder
*
* @return bool True if user can upload, false if not
*/
protected function can_upload()
{
- return ($this->filesystem->exists($this->phpbb_root_path . $this->config['avatar_path']) && $this->filesystem->is_writable($this->phpbb_root_path . $this->config['avatar_path']) && (@ini_get('file_uploads') || strtolower(@ini_get('file_uploads')) == 'on'));
+ return $this->php_ini->getBool('file_uploads');
}
}
diff --git a/phpBB/phpbb/cache/service.php b/phpBB/phpbb/cache/service.php
index 502ae27625..2d4e55bfbb 100644
--- a/phpBB/phpbb/cache/service.php
+++ b/phpBB/phpbb/cache/service.php
@@ -214,7 +214,6 @@ class service
$extensions[$extension] = array(
'display_cat' => (int) $row['cat_id'],
- 'download_mode' => (int) $row['download_mode'],
'upload_icon' => trim($row['upload_icon']),
'max_filesize' => (int) $row['max_filesize'],
'allow_group' => $row['allow_group'],
diff --git a/phpBB/phpbb/composer/exception/managed_with_clean_error_exception_exception.php b/phpBB/phpbb/composer/exception/managed_with_clean_error_exception_exception.php
new file mode 100644
index 0000000000..2339fa4096
--- /dev/null
+++ b/phpBB/phpbb/composer/exception/managed_with_clean_error_exception_exception.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\composer\exception;
+
+/**
+ * Packaged managed with success but error occurred when cleaning the filesystem
+ */
+class managed_with_clean_error_exception extends managed_with_error_exception
+{
+ /**
+ * Constructor
+ *
+ * @param string $prefix The language string prefix
+ * @param string $message The Exception message to throw (must be a language variable).
+ * @param array $parameters The parameters to use with the language var.
+ * @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining.
+ * @param integer $code The Exception code.
+ */
+ public function __construct($prefix, $message = '', array $parameters = [], \Exception $previous = null, $code = 0)
+ {
+ parent::__construct($prefix . $message, $parameters, $previous, $code);
+ }
+
+}
diff --git a/phpBB/phpbb/composer/exception/managed_with_enable_error_exception.php b/phpBB/phpbb/composer/exception/managed_with_enable_error_exception.php
new file mode 100644
index 0000000000..7ef7a42df3
--- /dev/null
+++ b/phpBB/phpbb/composer/exception/managed_with_enable_error_exception.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\composer\exception;
+
+/**
+ * Packaged managed with success but error occurred when re-enabling the extension
+ */
+class managed_with_enable_error_exception extends managed_with_error_exception
+{
+ /**
+ * Constructor
+ *
+ * @param string $prefix The language string prefix
+ * @param string $message The Exception message to throw (must be a language variable).
+ * @param array $parameters The parameters to use with the language var.
+ * @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining.
+ * @param integer $code The Exception code.
+ */
+ public function __construct($prefix, $message = '', array $parameters = [], \Exception $previous = null, $code = 0)
+ {
+ parent::__construct($prefix . $message, $parameters, $previous, $code);
+ }
+
+}
diff --git a/phpBB/phpbb/composer/exception/managed_with_error_exception.php b/phpBB/phpbb/composer/exception/managed_with_error_exception.php
new file mode 100644
index 0000000000..9e7c67580e
--- /dev/null
+++ b/phpBB/phpbb/composer/exception/managed_with_error_exception.php
@@ -0,0 +1,35 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\composer\exception;
+
+/**
+ * Packaged managed with success but errored at some point
+ */
+class managed_with_error_exception extends runtime_exception
+{
+ /**
+ * Constructor
+ *
+ * @param string $prefix The language string prefix
+ * @param string $message The Exception message to throw (must be a language variable).
+ * @param array $parameters The parameters to use with the language var.
+ * @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining.
+ * @param integer $code The Exception code.
+ */
+ public function __construct($prefix, $message = '', array $parameters = [], \Exception $previous = null, $code = 0)
+ {
+ parent::__construct($prefix . $message, $parameters, $previous, $code);
+ }
+
+}
diff --git a/phpBB/phpbb/composer/exception/runtime_exception.php b/phpBB/phpbb/composer/exception/runtime_exception.php
new file mode 100644
index 0000000000..eb92759318
--- /dev/null
+++ b/phpBB/phpbb/composer/exception/runtime_exception.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\composer\exception;
+
+use phpbb\exception\runtime_exception as base;
+
+/**
+ * Base class for exceptions thrown when managing packages through composer
+ */
+class runtime_exception extends base
+{
+ /**
+ * Constructor
+ *
+ * @param string $prefix The language string prefix
+ * @param string $message The Exception message to throw (must be a language variable).
+ * @param array $parameters The parameters to use with the language var.
+ * @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining.
+ * @param integer $code The Exception code.
+ */
+ public function __construct($prefix, $message = '', array $parameters = [], \Exception $previous = null, $code = 0)
+ {
+ parent::__construct($prefix . $message, $parameters, $previous, $code);
+ }
+
+}
diff --git a/phpBB/phpbb/composer/extension_manager.php b/phpBB/phpbb/composer/extension_manager.php
new file mode 100644
index 0000000000..96250e9dd3
--- /dev/null
+++ b/phpBB/phpbb/composer/extension_manager.php
@@ -0,0 +1,316 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\composer;
+
+use Composer\IO\IOInterface;
+use phpbb\cache\driver\driver_interface;
+use phpbb\composer\exception\managed_with_clean_error_exception;
+use phpbb\composer\exception\managed_with_enable_error_exception;
+use phpbb\composer\exception\runtime_exception;
+use phpbb\config\config;
+use phpbb\extension\manager as ext_manager;
+use phpbb\filesystem\exception\filesystem_exception;
+use phpbb\filesystem\filesystem;
+
+/**
+ * Class to safely manage extensions through composer.
+ */
+class extension_manager extends manager
+{
+ /**
+ * @var \phpbb\extension\manager
+ */
+ protected $extension_manager;
+
+ /**
+ * @var \phpbb\filesystem\filesystem
+ */
+ protected $filesystem;
+
+ /**
+ * @var array
+ */
+ private $enabled_extensions;
+
+ /**
+ * @var bool Enables extensions when installing them?
+ */
+ private $enable_on_install = false;
+
+ /**
+ * @var bool Purges extensions data when removing them?
+ */
+ private $purge_on_remove = true;
+
+ /**
+ * @param installer $installer Installer object
+ * @param driver_interface $cache Cache object
+ * @param ext_manager $extension_manager phpBB extension manager
+ * @param filesystem $filesystem Filesystem object
+ * @param string $package_type Composer type of managed packages
+ * @param string $exception_prefix Exception prefix to use
+ * @param string $root_path phpBB root path
+ * @param config $config Config object
+ */
+ public function __construct(installer $installer, driver_interface $cache, ext_manager $extension_manager, filesystem $filesystem, $package_type, $exception_prefix, $root_path, config $config = null)
+ {
+ $this->extension_manager = $extension_manager;
+ $this->filesystem = $filesystem;
+ $this->root_path = $root_path;
+
+ if ($config)
+ {
+ $this->enable_on_install = (bool) $config['exts_composer_enable_on_install'];
+ $this->purge_on_remove = (bool) $config['exts_composer_purge_on_remove'];
+ }
+
+ parent::__construct($installer, $cache, $package_type, $exception_prefix);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function pre_install(array $packages, IOInterface $io = null)
+ {
+ $installed_manually = array_intersect(array_keys($this->extension_manager->all_available()), array_keys($packages));
+ if (count($installed_manually) !== 0)
+ {
+ throw new runtime_exception($this->exception_prefix, 'ALREADY_INSTALLED_MANUALLY', [implode('|', array_keys($installed_manually))]);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function post_install(array $packages, IOInterface $io = null)
+ {
+ if ($this->enable_on_install)
+ {
+ $io->writeError([['ENABLING_EXTENSIONS', [], 1]], true);
+ foreach ($packages as $package => $version)
+ {
+ try
+ {
+ $this->extension_manager->enable($package);
+ }
+ catch (\phpbb\exception\runtime_exception $e)
+ {
+ $io->writeError([[$e->getMessage(), $e->get_parameters(), 4]], true);
+ }
+ catch (\Exception $e)
+ {
+ $io->writeError([[$e->getMessage(), [], 4]], true);
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function pre_update(array $packages, IOInterface $io = null)
+ {
+ $io->writeError([['DISABLING_EXTENSIONS', [], 1]], true);
+ $this->enabled_extensions = [];
+ foreach ($packages as $package => $version)
+ {
+ try
+ {
+ if ($this->extension_manager->is_enabled($package))
+ {
+ $this->enabled_extensions[] = $package;
+ $this->extension_manager->disable($package);
+ }
+ }
+ catch (\phpbb\exception\runtime_exception $e)
+ {
+ $io->writeError([[$e->getMessage(), $e->get_parameters(), 4]], true);
+ }
+ catch (\Exception $e)
+ {
+ $io->writeError([[$e->getMessage(), [], 4]], true);
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function post_update(array $packages, IOInterface $io = null)
+ {
+ $io->writeError([['ENABLING_EXTENSIONS', [], 1]], true);
+ foreach ($this->enabled_extensions as $package)
+ {
+ try
+ {
+ $this->extension_manager->enable($package);
+ }
+ catch (\phpbb\exception\runtime_exception $e)
+ {
+ $io->writeError([[$e->getMessage(), $e->get_parameters(), 4]], true);
+ }
+ catch (\Exception $e)
+ {
+ $io->writeError([[$e->getMessage(), [], 4]], true);
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function remove(array $packages, IOInterface $io = null)
+ {
+ $packages = $this->normalize_version($packages);
+
+ $not_installed = array_diff(array_keys($packages), array_keys($this->extension_manager->all_available()));
+ if (count($not_installed) !== 0)
+ {
+ throw new runtime_exception($this->exception_prefix, 'NOT_INSTALLED', [implode('|', array_keys($not_installed))]);
+ }
+
+ parent::remove($packages, $io);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function pre_remove(array $packages, IOInterface $io = null)
+ {
+ if ($this->purge_on_remove)
+ {
+ $io->writeError([['DISABLING_EXTENSIONS', [], 1]], true);
+ }
+
+ foreach ($packages as $package => $version)
+ {
+ try
+ {
+ if ($this->extension_manager->is_enabled($package))
+ {
+ if ($this->purge_on_remove)
+ {
+ $this->extension_manager->purge($package);
+ }
+ else
+ {
+ $this->extension_manager->disable($package);
+ }
+ }
+ }
+ catch (\phpbb\exception\runtime_exception $e)
+ {
+ $io->writeError([[$e->getMessage(), $e->get_parameters(), 4]], true);
+ }
+ catch (\Exception $e)
+ {
+ $io->writeError([[$e->getMessage(), [], 4]], true);
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function start_managing($package, $io)
+ {
+ if (!$this->extension_manager->is_available($package))
+ {
+ throw new runtime_exception($this->exception_prefix, 'NOT_INSTALLED', [$package]);
+ }
+
+ if ($this->is_managed($package))
+ {
+ throw new runtime_exception($this->exception_prefix, 'ALREADY_MANAGED', [$package]);
+ }
+
+ $enabled = false;
+ if ($this->extension_manager->is_enabled($package))
+ {
+ $enabled = true;
+ $io->writeError([['DISABLING_EXTENSIONS', [], 1]], true);
+ $this->extension_manager->disable($package);
+ }
+
+ $ext_path = $this->extension_manager->get_extension_path($package, true);
+ $backup_path = rtrim($ext_path, '/') . '__backup__';
+
+ try
+ {
+ $this->filesystem->rename($ext_path, $backup_path);
+ }
+ catch (filesystem_exception $e)
+ {
+ throw new runtime_exception($this->exception_prefix, 'CANNOT_MANAGE_FILESYSTEM_ERROR', [$package], $e);
+ }
+
+ try
+ {
+ $this->install((array) $package, $io);
+ $this->filesystem->remove($backup_path);
+ }
+ catch (runtime_exception $e)
+ {
+ $this->filesystem->rename($backup_path, $ext_path);
+ throw new runtime_exception($this->exception_prefix, 'CANNOT_MANAGE_INSTALL_ERROR', [$package], $e);
+ }
+ catch (filesystem_exception $e)
+ {
+ throw new managed_with_clean_error_exception($this->exception_prefix, 'MANAGED_WITH_CLEAN_ERROR', [$package, $backup_path], $e);
+ }
+
+ if ($enabled)
+ {
+ try
+ {
+ $io->writeError([['ENABLING_EXTENSIONS', [], 1]], true);
+ $this->extension_manager->enable($package);
+ }
+ catch (\Exception $e)
+ {
+ throw new managed_with_enable_error_exception($this->exception_prefix, 'MANAGED_WITH_ENABLE_ERROR', [$package], $e);
+ }
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check_requirements()
+ {
+ return parent::check_requirements() && $this->filesystem->is_writable($this->root_path . 'ext/');
+ }
+
+ /**
+ * Enable the extensions when installing
+ *
+ * Warning: Only the explicitly required extensions will be enabled
+ *
+ * @param bool $enable
+ */
+ public function set_enable_on_install($enable)
+ {
+ $this->enable_on_install = $enable;
+ }
+
+ /**
+ * Purge the extension when disabling it
+ *
+ * @param bool $purge
+ */
+ public function set_purge_on_remove($purge)
+ {
+ $this->purge_on_remove = $purge;
+ }
+}
diff --git a/phpBB/phpbb/composer/installer.php b/phpBB/phpbb/composer/installer.php
new file mode 100644
index 0000000000..1bc2c8e6b4
--- /dev/null
+++ b/phpBB/phpbb/composer/installer.php
@@ -0,0 +1,716 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\composer;
+
+use Composer\Composer;
+use Composer\Factory;
+use Composer\IO\IOInterface;
+use Composer\IO\NullIO;
+use Composer\Json\JsonFile;
+use Composer\Package\BasePackage;
+use Composer\Package\CompletePackage;
+use Composer\Repository\ComposerRepository;
+use Composer\Semver\Constraint\ConstraintInterface;
+use Composer\Util\RemoteFilesystem;
+use phpbb\composer\io\null_io;
+use phpbb\config\config;
+use phpbb\exception\runtime_exception;
+use phpbb\filesystem\filesystem;
+use phpbb\request\request;
+use Seld\JsonLint\ParsingException;
+use phpbb\filesystem\helper as filesystem_helper;
+
+/**
+ * Class to install packages through composer while freezing core dependencies.
+ */
+class installer
+{
+ const PHPBB_TYPES = 'phpbb-extension,phpbb-style,phpbb-language';
+
+ /**
+ * @var array Repositories to look packages from
+ */
+ protected $repositories = [];
+
+ /**
+ * @var bool Indicates whether packagist usage is allowed or not
+ */
+ protected $packagist = false;
+
+ /**
+ * @var string Composer filename used to manage the packages
+ */
+ protected $composer_filename = 'composer-ext.json';
+
+ /**
+ * @var string Directory where to install packages vendors
+ */
+ protected $packages_vendor_dir = 'vendor-ext/';
+
+ /**
+ * @var string Minimum stability
+ */
+ protected $minimum_stability = 'stable';
+
+ /**
+ * @var string phpBB root path
+ */
+ protected $root_path;
+
+ /**
+ * @var string Stores the original working directory in case it has been changed through move_to_root()
+ */
+ private $original_cwd;
+
+ /**
+ * @var array Stores the content of the ext json file before generate_ext_json_file() overrides it
+ */
+ private $ext_json_file_backup;
+
+ /**
+ * @var request phpBB request object
+ */
+ private $request;
+
+ /**
+ * @param string $root_path phpBB root path
+ * @param filesystem $filesystem Filesystem object
+ * @param request $request phpBB request object
+ * @param config $config Config object
+ */
+ public function __construct($root_path, filesystem $filesystem, request $request, config $config = null)
+ {
+ if ($config)
+ {
+ $repositories = json_decode($config['exts_composer_repositories'], true);
+
+ if (is_array($repositories) && !empty($repositories))
+ {
+ $this->repositories = (array) $repositories;
+ }
+
+ $this->packagist = (bool) $config['exts_composer_packagist'];
+ $this->composer_filename = $config['exts_composer_json_file'];
+ $this->packages_vendor_dir = $config['exts_composer_vendor_dir'];
+ $this->minimum_stability = $config['exts_composer_minimum_stability'];
+ }
+
+ $this->root_path = $root_path;
+ $this->request = $request;
+
+ putenv('COMPOSER_HOME=' . filesystem_helper::realpath($root_path) . '/store/composer');
+ }
+
+ /**
+ * Update the current installed set of packages
+ *
+ * @param array $packages Packages to install.
+ * Each entry may be a name or an array associating a version constraint to a name
+ * @param array $whitelist White-listed packages (packages that can be installed/updated/removed)
+ * @param IOInterface $io IO object used for the output
+ *
+ * @throws runtime_exception
+ */
+ public function install(array $packages, $whitelist, IOInterface $io = null)
+ {
+ $this->wrap(function() use ($packages, $whitelist, $io) {
+ $this->do_install($packages, $whitelist, $io);
+ });
+ }
+
+ /**
+ * Update the current installed set of packages
+ *
+ * /!\ Doesn't change the current working directory
+ *
+ * @param array $packages Packages to install.
+ * Each entry may be a name or an array associating a version constraint to a name
+ * @param array $whitelist White-listed packages (packages that can be installed/updated/removed)
+ * @param IOInterface $io IO object used for the output
+ *
+ * @throws runtime_exception
+ */
+ protected function do_install(array $packages, $whitelist, IOInterface $io = null)
+ {
+ if (!$io)
+ {
+ $io = new null_io();
+ }
+
+ $this->generate_ext_json_file($packages);
+
+ $composer = Factory::create($io, $this->get_composer_ext_json_filename(), false);
+ $install = \Composer\Installer::create($io, $composer);
+
+ $composer->getDownloadManager()->setOutputProgress(false);
+
+ $install
+ ->setVerbose(true)
+ ->setPreferSource(false)
+ ->setPreferDist(true)
+ ->setDevMode(false)
+ ->setUpdate(true)
+ ->setUpdateWhitelist($whitelist)
+ ->setWhitelistDependencies(false)
+ ->setIgnorePlatformRequirements(false)
+ ->setOptimizeAutoloader(true)
+ ->setDumpAutoloader(true)
+ ->setPreferStable(true)
+ ->setRunScripts(false)
+ ->setDryRun(false);
+
+ try
+ {
+ $result = $install->run();
+ }
+ catch (\Exception $e)
+ {
+ $this->restore_ext_json_file();
+
+ throw new runtime_exception('COMPOSER_CANNOT_INSTALL', [], $e);
+ }
+
+ if ($result !== 0)
+ {
+ $this->restore_ext_json_file();
+
+ throw new runtime_exception($io->get_composer_error(), []);
+ }
+ }
+
+ /**
+ * Returns the list of currently installed packages
+ *
+ * @param string|array $types Returns only the packages with the given type(s)
+ *
+ * @return array The installed packages associated to their version.
+ *
+ * @throws runtime_exception
+ */
+ public function get_installed_packages($types)
+ {
+ return $this->wrap(function() use ($types) {
+ return $this->do_get_installed_packages($types);
+ });
+ }
+
+ /**
+ * Returns the list of currently installed packages
+ *
+ * /!\ Doesn't change the current working directory
+ *
+ * @param string|array $types Returns only the packages with the given type(s)
+ *
+ * @return array The installed packages associated to their version.
+ */
+ protected function do_get_installed_packages($types)
+ {
+ $types = (array) $types;
+
+ try
+ {
+ $io = new NullIO();
+ $composer = Factory::create($io, $this->get_composer_ext_json_filename(), false);
+
+ $installed = [];
+
+ /** @var \Composer\Package\Link[] $required_links */
+ $required_links = $composer->getPackage()->getRequires();
+ $installed_packages = $composer->getRepositoryManager()->getLocalRepository()->getCanonicalPackages();
+
+ foreach ($installed_packages as $package)
+ {
+ if (in_array($package->getType(), $types, true))
+ {
+ $version = array_key_exists($package->getName(), $required_links) ?
+ $required_links[$package->getName()]->getPrettyConstraint() : '*';
+ $installed[$package->getName()] = $version;
+ }
+ }
+
+ return $installed;
+ }
+ catch (\Exception $e)
+ {
+ return [];
+ }
+ }
+
+ /**
+ * Gets the list of the available packages of the configured type in the configured repositories
+ *
+ * /!\ Doesn't change the current working directory
+ *
+ * @param string $type Returns only the packages with the given type
+ *
+ * @return array The name of the available packages, associated to their definition. Ordered by name.
+ *
+ * @throws runtime_exception
+ */
+ public function get_available_packages($type)
+ {
+ return $this->wrap(function() use ($type) {
+ return $this->do_get_available_packages($type);
+ });
+ }
+
+ /**
+ * Gets the list of the available packages of the configured type in the configured repositories
+ *
+ * @param string $type Returns only the packages with the given type
+ *
+ * @return array The name of the available packages, associated to their definition. Ordered by name.
+ */
+ protected function do_get_available_packages($type)
+ {
+ try
+ {
+ $this->generate_ext_json_file($this->do_get_installed_packages(explode(',', self::PHPBB_TYPES)));
+
+ $io = new NullIO();
+ $composer = Factory::create($io, $this->get_composer_ext_json_filename(), false);
+
+ /** @var ConstraintInterface $core_constraint */
+ $core_constraint = $composer->getPackage()->getRequires()['phpbb/phpbb']->getConstraint();
+ $core_stability = $composer->getPackage()->getMinimumStability();
+
+ $available = [];
+
+ $compatible_packages = [];
+ $repositories = $composer->getRepositoryManager()->getRepositories();
+
+ /** @var \Composer\Repository\RepositoryInterface $repository */
+ foreach ($repositories as $repository)
+ {
+ try
+ {
+ if ($repository instanceof ComposerRepository && $repository->hasProviders())
+ {
+ // Special case for packagist which exposes an api to retrieve all packages of a given type.
+ // For the others composer repositories with providers we can't do anything. It would be too slow.
+
+ $r = new \ReflectionObject($repository);
+ $repo_url = $r->getProperty('url');
+ $repo_url->setAccessible(true);
+
+ if ($repo_url->getValue($repository) === 'http://packagist.org')
+ {
+ $url = 'https://packagist.org/packages/list.json?type=' . $type;
+ $rfs = new RemoteFilesystem($io);
+ $hostname = parse_url($url, PHP_URL_HOST) ?: $url;
+ $json = $rfs->getContents($hostname, $url, false);
+
+ /** @var \Composer\Package\PackageInterface $package */
+ foreach (JsonFile::parseJson($json, $url)['packageNames'] as $package)
+ {
+ $versions = $repository->findPackages($package);
+ $compatible_packages = $this->get_compatible_versions($compatible_packages, $core_constraint, $core_stability, $package, $versions);
+ }
+ }
+ }
+ else
+ {
+ // Pre-filter repo packages by their type
+ $packages = [];
+ /** @var \Composer\Package\PackageInterface $package */
+ foreach ($repository->getPackages() as $package)
+ {
+ if ($package->getType() === $type)
+ {
+ $packages[$package->getName()][] = $package;
+ }
+ }
+
+ // Filter the compatibles versions
+ foreach ($packages as $package => $versions)
+ {
+ $compatible_packages = $this->get_compatible_versions($compatible_packages, $core_constraint, $core_stability, $package, $versions);
+ }
+ }
+ }
+ catch (\Exception $e)
+ {
+ // If a repo fails, just skip it.
+ continue;
+ }
+ }
+
+ foreach ($compatible_packages as $name => $versions)
+ {
+ // Determine the highest version of the package
+ /** @var CompletePackage $highest_version */
+ $highest_version = null;
+
+ /** @var CompletePackage $version */
+ foreach ($versions as $version)
+ {
+ if (!$highest_version || version_compare($version->getVersion(), $highest_version->getVersion(), '>'))
+ {
+ $highest_version = $version;
+ }
+ }
+
+ // Generates the entry
+ $available[$name] = [];
+ $available[$name]['name'] = $highest_version->getPrettyName();
+ $available[$name]['display_name'] = $highest_version->getExtra()['display-name'];
+ $available[$name]['composer_name'] = $highest_version->getName();
+ $available[$name]['version'] = $highest_version->getPrettyVersion();
+
+ if ($version instanceof CompletePackage)
+ {
+ $available[$name]['description'] = $highest_version->getDescription();
+ $available[$name]['url'] = $highest_version->getHomepage();
+ $available[$name]['authors'] = $highest_version->getAuthors();
+ }
+ else
+ {
+ $available[$name]['description'] = '';
+ $available[$name]['url'] = '';
+ $available[$name]['authors'] = [];
+ }
+ }
+
+ usort($available, function($a, $b)
+ {
+ return strcasecmp($a['display_name'], $b['display_name']);
+ });
+
+ return $available;
+ }
+ catch (\Exception $e)
+ {
+ return [];
+ }
+ }
+
+ /**
+ * Checks the requirements of the manager and returns true if it can be used.
+ *
+ * @return bool
+ */
+ public function check_requirements()
+ {
+ $filesystem = new \phpbb\filesystem\filesystem();
+
+ return $filesystem->is_writable([
+ $this->root_path . $this->composer_filename,
+ $this->root_path . $this->packages_vendor_dir,
+ $this->root_path . substr($this->composer_filename, 0, -5) . '.lock',
+ ]);
+ }
+
+ /**
+ * Updates $compatible_packages with the versions of $versions compatibles with the $core_constraint
+ *
+ * @param array $compatible_packages List of compatibles versions
+ * @param ConstraintInterface $core_constraint Constraint against the phpBB version
+ * @param string $core_stability Core stability
+ * @param string $package_name Considered package
+ * @param array $versions List of available versions
+ *
+ * @return array
+ */
+ private function get_compatible_versions(array $compatible_packages, ConstraintInterface $core_constraint, $core_stability, $package_name, array $versions)
+ {
+ $core_stability_value = BasePackage::$stabilities[$core_stability];
+
+ /** @var \Composer\Package\PackageInterface $version */
+ foreach ($versions as $version)
+ {
+ try
+ {
+ if (BasePackage::$stabilities[$version->getStability()] > $core_stability_value)
+ {
+ continue;
+ }
+
+ if (array_key_exists('phpbb/phpbb', $version->getRequires()))
+ {
+ /** @var ConstraintInterface $package_constraint */
+ $package_constraint = $version->getRequires()['phpbb/phpbb']->getConstraint();
+
+ if (!$package_constraint->matches($core_constraint))
+ {
+ continue;
+ }
+ }
+
+ $compatible_packages[$package_name][] = $version;
+ }
+ catch (\Exception $e)
+ {
+ // Do nothing (to log when a true debug logger is available)
+ }
+ }
+
+ return $compatible_packages;
+ }
+
+ /**
+ * Generates and write the json file used to install the set of packages
+ *
+ * @param array $packages Packages to update.
+ * Each entry may be a name or an array associating a version constraint to a name
+ */
+ protected function generate_ext_json_file(array $packages)
+ {
+ $io = new NullIO();
+
+ $composer = Factory::create($io, null, false);
+
+ $core_packages = $this->get_core_packages($composer);
+
+ // The composer/installers package must be installed on his own and not provided by the existing autoloader
+ $core_replace = $core_packages;
+ unset($core_replace['composer/installers']);
+
+ $ext_json_data = [
+ 'require' => array_merge(
+ ['php' => $this->get_core_php_requirement($composer)],
+ $core_packages,
+ $this->get_extra_dependencies(),
+ $packages),
+ 'replace' => $core_replace,
+ 'repositories' => $this->get_composer_repositories(),
+ 'config' => [
+ 'vendor-dir'=> $this->packages_vendor_dir,
+ ],
+ 'minimum-stability' => $this->minimum_stability,
+ ];
+
+ $this->ext_json_file_backup = null;
+ $json_file = new JsonFile($this->get_composer_ext_json_filename());
+
+ try
+ {
+ $ext_json_file_backup = $json_file->read();
+ }
+ catch (ParsingException $e)
+ {
+ $ext_json_file_backup = '{}';
+
+ $lockFile = new JsonFile(substr($this->get_composer_ext_json_filename(), 0, -5) . '.lock');
+ $lockFile->write([]);
+ }
+
+ $json_file->write($ext_json_data);
+ $this->ext_json_file_backup = $ext_json_file_backup;
+ }
+
+ /**
+ * Restore the json file overridden by generate_ext_json_file()
+ */
+ protected function restore_ext_json_file()
+ {
+ if ($this->ext_json_file_backup)
+ {
+ try
+ {
+ $json_file = new JsonFile($this->get_composer_ext_json_filename());
+ $json_file->write($this->ext_json_file_backup);
+ }
+ catch (\Exception $e)
+ {
+ }
+
+ $this->ext_json_file_backup = null;
+ }
+ }
+
+ /**
+ * Get the core installed packages
+ *
+ * @param Composer $composer Composer object to load the dependencies
+ * @return array The core packages with their version
+ */
+ protected function get_core_packages(Composer $composer)
+ {
+ $core_deps = [];
+ $packages = $composer->getRepositoryManager()->getLocalRepository()->getCanonicalPackages();
+
+ foreach ($packages as $package)
+ {
+ $core_deps[$package->getName()] = $package->getPrettyVersion();
+ }
+
+ $core_deps['phpbb/phpbb'] = PHPBB_VERSION;
+
+ return $core_deps;
+ }
+
+ /**
+ * Get the PHP version required by the core
+ *
+ * @param Composer $composer Composer object to load the dependencies
+ * @return string The PHP version required by the core
+ */
+ protected function get_core_php_requirement(Composer $composer)
+ {
+ return $composer->getLocker()->getLockData()['platform']['php'];
+ }
+
+ /**
+ * Generate the repositories entry of the packages json file
+ *
+ * @return array repositories entry
+ */
+ protected function get_composer_repositories()
+ {
+ $repositories = [];
+
+ if (!$this->packagist)
+ {
+ $repositories[]['packagist'] = false;
+ }
+
+ foreach ($this->repositories as $repository)
+ {
+ if (preg_match('#^' . get_preg_expression('url') . '$#iu', $repository))
+ {
+ $repositories[] = [
+ 'type' => 'composer',
+ 'url' => $repository,
+ ];
+ }
+ }
+
+ return $repositories;
+ }
+
+ /**
+ * Get the name of the json file used for the packages.
+ *
+ * @return string The json filename
+ */
+ protected function get_composer_ext_json_filename()
+ {
+ return $this->composer_filename;
+ }
+
+ /**
+ * Get extra dependencies required to install the packages
+ *
+ * @return array Array of composer dependencies
+ */
+ protected function get_extra_dependencies()
+ {
+ return [];
+ }
+
+ /**
+ * Sets the customs repositories
+ *
+ * @param array $repositories An array of composer repositories to use
+ */
+ public function set_repositories(array $repositories)
+ {
+ $this->repositories = $repositories;
+ }
+
+ /**
+ * Allow or disallow packagist
+ *
+ * @param boolean $packagist
+ */
+ public function set_packagist($packagist)
+ {
+ $this->packagist = $packagist;
+ }
+
+ /**
+ * Sets the name of the managed packages' json file
+ *
+ * @param string $composer_filename
+ */
+ public function set_composer_filename($composer_filename)
+ {
+ $this->composer_filename = $composer_filename;
+ }
+
+ /**
+ * Sets the location of the managed packages' vendors
+ *
+ * @param string $packages_vendor_dir
+ */
+ public function set_packages_vendor_dir($packages_vendor_dir)
+ {
+ $this->packages_vendor_dir = $packages_vendor_dir;
+ }
+
+ /**
+ * Sets the phpBB root path
+ *
+ * @param string $root_path
+ */
+ public function set_root_path($root_path)
+ {
+ $this->root_path = $root_path;
+ }
+
+ /**
+ * Change the current directory to phpBB root
+ */
+ protected function move_to_root()
+ {
+ if ($this->original_cwd === null)
+ {
+ $this->original_cwd = getcwd();
+ chdir($this->root_path);
+ }
+ }
+
+ /**
+ * Restore the current working directory if move_to_root() have been called
+ */
+ protected function restore_cwd()
+ {
+ if ($this->original_cwd)
+ {
+ chdir($this->original_cwd);
+ $this->original_cwd = null;
+ }
+ }
+
+ /**
+ * Wraps a callable in order to adjust the context needed by composer
+ *
+ * @param callable $callable
+ *
+ * @return mixed
+ */
+ protected function wrap(callable $callable)
+ {
+ // The composer installers works with a path relative to the current directory
+ $this->move_to_root();
+
+ // The composer installers uses some super globals
+ $super_globals = $this->request->super_globals_disabled();
+ $this->request->enable_super_globals();
+
+ try
+ {
+ return $callable();
+ }
+ finally
+ {
+ $this->restore_cwd();
+
+ if ($super_globals)
+ {
+ $this->request->disable_super_globals();
+ }
+ }
+ }
+}
diff --git a/phpBB/phpbb/composer/io/console_io.php b/phpBB/phpbb/composer/io/console_io.php
new file mode 100644
index 0000000000..5239b050bb
--- /dev/null
+++ b/phpBB/phpbb/composer/io/console_io.php
@@ -0,0 +1,40 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\composer\io;
+
+use Composer\IO\ConsoleIO;
+use phpbb\language\language;
+use Symfony\Component\Console\Helper\HelperSet;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+class console_io extends ConsoleIO implements io_interface
+{
+ use translate_composer_trait;
+
+ /**
+ * Constructor.
+ *
+ * @param InputInterface $input The input instance
+ * @param OutputInterface $output The output instance
+ * @param HelperSet $helperSet The helperSet instance
+ * @param language $language Language object
+ */
+ public function __construct(InputInterface $input, OutputInterface $output, HelperSet $helperSet, language $language)
+ {
+ $this->language = $language;
+
+ parent::__construct($input, $output, $helperSet);
+ }
+}
diff --git a/phpBB/phpbb/composer/io/html_output_formatter.php b/phpBB/phpbb/composer/io/html_output_formatter.php
new file mode 100644
index 0000000000..588be30a21
--- /dev/null
+++ b/phpBB/phpbb/composer/io/html_output_formatter.php
@@ -0,0 +1,86 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\composer\io;
+
+class html_output_formatter extends \Composer\Console\HtmlOutputFormatter
+{
+ protected static $availableForegroundColors = [
+ 30 => 'black',
+ 31 => 'red',
+ 32 => 'green',
+ 33 => 'orange',
+ 34 => 'blue',
+ 35 => 'magenta',
+ 36 => 'cyan',
+ 37 => 'white',
+ ];
+
+ protected static $availableBackgroundColors = [
+ 40 => 'black',
+ 41 => 'red',
+ 42 => 'green',
+ 43 => 'yellow',
+ 44 => 'blue',
+ 45 => 'magenta',
+ 46 => 'cyan',
+ 47 => 'white',
+ ];
+
+ protected static $availableOptions
+ = [
+ 1 => 'bold',
+ 4 => 'underscore',
+ ];
+
+ /**
+ * {@inheritdoc}
+ */
+ public function format($message)
+ {
+ $formatted = parent::format($message);
+
+ return preg_replace_callback("{[\033\e]\[([0-9;]+)m(.*?)[\033\e]\[[0-9;]+m}s", [$this, 'formatHtml'], $formatted);
+ }
+
+ protected function formatHtml($matches)
+ {
+ $out = '<span style="';
+ foreach (explode(';', $matches[1]) as $code)
+ {
+ if (isset(self::$availableForegroundColors[$code]))
+ {
+ $out .= 'color:' . self::$availableForegroundColors[$code] . ';';
+ }
+ else if (isset(self::$availableBackgroundColors[$code]))
+ {
+ $out .= 'background-color:' . self::$availableBackgroundColors[$code] . ';';
+ }
+ else if (isset(self::$availableOptions[$code]))
+ {
+ switch (self::$availableOptions[$code])
+ {
+ case 'bold':
+ $out .= 'font-weight:bold;';
+ break;
+
+ case 'underscore':
+ $out .= 'text-decoration:underline;';
+ break;
+ }
+ }
+ }
+
+ return $out . '">' . $matches[2] . '</span>';
+ }
+}
diff --git a/phpBB/phpbb/composer/io/io_interface.php b/phpBB/phpbb/composer/io/io_interface.php
new file mode 100644
index 0000000000..a1d41122cb
--- /dev/null
+++ b/phpBB/phpbb/composer/io/io_interface.php
@@ -0,0 +1,26 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\composer\io;
+
+use Composer\IO\IOInterface;
+
+interface io_interface extends IOInterface
+{
+ /**
+ * Returns the composer errors that occurred since the last tcall of the method.
+ *
+ * @return string
+ */
+ public function get_composer_error();
+}
diff --git a/phpBB/phpbb/composer/io/null_io.php b/phpBB/phpbb/composer/io/null_io.php
new file mode 100644
index 0000000000..9a667ca097
--- /dev/null
+++ b/phpBB/phpbb/composer/io/null_io.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\composer\io;
+
+use Composer\IO\NullIO;
+
+class null_io extends NullIO implements io_interface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function get_composer_error()
+ {
+ return '';
+ }
+}
diff --git a/phpBB/phpbb/composer/io/translate_composer_trait.php b/phpBB/phpbb/composer/io/translate_composer_trait.php
new file mode 100644
index 0000000000..444cf38e6b
--- /dev/null
+++ b/phpBB/phpbb/composer/io/translate_composer_trait.php
@@ -0,0 +1,245 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\composer\io;
+
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Trait to translate the composer Output
+ */
+trait translate_composer_trait
+{
+ /**
+ * @var \phpbb\language\language
+ */
+ protected $language;
+
+ /**
+ * @var array
+ */
+ protected $composer_error = [];
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write($messages, $newline = true, $verbosity = self::NORMAL)
+ {
+ $messages = (array) $messages;
+ $translated_messages = [];
+
+ foreach ($messages as $message)
+ {
+ $level = 0;
+ if (is_array($message))
+ {
+ $lang_key = $message[0];
+ $parameters = $message[1];
+ if (count($message) > 2)
+ {
+ $level = $message[2];
+ }
+ }
+ else
+ {
+ $lang_key = $message;
+ $parameters = [];
+ }
+
+ $message = trim($this->strip_format($lang_key), "\n\r");
+
+ if ($this->output->getVerbosity() === OutputInterface::VERBOSITY_DEBUG)
+ {
+ // Do nothing
+ }
+ else if (strpos($message, 'Deleting ') === 0)
+ {
+ $elements = explode(' ', $message);
+ $lang_key = 'COMPOSER_DELETING';
+ $parameters = [$elements[1]];
+ }
+
+ $translated_message = $this->language->lang_array($lang_key, $parameters);
+
+ switch ($level)
+ {
+ case 1:
+ $translated_message = '<info>' . $translated_message . '</info>';
+ break;
+ case 2:
+ $translated_message = '<comment>' . $translated_message . '</comment>';
+ break;
+ case 3:
+ $translated_message = '<warning>' . $translated_message . '</warning>';
+ break;
+ case 4:
+ $translated_message = '<error>' . $translated_message . '</error>';
+ break;
+ }
+
+ $translated_messages[] = $translated_message;
+ }
+
+ parent::write($translated_messages, $newline);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function writeError($messages, $newline = true, $verbosity = self::NORMAL)
+ {
+ $messages = (array) $messages;
+ $translated_messages = [];
+
+ foreach ($messages as $message)
+ {
+ $level = 0;
+ if (is_array($message))
+ {
+ $lang_key = $message[0];
+ $parameters = $message[1];
+ if (count($message) > 2)
+ {
+ $level = $message[2];
+ }
+ }
+ else
+ {
+ $lang_key = $message;
+ $parameters = [];
+ }
+
+ $message = trim($this->strip_format($lang_key), "\n\r");
+
+ if ($message === 'Your requirements could not be resolved to an installable set of packages.')
+ {
+ $this->composer_error[] = ['COMPOSER_ERROR_CONFLICT', []];
+
+ if ($this->output->getVerbosity() < OutputInterface::VERBOSITY_DEBUG)
+ {
+ continue;
+ }
+ }
+ else if (strpos($message, ' Problem ') === 0)
+ {
+ if ($this->output->getVerbosity() < OutputInterface::VERBOSITY_VERBOSE)
+ {
+ continue;
+ }
+
+ $lang_key = "\n" . htmlentities($message) . "\n";
+ $level = 4;
+ }
+ else if ($message === 'Updating dependencies')
+ {
+ $lang_key = 'COMPOSER_UPDATING_DEPENDENCIES';
+ $level = 1;
+ }
+ else if ($message === 'Loading composer repositories with package information')
+ {
+ $lang_key = 'COMPOSER_LOADING_REPOSITORIES';
+ $level = 1;
+ }
+ else if (strpos($message, 'could not be fully loaded, package information was loaded from the local cache and may be out of date') !== false)
+ {
+ $end_repo = strpos($message, 'could not be fully loaded, package information was loaded from the local cache and may be out of date');
+ $repo = substr($message, 0, $end_repo - 1);
+
+ $lang_key = 'COMPOSER_REPOSITORY_UNAVAILABLE';
+ $parameters = [$repo];
+ $level = 3;
+ }
+ else if (strpos($message, 'file could not be downloaded') !== false)
+ {
+ continue;
+ }
+ else if (strpos($message, ' - Installing ') === 0)
+ {
+ $elements = explode(' ', $message);
+ $lang_key = 'COMPOSER_INSTALLING_PACKAGE';
+ $parameters = [$elements[4], trim($elements[5], '()')];
+ }
+ else if ($message === 'Nothing to install or update')
+ {
+ $lang_key = 'COMPOSER_UPDATE_NOTHING';
+ $level = 3;
+ }
+ else if ($message === ' Downloading')
+ {
+ continue;
+ }
+ else if ($message === ' Loading from cache')
+ {
+ continue;
+ }
+ else if ($message === 'Writing lock file')
+ {
+ continue;
+ }
+ else if ($message === ' Extracting archive')
+ {
+ continue;
+ }
+ else if (empty($message))
+ {
+ continue;
+ }
+
+ $translated_message = $this->language->lang_array($lang_key, $parameters);
+
+ switch ($level)
+ {
+ case 1:
+ $translated_message = '<info>' . $translated_message . '</info>';
+ break;
+ case 2:
+ $translated_message = '<comment>' . $translated_message . '</comment>';
+ break;
+ case 3:
+ $translated_message = '<warning>' . $translated_message . '</warning>';
+ break;
+ case 4:
+ $translated_message = '<error>' . $translated_message . '</error>';
+ break;
+ }
+
+ $translated_messages[] = $translated_message;
+ }
+
+ parent::writeError($translated_messages, $newline);
+ }
+
+ public function get_composer_error()
+ {
+ $error = '';
+ foreach ($this->composer_error as $error_line)
+ {
+ $error .= $this->language->lang_array($error_line[0], $error_line[1]);
+ $error .= "\n";
+ }
+
+ $this->composer_error = [];
+
+ return $error;
+ }
+
+ protected function strip_format($message)
+ {
+ return str_replace([
+ '<info>', '</info>',
+ '<warning>', '</warning>',
+ '<comment>', '</comment>',
+ '<error>', '</error>',
+ ], '', $message);
+ }
+}
diff --git a/phpBB/phpbb/composer/io/web_io.php b/phpBB/phpbb/composer/io/web_io.php
new file mode 100644
index 0000000000..4eab3d099a
--- /dev/null
+++ b/phpBB/phpbb/composer/io/web_io.php
@@ -0,0 +1,37 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\composer\io;
+
+use Composer\IO\BufferIO;
+use phpbb\language\language;
+use Symfony\Component\Console\Formatter\OutputFormatterInterface;
+use Symfony\Component\Console\Output\StreamOutput;
+
+class web_io extends BufferIO implements io_interface
+{
+ use translate_composer_trait;
+
+ /**
+ * @param language $language Language object
+ * @param string $input Input string
+ * @param int $verbosity Verbosity level
+ * @param OutputFormatterInterface $formatter Output formatter
+ */
+ public function __construct(language $language, $input = '', $verbosity = StreamOutput::VERBOSITY_NORMAL, OutputFormatterInterface $formatter = null)
+ {
+ $this->language = $language;
+
+ parent::__construct($input, $verbosity, $formatter);
+ }
+}
diff --git a/phpBB/phpbb/composer/manager.php b/phpBB/phpbb/composer/manager.php
new file mode 100644
index 0000000000..43ea8a2503
--- /dev/null
+++ b/phpBB/phpbb/composer/manager.php
@@ -0,0 +1,332 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\composer;
+
+use Composer\IO\IOInterface;
+use phpbb\cache\driver\driver_interface;
+use phpbb\composer\exception\runtime_exception;
+
+/**
+ * Class to manage packages through composer.
+ */
+class manager implements manager_interface
+{
+ /**
+ * @var installer Composer packages installer
+ */
+ protected $installer;
+
+ /**
+ * @var driver_interface Cache instance
+ */
+ protected $cache;
+
+ /**
+ * @var string Type of packages (phpbb-packages per example)
+ */
+ protected $package_type;
+
+ /**
+ * @var string Prefix used for the exception's language string
+ */
+ protected $exception_prefix;
+
+ /**
+ * @var array Caches the managed packages list (for the current type)
+ */
+ private $managed_packages;
+
+ /**
+ * @var array Caches the managed packages list (for all phpBB types)
+ */
+ private $all_managed_packages;
+
+ /**
+ * @var array Caches the available packages list
+ */
+ private $available_packages;
+
+ /**
+ * @param installer $installer Installer object
+ * @param driver_interface $cache Cache object
+ * @param string $package_type Composer type of managed packages
+ * @param string $exception_prefix Exception prefix to use
+ */
+ public function __construct(installer $installer, driver_interface $cache, $package_type, $exception_prefix)
+ {
+ $this->installer = $installer;
+ $this->cache = $cache;
+ $this->package_type = $package_type;
+ $this->exception_prefix = $exception_prefix;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function install(array $packages, IOInterface $io = null)
+ {
+ $packages = $this->normalize_version($packages);
+
+ $already_managed = array_intersect(array_keys($this->get_managed_packages()), array_keys($packages));
+ if (count($already_managed) !== 0)
+ {
+ throw new runtime_exception($this->exception_prefix, 'ALREADY_INSTALLED', [implode('|', $already_managed)]);
+ }
+
+ $this->pre_install($packages, $io);
+
+ $managed_packages = array_merge($this->get_all_managed_packages(), $packages);
+ ksort($managed_packages);
+
+ $this->installer->install($managed_packages, array_keys($packages), $io);
+
+ $this->post_install($packages, $io);
+
+ $this->managed_packages = null;
+ }
+
+ /**
+ * Hook called before installing the packages
+ *
+ * @param array $packages Packages to update.
+ * Each entry may be a name or an array associating a version constraint to a name
+ * @param IOInterface $io IO object used for the output
+ */
+ protected function pre_install(array $packages, IOInterface $io = null)
+ {
+ }
+
+ /**
+ * Hook called after installing the packages
+ *
+ * @param array $packages Packages to update.
+ * Each entry may be a name or an array associating a version constraint to a name
+ * @param IOInterface $io IO object used for the output
+ */
+ protected function post_install(array $packages, IOInterface $io = null)
+ {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function update(array $packages, IOInterface $io = null)
+ {
+ $packages = $this->normalize_version($packages);
+
+ $not_managed = array_diff_key($packages, $this->get_managed_packages());
+ if (count($not_managed) !== 0)
+ {
+ throw new runtime_exception($this->exception_prefix, 'NOT_MANAGED', [implode('|', array_keys($not_managed))]);
+ }
+
+ $this->pre_update($packages, $io);
+
+ $managed_packages = array_merge($this->get_all_managed_packages(), $packages);
+ ksort($managed_packages);
+
+ $this->installer->install($managed_packages, array_keys($packages), $io);
+
+ $this->post_update($packages, $io);
+ }
+
+ /**
+ * Hook called before updating the packages
+ *
+ * @param array $packages Packages to update.
+ * Each entry may be a name or an array associating a version constraint to a name
+ * @param IOInterface $io IO object used for the output
+ */
+ protected function pre_update(array $packages, IOInterface $io = null)
+ {
+ }
+
+ /**
+ * Hook called after updating the packages
+ *
+ * @param array $packages Packages to update.
+ * Each entry may be a name or an array associating a version constraint to a name
+ * @param IOInterface $io IO object used for the output
+ */
+ protected function post_update(array $packages, IOInterface $io = null)
+ {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function remove(array $packages, IOInterface $io = null)
+ {
+ $packages = $this->normalize_version($packages);
+
+ $not_managed = array_diff_key($packages, $this->get_managed_packages());
+ if (count($not_managed) !== 0)
+ {
+ throw new runtime_exception($this->exception_prefix, 'NOT_MANAGED', [implode('|', array_keys($not_managed))]);
+ }
+
+ $this->pre_remove($packages, $io);
+
+ $managed_packages = array_diff_key($this->get_all_managed_packages(), $packages);
+ ksort($managed_packages);
+
+ $this->installer->install($managed_packages, array_keys($packages), $io);
+
+ $this->post_remove($packages, $io);
+
+ $this->managed_packages = null;
+ }
+
+ /**
+ * Hook called before removing the packages
+ *
+ * @param array $packages Packages to update.
+ * Each entry may be a name or an array associating a version constraint to a name
+ * @param IOInterface $io IO object used for the output
+ */
+ protected function pre_remove(array $packages, IOInterface $io = null)
+ {
+ }
+
+ /**
+ * Hook called after removing the packages
+ *
+ * @param array $packages Packages to update.
+ * Each entry may be a name or an array associating a version constraint to a name
+ * @param IOInterface $io IO object used for the output
+ */
+ protected function post_remove(array $packages, IOInterface $io = null)
+ {
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function is_managed($package)
+ {
+ return array_key_exists($package, $this->get_managed_packages());
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_managed_packages()
+ {
+ if ($this->managed_packages === null)
+ {
+ $this->managed_packages = $this->installer->get_installed_packages($this->package_type);
+ }
+
+ return $this->managed_packages;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_all_managed_packages()
+ {
+ if ($this->all_managed_packages === null)
+ {
+ $this->all_managed_packages = $this->installer->get_installed_packages(explode(',', installer::PHPBB_TYPES));
+ }
+
+ return $this->all_managed_packages;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_available_packages()
+ {
+ if ($this->available_packages === null)
+ {
+ $this->available_packages = $this->cache->get('_composer_' . $this->package_type . '_available');
+
+ if (!$this->available_packages)
+ {
+ $this->available_packages = $this->installer->get_available_packages($this->package_type);
+ $this->cache->put('_composer_' . $this->package_type . '_available', $this->available_packages, 24*60*60);
+ }
+ }
+
+ return $this->available_packages;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function reset_cache()
+ {
+ $this->cache->destroy('_composer_' . $this->package_type . '_available');
+
+ $this->available_packages = null;
+ $this->managed_packages = null;
+ $this->all_managed_packages = null;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function start_managing($package, $io)
+ {
+ throw new \phpbb\exception\runtime_exception('COMPOSER_UNSUPPORTED_OPERATION', (array) $this->package_type);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function check_requirements()
+ {
+ return $this->installer->check_requirements();
+ }
+
+ /**
+ * Normalize a packages/version array. Every entry can have 3 different forms:
+ * - $package => $version
+ * - $indice => $package:$version
+ * - $indice => $package
+ * They are converted to he form:
+ * - $package => $version ($version is set to '*' for the third form)
+ *
+ * @param array $packages
+ *
+ * @return array
+ */
+ protected function normalize_version(array $packages)
+ {
+ $normalized_packages = [];
+
+ foreach ($packages as $package => $version)
+ {
+ if (is_numeric($package))
+ {
+ if (strpos($version, ':') !== false)
+ {
+ $parts = explode(':', $version);
+ $normalized_packages[$parts[0]] = $parts[1];
+ }
+ else
+ {
+ $normalized_packages[$version] = '*';
+ }
+ }
+ else
+ {
+ $normalized_packages[$package] = $version;
+ }
+ }
+
+ return $normalized_packages;
+ }
+}
diff --git a/phpBB/phpbb/composer/manager_interface.php b/phpBB/phpbb/composer/manager_interface.php
new file mode 100644
index 0000000000..3cb401f2b6
--- /dev/null
+++ b/phpBB/phpbb/composer/manager_interface.php
@@ -0,0 +1,110 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\composer;
+
+use Composer\IO\IOInterface;
+use phpbb\composer\exception\runtime_exception;
+
+/**
+ * Class to manage packages through composer.
+ */
+interface manager_interface
+{
+ /**
+ * Installs (if necessary) a set of packages
+ *
+ * @param array $packages Packages to install.
+ * Each entry may be a name or an array associating a version constraint to a name
+ * @param IOInterface $io IO object used for the output
+ *
+ * @throws runtime_exception
+ */
+ public function install(array $packages, IOInterface $io = null);
+
+ /**
+ * Updates or installs a set of packages
+ *
+ * @param array $packages Packages to update.
+ * Each entry may be a name or an array associating a version constraint to a name
+ * @param IOInterface $io IO object used for the output
+ *
+ * @throws runtime_exception
+ */
+ public function update(array $packages, IOInterface $io = null);
+
+ /**
+ * Removes a set of packages
+ *
+ * @param array $packages Packages to remove.
+ * Each entry may be a name or an array associating a version constraint to a name
+ * @param IOInterface $io IO object used for the output
+ *
+ * @throws runtime_exception
+ */
+ public function remove(array $packages, IOInterface $io = null);
+
+ /**
+ * Tells whether or not a package is managed by Composer.
+ *
+ * @param string $packages Package name
+ *
+ * @return bool
+ */
+ public function is_managed($packages);
+
+ /**
+ * Returns the list of managed packages for the current type
+ *
+ * @return array The managed packages associated to their version.
+ */
+ public function get_managed_packages();
+
+ /**
+ * Returns the list of managed packages for all phpBB types
+ *
+ * @return array The managed packages associated to their version.
+ */
+ public function get_all_managed_packages();
+
+ /**
+ * Returns the list of available packages
+ *
+ * @return array The name of the available packages, associated to their definition. Ordered by name.
+ */
+ public function get_available_packages();
+
+ /**
+ * Reset the cache
+ */
+ public function reset_cache();
+
+ /**
+ * Start managing a manually installed package
+ *
+ * Remove a package installed manually and reinstall it using composer.
+ *
+ * @param string $package Package to manage
+ * @param IOInterface $io IO object used for the output
+ *
+ * @throws runtime_exception
+ */
+ public function start_managing($package, $io);
+
+ /**
+ * Checks the requirements of the manager and returns true if it can be used.
+ *
+ * @return bool
+ */
+ public function check_requirements();
+}
diff --git a/phpBB/phpbb/console/command/extension/install.php b/phpBB/phpbb/console/command/extension/install.php
new file mode 100644
index 0000000000..bbed53be30
--- /dev/null
+++ b/phpBB/phpbb/console/command/extension/install.php
@@ -0,0 +1,103 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\console\command\extension;
+
+use phpbb\composer\extension_manager;
+use phpbb\composer\io\console_io;
+use phpbb\language\language;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+
+class install extends \phpbb\console\command\command
+{
+ /**
+ * @var extension_manager Composer extensions manager
+ */
+ protected $manager;
+
+ /**
+ * @var \phpbb\language\language
+ */
+ protected $language;
+
+ public function __construct(\phpbb\user $user, extension_manager $manager, language $language)
+ {
+ $this->manager = $manager;
+ $this->language = $language;
+
+ $language->add_lang('acp/extensions');
+
+ parent::__construct($user);
+ }
+
+ /**
+ * Sets the command name and description
+ *
+ * @return null
+ */
+ protected function configure()
+ {
+ $this
+ ->setName('extension:install')
+ ->setDescription($this->language->lang('CLI_DESCRIPTION_EXTENSION_INSTALL'))
+ ->addOption(
+ 'enable',
+ null,
+ InputOption::VALUE_NONE,
+ $this->language->lang('CLI_DESCRIPTION_EXTENSION_INSTALL_OPTION_ENABLE'))
+ ->addArgument(
+ 'extensions',
+ InputArgument::IS_ARRAY | InputArgument::REQUIRED,
+ $this->language->lang('CLI_DESCRIPTION_EXTENSION_INSTALL_ARGUMENT'))
+ ;
+ }
+
+ /**
+ * Executes the command extension:install
+ *
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return integer
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $output->getFormatter()->setStyle('warning', new OutputFormatterStyle('black', 'yellow'));
+
+ $io = new SymfonyStyle($input, $output);
+
+ if (!$this->manager->check_requirements())
+ {
+ $io->error($this->language->lang('EXTENSIONS_COMPOSER_NOT_WRITABLE'));
+ return 1;
+ }
+
+ $composer_io = new console_io($input, $output, $this->getHelperSet(), $this->language);
+ $extensions = $input->getArgument('extensions');
+
+ if ($input->getOption('enable'))
+ {
+ $this->manager->set_enable_on_install(true);
+ }
+
+ $this->manager->install($extensions, $composer_io);
+
+ $io->success($this->language->lang('EXTENSIONS_INSTALLED'));
+
+ return 0;
+ }
+}
diff --git a/phpBB/phpbb/console/command/extension/list_available.php b/phpBB/phpbb/console/command/extension/list_available.php
new file mode 100644
index 0000000000..7f9efe6771
--- /dev/null
+++ b/phpBB/phpbb/console/command/extension/list_available.php
@@ -0,0 +1,73 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\console\command\extension;
+
+use phpbb\composer\manager_interface;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+
+class list_available extends \phpbb\console\command\command
+{
+ /**
+ * @var manager_interface Composer extensions manager
+ */
+ protected $manager;
+
+ public function __construct(\phpbb\user $user, manager_interface $manager)
+ {
+ $this->manager = $manager;
+
+ $user->add_lang('acp/extensions');
+
+ parent::__construct($user);
+ }
+
+ /**
+ * Sets the command name and description
+ *
+ * @return null
+ */
+ protected function configure()
+ {
+ $this
+ ->setName('extension:list-available')
+ ->setDescription($this->user->lang('CLI_DESCRIPTION_EXTENSION_LIST_AVAILABLE'))
+ ;
+ }
+
+ /**
+ * Executes the command extension:install
+ *
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return integer
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $io = new SymfonyStyle($input, $output);
+
+ $extensions = [];
+
+ foreach ($this->manager->get_available_packages() as $package)
+ {
+ $extensions[] = '<info>' . $package['name'] . '</info> (<comment>' . $package['version'] . '</comment>) ' . $package['url'] .
+ ($package['description'] ? "\n" . $package['description'] : '');
+ }
+
+ $io->listing($extensions);
+
+ return 0;
+ }
+}
diff --git a/phpBB/phpbb/console/command/extension/manage.php b/phpBB/phpbb/console/command/extension/manage.php
new file mode 100644
index 0000000000..cd8bbc1a7d
--- /dev/null
+++ b/phpBB/phpbb/console/command/extension/manage.php
@@ -0,0 +1,99 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\console\command\extension;
+
+use phpbb\composer\exception\managed_with_error_exception;
+use phpbb\composer\io\console_io;
+use phpbb\composer\manager_interface;
+use phpbb\language\language;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+
+class manage extends \phpbb\console\command\command
+{
+ /**
+ * @var manager_interface Composer extensions manager
+ */
+ protected $manager;
+
+ /**
+ * @var \phpbb\language\language
+ */
+ protected $language;
+
+ public function __construct(\phpbb\user $user, manager_interface $manager, language $language)
+ {
+ $this->manager = $manager;
+ $this->language = $language;
+
+ $language->add_lang('acp/extensions');
+
+ parent::__construct($user);
+ }
+
+ /**
+ * Sets the command name and description
+ *
+ * @return null
+ */
+ protected function configure()
+ {
+ $this
+ ->setName('extension:manage')
+ ->setDescription($this->language->lang('CLI_DESCRIPTION_EXTENSION_MANAGE'))
+ ->addArgument(
+ 'extension',
+ InputArgument::REQUIRED,
+ $this->language->lang('CLI_DESCRIPTION_EXTENSION_MANAGE_ARGUMENT'))
+ ;
+ }
+
+ /**
+ * Executes the command extension:install
+ *
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return integer
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $io = new SymfonyStyle($input, $output);
+
+ if (!$this->manager->check_requirements())
+ {
+ $io->error($this->language->lang('EXTENSIONS_COMPOSER_NOT_WRITABLE'));
+ return 1;
+ }
+
+ $composer_io = new console_io($input, $output, $this->getHelperSet(), $this->language);
+
+ $extension = $input->getArgument('extension');
+
+ try
+ {
+ $this->manager->start_managing($extension, $composer_io);
+ }
+ catch (managed_with_error_exception $e)
+ {
+ $io->warning($this->language->lang_array($e->getMessage(), $e->get_parameters()));
+ return 1;
+ }
+
+ $io->success($this->language->lang('EXTENSION_MANAGED_SUCCESS', $extension));
+
+ return 0;
+ }
+}
diff --git a/phpBB/phpbb/console/command/extension/remove.php b/phpBB/phpbb/console/command/extension/remove.php
new file mode 100644
index 0000000000..69d2a62dd9
--- /dev/null
+++ b/phpBB/phpbb/console/command/extension/remove.php
@@ -0,0 +1,103 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\console\command\extension;
+
+use phpbb\composer\extension_manager;
+use phpbb\composer\io\console_io;
+use phpbb\language\language;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+
+class remove extends \phpbb\console\command\command
+{
+ /**
+ * @var extension_manager Composer extensions manager
+ */
+ protected $manager;
+
+ /**
+ * @var \phpbb\language\language
+ */
+ protected $language;
+
+ public function __construct(\phpbb\user $user, extension_manager $manager, language $language)
+ {
+ $this->manager = $manager;
+ $this->language = $language;
+
+ $language->add_lang('acp/extensions');
+
+ parent::__construct($user);
+ }
+
+ /**
+ * Sets the command name and description
+ *
+ * @return null
+ */
+ protected function configure()
+ {
+ $this
+ ->setName('extension:remove')
+ ->setDescription($this->language->lang('CLI_DESCRIPTION_EXTENSION_REMOVE'))
+ ->addOption(
+ 'purge',
+ null,
+ InputOption::VALUE_NONE,
+ $this->language->lang('CLI_DESCRIPTION_EXTENSION_REMOVE_OPTION_PURGE'))
+ ->addArgument(
+ 'extensions',
+ InputArgument::IS_ARRAY | InputArgument::REQUIRED,
+ $this->language->lang('CLI_DESCRIPTION_EXTENSION_REMOVE_ARGUMENT'))
+ ;
+ }
+
+ /**
+ * Executes the command extension:install
+ *
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return integer
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $output->getFormatter()->setStyle('warning', new OutputFormatterStyle('black', 'yellow'));
+
+ $io = new SymfonyStyle($input, $output);
+
+ if (!$this->manager->check_requirements())
+ {
+ $io->error($this->language->lang('EXTENSIONS_COMPOSER_NOT_WRITABLE'));
+ return 1;
+ }
+
+ $composer_io = new console_io($input, $output, $this->getHelperSet(), $this->language);
+ $extensions = $input->getArgument('extensions');
+
+ if ($input->getOption('purge'))
+ {
+ $this->manager->set_purge_on_remove(true);
+ }
+
+ $this->manager->remove($extensions, $composer_io);
+
+ $io->success($this->language->lang('EXTENSIONS_REMOVED'));
+
+ return 0;
+ }
+}
diff --git a/phpBB/phpbb/console/command/extension/update.php b/phpBB/phpbb/console/command/extension/update.php
new file mode 100644
index 0000000000..f1479c8b0d
--- /dev/null
+++ b/phpBB/phpbb/console/command/extension/update.php
@@ -0,0 +1,90 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\console\command\extension;
+
+use phpbb\composer\io\console_io;
+use phpbb\composer\manager_interface;
+use phpbb\language\language;
+use Symfony\Component\Console\Formatter\OutputFormatterStyle;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+use Symfony\Component\Console\Style\SymfonyStyle;
+
+class update extends \phpbb\console\command\command
+{
+ /**
+ * @var manager_interface Composer extensions manager
+ */
+ protected $manager;
+
+ /**
+ * @var \phpbb\language\language
+ */
+ protected $language;
+
+ public function __construct(\phpbb\user $user, manager_interface $manager, language $language)
+ {
+ $this->manager = $manager;
+ $this->language = $language;
+
+ parent::__construct($user);
+ }
+
+ /**
+ * Sets the command name and description
+ *
+ * @return null
+ */
+ protected function configure()
+ {
+ $this
+ ->setName('extension:update')
+ ->setDescription($this->user->lang('CLI_DESCRIPTION_EXTENSION_UPDATE'))
+ ->addArgument(
+ 'extensions',
+ InputArgument::IS_ARRAY | InputArgument::REQUIRED,
+ $this->user->lang('CLI_DESCRIPTION_EXTENSION_UPDATE_ARGUMENT'))
+ ;
+ }
+
+ /**
+ * Executes the command extension:install
+ *
+ * @param InputInterface $input
+ * @param OutputInterface $output
+ * @return integer
+ */
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $output->getFormatter()->setStyle('warning', new OutputFormatterStyle('black', 'yellow'));
+
+ $io = new SymfonyStyle($input, $output);
+
+ if (!$this->manager->check_requirements())
+ {
+ $io->error($this->language->lang('EXTENSIONS_COMPOSER_NOT_WRITABLE'));
+ return 1;
+ }
+
+ $composer_io = new console_io($input, $output, $this->getHelperSet(), $this->language);
+ $extensions = $input->getArgument('extensions');
+
+ $this->manager->update($extensions, $composer_io);
+
+ $io->success($this->language->lang('EXTENSIONS_UPDATED'));
+
+ return 0;
+ }
+}
diff --git a/phpBB/phpbb/db/extractor/base_extractor.php b/phpBB/phpbb/db/extractor/base_extractor.php
index 547c85f066..106e047eaa 100644
--- a/phpBB/phpbb/db/extractor/base_extractor.php
+++ b/phpBB/phpbb/db/extractor/base_extractor.php
@@ -22,9 +22,9 @@ use phpbb\db\extractor\exception\extractor_not_initialized_exception;
abstract class base_extractor implements extractor_interface
{
/**
- * @var string phpBB root path
+ * @var \phpbb\filesystem\temp
*/
- protected $phpbb_root_path;
+ protected $temp;
/**
* @var \phpbb\request\request_interface
@@ -84,13 +84,13 @@ abstract class base_extractor implements extractor_interface
/**
* Constructor
*
- * @param string $phpbb_root_path
+ * @param \phpbb\filesystem\temp $temp
* @param \phpbb\request\request_interface $request
* @param \phpbb\db\driver\driver_interface $db
*/
- public function __construct($phpbb_root_path, \phpbb\request\request_interface $request, \phpbb\db\driver\driver_interface $db)
+ public function __construct(\phpbb\filesystem\temp $temp, \phpbb\request\request_interface $request, \phpbb\db\driver\driver_interface $db)
{
- $this->phpbb_root_path = $phpbb_root_path;
+ $this->temp = $temp;
$this->request = $request;
$this->db = $db;
$this->fp = null;
@@ -164,13 +164,13 @@ abstract class base_extractor implements extractor_interface
if ($store === true)
{
- $file = $this->phpbb_root_path . 'store/' . $filename . $ext;
+ $file = $this->temp->get_dir() . '/' . $filename . $ext;
$this->fp = $open($file, 'w');
if (!$this->fp)
{
- trigger_error('FILE_WRITE_FAIL', E_USER_ERROR);
+ throw new \phpbb\exception\runtime_exception('FILE_WRITE_FAIL');
}
}
diff --git a/phpBB/phpbb/db/migration/data/v400/acp_storage_module.php b/phpBB/phpbb/db/migration/data/v400/acp_storage_module.php
new file mode 100644
index 0000000000..7177a6a0ee
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v400/acp_storage_module.php
@@ -0,0 +1,55 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v400;
+
+use phpbb\db\migration\migration;
+
+class acp_storage_module extends migration
+{
+ public function effectively_installed()
+ {
+ $sql = 'SELECT module_id
+ FROM ' . $this->tables['modules'] . "
+ WHERE module_class = 'acp'
+ AND module_langname = 'ACP_STORAGE_SETTINGS'";
+ $result = $this->db->sql_query($sql);
+ $acp_storage_module_id = (int) $this->db->sql_fetchfield('module_id');
+ $this->db->sql_freeresult($result);
+
+ return !empty($acp_storage_module_id);
+ }
+
+ static public function depends_on()
+ {
+ return [
+ '\phpbb\db\migration\data\v400\dev',
+ ];
+ }
+
+ public function update_data()
+ {
+ return [
+ ['module.add', [
+ 'acp',
+ 'ACP_SERVER_CONFIGURATION',
+ [
+ 'module_basename' => 'acp_storage',
+ 'module_langname' => 'ACP_STORAGE_SETTINGS',
+ 'module_mode' => 'settings',
+ 'module_auth' => 'acl_a_storage',
+ ],
+ ]],
+ ];
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v400/add_storage_permission.php b/phpBB/phpbb/db/migration/data/v400/add_storage_permission.php
new file mode 100644
index 0000000000..de7b1786d8
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v400/add_storage_permission.php
@@ -0,0 +1,49 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v400;
+
+use phpbb\db\migration\migration;
+
+class add_storage_permission extends migration
+{
+ public function effectively_installed()
+ {
+ $sql = 'SELECT auth_option_id
+ FROM ' . $this->tables['acl_options'] . "
+ WHERE auth_option = 'a_storage'";
+ $result = $this->db->sql_query($sql);
+ $a_storage_option_id = (int) $this->db->sql_fetchfield('auth_option_id');
+ $this->db->sql_freeresult($result);
+
+ return !empty($a_storage_option_id);
+ }
+
+ static public function depends_on()
+ {
+ return [
+ '\phpbb\db\migration\data\v400\dev',
+ ];
+ }
+
+ public function update_data()
+ {
+ return [
+ // Add permission
+ ['permission.add', ['a_storage']],
+
+ // Set permissions
+ ['permission.permission_set', ['ROLE_ADMIN_FULL', 'a_storage']],
+ ];
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v400/dev.php b/phpBB/phpbb/db/migration/data/v400/dev.php
new file mode 100644
index 0000000000..b47525384a
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v400/dev.php
@@ -0,0 +1,36 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v400;
+
+use phpbb\db\migration\migration;
+
+class dev extends migration
+{
+ public function effectively_installed()
+ {
+ return version_compare($this->config['version'], '4.0.0-dev', '>=');
+ }
+
+ static public function depends_on()
+ {
+ return ['\phpbb\db\migration\data\v330\v330rc1'];
+ }
+
+ public function update_data()
+ {
+ return [
+ ['config.update', ['version', '4.0.0-dev']],
+ ];
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v400/extensions_composer.php b/phpBB/phpbb/db/migration/data/v400/extensions_composer.php
new file mode 100644
index 0000000000..fce3847972
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v400/extensions_composer.php
@@ -0,0 +1,53 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v400;
+
+use phpbb\db\migration\migration;
+
+class extensions_composer extends migration
+{
+ public function effectively_installed()
+ {
+ return $this->config->offsetExists('exts_composer_repositories');
+ }
+
+ static public function depends_on()
+ {
+ return [
+ '\phpbb\db\migration\data\v400\dev',
+ ];
+ }
+
+ public function update_data()
+ {
+ return [
+ ['config.add', ['exts_composer_repositories', json_encode([
+ 'https://www.phpbb.com/customise/db/composer/',
+ ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)]],
+ ['config.add', ['exts_composer_packagist', false]],
+ ['config.add', ['exts_composer_json_file', 'composer-ext.json']],
+ ['config.add', ['exts_composer_vendor_dir', 'vendor-ext/']],
+ ['config.add', ['exts_composer_enable_on_install', false]],
+ ['config.add', ['exts_composer_purge_on_remove', true]],
+ ['module.add', [
+ 'acp',
+ 'ACP_EXTENSION_MANAGEMENT',
+ [
+ 'module_basename' => 'acp_extensions',
+ 'modes' => ['catalog'],
+ ],
+ ]],
+ ];
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v400/extensions_composer_2.php b/phpBB/phpbb/db/migration/data/v400/extensions_composer_2.php
new file mode 100644
index 0000000000..d72e2145e3
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v400/extensions_composer_2.php
@@ -0,0 +1,40 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v400;
+
+use phpbb\db\migration\migration;
+
+class extensions_composer_2 extends migration
+{
+ public function effectively_installed()
+ {
+ return strpos($this->config['exts_composer_repositories'], 'https://satis.phpbb.com') !== false;
+ }
+
+ public function update_data()
+ {
+ $repositories = json_decode($this->config['exts_composer_repositories'], true);
+ $repositories[] = 'https://satis.phpbb.com';
+ $repositories = array_unique($repositories);
+
+ return [
+ ['config.update', ['exts_composer_repositories', json_encode($repositories, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)]],
+ ];
+ }
+
+ static public function depends_on()
+ {
+ return ['\phpbb\db\migration\data\v400\extensions_composer'];
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v400/remove_attachment_download_mode.php b/phpBB/phpbb/db/migration/data/v400/remove_attachment_download_mode.php
new file mode 100644
index 0000000000..59ac1b7be0
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v400/remove_attachment_download_mode.php
@@ -0,0 +1,53 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v400;
+
+use phpbb\db\migration\migration;
+
+class remove_attachment_download_mode extends migration
+{
+ public function effectively_installed()
+ {
+ return !$this->db_tools->sql_column_exists($this->tables['extension_groups'], 'download_mode');
+ }
+
+ static public function depends_on()
+ {
+ return [
+ '\phpbb\db\migration\data\v400\dev',
+ ];
+ }
+
+ public function update_schema()
+ {
+ return [
+ 'drop_columns' => [
+ $this->table_prefix . 'extension_groups' => [
+ 'download_mode',
+ ],
+ ],
+ ];
+ }
+
+ public function revert_schema()
+ {
+ return [
+ 'add_columns' => [
+ $this->table_prefix . 'extension_groups' => [
+ 'download_mode' => ['BOOL', '1'],
+ ],
+ ],
+ ];
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v400/storage_adapter_local_subfolders.php b/phpBB/phpbb/db/migration/data/v400/storage_adapter_local_subfolders.php
new file mode 100644
index 0000000000..3c4e5e3a0f
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v400/storage_adapter_local_subfolders.php
@@ -0,0 +1,54 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v400;
+
+use phpbb\db\migration\migration;
+use phpbb\storage\provider\local;
+
+class storage_adapter_local_subfolders extends migration
+{
+ public function effectively_installed()
+ {
+ return $this->config->offsetExists('storage\\attachment\\config\\subfolders') ||
+ $this->config->offsetExists('storage\\avatar\\config\\subfolders') ||
+ $this->config->offsetExists('storage\\backup\\config\\subfolders');
+ }
+
+ static public function depends_on()
+ {
+ return [
+ '\phpbb\db\migration\data\v400\storage_attachment',
+ '\phpbb\db\migration\data\v400\storage_avatar',
+ '\phpbb\db\migration\data\v400\storage_backup',
+ ];
+ }
+
+ public function update_data()
+ {
+ return [
+ ['if', [
+ ($this->config['storage\\attachment\\provider'] == local::class),
+ ['config.add', ['storage\\attachment\\config\\subfolders', '0']],
+ ]],
+ ['if', [
+ ($this->config['storage\\avatar\\provider'] == local::class),
+ ['config.add', ['storage\\avatar\\config\\subfolders', '0']],
+ ]],
+ ['if', [
+ ($this->config['storage\\backup\\provider'] == local::class),
+ ['config.add', ['storage\\backup\\config\\subfolders', '0']],
+ ]],
+ ];
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v400/storage_attachment.php b/phpBB/phpbb/db/migration/data/v400/storage_attachment.php
new file mode 100644
index 0000000000..7d091ac093
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v400/storage_attachment.php
@@ -0,0 +1,41 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v400;
+
+use phpbb\db\migration\migration;
+use phpbb\storage\provider\local;
+
+class storage_attachment extends migration
+{
+ public function effectively_installed()
+ {
+ return $this->config->offsetExists('storage\\attachment\\provider');
+ }
+
+ static public function depends_on()
+ {
+ return [
+ '\phpbb\db\migration\data\v400\dev',
+ ];
+ }
+
+ public function update_data()
+ {
+ return [
+ ['config.add', ['storage\\attachment\\provider', local::class]],
+ ['config.add', ['storage\\attachment\\config\\path', $this->config['upload_path']]],
+ ['config.remove', ['upload_path']],
+ ];
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v400/storage_avatar.php b/phpBB/phpbb/db/migration/data/v400/storage_avatar.php
new file mode 100644
index 0000000000..cbb93b4775
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v400/storage_avatar.php
@@ -0,0 +1,41 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v400;
+
+use phpbb\db\migration\migration;
+use phpbb\storage\provider\local;
+
+class storage_avatar extends migration
+{
+ public function effectively_installed()
+ {
+ return $this->config->offsetExists('storage\\avatar\\provider');
+ }
+
+ static public function depends_on()
+ {
+ return [
+ '\phpbb\db\migration\data\v400\dev',
+ ];
+ }
+
+ public function update_data()
+ {
+ return [
+ ['config.add', ['storage\\avatar\\provider', local::class]],
+ ['config.add', ['storage\\avatar\\config\\path', $this->config['avatar_path']]],
+ ['config.remove', ['avatar_path']],
+ ];
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v400/storage_backup.php b/phpBB/phpbb/db/migration/data/v400/storage_backup.php
new file mode 100644
index 0000000000..3677620508
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v400/storage_backup.php
@@ -0,0 +1,55 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v400;
+
+use phpbb\db\migration\migration;
+use phpbb\storage\provider\local;
+
+class storage_backup extends migration
+{
+ public function effectively_installed()
+ {
+ return $this->db_tools->sql_table_exists($this->tables['backups']);
+ }
+
+ static public function depends_on()
+ {
+ return [
+ '\phpbb\db\migration\data\v400\dev',
+ ];
+ }
+
+ public function update_schema()
+ {
+ return [
+ 'add_tables' => [
+ $this->table_prefix . 'backups' => [
+ 'COLUMNS' => [
+ 'backup_id' => ['UINT', null, 'auto_increment'],
+ 'filename' => ['VCHAR', ''],
+ ],
+ 'PRIMARY_KEY' => 'backup_id',
+ ],
+ ],
+ ];
+ }
+
+ public function update_data()
+ {
+ return [
+ ['config.add', ['storage\\backup\\provider', local::class]],
+ ['config.add', ['storage\\backup\\config\\path', 'store']],
+ ];
+ }
+}
diff --git a/phpBB/phpbb/db/migration/data/v400/storage_track.php b/phpBB/phpbb/db/migration/data/v400/storage_track.php
new file mode 100644
index 0000000000..a4aec87fb2
--- /dev/null
+++ b/phpBB/phpbb/db/migration/data/v400/storage_track.php
@@ -0,0 +1,168 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+namespace phpbb\db\migration\data\v400;
+
+use phpbb\db\migration\container_aware_migration;
+use phpbb\storage\exception\exception;
+use phpbb\storage\storage;
+
+class storage_track extends container_aware_migration
+{
+ public function effectively_installed()
+ {
+ return $this->db_tools->sql_table_exists($this->tables['storage']);
+ }
+
+ static public function depends_on()
+ {
+ return [
+ '\phpbb\db\migration\data\v400\storage_attachment',
+ '\phpbb\db\migration\data\v400\storage_avatar',
+ '\phpbb\db\migration\data\v400\storage_backup',
+ ];
+ }
+
+ public function update_schema()
+ {
+ return [
+ 'add_tables' => [
+ $this->table_prefix . 'storage' => [
+ 'COLUMNS' => [
+ 'file_id' => ['UINT', null, 'auto_increment'],
+ 'file_path' => ['VCHAR', ''],
+ 'storage' => ['VCHAR', ''],
+ 'filesize' => ['UINT:20', 0],
+ ],
+ 'PRIMARY_KEY' => 'file_id',
+ ],
+ ],
+ ];
+ }
+
+ public function revert_schema()
+ {
+ return [
+ 'drop_tables' => [
+ $this->table_prefix . 'storage',
+ ],
+ ];
+ }
+
+ public function update_data()
+ {
+ return [
+ ['custom', [[$this, 'track_avatars']]],
+ ['custom', [[$this, 'track_attachments']]],
+ ['custom', [[$this, 'track_backups']]],
+ ];
+ }
+
+ public function track_avatars()
+ {
+ /** @var storage $storage */
+ $storage = $this->container->get('storage.avatar');
+
+ $sql = 'SELECT user_avatar
+ FROM ' . USERS_TABLE . "
+ WHERE user_avatar_type = 'avatar.driver.upload'";
+
+ $result = $this->db->sql_query($sql);
+
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ $avatar_group = false;
+ $filename = $row['user_avatar'];
+
+ if (isset($filename[0]) && $filename[0] === 'g')
+ {
+ $avatar_group = true;
+ $filename = substr($filename, 1);
+ }
+
+ $ext = substr(strrchr($filename, '.'), 1);
+ $filename = (int) $filename;
+
+ try
+ {
+ $storage->track_file($this->config['avatar_salt'] . '_' . ($avatar_group ? 'g' : '') . $filename . '.' . $ext);
+ }
+ catch (exception $e)
+ {
+ // If file doesn't exist, don't track it
+ }
+ }
+ $this->db->sql_freeresult($result);
+ }
+
+ public function track_attachments()
+ {
+ /** @var storage $storage */
+ $storage = $this->container->get('storage.attachment');
+
+ $sql = 'SELECT physical_filename, thumbnail
+ FROM ' . ATTACHMENTS_TABLE;
+
+ $result = $this->db->sql_query($sql);
+
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ try
+ {
+ $storage->track_file($row['physical_filename']);
+ }
+ catch (exception $e)
+ {
+ // If file doesn't exist, don't track it
+ }
+
+ if ($row['thumbnail'] == 1)
+ {
+ try
+ {
+ $storage->track_file('thumb_' . $row['physical_filename']);
+ }
+ catch (exception $e)
+ {
+ // If file doesn't exist, don't track it
+ }
+ }
+ }
+ $this->db->sql_freeresult($result);
+ }
+
+ public function track_backups()
+ {
+ /** @var storage $storage */
+ $storage = $this->container->get('storage.backup');
+
+ $sql = 'SELECT filename
+ FROM ' . BACKUPS_TABLE;
+
+ $result = $this->db->sql_query($sql);
+
+ while ($row = $this->db->sql_fetchrow($result))
+ {
+ try
+ {
+ $storage->track_file($row['filename']);
+ }
+ catch (exception $e)
+ {
+ // If file doesn't exist, don't track it
+ }
+ }
+
+ $this->db->sql_freeresult($result);
+ }
+}
diff --git a/phpBB/phpbb/db/migration/migration.php b/phpBB/phpbb/db/migration/migration.php
index 4e218344f4..c94ac29407 100644
--- a/phpBB/phpbb/db/migration/migration.php
+++ b/phpBB/phpbb/db/migration/migration.php
@@ -34,6 +34,9 @@ abstract class migration implements migration_interface
/** @var string */
protected $table_prefix;
+ /** @var array Tables array */
+ protected $tables;
+
/** @var string */
protected $phpbb_root_path;
@@ -55,13 +58,15 @@ abstract class migration implements migration_interface
* @param string $phpbb_root_path
* @param string $php_ext
* @param string $table_prefix
+ * @param array $tables
*/
- public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools\tools_interface $db_tools, $phpbb_root_path, $php_ext, $table_prefix)
+ public function __construct(\phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools\tools_interface $db_tools, $phpbb_root_path, $php_ext, $table_prefix, $tables)
{
$this->config = $config;
$this->db = $db;
$this->db_tools = $db_tools;
$this->table_prefix = $table_prefix;
+ $this->tables = $tables;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
diff --git a/phpBB/phpbb/db/migration/schema_generator.php b/phpBB/phpbb/db/migration/schema_generator.php
index c579e25824..0d1f6e33b1 100644
--- a/phpBB/phpbb/db/migration/schema_generator.php
+++ b/phpBB/phpbb/db/migration/schema_generator.php
@@ -43,12 +43,23 @@ class schema_generator
protected $tables;
/** @var array */
+ protected $table_names;
+
+ /** @var array */
protected $dependencies = array();
/**
- * Constructor
- */
- public function __construct(array $class_names, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools\tools_interface $db_tools, $phpbb_root_path, $php_ext, $table_prefix)
+ * Constructor
+ * @param array $class_names
+ * @param \phpbb\config\config $config
+ * @param \phpbb\db\driver\driver_interface $db
+ * @param \phpbb\db\tools\tools_interface $db_tools
+ * @param string $phpbb_root_path
+ * @param string $php_ext
+ * @param string $table_prefix
+ * @param array $tables
+ */
+ public function __construct(array $class_names, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools\tools_interface $db_tools, $phpbb_root_path, $php_ext, $table_prefix, $tables)
{
$this->config = $config;
$this->db = $db;
@@ -57,6 +68,7 @@ class schema_generator
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
$this->table_prefix = $table_prefix;
+ $this->table_names = $tables;
}
/**
@@ -90,7 +102,7 @@ class schema_generator
if (empty($open_dependencies))
{
- $migration = new $migration_class($this->config, $this->db, $this->db_tools, $this->phpbb_root_path, $this->php_ext, $this->table_prefix);
+ $migration = new $migration_class($this->config, $this->db, $this->db_tools, $this->phpbb_root_path, $this->php_ext, $this->table_prefix, $this->table_names);
$tree[] = $migration_class;
$migration_key = array_search($migration_class, $migrations);
diff --git a/phpBB/phpbb/db/migrator.php b/phpBB/phpbb/db/migrator.php
index 3a1ee758cf..e93b96ad28 100644
--- a/phpBB/phpbb/db/migrator.php
+++ b/phpBB/phpbb/db/migrator.php
@@ -13,8 +13,12 @@
namespace phpbb\db;
+use phpbb\config\config;
+use phpbb\db\driver\driver_interface;
+use phpbb\db\migration\helper;
use phpbb\db\output_handler\migrator_output_handler_interface;
use phpbb\db\output_handler\null_migrator_output_handler;
+use phpbb\db\tools\tools_interface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -28,21 +32,24 @@ class migrator
*/
protected $container;
- /** @var \phpbb\config\config */
+ /** @var config */
protected $config;
- /** @var \phpbb\db\driver\driver_interface */
+ /** @var driver_interface */
protected $db;
- /** @var \phpbb\db\tools\tools_interface */
+ /** @var tools_interface */
protected $db_tools;
- /** @var \phpbb\db\migration\helper */
+ /** @var helper */
protected $helper;
/** @var string */
protected $table_prefix;
+ /** @var array */
+ protected $tables;
+
/** @var string */
protected $phpbb_root_path;
@@ -92,9 +99,20 @@ class migrator
protected $output_handler;
/**
- * Constructor of the database migrator
- */
- public function __construct(ContainerInterface $container, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\db\tools\tools_interface $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tools, \phpbb\db\migration\helper $helper)
+ * Constructor of the database migrator
+ * @param ContainerInterface $container
+ * @param config $config
+ * @param driver\driver_interface $db
+ * @param tools\tools_interface $db_tools
+ * @param $migrations_table
+ * @param $phpbb_root_path
+ * @param $php_ext
+ * @param $table_prefix
+ * @param $tables
+ * @param $tools
+ * @param migration\helper $helper
+ */
+ public function __construct(ContainerInterface $container, config $config, driver_interface $db, tools_interface $db_tools, $migrations_table, $phpbb_root_path, $php_ext, $table_prefix, $tables, $tools, helper $helper)
{
$this->container = $container;
$this->config = $config;
@@ -108,6 +126,7 @@ class migrator
$this->php_ext = $php_ext;
$this->table_prefix = $table_prefix;
+ $this->tables = $tables;
$this->output_handler = new null_migrator_output_handler();
@@ -950,7 +969,7 @@ class migrator
*/
protected function get_migration($name)
{
- $migration = new $name($this->config, $this->db, $this->db_tools, $this->phpbb_root_path, $this->php_ext, $this->table_prefix);
+ $migration = new $name($this->config, $this->db, $this->db_tools, $this->phpbb_root_path, $this->php_ext, $this->table_prefix, $this->tables);
if ($migration instanceof ContainerAwareInterface)
{
diff --git a/phpBB/phpbb/di/container_builder.php b/phpBB/phpbb/di/container_builder.php
index 70ceb9b5e3..e4b6d8730e 100644
--- a/phpBB/phpbb/di/container_builder.php
+++ b/phpBB/phpbb/di/container_builder.php
@@ -13,7 +13,6 @@
namespace phpbb\di;
-use phpbb\filesystem\filesystem;
use Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper;
use Symfony\Component\Config\ConfigCache;
use Symfony\Component\Config\FileLocator;
@@ -25,6 +24,7 @@ use Symfony\Component\EventDispatcher\DependencyInjection\RegisterListenersPass;
use Symfony\Component\Filesystem\Exception\IOException;
use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpKernel\DependencyInjection\MergeExtensionConfigurationPass;
+use phpbb\filesystem\helper as filesystem_helper;
class container_builder
{
@@ -192,8 +192,7 @@ class container_builder
$this->register_ext_compiler_pass();
}
- $filesystem = new filesystem();
- $loader = new YamlFileLoader($this->container, new FileLocator($filesystem->realpath($this->get_config_path())));
+ $loader = new YamlFileLoader($this->container, new FileLocator(filesystem_helper::realpath($this->get_config_path())));
$loader->load($this->container->getParameter('core.environment') . '/config.yml');
$this->inject_custom_parameters();
@@ -427,6 +426,12 @@ class container_builder
$ext_container->register('cache.driver', '\\phpbb\\cache\\driver\\dummy');
$ext_container->compile();
+ $config = $ext_container->get('config');
+ if (@is_file($this->phpbb_root_path . $config['exts_composer_vendor_dir'] . '/autoload.php'))
+ {
+ require_once($this->phpbb_root_path . $config['exts_composer_vendor_dir'] . '/autoload.php');
+ }
+
$extensions = $ext_container->get('ext.manager')->all_enabled();
// Load each extension found
diff --git a/phpBB/phpbb/di/extension/container_configuration.php b/phpBB/phpbb/di/extension/container_configuration.php
index 57e7ef6ca6..a1e0a4c297 100644
--- a/phpBB/phpbb/di/extension/container_configuration.php
+++ b/phpBB/phpbb/di/extension/container_configuration.php
@@ -50,6 +50,13 @@ class container_configuration implements ConfigurationInterface
->booleanNode('enable_debug_extension')->defaultValue(false)->end()
->end()
->end()
+ ->arrayNode('extensions')
+ ->addDefaultsIfNotSet()
+ ->children()
+ ->booleanNode('composer_debug')->defaultValue(false)->end()
+ ->booleanNode('composer_verbose')->defaultValue(false)->end()
+ ->end()
+ ->end()
->arrayNode('session')
->addDefaultsIfNotSet()
->children()
diff --git a/phpBB/phpbb/di/extension/core.php b/phpBB/phpbb/di/extension/core.php
index 0497c90e2a..65848cdadf 100644
--- a/phpBB/phpbb/di/extension/core.php
+++ b/phpBB/phpbb/di/extension/core.php
@@ -15,9 +15,11 @@ namespace phpbb\di\extension;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Resource\FileResource;
+use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
+use phpbb\filesystem\helper as filesystem_helper;
/**
* Container core extension
@@ -52,8 +54,7 @@ class core extends Extension
*/
public function load(array $configs, ContainerBuilder $container)
{
- $filesystem = new \phpbb\filesystem\filesystem();
- $loader = new YamlFileLoader($container, new FileLocator($filesystem->realpath($this->config_path)));
+ $loader = new YamlFileLoader($container, new FileLocator(filesystem_helper::realpath($this->config_path)));
$loader->load($container->getParameter('core.environment') . '/container/environment.yml');
$config = $this->getConfiguration($configs, $container);
@@ -94,6 +95,18 @@ class core extends Extension
$definition->addTag('twig.extension');
}
+ $composer_output = OutputInterface::VERBOSITY_NORMAL;
+ if ($config['extensions']['composer_verbose'])
+ {
+ $composer_output = OutputInterface::VERBOSITY_VERBOSE;
+ }
+ if ($config['extensions']['composer_debug'])
+ {
+ $composer_output = OutputInterface::VERBOSITY_DEBUG;
+ }
+
+ $container->setParameter('extensions.composer.output', $composer_output);
+
// Set the debug options
foreach ($config['debug'] as $name => $value)
{
diff --git a/phpBB/phpbb/extension/di/extension_base.php b/phpBB/phpbb/extension/di/extension_base.php
index ba74615e70..97033e7ddb 100644
--- a/phpBB/phpbb/extension/di/extension_base.php
+++ b/phpBB/phpbb/extension/di/extension_base.php
@@ -18,6 +18,7 @@ use Symfony\Component\Config\Resource\FileResource;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
+use phpbb\filesystem\helper as filesystem_helper;
/**
* Container core extension
@@ -94,8 +95,7 @@ class extension_base extends Extension
if ($services_directory && $services_file)
{
- $filesystem = new \phpbb\filesystem\filesystem();
- $loader = new YamlFileLoader($container, new FileLocator($filesystem->realpath($services_directory)));
+ $loader = new YamlFileLoader($container, new FileLocator(filesystem_helper::realpath($services_directory)));
$loader->load($services_file);
}
}
diff --git a/phpBB/phpbb/extension/manager.php b/phpBB/phpbb/extension/manager.php
index 1ce8425fff..ecbb6c270e 100644
--- a/phpBB/phpbb/extension/manager.php
+++ b/phpBB/phpbb/extension/manager.php
@@ -40,14 +40,13 @@ class manager
* @param ContainerInterface $container A container
* @param \phpbb\db\driver\driver_interface $db A database connection
* @param \phpbb\config\config $config Config object
- * @param \phpbb\filesystem\filesystem_interface $filesystem
* @param string $extension_table The name of the table holding extensions
* @param string $phpbb_root_path Path to the phpbb includes directory.
* @param string $php_ext php file extension, defaults to php
* @param \phpbb\cache\service $cache A cache instance or null
* @param string $cache_name The name of the cache variable, defaults to _ext
*/
- public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\filesystem\filesystem_interface $filesystem, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\service $cache = null, $cache_name = '_ext')
+ public function __construct(ContainerInterface $container, \phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, $extension_table, $phpbb_root_path, $php_ext = 'php', \phpbb\cache\service $cache = null, $cache_name = '_ext')
{
$this->cache = $cache;
$this->cache_name = $cache_name;
@@ -55,7 +54,6 @@ class manager
$this->container = $container;
$this->db = $db;
$this->extension_table = $extension_table;
- $this->filesystem = $filesystem;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
@@ -577,7 +575,7 @@ class manager
*/
public function get_finder($use_all_available = false)
{
- $finder = new \phpbb\finder($this->filesystem, $this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder');
+ $finder = new \phpbb\finder($this->phpbb_root_path, $this->cache, $this->php_ext, $this->cache_name . '_finder');
if ($use_all_available)
{
$finder->set_extensions(array_keys($this->all_available()));
diff --git a/phpBB/phpbb/files/filespec_storage.php b/phpBB/phpbb/files/filespec_storage.php
new file mode 100644
index 0000000000..bc9d7bf6a1
--- /dev/null
+++ b/phpBB/phpbb/files/filespec_storage.php
@@ -0,0 +1,519 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\files;
+
+use phpbb\language\language;
+
+/**
+ * Responsible for holding all file relevant information, as well as doing file-specific operations.
+ * The {@link fileupload fileupload class} can be used to upload several files, each of them being this object to operate further on.
+ */
+class filespec_storage
+{
+ /** @var string File name */
+ protected $filename = '';
+
+ /** @var string Real name of file */
+ protected $realname = '';
+
+ /** @var string Upload name of file */
+ protected $uploadname = '';
+
+ /** @var string Mimetype of file */
+ protected $mimetype = '';
+
+ /** @var string File extension */
+ protected $extension = '';
+
+ /** @var int File size */
+ protected $filesize = 0;
+
+ /** @var int Width of file */
+ protected $width = 0;
+
+ /** @var int Height of file */
+ protected $height = 0;
+
+ /** @var array Image info including type and size */
+ protected $image_info = array();
+
+ /** @var string Destination file name */
+ protected $destination_file = '';
+
+ /** @var bool Whether file was moved */
+ protected $file_moved = false;
+
+ /** @var bool Whether file is local */
+ protected $local = false;
+
+ /** @var bool Class initialization flag */
+ protected $class_initialized = false;
+
+ /** @var array Error array */
+ public $error = array();
+
+ /** @var upload Instance of upload class */
+ public $upload;
+
+ /** @var \bantu\IniGetWrapper\IniGetWrapper ini_get() wrapper class */
+ protected $php_ini;
+
+ /** @var \FastImageSize\FastImageSize */
+ protected $imagesize;
+
+ /** @var language Language class */
+ protected $language;
+
+ /** @var \phpbb\plupload\plupload The plupload object */
+ protected $plupload;
+
+ /** @var \phpbb\mimetype\guesser phpBB Mimetype guesser */
+ protected $mimetype_guesser;
+
+ /**
+ * File upload class
+ *
+ * @param language $language Language
+ * @param \bantu\IniGetWrapper\IniGetWrapper $php_ini ini_get() wrapper
+ * @param \FastImageSize\FastImageSize $imagesize Imagesize class
+ * @param \phpbb\mimetype\guesser $mimetype_guesser Mime type guesser
+ * @param \phpbb\plupload\plupload $plupload Plupload
+ */
+ public function __construct(language $language, \bantu\IniGetWrapper\IniGetWrapper $php_ini, \FastImageSize\FastImageSize $imagesize, \phpbb\mimetype\guesser $mimetype_guesser = null, \phpbb\plupload\plupload $plupload = null)
+ {
+ $this->language = $language;
+ $this->php_ini = $php_ini;
+ $this->imagesize = $imagesize;
+ $this->plupload = $plupload;
+ $this->mimetype_guesser = $mimetype_guesser;
+ }
+
+ /**
+ * Set upload ary
+ *
+ * @param array $upload_ary Upload ary
+ *
+ * @return filespec This instance of the filespec class
+ */
+ public function set_upload_ary($upload_ary)
+ {
+ if (!isset($upload_ary) || !count($upload_ary))
+ {
+ return $this;
+ }
+
+ $this->class_initialized = true;
+ $this->filename = $upload_ary['tmp_name'];
+ $this->filesize = $upload_ary['size'];
+ $name = $upload_ary['name'];
+ $name = trim(utf8_basename($name));
+ $this->realname = $this->uploadname = $name;
+ $this->mimetype = $upload_ary['type'];
+
+ // Opera adds the name to the mime type
+ $this->mimetype = (strpos($this->mimetype, '; name') !== false) ? str_replace(strstr($this->mimetype, '; name'), '', $this->mimetype) : $this->mimetype;
+
+ if (!$this->mimetype)
+ {
+ $this->mimetype = 'application/octet-stream';
+ }
+
+ $this->extension = strtolower(self::get_extension($this->realname));
+
+ // Try to get real filesize from temporary folder (not always working) ;)
+ $this->filesize = ($this->get_filesize($this->filename)) ?: $this->filesize;
+
+ $this->width = $this->height = 0;
+ $this->file_moved = false;
+
+ $this->local = (isset($upload_ary['local_mode'])) ? true : false;
+
+ return $this;
+ }
+
+ /**
+ * Set the upload namespace
+ *
+ * @param upload $namespace Instance of upload class
+ *
+ * @return filespec This instance of the filespec class
+ */
+ public function set_upload_namespace($namespace)
+ {
+ $this->upload = $namespace;
+
+ return $this;
+ }
+
+ /**
+ * Check if class members were not properly initialised yet
+ *
+ * @return bool True if there was an init error, false if not
+ */
+ public function init_error()
+ {
+ return !$this->class_initialized;
+ }
+
+ /**
+ * Set error in error array
+ *
+ * @param mixed $error Content for error array
+ *
+ * @return \phpbb\files\filespec This instance of the filespec class
+ */
+ public function set_error($error)
+ {
+ $this->error[] = $error;
+
+ return $this;
+ }
+
+ /**
+ * Cleans destination filename
+ *
+ * @param string $mode Either real, unique, or unique_ext. Real creates a
+ * realname, filtering some characters, lowering every
+ * character. Unique creates a unique filename.
+ * @param string $prefix Prefix applied to filename
+ * @param string $user_id The user_id is only needed for when cleaning a user's avatar
+ */
+ public function clean_filename($mode = 'unique', $prefix = '', $user_id = '')
+ {
+ if ($this->init_error())
+ {
+ return;
+ }
+
+ switch ($mode)
+ {
+ case 'real':
+ // Remove every extension from filename (to not let the mime bug being exposed)
+ if (strpos($this->realname, '.') !== false)
+ {
+ $this->realname = substr($this->realname, 0, strpos($this->realname, '.'));
+ }
+
+ // Replace any chars which may cause us problems with _
+ $bad_chars = array("'", "\\", ' ', '/', ':', '*', '?', '"', '<', '>', '|');
+
+ $this->realname = rawurlencode(str_replace($bad_chars, '_', strtolower($this->realname)));
+ $this->realname = preg_replace("/%(\w{2})/", '_', $this->realname);
+
+ $this->realname = $prefix . $this->realname . '.' . $this->extension;
+ break;
+
+ case 'unique':
+ $this->realname = $prefix . md5(unique_id());
+ break;
+
+ case 'avatar':
+ $this->extension = strtolower($this->extension);
+ $this->realname = $prefix . $user_id . '.' . $this->extension;
+
+ break;
+
+ case 'unique_ext':
+ default:
+ $this->realname = $prefix . md5(unique_id()) . '.' . $this->extension;
+ }
+ }
+
+ /**
+ * Get property from file object
+ *
+ * @param string $property Name of property
+ *
+ * @return mixed Content of property
+ */
+ public function get($property)
+ {
+ if ($this->init_error() || !isset($this->$property))
+ {
+ return false;
+ }
+
+ return $this->$property;
+ }
+
+ /**
+ * Check if file is an image (mime type)
+ *
+ * @return bool true if it is an image, false if not
+ */
+ public function is_image()
+ {
+ return (strpos($this->mimetype, 'image/') === 0);
+ }
+
+ /**
+ * Check if the file got correctly uploaded
+ *
+ * @return bool true if it is a valid upload, false if not
+ */
+ public function is_uploaded()
+ {
+ $is_plupload = $this->plupload && $this->plupload->is_active();
+
+ if (!$this->local && !$is_plupload && !is_uploaded_file($this->filename))
+ {
+ return false;
+ }
+
+ if (($this->local || $is_plupload) && !file_exists($this->filename))
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ /**
+ * Remove file
+ */
+ public function remove($storage)
+ {
+ if ($this->file_moved)
+ {
+ $storage->delete($this->destination_file);
+ }
+ else
+ {
+ @unlink($this->filename);
+ }
+ }
+
+ /**
+ * Get file extension
+ *
+ * @param string $filename Filename that needs to be checked
+ *
+ * @return string Extension of the supplied filename
+ */
+ static public function get_extension($filename)
+ {
+ $filename = utf8_basename($filename);
+
+ if (strpos($filename, '.') === false)
+ {
+ return '';
+ }
+
+ $filename = explode('.', $filename);
+ return array_pop($filename);
+ }
+
+ /**
+ * Get mime type
+ *
+ * @param string $filename Filename that needs to be checked
+ * @return string Mime type of supplied filename
+ */
+ public function get_mimetype($filename)
+ {
+ if ($this->mimetype_guesser !== null)
+ {
+ $mimetype = $this->mimetype_guesser->guess($filename, $this->uploadname);
+
+ if ($mimetype !== 'application/octet-stream')
+ {
+ $this->mimetype = $mimetype;
+ }
+ }
+
+ return $this->mimetype;
+ }
+
+ /**
+ * Get file size
+ *
+ * @param string $filename File name of file to check
+ *
+ * @return int File size
+ */
+ public function get_filesize($filename)
+ {
+ return @filesize($filename);
+ }
+
+
+ /**
+ * Check the first 256 bytes for forbidden content
+ *
+ * @param array $disallowed_content Array containg disallowed content
+ *
+ * @return bool False if disallowed content found, true if not
+ */
+ public function check_content($disallowed_content)
+ {
+ if (empty($disallowed_content))
+ {
+ return true;
+ }
+
+ $fp = @fopen($this->filename, 'rb');
+
+ if ($fp !== false)
+ {
+ $ie_mime_relevant = fread($fp, 256);
+ fclose($fp);
+ foreach ($disallowed_content as $forbidden)
+ {
+ if (stripos($ie_mime_relevant, '<' . $forbidden) !== false)
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Move file to destination folder
+ *
+ * @param \phpbb\storage\storage $storage
+ * @param bool $overwrite If set to true, an already existing file will be overwritten
+ * @param bool $skip_image_check If set to true, the check for the file to be a valid image is skipped
+ *
+ * @return bool True if file was moved, false if not
+ * @access public
+ */
+ public function move_file($storage, $overwrite = false, $skip_image_check = false)
+ {
+ if (count($this->error))
+ {
+ return false;
+ }
+
+ $this->destination_file = utf8_basename($this->realname);
+
+ // Try to get real filesize from destination folder
+ $this->filesize = ($this->get_filesize($this->filename)) ?: $this->filesize;
+
+ // Get mimetype of supplied file
+ $this->mimetype = $this->get_mimetype($this->filename);
+
+ if ($this->is_image() && !$skip_image_check)
+ {
+ $this->width = $this->height = 0;
+
+ $this->image_info = $this->imagesize->getImageSize($this->filename, $this->mimetype);
+
+ if ($this->image_info !== false)
+ {
+ $this->width = $this->image_info['width'];
+ $this->height = $this->image_info['height'];
+
+ // Check image type
+ $types = upload::image_types();
+
+ if (!isset($types[$this->image_info['type']]) || !in_array($this->extension, $types[$this->image_info['type']]))
+ {
+ if (!isset($types[$this->image_info['type']]))
+ {
+ $this->error[] = $this->language->lang('IMAGE_FILETYPE_INVALID', $this->image_info['type'], $this->mimetype);
+ }
+ else
+ {
+ $this->error[] = $this->language->lang('IMAGE_FILETYPE_MISMATCH', $types[$this->image_info['type']][0], $this->extension);
+ }
+ }
+
+ // Make sure the dimensions match a valid image
+ if (empty($this->width) || empty($this->height))
+ {
+ $this->error[] = $this->language->lang('ATTACHED_IMAGE_NOT_IMAGE');
+ }
+ }
+ else
+ {
+ $this->error[] = $this->language->lang('UNABLE_GET_IMAGE_SIZE');
+ }
+ }
+
+ if ($overwrite && $storage->exists($this->destination_file))
+ {
+ $storage->delete($this->destination_file);
+ }
+
+ try
+ {
+ $fp = fopen($this->filename, 'rb');
+
+ $storage->write_stream($this->destination_file, $fp);
+
+ if (is_resource($fp))
+ {
+ fclose($fp);
+ }
+ }
+ catch (\phpbb\storage\exception\exception $e)
+ {
+ $this->error[] = $this->language->lang($this->upload->error_prefix . 'GENERAL_UPLOAD_ERROR', $this->destination_file);
+ $this->file_moved = false;
+ }
+
+ // Remove temporary filename
+ @unlink($this->filename);
+
+ if (count($this->error))
+ {
+ return false;
+ }
+
+ $this->file_moved = true;
+ $this->additional_checks();
+ unset($this->upload);
+
+ return true;
+ }
+
+ /**
+ * Performing additional checks
+ *
+ * @return bool False if issue was found, true if not
+ */
+ public function additional_checks()
+ {
+ if (!$this->file_moved)
+ {
+ return false;
+ }
+
+ // Filesize is too big or it's 0 if it was larger than the maxsize in the upload form
+ if ($this->upload->max_filesize && ($this->get('filesize') > $this->upload->max_filesize || $this->filesize == 0))
+ {
+ $max_filesize = get_formatted_filesize($this->upload->max_filesize, false);
+
+ $this->error[] = $this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit']);
+
+ return false;
+ }
+
+ if (!$this->upload->valid_dimensions($this))
+ {
+ $this->error[] = $this->language->lang($this->upload->error_prefix . 'WRONG_SIZE',
+ $this->language->lang('PIXELS', (int) $this->upload->min_width),
+ $this->language->lang('PIXELS', (int) $this->upload->min_height),
+ $this->language->lang('PIXELS', (int) $this->upload->max_width),
+ $this->language->lang('PIXELS', (int) $this->upload->max_height),
+ $this->language->lang('PIXELS', (int) $this->width),
+ $this->language->lang('PIXELS', (int) $this->height));
+
+ return false;
+ }
+
+ return true;
+ }
+}
diff --git a/phpBB/phpbb/files/types/form.php b/phpBB/phpbb/files/types/form.php
index 2c3beb6e02..a915476191 100644
--- a/phpBB/phpbb/files/types/form.php
+++ b/phpBB/phpbb/files/types/form.php
@@ -25,21 +25,12 @@ class form extends base
/** @var factory Files factory */
protected $factory;
- /** @var language */
- protected $language;
-
- /** @var IniGetWrapper */
- protected $php_ini;
-
/** @var plupload */
protected $plupload;
/** @var request_interface */
protected $request;
- /** @var \phpbb\files\upload */
- protected $upload;
-
/**
* Construct a form upload type
*
diff --git a/phpBB/phpbb/files/types/form_storage.php b/phpBB/phpbb/files/types/form_storage.php
new file mode 100644
index 0000000000..3024dc83e7
--- /dev/null
+++ b/phpBB/phpbb/files/types/form_storage.php
@@ -0,0 +1,128 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\files\types;
+
+use bantu\IniGetWrapper\IniGetWrapper;
+use phpbb\files\factory;
+use phpbb\files\filespec;
+use phpbb\language\language;
+use phpbb\plupload\plupload;
+use phpbb\request\request_interface;
+
+class form_storage extends base
+{
+ /** @var factory Files factory */
+ protected $factory;
+
+ /** @var plupload */
+ protected $plupload;
+
+ /** @var request_interface */
+ protected $request;
+
+ /**
+ * Construct a form upload type
+ *
+ * @param factory $factory Files factory
+ * @param language $language Language class
+ * @param IniGetWrapper $php_ini ini_get() wrapper
+ * @param plupload $plupload Plupload
+ * @param request_interface $request Request object
+ */
+ public function __construct(factory $factory, language $language, IniGetWrapper $php_ini, plupload $plupload, request_interface $request)
+ {
+ $this->factory = $factory;
+ $this->language = $language;
+ $this->php_ini = $php_ini;
+ $this->plupload = $plupload;
+ $this->request = $request;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function upload()
+ {
+ $args = func_get_args();
+ return $this->form_upload($args[0]);
+ }
+
+ /**
+ * Form upload method
+ * Upload file from users harddisk
+ *
+ * @param string $form_name Form name assigned to the file input field (if it is an array, the key has to be specified)
+ *
+ * @return filespec $file Object "filespec" is returned, all further operations can be done with this object
+ */
+ protected function form_upload($form_name)
+ {
+ $upload = $this->request->file($form_name);
+ unset($upload['local_mode']);
+
+ $result = $this->plupload->handle_upload($form_name);
+ if (is_array($result))
+ {
+ $upload = array_merge($upload, $result);
+ }
+
+ /** @var filespec $file */
+ $file = $this->factory->get('filespec_storage')
+ ->set_upload_ary($upload)
+ ->set_upload_namespace($this->upload);
+
+ if ($file->init_error())
+ {
+ $file->error[] = '';
+ return $file;
+ }
+
+ // Error array filled?
+ if (isset($upload['error']))
+ {
+ $error = $this->upload->assign_internal_error($upload['error']);
+
+ if ($error !== false)
+ {
+ $file->error[] = $error;
+ return $file;
+ }
+ }
+
+ // Check if empty file got uploaded (not catched by is_uploaded_file)
+ if (isset($upload['size']) && $upload['size'] == 0)
+ {
+ $file->error[] = $this->language->lang($this->upload->error_prefix . 'EMPTY_FILEUPLOAD');
+ return $file;
+ }
+
+ // PHP Upload file size check
+ $file = $this->check_upload_size($file);
+ if (count($file->error))
+ {
+ return $file;
+ }
+
+ // Not correctly uploaded
+ if (!$file->is_uploaded())
+ {
+ $file->error[] = $this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED');
+ return $file;
+ }
+
+ $this->upload->common_checks($file);
+
+ return $file;
+ }
+}
diff --git a/phpBB/phpbb/files/types/local.php b/phpBB/phpbb/files/types/local.php
index 4dfe4f7506..67948ea6df 100644
--- a/phpBB/phpbb/files/types/local.php
+++ b/phpBB/phpbb/files/types/local.php
@@ -24,18 +24,9 @@ class local extends base
/** @var factory Files factory */
protected $factory;
- /** @var language */
- protected $language;
-
- /** @var IniGetWrapper */
- protected $php_ini;
-
/** @var request_interface */
protected $request;
- /** @var \phpbb\files\upload */
- protected $upload;
-
/**
* Construct a form upload type
*
diff --git a/phpBB/phpbb/files/types/local_storage.php b/phpBB/phpbb/files/types/local_storage.php
new file mode 100644
index 0000000000..c3990fe389
--- /dev/null
+++ b/phpBB/phpbb/files/types/local_storage.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\files\types;
+
+use bantu\IniGetWrapper\IniGetWrapper;
+use phpbb\files\factory;
+use phpbb\files\filespec;
+use phpbb\language\language;
+use phpbb\request\request_interface;
+
+class local_storage extends base
+{
+ /** @var factory Files factory */
+ protected $factory;
+
+ /** @var language */
+ protected $language;
+
+ /** @var IniGetWrapper */
+ protected $php_ini;
+
+ /** @var request_interface */
+ protected $request;
+
+ /** @var \phpbb\files\upload */
+ protected $upload;
+
+ /**
+ * Construct a form upload type
+ *
+ * @param factory $factory Files factory
+ * @param language $language Language class
+ * @param IniGetWrapper $php_ini ini_get() wrapper
+ * @param request_interface $request Request object
+ */
+ public function __construct(factory $factory, language $language, IniGetWrapper $php_ini, request_interface $request)
+ {
+ $this->factory = $factory;
+ $this->language = $language;
+ $this->php_ini = $php_ini;
+ $this->request = $request;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function upload()
+ {
+ $args = func_get_args();
+ return $this->local_upload($args[0], isset($args[1]) ? $args[1] : false);
+ }
+
+ /**
+ * Move file from another location to phpBB
+ *
+ * @param string $source_file Filename of source file
+ * @param array|bool $filedata Array with filedata or false
+ *
+ * @return filespec Object "filespec" is returned, all further operations can be done with this object
+ */
+ protected function local_upload($source_file, $filedata = false)
+ {
+ $upload = $this->get_upload_ary($source_file, $filedata);
+
+ /** @var filespec $file */
+ $file = $this->factory->get('filespec_storage')
+ ->set_upload_ary($upload)
+ ->set_upload_namespace($this->upload);
+
+ if ($file->init_error())
+ {
+ $file->error[] = '';
+ return $file;
+ }
+
+ // PHP Upload file size check
+ $file = $this->check_upload_size($file);
+ if (count($file->error))
+ {
+ return $file;
+ }
+
+ // Not correctly uploaded
+ if (!$file->is_uploaded())
+ {
+ $file->error[] = $this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED');
+ return $file;
+ }
+
+ $this->upload->common_checks($file);
+ $this->request->overwrite('local', $upload, request_interface::FILES);
+
+ return $file;
+ }
+
+ /**
+ * Retrieve upload array
+ *
+ * @param string $source_file Source file name
+ * @param array $filedata File data array
+ *
+ * @return array Upload array
+ */
+ protected function get_upload_ary($source_file, $filedata)
+ {
+ $upload = array();
+
+ $upload['local_mode'] = true;
+ $upload['tmp_name'] = $source_file;
+
+ if ($filedata === false)
+ {
+ $upload['name'] = utf8_basename($source_file);
+ $upload['size'] = 0;
+ }
+ else
+ {
+ $upload['name'] = $filedata['realname'];
+ $upload['size'] = $filedata['size'];
+ $upload['type'] = $filedata['type'];
+ }
+
+ return $upload;
+ }
+}
diff --git a/phpBB/phpbb/files/types/remote.php b/phpBB/phpbb/files/types/remote.php
index 1fdba0ca32..17c3d7a614 100644
--- a/phpBB/phpbb/files/types/remote.php
+++ b/phpBB/phpbb/files/types/remote.php
@@ -17,6 +17,7 @@ use bantu\IniGetWrapper\IniGetWrapper;
use phpbb\config\config;
use phpbb\files\factory;
use phpbb\files\filespec;
+use phpbb\filesystem\temp;
use phpbb\language\language;
use phpbb\request\request_interface;
@@ -28,6 +29,9 @@ class remote extends base
/** @var factory Files factory */
protected $factory;
+ /** @var filesystem Filesystem temp */
+ protected $temp;
+
/** @var language */
protected $language;
@@ -37,30 +41,24 @@ class remote extends base
/** @var request_interface */
protected $request;
- /** @var \phpbb\files\upload */
- protected $upload;
-
- /** @var string phpBB root path */
- protected $phpbb_root_path;
-
/**
* Construct a form upload type
*
* @param config $config phpBB config
* @param factory $factory Files factory
+ * @param temp $temp Filesystem temp
* @param language $language Language class
* @param IniGetWrapper $php_ini ini_get() wrapper
* @param request_interface $request Request object
- * @param string $phpbb_root_path phpBB root path
*/
- public function __construct(config $config, factory $factory, language $language, IniGetWrapper $php_ini, request_interface $request, $phpbb_root_path)
+ public function __construct(config $config, factory $factory, temp $temp, language $language, IniGetWrapper $php_ini, request_interface $request)
{
$this->config = $config;
$this->factory = $factory;
+ $this->temp = $temp;
$this->language = $language;
$this->php_ini = $php_ini;
$this->request = $request;
- $this->phpbb_root_path = $phpbb_root_path;
}
/**
@@ -148,7 +146,7 @@ class remote extends base
$data = $response->getBody();
- $filename = tempnam(sys_get_temp_dir(), unique_id() . '-');
+ $filename = tempnam($this->temp->get_dir(), unique_id() . '-');
if (!($fp = @fopen($filename, 'wb')))
{
diff --git a/phpBB/phpbb/files/types/remote_storage.php b/phpBB/phpbb/files/types/remote_storage.php
new file mode 100644
index 0000000000..d542c5e2f4
--- /dev/null
+++ b/phpBB/phpbb/files/types/remote_storage.php
@@ -0,0 +1,204 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\files\types;
+
+use bantu\IniGetWrapper\IniGetWrapper;
+use phpbb\config\config;
+use phpbb\files\factory;
+use phpbb\files\filespec;
+use phpbb\filesystem\temp;
+use phpbb\language\language;
+use phpbb\request\request_interface;
+
+class remote_storage extends base
+{
+ /** @var config phpBB config */
+ protected $config;
+
+ /** @var factory Files factory */
+ protected $factory;
+
+ /** @var temp Filesystem temp */
+ protected $temp;
+
+ /** @var language */
+ protected $language;
+
+ /** @var IniGetWrapper */
+ protected $php_ini;
+
+ /** @var request_interface */
+ protected $request;
+
+ /**
+ * Construct a form upload type
+ *
+ * @param config $config phpBB config
+ * @param factory $factory Files factory
+ * @param temp $temp Filesystem temp
+ * @param language $language Language class
+ * @param IniGetWrapper $php_ini ini_get() wrapper
+ * @param request_interface $request Request object
+ */
+ public function __construct(config $config, factory $factory, temp $temp, language $language, IniGetWrapper $php_ini, request_interface $request)
+ {
+ $this->config = $config;
+ $this->factory = $factory;
+ $this->temp = $temp;
+ $this->language = $language;
+ $this->php_ini = $php_ini;
+ $this->request = $request;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function upload()
+ {
+ $args = func_get_args();
+ return $this->remote_upload($args[0]);
+ }
+
+ /**
+ * Remote upload method
+ * Uploads file from given url
+ *
+ * @param string $upload_url URL pointing to file to upload, for example http://www.foobar.com/example.gif
+ * @return filespec $file Object "filespec" is returned, all further operations can be done with this object
+ */
+ protected function remote_upload($upload_url)
+ {
+ $upload_ary = array();
+ $upload_ary['local_mode'] = true;
+
+ if (!preg_match('#^(https?://).*?\.(' . implode('|', $this->upload->allowed_extensions) . ')$#i', $upload_url, $match))
+ {
+ return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'URL_INVALID'));
+ }
+
+ $url = parse_url($upload_url);
+
+ $upload_ary['type'] = 'application/octet-stream';
+
+ $url['path'] = explode('.', $url['path']);
+ $ext = array_pop($url['path']);
+
+ $url['path'] = implode('', $url['path']);
+ $upload_ary['name'] = utf8_basename($url['path']) . (($ext) ? '.' . $ext : '');
+
+ $remote_max_filesize = $this->get_max_file_size();
+
+ $guzzle_options = [
+ 'timeout' => $this->upload->upload_timeout,
+ 'connect_timeout' => $this->upload->upload_timeout,
+ 'verify' => !empty($this->config['remote_upload_verify']) ? (bool) $this->config['remote_upload_verify'] : false,
+ ];
+ $client = new \GuzzleHttp\Client($guzzle_options);
+
+ try
+ {
+ $response = $client->get($upload_url, $guzzle_options);
+ }
+ catch (\GuzzleHttp\Exception\ClientException $clientException)
+ {
+ return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'URL_NOT_FOUND');
+ }
+ catch (\GuzzleHttp\Exception\RequestException $requestException)
+ {
+ if (strpos($requestException->getMessage(), 'cURL error 28') !== false || preg_match('/408|504/', $requestException->getCode()))
+ {
+ return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'REMOTE_UPLOAD_TIMEOUT');
+ }
+ else
+ {
+ return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED'));
+ }
+ }
+ catch (\Exception $e)
+ {
+ return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'NOT_UPLOADED'));
+ }
+
+ $content_length = $response->getBody()->getSize();
+ if ($remote_max_filesize && $content_length > $remote_max_filesize)
+ {
+ $max_filesize = get_formatted_filesize($remote_max_filesize, false);
+
+ return $this->factory->get('filespec')->set_error($this->language->lang($this->upload->error_prefix . 'WRONG_FILESIZE', $max_filesize['value'], $max_filesize['unit']));
+ }
+
+ if ($content_length === 0)
+ {
+ return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'EMPTY_REMOTE_DATA');
+ }
+
+ $data = $response->getBody();
+
+ $filename = tempnam($this->temp->get_dir(), unique_id() . '-');
+
+ if (!($fp = @fopen($filename, 'wb')))
+ {
+ return $this->factory->get('filespec')->set_error($this->upload->error_prefix . 'NOT_UPLOADED');
+ }
+
+ $upload_ary['size'] = fwrite($fp, $data);
+ fclose($fp);
+ unset($data);
+
+ $upload_ary['tmp_name'] = $filename;
+
+ /** @var filespec $file */
+ $file = $this->factory->get('filespec_storage')
+ ->set_upload_ary($upload_ary)
+ ->set_upload_namespace($this->upload);
+ $this->upload->common_checks($file);
+
+ return $file;
+ }
+
+ /**
+ * Get maximum file size for remote uploads
+ *
+ * @return int Maximum file size
+ */
+ protected function get_max_file_size()
+ {
+ $max_file_size = $this->upload->max_filesize;
+ if (!$max_file_size)
+ {
+ $max_file_size = $this->php_ini->getString('upload_max_filesize');
+
+ if (!empty($max_file_size))
+ {
+ $unit = strtolower(substr($max_file_size, -1, 1));
+ $max_file_size = (int) $max_file_size;
+
+ switch ($unit)
+ {
+ case 'g':
+ $max_file_size *= 1024;
+ // no break
+ case 'm':
+ $max_file_size *= 1024;
+ // no break
+ case 'k':
+ $max_file_size *= 1024;
+ // no break
+ }
+ }
+ }
+
+ return $max_file_size;
+ }
+}
diff --git a/phpBB/phpbb/filesystem/exception/filesystem_exception.php b/phpBB/phpbb/filesystem/exception/filesystem_exception.php
index d68fa9adf3..ddff8046e5 100644
--- a/phpBB/phpbb/filesystem/exception/filesystem_exception.php
+++ b/phpBB/phpbb/filesystem/exception/filesystem_exception.php
@@ -13,7 +13,9 @@
namespace phpbb\filesystem\exception;
-class filesystem_exception extends \phpbb\exception\runtime_exception
+use phpbb\exception\runtime_exception;
+
+class filesystem_exception extends runtime_exception
{
/**
* Constructor
@@ -24,7 +26,7 @@ class filesystem_exception extends \phpbb\exception\runtime_exception
* @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining.
* @param integer $code The Exception code.
*/
- public function __construct($message = "", $filename = '', $parameters = array(), \Exception $previous = null, $code = 0)
+ public function __construct($message = '', $filename = '', $parameters = array(), \Exception $previous = null, $code = 0)
{
parent::__construct($message, array_merge(array('filename' => $filename), $parameters), $previous, $code);
}
@@ -36,7 +38,7 @@ class filesystem_exception extends \phpbb\exception\runtime_exception
*/
public function get_filename()
{
- $parameters = parent::get_parameters();
+ $parameters = $this->get_parameters();
return $parameters['filename'];
}
}
diff --git a/phpBB/phpbb/filesystem/filesystem.php b/phpBB/phpbb/filesystem/filesystem.php
index 9acead0876..145def7f42 100644
--- a/phpBB/phpbb/filesystem/filesystem.php
+++ b/phpBB/phpbb/filesystem/filesystem.php
@@ -13,6 +13,7 @@
namespace phpbb\filesystem;
+use Symfony\Component\Filesystem\Exception\IOException;
use phpbb\filesystem\exception\filesystem_exception;
/**
@@ -60,7 +61,7 @@ class filesystem implements filesystem_interface
{
$this->symfony_filesystem->chgrp($files, $group, $recursive);
}
- catch (\Symfony\Component\Filesystem\Exception\IOException $e)
+ catch (IOException $e)
{
// Try to recover filename
// By the time this is written that is at the end of the message
@@ -146,7 +147,7 @@ class filesystem implements filesystem_interface
{
$this->symfony_filesystem->chown($files, $user, $recursive);
}
- catch (\Symfony\Component\Filesystem\Exception\IOException $e)
+ catch (IOException $e)
{
// Try to recover filename
// By the time this is written that is at the end of the message
@@ -162,26 +163,7 @@ class filesystem implements filesystem_interface
*/
public function clean_path($path)
{
- $exploded = explode('/', $path);
- $filtered = array();
- foreach ($exploded as $part)
- {
- if ($part === '.' && !empty($filtered))
- {
- continue;
- }
-
- if ($part === '..' && !empty($filtered) && $filtered[count($filtered) - 1] !== '.' && $filtered[count($filtered) - 1] !== '..')
- {
- array_pop($filtered);
- }
- else
- {
- $filtered[] = $part;
- }
- }
- $path = implode('/', $filtered);
- return $path;
+ return helper::clean_path($path);
}
/**
@@ -193,7 +175,7 @@ class filesystem implements filesystem_interface
{
$this->symfony_filesystem->copy($origin_file, $target_file, $override);
}
- catch (\Symfony\Component\Filesystem\Exception\IOException $e)
+ catch (IOException $e)
{
throw new filesystem_exception('FILESYSTEM_CANNOT_COPY_FILES', '', array(), $e);
}
@@ -208,7 +190,7 @@ class filesystem implements filesystem_interface
{
$this->symfony_filesystem->dumpFile($filename, $content);
}
- catch (\Symfony\Component\Filesystem\Exception\IOException $e)
+ catch (IOException $e)
{
throw new filesystem_exception('FILESYSTEM_CANNOT_DUMP_FILE', $filename, array(), $e);
}
@@ -227,7 +209,7 @@ class filesystem implements filesystem_interface
*/
public function is_absolute_path($path)
{
- return (isset($path[0]) && $path[0] === '/' || preg_match('#^[a-z]:[/\\\]#i', $path)) ? true : false;
+ return helper::is_absolute_path($path);
}
/**
@@ -305,7 +287,7 @@ class filesystem implements filesystem_interface
*/
public function make_path_relative($end_path, $start_path)
{
- return $this->symfony_filesystem->makePathRelative($end_path, $start_path);
+ return helper::make_path_relative($end_path, $start_path);
}
/**
@@ -317,7 +299,7 @@ class filesystem implements filesystem_interface
{
$this->symfony_filesystem->mirror($origin_dir, $target_dir, $iterator, $options);
}
- catch (\Symfony\Component\Filesystem\Exception\IOException $e)
+ catch (IOException $e)
{
$msg = $e->getMessage();
$filename = substr($msg, strpos($msg, '"'), strrpos($msg, '"'));
@@ -335,7 +317,7 @@ class filesystem implements filesystem_interface
{
$this->symfony_filesystem->mkdir($dirs, $mode);
}
- catch (\Symfony\Component\Filesystem\Exception\IOException $e)
+ catch (IOException $e)
{
$msg = $e->getMessage();
$filename = substr($msg, strpos($msg, '"'), strrpos($msg, '"'));
@@ -486,27 +468,7 @@ class filesystem implements filesystem_interface
*/
public function realpath($path)
{
- if (!function_exists('realpath'))
- {
- return $this->phpbb_own_realpath($path);
- }
-
- $realpath = realpath($path);
-
- // Strangely there are provider not disabling realpath but returning strange values. :o
- // We at least try to cope with them.
- if ((!$this->is_absolute_path($path) && $realpath === $path) || $realpath === false)
- {
- return $this->phpbb_own_realpath($path);
- }
-
- // Check for DIRECTORY_SEPARATOR at the end (and remove it!)
- if (substr($realpath, -1) === DIRECTORY_SEPARATOR)
- {
- $realpath = substr($realpath, 0, -1);
- }
-
- return $realpath;
+ return helper::realpath($path);
}
/**
@@ -518,7 +480,7 @@ class filesystem implements filesystem_interface
{
$this->symfony_filesystem->remove($files);
}
- catch (\Symfony\Component\Filesystem\Exception\IOException $e)
+ catch (IOException $e)
{
// Try to recover filename
// By the time this is written that is at the end of the message
@@ -538,7 +500,7 @@ class filesystem implements filesystem_interface
{
$this->symfony_filesystem->rename($origin, $target, $overwrite);
}
- catch (\Symfony\Component\Filesystem\Exception\IOException $e)
+ catch (IOException $e)
{
$msg = $e->getMessage();
$filename = substr($msg, strpos($msg, '"'), strrpos($msg, '"'));
@@ -556,7 +518,7 @@ class filesystem implements filesystem_interface
{
$this->symfony_filesystem->symlink($origin_dir, $target_dir, $copy_on_windows);
}
- catch (\Symfony\Component\Filesystem\Exception\IOException $e)
+ catch (IOException $e)
{
throw new filesystem_exception('FILESYSTEM_CANNOT_CREATE_SYMLINK', $origin_dir, array(), $e);
}
@@ -571,7 +533,7 @@ class filesystem implements filesystem_interface
{
$this->symfony_filesystem->touch($files, $time, $access_time);
}
- catch (\Symfony\Component\Filesystem\Exception\IOException $e)
+ catch (IOException $e)
{
// Try to recover filename
// By the time this is written that is at the end of the message
@@ -639,6 +601,8 @@ class filesystem implements filesystem_interface
/**
* Try to resolve real path when PHP's realpath failes to do so
*
+ * @deprecated 3.3.0-a1 (To be removed: 4.0.0)
+ *
* @param string $path
* @return bool|string
*/
@@ -764,6 +728,8 @@ class filesystem implements filesystem_interface
/**
* Try to resolve symlinks in path
*
+ * @deprecated 3.3.0-a1 (To be removed: 4.0.0)
+ *
* @param string $path The path to resolve
* @param string $prefix The path prefix (on windows the drive letter)
* @param bool $absolute Whether or not the path is absolute
@@ -774,143 +740,6 @@ class filesystem implements filesystem_interface
*/
protected function resolve_path($path, $prefix = '', $absolute = false, $return_array = false)
{
- if ($return_array)
- {
- $path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
- }
-
- trim ($path, '/');
- $path_parts = explode('/', $path);
- $resolved = array();
- $resolved_path = $prefix;
- $file_found = false;
-
- foreach ($path_parts as $path_part)
- {
- if ($file_found)
- {
- return false;
- }
-
- if (empty($path_part) || ($path_part === '.' && ($absolute || !empty($resolved))))
- {
- continue;
- }
- else if ($absolute && $path_part === '..')
- {
- if (empty($resolved))
- {
- // No directories above root
- return false;
- }
-
- array_pop($resolved);
- $resolved_path = false;
- }
- else if ($path_part === '..' && !empty($resolved) && !in_array($resolved[count($resolved) - 1], array('.', '..')))
- {
- array_pop($resolved);
- $resolved_path = false;
- }
- else
- {
- if ($resolved_path === false)
- {
- if (empty($resolved))
- {
- $resolved_path = ($absolute) ? $prefix . '/' . $path_part : $path_part;
- }
- else
- {
- $tmp_array = $resolved;
- if ($absolute)
- {
- array_unshift($tmp_array, $prefix);
- }
-
- $resolved_path = implode('/', $tmp_array);
- }
- }
-
- $current_path = $resolved_path . '/' . $path_part;
-
- // Resolve symlinks
- if (@is_link($current_path))
- {
- if (!function_exists('readlink'))
- {
- return false;
- }
-
- $link = readlink($current_path);
-
- // Is link has an absolute path in it?
- if ($this->is_absolute_path($link))
- {
- if (defined('PHP_WINDOWS_VERSION_MAJOR'))
- {
- $prefix = $link[0] . ':';
- $link = substr($link, 2);
- }
- else
- {
- $prefix = '';
- }
-
- $resolved = $this->resolve_path($link, $prefix, true, true);
- $absolute = true;
- }
- else
- {
- $resolved = $this->resolve_path($resolved_path . '/' . $link, $prefix, $absolute, true);
- }
-
- if (!$resolved)
- {
- return false;
- }
-
- $resolved_path = false;
- }
- else if (@is_dir($current_path . '/'))
- {
- $resolved[] = $path_part;
- $resolved_path = $current_path;
- }
- else if (@is_file($current_path))
- {
- $resolved[] = $path_part;
- $resolved_path = $current_path;
- $file_found = true;
- }
- else
- {
- return false;
- }
- }
- }
-
- // If at the end of the path there were a .. or .
- // we need to build the path again.
- // Only doing this when a string is expected in return
- if ($resolved_path === false && $return_array === false)
- {
- if (empty($resolved))
- {
- $resolved_path = ($absolute) ? $prefix . '/' : './';
- }
- else
- {
- $tmp_array = $resolved;
- if ($absolute)
- {
- array_unshift($tmp_array, $prefix);
- }
-
- $resolved_path = implode('/', $tmp_array);
- }
- }
-
- return ($return_array) ? $resolved : $resolved_path;
+ return helper::resolve_path($path, $prefix, $absolute, $return_array);
}
}
diff --git a/phpBB/phpbb/filesystem/filesystem_interface.php b/phpBB/phpbb/filesystem/filesystem_interface.php
index 39ae0c3954..139cd27ef6 100644
--- a/phpBB/phpbb/filesystem/filesystem_interface.php
+++ b/phpBB/phpbb/filesystem/filesystem_interface.php
@@ -89,6 +89,8 @@ interface filesystem_interface
/**
* Eliminates useless . and .. components from specified path.
*
+ * @deprecated 3.3.0-a1 (To be removed: 4.0.0)
+ *
* @param string $path Path to clean
*
* @return string Cleaned path
@@ -132,6 +134,8 @@ interface filesystem_interface
/**
* Checks if a path is absolute or not
*
+ * @deprecated 3.3.0-a1 (To be removed: 4.0.0)
+ *
* @param string $path Path to check
*
* @return bool true if the path is absolute, false otherwise
@@ -161,6 +165,8 @@ interface filesystem_interface
/**
* Given an existing path, convert it to a path relative to a given starting path
*
+ * @deprecated 3.3.0-a1 (To be removed: 4.0.0)
+ *
* @param string $end_path Absolute path of target
* @param string $start_path Absolute path where traversal begins
*
@@ -228,6 +234,8 @@ interface filesystem_interface
/**
* A wrapper for PHP's realpath
*
+ * @deprecated 3.3.0-a1 (To be removed: 4.0.0)
+ *
* Try to resolve realpath when PHP's realpath is not available, or
* known to be buggy.
*
diff --git a/phpBB/phpbb/filesystem/helper.php b/phpBB/phpbb/filesystem/helper.php
new file mode 100644
index 0000000000..f73dd7f2f5
--- /dev/null
+++ b/phpBB/phpbb/filesystem/helper.php
@@ -0,0 +1,385 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\filesystem;
+
+use Symfony\Component\Filesystem\Filesystem as symfony_filesystem;
+
+class helper
+{
+ /**
+ * @var \Symfony\Component\Filesystem\Filesystem
+ */
+ protected static $symfony_filesystem;
+
+ /**
+ * Eliminates useless . and .. components from specified path.
+ *
+ * @param string $path Path to clean
+ *
+ * @return string Cleaned path
+ */
+ public static function clean_path($path)
+ {
+ $exploded = explode('/', $path);
+ $filtered = array();
+ foreach ($exploded as $part)
+ {
+ if ($part === '.' && !empty($filtered))
+ {
+ continue;
+ }
+
+ if ($part === '..' && !empty($filtered) && $filtered[count($filtered) - 1] !== '.' && $filtered[count($filtered) - 1] !== '..')
+ {
+ array_pop($filtered);
+ }
+ else
+ {
+ $filtered[] = $part;
+ }
+ }
+ $path = implode('/', $filtered);
+ return $path;
+ }
+
+ /**
+ * Checks if a path is absolute or not
+ *
+ * @param string $path Path to check
+ *
+ * @return bool true if the path is absolute, false otherwise
+ */
+ public static function is_absolute_path($path)
+ {
+ return (isset($path[0]) && $path[0] === '/' || preg_match('#^[a-z]:[/\\\]#i', $path)) ? true : false;
+ }
+
+ /**
+ * Try to resolve real path when PHP's realpath failes to do so
+ *
+ * @param string $path
+ * @return bool|string
+ */
+ protected static function phpbb_own_realpath($path)
+ {
+ // Replace all directory separators with '/'
+ $path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
+
+ $is_absolute_path = false;
+ $path_prefix = '';
+
+ if (self::is_absolute_path($path))
+ {
+ $is_absolute_path = true;
+ }
+ else
+ {
+ if (function_exists('getcwd'))
+ {
+ $working_directory = str_replace(DIRECTORY_SEPARATOR, '/', getcwd());
+ }
+
+ //
+ // From this point on we really just guessing
+ // If chdir were called we screwed
+ //
+ else if (function_exists('debug_backtrace'))
+ {
+ $call_stack = debug_backtrace(0);
+ $working_directory = str_replace(DIRECTORY_SEPARATOR, '/', dirname($call_stack[count($call_stack) - 1]['file']));
+ }
+ else
+ {
+ //
+ // Assuming that the working directory is phpBB root
+ // we could use this as a fallback, when phpBB will use controllers
+ // everywhere this will be a safe assumption
+ //
+ //$dir_parts = explode(DIRECTORY_SEPARATOR, __DIR__);
+ //$namespace_parts = explode('\\', trim(__NAMESPACE__, '\\'));
+
+ //$namespace_part_count = count($namespace_parts);
+
+ // Check if we still loading from root
+ //if (array_slice($dir_parts, -$namespace_part_count) === $namespace_parts)
+ //{
+ // $working_directory = implode('/', array_slice($dir_parts, 0, -$namespace_part_count));
+ //}
+ //else
+ //{
+ // $working_directory = false;
+ //}
+
+ $working_directory = false;
+ }
+
+ if ($working_directory !== false)
+ {
+ $is_absolute_path = true;
+ $path = $working_directory . '/' . $path;
+ }
+ }
+
+ if ($is_absolute_path)
+ {
+ if (defined('PHP_WINDOWS_VERSION_MAJOR'))
+ {
+ $path_prefix = $path[0] . ':';
+ $path = substr($path, 2);
+ }
+ else
+ {
+ $path_prefix = '';
+ }
+ }
+
+ $resolved_path = self::resolve_path($path, $path_prefix, $is_absolute_path);
+ if ($resolved_path === false)
+ {
+ return false;
+ }
+
+ if (!@file_exists($resolved_path) || (!@is_dir($resolved_path . '/') && !is_file($resolved_path)))
+ {
+ return false;
+ }
+
+ // Return OS specific directory separators
+ $resolved = str_replace('/', DIRECTORY_SEPARATOR, $resolved_path);
+
+ // Check for DIRECTORY_SEPARATOR at the end (and remove it!)
+ if (substr($resolved, -1) === DIRECTORY_SEPARATOR)
+ {
+ return substr($resolved, 0, -1);
+ }
+
+ return $resolved;
+ }
+
+ /**
+ * A wrapper for PHP's realpath
+ *
+ * Try to resolve realpath when PHP's realpath is not available, or
+ * known to be buggy.
+ *
+ * @param string $path Path to resolve
+ *
+ * @return string Resolved path
+ */
+ public static function realpath($path)
+ {
+ if (!function_exists('realpath'))
+ {
+ return self::phpbb_own_realpath($path);
+ }
+
+ $realpath = realpath($path);
+
+ // Strangely there are provider not disabling realpath but returning strange values. :o
+ // We at least try to cope with them.
+ if ((!self::is_absolute_path($path) && $realpath === $path) || $realpath === false)
+ {
+ return self::phpbb_own_realpath($path);
+ }
+
+ // Check for DIRECTORY_SEPARATOR at the end (and remove it!)
+ if (substr($realpath, -1) === DIRECTORY_SEPARATOR)
+ {
+ $realpath = substr($realpath, 0, -1);
+ }
+
+ return $realpath;
+ }
+
+ /**
+ * Given an existing path, convert it to a path relative to a given starting path
+ *
+ * @param string $end_path Absolute path of target
+ * @param string $start_path Absolute path where traversal begins
+ *
+ * @return string Path of target relative to starting path
+ */
+ public static function make_path_relative($end_path, $start_path)
+ {
+ return self::get_symfony_filesystem()->makePathRelative($end_path, $start_path);
+ }
+
+ /**
+ * Try to resolve symlinks in path
+ *
+ * @param string $path The path to resolve
+ * @param string $prefix The path prefix (on windows the drive letter)
+ * @param bool $absolute Whether or not the path is absolute
+ * @param bool $return_array Whether or not to return path parts
+ *
+ * @return string|array|bool returns the resolved path or an array of parts of the path if $return_array is true
+ * or false if path cannot be resolved
+ */
+ public static function resolve_path($path, $prefix = '', $absolute = false, $return_array = false)
+ {
+ if ($return_array)
+ {
+ $path = str_replace(DIRECTORY_SEPARATOR, '/', $path);
+ }
+
+ trim($path, '/');
+ $path_parts = explode('/', $path);
+ $resolved = array();
+ $resolved_path = $prefix;
+ $file_found = false;
+
+ foreach ($path_parts as $path_part)
+ {
+ if ($file_found)
+ {
+ return false;
+ }
+
+ if (empty($path_part) || ($path_part === '.' && ($absolute || !empty($resolved))))
+ {
+ continue;
+ }
+ else if ($absolute && $path_part === '..')
+ {
+ if (empty($resolved))
+ {
+ // No directories above root
+ return false;
+ }
+
+ array_pop($resolved);
+ $resolved_path = false;
+ }
+ else if ($path_part === '..' && !empty($resolved) && !in_array($resolved[count($resolved) - 1], array('.', '..')))
+ {
+ array_pop($resolved);
+ $resolved_path = false;
+ }
+ else
+ {
+ if ($resolved_path === false)
+ {
+ if (empty($resolved))
+ {
+ $resolved_path = ($absolute) ? $prefix . '/' . $path_part : $path_part;
+ }
+ else
+ {
+ $tmp_array = $resolved;
+ if ($absolute)
+ {
+ array_unshift($tmp_array, $prefix);
+ }
+
+ $resolved_path = implode('/', $tmp_array);
+ }
+ }
+
+ $current_path = $resolved_path . '/' . $path_part;
+
+ // Resolve symlinks
+ if (@is_link($current_path))
+ {
+ if (!function_exists('readlink'))
+ {
+ return false;
+ }
+
+ $link = readlink($current_path);
+
+ // Is link has an absolute path in it?
+ if (self::is_absolute_path($link))
+ {
+ if (defined('PHP_WINDOWS_VERSION_MAJOR'))
+ {
+ $prefix = $link[0] . ':';
+ $link = substr($link, 2);
+ }
+ else
+ {
+ $prefix = '';
+ }
+
+ $resolved = self::resolve_path($link, $prefix, true, true);
+ $absolute = true;
+ }
+ else
+ {
+ $resolved = self::resolve_path($resolved_path . '/' . $link, $prefix, $absolute, true);
+ }
+
+ if (!$resolved)
+ {
+ return false;
+ }
+
+ $resolved_path = false;
+ }
+ else if (@is_dir($current_path . '/'))
+ {
+ $resolved[] = $path_part;
+ $resolved_path = $current_path;
+ }
+ else if (@is_file($current_path))
+ {
+ $resolved[] = $path_part;
+ $resolved_path = $current_path;
+ $file_found = true;
+ }
+ else
+ {
+ return false;
+ }
+ }
+ }
+
+ // If at the end of the path there were a .. or .
+ // we need to build the path again.
+ // Only doing this when a string is expected in return
+ if ($resolved_path === false && $return_array === false)
+ {
+ if (empty($resolved))
+ {
+ $resolved_path = ($absolute) ? $prefix . '/' : './';
+ }
+ else
+ {
+ $tmp_array = $resolved;
+ if ($absolute)
+ {
+ array_unshift($tmp_array, $prefix);
+ }
+
+ $resolved_path = implode('/', $tmp_array);
+ }
+ }
+
+ return $return_array ? $resolved : $resolved_path;
+ }
+
+ /**
+ * Get an instance of symfony's filesystem object.
+ *
+ * @return \Symfony\Component\Filesystem\Filesystem Symfony filesystem
+ */
+ protected static function get_symfony_filesystem()
+ {
+ if (self::$symfony_filesystem === null)
+ {
+ self::$symfony_filesystem = new symfony_filesystem();
+ }
+
+ return self::$symfony_filesystem;
+ }
+}
diff --git a/phpBB/phpbb/filesystem/temp.php b/phpBB/phpbb/filesystem/temp.php
new file mode 100644
index 0000000000..649221d802
--- /dev/null
+++ b/phpBB/phpbb/filesystem/temp.php
@@ -0,0 +1,54 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\filesystem;
+
+class temp
+{
+ /**
+ * @var string Temporary directory path
+ */
+ protected $temp_dir;
+
+ /**
+ * Constructor
+ */
+ public function __construct($filesystem, $cache_temp_dir)
+ {
+ $tmp_dir = (function_exists('sys_get_temp_dir')) ? sys_get_temp_dir() : '';
+
+ // Prevent trying to write to system temp dir in case of open_basedir
+ // restrictions being in effect
+ if (empty($tmp_dir) || !@file_exists($tmp_dir) || !@is_writable($tmp_dir))
+ {
+ $tmp_dir = $cache_temp_dir;
+
+ if (!is_dir($tmp_dir))
+ {
+ $filesystem->mkdir($tmp_dir, 0777);
+ }
+ }
+
+ $this->temp_dir = helper::realpath($tmp_dir);
+ }
+
+ /**
+ * Get a temporary directory to write files
+ *
+ * @return string returns the directory
+ */
+ public function get_dir()
+ {
+ return $this->temp_dir;
+ }
+}
diff --git a/phpBB/phpbb/finder.php b/phpBB/phpbb/finder.php
index 0a2b67a034..19056318f8 100644
--- a/phpBB/phpbb/finder.php
+++ b/phpBB/phpbb/finder.php
@@ -13,13 +13,14 @@
namespace phpbb;
+use phpbb\filesystem\helper as filesystem_helper;
+
/**
* The finder provides a simple way to locate files in the core and a set of extensions
*/
class finder
{
protected $extensions;
- protected $filesystem;
protected $phpbb_root_path;
protected $cache;
protected $php_ext;
@@ -48,16 +49,14 @@ class finder
/**
* Creates a new finder instance with its dependencies
*
- * @param \phpbb\filesystem\filesystem_interface $filesystem Filesystem instance
* @param string $phpbb_root_path Path to the phpbb root directory
* @param \phpbb\cache\service $cache A cache instance or null
* @param string $php_ext php file extension
* @param string $cache_name The name of the cache variable, defaults to
* _ext_finder
*/
- public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $phpbb_root_path = '', \phpbb\cache\service $cache = null, $php_ext = 'php', $cache_name = '_ext_finder')
+ public function __construct($phpbb_root_path = '', \phpbb\cache\service $cache = null, $php_ext = 'php', $cache_name = '_ext_finder')
{
- $this->filesystem = $filesystem;
$this->phpbb_root_path = $phpbb_root_path;
$this->cache = $cache;
$this->php_ext = $php_ext;
@@ -244,7 +243,7 @@ class finder
*/
protected function sanitise_directory($directory)
{
- $directory = $this->filesystem->clean_path($directory);
+ $directory = filesystem_helper::clean_path($directory);
$dir_len = strlen($directory);
if ($dir_len > 1 && $directory[$dir_len - 1] === '/')
diff --git a/phpBB/phpbb/hook/finder.php b/phpBB/phpbb/hook/finder.php
deleted file mode 100644
index f5a68a1370..0000000000
--- a/phpBB/phpbb/hook/finder.php
+++ /dev/null
@@ -1,91 +0,0 @@
-<?php
-/**
-*
-* This file is part of the phpBB Forum Software package.
-*
-* @copyright (c) phpBB Limited <https://www.phpbb.com>
-* @license GNU General Public License, version 2 (GPL-2.0)
-*
-* For full copyright and license information, please see
-* the docs/CREDITS.txt file.
-*
-*/
-
-namespace phpbb\hook;
-
-/**
-* The hook finder locates installed hooks.
-*/
-class finder
-{
- /**
- * @var \phpbb\cache\driver\driver_interface
- */
- protected $cache;
-
- /**
- * @var string
- */
- protected $phpbb_root_path;
-
- /**
- * @var string
- */
- protected $php_ext;
-
- /**
- * Creates a new finder instance.
- *
- * @param string $phpbb_root_path Path to the phpbb root directory
- * @param string $php_ext php file extension
- * @param \phpbb\cache\driver\driver_interface $cache A cache instance or null
- */
- public function __construct($phpbb_root_path, $php_ext, \phpbb\cache\driver\driver_interface $cache = null)
- {
- $this->phpbb_root_path = $phpbb_root_path;
- $this->cache = $cache;
- $this->php_ext = $php_ext;
- }
-
- /**
- * Finds all hook files.
- *
- * @param bool $cache Whether the result should be cached
- * @return array An array of paths to found hook files
- */
- public function find($cache = true)
- {
- if (!defined('DEBUG') && $cache && $this->cache)
- {
- $hook_files = $this->cache->get('_hooks');
- if ($hook_files !== false)
- {
- return $hook_files;
- }
- }
-
- $hook_files = array();
-
- // Now search for hooks...
- $dh = @opendir($this->phpbb_root_path . 'includes/hooks/');
-
- if ($dh)
- {
- while (($file = readdir($dh)) !== false)
- {
- if (strpos($file, 'hook_') === 0 && substr($file, -strlen('.' . $this->php_ext)) === '.' . $this->php_ext)
- {
- $hook_files[] = substr($file, 0, -(strlen($this->php_ext) + 1));
- }
- }
- closedir($dh);
- }
-
- if ($cache && $this->cache)
- {
- $this->cache->put('_hooks', $hook_files);
- }
-
- return $hook_files;
- }
-}
diff --git a/phpBB/phpbb/install/helper/database.php b/phpBB/phpbb/install/helper/database.php
index 51fd18f874..f495b47496 100644
--- a/phpBB/phpbb/install/helper/database.php
+++ b/phpBB/phpbb/install/helper/database.php
@@ -14,6 +14,7 @@
namespace phpbb\install\helper;
use phpbb\install\exception\invalid_dbms_exception;
+use phpbb\filesystem\helper as filesystem_helper;
/**
* Database related general functionality for installer
@@ -319,7 +320,7 @@ class database
// Make sure we don't have a daft user who thinks having the SQLite database in the forum directory is a good idea
if ($dbms_info['SCHEMA'] === 'sqlite'
- && stripos($this->filesystem->realpath($dbhost), $this->filesystem->realpath($this->phpbb_root_path) === 0))
+ && stripos(filesystem_helper::realpath($dbhost), filesystem_helper::realpath($this->phpbb_root_path) === 0))
{
$errors[] = array(
'title' =>'INST_ERR_DB_FORUM_PATH',
diff --git a/phpBB/phpbb/install/module/install_database/task/create_schema.php b/phpBB/phpbb/install/module/install_database/task/create_schema.php
index 983bb42122..46529d1542 100644
--- a/phpBB/phpbb/install/module/install_database/task/create_schema.php
+++ b/phpBB/phpbb/install/module/install_database/task/create_schema.php
@@ -13,7 +13,14 @@
namespace phpbb\install\module\install_database\task;
+use phpbb\db\driver\driver_interface;
+use phpbb\db\migration\schema_generator;
+use phpbb\db\tools\tools_interface;
+use phpbb\filesystem\filesystem_interface;
use phpbb\install\exception\resource_limit_reached_exception;
+use phpbb\install\helper\config;
+use phpbb\install\helper\database;
+use phpbb\install\helper\iohandler\iohandler_interface;
/**
* Create database schema
@@ -21,32 +28,32 @@ use phpbb\install\exception\resource_limit_reached_exception;
class create_schema extends \phpbb\install\task_base
{
/**
- * @var \phpbb\install\helper\config
+ * @var config
*/
protected $config;
/**
- * @var \phpbb\db\driver\driver_interface
+ * @var driver_interface
*/
protected $db;
/**
- * @var \phpbb\db\tools\tools_interface
+ * @var tools_interface
*/
protected $db_tools;
/**
- * @var \phpbb\install\helper\database
+ * @var database
*/
protected $database_helper;
/**
- * @var \phpbb\filesystem\filesystem_interface
+ * @var filesystem_interface
*/
protected $filesystem;
/**
- * @var \phpbb\install\helper\iohandler\iohandler_interface
+ * @var iohandler_interface
*/
protected $iohandler;
@@ -61,21 +68,28 @@ class create_schema extends \phpbb\install\task_base
protected $php_ext;
/**
+ * @var array
+ */
+ protected $tables;
+
+ /**
* Constructor
*
- * @param \phpbb\install\helper\config $config Installer's config provider
- * @param \phpbb\install\helper\database $db_helper Installer's database helper
- * @param \phpbb\filesystem\filesystem_interface $filesystem Filesystem service
- * @param \phpbb\install\helper\iohandler\iohandler_interface $iohandler Installer's input-output handler
- * @param string $phpbb_root_path Path phpBB's root
- * @param string $php_ext Extension of PHP files
+ * @param config $config Installer's config provider
+ * @param database $db_helper Installer's database helper
+ * @param filesystem_interface $filesystem Filesystem service
+ * @param iohandler_interface $iohandler Installer's input-output handler
+ * @param string $phpbb_root_path Path phpBB's root
+ * @param string $php_ext Extension of PHP files
+ * @param array $tables Tables array
*/
- public function __construct(\phpbb\install\helper\config $config,
- \phpbb\install\helper\database $db_helper,
- \phpbb\filesystem\filesystem_interface $filesystem,
- \phpbb\install\helper\iohandler\iohandler_interface $iohandler,
+ public function __construct(config $config,
+ database $db_helper,
+ filesystem_interface $filesystem,
+ iohandler_interface $iohandler,
$phpbb_root_path,
- $php_ext)
+ $php_ext,
+ $tables)
{
$dbms = $db_helper->get_available_dbms($config->get('dbms'));
$dbms = $dbms[$config->get('dbms')]['DRIVER'];
@@ -99,6 +113,7 @@ class create_schema extends \phpbb\install\task_base
$this->iohandler = $iohandler;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
+ $this->tables = $tables;
parent::__construct(true);
}
@@ -176,18 +191,19 @@ class create_schema extends \phpbb\install\task_base
include ($this->phpbb_root_path . 'includes/constants.' . $this->php_ext);
}
- $finder = new \phpbb\finder($this->filesystem, $this->phpbb_root_path, null, $this->php_ext);
+ $finder = new \phpbb\finder($this->phpbb_root_path, null, $this->php_ext);
$migrator_classes = $finder->core_path('phpbb/db/migration/data/')->get_classes();
$factory = new \phpbb\db\tools\factory();
$db_tools = $factory->get($this->db, true);
- $schema_generator = new \phpbb\db\migration\schema_generator(
+ $schema_generator = new schema_generator(
$migrator_classes,
new \phpbb\config\config(array()),
$this->db,
$db_tools,
$this->phpbb_root_path,
$this->php_ext,
- $table_prefix
+ $table_prefix,
+ $this->tables
);
$db_table_schema = $schema_generator->get_schema();
}
diff --git a/phpBB/phpbb/install/module/install_database/task/create_schema_file.php b/phpBB/phpbb/install/module/install_database/task/create_schema_file.php
index b6d6ece17f..4dfaa07ebf 100644
--- a/phpBB/phpbb/install/module/install_database/task/create_schema_file.php
+++ b/phpBB/phpbb/install/module/install_database/task/create_schema_file.php
@@ -117,10 +117,17 @@ class create_schema_file extends \phpbb\install\task_base
include ($this->phpbb_root_path . 'includes/constants.' . $this->php_ext);
}
- $finder = new \phpbb\finder($this->filesystem, $this->phpbb_root_path, null, $this->php_ext);
+ $finder = new \phpbb\finder($this->phpbb_root_path, null, $this->php_ext);
$migrator_classes = $finder->core_path('phpbb/db/migration/data/')->get_classes();
$factory = new \phpbb\db\tools\factory();
$db_tools = $factory->get($this->db, true);
+ $tables_data = \Symfony\Component\Yaml\Yaml::parseFile($this->phpbb_root_path . '/config/default/container/tables.yml');
+ $tables = [];
+ foreach ($tables_data['parameters'] as $parameter => $table)
+ {
+ $tables[str_replace('tables.', '', $parameter)] = str_replace('%core.table_prefix%', $table_prefix, $table);
+ }
+
$schema_generator = new \phpbb\db\migration\schema_generator(
$migrator_classes,
new \phpbb\config\config(array()),
@@ -128,7 +135,8 @@ class create_schema_file extends \phpbb\install\task_base
$db_tools,
$this->phpbb_root_path,
$this->php_ext,
- $table_prefix
+ $table_prefix,
+ $tables
);
$db_table_schema = $schema_generator->get_schema();
$db_table_schema = json_encode($db_table_schema, JSON_PRETTY_PRINT);
diff --git a/phpBB/phpbb/path_helper.php b/phpBB/phpbb/path_helper.php
index 5b6db35f23..e58704937f 100644
--- a/phpBB/phpbb/path_helper.php
+++ b/phpBB/phpbb/path_helper.php
@@ -13,6 +13,8 @@
namespace phpbb;
+use phpbb\filesystem\helper as filesystem_helper;
+
/**
* A class with various functions that are related to paths, files and the filesystem
*/
@@ -21,9 +23,6 @@ class path_helper
/** @var \phpbb\symfony_request */
protected $symfony_request;
- /** @var \phpbb\filesystem\filesystem_interface */
- protected $filesystem;
-
/** @var \phpbb\request\request_interface */
protected $request;
@@ -43,16 +42,14 @@ class path_helper
* Constructor
*
* @param \phpbb\symfony_request $symfony_request
- * @param \phpbb\filesystem\filesystem_interface $filesystem
* @param \phpbb\request\request_interface $request
* @param string $phpbb_root_path Relative path to phpBB root
* @param string $php_ext PHP file extension
* @param mixed $adm_relative_path Relative path admin path to adm/ root
*/
- public function __construct(\phpbb\symfony_request $symfony_request, \phpbb\filesystem\filesystem_interface $filesystem, \phpbb\request\request_interface $request, $phpbb_root_path, $php_ext, $adm_relative_path = null)
+ public function __construct(\phpbb\symfony_request $symfony_request, \phpbb\request\request_interface $request, $phpbb_root_path, $php_ext, $adm_relative_path = null)
{
$this->symfony_request = $symfony_request;
- $this->filesystem = $filesystem;
$this->request = $request;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
@@ -117,7 +114,7 @@ class path_helper
$path = substr($path, 8);
}
- return $this->filesystem->clean_path($web_root_path . $path);
+ return filesystem_helper::clean_path($web_root_path . $path);
}
return $path;
@@ -163,7 +160,7 @@ class path_helper
// We do not need to escape $path_info, $request_uri and $script_name because we can not find their content in the result.
// Path info (e.g. /foo/bar)
- $path_info = $this->filesystem->clean_path($this->symfony_request->getPathInfo());
+ $path_info = filesystem_helper::clean_path($this->symfony_request->getPathInfo());
// Full request URI (e.g. phpBB/app.php/foo/bar)
$request_uri = $this->symfony_request->getRequestUri();
@@ -178,7 +175,7 @@ class path_helper
*/
if ($path_info === '/' && preg_match('/app\.' . $this->php_ext . '\/$/', $request_uri))
{
- return $this->web_root_path = $this->filesystem->clean_path('./../' . $this->phpbb_root_path);
+ return $this->web_root_path = filesystem_helper::clean_path('./../' . $this->phpbb_root_path);
}
/*
@@ -235,7 +232,7 @@ class path_helper
}
// Prepend ../ to the phpbb_root_path as many times as / exists in path_info
- $this->web_root_path = $this->filesystem->clean_path(
+ $this->web_root_path = filesystem_helper::clean_path(
'./' . str_repeat('../', $corrections) . $this->phpbb_root_path
);
return $this->web_root_path;
@@ -326,7 +323,7 @@ class path_helper
// Add length of URL delimiter to position
$path = substr($url, $delimiter_position + 3);
- return $scheme . $this->filesystem->clean_path($path);
+ return $scheme . filesystem_helper::clean_path($path);
}
/**
diff --git a/phpBB/phpbb/permissions.php b/phpBB/phpbb/permissions.php
index 236535cc6a..a88e82d531 100644
--- a/phpBB/phpbb/permissions.php
+++ b/phpBB/phpbb/permissions.php
@@ -350,6 +350,7 @@ class permissions
'a_roles' => array('lang' => 'ACL_A_ROLES', 'cat' => 'permissions'),
'a_switchperm' => array('lang' => 'ACL_A_SWITCHPERM', 'cat' => 'permissions'),
+ 'a_storage' => array('lang' => 'ACL_A_STORAGE', 'cat' => 'misc'),
'a_styles' => array('lang' => 'ACL_A_STYLES', 'cat' => 'misc'),
'a_extensions' => array('lang' => 'ACL_A_EXTENSIONS', 'cat' => 'misc'),
'a_viewlogs' => array('lang' => 'ACL_A_VIEWLOGS', 'cat' => 'misc'),
diff --git a/phpBB/phpbb/routing/file_locator.php b/phpBB/phpbb/routing/file_locator.php
index 64efcc6c76..bd2c1850bb 100644
--- a/phpBB/phpbb/routing/file_locator.php
+++ b/phpBB/phpbb/routing/file_locator.php
@@ -13,19 +13,19 @@
namespace phpbb\routing;
-use phpbb\filesystem\filesystem_interface;
use Symfony\Component\Config\FileLocator;
+use phpbb\filesystem\helper as filesystem_helper;
class file_locator extends FileLocator
{
- public function __construct(filesystem_interface $filesystem, $paths = [])
+ public function __construct($paths = [])
{
$paths = (array) $paths;
$absolute_paths = [];
foreach ($paths as $path)
{
- $absolute_paths[] = $filesystem->realpath($path);
+ $absolute_paths[] = filesystem_helper::realpath($path);
}
parent::__construct($absolute_paths);
diff --git a/phpBB/phpbb/routing/helper.php b/phpBB/phpbb/routing/helper.php
index c15608dce5..3d38105aa3 100644
--- a/phpBB/phpbb/routing/helper.php
+++ b/phpBB/phpbb/routing/helper.php
@@ -15,6 +15,7 @@ namespace phpbb\routing;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Routing\RequestContext;
+use phpbb\filesystem\helper as filesystem_helper;
/**
* Controller helper class, contains methods that do things for controllers
@@ -44,11 +45,6 @@ class helper
protected $request;
/**
- * @var \phpbb\filesystem The filesystem object
- */
- protected $filesystem;
-
- /**
* phpBB root path
* @var string
*/
@@ -67,17 +63,15 @@ class helper
* @param \phpbb\routing\router $router phpBB router
* @param \phpbb\symfony_request $symfony_request Symfony Request object
* @param \phpbb\request\request_interface $request phpBB request object
- * @param \phpbb\filesystem\filesystem $filesystem The filesystem object
* @param string $phpbb_root_path phpBB root path
* @param string $php_ext PHP file extension
*/
- public function __construct(\phpbb\config\config $config, \phpbb\routing\router $router, \phpbb\symfony_request $symfony_request, \phpbb\request\request_interface $request, \phpbb\filesystem\filesystem $filesystem, $phpbb_root_path, $php_ext)
+ public function __construct(\phpbb\config\config $config, \phpbb\routing\router $router, \phpbb\symfony_request $symfony_request, \phpbb\request\request_interface $request, $phpbb_root_path, $php_ext)
{
$this->config = $config;
$this->router = $router;
$this->symfony_request = $symfony_request;
$this->request = $request;
- $this->filesystem = $filesystem;
$this->phpbb_root_path = $phpbb_root_path;
$this->php_ext = $php_ext;
}
@@ -140,7 +134,7 @@ class helper
}
}
- $base_url = $this->request->escape($this->filesystem->clean_path($base_url), true);
+ $base_url = $this->request->escape(filesystem_helper::clean_path($base_url), true);
$context->setBaseUrl($base_url);
diff --git a/phpBB/phpbb/session.php b/phpBB/phpbb/session.php
index 6851bc8188..cdadf2e389 100644
--- a/phpBB/phpbb/session.php
+++ b/phpBB/phpbb/session.php
@@ -13,6 +13,8 @@
namespace phpbb;
+use phpbb\filesystem\helper as filesystem_helper;
+
/**
* Session class
*/
@@ -38,7 +40,7 @@ class session
*/
static function extract_current_page($root_path)
{
- global $request, $symfony_request, $phpbb_filesystem;
+ global $request, $symfony_request;
$page_array = array();
@@ -85,7 +87,7 @@ class session
$page_name = (substr($script_name, -1, 1) == '/') ? '' : basename($script_name);
$page_name = urlencode(htmlspecialchars($page_name));
- $symfony_request_path = $phpbb_filesystem->clean_path($symfony_request->getPathInfo());
+ $symfony_request_path = filesystem_helper::clean_path($symfony_request->getPathInfo());
if ($symfony_request_path !== '/')
{
$page_name .= str_replace('%2F', '/', urlencode($symfony_request_path));
@@ -99,8 +101,8 @@ class session
else
{
// current directory within the phpBB root (for example: adm)
- $root_dirs = explode('/', str_replace('\\', '/', $phpbb_filesystem->realpath($root_path)));
- $page_dirs = explode('/', str_replace('\\', '/', $phpbb_filesystem->realpath('./')));
+ $root_dirs = explode('/', str_replace('\\', '/', filesystem_helper::realpath($root_path)));
+ $page_dirs = explode('/', str_replace('\\', '/', filesystem_helper::realpath('./')));
}
$intersection = array_intersect_assoc($root_dirs, $page_dirs);
diff --git a/phpBB/phpbb/storage/adapter/adapter_interface.php b/phpBB/phpbb/storage/adapter/adapter_interface.php
new file mode 100644
index 0000000000..9c97f34a11
--- /dev/null
+++ b/phpBB/phpbb/storage/adapter/adapter_interface.php
@@ -0,0 +1,103 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\storage\adapter;
+
+interface adapter_interface
+{
+ /**
+ * Set adapter parameters
+ *
+ * @param array options Storage-specific options.
+ */
+ public function configure($options);
+
+ /**
+ * Dumps content into a file
+ *
+ * @param string path The file to be written to.
+ * @param string content The data to write into the file.
+ *
+ * @throws \phpbb\storage\exception\exception When the file cannot be written
+ */
+ public function put_contents($path, $content);
+
+ /**
+ * Read the contents of a file
+ *
+ * @param string $path The file to read
+ *
+ * @throws \phpbb\storage\exception\exception When cannot read file contents
+ *
+ * @return string Returns file contents
+ *
+ */
+ public function get_contents($path);
+
+ /**
+ * Checks the existence of files or directories
+ *
+ * @param string $path file/directory to check
+ *
+ * @return bool Returns true if the file/directory exist, false otherwise.
+ */
+ public function exists($path);
+
+ /**
+ * Removes files or directories
+ *
+ * @param string $path file/directory to remove
+ *
+ * @throws \phpbb\storage\exception\exception When removal fails.
+ */
+ public function delete($path);
+
+ /**
+ * Rename a file or a directory
+ *
+ * @param string $path_orig The original file/direcotry
+ * @param string $path_dest The target file/directory
+ *
+ * @throws \phpbb\storage\exception\exception When file/directory cannot be renamed
+ */
+ public function rename($path_orig, $path_dest);
+
+ /**
+ * Copies a file
+ *
+ * @param string $path_orig The original filename
+ * @param string $path_dest The target filename
+ *
+ * @throws \phpbb\storage\exception\exception When the file cannot be copied
+ */
+ public function copy($path_orig, $path_dest);
+
+ /**
+ * Get direct link
+ *
+ * @param string $path The file
+ *
+ * @return string Returns link.
+ *
+ */
+ public function get_link($path);
+
+ /*
+ * Get space available in bytes
+ *
+ * @throws \phpbb\storage\exception\exception When unable to retrieve available storage space
+ *
+ * @return float Returns available space
+ */
+ public function free_space();
+}
diff --git a/phpBB/phpbb/storage/adapter/local.php b/phpBB/phpbb/storage/adapter/local.php
new file mode 100644
index 0000000000..132c16230d
--- /dev/null
+++ b/phpBB/phpbb/storage/adapter/local.php
@@ -0,0 +1,440 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\storage\adapter;
+
+use phpbb\storage\stream_interface;
+use phpbb\storage\exception\exception;
+use phpbb\filesystem\exception\filesystem_exception;
+use phpbb\filesystem\filesystem;
+use phpbb\filesystem\helper as filesystem_helper;
+use phpbb\mimetype\guesser;
+use FastImageSize\FastImageSize;
+
+/**
+ * @internal Experimental
+ */
+class local implements adapter_interface, stream_interface
+{
+ /**
+ * Filesystem component
+ *
+ * @var \phpbb\filesystem\filesystem
+ */
+ protected $filesystem;
+
+ /**
+ * FastImageSize
+ *
+ * @var \FastImageSize\FastImageSize
+ */
+ protected $imagesize;
+
+ /**
+ * Mimetype Guesser component
+ *
+ * @var \phpbb\mimetype\guesser
+ */
+ protected $mimetype_guesser;
+
+ /**
+ * @var string path
+ */
+ protected $phpbb_root_path;
+
+ /**
+ * @var string path
+ */
+ protected $root_path;
+
+ /**
+ * @var string path
+ */
+ protected $path;
+
+ /*
+ * Subdirectories depth
+ *
+ * Instead of storing all folders in the same directory, they can be divided
+ * into smaller directories. The variable describes the number of subdirectories
+ * to be used for storing the files. For example:
+ * depth = 0 -> /images/avatars/upload/my_avatar.jpg
+ * depth = 2 -> /images/avatars/upload/d9/8c/my_avatar.jpg
+ * This is for those who have problems storing a large number of files in
+ * a single directory.
+ * More info: https://tracker.phpbb.com/browse/PHPBB3-15371
+ */
+
+ /*
+ * @var bool subfolders
+ */
+ protected $subfolders;
+
+ /*
+ * @var int dir_depth
+ */
+ protected $dir_depth = 2;
+
+ /**
+ * Constructor
+ */
+ public function __construct(filesystem $filesystem, FastImageSize $imagesize, guesser $mimetype_guesser, $phpbb_root_path)
+ {
+ $this->filesystem = $filesystem;
+ $this->imagesize = $imagesize;
+ $this->mimetype_guesser = $mimetype_guesser;
+ $this->phpbb_root_path = $phpbb_root_path;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function configure($options)
+ {
+ if (substr($options['path'], -1, 1) !== DIRECTORY_SEPARATOR)
+ {
+ $options['path'] = $options['path'] . DIRECTORY_SEPARATOR;
+ }
+
+ $this->path = $options['path'];
+ $this->root_path = $this->phpbb_root_path . $options['path'];
+ $this->subfolders = (bool) $options['subfolders'];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function put_contents($path, $content)
+ {
+ $this->ensure_directory_exists($path);
+
+ try
+ {
+ $this->filesystem->dump_file($this->root_path . $this->get_path($path) . $this->get_filename($path), $content);
+ }
+ catch (filesystem_exception $e)
+ {
+ throw new exception('STORAGE_CANNOT_WRITE_FILE', $path, array(), $e);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_contents($path)
+ {
+ $content = @file_get_contents($this->root_path . $this->get_path($path) . $this->get_filename($path));
+
+ if ($content === false)
+ {
+ throw new exception('STORAGE_CANNOT_READ_FILE', $path);
+ }
+
+ return $content;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function exists($path)
+ {
+ return $this->filesystem->exists($this->root_path . $this->get_path($path) . $this->get_filename($path));
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function delete($path)
+ {
+ try
+ {
+ $this->filesystem->remove($this->root_path . $this->get_path($path) . $this->get_filename($path));
+ }
+ catch (filesystem_exception $e)
+ {
+ throw new exception('STORAGE_CANNOT_DELETE', $path, array(), $e);
+ }
+
+ $this->remove_empty_dirs($path);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function rename($path_orig, $path_dest)
+ {
+ $this->ensure_directory_exists($path_dest);
+
+ try
+ {
+ $this->filesystem->rename($this->root_path . $this->get_path($path_orig) . $this->get_filename($path_orig), $this->root_path . $this->get_path($path_dest) . $this->get_filename($path_dest), false);
+ }
+ catch (filesystem_exception $e)
+ {
+ throw new exception('STORAGE_CANNOT_RENAME', $path_orig, array(), $e);
+ }
+
+ $this->remove_empty_dirs($path_orig);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function copy($path_orig, $path_dest)
+ {
+ $this->ensure_directory_exists($path_dest);
+
+ try
+ {
+ $this->filesystem->copy($this->root_path . $this->get_path($path_orig) . $this->get_filename($path_orig), $this->root_path . $this->get_path($path_dest) . $this->get_filename($path_dest), false);
+ }
+ catch (filesystem_exception $e)
+ {
+ throw new exception('STORAGE_CANNOT_COPY', $path_orig, array(), $e);
+ }
+ }
+
+ /**
+ * Creates a directory recursively.
+ *
+ * @param string $path The directory path
+ *
+ * @throws \phpbb\storage\exception\exception On any directory creation failure
+ */
+ protected function create_dir($path)
+ {
+ try
+ {
+ $this->filesystem->mkdir($this->root_path . $path);
+ }
+ catch (filesystem_exception $e)
+ {
+ throw new exception('STORAGE_CANNOT_CREATE_DIR', $path, array(), $e);
+ }
+ }
+
+ /**
+ * Ensures that the directory of a file exists.
+ *
+ * @param string $path The file path
+ */
+ protected function ensure_directory_exists($path)
+ {
+ $path = dirname($this->root_path . $this->get_path($path) . $this->get_filename($path));
+ $path = filesystem_helper::make_path_relative($path, $this->root_path);
+
+ if (!$this->exists($path))
+ {
+ $this->create_dir($path);
+ }
+ }
+
+ /**
+ * Removes the directory tree ascending until it finds a non empty directory.
+ *
+ * @param string $path The file path
+ */
+ protected function remove_empty_dirs($path)
+ {
+ if ($this->subfolders)
+ {
+ $dirpath = dirname($this->root_path . $path);
+ $filepath = dirname($this->root_path . $this->get_path($path) . $this->get_filename($path));
+ $path = filesystem_helper::make_path_relative($filepath, $dirpath);
+
+ do
+ {
+ $parts = explode('/', $path);
+ $parts = array_slice($parts, 0, -1);
+ $path = implode('/', $parts);
+ }
+ while ($path && @rmdir($dirpath . '/' . $path));
+ }
+ }
+
+ /**
+ * Get the path to the file, appending subdirectories for directory depth
+ * if $dir_depth > 0.
+ *
+ * @param string $path The file path
+ */
+ protected function get_path($path)
+ {
+ $dirname = dirname($path);
+ $dirname = ($dirname != '.') ? $dirname . DIRECTORY_SEPARATOR : '';
+
+ if ($this->subfolders)
+ {
+ $hash = md5(basename($path));
+
+ $parts = str_split($hash, 2);
+ $parts = array_slice($parts, 0, $this->dir_depth);
+
+ if (!empty($parts))
+ {
+ $dirname .= implode(DIRECTORY_SEPARATOR, $parts) . DIRECTORY_SEPARATOR;
+ }
+ }
+
+ return $dirname;
+ }
+
+ /**
+ * To be used in other PR
+ *
+ * @param string $path The file path
+ */
+ protected function get_filename($path)
+ {
+ return basename($path);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function read_stream($path)
+ {
+ $stream = @fopen($this->root_path . $this->get_path($path) . $this->get_filename($path), 'rb');
+
+ if (!$stream)
+ {
+ throw new exception('STORAGE_CANNOT_OPEN_FILE', $path);
+ }
+
+ return $stream;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function write_stream($path, $resource)
+ {
+ $this->ensure_directory_exists($path);
+
+ $stream = @fopen($this->root_path . $this->get_path($path) . $this->get_filename($path), 'w+b');
+
+ if (!$stream)
+ {
+ throw new exception('STORAGE_CANNOT_CREATE_FILE', $path);
+ }
+
+ if (stream_copy_to_stream($resource, $stream) === false)
+ {
+ fclose($stream);
+ throw new exception('STORAGE_CANNOT_COPY_RESOURCE');
+ }
+
+ fclose($stream);
+ }
+
+ /**
+ * Get file size
+ *
+ * @param string $path The file
+ *
+ * @throws \phpbb\storage\exception\exception When cannot get size
+ *
+ * @return array Properties
+ */
+ public function file_size($path)
+ {
+ $size = @filesize($this->root_path . $this->get_path($path) . $this->get_filename($path));
+
+ if ($size === null)
+ {
+ throw new exception('STORAGE_CANNOT_GET_FILESIZE');
+ }
+
+ return ['size' => $size];
+ }
+
+ /**
+ * Get file mimetype
+ *
+ * @param string $path The file
+ *
+ * @return array Properties
+ */
+ public function file_mimetype($path)
+ {
+ return ['mimetype' => $this->mimetype_guesser->guess($this->root_path . $this->get_path($path) . $this->get_filename($path))];
+ }
+
+ /**
+ * Get image dimensions
+ *
+ * @param string $path The file
+ *
+ * @return array Properties
+ */
+ protected function image_dimensions($path)
+ {
+ $size = $this->imagesize->getImageSize($this->root_path . $this->get_path($path) . $this->get_filename($path));
+
+ // For not supported types like swf
+ if ($size === false)
+ {
+ $imsize = getimagesize($this->root_path . $this->get_path($path) . $this->get_filename($path));
+ $size = ['width' => $imsize[0], 'height' => $imsize[1]];
+ }
+
+ return ['image_width' => $size['width'], 'image_height' => $size['height']];
+ }
+
+ /**
+ * Get image width
+ *
+ * @param string $path The file
+ *
+ * @return array Properties
+ */
+ public function file_image_width($path)
+ {
+ return $this->image_dimensions($path);
+ }
+
+ /**
+ * Get image height
+ *
+ * @param string $path The file
+ *
+ * @return array Properties
+ */
+ public function file_image_height($path)
+ {
+ return $this->image_dimensions($path);
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_link($path)
+ {
+ return generate_board_url() . '/' . $this->path . $path;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function free_space()
+ {
+ $free_space = @disk_free_space($this->root_path);
+
+ if ($free_space === false)
+ {
+ throw new exception('STORAGE_CANNOT_GET_FREE_SPACE');
+ }
+
+ return $free_space;
+ }
+}
diff --git a/phpBB/phpbb/storage/adapter_factory.php b/phpBB/phpbb/storage/adapter_factory.php
new file mode 100644
index 0000000000..6be702c0c8
--- /dev/null
+++ b/phpBB/phpbb/storage/adapter_factory.php
@@ -0,0 +1,93 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\storage;
+
+use phpbb\config\config;
+use phpbb\di\service_collection;
+use phpbb\storage\exception\exception;
+
+class adapter_factory
+{
+ /**
+ * @var \phpbb\config\config
+ */
+ protected $config;
+
+ /**
+ * @var \phpbb\di\service_collection
+ */
+ protected $adapters;
+
+ /**
+ * @var \phpbb\di\service_collection
+ */
+ protected $providers;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\config\config $config
+ * @param \phpbb\di\service_collection $adapters
+ * @param \phpbb\di\service_collection $providers
+ */
+ public function __construct(config $config, service_collection $adapters, service_collection $providers)
+ {
+ $this->config = $config;
+ $this->adapters = $adapters;
+ $this->providers = $providers;
+ }
+
+ /**
+ * Obtains a configured adapters for a given storage
+ *
+ * @param string $storage_name
+ *
+ * @return \phpbb\storage\adapter\adapter_interface
+ */
+ public function get($storage_name)
+ {
+ $provider_class = $this->config['storage\\' . $storage_name . '\\provider'];
+ $provider = $this->providers->get_by_class($provider_class);
+
+ if (!$provider->is_available())
+ {
+ throw new exception('STORAGE_ADAPTER_NOT_AVAILABLE');
+ }
+
+ $adapter = $this->adapters->get_by_class($provider->get_adapter_class());
+ $adapter->configure($this->build_options($storage_name, $provider->get_options()));
+
+ return $adapter;
+ }
+
+ /**
+ * Obtains configuration for a given storage
+ *
+ * @param string $storage_name
+ * @param array $definitions
+ *
+ * @return array Returns storage configuration values
+ */
+ public function build_options($storage_name, array $definitions)
+ {
+ $options = [];
+
+ foreach (array_keys($definitions) as $definition)
+ {
+ $options[$definition] = $this->config['storage\\' . $storage_name . '\\config\\' . $definition];
+ }
+
+ return $options;
+ }
+}
diff --git a/phpBB/phpbb/storage/exception/exception.php b/phpBB/phpbb/storage/exception/exception.php
new file mode 100644
index 0000000000..3a587bea3f
--- /dev/null
+++ b/phpBB/phpbb/storage/exception/exception.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\storage\exception;
+
+use phpbb\exception\runtime_exception;
+
+class exception extends runtime_exception
+{
+ /**
+ * Constructor
+ *
+ * @param string $message The Exception message to throw (must be a language variable)
+ * @param string $filename The file that caused the error
+ * @param array $parameters The parameters to use with the language var
+ * @param \Exception $previous The previous runtime_exception used for the runtime_exception chaining
+ * @param integer $code The Exception code
+ */
+ public function __construct($message = '', $filename = '', $parameters = [], \Exception $previous = null, $code = 0)
+ {
+ parent::__construct($message, array_merge(array('filename' => $filename), $parameters), $previous, $code);
+ }
+
+ /**
+ * Returns the filename that triggered the error
+ *
+ * @return string
+ */
+ public function get_filename()
+ {
+ $parameters = $this->get_parameters();
+ return $parameters['filename'];
+ }
+}
diff --git a/phpBB/phpbb/storage/file_info.php b/phpBB/phpbb/storage/file_info.php
new file mode 100644
index 0000000000..6b10e6892a
--- /dev/null
+++ b/phpBB/phpbb/storage/file_info.php
@@ -0,0 +1,85 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\storage;
+
+use phpbb\storage\exception\exception;
+use phpbb\storage\adapter\adapter_interface;
+
+class file_info
+{
+ /**
+ * @var \phpbb\storage\adapter\adapter_interface
+ */
+ protected $adapter;
+
+ /**
+ * Path of the file
+ *
+ * @var string
+ */
+ protected $path;
+
+ /**
+ * Stores the properties of $path file, so dont have to be consulted multiple times.
+ * For example, when you need the width of an image, using getimagesize() you get
+ * both dimensions, so you store both here, and when you get the height, you dont have
+ * to call getimagesize() again
+ *
+ * @var array
+ */
+ protected $properties;
+
+ /**
+ * Constructor
+ *
+ * @param \Symfony\Component\DependencyInjection\ContainerInterface $adapter
+ * @param string $path
+ */
+ public function __construct(adapter_interface $adapter, $path)
+ {
+ $this->adapter = $adapter;
+ $this->path = $path;
+ $this->properties = [];
+ }
+
+ /**
+ * Load propertys lazily
+ *
+ * @param string name The property name.
+ *
+ * @return string Returns the property value
+ */
+ public function get($name)
+ {
+ if (!isset($this->properties[$name]))
+ {
+ if (!method_exists($this->adapter, 'file_' . $name))
+ {
+ throw new exception('STORAGE_METHOD_NOT_IMPLEMENTED');
+ }
+
+ $this->properties = array_merge($this->properties, call_user_func([$this->adapter, 'file_' . $name], $this->path));
+ }
+
+ return $this->properties[$name];
+ }
+
+ /**
+ * Alias of \phpbb\storage\file_info->get()
+ */
+ public function __get($name)
+ {
+ return $this->get($name);
+ }
+}
diff --git a/phpBB/phpbb/storage/provider/local.php b/phpBB/phpbb/storage/provider/local.php
new file mode 100644
index 0000000000..8e0de2b6fd
--- /dev/null
+++ b/phpBB/phpbb/storage/provider/local.php
@@ -0,0 +1,58 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\storage\provider;
+
+class local implements provider_interface
+{
+ /**
+ * {@inheritdoc}
+ */
+ public function get_name()
+ {
+ return 'local';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_adapter_class()
+ {
+ return \phpbb\storage\adapter\local::class;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get_options()
+ {
+ return [
+ 'path' => ['type' => 'text'],
+ 'subfolders' => [
+ 'type' => 'radio',
+ 'options' => [
+ 'ENABLE' => '1',
+ 'DISABLE' => '0',
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function is_available()
+ {
+ return true;
+ }
+}
diff --git a/phpBB/phpbb/storage/provider/provider_interface.php b/phpBB/phpbb/storage/provider/provider_interface.php
new file mode 100644
index 0000000000..428b6eb187
--- /dev/null
+++ b/phpBB/phpbb/storage/provider/provider_interface.php
@@ -0,0 +1,45 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\storage\provider;
+
+interface provider_interface
+{
+ /**
+ * Gets adapter name
+ *
+ * @return string
+ */
+ public function get_name();
+
+ /**
+ * Gets adapter class
+ *
+ * @return \phpbb\storage\adapter\adapter_interface
+ */
+ public function get_adapter_class();
+
+ /**
+ * Gets adapter options
+ *
+ * @return array Configuration keys
+ */
+ public function get_options();
+
+ /**
+ * Return true if the adapter is available
+ *
+ * @return bool
+ */
+ public function is_available();
+}
diff --git a/phpBB/phpbb/storage/storage.php b/phpBB/phpbb/storage/storage.php
new file mode 100644
index 0000000000..7ba26d6b95
--- /dev/null
+++ b/phpBB/phpbb/storage/storage.php
@@ -0,0 +1,495 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\storage;
+
+use phpbb\cache\driver\driver_interface as cache;
+use phpbb\db\driver\driver_interface as db;
+use phpbb\storage\exception\exception;
+
+/**
+ * @internal Experimental
+ */
+class storage
+{
+ /**
+ * @var \phpbb\storage\adapter\adapter_interface
+ */
+ protected $adapter;
+
+ /**
+ * @var \phpbb\db\driver\driver_interface
+ */
+ protected $db;
+
+ /**
+ * Cache driver
+ * @var \phpbb\cache\driver\driver_interface
+ */
+ protected $cache;
+
+ /**
+ * @var \phpbb\storage\adapter_factory
+ */
+ protected $factory;
+
+ /**
+ * @var string
+ */
+ protected $storage_name;
+
+ /**
+ * @var string
+ */
+ protected $storage_table;
+
+ /**
+ * Constructor
+ *
+ * @param \phpbb\db\driver\driver_interface $db
+ * @param \phpbb\cache\driver\driver_interface $cache
+ * @param \phpbb\storage\adapter_factory $factory
+ * @param string $storage_name
+ * @param string $storage_table
+ */
+ public function __construct(db $db, cache $cache, adapter_factory $factory, $storage_name, $storage_table)
+ {
+ $this->db = $db;
+ $this->cache = $cache;
+ $this->factory = $factory;
+ $this->storage_name = $storage_name;
+ $this->storage_table = $storage_table;
+ }
+
+ /**
+ * Returns storage name
+ *
+ * @return string
+ */
+ public function get_name()
+ {
+ return $this->storage_name;
+ }
+
+ /**
+ * Returns an adapter instance
+ *
+ * @return \phpbb\storage\adapter\adapter_interface
+ */
+ protected function get_adapter()
+ {
+ if ($this->adapter === null)
+ {
+ $this->adapter = $this->factory->get($this->storage_name);
+ }
+
+ return $this->adapter;
+ }
+
+ /**
+ * Dumps content into a file
+ *
+ * @param string path The file to be written to.
+ * @param string content The data to write into the file.
+ *
+ * @throws \phpbb\storage\exception\exception When the file already exists
+ * When the file cannot be written
+ */
+ public function put_contents($path, $content)
+ {
+ if ($this->exists($path))
+ {
+ throw new exception('STORAGE_FILE_EXISTS', $path);
+ }
+
+ $this->get_adapter()->put_contents($path, $content);
+ $this->track_file($path);
+ }
+
+ /**
+ * Read the contents of a file
+ *
+ * @param string $path The file to read
+ *
+ * @throws \phpbb\storage\exception\exception When the file doesn't exist
+ * When cannot read file contents
+ *
+ * @return string Returns file contents
+ *
+ */
+ public function get_contents($path)
+ {
+ if (!$this->exists($path))
+ {
+ throw new exception('STORAGE_FILE_NO_EXIST', $path);
+ }
+
+ return $this->get_adapter()->get_contents($path);
+ }
+
+ /**
+ * Checks the existence of files or directories
+ *
+ * @param string $path file/directory to check
+ * @param bool $full_check check in the filesystem too
+ *
+ * @return bool Returns true if the file/directory exist, false otherwise
+ */
+ public function exists($path, $full_check = false)
+ {
+ return ($this->is_tracked($path) && (!$full_check || $this->get_adapter()->exists($path)));
+ }
+
+ /**
+ * Removes files or directories
+ *
+ * @param string $path file/directory to remove
+ *
+ * @throws \phpbb\storage\exception\exception When removal fails
+ * When the file doesn't exist
+ */
+ public function delete($path)
+ {
+ if (!$this->exists($path))
+ {
+ throw new exception('STORAGE_FILE_NO_EXIST', $path);
+ }
+
+ $this->get_adapter()->delete($path);
+ $this->untrack_file($path);
+ }
+
+ /**
+ * Rename a file or a directory
+ *
+ * @param string $path_orig The original file/direcotry
+ * @param string $path_dest The target file/directory
+ *
+ * @throws \phpbb\storage\exception\exception When the file doesn't exist
+ * When target exists
+ * When file/directory cannot be renamed
+ */
+ public function rename($path_orig, $path_dest)
+ {
+ if (!$this->exists($path_orig))
+ {
+ throw new exception('STORAGE_FILE_NO_EXIST', $path_orig);
+ }
+
+ if ($this->exists($path_dest))
+ {
+ throw new exception('STORAGE_FILE_EXISTS', $path_dest);
+ }
+
+ $this->get_adapter()->rename($path_orig, $path_dest);
+ $this->track_rename($path_orig, $path_dest);
+ }
+
+ /**
+ * Copies a file
+ *
+ * @param string $path_orig The original filename
+ * @param string $path_dest The target filename
+ *
+ * @throws \phpbb\storage\exception\exception When the file doesn't exist
+ * When target exists
+ * When the file cannot be copied
+ */
+ public function copy($path_orig, $path_dest)
+ {
+ if (!$this->exists($path_orig))
+ {
+ throw new exception('STORAGE_FILE_NO_EXIST', $path_orig);
+ }
+
+ if ($this->exists($path_dest))
+ {
+ throw new exception('STORAGE_FILE_EXISTS', $path_dest);
+ }
+
+ $this->get_adapter()->copy($path_orig, $path_dest);
+ $this->track_file($path_dest);
+ }
+
+ /**
+ * Reads a file as a stream
+ *
+ * @param string $path File to read
+ *
+ * @throws \phpbb\storage\exception\exception When the file doesn't exist
+ * When unable to open file
+ *
+ * @return resource Returns a file pointer
+ */
+ public function read_stream($path)
+ {
+ if (!$this->exists($path))
+ {
+ throw new exception('STORAGE_FILE_NO_EXIST', $path);
+ }
+
+ $stream = null;
+ $adapter = $this->get_adapter();
+
+ if ($adapter instanceof stream_interface)
+ {
+ $stream = $adapter->read_stream($path);
+ }
+ else
+ {
+ // Simulate the stream
+ $stream = fopen('php://temp', 'w+b');
+ fwrite($stream, $adapter->get_contents($path));
+ rewind($stream);
+ }
+
+ return $stream;
+ }
+
+ /**
+ * Writes a new file using a stream
+ *
+ * @param string $path The target file
+ * @param resource $resource The resource
+ *
+ * @throws \phpbb\storage\exception\exception When the file exist
+ * When target file cannot be created
+ */
+ public function write_stream($path, $resource)
+ {
+ if ($this->exists($path))
+ {
+ throw new exception('STORAGE_FILE_EXISTS', $path);
+ }
+
+ if (!is_resource($resource))
+ {
+ throw new exception('STORAGE_INVALID_RESOURCE');
+ }
+
+ $adapter = $this->get_adapter();
+
+ if ($adapter instanceof stream_interface)
+ {
+ $adapter->write_stream($path, $resource);
+ $this->track_file($path);
+ }
+ else
+ {
+ // Simulate the stream
+ $adapter->put_contents($path, stream_get_contents($resource));
+ }
+ }
+
+ /**
+ * Track file in database
+ *
+ * @param string $path The target file
+ * @param bool $update Update file size when already tracked
+ */
+ public function track_file($path, $update = false)
+ {
+ if (!$this->get_adapter()->exists($path))
+ {
+ throw new exception('STORAGE_FILE_NO_EXIST', $path);
+ }
+
+ $sql_ary = array(
+ 'file_path' => $path,
+ 'storage' => $this->get_name(),
+ );
+
+ // Get file, if exist update filesize, if not add new record
+ $sql = 'SELECT * FROM ' . $this->storage_table . '
+ WHERE ' . $this->db->sql_build_array('SELECT', $sql_ary);
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ if (!$row)
+ {
+ // Don't call the file_info method, because it check's if the file is tracked
+ // and is not (for now). This method check if the file exists using the adapter
+ // at the beginning.
+ $file = new file_info($this->get_adapter(), $path);
+ $sql_ary['filesize'] = $file->size;
+
+ $sql = 'INSERT INTO ' . $this->storage_table . $this->db->sql_build_array('INSERT', $sql_ary);
+ $this->db->sql_query($sql);
+ }
+ else if ($update)
+ {
+ $file = $this->file_info($path);
+ $sql = 'UPDATE ' . $this->storage_table . '
+ SET filesize = ' . $file->size . '
+ WHERE ' . $this->db->sql_build_array('SELECT', $sql_ary);
+ $this->db->sql_query($sql);
+ }
+
+ $this->cache->destroy('_storage_' . $this->get_name() . '_totalsize');
+ $this->cache->destroy('_storage_' . $this->get_name() . '_numfiles');
+ }
+
+ /**
+ * Untrack file
+ *
+ * @param string $path The target file
+ */
+ public function untrack_file($path)
+ {
+ $sql_ary = array(
+ 'file_path' => $path,
+ 'storage' => $this->get_name(),
+ );
+
+ $sql = 'DELETE FROM ' . $this->storage_table . '
+ WHERE ' . $this->db->sql_build_array('DELETE', $sql_ary);
+ $this->db->sql_query($sql);
+
+ $this->cache->destroy('_storage_' . $this->get_name() . '_totalsize');
+ $this->cache->destroy('_storage_' . $this->get_name() . '_numfiles');
+ }
+
+ /**
+ * Check if a file is tracked
+ *
+ * @param string $path The file
+ *
+ * @return bool True if file is tracked
+ */
+ public function is_tracked($path)
+ {
+ $sql_ary = array(
+ 'file_path' => $path,
+ 'storage' => $this->get_name(),
+ );
+
+ $sql = 'SELECT file_id FROM ' . $this->storage_table . '
+ WHERE ' . $this->db->sql_build_array('SELECT', $sql_ary);
+ $result = $this->db->sql_query($sql);
+ $row = $this->db->sql_fetchrow($result);
+ $this->db->sql_freeresult($result);
+
+ return ($row) ? true : false;
+ }
+
+ /**
+ * Rename tracked file
+ *
+ * @param string $path_orig The original file/direcotry
+ * @param string $path_dest The target file/directory
+ */
+ protected function track_rename($path_orig, $path_dest)
+ {
+ $sql = 'UPDATE ' . $this->storage_table . "
+ SET file_path = '" . $this->db->sql_escape($path_dest) . "'
+ WHERE file_path = '" . $this->db->sql_escape($path_orig) . "'
+ AND storage = '" . $this->db->sql_escape($this->get_name()) . "'";
+ $this->db->sql_query($sql);
+ }
+
+ /**
+ * Get file info
+ *
+ * @param string $path The file
+ *
+ * @throws \phpbb\storage\exception\not_implemented When the adapter doesnt implement the method
+ * When the file doesn't exist
+ *
+ * @return \phpbb\storage\file_info Returns file_info object
+ */
+ public function file_info($path)
+ {
+ if (!$this->exists($path))
+ {
+ throw new exception('STORAGE_FILE_NO_EXIST', $path);
+ }
+
+ return new file_info($this->get_adapter(), $path);
+ }
+
+ /**
+ * Get direct link
+ *
+ * @param string $path The file
+ *
+ * @return string Returns link.
+ *
+ */
+ public function get_link($path)
+ {
+ return $this->get_adapter()->get_link($path);
+ }
+
+ /**
+ * Get total storage size
+ *
+ * @return int Size in bytes
+ */
+ public function get_size()
+ {
+ $total_size = $this->cache->get('_storage_' . $this->get_name() . '_totalsize');
+
+ if ($total_size === false)
+ {
+ $sql = 'SELECT SUM(filesize) AS totalsize
+ FROM ' . $this->storage_table . "
+ WHERE storage = '" . $this->db->sql_escape($this->get_name()) . "'";
+ $result = $this->db->sql_query($sql);
+
+ $total_size = (int) $this->db->sql_fetchfield('totalsize');
+ $this->cache->put('_storage_' . $this->get_name() . '_totalsize', $total_size);
+
+ $this->db->sql_freeresult($result);
+ }
+
+ return (int) $total_size;
+ }
+
+ /**
+ * Get number of storage files
+ *
+ * @return int Number of files
+ */
+ public function get_num_files()
+ {
+ $number_files = $this->cache->get('_storage_' . $this->get_name() . '_numfiles');
+
+ if ($number_files === false)
+ {
+ $sql = 'SELECT COUNT(file_id) AS numfiles
+ FROM ' . $this->storage_table . "
+ WHERE storage = '" . $this->db->sql_escape($this->get_name()) . "'";
+ $result = $this->db->sql_query($sql);
+
+ $number_files = (int) $this->db->sql_fetchfield('numfiles');
+ $this->cache->put('_storage_' . $this->get_name() . '_numfiles', $number_files);
+
+ $this->db->sql_freeresult($result);
+ }
+
+ return (int) $number_files;
+ }
+
+ /**
+ * Get space available in bytes
+ *
+ * @throws \phpbb\storage\exception\exception When unable to retrieve available storage space
+ *
+ * @return float Returns available space
+ */
+ public function free_space()
+ {
+ return $this->get_adapter()->free_space();
+ }
+}
diff --git a/phpBB/phpbb/storage/stream_interface.php b/phpBB/phpbb/storage/stream_interface.php
new file mode 100644
index 0000000000..6d0af71550
--- /dev/null
+++ b/phpBB/phpbb/storage/stream_interface.php
@@ -0,0 +1,39 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\storage;
+
+interface stream_interface
+{
+ /**
+ * Reads a file as a stream
+ *
+ * @param string $path File to read
+ *
+ * @throws \phpbb\storage\exception\exception When unable to open file
+ *
+ * @return resource Returns a file pointer
+ */
+ public function read_stream($path);
+
+ /**
+ * Writes a new file using a stream
+ *
+ * @param string $path The target file
+ * @param resource $resource The resource
+ *
+ * @throws \phpbb\storage\exception\exception When target file exists
+ * When target file cannot be created
+ */
+ public function write_stream($path, $resource);
+}
diff --git a/phpBB/phpbb/template/asset.php b/phpBB/phpbb/template/asset.php
index d6b46234f0..5fc3e4acaf 100644
--- a/phpBB/phpbb/template/asset.php
+++ b/phpBB/phpbb/template/asset.php
@@ -13,6 +13,8 @@
namespace phpbb\template;
+use phpbb\filesystem\helper as filesystem_helper;
+
class asset
{
protected $components = array();
@@ -20,20 +22,15 @@ class asset
/** @var \phpbb\path_helper **/
protected $path_helper;
- /** @var \phpbb\filesystem\filesystem */
- protected $filesystem;
-
/**
* Constructor
*
* @param string $url URL
* @param \phpbb\path_helper $path_helper Path helper object
- * @param \phpbb\filesystem\filesystem $filesystem
*/
- public function __construct($url, \phpbb\path_helper $path_helper, \phpbb\filesystem\filesystem $filesystem)
+ public function __construct($url, \phpbb\path_helper $path_helper)
{
$this->path_helper = $path_helper;
- $this->filesystem = $filesystem;
$this->set_url($url);
}
@@ -151,7 +148,7 @@ class asset
public function set_path($path, $urlencode = false)
{
// Since 1.7.0 Twig returns the real path of the file. We need it to be relative.
- $real_root_path = $this->filesystem->realpath($this->path_helper->get_phpbb_root_path()) . DIRECTORY_SEPARATOR;
+ $real_root_path = filesystem_helper::realpath($this->path_helper->get_phpbb_root_path()) . DIRECTORY_SEPARATOR;
// If the asset is under the phpBB root path we need to remove its path and then prepend $phpbb_root_path
if ($real_root_path && substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path)
@@ -161,7 +158,7 @@ class asset
else
{
// Else we make the path relative to the current working directory
- $real_root_path = $this->filesystem->realpath('.') . DIRECTORY_SEPARATOR;
+ $real_root_path = filesystem_helper::realpath('.') . DIRECTORY_SEPARATOR;
if ($real_root_path && substr($path . DIRECTORY_SEPARATOR, 0, strlen($real_root_path)) === $real_root_path)
{
$path = str_replace('\\', '/', substr($path, strlen($real_root_path)));
diff --git a/phpBB/phpbb/template/base.php b/phpBB/phpbb/template/base.php
index d502aceab8..314cdc4796 100644
--- a/phpBB/phpbb/template/base.php
+++ b/phpBB/phpbb/template/base.php
@@ -168,26 +168,4 @@ abstract class base implements template
{
return $this->context->find_key_index($blockname, $key);
}
-
- /**
- * Calls hook if any is defined.
- *
- * @param string $handle Template handle being displayed.
- * @param string $method Method name of the caller.
- */
- protected function call_hook($handle, $method)
- {
- global $phpbb_hook;
-
- if (!empty($phpbb_hook) && $phpbb_hook->call_hook(array('template', $method), $handle, $this))
- {
- if ($phpbb_hook->hook_return(array('template', $method)))
- {
- $result = $phpbb_hook->hook_return_result(array('template', $method));
- return array($result);
- }
- }
-
- return false;
- }
}
diff --git a/phpBB/phpbb/template/twig/extension/icon.php b/phpBB/phpbb/template/twig/extension/icon.php
new file mode 100644
index 0000000000..f96ed94821
--- /dev/null
+++ b/phpBB/phpbb/template/twig/extension/icon.php
@@ -0,0 +1,321 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+namespace phpbb\template\twig\extension;
+
+use phpbb\template\twig\environment;
+
+class icon extends \Twig\Extension\AbstractExtension
+{
+ /** @var \phpbb\user */
+ protected $user;
+
+ /**
+ * Constructor.
+ *
+ * @param \phpbb\user $user User object
+ */
+ public function __construct(\phpbb\user $user)
+ {
+ $this->user = $user;
+ }
+
+ /**
+ * Returns the name of this extension.
+ *
+ * @return string The extension name
+ */
+ public function getName()
+ {
+ return 'icon';
+ }
+
+ /**
+ * Returns a list of functions to add to the existing list.
+ *
+ * @return \Twig\TwigFunction[] Array of twig functions
+ */
+ public function getFunctions()
+ {
+ return [
+ new \Twig\TwigFunction('Icon', [$this, 'icon'], ['needs_environment' => true]),
+ ];
+ }
+
+ /**
+ * Generate icon HTML for use in the template, depending on the mode.
+ *
+ * @param environment $environment Twig environment object
+ * @param string $type Icon type (font|iconify|png|svg)
+ * @param string $icon Icon name (eg. "bold")
+ * @param string $title Icon title
+ * @param bool $hidden Hide the icon title from view
+ * @param string $classes Additional classes (eg. "fa-fw")
+ * @param array $attributes Additional attributes for the icon, where the key is the attribute.
+ * {'data-ajax': 'mark_forums'} results in ' data-ajax="mark_forums"'
+ * @return string
+ */
+ public function icon(environment $environment, $type, $icon, $title = '', $hidden = false, $classes = '', array $attributes = [])
+ {
+ $type = strtolower($type);
+ $icon = is_array($icon) ? $this->get_first_icon($icon) : $icon;
+
+ if (empty($icon))
+ {
+ return '';
+ }
+
+ $not_found = false;
+ $source = '';
+ $view_box = '';
+
+ switch ($type)
+ {
+ case 'font':
+ // Nothing to do here..
+ break;
+
+ case 'iconify':
+ $source = explode(':', $icon);
+ $source = $source[0];
+ break;
+
+ case 'png':
+ $filesystem = $environment->get_filesystem();
+ $root_path = $environment->get_web_root_path();
+
+ $board_url = defined('PHPBB_USE_BOARD_URL_PATH') && PHPBB_USE_BOARD_URL_PATH;
+ $base_path = $board_url ? generate_board_url() . '/' : $root_path;
+
+ // Iterate over the user's styles and check for icon existance
+ foreach ($this->get_style_list() as $style_path)
+ {
+ if ($filesystem->exists("{$root_path}styles/{$style_path}/theme/png/{$icon}.png"))
+ {
+ $source = "{$base_path}styles/{$style_path}/theme/png/{$icon}.png";
+
+ break;
+ }
+ }
+
+ // Check if the icon was found or not
+ $not_found = empty($source);
+ break;
+
+ case 'svg':
+ try
+ {
+ // Try to load and prepare the SVG icon
+ $file = $environment->load('svg/' . $icon . '.svg');
+ $source = $this->prepare_svg($file, $view_box);
+
+ if (empty($view_box))
+ {
+ return '';
+ }
+ }
+ catch (\Twig\Error\LoaderError $e)
+ {
+ // Icon was not found
+ $not_found = true;
+ }
+ catch (\Twig\Error\Error $e)
+ {
+ return '';
+ }
+ break;
+
+ default:
+ return '';
+ break;
+ }
+
+ // If no PNG or SVG icon was found, display a default 404 SVG icon.
+ if ($not_found)
+ {
+ try
+ {
+ $file = $environment->load('svg/404.svg');
+ $source = $this->prepare_svg($file, $view_box);
+ }
+ catch (\Twig\Error\Error $e)
+ {
+ return '';
+ }
+
+ $type = 'svg';
+ $icon = '404';
+ }
+
+ try
+ {
+ return $environment->render("macros/icons/{$type}.twig", [
+ 'ATTRIBUTES' => (string) $this->implode_attributes($attributes),
+ 'CLASSES' => (string) $classes,
+ 'ICON' => (string) $icon,
+ 'SOURCE' => (string) $source,
+ 'TITLE' => (string) $title,
+ 'VIEW_BOX' => (string) $view_box,
+ 'S_HIDDEN' => (bool) $hidden,
+ ]);
+ }
+ catch (\Twig\Error\Error $e)
+ {
+ return '';
+ }
+ }
+
+ /**
+ * Prepare an SVG for usage in the template icon.
+ *
+ * This removes any <?xml ?> and <!DOCTYPE> elements,
+ * aswell as the root <svg> and any <title> elements.
+ *
+ * @param \Twig\TemplateWrapper $file The SVG file loaded from the environment
+ * @param string $view_box The viewBox attribute value
+ * @return string The cleaned SVG
+ */
+ protected function prepare_svg(\Twig\TemplateWrapper $file, &$view_box = '')
+ {
+ $code = $file->render();
+ $code = preg_replace( "/<\?xml.+?\?>/", '', $code);
+
+ $doc = new \DOMDocument();
+ $doc->preserveWhiteSpace = false;
+
+ /**
+ * Suppression is needed as DOMDocument does not like HTML5 and SVGs.
+ * Options parameter prevents $dom->saveHTML() from adding an <html> element.
+ */
+ @$doc->loadHTML($code, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
+
+ // Remove any DOCTYPE
+ foreach ($doc->childNodes as $child)
+ {
+ if ($child->nodeType === XML_DOCUMENT_TYPE_NODE)
+ {
+ $child->parentNode->removeChild($child);
+ }
+ }
+
+ $xpath = new \DOMXPath($doc);
+
+ /**
+ * Remove the root <svg> element
+ * and all <title> elements.
+ *
+ * @var \DOMElement $element
+ */
+ foreach ($xpath->query('/svg | //title') as $element)
+ {
+ if ($element->nodeName === 'svg')
+ {
+ // Return the viewBox attribute value of the root SVG element by reference
+ $view_box = $element->getAttribute('viewbox');
+
+ $width = $element->getAttribute('width');
+ $height = $element->getAttribute('height');
+
+ if (empty($view_box) && $width && $height)
+ {
+ $view_box = "0 0 {$width} {$height}";
+ }
+
+ while (isset($element->firstChild))
+ {
+ $element->parentNode->insertBefore($element->firstChild, $element);
+ }
+ }
+
+ $element->parentNode->removeChild($element);
+ }
+
+ $string = $doc->saveHTML();
+ $string = preg_replace('/\s+/', ' ', $string);
+
+ return $string;
+ }
+
+ /**
+ * Finds the first icon that has a "true" value and returns it.
+ *
+ * This allows sending an array to the Icon() function,
+ * where the keys are the icon names and the values are their checks.
+ *
+ * {{ Icon('font', {
+ * 'bullhorn': topicrow.S_POST_GLOBAL or topicrow.S_POST_ANNOUNCE,
+ * 'star': topicrow.S_POST_STICKY,
+ * 'lock': topicrow.S_TOPIC_LOCKED,
+ * 'fire': topicrow.S_TOPIC_HOT,
+ * 'file': true,
+ * }, 'MY_TITLE', true) }}
+ *
+ * @param array $icons Array of icons and their booleans
+ * @return string The first 'true' icon
+ */
+ protected function get_first_icon(array $icons)
+ {
+ foreach ($icons as $icon => $boolean)
+ {
+ // In case the key is not a string,
+ // this icon does not have a check
+ // so instantly return it
+ if (!is_string($icon))
+ {
+ return $boolean;
+ }
+
+ if ($boolean)
+ {
+ return $icon;
+ }
+ }
+
+ return '';
+ }
+
+ /**
+ * Implode an associated array of attributes to a string for usage in a template.
+ *
+ * @param array $attributes Associated array of attributes
+ * @return string
+ */
+ protected function implode_attributes(array $attributes)
+ {
+ $string = '';
+
+ foreach ($attributes as $key => $value)
+ {
+ $string .= ' ' . $key . '="' . $value . '"';
+ }
+
+ return $string;
+ }
+
+ /**
+ * Get the style tree of the style preferred by the current user.
+ *
+ * @return array Style tree, most specific first
+ */
+ protected function get_style_list()
+ {
+ $style_list = [$this->user->style['style_path']];
+
+ if ($this->user->style['style_parent_id'])
+ {
+ $style_list = array_merge($style_list, array_reverse(explode('/', $this->user->style['style_parent_tree'])));
+ }
+
+ return $style_list;
+ }
+}
diff --git a/phpBB/phpbb/template/twig/loader.php b/phpBB/phpbb/template/twig/loader.php
index 0f193dbe59..cddcf33146 100644
--- a/phpBB/phpbb/template/twig/loader.php
+++ b/phpBB/phpbb/template/twig/loader.php
@@ -13,6 +13,8 @@
namespace phpbb\template\twig;
+use phpbb\filesystem\helper as filesystem_helper;
+
/**
* Twig Template loader
*/
@@ -21,20 +23,12 @@ class loader extends \Twig_Loader_Filesystem
protected $safe_directories = array();
/**
- * @var \phpbb\filesystem\filesystem_interface
- */
- protected $filesystem;
-
- /**
* Constructor
*
- * @param \phpbb\filesystem\filesystem_interface $filesystem
* @param string|array $paths
*/
- public function __construct(\phpbb\filesystem\filesystem_interface $filesystem, $paths = array())
+ public function __construct($paths = array())
{
- $this->filesystem = $filesystem;
-
parent::__construct($paths, __DIR__);
}
@@ -67,7 +61,7 @@ class loader extends \Twig_Loader_Filesystem
*/
public function addSafeDirectory($directory)
{
- $directory = $this->filesystem->realpath($directory);
+ $directory = filesystem_helper::realpath($directory);
if ($directory !== false)
{
@@ -107,7 +101,7 @@ class loader extends \Twig_Loader_Filesystem
*/
public function addPath($path, $namespace = self::MAIN_NAMESPACE)
{
- return parent::addPath($this->filesystem->realpath($path), $namespace);
+ return parent::addPath(filesystem_helper::realpath($path), $namespace);
}
/**
@@ -147,7 +141,7 @@ class loader extends \Twig_Loader_Filesystem
// can now check if we're within a "safe" directory
// Find the real path of the directory the file is in
- $directory = $this->filesystem->realpath(dirname($file));
+ $directory = filesystem_helper::realpath(dirname($file));
if ($directory === false)
{
diff --git a/phpBB/phpbb/template/twig/node/includeasset.php b/phpBB/phpbb/template/twig/node/includeasset.php
index 69bfd58803..bf29fa7277 100644
--- a/phpBB/phpbb/template/twig/node/includeasset.php
+++ b/phpBB/phpbb/template/twig/node/includeasset.php
@@ -49,7 +49,7 @@ abstract class includeasset extends \Twig_Node
->write("\n")
->write("if (\$asset->is_relative()) {\n")
->indent()
- ->write("\$asset->add_assets_version(\$this->env->get_phpbb_config()['assets_version']);\n")
+ ->write("\$asset->add_assets_version(\$this->env->get_phpbb_config()['assets_version']);\n")
->outdent()
->write("}\n")
->write("\$this->env->get_assets_bag()->add_{$this->get_setters_name()}(\$asset);")
diff --git a/phpBB/phpbb/template/twig/twig.php b/phpBB/phpbb/template/twig/twig.php
index f322778eda..f0736045de 100644
--- a/phpBB/phpbb/template/twig/twig.php
+++ b/phpBB/phpbb/template/twig/twig.php
@@ -308,12 +308,6 @@ class twig extends \phpbb\template\base
*/
public function display($handle)
{
- $result = $this->call_hook($handle, __FUNCTION__);
- if ($result !== false)
- {
- return $result[0];
- }
-
$this->twig->display($this->get_filename_from_handle($handle), $this->get_template_vars());
return $this;
diff --git a/phpBB/phpbb/user.php b/phpBB/phpbb/user.php
index 21d156e060..60cc85e46c 100644
--- a/phpBB/phpbb/user.php
+++ b/phpBB/phpbb/user.php
@@ -342,10 +342,6 @@ class user extends \phpbb\session
$this->img_lang = $this->lang_name;
- // Call phpbb_user_session_handler() in case external application want to "bend" some variables or replace classes...
- // After calling it we continue script execution...
- phpbb_user_session_handler();
-
/**
* Execute code at the end of user setup
*
diff --git a/phpBB/phpbb/viewonline_helper.php b/phpBB/phpbb/viewonline_helper.php
index 89915f2228..8df1f484d8 100644
--- a/phpBB/phpbb/viewonline_helper.php
+++ b/phpBB/phpbb/viewonline_helper.php
@@ -13,20 +13,18 @@
namespace phpbb;
+use phpbb\filesystem\helper as filesystem_helper;
+
/**
* Class to handle viewonline related tasks
*/
class viewonline_helper
{
- /** @var \phpbb\filesystem\filesystem_interface */
- protected $filesystem;
-
/**
- * @param \phpbb\filesystem\filesystem_interface $filesystem phpBB's filesystem service
+ *
*/
- public function __construct(\phpbb\filesystem\filesystem_interface $filesystem)
+ public function __construct()
{
- $this->filesystem = $filesystem;
}
/**
@@ -37,7 +35,7 @@ class viewonline_helper
*/
public function get_user_page($session_page)
{
- $session_page = $this->filesystem->clean_path($session_page);
+ $session_page = filesystem_helper::clean_path($session_page);
if (strpos($session_page, './') === 0)
{
$session_page = substr($session_page, 2);
diff --git a/phpBB/styles/all/imgs/svg/404.svg b/phpBB/styles/all/imgs/svg/404.svg
new file mode 100644
index 0000000000..a8bc69bba7
--- /dev/null
+++ b/phpBB/styles/all/imgs/svg/404.svg
@@ -0,0 +1,7 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
+ <g fill="none" fill-rule="evenodd">
+ <path fill="#D8D8D8" d="M0 0h512v512H0z"/>
+ <path fill="#979797" fill-rule="nonzero" d="M8 6.586l496 496v2.828L8 9.414z"/>
+ <path fill="#979797" fill-rule="nonzero" d="M504 7.586v2.828l-496 496v-2.828z"/>
+ </g>
+</svg>
diff --git a/phpBB/styles/all/template/macros/icons/font.twig b/phpBB/styles/all/template/macros/icons/font.twig
new file mode 100644
index 0000000000..a882a25c40
--- /dev/null
+++ b/phpBB/styles/all/template/macros/icons/font.twig
@@ -0,0 +1,4 @@
+{% spaceless %}
+ <i class="o-icon o-icon-font fa-{{ ICON ~ (CLASSES ? ' ' ~ CLASSES) }}"{% if S_HIDDEN %}{% if TITLE %} title="{{ lang(TITLE) }}"{% endif %} aria-hidden="true"{% endif %}{{ ATTRIBUTES }}></i>
+ {% if TITLE %}<span{% if S_HIDDEN %} class="sr-only"{% endif %}>{{ lang(TITLE) }}</span>{% endif %}
+{% endspaceless %}
diff --git a/phpBB/styles/all/template/macros/icons/iconify.twig b/phpBB/styles/all/template/macros/icons/iconify.twig
new file mode 100644
index 0000000000..43b8b88948
--- /dev/null
+++ b/phpBB/styles/all/template/macros/icons/iconify.twig
@@ -0,0 +1,4 @@
+{% spaceless %}
+ <i class="iconify o-icon-src-{{ SOURCE }} o-icon{{ CLASSES ? ' ' ~ CLASSES }}"{% if S_HIDDEN %}{% if TITLE %} title="{{ lang(TITLE) }}"{% endif %} aria-hidden="true"{% endif %} data-icon="{{ ICON }}" data-inline="true"{{ ATTRIBUTES }}></i>
+ {% if TITLE %}<span{% if S_HIDDEN %} class="sr-only"{% endif %}>{{ lang(TITLE) }}</span>{% endif %}
+{% endspaceless %}
diff --git a/phpBB/styles/all/template/macros/icons/png.twig b/phpBB/styles/all/template/macros/icons/png.twig
new file mode 100644
index 0000000000..426f7a3a5e
--- /dev/null
+++ b/phpBB/styles/all/template/macros/icons/png.twig
@@ -0,0 +1,3 @@
+{% spaceless %}
+ <img class="o-icon o-icon-png png-{{ ICON ~ (CLASSES ? ' ' ~ CLASSES) }}" src="{{ SOURCE }}" alt="{{ lang(TITLE) }}"{{ ATTRIBUTES }} />
+{% endspaceless %}
diff --git a/phpBB/styles/all/template/macros/icons/svg.twig b/phpBB/styles/all/template/macros/icons/svg.twig
new file mode 100644
index 0000000000..e24777272e
--- /dev/null
+++ b/phpBB/styles/all/template/macros/icons/svg.twig
@@ -0,0 +1,9 @@
+{% spaceless %}
+ {% set TITLE_ID = TITLE ? TITLE|lower|replace({' ': '_'}) ~ '-' ~ random() %}
+
+ <svg class="o-icon o-icon-svg svg-{{ ICON ~ (CLASSES ? ' ' ~ CLASSES) }}" xmlns="http://www.w3.org/2000/svg" viewBox="{{ VIEW_BOX }}"{% if TITLE %}{% if S_HIDDEN %} aria-hidden="true"{% endif %} aria-labelledby="{{ TITLE_ID }}"{% endif %} role="img"{{ ATTRIBUTES }}>
+ {% if TITLE %}<title id="{{ TITLE_ID }}">{{ lang(TITLE) }}</title>{% endif %}
+
+ {{ SOURCE }}
+ </svg>
+{% endspaceless %}
diff --git a/phpBB/styles/prosilver/style.cfg b/phpBB/styles/prosilver/style.cfg
index 0c7eba6700..0f795e6a60 100644
--- a/phpBB/styles/prosilver/style.cfg
+++ b/phpBB/styles/prosilver/style.cfg
@@ -21,8 +21,8 @@
# General Information about this style
name = prosilver
copyright = © phpBB Limited, 2007
-style_version = 3.3.0
-phpbb_version = 3.3.0
+style_version = 4.0.0-a1-dev
+phpbb_version = 4.0.0-a1-dev
# Defining a different template bitfield
# template_bitfield = //g=
diff --git a/phpBB/styles/prosilver/template/ajax.js b/phpBB/styles/prosilver/template/ajax.js
index 5e66e5cda1..d85ba35873 100644
--- a/phpBB/styles/prosilver/template/ajax.js
+++ b/phpBB/styles/prosilver/template/ajax.js
@@ -100,7 +100,7 @@ phpbb.addAjaxCallback('mark_topics_read', function(res, updateTopicLinks) {
// This callback will mark all notifications read
phpbb.addAjaxCallback('notification.mark_all_read', function(res) {
if (typeof res.success !== 'undefined') {
- phpbb.markNotifications($('#notification_list li.bg2'), 0);
+ phpbb.markNotifications($('[data-notification-unread="true"]'), 0);
phpbb.closeDarkenWrapper(3000);
}
});
@@ -108,8 +108,8 @@ phpbb.addAjaxCallback('notification.mark_all_read', function(res) {
// This callback will mark a notification read
phpbb.addAjaxCallback('notification.mark_read', function(res) {
if (typeof res.success !== 'undefined') {
- var unreadCount = Number($('#notification_list_button strong').html()) - 1;
- phpbb.markNotifications($(this).parent('li.bg2'), unreadCount);
+ var unreadCount = Number($('#notification-button strong').html()) - 1;
+ phpbb.markNotifications($(this).parent('[data-notification-unread="true"]'), unreadCount);
}
});
@@ -131,11 +131,11 @@ phpbb.markNotifications = function($popup, unreadCount) {
});
// Update the unread count.
- $('strong', '#notification_list_button').html(unreadCount);
+ $('strong', '#notification-button').html(unreadCount);
// Remove the Mark all read link and hide notification count if there are no unread notifications.
if (!unreadCount) {
$('#mark_all_notifications').remove();
- $('#notification_list_button > strong').addClass('hidden');
+ $('#notification-button > strong').addClass('hidden');
}
// Update page title
diff --git a/phpBB/styles/prosilver/template/captcha_default.html b/phpBB/styles/prosilver/template/captcha_default.html
index 02899bcafd..6df124b443 100644
--- a/phpBB/styles/prosilver/template/captcha_default.html
+++ b/phpBB/styles/prosilver/template/captcha_default.html
@@ -12,7 +12,7 @@
<dt><label for="confirm_code">{L_CONFIRM_CODE}{L_COLON}</label></dt>
<dd class="captcha captcha-image"><img src="{CONFIRM_IMAGE_LINK}" alt="{L_CONFIRM_CODE}" /></dd>
<dd><input type="text" name="confirm_code" id="confirm_code" size="8" maxlength="8" tabindex="{$CAPTCHA_TAB_INDEX}" class="inputbox narrow" title="{L_CONFIRM_CODE}" />
- <!-- IF S_CONFIRM_REFRESH --><input type="submit" name="refresh_vc" id="refresh_vc" class="button2" value="{L_VC_REFRESH}" /><!-- ENDIF -->
+ <!-- IF S_CONFIRM_REFRESH --><input type="submit" name="refresh_vc" id="refresh_vc" class="button1 button button-form-bold" value="{L_VC_REFRESH}" /><!-- ENDIF -->
<input type="hidden" name="confirm_id" id="confirm_id" value="{CONFIRM_ID}" /></dd>
<dd>{L_CONFIRM_CODE_EXPLAIN}</dd>
</dl>
diff --git a/phpBB/styles/prosilver/template/confirm_body.html b/phpBB/styles/prosilver/template/confirm_body.html
index aaea5cfd05..180ccaac59 100644
--- a/phpBB/styles/prosilver/template/confirm_body.html
+++ b/phpBB/styles/prosilver/template/confirm_body.html
@@ -4,8 +4,8 @@
<p>{MESSAGE_TEXT}</p>
<fieldset class="submit-buttons">
- <input type="button" name="confirm" value="{L_YES}" class="button2" />&nbsp;
- <input type="button" name="cancel" value="{L_NO}" class="button2" />
+ <input type="button" name="confirm" value="{L_YES}" class="button1 button button-form-bold" />&nbsp;
+ <input type="button" name="cancel" value="{L_NO}" class="button1 button button-form-bold" />
</fieldset>
</form>
@@ -22,8 +22,8 @@
<fieldset class="submit-buttons">
{S_HIDDEN_FIELDS}
- <input type="submit" name="confirm" value="{L_YES}" class="button2" />&nbsp;
- <input type="submit" name="cancel" value="{L_NO}" class="button2" />
+ <input type="submit" name="confirm" value="{L_YES}" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="cancel" value="{L_NO}" class="button1 button button-form-bold" />
</fieldset>
</div>
diff --git a/phpBB/styles/prosilver/template/confirm_delete_body.html b/phpBB/styles/prosilver/template/confirm_delete_body.html
index 637830a5bc..d91dbc6970 100644
--- a/phpBB/styles/prosilver/template/confirm_delete_body.html
+++ b/phpBB/styles/prosilver/template/confirm_delete_body.html
@@ -18,8 +18,8 @@
<!-- ENDIF -->
<fieldset class="submit-buttons">
- <input type="button" name="confirm" value="{L_YES}" class="button1" />&nbsp;
- <input type="button" name="cancel" value="{L_NO}" class="button2" />
+ <input type="button" name="confirm" value="{L_YES}" class="button1 button button-form" />&nbsp;
+ <input type="button" name="cancel" value="{L_NO}" class="button1 button button-form-bold" />
</fieldset>
</form>
@@ -60,8 +60,8 @@
<fieldset class="submit-buttons">
{S_HIDDEN_FIELDS}
- <input type="submit" name="confirm" value="{L_YES}" class="button1" />&nbsp;
- <input type="submit" name="cancel" value="{L_NO}" class="button2" />
+ <input type="submit" name="confirm" value="{L_YES}" class="button1 button button-form" />&nbsp;
+ <input type="submit" name="cancel" value="{L_NO}" class="button1 button button-form-bold" />
</fieldset>
</div>
diff --git a/phpBB/styles/prosilver/template/display_options.html b/phpBB/styles/prosilver/template/display_options.html
index a426d08845..1bcaf40087 100644
--- a/phpBB/styles/prosilver/template/display_options.html
+++ b/phpBB/styles/prosilver/template/display_options.html
@@ -11,7 +11,7 @@
<label>{L_SORT_BY}{L_COLON} <select name="sk" id="sk">{S_SORT_OPTIONS}</select></label>
<label>{L_SORT_DIRECTION}{L_COLON} <select name="sd" id="sd">{S_ORDER_SELECT}</select></label>
<hr class="dashed" />
- <input type="submit" class="button2" name="sort" value="{L_SORT}" />
+ <input type="submit" class="button1 button button-form-bold" name="sort" value="{L_SORT}" />
<!-- ELSE -->
<label>{L_DISPLAY}{L_COLON} {S_SELECT_SORT_DAYS}</label>
<!-- IF S_SELECT_SORT_KEY -->
@@ -19,7 +19,7 @@
<label>{L_SORT_DIRECTION}{L_COLON} {S_SELECT_SORT_DIR}</label>
<!-- ENDIF -->
<hr class="dashed" />
- <input type="submit" class="button2" name="sort" value="{L_GO}" />
+ <input type="submit" class="button1 button button-form-bold" name="sort" value="{L_GO}" />
<!-- ENDIF -->
</fieldset>
</div>
diff --git a/phpBB/styles/prosilver/template/forumlist_body.html b/phpBB/styles/prosilver/template/forumlist_body.html
index 4932860f8c..00c104f06c 100644
--- a/phpBB/styles/prosilver/template/forumlist_body.html
+++ b/phpBB/styles/prosilver/template/forumlist_body.html
@@ -48,17 +48,21 @@
<!-- EVENT forumlist_body_forum_image_after -->
<!-- ENDIF -->
<a href="{forumrow.U_VIEWFORUM}" class="forumtitle">{forumrow.FORUM_NAME}</a>
- <!-- IF forumrow.FORUM_DESC --><br />{forumrow.FORUM_DESC}<!-- ENDIF -->
+ <!-- IF forumrow.FORUM_DESC --><span class="forum-desc">{forumrow.FORUM_DESC}</span><!-- ENDIF -->
<!-- IF forumrow.MODERATORS -->
- <br /><strong>{forumrow.L_MODERATOR_STR}{L_COLON}</strong> {forumrow.MODERATORS}
+ <span class="forum-mods"><strong>{forumrow.L_MODERATOR_STR}{L_COLON}</strong> {forumrow.MODERATORS}</span>
<!-- ENDIF -->
<!-- IF .forumrow.subforum and forumrow.S_LIST_SUBFORUMS -->
<!-- EVENT forumlist_body_subforums_before -->
- <br /><strong>{forumrow.L_SUBFORUM_STR}{L_COLON}</strong>
+ <span class="forum-subs">
+ <strong>{forumrow.L_SUBFORUM_STR}{L_COLON}</strong>
<!-- BEGIN subforum -->
- <!-- EVENT forumlist_body_subforum_link_prepend --><a href="{forumrow.subforum.U_SUBFORUM}" class="subforum<!-- IF forumrow.subforum.S_UNREAD --> unread<!-- ELSE --> read<!-- ENDIF -->" title="<!-- IF forumrow.subforum.S_UNREAD -->{L_UNREAD_POSTS}<!-- ELSE -->{L_NO_UNREAD_POSTS}<!-- ENDIF -->">
- <i class="icon <!-- IF forumrow.subforum.IS_LINK -->fa-external-link<!-- ELSE -->fa-file-o<!-- ENDIF --> fa-fw <!-- IF forumrow.subforum.S_UNREAD --> icon-red<!-- ELSE --> icon-blue<!-- ENDIF --> icon-md" aria-hidden="true"></i>{forumrow.subforum.SUBFORUM_NAME}</a><!-- IF not forumrow.subforum.S_LAST_ROW -->{L_COMMA_SEPARATOR}<!-- ENDIF --><!-- EVENT forumlist_body_subforum_link_append -->
+ <!-- EVENT forumlist_body_subforum_link_prepend -->
+ <a href="{forumrow.subforum.U_SUBFORUM}" class="subforum<!-- IF forumrow.subforum.S_UNREAD --> unread<!-- ELSE --> read<!-- ENDIF -->" title="<!-- IF forumrow.subforum.S_UNREAD -->{L_UNREAD_POSTS}<!-- ELSE -->{L_NO_UNREAD_POSTS}<!-- ENDIF -->">
+ <i class="icon <!-- IF forumrow.subforum.IS_LINK -->fa-external-link<!-- ELSE -->fa-file-o<!-- ENDIF --> fa-fw <!-- IF forumrow.subforum.S_UNREAD --> icon-red<!-- ELSE --> icon-blue<!-- ENDIF --> icon-md" aria-hidden="true"></i>{forumrow.subforum.SUBFORUM_NAME}</a><!-- IF not forumrow.subforum.S_LAST_ROW -->{L_COMMA_SEPARATOR}<!-- ENDIF -->
+ <!-- EVENT forumlist_body_subforum_link_append -->
<!-- END subforum -->
+ </span>
<!-- EVENT forumlist_body_subforums_after -->
<!-- ENDIF -->
diff --git a/phpBB/styles/prosilver/template/index_body.html b/phpBB/styles/prosilver/template/index_body.html
index 239a91c580..94d069b597 100644
--- a/phpBB/styles/prosilver/template/index_body.html
+++ b/phpBB/styles/prosilver/template/index_body.html
@@ -27,7 +27,7 @@
<!-- IF S_AUTOLOGIN_ENABLED -->
<span class="responsive-hide">|</span> <label for="autologin">{L_LOG_ME_IN} <input type="checkbox" tabindex="4" name="autologin" id="autologin" /></label>
<!-- ENDIF -->
- <input type="submit" tabindex="5" name="login" value="{L_LOGIN}" class="button2" />
+ <input type="submit" tabindex="5" name="login" value="{L_LOGIN}" class="button1 button button-form-bold" />
{S_LOGIN_REDIRECT}
{S_FORM_TOKEN_LOGIN}
</fieldset>
diff --git a/phpBB/styles/prosilver/template/login_body.html b/phpBB/styles/prosilver/template/login_body.html
index dc597af51d..85d3a768fc 100644
--- a/phpBB/styles/prosilver/template/login_body.html
+++ b/phpBB/styles/prosilver/template/login_body.html
@@ -36,7 +36,7 @@
{S_FORM_TOKEN_LOGIN}
<dl>
<dt>&nbsp;</dt>
- <dd>{S_HIDDEN_FIELDS}<input type="submit" name="login" tabindex="6" value="{L_LOGIN}" class="button1" /></dd>
+ <dd>{S_HIDDEN_FIELDS}<input type="submit" name="login" tabindex="6" value="{L_LOGIN}" class="button1 button button-form" /></dd>
</dl>
</fieldset>
</div>
@@ -57,7 +57,7 @@
<p>{L_LOGIN_INFO}</p>
<p><strong><a href="{U_TERMS_USE}">{L_TERMS_USE}</a> | <a href="{U_PRIVACY}">{L_PRIVACY}</a></strong></p>
<hr class="dashed" />
- <p><a href="{U_REGISTER}" class="button2">{L_REGISTER}</a></p>
+ <p><a href="{U_REGISTER}" class="button1 button button-form-bold">{L_REGISTER}</a></p>
</div>
</div>
diff --git a/phpBB/styles/prosilver/template/login_body_oauth.html b/phpBB/styles/prosilver/template/login_body_oauth.html
index 1364d01ccb..e15a60793c 100644
--- a/phpBB/styles/prosilver/template/login_body_oauth.html
+++ b/phpBB/styles/prosilver/template/login_body_oauth.html
@@ -1,6 +1,6 @@
<br>
<div class="content">
{% for oauth in oauth %}
- <a href="{{ oauth.REDIRECT_URL }}" class="button2">{{ oauth.SERVICE_NAME }}</a>
+ <a href="{{ oauth.REDIRECT_URL }}" class="button1 button button-form-bold">{{ oauth.SERVICE_NAME }}</a>
{% endfor %}
</div>
diff --git a/phpBB/styles/prosilver/template/login_forum.html b/phpBB/styles/prosilver/template/login_forum.html
index c5c36d4564..3128bac788 100644
--- a/phpBB/styles/prosilver/template/login_forum.html
+++ b/phpBB/styles/prosilver/template/login_forum.html
@@ -28,7 +28,7 @@
{S_FORM_TOKEN_LOGIN}
<dl>
<dt>&nbsp;</dt>
- <dd>{S_HIDDEN_FIELDS}<input type="submit" name="login" id="login" class="button1" value="{L_LOGIN}" tabindex="2" /></dd>
+ <dd>{S_HIDDEN_FIELDS}<input type="submit" name="login" id="login" class="button1 button button-form" value="{L_LOGIN}" tabindex="2" /></dd>
</dl>
</fieldset>
</div>
diff --git a/phpBB/styles/prosilver/template/mcp_approve.html b/phpBB/styles/prosilver/template/mcp_approve.html
index f7874ab90b..2acc4753ab 100644
--- a/phpBB/styles/prosilver/template/mcp_approve.html
+++ b/phpBB/styles/prosilver/template/mcp_approve.html
@@ -19,8 +19,8 @@
<!-- ENDIF -->
<fieldset class="submit-buttons">
- <input type="button" name="confirm" value="{YES_VALUE}" class="button1" />&nbsp;
- <input type="button" name="cancel" value="{L_NO}" class="button2" />
+ <input type="button" name="confirm" value="{YES_VALUE}" class="button1 button button-form" />&nbsp;
+ <input type="button" name="cancel" value="{L_NO}" class="button1 button button-form-bold" />
</fieldset>
<!-- ELSE -->
@@ -66,8 +66,8 @@
</fieldset>
<fieldset class="submit-buttons">
- {S_HIDDEN_FIELDS}<input type="submit" name="confirm" value="{YES_VALUE}" class="button1" />&nbsp;
- <input type="submit" name="cancel" value="{L_NO}" class="button2" />
+ {S_HIDDEN_FIELDS}<input type="submit" name="confirm" value="{YES_VALUE}" class="button1 button button-form" />&nbsp;
+ <input type="submit" name="cancel" value="{L_NO}" class="button1 button button-form-bold" />
</fieldset>
</div>
diff --git a/phpBB/styles/prosilver/template/mcp_ban.html b/phpBB/styles/prosilver/template/mcp_ban.html
index 86a322435d..cbc50d5183 100644
--- a/phpBB/styles/prosilver/template/mcp_ban.html
+++ b/phpBB/styles/prosilver/template/mcp_ban.html
@@ -81,8 +81,8 @@
</div>
<fieldset class="submit-buttons">
- {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="bansubmit" value="{L_SUBMIT}" class="button1" />
+ {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="bansubmit" value="{L_SUBMIT}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
@@ -118,8 +118,8 @@
</div>
<fieldset class="submit-buttons">
- {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="unbansubmit" value="{L_SUBMIT}" class="button1" />
+ {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="unbansubmit" value="{L_SUBMIT}" class="button1 button button-form" />
</fieldset>
<!-- ELSE -->
diff --git a/phpBB/styles/prosilver/template/mcp_forum.html b/phpBB/styles/prosilver/template/mcp_forum.html
index 82df5d5dbe..c8cd0a1f86 100644
--- a/phpBB/styles/prosilver/template/mcp_forum.html
+++ b/phpBB/styles/prosilver/template/mcp_forum.html
@@ -144,7 +144,7 @@
<!-- IF S_CAN_MAKE_ANNOUNCE_GLOBAL --><option value="make_global">{L_MAKE_GLOBAL}</option><!-- ENDIF -->
<!-- EVENT mcp_forum_actions_append -->
</select>
- <input class="button2" type="submit" value="{L_SUBMIT}" />
+ <input class="button1 button button-form-bold" type="submit" value="{L_SUBMIT}" />
<div><a href="#" onclick="marklist('mcp', 'topic_id_list', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('mcp', 'topic_id_list', false); return false;">{L_UNMARK_ALL}</a></div>
<!-- ENDIF -->
{S_FORM_TOKEN}
diff --git a/phpBB/styles/prosilver/template/mcp_front.html b/phpBB/styles/prosilver/template/mcp_front.html
index 3eba12fe74..2f943b69c1 100644
--- a/phpBB/styles/prosilver/template/mcp_front.html
+++ b/phpBB/styles/prosilver/template/mcp_front.html
@@ -53,8 +53,8 @@
<!-- IF .unapproved -->
<fieldset class="display-actions">
{S_HIDDEN_FIELDS}
- <input class="button2" type="submit" name="action[disapprove]" value="{L_DISAPPROVE}" />&nbsp;
- <input class="button1" type="submit" name="action[approve]" value="{L_APPROVE}" />
+ <input class="button1 button button-form-bold" type="submit" name="action[disapprove]" value="{L_DISAPPROVE}" />&nbsp;
+ <input class="button1 button button-form" type="submit" name="action[approve]" value="{L_APPROVE}" />
<div><a href="#" onclick="marklist('mcp_queue', 'post_id_list', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('mcp_queue', 'post_id_list', false); return false;">{L_UNMARK_ALL}</a></div>
</fieldset>
<!-- ENDIF -->
diff --git a/phpBB/styles/prosilver/template/mcp_logs.html b/phpBB/styles/prosilver/template/mcp_logs.html
index 03216b4f38..d693ca0fed 100644
--- a/phpBB/styles/prosilver/template/mcp_logs.html
+++ b/phpBB/styles/prosilver/template/mcp_logs.html
@@ -8,7 +8,7 @@
<div class="inner">
<div class="action-bar bar-top">
- {L_SEARCH_KEYWORDS}{L_COLON} <input type="search" class="inputbox autowidth" name="keywords" value="{S_KEYWORDS}" />&nbsp;<input type="submit" class="button2" name="filter" value="{L_SEARCH}" />
+ {L_SEARCH_KEYWORDS}{L_COLON} <input type="search" class="inputbox autowidth" name="keywords" value="{S_KEYWORDS}" />&nbsp;<input type="submit" class="button1 button button-form-bold" name="filter" value="{L_SEARCH}" />
<div class="pagination">
{TOTAL}
<!-- IF .pagination -->
@@ -70,8 +70,8 @@
<!-- IF S_CLEAR_ALLOWED -->
<fieldset class="display-actions">
- <input class="button2" type="submit" name="action[del_all]" value="{L_DELETE_ALL}" />
- &nbsp;<input class="button1" type="submit" value="{L_DELETE_MARKED}" name="action[del_marked]" />
+ <input class="button1 button button-form-bold" type="submit" name="action[del_all]" value="{L_DELETE_ALL}" />
+ &nbsp;<input class="button1 button button-form" type="submit" value="{L_DELETE_MARKED}" name="action[del_marked]" />
<div><a href="#" onclick="marklist('mcp', 'mark', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('mcp', 'mark', false); return false;">{L_UNMARK_ALL}</a></div>
</fieldset>
diff --git a/phpBB/styles/prosilver/template/mcp_move.html b/phpBB/styles/prosilver/template/mcp_move.html
index 63197ef274..ee3e2146ac 100644
--- a/phpBB/styles/prosilver/template/mcp_move.html
+++ b/phpBB/styles/prosilver/template/mcp_move.html
@@ -23,8 +23,8 @@
<!-- ENDIF -->
<fieldset class="submit-buttons">
- <input type="button" name="confirm" value="{YES_VALUE}" class="button1" />&nbsp;
- <input type="button" name="cancel" value="{L_NO}" class="button2" />
+ <input type="button" name="confirm" value="{YES_VALUE}" class="button1 button button-form" />&nbsp;
+ <input type="button" name="cancel" value="{L_NO}" class="button1 button button-form-bold" />
</fieldset>
<!-- ELSE -->
@@ -58,8 +58,8 @@
</fieldset>
<fieldset class="submit-buttons">
- {S_HIDDEN_FIELDS}<input type="submit" name="confirm" value="{YES_VALUE}" class="button1" />&nbsp;
- <input type="submit" name="cancel" value="{L_NO}" class="button2" />
+ {S_HIDDEN_FIELDS}<input type="submit" name="confirm" value="{YES_VALUE}" class="button1 button button-form" />&nbsp;
+ <input type="submit" name="cancel" value="{L_NO}" class="button1 button button-form-bold" />
{S_FORM_TOKEN}
</fieldset>
diff --git a/phpBB/styles/prosilver/template/mcp_notes_front.html b/phpBB/styles/prosilver/template/mcp_notes_front.html
index 11f362376d..ee985a53da 100644
--- a/phpBB/styles/prosilver/template/mcp_notes_front.html
+++ b/phpBB/styles/prosilver/template/mcp_notes_front.html
@@ -19,8 +19,8 @@
</div>
<fieldset class="submit-buttons">
- <input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="submituser" value="{L_SUBMIT}" class="button1" />
+ <input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="submituser" value="{L_SUBMIT}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
</form>
diff --git a/phpBB/styles/prosilver/template/mcp_notes_user.html b/phpBB/styles/prosilver/template/mcp_notes_user.html
index 62d0562a46..6d318dda97 100644
--- a/phpBB/styles/prosilver/template/mcp_notes_user.html
+++ b/phpBB/styles/prosilver/template/mcp_notes_user.html
@@ -42,8 +42,8 @@
</div>
<fieldset class="submit-buttons">
- {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="action[add_feedback]" value="{L_SUBMIT}" class="button1" />
+ {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="action[add_feedback]" value="{L_SUBMIT}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
@@ -51,7 +51,7 @@
<div class="inner">
<div class="action-bar bar-top">
- {L_SEARCH_KEYWORDS}{L_COLON} <input type="search" class="inputbox autowidth" name="keywords" value="{S_KEYWORDS}" />&nbsp;<input type="submit" class="button2" name="filter" value="{L_SEARCH}" />
+ {L_SEARCH_KEYWORDS}{L_COLON} <input type="search" class="inputbox autowidth" name="keywords" value="{S_KEYWORDS}" />&nbsp;<input type="submit" class="button1 button button-form-bold" name="filter" value="{L_SEARCH}" />
<div class="pagination">
{TOTAL_REPORTS}
<!-- IF .pagination -->
@@ -108,8 +108,8 @@
<!-- IF S_CLEAR_ALLOWED -->
<fieldset class="display-actions">
- <input class="button2" type="submit" name="action[del_all]" value="{L_DELETE_ALL}" />
- &nbsp;<input class="button1" type="submit" name="action[del_marked]" value="{L_DELETE_MARKED}" />
+ <input class="button1 button button-form-bold" type="submit" name="action[del_all]" value="{L_DELETE_ALL}" />
+ &nbsp;<input class="button1 button button-form" type="submit" name="action[del_marked]" value="{L_DELETE_MARKED}" />
</fieldset>
<fieldset class="display-actions">
diff --git a/phpBB/styles/prosilver/template/mcp_post.html b/phpBB/styles/prosilver/template/mcp_post.html
index c2297a8053..cd6da1199d 100644
--- a/phpBB/styles/prosilver/template/mcp_post.html
+++ b/phpBB/styles/prosilver/template/mcp_post.html
@@ -33,9 +33,9 @@
<fieldset class="submit-buttons">
{% EVENT mcp_post_report_buttons_top_before %}
<!-- IF not S_REPORT_CLOSED -->
- <input class="button1" type="submit" value="{L_CLOSE_REPORT}" name="action[close]" /> &nbsp;
+ <input class="button1 button button-form" type="submit" value="{L_CLOSE_REPORT}" name="action[close]" /> &nbsp;
<!-- ENDIF -->
- <input class="button2" type="submit" value="{L_DELETE_REPORT}" name="action[delete]" />
+ <input class="button1 button button-form-bold" type="submit" value="{L_DELETE_REPORT}" name="action[delete]" />
{% EVENT mcp_post_report_buttons_top_after %}
<input type="hidden" name="report_id_list[]" value="{REPORT_ID}" />
{S_FORM_TOKEN}
@@ -82,8 +82,8 @@
<form method="post" id="mcp_approve" action="{U_APPROVE_ACTION}">
<p class="post-notice unapproved">
- <input class="button2" type="submit" value="{L_DISAPPROVE}" name="action[disapprove]" /> &nbsp;
- <input class="button1" type="submit" value="{L_APPROVE}" name="action[approve]" />
+ <input class="button1 button button-form-bold" type="submit" value="{L_DISAPPROVE}" name="action[disapprove]" /> &nbsp;
+ <input class="button1 button button-form" type="submit" value="{L_APPROVE}" name="action[approve]" />
<!-- IF not S_FIRST_POST --><input type="hidden" name="mode" value="unapproved_posts" /><!-- ENDIF -->
<input type="hidden" name="post_id_list[]" value="{POST_ID}" />
{S_FORM_TOKEN}
@@ -93,8 +93,8 @@
<form method="post" id="mcp_approve" action="{U_APPROVE_ACTION}">
<p class="post-notice deleted">
- <!-- IF S_CAN_DELETE_POST --><input class="button2" type="submit" value="{L_DELETE}" name="action[delete]" /> &nbsp;<!-- ENDIF -->
- <input class="button1" type="submit" value="{L_RESTORE}" name="action[restore]" />
+ <!-- IF S_CAN_DELETE_POST --><input class="button1 button button-form-bold" type="submit" value="{L_DELETE}" name="action[delete]" /> &nbsp;<!-- ENDIF -->
+ <input class="button1 button button-form" type="submit" value="{L_RESTORE}" name="action[restore]" />
<!-- IF not S_FIRST_POST --><input type="hidden" name="mode" value="deleted_posts" /><!-- ENDIF -->
<input type="hidden" name="post_id_list[]" value="{POST_ID}" />
{S_FORM_TOKEN}
@@ -161,10 +161,10 @@
<fieldset>
<dl>
<dt><label>{L_CHANGE_POSTER}{L_COLON}</label></dt>
- <!-- IF S_USER_SELECT --><dd><select name="u">{S_USER_SELECT}</select> <input type="submit" class="button2" name="action[chgposter_ip]" value="{L_CONFIRM}" /></dd><!-- ENDIF -->
+ <!-- IF S_USER_SELECT --><dd><select name="u">{S_USER_SELECT}</select> <input type="submit" class="button1 button button-form-bold" name="action[chgposter_ip]" value="{L_CONFIRM}" /></dd><!-- ENDIF -->
<dd style="margin-top:3px;">
<input class="inputbox autowidth" type="text" name="username" value="" />
- <input type="submit" class="button2" name="action[chgposter]" value="{L_CONFIRM}" />
+ <input type="submit" class="button1 button button-form-bold" name="action[chgposter]" value="{L_CONFIRM}" />
<br />
<span>[ <a href="{U_FIND_USERNAME}" onclick="find_username(this.href); return false;">{L_FIND_USERNAME}</a> ]</span>
</dd>
@@ -185,7 +185,7 @@
<dd><select name="action">
<!-- IF S_CAN_LOCK_POST --><!-- IF S_POST_LOCKED --><option value="unlock_post">{L_UNLOCK_POST} [{L_UNLOCK_POST_EXPLAIN}]</option><!-- ELSE --><option value="lock_post">{L_LOCK_POST} [{L_LOCK_POST_EXPLAIN}]</option><!-- ENDIF --><!-- ENDIF -->
<!-- IF S_CAN_DELETE_POST --><option value="delete_post">{L_DELETE_POST}</option><!-- ENDIF -->
- </select> <input class="button2" type="submit" value="{L_SUBMIT}" />
+ </select> <input class="button1 button button-form-bold" type="submit" value="{L_SUBMIT}" />
</dd>
</dl>
{S_FORM_TOKEN}
@@ -230,8 +230,8 @@
<!-- IF S_CLEAR_ALLOWED -->
<fieldset class="submit-buttons">
- <input class="button2" type="submit" name="action[del_all]" value="{L_DELETE_ALL}" />&nbsp;
- <input class="button2" type="submit" name="action[del_marked]" value="{L_DELETE_MARKED}" />
+ <input class="button1 button button-form-bold" type="submit" name="action[del_all]" value="{L_DELETE_ALL}" />&nbsp;
+ <input class="button1 button button-form-bold" type="submit" name="action[del_marked]" value="{L_DELETE_MARKED}" />
</fieldset>
<!-- ENDIF -->
<!-- ENDIF -->
@@ -244,8 +244,8 @@
</fieldset>
<fieldset class="submit-buttons">
- <input class="button1" type="submit" name="action[add_feedback]" value="{L_SUBMIT}" />&nbsp;
- <input class="button2" type="reset" value="{L_RESET}" />
+ <input class="button1 button button-form" type="submit" name="action[add_feedback]" value="{L_SUBMIT}" />&nbsp;
+ <input class="button1 button button-form-bold" type="reset" value="{L_RESET}" />
{S_FORM_TOKEN}
</fieldset>
</form>
diff --git a/phpBB/styles/prosilver/template/mcp_queue.html b/phpBB/styles/prosilver/template/mcp_queue.html
index ee69bf448d..a0fa8ee839 100644
--- a/phpBB/styles/prosilver/template/mcp_queue.html
+++ b/phpBB/styles/prosilver/template/mcp_queue.html
@@ -4,7 +4,7 @@
<fieldset class="forum-selection">
<label for="fo">{L_FORUM}{L_COLON} <select name="f" id="fo">{S_FORUM_OPTIONS}</select></label>
- <input type="submit" name="sort" value="{L_GO}" class="button2" />
+ <input type="submit" name="sort" value="{L_GO}" class="button1 button button-form-bold" />
{S_FORM_TOKEN}
</fieldset>
@@ -103,11 +103,11 @@
<!-- IF .postrow -->
<fieldset class="display-actions">
<!-- IF S_RESTORE -->
- <input class="button2" type="submit" name="action[delete]" value="{L_DELETE}" />&nbsp;
- <input class="button1" type="submit" name="action[restore]" value="{L_RESTORE}" />
+ <input class="button1 button button-form-bold" type="submit" name="action[delete]" value="{L_DELETE}" />&nbsp;
+ <input class="button1 button button-form" type="submit" name="action[restore]" value="{L_RESTORE}" />
<!-- ELSE -->
- <input class="button2" type="submit" name="action[disapprove]" value="{L_DISAPPROVE}" />&nbsp;
- <input class="button1" type="submit" name="action[approve]" value="{L_APPROVE}" />
+ <input class="button1 button button-form-bold" type="submit" name="action[disapprove]" value="{L_DISAPPROVE}" />&nbsp;
+ <input class="button1 button button-form" type="submit" name="action[approve]" value="{L_APPROVE}" />
<!-- ENDIF -->
<div>
<!-- IF S_TOPICS -->
diff --git a/phpBB/styles/prosilver/template/mcp_reports.html b/phpBB/styles/prosilver/template/mcp_reports.html
index e7e0a5c9ba..9b7d8963d4 100644
--- a/phpBB/styles/prosilver/template/mcp_reports.html
+++ b/phpBB/styles/prosilver/template/mcp_reports.html
@@ -5,7 +5,7 @@
<!-- IF not S_PM -->
<fieldset class="forum-selection">
<label for="fo">{L_FORUM}{L_COLON} <select name="f" id="fo">{S_FORUM_OPTIONS}</select></label>
- <input type="submit" name="sort" value="{L_GO}" class="button2" />
+ <input type="submit" name="sort" value="{L_GO}" class="button1 button button-form-bold" />
{S_FORM_TOKEN}
</fieldset>
<!-- ENDIF -->
@@ -102,8 +102,8 @@
<!-- IF .postrow -->
<fieldset class="display-actions">
- <input class="button2" type="submit" value="{L_DELETE_REPORTS}" name="action[delete]" />
- <!-- IF not S_CLOSED -->&nbsp;<input class="button1" type="submit" name="action[close]" value="{L_CLOSE_REPORTS}" /><!-- ENDIF -->
+ <input class="button1 button button-form-bold" type="submit" value="{L_DELETE_REPORTS}" name="action[delete]" />
+ <!-- IF not S_CLOSED -->&nbsp;<input class="button1 button button-form" type="submit" name="action[close]" value="{L_CLOSE_REPORTS}" /><!-- ENDIF -->
<div><a href="#" onclick="marklist('mcp', 'report_id_list', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('mcp', 'report_id_list', false); return false;">{L_UNMARK_ALL}</a></div>
</fieldset>
<!-- ENDIF -->
diff --git a/phpBB/styles/prosilver/template/mcp_topic.html b/phpBB/styles/prosilver/template/mcp_topic.html
index 889cab8b83..7e00d92f09 100644
--- a/phpBB/styles/prosilver/template/mcp_topic.html
+++ b/phpBB/styles/prosilver/template/mcp_topic.html
@@ -38,7 +38,7 @@
</dl>
<dl>
<dt><label>{L_DISPLAY_POSTS}{L_COLON}</label></dt>
- <dd>{S_SELECT_SORT_DAYS}&nbsp;&nbsp;<label>{L_SORT_BY} {S_SELECT_SORT_KEY}</label><label>{S_SELECT_SORT_DIR}</label> <input type="submit" name="sort" value="{L_GO}" class="button2" /></dd>
+ <dd>{S_SELECT_SORT_DAYS}&nbsp;&nbsp;<label>{L_SORT_BY} {S_SELECT_SORT_KEY}</label><label>{S_SELECT_SORT_DIR}</label> <input type="submit" name="sort" value="{L_GO}" class="button1 button button-form-bold" /></dd>
</dl>
</fieldset>
@@ -191,7 +191,7 @@
<!-- IF S_CAN_SPLIT --><option value="split_all"<!-- IF S_SPLIT_VIEW --> selected="selected"<!-- ENDIF -->>{L_SPLIT_POSTS}</option><option value="split_beyond">{L_SPLIT_AFTER}</option><!-- ENDIF -->
<!-- IF S_CAN_SYNC --><option value="resync">{L_RESYNC}</option><!-- ENDIF -->
</select>&nbsp;
- <input class="button1" type="submit" name="mcp_topic_submit" value="{L_SUBMIT}" />
+ <input class="button1 button button-form" type="submit" name="mcp_topic_submit" value="{L_SUBMIT}" />
<div><a href="#" onclick="marklist('mcp', 'post', true); return false;">{L_MARK_ALL}</a> :: <a href="#" onclick="marklist('mcp', 'post', false); return false;">{L_UNMARK_ALL}</a></div>
{S_HIDDEN_FIELDS}
{S_FORM_TOKEN}
diff --git a/phpBB/styles/prosilver/template/mcp_warn_front.html b/phpBB/styles/prosilver/template/mcp_warn_front.html
index 9b188b52ac..5514f3069f 100644
--- a/phpBB/styles/prosilver/template/mcp_warn_front.html
+++ b/phpBB/styles/prosilver/template/mcp_warn_front.html
@@ -21,8 +21,8 @@
</div>
<fieldset class="submit-buttons">
- <input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="submituser" value="{L_SUBMIT}" class="button1" />
+ <input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="submituser" value="{L_SUBMIT}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
</form>
diff --git a/phpBB/styles/prosilver/template/mcp_warn_post.html b/phpBB/styles/prosilver/template/mcp_warn_post.html
index 5e39480658..6c5b67f501 100644
--- a/phpBB/styles/prosilver/template/mcp_warn_post.html
+++ b/phpBB/styles/prosilver/template/mcp_warn_post.html
@@ -69,8 +69,8 @@
<!-- EVENT mcp_warn_post_add_warning_field_after -->
<fieldset class="submit-buttons">
- <input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="action[add_warning]" value="{L_SUBMIT}" class="button1" />
+ <input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="action[add_warning]" value="{L_SUBMIT}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
</form>
diff --git a/phpBB/styles/prosilver/template/mcp_warn_user.html b/phpBB/styles/prosilver/template/mcp_warn_user.html
index f4dbf2819e..8f7391e7b8 100644
--- a/phpBB/styles/prosilver/template/mcp_warn_user.html
+++ b/phpBB/styles/prosilver/template/mcp_warn_user.html
@@ -53,8 +53,8 @@
<!-- EVENT mcp_warn_user_add_warning_field_after -->
<fieldset class="submit-buttons">
- <input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="action[add_warning]" value="{L_SUBMIT}" class="button1" />
+ <input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="action[add_warning]" value="{L_SUBMIT}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
</form>
diff --git a/phpBB/styles/prosilver/template/memberlist_body.html b/phpBB/styles/prosilver/template/memberlist_body.html
index b8ff092372..551c168d1e 100644
--- a/phpBB/styles/prosilver/template/memberlist_body.html
+++ b/phpBB/styles/prosilver/template/memberlist_body.html
@@ -149,7 +149,7 @@
<!-- IF S_IN_SEARCH_POPUP and not S_SELECT_SINGLE -->
<fieldset class="display-actions">
- <input type="submit" name="submit" value="{L_SELECT_MARKED}" class="button2" />
+ <input type="submit" name="submit" value="{L_SELECT_MARKED}" class="button1 button button-form-bold" />
<div><a href="#" onclick="marklist('results', 'user', true); return false;">{L_MARK_ALL}</a> &bull; <a href="#" onclick="marklist('results', 'user', false); return false;">{L_UNMARK_ALL}</a></div>
</fieldset>
<!-- ENDIF -->
@@ -163,7 +163,7 @@
<fieldset class="display-options">
<label for="sk">{L_SELECT_SORT_METHOD}{L_COLON} <select name="sk" id="sk">{S_MODE_SELECT}</select></label>
<label for="sd">{L_ORDER} <select name="sd" id="sd">{S_ORDER_SELECT}</select></label>
- <input type="submit" name="sort" value="{L_SUBMIT}" class="button2" />
+ <input type="submit" name="sort" value="{L_SUBMIT}" class="button1 button button-form-bold" />
</fieldset>
<!-- ENDIF -->
diff --git a/phpBB/styles/prosilver/template/memberlist_email.html b/phpBB/styles/prosilver/template/memberlist_email.html
index eea699da08..29a886e2a8 100644
--- a/phpBB/styles/prosilver/template/memberlist_email.html
+++ b/phpBB/styles/prosilver/template/memberlist_email.html
@@ -95,7 +95,7 @@
<div class="inner">
<div class="content">
<fieldset class="submit-buttons">
- <input type="submit" tabindex="6" name="submit" class="button1" value="{L_SEND_EMAIL}" />
+ <input type="submit" tabindex="6" name="submit" class="button1 button button-form" value="{L_SEND_EMAIL}" />
</fieldset>
</div>
</div>
diff --git a/phpBB/styles/prosilver/template/memberlist_im.html b/phpBB/styles/prosilver/template/memberlist_im.html
index 874607d913..f91454aacb 100644
--- a/phpBB/styles/prosilver/template/memberlist_im.html
+++ b/phpBB/styles/prosilver/template/memberlist_im.html
@@ -26,7 +26,7 @@
</dl>
<dl class="fields2">
<dt>&nbsp;</dt>
- <dd><input class="button1" name="submit" type="submit" value="{L_IM_SEND}" /></dd>
+ <dd><input class="button1 button button-form" name="submit" type="submit" value="{L_IM_SEND}" /></dd>
</dl>
<!-- ELSE IF S_NO_SEND_JABBER -->
<dl class="fields2">
diff --git a/phpBB/styles/prosilver/template/memberlist_search.html b/phpBB/styles/prosilver/template/memberlist_search.html
index 34915ebc41..51e21d01bc 100644
--- a/phpBB/styles/prosilver/template/memberlist_search.html
+++ b/phpBB/styles/prosilver/template/memberlist_search.html
@@ -76,8 +76,8 @@
<hr />
<fieldset class="submit-buttons">
- <input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="submit" value="{L_SEARCH}" class="button1" />
+ <input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="submit" value="{L_SEARCH}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
diff --git a/phpBB/styles/prosilver/template/memberlist_team.html b/phpBB/styles/prosilver/template/memberlist_team.html
index 59041fbac0..9dca281b73 100644
--- a/phpBB/styles/prosilver/template/memberlist_team.html
+++ b/phpBB/styles/prosilver/template/memberlist_team.html
@@ -8,7 +8,7 @@
<div class="forumbg forumbg-table">
<div class="inner">
- <table class="table1" id="team">
+ <table class="table1 team" id="team">
<thead>
<tr>
<th class="name" data-dfn="{L_RANK}{L_COMMA_SEPARATOR}{L_USERNAME}"><span class="rank-img">{L_RANK}&nbsp;</span><!-- IF group.U_GROUP --><a href="{group.U_GROUP}">{group.GROUP_NAME}</a><!-- ELSE -->{group.GROUP_NAME}<!-- ENDIF --></th>
diff --git a/phpBB/styles/prosilver/template/memberlist_view.html b/phpBB/styles/prosilver/template/memberlist_view.html
index debf64cba2..a09f00c097 100644
--- a/phpBB/styles/prosilver/template/memberlist_view.html
+++ b/phpBB/styles/prosilver/template/memberlist_view.html
@@ -5,7 +5,7 @@
<!-- EVENT memberlist_view_content_prepend -->
<form method="post" action="{S_PROFILE_ACTION}" id="viewprofile">
-<div class="panel bg1<!-- IF S_ONLINE --> online<!-- ENDIF -->">
+<div class="panel bg1">
<div class="inner">
<!-- IF AVATAR_IMG -->
@@ -19,9 +19,11 @@
<!-- ENDIF -->
<dl class="left-box details profile-details">
- <dt>{L_USERNAME}{L_COLON}</dt>
+ <dt>
+ {L_USERNAME}{L_COLON}
+ </dt>
<dd>
- <!-- EVENT memberlist_view_username_prepend --><!-- IF USER_COLOR --><span style="color: {USER_COLOR}; font-weight: bold;"><!-- ELSE --><span><!-- ENDIF -->{USERNAME}</span><!-- EVENT memberlist_view_username_append -->
+ <!-- EVENT memberlist_view_username_prepend --><!-- IF USER_COLOR --><span style="color: {USER_COLOR}; font-weight: bold;"><!-- ELSE --><span><!-- ENDIF -->{USERNAME}</span><!-- EVENT memberlist_view_username_append --> <!-- IF S_ONLINE --> <i class="icon fa-circle fa-fw icon-md online" aria-hidden="true" title="{L_ONLINE}"></i><span class="sr-only">{L_ONLINE}</span><!-- ENDIF -->
<!-- IF U_EDIT_SELF --> [ <a href="{U_EDIT_SELF}">{L_EDIT_PROFILE}</a> ]<!-- ENDIF -->
<!-- IF U_USER_ADMIN --> [ <a href="{U_USER_ADMIN}">{L_USER_ADMIN}</a> ]<!-- ENDIF -->
<!-- IF U_USER_BAN --> [ <a href="{U_USER_BAN}">{L_USER_BAN}</a> ]<!-- ENDIF -->
@@ -35,7 +37,7 @@
<!-- ENDIF -->
<!-- IF S_USER_INACTIVE --><dt>{L_USER_IS_INACTIVE}{L_COLON}</dt> <dd>{USER_INACTIVE_REASON}</dd><!-- ENDIF -->
<!-- IF AGE !== '' --><dt>{L_AGE}{L_COLON}</dt> <dd>{AGE}</dd><!-- ENDIF -->
- <!-- IF S_GROUP_OPTIONS --><dt>{L_USERGROUPS}{L_COLON}</dt> <dd><select name="g">{S_GROUP_OPTIONS}</select> <input type="submit" name="submit" value="{L_GO}" class="button2" /></dd><!-- ENDIF -->
+ <!-- IF S_GROUP_OPTIONS --><dt>{L_USERGROUPS}{L_COLON}</dt> <dd><select name="g">{S_GROUP_OPTIONS}</select> <input type="submit" name="submit" value="{L_GO}" class="button1 button button-form-bold" /></dd><!-- ENDIF -->
<!-- EVENT memberlist_view_non_contact_custom_fields_before -->
<!-- BEGIN custom_fields -->
<!-- IF not custom_fields.S_PROFILE_CONTACT -->
diff --git a/phpBB/styles/prosilver/template/navbar_header.html b/phpBB/styles/prosilver/template/navbar_header.html
index bd54f71d41..173d0d530b 100644
--- a/phpBB/styles/prosilver/template/navbar_header.html
+++ b/phpBB/styles/prosilver/template/navbar_header.html
@@ -153,7 +153,7 @@
<!-- ENDIF -->
<!-- IF S_NOTIFICATIONS_DISPLAY -->
<li class="dropdown-container dropdown-{S_CONTENT_FLOW_END} rightside" data-skip-responsive="true">
- <a href="{U_VIEW_ALL_NOTIFICATIONS}" id="notification_list_button" class="dropdown-trigger">
+ <a href="{U_VIEW_ALL_NOTIFICATIONS}" id="notification-button" class="dropdown-trigger">
<i class="icon fa-bell fa-fw" aria-hidden="true"></i><span>{L_NOTIFICATIONS} </span><strong class="badge<!-- IF not NOTIFICATIONS_COUNT --> hidden<!-- ENDIF -->">{NOTIFICATIONS_COUNT}</strong>
</a>
<!-- INCLUDE notification_dropdown.html -->
diff --git a/phpBB/styles/prosilver/template/notification_dropdown.html b/phpBB/styles/prosilver/template/notification_dropdown.html
index e444d8fb90..8eb6e5e7ab 100644
--- a/phpBB/styles/prosilver/template/notification_dropdown.html
+++ b/phpBB/styles/prosilver/template/notification_dropdown.html
@@ -1,9 +1,9 @@
-<div id="notification_list" class="dropdown dropdown-extended notification_list">
- <div class="pointer"><div class="pointer-inner"></div></div>
+<div id="notification-menu" class="dropdown dropdown-extended notification-menu">
+ <div class="pointer dropdown-extended-pointer"><div class="pointer-inner"></div></div>
<div class="dropdown-contents">
<div class="header">
{L_NOTIFICATIONS}
- <span class="header_settings">
+ <span class="header-settings">
<a href="{U_NOTIFICATION_SETTINGS}">{L_SETTINGS}</a>
<!-- IF NOTIFICATIONS_COUNT -->
<span id="mark_all_notifications"> &bull; <a href="{U_MARK_ALL_NOTIFICATIONS}" data-ajax="notification.mark_all_read">{L_MARK_ALL_READ}</a></span>
@@ -11,19 +11,19 @@
</span>
</div>
- <ul>
+ <ul class="dropdown-extended-list notification-list">
<!-- IF not .notifications -->
- <li class="no_notifications">
+ <li class="dropdown-extended-item no-notifications">
{L_NO_NOTIFICATIONS}
</li>
<!-- ENDIF -->
<!-- BEGIN notifications -->
- <li class="<!-- IF notifications.UNREAD --> bg2<!-- ENDIF --><!-- IF notifications.STYLING --> {notifications.STYLING}<!-- ENDIF --><!-- IF not notifications.URL --> no-url<!-- ENDIF -->">
+ <li class="dropdown-extended-item notification-item<!-- IF notifications.UNREAD --> bg2<!-- ENDIF --><!-- IF notifications.STYLING --> {notifications.STYLING}<!-- ENDIF --><!-- IF not notifications.URL --> no-url<!-- ENDIF -->" <!-- IF notifications.UNREAD -->data-notification-unread="true"<!-- ENDIF -->>
<!-- IF notifications.URL -->
<a class="notification-block" href="<!-- IF notifications.UNREAD -->{notifications.U_MARK_READ}" data-real-url="{notifications.URL}<!-- ELSE -->{notifications.URL}<!-- ENDIF -->">
<!-- ENDIF -->
- <!-- IF notifications.AVATAR -->{notifications.AVATAR}<!-- ELSE --><img src="{T_THEME_PATH}/images/no_avatar.gif" alt="" /><!-- ENDIF -->
- <div class="notification_text">
+ <!-- IF notifications.AVATAR -->{notifications.AVATAR}<!-- ELSE --><img class="avatar notification-avatar" src="{T_THEME_PATH}/images/no_avatar.gif" alt="" /><!-- ENDIF -->
+ <div class="notification-text">
<p class="notification-title">{notifications.FORMATTED_TITLE}</p>
<!-- IF notifications.REFERENCE --><p class="notification-reference">{notifications.REFERENCE}</p><!-- ENDIF -->
<!-- IF notifications.FORUM --><p class="notification-forum">{notifications.FORUM}</p><!-- ENDIF -->
diff --git a/phpBB/styles/prosilver/template/overall_footer.html b/phpBB/styles/prosilver/template/overall_footer.html
index d1b8863438..45331902f7 100644
--- a/phpBB/styles/prosilver/template/overall_footer.html
+++ b/phpBB/styles/prosilver/template/overall_footer.html
@@ -41,6 +41,14 @@
<div id="darkenwrapper" class="darkenwrapper" data-ajax-error-title="{L_AJAX_ERROR_TITLE}" data-ajax-error-text="{L_AJAX_ERROR_TEXT}" data-ajax-error-text-abort="{L_AJAX_ERROR_TEXT_ABORT}" data-ajax-error-text-timeout="{L_AJAX_ERROR_TEXT_TIMEOUT}" data-ajax-error-text-parsererror="{L_AJAX_ERROR_TEXT_PARSERERROR}">
<div id="darken" class="darken">&nbsp;</div>
</div>
+ <div id="loading_indicator" class="loading_indicator">
+ <div class="loader">
+ <svg class="spinner" width="48px" height="48px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg" aria-labelledby="loader-title" role="img">
+ <title id="loader-title">{L_LOADING}</title>
+ <circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle>
+ </svg>
+ </div>
+ </div>
<div id="phpbb_alert" class="phpbb_alert" data-l-err="{L_ERROR}" data-l-timeout-processing-req="{L_TIMEOUT_PROCESSING_REQ}">
<a href="#" class="alert_close">
diff --git a/phpBB/styles/prosilver/template/overall_header.html b/phpBB/styles/prosilver/template/overall_header.html
index 2867802de4..dbf8486620 100644
--- a/phpBB/styles/prosilver/template/overall_header.html
+++ b/phpBB/styles/prosilver/template/overall_header.html
@@ -49,10 +49,6 @@
<link href="{T_STYLESHEET_LINK}" rel="stylesheet">
<link href="{T_STYLESHEET_LANG_LINK}" rel="stylesheet">
-<!-- IF S_CONTENT_DIRECTION eq 'rtl' -->
- <link href="{T_THEME_PATH}/bidi.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet">
-<!-- ENDIF -->
-
<!-- IF S_PLUPLOAD -->
<link href="{T_THEME_PATH}/plupload.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet">
<!-- ENDIF -->
@@ -61,10 +57,6 @@
<link href="{T_ASSETS_PATH}/cookieconsent/cookieconsent.min.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet">
<!-- ENDIF -->
-<!--[if lte IE 9]>
- <link href="{T_THEME_PATH}/tweaks.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet">
-<![endif]-->
-
<!-- EVENT overall_header_head_append -->
{$STYLESHEETS}
diff --git a/phpBB/styles/prosilver/template/pagination.html b/phpBB/styles/prosilver/template/pagination.html
index 5d484517ad..4e7297dafc 100644
--- a/phpBB/styles/prosilver/template/pagination.html
+++ b/phpBB/styles/prosilver/template/pagination.html
@@ -8,7 +8,7 @@
<li>{L_JUMP_TO_PAGE}{L_COLON}</li>
<li class="page-jump-form">
<input type="number" name="page-number" min="1" max="999999" title="{L_JUMP_PAGE}" class="inputbox tiny" data-per-page="{PER_PAGE}" data-base-url="{BASE_URL|e('html_attr')}" data-start-name="{START_NAME}" />
- <input class="button2" value="{L_GO}" type="button" />
+ <input class="button1 button button-form-bold" value="{L_GO}" type="button" />
</li>
</ul>
</div>
diff --git a/phpBB/styles/prosilver/template/posting_attach_body.html b/phpBB/styles/prosilver/template/posting_attach_body.html
index 0363fe0f05..02a595a2ce 100644
--- a/phpBB/styles/prosilver/template/posting_attach_body.html
+++ b/phpBB/styles/prosilver/template/posting_attach_body.html
@@ -8,7 +8,7 @@
<dt><label for="fileupload">{L_FILENAME}{L_COLON}</label></dt>
<dd>
<input type="file" name="fileupload" id="fileupload" class="inputbox autowidth" />
- <input type="submit" name="add_file" value="{L_ADD_FILE}" class="button2" onclick="upload = true;" />
+ <input type="submit" name="add_file" value="{L_ADD_FILE}" class="button1 button button-form-bold" onclick="upload = true;" />
</dd>
</dl>
<dl>
@@ -18,7 +18,7 @@
</fieldset>
<div id="attach-panel-multi" class="attach-panel-multi">
- <input type="button" class="button2" value="{L_PLUPLOAD_ADD_FILES}" id="add_files" />
+ <input type="button" class="button1 button button-form-bold" value="{L_PLUPLOAD_ADD_FILES}" id="add_files" />
</div>
{% EVENT posting_attach_body_file_list_before %}
@@ -38,8 +38,8 @@
<td class="attach-name">
<span class="file-name ellipsis-text"></span>
<span class="attach-controls">
- {% if S_BBCODE_ALLOWED %}<input type="button" value="{{ lang('PLACE_INLINE') }}" class="button2 hidden file-inline-bbcode" />&nbsp;{% endif %}
- <input type="button" value="{L_DELETE_FILE}" class="button2 file-delete" />
+ {% if S_BBCODE_ALLOWED %}<input type="button" value="{{ lang('PLACE_INLINE') }}}" class="button1 button button-form-bold hidden file-inline-bbcode" />&nbsp;{% endif %}
+ <input type="button" value="{L_DELETE_FILE}" class="button1 button button-form-bold file-delete" />
</span>
<span class="clear"></span>
</td>
@@ -64,8 +64,8 @@
<span class="file-name ellipsis-text"><a href="{attach_row.U_VIEW_ATTACHMENT}">{attach_row.FILENAME}</a></span>
{% EVENT posting_attach_body_attach_row_controls_prepend %}
<span class="attach-controls">
- {% if S_BBCODE_ALLOWED and S_INLINE_ATTACHMENT_OPTIONS %}<input type="button" value="{{ lang('PLACE_INLINE') }}" class="button2 file-inline-bbcode" />&nbsp;{% endif %}
- <input type="submit" name="delete_file[{attach_row.ASSOC_INDEX}]" value="{L_DELETE_FILE}" class="button2 file-delete" />
+ {% if S_BBCODE_ALLOWED and S_INLINE_ATTACHMENT_OPTIONS %}<input type="button" value="{{ lang('PLACE_INLINE') }}" class="button1 button button-form-bold file-inline-bbcode" />&nbsp;{% endif %}
+ <input type="submit" name="delete_file[{attach_row.ASSOC_INDEX}]" value="{L_DELETE_FILE}" class="button1 button button-form-bold file-delete" />
</span>
{% EVENT posting_attach_body_attach_row_controls_append %}
<span class="clear"></span>
diff --git a/phpBB/styles/prosilver/template/posting_editor.html b/phpBB/styles/prosilver/template/posting_editor.html
index d963c98e08..49fff3fb08 100644
--- a/phpBB/styles/prosilver/template/posting_editor.html
+++ b/phpBB/styles/prosilver/template/posting_editor.html
@@ -94,10 +94,10 @@
{S_HIDDEN_ADDRESS_FIELD}
{S_HIDDEN_FIELDS}
<!-- EVENT posting_editor_submit_buttons -->
- <!-- IF S_HAS_DRAFTS --><input type="submit" accesskey="d" tabindex="8" name="load" value="{L_LOAD_DRAFT}" class="button2" onclick="load_draft = true;" />&nbsp; <!-- ENDIF -->
- <!-- IF S_SAVE_ALLOWED --><input type="submit" accesskey="k" tabindex="7" name="save" value="{L_SAVE_DRAFT}" class="button2" />&nbsp; <!-- ENDIF -->
- <input type="submit" tabindex="5" name="preview" value="{L_PREVIEW}" class="button1"<!-- IF not S_PRIVMSGS --> onclick="document.getElementById('postform').action += '#preview';"<!-- ENDIF --> />&nbsp;
- <input type="submit" accesskey="s" tabindex="6" name="post" value="{L_SUBMIT}" class="button1 default-submit-action" />&nbsp;
+ <!-- IF S_HAS_DRAFTS --><input type="submit" accesskey="d" tabindex="8" name="load" value="{L_LOAD_DRAFT}" class="button1 button button-form-bold" onclick="load_draft = true;" />&nbsp; <!-- ENDIF -->
+ <!-- IF S_SAVE_ALLOWED --><input type="submit" accesskey="k" tabindex="7" name="save" value="{L_SAVE_DRAFT}" class="button1 button button-form-bold" />&nbsp; <!-- ENDIF -->
+ <input type="submit" tabindex="5" name="preview" value="{L_PREVIEW}" class="button1 button button-form"<!-- IF not S_PRIVMSGS --> onclick="document.getElementById('postform').action += '#preview';"<!-- ENDIF --> />&nbsp;
+ <input type="submit" accesskey="s" tabindex="6" name="post" value="{L_SUBMIT}" class="button1 button button-form default-submit-action" />&nbsp;
</fieldset>
diff --git a/phpBB/styles/prosilver/template/posting_pm_header.html b/phpBB/styles/prosilver/template/posting_pm_header.html
index 7fee914525..6ec0771ccd 100644
--- a/phpBB/styles/prosilver/template/posting_pm_header.html
+++ b/phpBB/styles/prosilver/template/posting_pm_header.html
@@ -13,8 +13,8 @@
<dl class="pmlist">
<dt><label><strong>{L_TO_ADD_MASS}{L_COLON}</strong><textarea id="username_list" name="username_list" class="inputbox" cols="50" rows="2" tabindex="1"></textarea></label></dt>
<dd class="recipients">
- <input type="submit" name="add_to" value="{L_ADD}" class="button2" tabindex="1" />
- <input type="submit" name="add_bcc" value="{L_ADD_BCC}" class="button2" tabindex="1" />
+ <input type="submit" name="add_to" value="{L_ADD}" class="button1 button button-form-bold" tabindex="1" />
+ <input type="submit" name="add_bcc" value="{L_ADD_BCC}" class="button1 button button-form-bold" tabindex="1" />
<!-- EVENT posting_pm_header_find_username_before -->
<span><a href="{U_FIND_USERNAME}" onclick="find_username(this.href); return false;">{L_FIND_USERNAME}</a></span>
<!-- EVENT posting_pm_header_find_username_after -->
@@ -31,7 +31,7 @@
<ul class="recipients">
<!-- BEGIN to_recipient -->
<li>
- <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{to_recipient.TYPE}[{to_recipient.UG_ID}]" value="x" class="button2" /><!-- ENDIF -->
+ <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{to_recipient.TYPE}[{to_recipient.UG_ID}]" value="x" class="button1 button button-form-bold" /><!-- ENDIF -->
<!-- IF to_recipient.IS_GROUP --><a href="{to_recipient.U_VIEW}" style="color: {{ to_recipient.COLOUR }}"><strong>{to_recipient.NAME}</strong></a><!-- ELSE -->{to_recipient.NAME_FULL}<!-- ENDIF -->
</li>
<!-- END to_recipient -->
@@ -48,7 +48,7 @@
<ul class="recipients">
<!-- BEGIN bcc_recipient -->
<li>
- <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{bcc_recipient.TYPE}[{bcc_recipient.UG_ID}]" value="x" class="button2" /><!-- ENDIF -->
+ <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{bcc_recipient.TYPE}[{bcc_recipient.UG_ID}]" value="x" class="button1 button button-form-bold" /><!-- ENDIF -->
<!-- IF bcc_recipient.IS_GROUP --><a href="{bcc_recipient.U_VIEW}" style="color: {{ bcc_recipient.COLOUR }}"><strong>{bcc_recipient.NAME}</strong></a><!-- ELSE -->{bcc_recipient.NAME_FULL}<!-- ENDIF -->
</li>
<!-- END bcc_recipient -->
@@ -62,7 +62,7 @@
<dl>
<dt><label for="username_list">{L_TO_ADD}{L_COLON}</label><!-- IF not S_EDIT_POST --><br /><span><a href="{U_FIND_USERNAME}" onclick="find_username(this.href); return false">{L_FIND_USERNAME}</a></span><!-- ENDIF --></dt>
<!-- IF not S_EDIT_POST -->
- <dd><input class="inputbox" type="text" name="username_list" id="username_list" size="20" value="" /> <input type="submit" name="add_to" value="{L_ADD}" class="button2" /></dd>
+ <dd><input class="inputbox" type="text" name="username_list" id="username_list" size="20" value="" /> <input type="submit" name="add_to" value="{L_ADD}" class="button1 button button-form-bold" /></dd>
<!-- ENDIF -->
<!-- IF .to_recipient -->
<dd class="recipients">
@@ -70,7 +70,7 @@
<!-- BEGIN to_recipient -->
<li>
<!-- IF to_recipient.IS_GROUP --><a href="{to_recipient.U_VIEW}"><strong>{to_recipient.NAME}</strong></a><!-- ELSE -->{to_recipient.NAME_FULL}<!-- ENDIF -->&nbsp;
- <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{to_recipient.TYPE}[{to_recipient.UG_ID}]" value="x" class="button2" /><!-- ENDIF -->
+ <!-- IF not S_EDIT_POST --><input type="submit" name="remove_{to_recipient.TYPE}[{to_recipient.UG_ID}]" value="x" class="button1 button button-form-bold" /><!-- ENDIF -->
</li>
<!-- END to_recipient -->
</dd>
diff --git a/phpBB/styles/prosilver/template/quickreply_editor.html b/phpBB/styles/prosilver/template/quickreply_editor.html
index 9839494491..86cc2a7654 100644
--- a/phpBB/styles/prosilver/template/quickreply_editor.html
+++ b/phpBB/styles/prosilver/template/quickreply_editor.html
@@ -18,8 +18,8 @@
<fieldset class="submit-buttons">
{S_FORM_TOKEN}
{QR_HIDDEN_FIELDS}
- <input type="submit" accesskey="f" tabindex="6" name="preview" value="{L_FULL_EDITOR}" class="button2" id="qr_full_editor" />&nbsp;
- <input type="submit" accesskey="s" tabindex="7" name="post" value="{L_SUBMIT}" class="button1" />&nbsp;
+ <input type="submit" accesskey="f" tabindex="6" name="preview" value="{L_FULL_EDITOR}" class="button1 button button-form-bold" id="qr_full_editor" />&nbsp;
+ <input type="submit" accesskey="s" tabindex="7" name="post" value="{L_SUBMIT}" class="button1 button button-form" />&nbsp;
</fieldset>
</div>
</div>
diff --git a/phpBB/styles/prosilver/template/report_body.html b/phpBB/styles/prosilver/template/report_body.html
index 285e8ec8d7..6fb7af7ad2 100644
--- a/phpBB/styles/prosilver/template/report_body.html
+++ b/phpBB/styles/prosilver/template/report_body.html
@@ -42,8 +42,8 @@
<div class="content">
<fieldset class="submit-buttons">
- <input type="submit" name="submit" class="button1" value="{L_SUBMIT}" />&nbsp;
- <input type="submit" name="cancel" class="button2" value="{L_CANCEL}" />
+ <input type="submit" name="submit" class="button1 button button-form" value="{L_SUBMIT}" />&nbsp;
+ <input type="submit" name="cancel" class="button1 button button-form-bold" value="{L_CANCEL}" />
{S_FORM_TOKEN}
</fieldset>
</div>
diff --git a/phpBB/styles/prosilver/template/search_body.html b/phpBB/styles/prosilver/template/search_body.html
index 618e2680ba..b194175892 100644
--- a/phpBB/styles/prosilver/template/search_body.html
+++ b/phpBB/styles/prosilver/template/search_body.html
@@ -93,8 +93,8 @@
<div class="inner">
<fieldset class="submit-buttons">
- {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="submit" value="{L_SEARCH}" class="button1" />
+ {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="submit" value="{L_SEARCH}" class="button1 button button-form" />
</fieldset>
</div>
diff --git a/phpBB/styles/prosilver/template/simple_footer.html b/phpBB/styles/prosilver/template/simple_footer.html
index fde162ab34..126ef084dd 100644
--- a/phpBB/styles/prosilver/template/simple_footer.html
+++ b/phpBB/styles/prosilver/template/simple_footer.html
@@ -8,8 +8,14 @@
<div id="darkenwrapper" class="darkenwrapper" data-ajax-error-title="{L_AJAX_ERROR_TITLE}" data-ajax-error-text="{L_AJAX_ERROR_TEXT}" data-ajax-error-text-abort="{L_AJAX_ERROR_TEXT_ABORT}" data-ajax-error-text-timeout="{L_AJAX_ERROR_TEXT_TIMEOUT}" data-ajax-error-text-parsererror="{L_AJAX_ERROR_TEXT_PARSERERROR}">
<div id="darken" class="darken">&nbsp;</div>
</div>
- <div id="loading_indicator" class="loading_indicator"></div>
-
+ <div id="loading_indicator" class="loading_indicator">
+ <div class="loader">
+ <svg class="spinner" width="48px" height="48px" viewBox="0 0 66 66" xmlns="http://www.w3.org/2000/svg" aria-labelledby="loader-title" role="img">
+ <title id="loader-title">{L_LOADING}</title>
+ <circle class="spinner-path" fill="none" stroke-width="6" stroke-linecap="round" cx="33" cy="33" r="30"></circle>
+ </svg>
+ </div>
+ </div>
<div id="phpbb_alert" class="phpbb_alert" data-l-err="{L_ERROR}" data-l-timeout-processing-req="{L_TIMEOUT_PROCESSING_REQ}">
<a href="#" class="alert_close">
<i class="icon fa-times-circle fa-fw" aria-hidden="true"></i>
diff --git a/phpBB/styles/prosilver/template/simple_header.html b/phpBB/styles/prosilver/template/simple_header.html
index 905d25096f..5543ea0e03 100644
--- a/phpBB/styles/prosilver/template/simple_header.html
+++ b/phpBB/styles/prosilver/template/simple_header.html
@@ -27,14 +27,6 @@
<link href="{T_STYLESHEET_LINK}" rel="stylesheet">
<link href="{T_STYLESHEET_LANG_LINK}" rel="stylesheet">
-<!-- IF S_CONTENT_DIRECTION eq 'rtl' -->
- <link href="{T_THEME_PATH}/bidi.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet">
-<!-- ENDIF -->
-
-<!--[if lte IE 8]>
- <link href="{T_THEME_PATH}/tweaks.css?assets_version={T_ASSETS_VERSION}" rel="stylesheet">
-<![endif]-->
-
<!-- DEFINE $POPUP = 1 -->
<!-- EVENT simple_header_head_append -->
diff --git a/phpBB/styles/prosilver/template/timezone_option.html b/phpBB/styles/prosilver/template/timezone_option.html
index 728dc9487a..01786d5ef4 100644
--- a/phpBB/styles/prosilver/template/timezone_option.html
+++ b/phpBB/styles/prosilver/template/timezone_option.html
@@ -8,7 +8,7 @@
<option value="{timezone_date.VALUE}"<!-- IF timezone_date.SELECTED --> selected="selected"<!-- ENDIF -->>{timezone_date.TITLE}</option>
<!-- END timezone_date -->
</select>
- <input type="button" id="tz_select_date_suggest" class="button2" style="display: none;" timezone-preselect="<!-- IF S_TZ_PRESELECT -->true<!-- ELSE -->false<!-- ENDIF -->" data-l-suggestion="{L_TIMEZONE_DATE_SUGGESTION}" value="{L_TIMEZONE_DATE_SUGGESTION}" />
+ <input type="button" id="tz_select_date_suggest" class="button1 button button-form-bold" style="display: none;" timezone-preselect="<!-- IF S_TZ_PRESELECT -->true<!-- ELSE -->false<!-- ENDIF -->" data-l-suggestion="{L_TIMEZONE_DATE_SUGGESTION}" value="{L_TIMEZONE_DATE_SUGGESTION}" />
</dd>
<!-- ENDIF -->
<dd>
diff --git a/phpBB/styles/prosilver/template/ucp_agreement.html b/phpBB/styles/prosilver/template/ucp_agreement.html
index 7959925d30..77adc60f21 100644
--- a/phpBB/styles/prosilver/template/ucp_agreement.html
+++ b/phpBB/styles/prosilver/template/ucp_agreement.html
@@ -43,11 +43,11 @@
<div class="inner">
<fieldset class="submit-buttons">
<!-- IF S_SHOW_COPPA -->
- <input type="submit" name="coppa_no" id="coppa_no" value="{{ L_COPPA_NO }}" class="button1" />
- <input type="submit" name="coppa_yes" id="coppa_yes" value="{{ L_COPPA_YES }}" class="button2" />
+ <input type="submit" name="coppa_no" id="coppa_no" value="{{ L_COPPA_NO }}" class="button1 button button-form" />
+ <input type="submit" name="coppa_yes" id="coppa_yes" value="{{ L_COPPA_YES }}" class="button1 button button-form-bold" />
<!-- ELSE -->
- <input type="submit" name="agreed" id="agreed" value="{L_AGREE}" class="button1" />&nbsp;
- <input type="submit" name="not_agreed" value="{L_NOT_AGREE}" class="button2" />
+ <input type="submit" name="agreed" id="agreed" value="{L_AGREE}" class="button1 button button-form" />&nbsp;
+ <input type="submit" name="not_agreed" value="{L_NOT_AGREE}" class="button1 button button-form-bold" />
<!-- ENDIF -->
{S_HIDDEN_FIELDS}
{S_FORM_TOKEN}
diff --git a/phpBB/styles/prosilver/template/ucp_attachments.html b/phpBB/styles/prosilver/template/ucp_attachments.html
index cfdbf9c7ea..a169c7cc35 100644
--- a/phpBB/styles/prosilver/template/ucp_attachments.html
+++ b/phpBB/styles/prosilver/template/ucp_attachments.html
@@ -73,7 +73,7 @@
<!-- IF S_ATTACHMENT_ROWS -->
<fieldset class="display-actions">
- <input class="button2" type="submit" name="delete" value="{L_DELETE_MARKED}" />
+ <input class="button1 button button-form-bold" type="submit" name="delete" value="{L_DELETE_MARKED}" />
<div><a href="#" onclick="marklist('ucp', 'attachment', true); return false;">{L_MARK_ALL}</a> &bull; <a href="#" onclick="marklist('ucp', 'attachment', false); return false;">{L_UNMARK_ALL}</a></div>
{S_FORM_TOKEN}
</fieldset>
diff --git a/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html b/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html
index 60061a3139..f2edbe1c6e 100644
--- a/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html
+++ b/phpBB/styles/prosilver/template/ucp_auth_link_oauth.html
@@ -10,7 +10,7 @@
</dl>
<dl>
<dt>&nbsp;</dt>
- <dd><input type="submit" name="submit" tabindex="6" value="{L_UCP_AUTH_LINK_UNLINK}" class="button1" /></dd>
+ <dd><input type="submit" name="submit" tabindex="6" value="{L_UCP_AUTH_LINK_UNLINK}" class="button1 button button-form" /></dd>
</dl>
<!-- ELSE -->
<dl>
@@ -18,7 +18,7 @@
</dl>
<dl>
<dt>&nbsp;</dt>
- <dd><input type="submit" name="submit" tabindex="6" value="{L_UCP_AUTH_LINK_LINK}" class="button1" /></dd>
+ <dd><input type="submit" name="submit" tabindex="6" value="{L_UCP_AUTH_LINK_LINK}" class="button1 button button-form" /></dd>
</dl>
<!-- ENDIF -->
</fieldset>
diff --git a/phpBB/styles/prosilver/template/ucp_avatar_options.html b/phpBB/styles/prosilver/template/ucp_avatar_options.html
index 2cf9488ed0..8987fecc72 100644
--- a/phpBB/styles/prosilver/template/ucp_avatar_options.html
+++ b/phpBB/styles/prosilver/template/ucp_avatar_options.html
@@ -39,8 +39,8 @@
</div>
<!-- IF not S_GROUP_MANAGE -->
<fieldset class="submit-buttons">
- <input type="reset" value="{L_RESET}" name="reset" class="button2" /> &nbsp;
- <input type="submit" name="submit" value="{L_SUBMIT}" class="button1" />
+ <input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" /> &nbsp;
+ <input type="submit" name="submit" value="{L_SUBMIT}" class="button1 button button-form" />
</fieldset>
<!-- ENDIF -->
</div>
diff --git a/phpBB/styles/prosilver/template/ucp_avatar_options_local.html b/phpBB/styles/prosilver/template/ucp_avatar_options_local.html
index e431b7425e..ee17902ed5 100644
--- a/phpBB/styles/prosilver/template/ucp_avatar_options_local.html
+++ b/phpBB/styles/prosilver/template/ucp_avatar_options_local.html
@@ -4,7 +4,7 @@
<option value="{avatar_local_cats.NAME}"<!-- IF avatar_local_cats.SELECTED --> selected="selected"<!-- ENDIF -->>{avatar_local_cats.NAME}</option>
<!-- END avatar_local_cats -->
</select></label>
-<input type="submit" value="{L_GO}" name="avatar_local_go" class="button2" />
+<input type="submit" value="{L_GO}" name="avatar_local_go" class="button1 button button-form-bold" />
<div id="gallery" class="gallery">
<!-- BEGIN avatar_local_row -->
diff --git a/phpBB/styles/prosilver/template/ucp_groups_manage.html b/phpBB/styles/prosilver/template/ucp_groups_manage.html
index adc8c614e6..bd3277ba32 100644
--- a/phpBB/styles/prosilver/template/ucp_groups_manage.html
+++ b/phpBB/styles/prosilver/template/ucp_groups_manage.html
@@ -74,8 +74,8 @@
<fieldset class="submit-buttons">
{S_HIDDEN_FIELDS}
- <input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="update" value="{L_SUBMIT}" class="button1" />
+ <input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="update" value="{L_SUBMIT}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
@@ -172,7 +172,7 @@
<fieldset class="display-actions">
<select name="action"><option value="">{L_SELECT_OPTION}</option>{S_ACTION_OPTIONS}</select>
- <input class="button2" type="submit" name="update" value="{L_SUBMIT}" />
+ <input class="button1 button button-form-bold" type="submit" name="update" value="{L_SUBMIT}" />
<div><a href="#" onclick="marklist('ucp', 'mark', true); return false;">{L_MARK_ALL}</a> &bull; <a href="#" onclick="marklist('ucp', 'mark', false); return false;">{L_UNMARK_ALL}</a></div>
</fieldset>
@@ -202,7 +202,7 @@
</div>
<fieldset class="submit-buttons">
- <input class="button1" type="submit" name="addusers" value="{L_SUBMIT}" />
+ <input class="button1 button button-form" type="submit" name="addusers" value="{L_SUBMIT}" />
{S_FORM_TOKEN}
</fieldset>
diff --git a/phpBB/styles/prosilver/template/ucp_groups_membership.html b/phpBB/styles/prosilver/template/ucp_groups_membership.html
index e824a7b867..e25e636391 100644
--- a/phpBB/styles/prosilver/template/ucp_groups_membership.html
+++ b/phpBB/styles/prosilver/template/ucp_groups_membership.html
@@ -149,7 +149,7 @@
<fieldset>
<!-- IF S_CHANGE_DEFAULT -->
<div class="left-box">
- <input class="button2" type="submit" name="change_default" value="{L_CHANGE_DEFAULT_GROUP}" />
+ <input class="button1 button button-form-bold" type="submit" name="change_default" value="{L_CHANGE_DEFAULT_GROUP}" />
{S_FORM_TOKEN}
</div>
<!-- ENDIF -->
@@ -162,7 +162,7 @@
<option value="resign">{L_RESIGN_SELECTED}</option>
<option value="demote">{L_DEMOTE_SELECTED}</option>
</select>&nbsp;
- <input class="button2" type="submit" name="submit" value="{L_SUBMIT}" />
+ <input class="button1 button button-form-bold" type="submit" name="submit" value="{L_SUBMIT}" />
{S_FORM_TOKEN}
</div>
<!-- ENDIF -->
diff --git a/phpBB/styles/prosilver/template/ucp_header.html b/phpBB/styles/prosilver/template/ucp_header.html
index 98d2eee1a0..9ebb404dd9 100644
--- a/phpBB/styles/prosilver/template/ucp_header.html
+++ b/phpBB/styles/prosilver/template/ucp_header.html
@@ -69,11 +69,11 @@
<dt>{L_FRIENDS}</dt>
<!-- BEGIN friends_online -->
- <dd class="friend-online" title="{L_FRIENDS_ONLINE}">{friends_online.USERNAME_FULL} <!-- IF S_SHOW_PM_BOX --> <input type="submit" name="add_to[{friends_online.USER_ID}]" value="{L_ADD}" class="button2" /><!-- ENDIF --><!-- IF friends_online.S_LAST_ROW and .friends_offline --><hr /><!-- ENDIF --></dd>
+ <dd class="friend-online" title="{L_FRIENDS_ONLINE}">{friends_online.USERNAME_FULL} <!-- IF S_SHOW_PM_BOX --> <input type="submit" name="add_to[{friends_online.USER_ID}]" value="{L_ADD}" class="button1 button button-form-bold" /><!-- ENDIF --><!-- IF friends_online.S_LAST_ROW and .friends_offline --><hr /><!-- ENDIF --></dd>
<!-- END friends_online -->
<!-- BEGIN friends_offline -->
- <dd class="friend-offline" title="{L_FRIENDS_OFFLINE}">{friends_offline.USERNAME_FULL} <!-- IF S_SHOW_PM_BOX --><input type="submit" name="add_to[{friends_offline.USER_ID}]" value="{L_ADD}" class="button2" /><!-- ENDIF --></dd>
+ <dd class="friend-offline" title="{L_FRIENDS_OFFLINE}">{friends_offline.USERNAME_FULL} <!-- IF S_SHOW_PM_BOX --><input type="submit" name="add_to[{friends_offline.USER_ID}]" value="{L_ADD}" class="button1 button button-form-bold" /><!-- ENDIF --></dd>
<!-- END friends_offline -->
</dl>
diff --git a/phpBB/styles/prosilver/template/ucp_login_link.html b/phpBB/styles/prosilver/template/ucp_login_link.html
index be173318cb..10d2d377ec 100644
--- a/phpBB/styles/prosilver/template/ucp_login_link.html
+++ b/phpBB/styles/prosilver/template/ucp_login_link.html
@@ -18,7 +18,7 @@
<fieldset class="fields1">
<dl>
<dt>&nbsp;</dt>
- <dd>{S_HIDDEN_FIELDS}<input type="submit" name="register" tabindex="1" value="{L_REGISTER}" class="button1" /></dd>
+ <dd>{S_HIDDEN_FIELDS}<input type="submit" name="register" tabindex="1" value="{L_REGISTER}" class="button1 button button-form" /></dd>
</dl>
</fieldset>
</form>
@@ -46,7 +46,7 @@
{S_LOGIN_REDIRECT}
<dl>
<dt>&nbsp;</dt>
- <dd>{S_HIDDEN_FIELDS}<input type="submit" name="login" tabindex="5" value="{L_LOGIN}" class="button1" /></dd>
+ <dd>{S_HIDDEN_FIELDS}<input type="submit" name="login" tabindex="5" value="{L_LOGIN}" class="button1 button button-form" /></dd>
</dl>
</fieldset>
</form>
diff --git a/phpBB/styles/prosilver/template/ucp_main_bookmarks.html b/phpBB/styles/prosilver/template/ucp_main_bookmarks.html
index 25647afe1a..d14ae23425 100644
--- a/phpBB/styles/prosilver/template/ucp_main_bookmarks.html
+++ b/phpBB/styles/prosilver/template/ucp_main_bookmarks.html
@@ -114,7 +114,7 @@
<!-- IF .topicrow and not S_NO_DISPLAY_BOOKMARKS -->
<fieldset class="display-actions">
- <input type="submit" name="unbookmark" value="{L_REMOVE_BOOKMARK_MARKED}" class="button2" />
+ <input type="submit" name="unbookmark" value="{L_REMOVE_BOOKMARK_MARKED}" class="button1 button button-form-bold" />
<div><a href="#" onclick="marklist('ucp', '', true); return false;">{L_MARK_ALL}</a> &bull; <a href="#" onclick="marklist('ucp', '', false); return false;">{L_UNMARK_ALL}</a></div>
{S_FORM_TOKEN}
</fieldset>
diff --git a/phpBB/styles/prosilver/template/ucp_main_drafts.html b/phpBB/styles/prosilver/template/ucp_main_drafts.html
index 52ad5b503b..25eb5ce2d1 100644
--- a/phpBB/styles/prosilver/template/ucp_main_drafts.html
+++ b/phpBB/styles/prosilver/template/ucp_main_drafts.html
@@ -16,8 +16,8 @@
</div>
<fieldset class="submit-buttons">
- {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="submit" value="{L_SAVE}" class="button1" />
+ {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="submit" value="{L_SAVE}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
@@ -66,7 +66,7 @@
<!-- IF .draftrow -->
<fieldset class="display-actions">
- <input class="button2" type="submit" name="delete" value="{L_DELETE_MARKED}" />
+ <input class="button1 button button-form-bold" type="submit" name="delete" value="{L_DELETE_MARKED}" />
<div><a href="#" onclick="marklist('postform', '', true); return false;">{L_MARK_ALL}</a> &bull; <a href="#" onclick="marklist('postform', '', false); return false;">{L_UNMARK_ALL}</a></div>
{S_FORM_TOKEN}
</fieldset>
diff --git a/phpBB/styles/prosilver/template/ucp_main_subscribed.html b/phpBB/styles/prosilver/template/ucp_main_subscribed.html
index d8de7fd093..ec1500ffac 100644
--- a/phpBB/styles/prosilver/template/ucp_main_subscribed.html
+++ b/phpBB/styles/prosilver/template/ucp_main_subscribed.html
@@ -160,7 +160,7 @@
<!-- IF .topicrow or .forumrow -->
<fieldset class="display-actions">
- <input type="submit" name="unwatch" value="{L_UNWATCH_MARKED}" class="button2" />
+ <input type="submit" name="unwatch" value="{L_UNWATCH_MARKED}" class="button1 button button-form-bold" />
<div><a href="#" onclick="marklist('ucp', 't', true); marklist('ucp', 'f', true); return false;">{L_MARK_ALL}</a> &bull; <a href="#" onclick="marklist('ucp', 't', false); marklist('ucp', 'f', false); return false;">{L_UNMARK_ALL}</a></div>
{S_FORM_TOKEN}
</fieldset>
diff --git a/phpBB/styles/prosilver/template/ucp_notifications.html b/phpBB/styles/prosilver/template/ucp_notifications.html
index 55e30477d2..8be157c933 100644
--- a/phpBB/styles/prosilver/template/ucp_notifications.html
+++ b/phpBB/styles/prosilver/template/ucp_notifications.html
@@ -2,11 +2,11 @@
<form id="ucp" method="post" action="{S_UCP_ACTION}"{S_FORM_ENCTYPE}>
-<h2>{TITLE}</h2>
+<h2 class="cp-title">{TITLE}</h2>
<div class="panel">
<div class="inner">
- <p>{TITLE_EXPLAIN}</p>
+ <p class="cp-desc">{TITLE_EXPLAIN}</p>
<!-- IF MODE == 'notification_options' -->
<table class="table1">
@@ -52,7 +52,7 @@
</div>
</div>
- <div class="notification_list">
+ <div class="notification-list">
<ul class="topiclist two-columns">
<li class="header">
<dl>
@@ -66,15 +66,15 @@
<li class="row<!-- IF notification_list.UNREAD --> bg3<!-- ELSE --><!-- IF notification_list.S_ROW_COUNT is odd --> bg1<!-- ELSE --> bg2<!-- ENDIF --><!-- ENDIF --><!-- IF notification_list.STYLING --> {notification_list.STYLING}<!-- ENDIF -->">
<dl>
<dt>
- <div class="list-inner">
- <!-- IF notification_list.AVATAR -->{notification_list.AVATAR}<!-- ELSE --><img src="{T_THEME_PATH}/images/no_avatar.gif" alt="" /><!-- ENDIF -->
- <div class="notifications">
+ <div class="list-inner notification-item">
+ <!-- IF notification_list.AVATAR -->{notification_list.AVATAR}<!-- ELSE --><img class="avatar notification-avatar" src="{T_THEME_PATH}/images/no_avatar.gif" alt="" /><!-- ENDIF -->
+ <div class="notification-text">
<!-- IF notification_list.URL --><a href="<!-- IF notification_list.UNREAD -->{notification_list.U_MARK_READ}<!-- ELSE -->{notification_list.URL}<!-- ENDIF -->"><!-- ENDIF -->
- <p class="notifications_title">{notification_list.FORMATTED_TITLE}<!-- IF notification_list.REFERENCE --> {notification_list.REFERENCE}<!-- ENDIF --></p>
+ <p class="notification-title">{notification_list.FORMATTED_TITLE}<!-- IF notification_list.REFERENCE --> {notification_list.REFERENCE}<!-- ENDIF --></p>
<!-- IF notification_list.URL --></a><!-- ENDIF -->
- <!-- IF notification_list.FORUM --><p class="notifications_forum">{notification_list.FORUM}</p><!-- ENDIF -->
- <!-- IF notification_list.REASON --><p class="notifications_reason">{notification_list.REASON}</p><!-- ENDIF -->
- <p class="notifications_time">{notification_list.TIME}</p>
+ <!-- IF notification_list.FORUM --><p class="notifications-forum">{notification_list.FORUM}</p><!-- ENDIF -->
+ <!-- IF notification_list.REASON --><p class="notifications-reason">{notification_list.REASON}</p><!-- ENDIF -->
+ <p class="notifications-time">{notification_list.TIME}</p>
</div>
</div>
</dt>
@@ -109,7 +109,7 @@
<fieldset class="display-actions">
<input type="hidden" name="form_time" value="{FORM_TIME}" />
{S_HIDDEN_FIELDS}
- <input type="submit" name="submit" value="<!-- IF MODE == 'notification_options' -->{L_SUBMIT}<!-- ELSE -->{L_MARK_READ}<!-- ENDIF -->" class="button1" />
+ <input type="submit" name="submit" value="<!-- IF MODE == 'notification_options' -->{L_SUBMIT}<!-- ELSE -->{L_MARK_READ}<!-- ENDIF -->" class="button1 button button-form" />
<div><a href="#" onclick="$('#ucp input:checkbox').prop('checked', true); return false;">{L_MARK_ALL}</a> &bull; <a href="#" onclick="$('#ucp input:checkbox').prop('checked', false); return false;">{L_UNMARK_ALL}</a></div>
{S_FORM_TOKEN}
</fieldset>
diff --git a/phpBB/styles/prosilver/template/ucp_pm_options.html b/phpBB/styles/prosilver/template/ucp_pm_options.html
index 247be8b6fd..4c971243b1 100644
--- a/phpBB/styles/prosilver/template/ucp_pm_options.html
+++ b/phpBB/styles/prosilver/template/ucp_pm_options.html
@@ -14,7 +14,7 @@
<ol class="def-rules">
<!-- BEGIN rule -->
- <li><div class="right-box"><input type="submit" name="delete_rule[{rule.RULE_ID}]" value="{L_DELETE_RULE}" class="button2" /></div><strong>{L_IF}</strong> {rule.CHECK} <em>{rule.RULE}</em> <!-- IF rule.STRING --><strong>{rule.STRING}</strong> | <!-- ENDIF -->{rule.ACTION}<!-- IF rule.FOLDER -->{L_COLON} {rule.FOLDER}<!-- ENDIF --><div style="clear: both;"></div></li>
+ <li><div class="right-box"><input type="submit" name="delete_rule[{rule.RULE_ID}]" value="{L_DELETE_RULE}" class="button1 button button-form-bold" /></div><strong>{L_IF}</strong> {rule.CHECK} <em>{rule.RULE}</em> <!-- IF rule.STRING --><strong>{rule.STRING}</strong> | <!-- ENDIF -->{rule.ACTION}<!-- IF rule.FOLDER -->{L_COLON} {rule.FOLDER}<!-- ENDIF --><div style="clear: both;"></div></li>
<!-- BEGINELSE -->
<li><strong>{L_NO_RULES_DEFINED}</strong></li>
<!-- END rule -->
@@ -28,22 +28,22 @@
<dl>
<dt><label<!-- IF S_CHECK_SELECT --> for="check_option"<!-- ENDIF -->>{L_IF}{L_COLON}</label></dt>
<dd>
- <!-- IF S_CHECK_SELECT --><select name="check_option" id="check_option">{S_CHECK_OPTIONS}</select> <input type="submit" name="next" value="{L_NEXT_STEP}" class="button2" /><!-- ELSE -->{CHECK_CURRENT}<input type="hidden" name="check_option" value="{CHECK_OPTION}" /><!-- ENDIF -->
+ <!-- IF S_CHECK_SELECT --><select name="check_option" id="check_option">{S_CHECK_OPTIONS}</select> <input type="submit" name="next" value="{L_NEXT_STEP}" class="button1 button button-form-bold" /><!-- ELSE -->{CHECK_CURRENT}<input type="hidden" name="check_option" value="{CHECK_OPTION}" /><!-- ENDIF -->
</dd>
</dl>
<!-- ENDIF -->
<!-- IF S_RULE_DEFINED -->
<dl>
- <dt><!-- IF S_RULE_SELECT --><input type="submit" name="back[rule]" value="{L_PREVIOUS_STEP}" class="button2" /><!-- ELSE --><label>&nbsp;</label><!-- ENDIF --></dt>
- <dd><!-- IF S_RULE_SELECT --><select name="rule_option" id="rule_option">{S_RULE_OPTIONS}</select> <input type="submit" name="next" value="{L_NEXT_STEP}" class="button2" /><!-- ELSE --><em>{RULE_CURRENT}</em><input type="hidden" name="rule_option" value="{RULE_OPTION}" /><!-- ENDIF --></dd>
+ <dt><!-- IF S_RULE_SELECT --><input type="submit" name="back[rule]" value="{L_PREVIOUS_STEP}" class="button1 button button-form-bold" /><!-- ELSE --><label>&nbsp;</label><!-- ENDIF --></dt>
+ <dd><!-- IF S_RULE_SELECT --><select name="rule_option" id="rule_option">{S_RULE_OPTIONS}</select> <input type="submit" name="next" value="{L_NEXT_STEP}" class="button1 button button-form-bold" /><!-- ELSE --><em>{RULE_CURRENT}</em><input type="hidden" name="rule_option" value="{RULE_OPTION}" /><!-- ENDIF --></dd>
</dl>
<!-- ENDIF -->
<!-- IF S_COND_DEFINED -->
<!-- IF S_COND_SELECT or COND_CURRENT -->
<dl>
- <dt><!-- IF S_COND_SELECT --><input type="submit" name="back[cond]" value="{L_PREVIOUS_STEP}" class="button2" /><!-- ELSE --><label>&nbsp;</label><!-- ENDIF --></dt>
+ <dt><!-- IF S_COND_SELECT --><input type="submit" name="back[cond]" value="{L_PREVIOUS_STEP}" class="button1 button button-form-bold" /><!-- ELSE --><label>&nbsp;</label><!-- ENDIF --></dt>
<dd>
<!-- IF S_COND_SELECT -->
<!-- IF S_TEXT_CONDITION -->
@@ -53,7 +53,7 @@
<!-- ELSEIF S_GROUP_CONDITION -->
<input type="hidden" name="rule_string" value="{CURRENT_STRING}" /><!-- IF S_GROUP_OPTIONS --><select name="rule_group_id">{S_GROUP_OPTIONS}</select><!-- ELSE -->{L_NO_GROUPS}<!-- ENDIF -->
<!-- ENDIF -->
- <input type="submit" name="next" value="{L_NEXT_STEP}" class="button2" />
+ <input type="submit" name="next" value="{L_NEXT_STEP}" class="button1 button button-form-bold" />
<!-- ELSE -->
<strong>{COND_CURRENT}</strong><input type="hidden" name="rule_string" value="{CURRENT_STRING}" /><input type="hidden" name="rule_user_id" value="{CURRENT_USER_ID}" /><input type="hidden" name="rule_group_id" value="{CURRENT_GROUP_ID}" />
<!-- ENDIF -->
@@ -68,8 +68,8 @@
<!-- IF S_ACTION_DEFINED -->
<dl>
- <dt><!-- IF S_ACTION_SELECT --><input type="submit" name="back[action]" value="{L_PREVIOUS_STEP}" class="button2" /><!-- ELSE --><label>&nbsp;</label><!-- ENDIF --></dt>
- <dd><!-- IF S_ACTION_SELECT --> <select name="action_option">{S_ACTION_OPTIONS}</select> <input type="submit" name="add_rule" value="{L_ADD_RULE}" class="button1" /><!-- ELSE -->{ACTION_CURRENT}<input type="hidden" name="action_option" value="{ACTION_OPTION}" /><!-- ENDIF --></dd>
+ <dt><!-- IF S_ACTION_SELECT --><input type="submit" name="back[action]" value="{L_PREVIOUS_STEP}" class="button1 button button-form-bold" /><!-- ELSE --><label>&nbsp;</label><!-- ENDIF --></dt>
+ <dd><!-- IF S_ACTION_SELECT --> <select name="action_option">{S_ACTION_OPTIONS}</select> <input type="submit" name="add_rule" value="{L_ADD_RULE}" class="button1 button button-form" /><!-- ELSE -->{ACTION_CURRENT}<input type="hidden" name="action_option" value="{ACTION_OPTION}" /><!-- ENDIF --></dd>
</dl>
<!-- ENDIF -->
@@ -82,7 +82,7 @@
<!-- IF not S_MAX_FOLDER_ZERO -->
<dl>
<dt><label for="foldername">{L_ADD_FOLDER}{L_COLON}</label></dt>
- <dd><!-- IF S_MAX_FOLDER_REACHED -->{L_MAX_FOLDER_REACHED}<!-- ELSE --><input type="text" class="inputbox medium" name="foldername" id="foldername" size="30" maxlength="30" /> <input class="button2" type="submit" name="addfolder" value="{L_ADD}" /><!-- ENDIF --></dd>
+ <dd><!-- IF S_MAX_FOLDER_REACHED -->{L_MAX_FOLDER_REACHED}<!-- ELSE --><input type="text" class="inputbox medium" name="foldername" id="foldername" size="30" maxlength="30" /> <input class="button1 button button-form-bold" type="submit" name="addfolder" value="{L_ADD}" /><!-- ENDIF --></dd>
</dl>
<!-- IF S_FOLDER_OPTIONS --><hr class="dashed" /><!-- ENDIF -->
<!-- ENDIF -->
@@ -94,7 +94,7 @@
<dt><label for="rename_folder_id">{L_RENAME_FOLDER}{L_COLON}</label></dt>
<dd><select name="rename_folder_id" id="rename_folder_id">{S_FOLDER_OPTIONS}</select></dd>
<dt><label for="new_folder_name">{L_NEW_FOLDER_NAME}{L_COLON}</label></dt>
- <dd><input type="text" class="inputbox tiny" name="new_folder_name" id="new_folder_name" maxlength="30" /> <input class="button2" type="submit" name="rename_folder" value="{L_RENAME}" /></dd>
+ <dd><input type="text" class="inputbox tiny" name="new_folder_name" id="new_folder_name" maxlength="30" /> <input class="button1 button button-form-bold" type="submit" name="rename_folder" value="{L_RENAME}" /></dd>
</dl>
<hr class="dashed" />
<dl>
@@ -102,7 +102,7 @@
<dd><select name="remove_folder_id" id="remove_folder_id">{S_FOLDER_OPTIONS}</select></dd>
<dd style="margin-top: 3px;"><label for="remove_action1"><input type="radio" name="remove_action" id="remove_action1" value="1" checked="checked" /> {L_MOVE_DELETED_MESSAGES_TO}{L_COLON}</label> <select name="move_to">{S_TO_FOLDER_OPTIONS}</select></dd>
<dd style="margin-top: 3px;"><label for="remove_action2"><input type="radio" name="remove_action" id="remove_action2" value="2" /> {L_DELETE_MESSAGES_IN_FOLDER}</label></dd>
- <dd style="margin-top: 3px;"><input class="button2" type="submit" name="remove_folder" value="{L_REMOVE}" /></dd>
+ <dd style="margin-top: 3px;"><input class="button1 button button-form-bold" type="submit" name="remove_folder" value="{L_REMOVE}" /></dd>
</dl>
<!-- ENDIF -->
@@ -119,7 +119,7 @@
<dl>
<dt><label>{L_DEFAULT_ACTION}{L_COLON}</label><br /><span>{L_DEFAULT_ACTION_EXPLAIN}</span></dt>
<dd>{DEFAULT_ACTION}</dd>
- <dd><input class="button2" type="submit" name="fullfolder" value="{L_CHANGE}" /></dd>
+ <dd><input class="button1 button button-form-bold" type="submit" name="fullfolder" value="{L_CHANGE}" /></dd>
</dl>
</fieldset>
diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html b/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html
index a290313df7..f4556c4555 100644
--- a/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html
+++ b/phpBB/styles/prosilver/template/ucp_pm_viewfolder.html
@@ -24,8 +24,8 @@
</div>
<fieldset class="submit-buttons">
<input type="hidden" name="export_option" value="CSV" />
- <input class="button1" type="submit" name="submit_export" value="{L_EXPORT_FOLDER}" />&nbsp;
- <input class="button2" type="reset" value="{L_RESET}" name="reset" />&nbsp;
+ <input class="button1 button button-form" type="submit" name="submit_export" value="{L_EXPORT_FOLDER}" />&nbsp;
+ <input class="button1 button button-form-bold" type="reset" value="{L_RESET}" name="reset" />&nbsp;
{S_FORM_TOKEN}
</fieldset>
</form>
@@ -100,8 +100,8 @@
<!-- IF FOLDER_CUR_MESSAGES neq 0 -->
<fieldset class="display-actions">
- <div class="left-box"><label for="export_option">{L_EXPORT_FOLDER}{L_COLON} <select name="export_option" id="export_option"><option value="CSV">{L_EXPORT_AS_CSV}</option><option value="CSV_EXCEL">{L_EXPORT_AS_CSV_EXCEL}</option><option value="XML">{L_EXPORT_AS_XML}</option></select></label> <input class="button2" type="submit" name="submit_export" value="{L_GO}" /><br /></div>
- <select name="mark_option">{S_MARK_OPTIONS}{S_MOVE_MARKED_OPTIONS}</select> <input class="button2" type="submit" name="submit_mark" value="{L_GO}" />
+ <div class="left-box"><label for="export_option">{L_EXPORT_FOLDER}{L_COLON} <select name="export_option" id="export_option"><option value="CSV">{L_EXPORT_AS_CSV}</option><option value="CSV_EXCEL">{L_EXPORT_AS_CSV_EXCEL}</option><option value="XML">{L_EXPORT_AS_XML}</option></select></label> <input class="button1 button button-form-bold" type="submit" name="submit_export" value="{L_GO}" /><br /></div>
+ <select name="mark_option">{S_MARK_OPTIONS}{S_MOVE_MARKED_OPTIONS}</select> <input class="button1 button button-form-bold" type="submit" name="submit_mark" value="{L_GO}" />
<div><a href="#" onclick="marklist('viewfolder', 'marked_msg', true); return false;">{L_MARK_ALL}</a> &bull; <a href="#" onclick="marklist('viewfolder', 'marked_msg', false); return false;">{L_UNMARK_ALL}</a></div>
</fieldset>
diff --git a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html
index 7cb44a0189..c1663f0882 100644
--- a/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html
+++ b/phpBB/styles/prosilver/template/ucp_pm_viewmessage.html
@@ -22,147 +22,147 @@
<!-- ENDIF -->
-<div id="post-{MESSAGE_ID}" class="post pm has-profile<!-- IF S_POST_UNAPPROVED or S_POST_REPORTED --> reported<!-- ENDIF --><!-- IF S_ONLINE --> online<!-- ENDIF -->">
-<div class="inner">
-
- <dl class="postprofile" id="profile{MESSAGE_ID}">
- <dt class="<!-- IF RANK_TITLE or RANK_IMG -->has-profile-rank<!-- ELSE -->no-profile-rank<!-- ENDIF --> <!-- IF AUTHOR_AVATAR -->has-avatar<!-- ELSE -->no-avatar<!-- ENDIF -->">
- <div class="avatar-container">
- <!-- EVENT ucp_pm_viewmessage_avatar_before -->
- <!-- IF AUTHOR_AVATAR --><a href="{U_MESSAGE_AUTHOR}" class="avatar">{AUTHOR_AVATAR}</a><!-- ENDIF -->
- <!-- EVENT ucp_pm_viewmessage_avatar_after -->
- </div>
- {MESSAGE_AUTHOR_FULL}
- </dt>
-
- <!-- EVENT ucp_pm_viewmessage_rank_before -->
- <!-- IF RANK_TITLE or RANK_IMG --><dd class="profile-rank">{RANK_TITLE}<!-- IF RANK_TITLE and RANK_IMG --><br /><!-- ENDIF -->{RANK_IMG}</dd><!-- ENDIF -->
- <!-- EVENT ucp_pm_viewmessage_rank_after -->
-
- <dd class="profile-posts"><strong>{L_POSTS}{L_COLON}</strong> <!-- IF U_AUTHOR_POSTS != '' --><a href="{U_AUTHOR_POSTS}">{AUTHOR_POSTS}</a><!-- ELSE -->{AUTHOR_POSTS}<!-- ENDIF --></dd>
- <!-- IF AUTHOR_JOINED --><dd class="profile-joined"><strong>{L_JOINED}{L_COLON}</strong> {AUTHOR_JOINED}</dd><!-- ENDIF -->
-
- <!-- EVENT ucp_pm_viewmessage_custom_fields_before -->
- <!-- BEGIN custom_fields -->
- <!-- IF not custom_fields.S_PROFILE_CONTACT -->
- <dd class="profile-custom-field profile-{custom_fields.PROFILE_FIELD_IDENT}"><strong>{custom_fields.PROFILE_FIELD_NAME}{L_COLON}</strong> {custom_fields.PROFILE_FIELD_VALUE}</dd>
- <!-- ENDIF -->
- <!-- END custom_fields -->
- <!-- EVENT ucp_pm_viewmessage_custom_fields_after -->
-
- <!-- EVENT ucp_pm_viewmessage_contact_fields_before -->
- <!-- IF .contact -->
- <dd class="profile-contact">
- <strong>{L_CONTACT}{L_COLON}</strong>
- <div class="dropdown-container dropdown-left">
- <a href="#" class="dropdown-trigger" title="{CONTACT_USER}"><i class="icon fa-commenting-o fa-fw icon-lg" aria-hidden="true"></i><span class="sr-only">{CONTACT_USER}</span></a>
- <div class="dropdown">
- <div class="pointer"><div class="pointer-inner"></div></div>
- <div class="dropdown-contents contact-icons">
- <!-- BEGIN contact -->
- {% set REMAINDER = contact.S_ROW_COUNT % 4 %}
- <!-- DEFINE $S_LAST_CELL = ((REMAINDER eq 3) or (contact.S_LAST_ROW and contact.S_NUM_ROWS < 4)) -->
- <!-- IF REMAINDER eq 0 -->
- <div>
- <!-- ENDIF -->
- <a href="<!-- IF contact.U_CONTACT -->{contact.U_CONTACT}<!-- ELSE -->{contact.U_PROFILE_AUTHOR}<!-- ENDIF -->" title="{contact.NAME}"<!-- IF $S_LAST_CELL --> class="last-cell"<!-- ENDIF --><!-- IF contact.ID eq 'jabber' --> onclick="popup(this.href, 750, 320); return false;"<!-- ENDIF -->>
- <span class="contact-icon {contact.ID}-icon">{contact.NAME}</span>
- </a>
- <!-- IF REMAINDER eq 3 or contact.S_LAST_ROW -->
- </div>
- <!-- ENDIF -->
- <!-- END contact -->
+<div id="post-{MESSAGE_ID}" class="post pm has-profile<!-- IF S_POST_UNAPPROVED or S_POST_REPORTED --> reported<!-- ENDIF -->">
+ <div class="inner">
+
+ <dl class="postprofile" id="profile{MESSAGE_ID}">
+ <dt class="<!-- IF RANK_TITLE or RANK_IMG -->has-profile-rank<!-- ELSE -->no-profile-rank<!-- ENDIF --> <!-- IF AUTHOR_AVATAR -->has-avatar<!-- ELSE -->no-avatar<!-- ENDIF -->">
+ <div class="avatar-container">
+ <!-- EVENT ucp_pm_viewmessage_avatar_before -->
+ <!-- IF AUTHOR_AVATAR --><a href="{U_MESSAGE_AUTHOR}" class="avatar">{AUTHOR_AVATAR}</a><!-- ENDIF -->
+ <!-- EVENT ucp_pm_viewmessage_avatar_after -->
+ </div>
+ {MESSAGE_AUTHOR_FULL}<!-- IF S_ONLINE --> <i class="icon fa-circle fa-fw icon-md online" aria-hidden="true" title="{L_ONLINE}"></i><span class="sr-only">{L_ONLINE}</span><!-- ENDIF -->
+ </dt>
+
+ <!-- EVENT ucp_pm_viewmessage_rank_before -->
+ <!-- IF RANK_TITLE or RANK_IMG --><dd class="profile-rank">{RANK_TITLE}<!-- IF RANK_TITLE and RANK_IMG --><br /><!-- ENDIF -->{RANK_IMG}</dd><!-- ENDIF -->
+ <!-- EVENT ucp_pm_viewmessage_rank_after -->
+
+ <dd class="profile-posts"><strong>{L_POSTS}{L_COLON}</strong> <!-- IF U_AUTHOR_POSTS != '' --><a href="{U_AUTHOR_POSTS}">{AUTHOR_POSTS}</a><!-- ELSE -->{AUTHOR_POSTS}<!-- ENDIF --></dd>
+ <!-- IF AUTHOR_JOINED --><dd class="profile-joined"><strong>{L_JOINED}{L_COLON}</strong> {AUTHOR_JOINED}</dd><!-- ENDIF -->
+
+ <!-- EVENT ucp_pm_viewmessage_custom_fields_before -->
+ <!-- BEGIN custom_fields -->
+ <!-- IF not custom_fields.S_PROFILE_CONTACT -->
+ <dd class="profile-custom-field profile-{custom_fields.PROFILE_FIELD_IDENT}"><strong>{custom_fields.PROFILE_FIELD_NAME}{L_COLON}</strong> {custom_fields.PROFILE_FIELD_VALUE}</dd>
+ <!-- ENDIF -->
+ <!-- END custom_fields -->
+ <!-- EVENT ucp_pm_viewmessage_custom_fields_after -->
+
+ <!-- EVENT ucp_pm_viewmessage_contact_fields_before -->
+ <!-- IF .contact -->
+ <dd class="profile-contact">
+ <strong>{L_CONTACT}{L_COLON}</strong>
+ <div class="dropdown-container dropdown-left">
+ <a href="#" class="dropdown-trigger" title="{CONTACT_USER}"><i class="icon fa-commenting-o fa-fw icon-lg" aria-hidden="true"></i><span class="sr-only">{CONTACT_USER}</span></a>
+ <div class="dropdown">
+ <div class="pointer"><div class="pointer-inner"></div></div>
+ <div class="dropdown-contents contact-icons">
+ <!-- BEGIN contact -->
+ {% set REMAINDER = contact.S_ROW_COUNT % 4 %}
+ <!-- DEFINE $S_LAST_CELL = ((REMAINDER eq 3) or (contact.S_LAST_ROW and contact.S_NUM_ROWS < 4)) -->
+ <!-- IF REMAINDER eq 0 -->
+ <div>
+ <!-- ENDIF -->
+ <a href="<!-- IF contact.U_CONTACT -->{contact.U_CONTACT}<!-- ELSE -->{contact.U_PROFILE_AUTHOR}<!-- ENDIF -->" title="{contact.NAME}"<!-- IF $S_LAST_CELL --> class="last-cell"<!-- ENDIF --><!-- IF contact.ID eq 'jabber' --> onclick="popup(this.href, 750, 320); return false;"<!-- ENDIF -->>
+ <span class="contact-icon {contact.ID}-icon">{contact.NAME}</span>
+ </a>
+ <!-- IF REMAINDER eq 3 or contact.S_LAST_ROW -->
+ </div>
+ <!-- ENDIF -->
+ <!-- END contact -->
+ </div>
</div>
</div>
- </div>
- </dd>
- <!-- ENDIF -->
- <!-- EVENT ucp_pm_viewmessage_contact_fields_after -->
- </dl>
-
- <div class="postbody">
- <h3 class="first">{SUBJECT}</h3>
-
- <!-- DEFINE $SHOW_PM_POST_BUTTONS = (U_EDIT or U_DELETE or U_REPORT or U_QUOTE) -->
- <!-- EVENT ucp_pm_viewmessage_post_buttons_list_before -->
- <!-- IF $SHOW_PM_POST_BUTTONS -->
- <ul class="post-buttons">
- <!-- EVENT ucp_pm_viewmessage_post_buttons_before -->
- <!-- IF U_EDIT -->
- <li>
- <a href="{U_EDIT}" title="{L_POST_EDIT_PM}" class="button button-icon-only">
- <i class="icon fa-pencil fa-fw" aria-hidden="true"></i><span class="sr-only">{L_BUTTON_EDIT}</span>
- </a>
- </li>
+ </dd>
<!-- ENDIF -->
- <!-- IF U_DELETE -->
- <li>
- <a href="{U_DELETE}" title="{L_DELETE_MESSAGE}" class="button button-icon-only">
- <i class="icon fa-times fa-fw" aria-hidden="true"></i><span class="sr-only">{L_BUTTON_DELETE}</span>
- </a>
- </li>
+ <!-- EVENT ucp_pm_viewmessage_contact_fields_after -->
+ </dl>
+
+ <div class="postbody">
+ <h3 class="first">{SUBJECT}</h3>
+
+ <!-- DEFINE $SHOW_PM_POST_BUTTONS = (U_EDIT or U_DELETE or U_REPORT or U_QUOTE) -->
+ <!-- EVENT ucp_pm_viewmessage_post_buttons_list_before -->
+ <!-- IF $SHOW_PM_POST_BUTTONS -->
+ <ul class="post-buttons">
+ <!-- EVENT ucp_pm_viewmessage_post_buttons_before -->
+ <!-- IF U_EDIT -->
+ <li>
+ <a href="{U_EDIT}" title="{L_POST_EDIT_PM}" class="button button-icon-only">
+ <i class="icon fa-pencil fa-fw" aria-hidden="true"></i><span class="sr-only">{L_BUTTON_EDIT}</span>
+ </a>
+ </li>
+ <!-- ENDIF -->
+ <!-- IF U_DELETE -->
+ <li>
+ <a href="{U_DELETE}" title="{L_DELETE_MESSAGE}" class="button button-icon-only">
+ <i class="icon fa-times fa-fw" aria-hidden="true"></i><span class="sr-only">{L_BUTTON_DELETE}</span>
+ </a>
+ </li>
+ <!-- ENDIF -->
+ <!-- IF U_REPORT -->
+ <li>
+ <a href="{U_REPORT}" title="{L_REPORT_PM}" class="button button-icon-only">
+ <i class="icon fa-exclamation fa-fw" aria-hidden="true"></i><span class="sr-only">{L_BUTTON_REPORT}</span>
+ </a>
+ </li>
+ <!-- ENDIF -->
+ <!-- IF U_QUOTE -->
+ <li>
+ <a href="{U_QUOTE}" title="{L_POST_QUOTE_PM}" class="button button-icon-only">
+ <i class="icon fa-quote-left fa-fw" aria-hidden="true"></i><span class="sr-only">{L_BUTTON_QUOTE}</span>
+ </a>
+ </li>
+ <!-- ENDIF -->
+ <!-- EVENT ucp_pm_viewmessage_post_buttons_after -->
+ </ul>
<!-- ENDIF -->
- <!-- IF U_REPORT -->
- <li>
- <a href="{U_REPORT}" title="{L_REPORT_PM}" class="button button-icon-only">
- <i class="icon fa-exclamation fa-fw" aria-hidden="true"></i><span class="sr-only">{L_BUTTON_REPORT}</span>
- </a>
- </li>
+ <!-- EVENT ucp_pm_viewmessage_post_buttons_list_after -->
+
+ <p class="author">
+ <strong>{L_SENT_AT}{L_COLON}</strong> {SENT_DATE}
+ <br /><strong>{L_PM_FROM}{L_COLON}</strong> {MESSAGE_AUTHOR_FULL}
+ <!-- IF S_TO_RECIPIENT --><br /><strong>{L_TO}{L_COLON}</strong> <!-- BEGIN to_recipient --><!-- IF to_recipient.NAME_FULL -->{to_recipient.NAME_FULL}<!-- ELSE --><a href="{to_recipient.U_VIEW}"<!-- IF to_recipient.COLOUR --> style="color:{to_recipient.COLOUR};"<!-- ENDIF -->><strong>{to_recipient.NAME}</strong></a><!-- ENDIF -->&nbsp;<!-- END to_recipient --><!-- ENDIF -->
+ <!-- IF S_BCC_RECIPIENT --><br /><strong>{L_BCC}{L_COLON}</strong> <!-- BEGIN bcc_recipient --><!-- IF bcc_recipient.NAME_FULL -->{bcc_recipient.NAME_FULL}<!-- ELSE --><a href="{bcc_recipient.U_VIEW}"<!-- IF bcc_recipient.COLOUR --> style="color:{bcc_recipient.COLOUR};"<!-- ENDIF -->><strong>{bcc_recipient.NAME}</strong></a><!-- ENDIF -->&nbsp;<!-- END bcc_recipient --><!-- ENDIF -->
+ </p>
+
+
+ <div class="content">{MESSAGE}</div>
+
+ <!-- IF S_HAS_ATTACHMENTS -->
+ <dl class="attachbox">
+ <dt>
+ {L_ATTACHMENTS}
+ </dt>
+ <!-- BEGIN attachment -->
+ <dd>{attachment.DISPLAY_ATTACHMENT}</dd>
+ <!-- END attachment -->
+ </dl>
<!-- ENDIF -->
- <!-- IF U_QUOTE -->
- <li>
- <a href="{U_QUOTE}" title="{L_POST_QUOTE_PM}" class="button button-icon-only">
- <i class="icon fa-quote-left fa-fw" aria-hidden="true"></i><span class="sr-only">{L_BUTTON_QUOTE}</span>
- </a>
- </li>
+
+ <!-- IF S_DISPLAY_NOTICE -->
+ <div class="post-notice error">{L_DOWNLOAD_NOTICE}</div>
<!-- ENDIF -->
- <!-- EVENT ucp_pm_viewmessage_post_buttons_after -->
- </ul>
- <!-- ENDIF -->
- <!-- EVENT ucp_pm_viewmessage_post_buttons_list_after -->
-
- <p class="author">
- <strong>{L_SENT_AT}{L_COLON}</strong> {SENT_DATE}
- <br /><strong>{L_PM_FROM}{L_COLON}</strong> {MESSAGE_AUTHOR_FULL}
- <!-- IF S_TO_RECIPIENT --><br /><strong>{L_TO}{L_COLON}</strong> <!-- BEGIN to_recipient --><!-- IF to_recipient.NAME_FULL -->{to_recipient.NAME_FULL}<!-- ELSE --><a href="{to_recipient.U_VIEW}"<!-- IF to_recipient.COLOUR --> style="color:{to_recipient.COLOUR};"<!-- ENDIF -->><strong>{to_recipient.NAME}</strong></a><!-- ENDIF -->&nbsp;<!-- END to_recipient --><!-- ENDIF -->
- <!-- IF S_BCC_RECIPIENT --><br /><strong>{L_BCC}{L_COLON}</strong> <!-- BEGIN bcc_recipient --><!-- IF bcc_recipient.NAME_FULL -->{bcc_recipient.NAME_FULL}<!-- ELSE --><a href="{bcc_recipient.U_VIEW}"<!-- IF bcc_recipient.COLOUR --> style="color:{bcc_recipient.COLOUR};"<!-- ENDIF -->><strong>{bcc_recipient.NAME}</strong></a><!-- ENDIF -->&nbsp;<!-- END bcc_recipient --><!-- ENDIF -->
- </p>
-
-
- <div class="content">{MESSAGE}</div>
-
- <!-- IF S_HAS_ATTACHMENTS -->
- <dl class="attachbox">
- <dt>
- {L_ATTACHMENTS}
- </dt>
- <!-- BEGIN attachment -->
- <dd>{attachment.DISPLAY_ATTACHMENT}</dd>
- <!-- END attachment -->
- </dl>
- <!-- ENDIF -->
- <!-- IF S_DISPLAY_NOTICE -->
- <div class="post-notice error">{L_DOWNLOAD_NOTICE}</div>
- <!-- ENDIF -->
+ <!-- IF EDITED_MESSAGE or EDIT_REASON -->
+ <div class="notice">{EDITED_MESSAGE}
+ <!-- IF EDIT_REASON --><br /><strong>{L_REASON}{L_COLON}</strong> <em>{EDIT_REASON}</em><!-- ENDIF -->
+ </div>
+ <!-- ENDIF -->
- <!-- IF EDITED_MESSAGE or EDIT_REASON -->
- <div class="notice">{EDITED_MESSAGE}
- <!-- IF EDIT_REASON --><br /><strong>{L_REASON}{L_COLON}</strong> <em>{EDIT_REASON}</em><!-- ENDIF -->
+ <!-- IF SIGNATURE -->
+ <div id="sig{MESSAGE_ID}" class="signature">{SIGNATURE}</div>
+ <!-- ENDIF -->
</div>
- <!-- ENDIF -->
- <!-- IF SIGNATURE -->
- <div id="sig{MESSAGE_ID}" class="signature">{SIGNATURE}</div>
- <!-- ENDIF -->
- </div>
-
- <div class="back2top">
- <a href="#top" class="top" title="{L_BACK_TO_TOP}">
- <i class="icon fa-chevron-circle-up fa-fw icon-gray" aria-hidden="true"></i>
- <span class="sr-only">{L_BACK_TO_TOP}</span>
- </a>
- </div>
+ <div class="back2top">
+ <a href="#top" class="top" title="{L_BACK_TO_TOP}">
+ <i class="icon fa-chevron-circle-up fa-fw icon-gray" aria-hidden="true"></i>
+ <span class="sr-only">{L_BACK_TO_TOP}</span>
+ </a>
+ </div>
</div>
</div>
@@ -171,7 +171,7 @@
<!-- IF S_VIEW_MESSAGE -->
<fieldset class="display-options">
- <!-- IF S_MARK_OPTIONS --><label for="mark_option"><select name="mark_option" id="mark_option">{S_MARK_OPTIONS}</select></label>&nbsp;<input class="button2" type="submit" name="submit_mark" value="{L_GO}" /><!-- ENDIF -->
+ <!-- IF S_MARK_OPTIONS --><label for="mark_option"><select name="mark_option" id="mark_option">{S_MARK_OPTIONS}</select></label>&nbsp;<input class="button1 button button-form-bold" type="submit" name="submit_mark" value="{L_GO}" /><!-- ENDIF -->
<!-- IF U_PREVIOUS_PM -->
<a href="{U_PREVIOUS_PM}" class="left-box arrow-{S_CONTENT_FLOW_BEGIN}">
<i class="icon fa-angle-{S_CONTENT_FLOW_BEGIN} fa-fw icon-black" aria-hidden="true"></i><span>{L_VIEW_PREVIOUS_PM}</span>
@@ -182,7 +182,7 @@
<i class="icon fa-angle-{S_CONTENT_FLOW_END} fa-fw icon-black" aria-hidden="true"></i><span>{L_VIEW_NEXT_PM}</span>
</a>
<!-- ENDIF -->
- <!-- IF not S_UNREAD and not S_SPECIAL_FOLDER --><label for="dest_folder"><!-- IF S_VIEW_MESSAGE -->{L_MOVE_TO_FOLDER}{L_COLON} <!-- ELSE -->{L_MOVE_MARKED_TO_FOLDER}<!-- ENDIF --> <select name="dest_folder" id="dest_folder">{S_TO_FOLDER_OPTIONS}</select></label> <input class="button2" type="submit" name="move_pm" value="{L_GO}" /><!-- ENDIF -->
+ <!-- IF not S_UNREAD and not S_SPECIAL_FOLDER --><label for="dest_folder"><!-- IF S_VIEW_MESSAGE -->{L_MOVE_TO_FOLDER}{L_COLON} <!-- ELSE -->{L_MOVE_MARKED_TO_FOLDER}<!-- ENDIF --> <select name="dest_folder" id="dest_folder">{S_TO_FOLDER_OPTIONS}</select></label> <input class="button1 button button-form-bold" type="submit" name="move_pm" value="{L_GO}" /><!-- ENDIF -->
<input type="hidden" name="marked_msg_id[]" value="{MSG_ID}" />
<input type="hidden" name="cur_folder_id" value="{CUR_FOLDER_ID}" />
<input type="hidden" name="p" value="{MSG_ID}" />
diff --git a/phpBB/styles/prosilver/template/ucp_prefs_personal.html b/phpBB/styles/prosilver/template/ucp_prefs_personal.html
index 1650705d4b..5aa200b8aa 100644
--- a/phpBB/styles/prosilver/template/ucp_prefs_personal.html
+++ b/phpBB/styles/prosilver/template/ucp_prefs_personal.html
@@ -79,8 +79,8 @@
</div>
<fieldset class="submit-buttons">
- {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="submit" value="{L_SUBMIT}" class="button1" />
+ {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="submit" value="{L_SUBMIT}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
</form>
diff --git a/phpBB/styles/prosilver/template/ucp_prefs_post.html b/phpBB/styles/prosilver/template/ucp_prefs_post.html
index 169d41bf72..97a5da0a85 100644
--- a/phpBB/styles/prosilver/template/ucp_prefs_post.html
+++ b/phpBB/styles/prosilver/template/ucp_prefs_post.html
@@ -44,8 +44,8 @@
</div>
<fieldset class="submit-buttons">
- {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="submit" value="{L_SUBMIT}" class="button1" />
+ {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="submit" value="{L_SUBMIT}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
</form>
diff --git a/phpBB/styles/prosilver/template/ucp_prefs_view.html b/phpBB/styles/prosilver/template/ucp_prefs_view.html
index 4b7142fbea..e28679aa96 100644
--- a/phpBB/styles/prosilver/template/ucp_prefs_view.html
+++ b/phpBB/styles/prosilver/template/ucp_prefs_view.html
@@ -89,8 +89,8 @@
</div>
<fieldset class="submit-buttons">
- {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="submit" value="{L_SUBMIT}" class="button1" />
+ {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="submit" value="{L_SUBMIT}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
</form>
diff --git a/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html b/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html
index 65909b7068..3f63c5b3c0 100644
--- a/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html
+++ b/phpBB/styles/prosilver/template/ucp_profile_autologin_keys.html
@@ -34,7 +34,7 @@
<!-- IF .sessions -->
<fieldset class="display-actions">
- {S_HIDDEN_FIELDS}<input type="submit" name="submit" value="{L_DELETE_MARKED}" class="button2" />
+ {S_HIDDEN_FIELDS}<input type="submit" name="submit" value="{L_DELETE_MARKED}" class="button1 button button-form-bold" />
<div><a href="#" onclick="$('#ucp input:checkbox').prop('checked', true); return false;">{L_MARK_ALL}</a> &bull; <a href="#" onclick="$('#ucp input:checkbox').prop('checked', false); return false;">{L_UNMARK_ALL}</a></div>
{S_FORM_TOKEN}
</fieldset>
diff --git a/phpBB/styles/prosilver/template/ucp_profile_profile_info.html b/phpBB/styles/prosilver/template/ucp_profile_profile_info.html
index ac0cd153c2..97856d5a86 100644
--- a/phpBB/styles/prosilver/template/ucp_profile_profile_info.html
+++ b/phpBB/styles/prosilver/template/ucp_profile_profile_info.html
@@ -42,8 +42,8 @@
</div>
<fieldset class="submit-buttons">
- {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="submit" value="{L_SUBMIT}" class="button1" />
+ {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="submit" value="{L_SUBMIT}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
</form>
diff --git a/phpBB/styles/prosilver/template/ucp_profile_reg_details.html b/phpBB/styles/prosilver/template/ucp_profile_reg_details.html
index f62d3cf37d..8d7c6728a7 100644
--- a/phpBB/styles/prosilver/template/ucp_profile_reg_details.html
+++ b/phpBB/styles/prosilver/template/ucp_profile_reg_details.html
@@ -50,8 +50,8 @@
</div>
<fieldset class="submit-buttons">
- {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="submit" value="{L_SUBMIT}" class="button1" />
+ {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="submit" value="{L_SUBMIT}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
</form>
diff --git a/phpBB/styles/prosilver/template/ucp_profile_signature.html b/phpBB/styles/prosilver/template/ucp_profile_signature.html
index ed28b7ab02..4e97157468 100644
--- a/phpBB/styles/prosilver/template/ucp_profile_signature.html
+++ b/phpBB/styles/prosilver/template/ucp_profile_signature.html
@@ -42,9 +42,9 @@
<fieldset class="submit-buttons">
{S_HIDDEN_FIELDS}
- <input type="reset" name="reset" value="{L_RESET}" class="button2" />&nbsp;
- <input type="submit" name="preview" value="{L_PREVIEW}" class="button2" />&nbsp;
- <input type="submit" name="submit" value="{L_SUBMIT}" class="button1" />
+ <input type="reset" name="reset" value="{L_RESET}" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="preview" value="{L_PREVIEW}" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="submit" value="{L_SUBMIT}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
</form>
diff --git a/phpBB/styles/prosilver/template/ucp_register.html b/phpBB/styles/prosilver/template/ucp_register.html
index f44382f500..dff4308869 100644
--- a/phpBB/styles/prosilver/template/ucp_register.html
+++ b/phpBB/styles/prosilver/template/ucp_register.html
@@ -105,8 +105,8 @@
<fieldset class="submit-buttons">
{S_HIDDEN_FIELDS}
- <input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" tabindex="9" name="submit" id="submit" value="{L_SUBMIT}" class="button1 default-submit-action" />
+ <input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" tabindex="9" name="submit" id="submit" value="{L_SUBMIT}" class="button1 button button-form default-submit-action" />
{S_FORM_TOKEN}
</fieldset>
diff --git a/phpBB/styles/prosilver/template/ucp_resend.html b/phpBB/styles/prosilver/template/ucp_resend.html
index 7713efe521..48827d811b 100644
--- a/phpBB/styles/prosilver/template/ucp_resend.html
+++ b/phpBB/styles/prosilver/template/ucp_resend.html
@@ -20,7 +20,7 @@
</dl>
<dl>
<dt>&nbsp;</dt>
- <dd>{S_HIDDEN_FIELDS}{S_FORM_TOKEN}<input type="submit" name="submit" id="submit" class="button1" value="{L_SUBMIT}" tabindex="2" />&nbsp; <input type="reset" value="{L_RESET}" name="reset" class="button2" /></dd>
+ <dd>{S_HIDDEN_FIELDS}{S_FORM_TOKEN}<input type="submit" name="submit" id="submit" class="button1 button button-form" value="{L_SUBMIT}" tabindex="2" />&nbsp; <input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" /></dd>
</dl>
</fieldset>
</div>
diff --git a/phpBB/styles/prosilver/template/ucp_zebra_foes.html b/phpBB/styles/prosilver/template/ucp_zebra_foes.html
index 2a0f6e0dea..efd7a0613d 100644
--- a/phpBB/styles/prosilver/template/ucp_zebra_foes.html
+++ b/phpBB/styles/prosilver/template/ucp_zebra_foes.html
@@ -32,8 +32,8 @@
</div>
<fieldset class="submit-buttons">
- {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="submit" value="{L_SUBMIT}" class="button1" />
+ {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="submit" value="{L_SUBMIT}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
</form>
diff --git a/phpBB/styles/prosilver/template/ucp_zebra_friends.html b/phpBB/styles/prosilver/template/ucp_zebra_friends.html
index e584d876b8..1478fb9546 100644
--- a/phpBB/styles/prosilver/template/ucp_zebra_friends.html
+++ b/phpBB/styles/prosilver/template/ucp_zebra_friends.html
@@ -34,8 +34,8 @@
</div>
<fieldset class="submit-buttons">
- {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button2" />&nbsp;
- <input type="submit" name="submit" value="{L_SUBMIT}" class="button1" />
+ {S_HIDDEN_FIELDS}<input type="reset" value="{L_RESET}" name="reset" class="button1 button button-form-bold" />&nbsp;
+ <input type="submit" name="submit" value="{L_SUBMIT}" class="button1 button button-form" />
{S_FORM_TOKEN}
</fieldset>
</form>
diff --git a/phpBB/styles/prosilver/template/viewforum_body.html b/phpBB/styles/prosilver/template/viewforum_body.html
index 40beb784d7..a484240c0e 100644
--- a/phpBB/styles/prosilver/template/viewforum_body.html
+++ b/phpBB/styles/prosilver/template/viewforum_body.html
@@ -111,7 +111,7 @@
</dl>
<dl>
<dt>&nbsp;</dt>
- <dd><input type="submit" name="login" tabindex="5" value="{L_LOGIN}" class="button1" /></dd>
+ <dd><input type="submit" name="login" tabindex="5" value="{L_LOGIN}" class="button1 button button-form" /></dd>
</dl>
{S_LOGIN_REDIRECT}
{S_FORM_TOKEN_LOGIN}
diff --git a/phpBB/styles/prosilver/template/viewtopic_body.html b/phpBB/styles/prosilver/template/viewtopic_body.html
index 6af33f2f87..eced46b23f 100644
--- a/phpBB/styles/prosilver/template/viewtopic_body.html
+++ b/phpBB/styles/prosilver/template/viewtopic_body.html
@@ -106,7 +106,7 @@
<!-- IF S_CAN_VOTE -->
<dl style="border-top: none;" class="poll_vote">
<dt>&nbsp;</dt>
- <dd class="resultbar"><input type="submit" name="update" value="{L_SUBMIT_VOTE}" class="button1" /></dd>
+ <dd class="resultbar"><input type="submit" name="update" value="{L_SUBMIT_VOTE}" class="button1 button button-form" /></dd>
</dl>
<!-- ENDIF -->
@@ -136,7 +136,7 @@
<!-- IF postrow.S_FIRST_UNREAD -->
<a id="unread" class="anchor"<!-- IF S_UNREAD_VIEW --> data-url="{postrow.U_MINI_POST}"<!-- ENDIF -->></a>
<!-- ENDIF -->
- <div id="p{postrow.POST_ID}" class="post has-profile <!-- IF postrow.S_ROW_COUNT is odd -->bg1<!-- ELSE -->bg2<!-- ENDIF --><!-- IF postrow.S_UNREAD_POST --> unreadpost<!-- ENDIF --><!-- IF postrow.S_POST_REPORTED --> reported<!-- ENDIF --><!-- IF postrow.S_POST_DELETED --> deleted<!-- ENDIF --><!-- IF postrow.S_ONLINE and not postrow.S_POST_HIDDEN --> online<!-- ENDIF --><!-- IF postrow.POSTER_WARNINGS --> warned<!-- ENDIF -->">
+ <div id="p{postrow.POST_ID}" class="post has-profile <!-- IF postrow.S_ROW_COUNT is odd -->bg1<!-- ELSE -->bg2<!-- ENDIF --><!-- IF postrow.S_UNREAD_POST --> unreadpost<!-- ENDIF --><!-- IF postrow.S_POST_REPORTED --> reported<!-- ENDIF --><!-- IF postrow.S_POST_DELETED --> deleted<!-- ENDIF --><!-- IF postrow.POSTER_WARNINGS --> warned<!-- ENDIF -->">
<div class="inner">
<dl class="postprofile" id="profile{postrow.POST_ID}"<!-- IF postrow.S_POST_HIDDEN --> style="display: none;"<!-- ENDIF -->>
@@ -149,7 +149,7 @@
<!-- EVENT viewtopic_body_avatar_after -->
</div>
<!-- EVENT viewtopic_body_post_author_before -->
- <!-- IF not postrow.U_POST_AUTHOR --><strong>{postrow.POST_AUTHOR_FULL}</strong><!-- ELSE -->{postrow.POST_AUTHOR_FULL}<!-- ENDIF -->
+ <!-- IF not postrow.U_POST_AUTHOR --><strong>{postrow.POST_AUTHOR_FULL}</strong><!-- ELSE -->{postrow.POST_AUTHOR_FULL}<!-- ENDIF --><!-- IF postrow.S_ONLINE and not postrow.S_POST_HIDDEN --> <i class="icon fa-circle fa-fw icon-md online" aria-hidden="true" title="{L_ONLINE}"></i><span class="sr-only">{L_ONLINE}</span><!-- ENDIF -->
<!-- EVENT viewtopic_body_post_author_after -->
</dt>
@@ -299,8 +299,8 @@
<p class="post-notice unapproved">
<span><i class="icon fa-question icon-red fa-fw" aria-hidden="true"></i></span>
<strong>{L_POST_UNAPPROVED_ACTION}</strong>
- <input class="button2" type="submit" value="{L_DISAPPROVE}" name="action[disapprove]" />
- <input class="button1" type="submit" value="{L_APPROVE}" name="action[approve]" />
+ <input class="button1 button button-form-bold" type="submit" value="{L_DISAPPROVE}" name="action[disapprove]" />
+ <input class="button1 button button-form" type="submit" value="{L_APPROVE}" name="action[approve]" />
<input type="hidden" name="post_id_list[]" value="{postrow.POST_ID}" />
{S_FORM_TOKEN}
</p>
@@ -316,9 +316,9 @@
<p class="post-notice deleted">
<strong>{L_POST_DELETED_ACTION}</strong>
<!-- IF postrow.S_DELETE_PERMANENT -->
- <input class="button2" type="submit" value="{L_DELETE}" name="action[delete]" />
+ <input class="button1 button button-form-bold" type="submit" value="{L_DELETE}" name="action[delete]" />
<!-- ENDIF -->
- <input class="button1" type="submit" value="{L_RESTORE}" name="action[restore]" />
+ <input class="button1 button button-form" type="submit" value="{L_RESTORE}" name="action[restore]" />
<input type="hidden" name="post_id_list[]" value="{postrow.POST_ID}" />
{S_FORM_TOKEN}
</p>
diff --git a/phpBB/styles/prosilver/theme/base.css b/phpBB/styles/prosilver/theme/base.css
index 98c57d9264..f4daeee1e5 100644
--- a/phpBB/styles/prosilver/theme/base.css
+++ b/phpBB/styles/prosilver/theme/base.css
@@ -1,6 +1,6 @@
-/* --------------------------------------------------------------
+/* -------------------------------------------------------------- /*
$Base
--------------------------------------------------------------- */
+/* -------------------------------------------------------------- */
/** {
-webkit-box-sizing: border-box;
@@ -12,19 +12,25 @@
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-}*/
+}
+*/
-/* Define your base font-size here; most elements will inherit this. _NO__DOTCOMMA__AFTER__*/
+/*
+ * 1. Define your base font-size here (16px), most elements will inherit this.
+ * 2. 24px (This is now our magic number; all subsequent margin-bottoms and
+ * line-heights want to be a multiple of this number in order to maintain
+ * vertical rhythm.)
+*/
html {
- font-size: 1em; /* Assuming 16px... */
- line-height: 1.5; /* 24px (This is now our magic number; all subsequent margin-bottoms and line-heights want to be a multiple of this number in order to maintain vertical rhythm.) _NO__DOTCOMMA__AFTER__*/
+ font-size: 16px; /* [1] */
+ line-height: 1.5; /* [2] */
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
}
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
- color: #333333;
background-color: #ffffff;
+ color: #333333;
}
input,
@@ -36,26 +42,31 @@ textarea {
line-height: inherit;
}
-figure { margin: 0 }
-img { vertical-align: middle }
+figure {
+ margin: 0;
+}
+
+img {
+ vertical-align: middle;
+}
hr {
- margin-top: 20px;
- margin-bottom: 20px;
border: 0;
border-top: 1px solid #e5e5e5;
+ margin-top: 20px;
+ margin-bottom: 20px;
}
a {
- color: #428bca;
text-decoration: none;
+ color: #428bca;
}
a:hover,
a:focus,
a:active {
- color: #2a6496;
text-decoration: underline;
+ color: #2a6496;
}
blockquote,
@@ -69,7 +80,10 @@ h5,
h6,
figure,
p,
-pre { margin: 0 }
+pre {
+ margin: 0;
+}
+
button {
background: transparent;
border: 0;
@@ -81,8 +95,7 @@ button {
* results in a loss of the default `button` focus styles.
*/
button:focus {
- outline: 1px dotted;
- outline: 5px auto -webkit-focus-ring-color;
+ outline: 1px dotted 5px auto -webkit-focus-ring-color;
}
fieldset {
@@ -91,12 +104,15 @@ fieldset {
padding: 0;
}
-iframe { border: 0 }
+iframe {
+ border: 0;
+}
+
ol,
ul {
- list-style: none;
margin: 0;
padding: 0;
+ list-style: none;
}
/**
@@ -104,7 +120,9 @@ ul {
* This prevents an unwanted focus outline from appearing around elements that
* might still respond to pointer events.
*/
-[tabindex="-1"]:focus { outline: none !important }
+[tabindex="-1"]:focus {
+ outline: none !important;
+}
/**
* Remove double underline from recent version of firefox
@@ -112,4 +130,3 @@ ul {
abbr[title] {
text-decoration: none;
}
-
diff --git a/phpBB/styles/prosilver/theme/bidi.css b/phpBB/styles/prosilver/theme/bidi.css
index 79b769b1e7..bcf271b0c8 100644
--- a/phpBB/styles/prosilver/theme/bidi.css
+++ b/phpBB/styles/prosilver/theme/bidi.css
@@ -1,5 +1,8 @@
-/* RTL definitions
----------------------------------------- */
+/* -------------------------------------------------------------- /*
+ $Bidi
+/* -------------------------------------------------------------- */
+/* stylelint-disable selector-max-compound-selectors */
+/* stylelint-disable selector-no-qualifying-type */
/**
* common.css
@@ -18,8 +21,8 @@
}
.rtl div.rules ul {
- margin-left: 0;
margin-right: 20px;
+ margin-left: 0;
}
/* Main blocks
@@ -51,48 +54,52 @@
}
/* Horizontal lists
-----------------------------------------*/
+---------------------------------------- */
.rtl ul.linklist > li {
float: right;
margin-right: 0;
margin-left: 7px;
}
-.rtl ul.linklist > li.rightside, .rtl p.rightside, .rtl a.rightside {
+.rtl ul.linklist > li.rightside,
+.rtl p.rightside,
+.rtl a.rightside {
+ text-align: left;
float: left;
margin-right: 7px;
margin-left: 0;
- text-align: left;
}
-.rtl ul.leftside > li, .rtl ul.rightside > li {
+.rtl ul.leftside > li,
+.rtl ul.rightside > li {
float: left;
}
.rtl ul.leftside {
+ text-align: right;
float: right;
- margin-left: 5px;
margin-right: 0;
- text-align: right;
+ margin-left: 5px;
}
.rtl ul.rightside {
+ text-align: left;
float: left;
- margin-left: -5px;
margin-right: 5px;
- text-align: left;
+ margin-left: -5px;
}
/* Bulletin icons for list items
-----------------------------------------*/
+---------------------------------------- */
.rtl ul.linklist.bulletin > li:before {
- padding-left: 4px;
padding-right: 0;
+ padding-left: 4px;
}
/* Dropdown menu
---------------------------------------- */
-.rtl .dropdown-container.topic-tools, .rtl .dropdown-container-left {
+.rtl .dropdown-container.topic-tools,
+.rtl .dropdown-container-left {
float: right;
}
@@ -101,8 +108,8 @@
}
.rtl .dropdown-contents > li {
- padding-left: 15px;
padding-right: 0;
+ padding-left: 15px;
}
.rtl .dropdown-nonscroll > li {
@@ -110,15 +117,16 @@
}
.rtl .dropdown li li {
- padding-left: 0;
padding-right: 18px;
+ padding-left: 0;
}
.rtl .dropdown-extended .header {
text-align: right;
}
-.rtl .dropdown-extended .header .header_settings, .rtl .dropdown-container-right {
+.rtl .dropdown-extended .header .header-settings,
+.rtl .dropdown-container-right {
float: left;
}
@@ -128,42 +136,42 @@
}
/* Notifications
------------------------------------------*/
-.rtl .notification_list ul li img {
+----------------------------------------- */
+.rtl .notification-avatar {
float: right;
- margin-left: 5px;
margin-right: 0;
+ margin-left: 5px;
}
-.rtl .notification_list div.notifications {
- margin-left: 0;
+.rtl .notification-menu .notifications {
margin-right: 50px;
+ margin-left: 0;
}
-.rtl .notification_text {
- margin-left: 0;
+.rtl .notification-text {
margin-right: 58px;
+ margin-left: 0;
}
-.rtl .notification_list p.notification-time {
+.rtl .notification-time {
text-align: left;
}
/* Responsive breadcrumbs
-----------------------------------------*/
+---------------------------------------- */
.rtl .breadcrumbs .crumb {
float: right;
}
/* Table styles
-----------------------------------------*/
+---------------------------------------- */
.rtl table.table1 thead th {
padding: 0 3px 4px 0;
}
.rtl table.table1 thead th span {
- padding-left: 0;
padding-right: 7px;
+ padding-left: 0;
}
.rtl table.table1 tbody th {
@@ -171,11 +179,27 @@
}
/* Specific column styles */
-.rtl table.table1 .name { text-align: right; }
-.rtl table.table1 .joined { text-align: right; }
-.rtl table.table1 .active { text-align: right; }
-.rtl table.table1 .info { text-align: right; }
-.rtl table.table1 thead .autocol { padding-left: 0; padding-right: 1em; }
+.rtl table.table1 .name {
+ text-align: right;
+}
+
+.rtl table.table1 .joined {
+ text-align: right;
+}
+
+.rtl table.table1 .active {
+ text-align: right;
+}
+
+.rtl table.table1 .info {
+ text-align: right;
+}
+
+/* Not used anywhere maybe deprecated? */
+.rtl table.table1 thead .autocol {
+ padding-right: 10px;
+ padding-left: 0;
+}
.rtl table.table1 span.rank-img {
float: left;
@@ -191,6 +215,7 @@
/* Misc layout styles
---------------------------------------- */
+
/* column[1-2] styles are containers for two column layouts */
.rtl .column1 {
float: right;
@@ -204,37 +229,27 @@
/* General classes for placing floating blocks */
.rtl .left-box {
- float: right;
text-align: right;
+ float: right;
}
.rtl .right-box {
- float: left;
text-align: left;
+ float: left;
}
.rtl dl.details dt {
+ text-align: left;
float: right;
clear: right;
- text-align: left;
}
.rtl dl.details dd {
+ float: right;
margin-right: 0;
margin-left: 0;
padding-right: 5px;
padding-left: 0;
- float: right;
-}
-
-*:first-child+html dl.details dd {
- margin-right: 30%;
- float: none;
-}
-
-* html dl.details dd {
- margin-right: 30%;
- float: none;
}
/* Pagination
@@ -249,16 +264,16 @@
}
.rtl .pagination > ul {
- margin-left: 0;
margin-right: 5px;
+ margin-left: 0;
}
/* Pagination in viewforum for multipage topics */
.rtl .row .pagination {
background-position: 100% 50%;
float: left;
- padding-left: 0;
padding-right: 15px;
+ padding-left: 0;
}
.rtl .row .pagination > ul {
@@ -269,21 +284,26 @@
direction: ltr;
}
-.pagination li.page-jump {
- margin-left: 5px;
+.rtl .pagination li.page-jump {
margin-right: 0;
+ margin-left: 5px;
+}
+
+.rtl .topic-poster {
+ float: right;
+ padding-left: 6px;
}
/* Action Bar styles
---------------------------------------- */
.rtl .action-bar .button {
- margin-right: 0;
float: right;
+ margin-right: 0;
}
.rtl .action-bar > .button {
- margin-left: 5px;
float: right;
+ margin-left: 5px;
}
.rtl .action-bar .dropdown-button-control .button {
@@ -294,14 +314,14 @@
/* Miscellaneous styles
---------------------------------------- */
.rtl .quick-links {
- margin-left: 7px;
margin-right: 0;
+ margin-left: 7px;
}
.rtl .header-avatar span:after {
float: left;
- padding-left: 0;
padding-right: 2px;
+ padding-left: 0;
}
.rtl .member-search {
@@ -318,15 +338,15 @@
unicode-bidi: embed;
}
-li.breadcrumbs span:first-child > a {
+.rtl li.breadcrumbs span:first-child > a {
padding-left: 0;
}
/* Notification mark read link */
.rtl .dropdown-extended a.mark_read {
border-radius: 0 3px 3px 0;
- left: 0;
right: auto;
+ left: 0;
}
.rtl .back2top .top {
@@ -335,9 +355,10 @@ li.breadcrumbs span:first-child > a {
}
.rtl .skiplink {
+ right: -999px;
+
/* invisible skip link, used for accessibility */
left: 0;
- right: -999px;
}
.rtl a.feed-icon-forum {
@@ -347,7 +368,8 @@ li.breadcrumbs span:first-child > a {
/**
* content.css
*/
-.rtl ul.topiclist dt, .rtl li.header dt {
+.rtl ul.topiclist dt,
+.rtl li.header dt {
float: right;
margin-right: 0;
margin-left: -440px;
@@ -389,21 +411,21 @@ li.breadcrumbs span:first-child > a {
}
.rtl ul.topiclist dd {
- float: right;
border-right-width: 1px;
border-right-style: solid;
border-left: none;
+ float: right;
}
.rtl ul.topiclist dfn {
- left: auto;
right: -999px;
+ left: auto;
}
.rtl ul.topiclist li.row dt a.subforum {
- padding-right: 12px;
background-position: right;
position: static;
+ padding-right: 12px;
}
.rtl .forum-image {
@@ -412,16 +434,17 @@ li.breadcrumbs span:first-child > a {
margin-left: 5px;
}
-.rtl li.header dt, .rtl li.header dd {
+.rtl li.header dt,
+.rtl li.header dd {
border-right-width: 0;
}
.rtl li.header dd {
- padding-left: 0;
padding-right: 1px;
+ padding-left: 0;
}
-.rtl dl.row-item{
+.rtl dl.row-item {
background-position: 99.5% 50%;
}
@@ -432,34 +455,39 @@ li.breadcrumbs span:first-child > a {
}
.rtl dl.row-item dt {
- background-position: 99.5% 95%; /* Position of topic icon */
+ background-position: 99.5% 95%; /* Position of topic icon */
}
.rtl dl.row-item dt .list-inner {
+ padding-right: 45px; /* Space for folder icon */
padding-left: 5px;
- padding-right: 45px; /* Space for folder icon */
}
-.rtl dl a.row-item-link { /* topic row icon links */
- display: inline-block;
- left: auto;
+.rtl dl a.row-item-link { /* topic row icon links */
right: 0;
- margin-left: 0;
+ left: auto;
+ display: inline-block;
margin-right: 2px;
+ margin-left: 0;
}
-.rtl dd.lastpost > span, .rtl ul.topiclist dd.info > span, .rtl ul.topiclist dd.time > span, .rtl dd.redirect > span, .rtl dd.moderation > span {
- padding-left: 0;
+.rtl dd.lastpost > span,
+.rtl ul.topiclist dd.info > span,
+.rtl ul.topiclist dd.time > span,
+.rtl dd.redirect > span,
+.rtl dd.moderation > span {
padding-right: 5px;
+ padding-left: 0;
}
/* Post body styles
-----------------------------------------*/
+---------------------------------------- */
.rtl .date {
float: left;
}
-.rtl .postbody, .rtl .postbody h3 {
+.rtl .postbody,
+.rtl .postbody h3 {
float: right;
}
@@ -473,21 +501,22 @@ li.breadcrumbs span:first-child > a {
}
.rtl p.post-notice:before {
- left: auto;
right: 0;
+ left: auto;
}
/* Topic review panel
-----------------------------------------*/
+---------------------------------------- */
.rtl .topicreview {
padding-right: 0;
padding-left: 5px;
}
/* Content container styles
-----------------------------------------*/
-.rtl .content ul, .rtl .content ol {
- margin-right: 3em;
+---------------------------------------- */
+.rtl .content ul,
+.rtl .content ol {
+ margin-right: 40px;
margin-left: 0;
}
@@ -505,23 +534,25 @@ li.breadcrumbs span:first-child > a {
}
/* BB Code styles
-----------------------------------------*/
+---------------------------------------- */
+
/* Quote block */
.rtl blockquote {
- margin: 0.5em 25px 0 1px;
+ margin: 5px 25px 0 1px;
}
+/* Nested quotes */
.rtl blockquote blockquote {
- /* Nested quotes */
- margin: 0.5em 15px 0 1px;
+ margin: 5px 15px 0 1px;
}
+/* Username/source of quoter */
.rtl blockquote cite {
- /* Username/source of quoter */
margin-left: 0;
}
-.rtl blockquote cite:before, .rtl .uncited:before {
+.rtl blockquote cite:before,
+.rtl .uncited:before {
padding-left: 5px;
}
@@ -534,11 +565,11 @@ li.breadcrumbs span:first-child > a {
}
/* Attachments
-----------------------------------------*/
+---------------------------------------- */
.rtl .attachbox {
float: right;
- margin: 5px 0 5px 5px;
clear: right;
+ margin: 5px 0 5px 5px;
}
.rtl .attachbox dd {
@@ -554,16 +585,16 @@ li.breadcrumbs span:first-child > a {
}
/* Post poll styles
-----------------------------------------*/
+---------------------------------------- */
.rtl fieldset.polls dt {
text-align: right;
- float: right;
border-left: none;
+ float: right;
}
.rtl fieldset.polls dd {
- float: right;
border-right: none;
+ float: right;
margin-right: 0;
}
@@ -571,18 +602,23 @@ li.breadcrumbs span:first-child > a {
text-align: left;
}
-.rtl .pollbar1, .rtl .pollbar2, .rtl .pollbar3, .rtl .pollbar4, .rtl .pollbar5 {
+.rtl .pollbar1,
+.rtl .pollbar2,
+.rtl .pollbar3,
+.rtl .pollbar4,
+.rtl .pollbar5 {
+ border-right: none;
border-left-width: 1px;
border-left-style: solid;
- border-right: none;
}
/* Poster profile block
-----------------------------------------*/
+---------------------------------------- */
.rtl .postprofile {
border-width: 0 1px 0 0;
float: left;
-/* text-align: right; */
+
+ /* text-align: right; */
}
.rtl .pm .postprofile {
@@ -591,19 +627,16 @@ li.breadcrumbs span:first-child > a {
border-left: none;
}
-.rtl .postprofile dd, .rtl .postprofile dt {
- margin-left: 0;
+.rtl .postprofile dd,
+.rtl .postprofile dt {
margin-right: 8px;
+ margin-left: 0;
}
.rtl .postprofile .avatar {
float: right;
}
-.rtl .online {
- background-position: 0 0;
-}
-
.rtl dl.pmlist dd {
margin-right: 61% !important;
margin-left: 0 !important;
@@ -627,8 +660,8 @@ li.breadcrumbs span:first-child > a {
}
.rtl .has-profile .post-buttons {
- left: 0;
right: auto;
+ left: 0;
}
.rtl .post-buttons li {
@@ -636,11 +669,11 @@ li.breadcrumbs span:first-child > a {
}
/* Poster contact icons
- ----------------------------------------*/
+ ---------------------------------------- */
.rtl .contact-icons a {
+ border-right: none;
border-left-width: 1px;
border-left-style: dotted;
- border-right: none;
float: right;
}
@@ -651,12 +684,13 @@ li.breadcrumbs span:first-child > a {
/**
* cp.css
*/
+
/* Control Panel Styles
---------------------------------------- */
/* Main CP box
-----------------------------------------*/
+---------------------------------------- */
.rtl .cp-menu {
float: right;
}
@@ -666,7 +700,7 @@ li.breadcrumbs span:first-child > a {
}
.rtl .cp-main .panel ol {
- margin-right: 2em;
+ margin-right: 22px;
margin-left: 0;
}
@@ -675,15 +709,15 @@ li.breadcrumbs span:first-child > a {
margin-left: 0;
}
-.tabs-container h2 {
+.rtl .tabs-container h2 {
float: right;
}
/* CP tabbed menu
-----------------------------------------*/
+---------------------------------------- */
.rtl .tabs {
- margin-left: 0;
margin-right: 7px;
+ margin-left: 0;
}
.rtl .tabs .tab {
@@ -691,12 +725,12 @@ li.breadcrumbs span:first-child > a {
}
.rtl .tabs .tab > a {
- margin-left: 1px;
margin-right: 0;
+ margin-left: 1px;
}
/* Mini tabbed menu used in MCP
-----------------------------------------*/
+---------------------------------------- */
.rtl .minitabs {
float: left;
margin-right: 0;
@@ -713,7 +747,7 @@ li.breadcrumbs span:first-child > a {
}
/* Responsive tabs
-----------------------------------------*/
+---------------------------------------- */
.rtl .tabs .dropdown {
margin-left: -2px;
}
@@ -730,23 +764,14 @@ li.breadcrumbs span:first-child > a {
text-align: right;
}
-/* Responsive *CP navigation
-----------------------------------------*/
-@media only screen and (max-width: 900px), only screen and (max-device-width: 900px)
-{
- .rtl .cp-menu, .rtl .navigation, .rtl .cp-main {
- float: none;
- }
-}
-
/* UCP navigation menu
-----------------------------------------*/
+---------------------------------------- */
/* Preferences pane layout
-----------------------------------------*/
+---------------------------------------- */
.rtl .cp-main h2 {
- margin-left: 0;
margin-right: 10px;
+ margin-left: 0;
}
/* Friends list */
@@ -755,7 +780,7 @@ li.breadcrumbs span:first-child > a {
}
/* PM Styles
-----------------------------------------*/
+---------------------------------------- */
/* PM panel adjustments */
.rtl .reply-all a.right {
@@ -780,8 +805,8 @@ li.breadcrumbs span:first-child > a {
border-right-width: 10px;
border-right-style: solid;
border-left-width: 0;
- padding-left: 0;
padding-right: 3px;
+ padding-left: 0;
}
/* Avatar gallery */
@@ -789,25 +814,16 @@ li.breadcrumbs span:first-child > a {
float: right;
}
-/* Responsive *CP navigation
-----------------------------------------*/
-@media only screen and (max-width: 900px), only screen and (max-device-width: 900px)
-{
- .rtl .cp-menu, .rtl .navigation, .rtl .cp-main {
- float: none;
- }
-}
-
/**
* forms.css
*/
/* General form styles
-----------------------------------------*/
+---------------------------------------- */
.rtl option {
padding-right: 0;
- padding-left: 1em;
+ padding-left: 11px;
}
.rtl label {
@@ -818,26 +834,26 @@ li.breadcrumbs span:first-child > a {
/* Definition list layout for forms
---------------------------------------- */
.rtl fieldset dt {
- float: right;
text-align: right;
+ float: right;
}
.rtl fieldset dd {
- margin-left: 0;
margin-right: 41%;
+ margin-left: 0;
}
/* Specific layout 1 */
.rtl fieldset.fields1 dt {
- border-left-width: 0;
border-right-width: 1px;
+ border-left-width: 0;
}
.rtl fieldset.fields1 dd {
- margin-right: 15em;
- margin-left: 0;
border-right-width: 0;
border-left-width: 1px;
+ margin-right: 165px;
+ margin-left: 0;
}
/* Specific layout 2 */
@@ -847,10 +863,10 @@ li.breadcrumbs span:first-child > a {
}
.rtl fieldset.fields2 dd {
- margin-right: 16em;
- margin-left: 0;
- border-left-width: 1px;
border-right-width: 0;
+ border-left-width: 1px;
+ margin-right: 176px;
+ margin-left: 0;
}
/* Form elements */
@@ -858,26 +874,27 @@ li.breadcrumbs span:first-child > a {
text-align: right;
}
-.rtl dd input, .rtl dd textarea {
- margin-left: 3px;
+.rtl dd input,
+.rtl dd textarea {
margin-right: 0;
+ margin-left: 3px;
}
/* Quick-login on index page */
.rtl fieldset.quick-login input.inputbox {
- margin-left: 5px;
margin-right: 0;
+ margin-left: 5px;
}
.rtl fieldset.quick-login label {
- padding-left: 2px;
padding-right: 0;
+ padding-left: 2px;
}
/* Display options on viewtopic/viewforum pages */
.rtl fieldset.display-options label {
- padding-left: 2px;
padding-right: 0;
+ padding-left: 2px;
}
.rtl .dropdown fieldset.display-options label {
@@ -887,16 +904,16 @@ li.breadcrumbs span:first-child > a {
/* Display actions for ucp and mcp pages */
.rtl fieldset.display-actions {
text-align: left;
- padding-left: 1em;
padding-right: 0;
+ padding-left: 11px;
}
.rtl fieldset.display-actions label {
- padding-left: 2px;
padding-right: 0;
+ padding-left: 2px;
}
-/* MCP forum selection*/
+/* MCP forum selection */
.rtl fieldset.forum-selection {
float: left;
}
@@ -906,7 +923,7 @@ li.breadcrumbs span:first-child > a {
}
/* Posting page styles
-----------------------------------------*/
+---------------------------------------- */
/* Emoticons panel */
.rtl .smiley-box {
@@ -922,22 +939,22 @@ li.breadcrumbs span:first-child > a {
}
.rtl .search-box .inputbox {
- border-left-width: 0;
border-right-width: 1px;
+ border-left-width: 0;
border-radius: 0 4px 4px 0;
float: right;
padding: 3px;
}
.rtl .button-search,
-.button-search-end {
+.rtl .button-search-end {
float: right;
}
.rtl .button-search-end {
- border-radius: 4px 0 0 4px;
- border-left-width: 1px;
border-right-width: 0;
+ border-left-width: 1px;
+ border-radius: 4px 0 0 4px;
}
.rtl .search-header .button-search-end {
@@ -955,7 +972,10 @@ li.breadcrumbs span:first-child > a {
---------------------------------------- */
/** Reference: Bug #27155 */
-.rtl .wrap, .rtl .headerbar, .rtl .site-description, .rtl .navbar {
+.rtl .wrap,
+.rtl .headerbar,
+.rtl .site-description,
+.rtl .navbar {
position: relative;
}
@@ -967,124 +987,4 @@ li.breadcrumbs span:first-child > a {
float: left;
}
-/**
-* responsive.css
-*/
-@media only screen and (max-width: 700px), only screen and (max-device-width: 700px)
-{
- /* .topiclist lists
- ----------------------------------------*/
- .rtl ul.topiclist li.header dt, .rtl ul.topiclist li.header dt .list-inner {
- margin-left: 0 !important;
- padding-left: 0;
- }
-
- .rtl ul.topiclist dt, .rtl ul.topiclist dt .list-inner,
- .rtl ul.topiclist.missing-column dt, .rtl ul.topiclist.missing-column dt .list-inner,
- .rtl ul.topiclist.two-long-columns dt, .rtl ul.topiclist.two-long-columns dt .list-inner,
- .rtl ul.topiclist.two-columns dt, .rtl ul.topiclist.two-columns dt .list-inner {
- margin-left: 0;
- }
-
- .rtl ul.topiclist dt .list-inner.with-mark {
- padding-left: 34px;
- }
-
- /* Forums and topics lists
- ----------------------------------------*/
- .rtl ul.topiclist.forums dt {
- margin-left: -250px;
- }
- .rtl ul.topiclist.forums dt .list-inner {
- margin-left: 250px;
- }
-
- .rtl ul.topiclist dd.mark {
- left: 5px;
- right: auto;
- text-align: right;
- }
-
- .rtl table.responsive.show-header thead, .rtl table.responsive.show-header th:first-child {
- text-align: right !important;
- }
-
- .rtl table.responsive td {
- text-align: right !important;
- }
-
- /* User profile
- ----------------------------------------*/
- .rtl .column1, .rtl .column2, .rtl .left-box.profile-details {
- float: none;
- }
-
- /* Post
- ----------------------------------------*/
- .rtl .postprofile, .rtl .postbody, .rtl .search .postbody {
- float: none;
- }
-
- .rtl .post .postprofile {
- border-width: 0 0 1px 0;
- }
-
- .rtl .postprofile dt, .rtl .postprofile dd.profile-rank, .rtl .search .postprofile dd {
- margin: 0;
- }
-
- .rtl .postprofile .avatar {
- margin-left: 5px;
- margin-right: 0;
- }
-
- .rtl .has-profile .post-buttons {
- left: 20px;
- }
-
- /* Forms
- ----------------------------------------*/
- .rtl fieldset dt, .rtl fieldset.fields1 dt, .rtl fieldset.fields2 dt {
- float: none;
- }
-
- .rtl fieldset dd, .rtl fieldset.fields1 dd, .rtl fieldset.fields2 dd {
- margin-right: 20px;
- }
-}
-
-@media only screen and (max-width: 550px), only screen and (max-device-width: 550px)
-{
- /* .topiclist lists
- ----------------------------------------*/
- .rtl ul.topiclist.forums dt {
- margin-left: 0;
- }
-
- .rtl ul.topiclist.forums dt .list-inner {
- margin-left: 0;
- }
-}
-
-@media only screen and (max-width: 500px), only screen and (max-device-width: 500px)
-{
- .rtl dl.details dt, .rtl dl.details dd {
- float: none;
- text-align: right;
- }
-
- .rtl dl.details dd {
- margin-left: 0;
- margin-right: 20px;
- }
-
- .captcha-panel dd.captcha {
- margin-right: 0;
- }
-
- .rtl p.responsive-center {
- float: none;
- text-align: center;
- margin-bottom: 5px;
- }
-}
+/* stylelint-enable selector-no-qualifying-type */
diff --git a/phpBB/styles/prosilver/theme/buttons.css b/phpBB/styles/prosilver/theme/buttons.css
index 575c41aaef..3a22537578 100644
--- a/phpBB/styles/prosilver/theme/buttons.css
+++ b/phpBB/styles/prosilver/theme/buttons.css
@@ -1,31 +1,31 @@
-/* Button Styles
----------------------------------------- */
+/* -------------------------------------------------------------- /*
+ $Buttons
+/* -------------------------------------------------------------- */
.button {
- display: inline-block;
- padding: 2px 8px;
+ font-family: "Open Sans", "Droid Sans", Verdana, Arial, Helvetica;
font-size: 13px;
font-weight: 600;
- font-family: "Open Sans", "Droid Sans", Verdana, Arial, Helvetica;
line-height: 1.4;
text-align: center;
- white-space: nowrap;
vertical-align: middle;
- -ms-touch-action: manipulation;
- touch-action: manipulation;
- cursor: pointer;
- -webkit-user-select: none;
- -moz-user-select: none;
- -ms-user-select: none;
- user-select: none;
+ white-space: nowrap;
border: 1px solid transparent;
border-radius: 4px;
+ display: inline-block;
+ padding: 2px 8px;
+ cursor: pointer;
+ touch-action: manipulation;
+ -webkit-user-select: none;
+ -moz-user-select: none;
+ -ms-user-select: none;
+ user-select: none;
}
.button:focus,
.button:hover {
- text-decoration: none;
- outline: none;
+ text-decoration: none;
+ outline: none;
}
.caret {
@@ -39,11 +39,21 @@
}
/* Posting page styles
-----------------------------------------*/
+---------------------------------------- */
+.button-form,
+.button-form-bold {
+ font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif;
+ border-radius: 0;
+}
+
+.button-form-bold {
+ font-weight: 700;
+}
+
.button-search,
-.button-search-end {
- float: left;
+.button-search-end {
border-radius: 0;
+ float: left;
margin: 0;
padding: 2px 5px;
}
@@ -65,27 +75,28 @@
}
.button-icon-only {
- padding-left: 3px;
padding-right: 3px;
+ padding-left: 3px;
}
/* Poster contact icons
-----------------------------------------*/
+---------------------------------------- */
.contact-icons.dropdown-contents {
+ font-size: 0;
min-width: 0;
padding: 0;
- font-size: 0;
}
.contact-icon {
background-repeat: no-repeat;
display: block;
- height: 16px;
width: 16px;
+ height: 16px;
}
+
.contact-icons a {
- border-bottom: 1px dotted;
border-right: 1px dotted;
+ border-bottom: 1px dotted;
display: block;
float: left;
padding: 8px;
@@ -107,16 +118,15 @@
--------------------------------------------- */
.post-buttons {
float: right;
- list-style: none;
margin-top: 2px;
+ list-style: none;
}
.has-profile .post-buttons {
- float: none;
position: absolute;
- margin: 0;
- right: 0;
top: 5px;
+ right: 0;
+ margin: 0;
}
.post-buttons > li {
@@ -124,9 +134,10 @@
margin-right: 3px;
}
-.post-buttons .button, .format-buttons .button {
- padding-left: 3px;
+.post-buttons .button,
+.format-buttons .button {
padding-right: 3px;
+ padding-left: 3px;
}
.hastouch .post-buttons {
@@ -143,27 +154,33 @@
}
.post-buttons .dropdown a {
- display: block;
- font-size: 1.2em;
+ font-size: 13px;
text-align: right;
+ display: block;
}
.hasjs .postbody .post-buttons {
max-width: 40%;
}
+/* Format buttons
+--------------------------------------------- */
+.format-buttons .button {
+ margin-bottom: 3px;
+}
+
/* Browser-specific tweaks */
button::-moz-focus-inner {
+ border: 0;
padding: 0;
- border: 0
}
/* Deprecated as of version 3.2
--------------------------------------------------*/
+------------------------------------------------- */
.small-icon {
- background-position: 0 50%;
- background-repeat: no-repeat;
background-image: none;
+ background-repeat: no-repeat;
+ background-position: 0 50%;
}
.dropdown .small-icon {
@@ -175,9 +192,12 @@ button::-moz-focus-inner {
padding: 0 0 0 18px;
}
+
+/* stylelint-disable selector-no-qualifying-type */
ul.linklist.bulletin > li.small-icon:before {
display: none;
}
+/* stylelint-enable selector-no-qualifying-type */
.dropdown .small-icon > a {
display: block;
@@ -188,6 +208,6 @@ ul.linklist.bulletin > li.small-icon:before {
}
.rtl .small-icon > a {
- padding-left: 0;
padding-right: 19px;
+ padding-left: 0;
}
diff --git a/phpBB/styles/prosilver/theme/colours.css b/phpBB/styles/prosilver/theme/colours.css
index 04a895873c..3de77eb13d 100644
--- a/phpBB/styles/prosilver/theme/colours.css
+++ b/phpBB/styles/prosilver/theme/colours.css
@@ -1,115 +1,121 @@
-/*
---------------------------------------------------------------
-Colours and backgrounds for common.css
--------------------------------------------------------------- */
+/* -------------------------------------------------------------- /*
+ $Colours
+/* -------------------------------------------------------------- *
-html, body {
- color: #536482;
- background-color: #F5F7FA;
+/* stylelint-disable selector-max-compound-selectors */
+/* stylelint-disable selector-no-qualifying-type */
+
+/* colours and backgrounds for common.css */
+html,
+body {
+ background-color: #f5f5f5;
+ color: #47536b;
+}
+
+.wrap {
+ background-color: #ffffff;
+ border-color: #ededed;
}
h1 {
- color: #FFFFFF;
+ color: #ffffff;
}
h2 {
- color: #28313F;
+ color: #29303d;
}
h3 {
- border-bottom-color: #CCCCCC;
- color: #115098;
+ border-bottom-color: #dedede;
+ color: #0059b3;
}
hr {
- border-color: #FFFFFF;
- border-top-color: #CCCCCC;
+ border-color: #ffffff;
+ border-top-color: #dedede;
}
-/*
---------------------------------------------------------------
-Colours and backgrounds for links.css
--------------------------------------------------------------- */
-
-a { color: #105289; }
-a:hover { color: #D31141; }
+/* colours and backgrounds for links.css */
+a {
+ color: #0f4d8a;
+}
-/* Links on gradient backgrounds */
-.forumbg .header a, .forabg .header a, th a {
- color: #FFFFFF;
+a:hover {
+ color: #d41142;
}
-.forumbg .header a:hover, .forabg .header a:hover, th a:hover {
- color: #A8D8FF;
+/* links on gradient backgrounds */
+.forumbg .header a,
+.forabg .header a,
+th a {
+ color: #ffffff;
}
-/* Notification mark read link */
-.dropdown-extended a.mark_read {
- background-color: #FFFFFF;
+.forumbg .header a:hover,
+.forabg .header a:hover,
+th a:hover {
+ color: #80bfff;
}
-/* Post body links */
+/* post body links */
.postlink {
- border-bottom-color: #368AD2;
- color: #368AD2;
+ border-bottom-color: #2d80d2;
+ color: #2d80d2;
}
.postlink:visited {
- border-bottom-color: #5D8FBD;
- color: #5D8FBD;
+ border-bottom-color: #5380ac;
+ color: #5380ac;
}
.postlink:hover {
- background-color: #D0E4F6;
- color: #0D4473;
+ background-color: #d4e6f7;
+ color: #164069;
}
-.signature a, .signature a:hover {
+.signature a,
+.signature a:hover {
background-color: transparent;
}
-/* Back to top of page */
+/* back to top of page */
.top i {
- color: #999999;
+ color: #9e9e9e;
}
-/* Arrow links */
-.arrow-left:hover, .arrow-right:hover {
- color: #368AD2;
-}
-
-/* Round cornered boxes and backgrounds
----------------------------------------- */
-.wrap {
- background-color: #FFF;
- border-color: #E6E9ED;
+/* arrow links */
+.arrow-left:hover,
+.arrow-right:hover {
+ color: #2d80d2;
}
+/* round cornered boxes and backgrounds */
.headerbar {
- color: #FFFFFF;
+ color: #ffffff;
}
-.headerbar, .forumbg {
- background-color: #12A3EB;
- background-image: -webkit-linear-gradient(top, #6ACEFF 0%, #0076B1 2px, #12A3EB 92px, #12A3EB 100%);
- background-image: linear-gradient(to bottom, #6ACEFF 0%,#0076B1 2px,#12A3EB 92px,#12A3EB 100%);
+.headerbar,
+.forumbg {
+ background-color: #13a4ec;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#80d5ff), color-stop(0.1%, #0077b3), color-stop(30%, #13a4ec), to(#13a4ec));
+ background-image: linear-gradient(to bottom, #80d5ff 0%, #0077b3 0.1%, #13a4ec 30%, #13a4ec 100%);
background-repeat: repeat-x;
}
.forabg {
- background-color: #0076B1;
- background-image: -webkit-linear-gradient(top, #6ACEFF 0%, #12A3EB 2px, #0076B1 92px, #0076B1 100%);
- background-image: linear-gradient(to bottom, #6ACEFF 0%,#12A3EB 2px,#0076B1 92px,#0076B1 100%);
+ background-color: #0077b3;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#80d5ff), color-stop(0.1%, #13a4ec), color-stop(30%, #0077b3), to(#0077b3));
+ background-image: linear-gradient(to bottom, #80d5ff 0%, #13a4ec 0.1%, #0077b3 30%, #0077b3 100%);
background-repeat: repeat-x;
}
.navbar {
- background-color: #CADCEB;
+ background-color: #c9dee8;
}
.panel {
- background-color: #ECF1F3;
- color: #28313F;
+ background-color: #f0f3f5;
+ color: #29303d;
}
.post:target .content {
@@ -121,226 +127,216 @@ a:hover { color: #D31141; }
}
.bg1 {
- background-color: #ECF3F7;
+ background-color: #edf4f7;
}
-table.zebra-list tr:nth-child(odd) td, ul.zebra-list li:nth-child(odd) {
- background-color: #ECF3F7;
+table.zebra-list tr:nth-child(odd) td,
+ul.zebra-list li:nth-child(odd) {
+ background-color: #edf4f7;
}
.bg2 {
- background-color: #E1EBF2;
-}
-
-table.zebra-list tr:nth-child(even) td, ul.zebra-list li:nth-child(even) {
- background-color: #E1EBF2;
-}
-
-.bg3 {
- background-color: #CADCEB;
+ background-color: #dbe9f0;
}
-.ucprowbg {
- background-color: #DCDEE2;
+table.zebra-list tr:nth-child(even) td,
+ul.zebra-list li:nth-child(even) {
+ background-color: #dbe9f0;
}
-.fieldsbg {
- background-color: #E7E8EA;
+.bg3 {
+ background-color: #c9dee8;
}
-.site_logo {
- background-image: url("./images/site_logo.svg");
-}
-
-/* Horizontal lists
-----------------------------------------*/
-
+/* horizontal lists */
ul.navlinks {
- border-top-color: #FFFFFF;
+ border-top-color: #ffffff;
}
-/* Table styles
-----------------------------------------*/
+/* table styles */
table.table1 thead th {
- color: #FFFFFF;
+ color: #ffffff;
}
table.table1 tbody tr {
- border-color: #BFC1CF;
+ border-color: #c9dee8;
}
-table.table1 tbody tr:hover, table.table1 tbody tr.hover {
- background-color: #CFE1F6;
- color: #000;
+table.table1 tbody tr:hover,
+table.table1 tbody tr.hover {
+ background-color: #d4e6f7;
+ color: #000000;
}
table.table1 td {
- color: #536482;
+ color: #47536b;
}
table.table1 tbody td {
- border-top-color: #FAFAFA;
+ border-top-color: #fafafa;
}
table.table1 tbody th {
+ background-color: #ffffff;
border-bottom-color: #000000;
- color: #333333;
- background-color: #FFFFFF;
+ color: #212121;
}
table.info tbody th {
color: #000000;
}
-/* Misc layout styles
----------------------------------------- */
+/* misc layout styles */
dl.details dt {
color: #000000;
}
dl.details dd {
- color: #536482;
+ color: #47536b;
}
-.sep {
- color: #1198D9;
+/* icon styles */
+.icon.icon-blue,
+a:hover .icon.icon-blue {
+ color: #0059b3;
}
-/* Icon styles
----------------------------------------- */
-.icon.icon-blue, a:hover .icon.icon-blue {
- color: #196db5;
+.icon.online {
+ color: #85de39;
}
-.icon.icon-green, a:hover .icon.icon-green{
- color: #1b9A1B;
+.icon.icon-green,
+a:hover .icon.icon-green {
+ color: #4db355;
}
-.icon.icon-red, a:hover .icon.icon-red{
- color: #BC2A4D;
+.icon.icon-red,
+a:hover .icon.icon-red {
+ color: #d41142;
}
-.icon.icon-orange, a:hover .icon.icon-orange{
- color: #FF6600;
+.icon.icon-orange,
+a:hover .icon.icon-orange {
+ color: #ff9500;
}
-.icon.icon-bluegray, a:hover .icon.icon-bluegray{
- color: #536482;
+.icon.icon-bluegray,
+a:hover .icon.icon-bluegray {
+ color: #47536b;
}
-.icon.icon-gray, a:hover .icon.icon-gray{
- color: #777777;
+.icon.icon-gray,
+a:hover .icon.icon-gray {
+ color: #757575;
}
-.icon.icon-lightgray, a:hover .icon.icon-lightgray{
- color: #999999;
+.icon.icon-lightgray,
+a:hover .icon.icon-lightgray {
+ color: #9e9e9e;
}
-.icon.icon-black, a:hover .icon.icon-black{
- color: #333333;
+.icon.icon-black,
+a:hover .icon.icon-black {
+ color: #212121;
}
.alert_close .icon:before {
- background-color: #FFFFFF;
+ background-color: #ffffff;
}
-/* Jumpbox */
+/* jumpbox */
.jumpbox .dropdown li {
- border-top-color: #CCCCCC;
+ border-top-color: #dedede;
}
.jumpbox-cat-link {
- background-color: #0076b1;
- border-top-color: #0076B1;
- color: #FFFFFF;
+ background-color: #0077b3;
+ border-top-color: #0077b3;
+ color: #ffffff;
}
-.jumpbox-cat-link:hover {
- background-color: #12A3EB;
- border-top-color: #12A3EB;
- color: #FFFFFF;
+.jumpbox-cat-link:hover,
+.jumpbox-cat-link:focus {
+ background-color: #13a4ec;
+ border-top-color: #13a4ec;
+ color: #ffffff;
}
.jumpbox-forum-link {
- background-color: #E1EBF2;
+ background-color: #dbe9f0;
}
.jumpbox-forum-link:hover {
- background-color: #F6F4D0;
+ background-color: #fffbcc;
}
.jumpbox .dropdown .pointer-inner {
- border-color: #E1EBF2 transparent;
+ border-color: #dbe9f0 transparent;
}
.jumpbox-sub-link {
- background-color: #E1EBF2;
+ background-color: #dbe9f0;
}
.jumpbox-sub-link:hover {
- background-color: #F1F8FF;
+ background-color: #e6f7ff;
}
-/* Miscellaneous styles
----------------------------------------- */
-
+/* miscellaneous styles */
.copyright {
- color: #555555;
+ color: #424242;
}
.error {
- color: #BC2A4D;
+ color: #d41142;
}
.reported {
- background-color: #F7ECEF;
+ background-color: #f7edf0;
}
li.reported:hover {
- background-color: #ECD5D8 !important;
+ background-color: #f0dbe0 !important;
}
-.sticky, .announce {
- /* you can add a background for stickies and announcements*/
+
+.sticky,
+.announce {
+ /* you can add a background for stickies and announcements */
}
div.rules {
- background-color: #ECD5D8;
- color: #BC2A4D;
+ background-color: #f0dbe0;
+ color: #d41142;
}
p.post-notice {
- background-color: #ECD5D8;
+ background-color: #f0dbe0;
background-image: none;
}
-/*
---------------------------------------------------------------
-Colours and backgrounds for content.css
--------------------------------------------------------------- */
-
+/* colours and backgrounds for content.css */
ul.forums {
- background-color: #EEF5F9; /* Old browsers */ /* FF3.6+ */
- background-image: -webkit-linear-gradient(top, #D2E0EB 0%, #EEF5F9 100%);
- background-image: linear-gradient(to bottom, #D2E0EB 0%,#EEF5F9 100%); /* W3C */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#D2E0EB', endColorstr='#EEF5F9',GradientType=0 ); /* IE6-9 */
+ background-color: #edf4f7;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#b8d3e0), to(#edf4f7));
+ background-image: linear-gradient(to bottom, #b8d3e0 0%, #edf4f7 100%);
}
-ul.topiclist li {
- color: #4C5D77;
+ul.topiclist > li {
+ color: #47536b;
}
ul.topiclist dd {
- border-left-color: #FFFFFF;
+ border-left-color: #ffffff;
}
.rtl ul.topiclist dd {
- border-right-color: #FFFFFF;
+ border-right-color: #ffffff;
border-left-color: transparent;
}
li.row {
- border-top-color: #FFFFFF;
- border-bottom-color: #00608F;
+ border-top-color: #ffffff;
+ border-bottom-color: #0077b3;
}
li.row strong {
@@ -348,150 +344,143 @@ li.row strong {
}
li.row:hover {
- background-color: #F6F4D0;
+ background-color: #fffbcc;
}
li.row:hover dd {
- border-left-color: #CCCCCC;
+ border-left-color: #dedede;
}
.rtl li.row:hover dd {
- border-right-color: #CCCCCC;
+ border-right-color: #dedede;
border-left-color: transparent;
}
-li.header dt, li.header dd {
- color: #FFFFFF;
+li.header dt,
+li.header dd {
+ color: #ffffff;
}
-/* Post body styles
-----------------------------------------*/
+/* post body styles */
.postbody {
- color: #333333;
+ color: #212121;
}
-/* Content container styles
-----------------------------------------*/
+/* content container styles */
.content {
- color: #333333;
+ color: #212121;
}
-.content h2, .panel h2 {
- color: #115098;
- border-bottom-color: #CCCCCC;
+.content h2,
+.panel h2 {
+ border-bottom-color: #dedede;
+ color: #0059b3;
}
dl.faq dt {
- color: #333333;
+ color: #212121;
}
.posthilit {
- background-color: #F3BFCC;
- color: #BC2A4D;
+ background-color: #f4becb;
+ color: #d41142;
}
-.announce, .unreadpost {
- /* Highlight the announcements & unread posts box */
+.announce,
+.unreadpost {
+ /* highlight the announcements & unread posts box */
}
-/* Post signature */
+/* post signature */
.signature {
- border-top-color: #CCCCCC;
+ border-top-color: #dedede;
}
-/* Post noticies */
+/* post noticies */
.notice {
- border-top-color: #CCCCCC;
+ border-top-color: #dedede;
}
-/* BB Code styles
-----------------------------------------*/
-/* Quote block */
+/* bb code styles */
+
+/* quote block */
blockquote {
- background-color: #EBEADD;
- border-color:#DBDBCE;
+ background-color: #f4f1d7;
+ border-color: #f1efda;
}
blockquote blockquote {
- /* Nested quotes */
- background-color:#EFEED9;
+ /* nested quotes */
+ background-color: #f7f4d4;
}
blockquote blockquote blockquote {
- /* Nested quotes */
- background-color: #EBEADD;
+ /* nested quotes */
+ background-color: #f4f1d7;
}
-/* Code block */
+/* code block */
.codebox {
- background-color: #FFFFFF;
- border-color: #C9D2D8;
+ background-color: #ffffff;
+ border-color: #c0d3dd;
}
.codebox p {
- border-bottom-color: #CCCCCC;
+ border-bottom-color: #dedede;
}
.codebox code {
- color: #2E8B57;
+ color: #4db355;
}
-/* Attachments
-----------------------------------------*/
+/* attachments */
.attachbox {
- background-color: #FFFFFF;
- border-color: #C9D2D8;
-}
-
-.pm-message .attachbox {
- background-color: #F2F3F3;
+ background-color: #ffffff;
+ border-color: #c0d3dd;
}
.attachbox dd {
- border-top-color: #C9D2D8;
+ border-top-color: #c0d3dd;
}
.attachbox p {
- color: #666666;
+ color: #616161;
}
.attachbox p.stats {
- color: #666666;
+ color: #616161;
}
.attach-image img {
- border-color: #999999;
+ border-color: #9e9e9e;
}
-/* Inline image thumbnails */
-
+/* inline image thumbnails */
dl.file dd {
- color: #666666;
+ color: #616161;
}
dl.thumbnail img {
- border-color: #666666;
- background-color: #FFFFFF;
+ background-color: #ffffff;
+ border-color: #616161;
}
dl.thumbnail dd {
- color: #666666;
+ color: #616161;
}
dl.thumbnail dt a:hover {
- background-color: #EEEEEE;
+ background-color: #ededed;
}
dl.thumbnail dt a:hover img {
- border-color: #368AD2;
+ border-color: #2d80d2;
}
-/* Post poll styles
-----------------------------------------*/
-
+/* post poll styles */
fieldset.polls dl {
- border-top-color: #DCDEE2;
- color: #666666;
+ border-top-color: #c9dee8;
+ color: #616161;
}
fieldset.polls dl.voted {
@@ -499,477 +488,491 @@ fieldset.polls dl.voted {
}
fieldset.polls dd div {
- color: #FFFFFF;
+ color: #ffffff;
}
-.rtl .pollbar1, .rtl .pollbar2, .rtl .pollbar3, .rtl .pollbar4, .rtl .pollbar5 {
+.rtl .pollbar1,
+.rtl .pollbar2,
+.rtl .pollbar3,
+.rtl .pollbar4,
+.rtl .pollbar5 {
border-right-color: transparent;
}
.pollbar1 {
- background-color: #AA2346;
- border-bottom-color: #74162C;
- border-right-color: #74162C;
+ background-color: #b31a40;
+ border-right-color: #821732;
+ border-bottom-color: #821732;
}
.rtl .pollbar1 {
- border-left-color: #74162C;
+ border-left-color: #821732;
}
.pollbar2 {
- background-color: #BE1E4A;
- border-bottom-color: #8C1C38;
- border-right-color: #8C1C38;
+ background-color: #cf1745;
+ border-right-color: #9c1638;
+ border-bottom-color: #9c1638;
}
.rtl .pollbar2 {
- border-left-color: #8C1C38;
+ border-left-color: #9c1638;
}
.pollbar3 {
- background-color: #D11A4E;
- border-bottom-color: #AA2346;
- border-right-color: #AA2346;
+ background-color: #ec1349;
+ border-right-color: #cf1745;
+ border-bottom-color: #cf1745;
}
.rtl .pollbar3 {
- border-left-color: #AA2346;
+ border-left-color: #cf1745;
}
.pollbar4 {
- background-color: #E41653;
- border-bottom-color: #BE1E4A;
- border-right-color: #BE1E4A;
+ background-color: #f42559;
+ border-right-color: #ec1349;
+ border-bottom-color: #ec1349;
}
.rtl .pollbar4 {
- border-left-color: #BE1E4A;
+ border-left-color: #ec1349;
}
.pollbar5 {
- background-color: #F81157;
- border-bottom-color: #D11A4E;
- border-right-color: #D11A4E;
+ background-color: #fa3869;
+ border-right-color: #f42559;
+ border-bottom-color: #f42559;
}
.rtl .pollbar5 {
- border-left-color: #D11A4E;
+ border-left-color: #f42559;
}
-/* Poster profile block
-----------------------------------------*/
+/* poster profile block */
.postprofile {
- color: #666666;
- border-color: #FFFFFF;
+ border-color: #ffffff;
+ color: #616161;
}
.pm .postprofile {
- border-color: #DDDDDD;
+ border-color: #dedede;
}
.postprofile strong {
color: #000000;
}
-.online {
- background-image: url("./en/icon_user_online.gif");
+dd.profile-warnings {
+ color: #d41142;
}
-dd.profile-warnings {
- color: #BC2A4D;
+/* Show scrollbars for items with overflow on iOS devices */
+.postbody .content::-webkit-scrollbar,
+.topicreview::-webkit-scrollbar,
+.post_details::-webkit-scrollbar,
+.codebox code::-webkit-scrollbar,
+.attachbox dd::-webkit-scrollbar,
+.attach-image::-webkit-scrollbar,
+.dropdown-extended ul::-webkit-scrollbar {
+ background: rgba(0, 0, 0, 0.1);
+}
+
+.postbody .content::-webkit-scrollbar-thumb,
+.topicreview::-webkit-scrollbar-thumb,
+.post_details::-webkit-scrollbar-thumb,
+.codebox code::-webkit-scrollbar-thumb,
+.attachbox dd::-webkit-scrollbar-thumb,
+.attach-image::-webkit-scrollbar-thumb,
+.dropdown-extended ul::-webkit-scrollbar-thumb {
+ background: rgba(0, 0, 0, 0.3);
}
-/*
---------------------------------------------------------------
-Colours and backgrounds for buttons.css
--------------------------------------------------------------- */
+/* colours and backgrounds for buttons.css */
.button {
- border-color: #C7C3BF;
- background-color: #E9E9E9; /* Old browsers */ /* FF3.6+ */
- background-image: -webkit-linear-gradient(top, #FFFFFF 0%, #E9E9E9 100%);
- background-image: linear-gradient(to bottom, #FFFFFF 0%,#E9E9E9 100%); /* W3C */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#FFFFFF', endColorstr='#E9E9E9',GradientType=0 ); /* IE6-9 */
- box-shadow: 0 0 0 1px #FFFFFF inset;
- -webkit-box-shadow: 0 0 0 1px #FFFFFF inset;
- color: #D31141;
+ background-color: #e0e0e0;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#ffffff), to(#e0e0e0));
+ background-image: linear-gradient(to bottom, #ffffff 0%, #e0e0e0 100%);
+ border-color: #bdbdbd;
+ -webkit-box-shadow: 0 0 0 1px #ffffff inset;
+ box-shadow: 0 0 0 1px #ffffff inset;
+ color: #d41142;
}
.button:hover,
.button:focus {
- border-color: #0A8ED0;
- background-color: #FFFFFF; /* Old browsers */ /* FF3.6+ */
- background-image: -webkit-linear-gradient(top, #E9E9E9 0%, #FFFFFF 100%);
- background-image: linear-gradient(to bottom, #E9E9E9 0%,#FFFFFF 100%); /* W3C */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#E9E9E9', endColorstr='#FFFFFF',GradientType=0 ); /* IE6-9 */
- text-shadow: 1px 1px 0 #FFFFFF, -1px -1px 0 #FFFFFF, -1px -1px 0 rgba(188, 42, 77, 0.2);
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#e0e0e0), to(#ffffff));
+ background-image: linear-gradient(to bottom, #e0e0e0 0%, #ffffff 100%);
+ border-color: #0077b3;
+ text-shadow: 1px 1px 0 #ffffff, -1px -1px 0 #ffffff, -1px -1px 0 rgba(189, 40, 77, 0.2);
+ color: #d41142;
}
-
.button .icon,
.button-secondary {
- color: #8f8f8f;
+ color: #9e9e9e;
+}
+
+.button-form,
+.button-form-bold {
+ border-color: #757575;
+ -webkit-box-shadow: none;
+ box-shadow: none;
+ color: #212121;
+}
+
+.button-form:hover,
+.button-form-bold:hover {
+ border-color: #d41142;
+ text-shadow: none;
+ color: #d41142;
+}
+
+.button-form:focus,
+.button-form-bold:focus {
+ border-color: #0077b3;
+ text-shadow: none;
+ color: #0077b3;
}
.button-secondary:focus,
.button-secondary:hover,
.button:focus .icon,
.button:hover .icon {
- color: #0A8ED0;
+ color: #0077b3;
}
.button-search:hover,
.button-search-end:hover {
- border-color: #C7C3BF;
+ border-color: #bdbdbd;
}
-.caret { border-color: #DADADA; }
-.caret { border-color: #C7C3BF; }
+.caret {
+ border-color: #bdbdbd;
+}
-.contact-icons a { border-color: #DCDCDC; }
-.contact-icons a:hover { background-color: #F2F6F9; }
+.contact-icons a {
+ border-color: #dedede;
+}
-/* Pagination
----------------------------------------- */
+.contact-icons a:hover {
+ background-color: #ededed;
+}
+/* pagination */
.pagination li a {
- background: #ECEDEE;
+ background: #ededed;
+ -webkit-filter: none;
filter: none;
- border-color: #B4BAC0;
- box-shadow: none;
+ border-color: #bdbdbd;
-webkit-box-shadow: none;
- color: #5C758C;
+ box-shadow: none;
+ color: #9e9e9e;
}
.pagination li.ellipsis span {
background: transparent;
- color: #000000;
+ color: #000000;
}
.pagination li.active span {
- background: #4692BF;
- border-color: #4692BF;
- color: #FFFFFF;
+ background: #2d80d2;
+ border-color: #2d80d2;
+ color: #ffffff;
}
-.pagination li a:hover, .pagination li a:hover .icon, .pagination .dropdown-visible a.dropdown-trigger, .nojs .pagination .dropdown-container:hover a.dropdown-trigger {
- background: #368AD2;
- border-color: #368AD2;
- filter: none;
- color: #FFFFFF;
+.pagination li a:hover,
+.pagination li a:hover .icon,
+.pagination .dropdown-visible a.dropdown-trigger,
+.nojs .pagination .dropdown-container:hover a.dropdown-trigger {
+ background: #2d80d2;
+ border-color: #2d80d2;
text-shadow: none;
+ color: #ffffff;
}
-/* Search box
---------------------------------------------- */
-
+/* search box */
.search-box .inputbox,
.search-box .inputbox:hover,
.search-box .inputbox:focus {
- border-color: #C7C3BF;
+ border-color: #bdbdbd;
}
.search-header {
- box-shadow: 0 0 10px #0075B0;
+ -webkit-box-shadow: 0 0 10px #0077b3;
+ box-shadow: 0 0 10px #0077b3;
}
.search-results li:hover,
.search-results li.active {
- background-color: #CFE1F6;
-}
-
-/* Icon images
----------------------------------------- */
-
-.contact-icon { background-image: url("./images/icons_contact.png"); }
-
-/* Profile & navigation icons */
-.pm-icon { background-position: 0 0; }
-.email-icon { background-position: -21px 0; }
-.jabber-icon { background-position: -80px 0; }
-.phpbb_icq-icon { background-position: -61px 0 ; }
-.phpbb_wlm-icon { background-position: -182px 0; }
-.phpbb_aol-icon { background-position: -244px 0; }
-.phpbb_website-icon { background-position: -40px 0; }
-.phpbb_youtube-icon { background-position: -98px 0; }
-.phpbb_facebook-icon { background-position: -119px 0; }
-.phpbb_googleplus-icon { background-position: -140px 0; }
-.phpbb_skype-icon { background-position: -161px 0; }
-.phpbb_twitter-icon { background-position: -203px 0; }
-.phpbb_yahoo-icon { background-position: -224px 0; }
-
-/* Forum icons & Topic icons */
-.global_read { background-image: url("./images/announce_read.gif"); }
-.global_read_mine { background-image: url("./images/announce_read_mine.gif"); }
-.global_read_locked { background-image: url("./images/announce_read_locked.gif"); }
-.global_read_locked_mine { background-image: url("./images/announce_read_locked_mine.gif"); }
-.global_unread { background-image: url("./images/announce_unread.gif"); }
-.global_unread_mine { background-image: url("./images/announce_unread_mine.gif"); }
-.global_unread_locked { background-image: url("./images/announce_unread_locked.gif"); }
-.global_unread_locked_mine { background-image: url("./images/announce_unread_locked_mine.gif"); }
-
-.announce_read { background-image: url("./images/announce_read.gif"); }
-.announce_read_mine { background-image: url("./images/announce_read_mine.gif"); }
-.announce_read_locked { background-image: url("./images/announce_read_locked.gif"); }
-.announce_read_locked_mine { background-image: url("./images/announce_read_locked_mine.gif"); }
-.announce_unread { background-image: url("./images/announce_unread.gif"); }
-.announce_unread_mine { background-image: url("./images/announce_unread_mine.gif"); }
-.announce_unread_locked { background-image: url("./images/announce_unread_locked.gif"); }
-.announce_unread_locked_mine { background-image: url("./images/announce_unread_locked_mine.gif"); }
-
-.forum_link { background-image: url("./images/forum_link.gif"); }
-.forum_read { background-image: url("./images/forum_read.gif"); }
-.forum_read_locked { background-image: url("./images/forum_read_locked.gif"); }
-.forum_read_subforum { background-image: url("./images/forum_read_subforum.gif"); }
-.forum_unread { background-image: url("./images/forum_unread.gif"); }
-.forum_unread_locked { background-image: url("./images/forum_unread_locked.gif"); }
-.forum_unread_subforum { background-image: url("./images/forum_unread_subforum.gif"); }
-
-.sticky_read { background-image: url("./images/sticky_read.gif"); }
-.sticky_read_mine { background-image: url("./images/sticky_read_mine.gif"); }
-.sticky_read_locked { background-image: url("./images/sticky_read_locked.gif"); }
-.sticky_read_locked_mine { background-image: url("./images/sticky_read_locked_mine.gif"); }
-.sticky_unread { background-image: url("./images/sticky_unread.gif"); }
-.sticky_unread_mine { background-image: url("./images/sticky_unread_mine.gif"); }
-.sticky_unread_locked { background-image: url("./images/sticky_unread_locked.gif"); }
-.sticky_unread_locked_mine { background-image: url("./images/sticky_unread_locked_mine.gif"); }
-
-.topic_moved { background-image: url("./images/topic_moved.gif"); }
-.pm_read,
-.topic_read { background-image: url("./images/topic_read.gif"); }
-.topic_read_mine { background-image: url("./images/topic_read_mine.gif"); }
-.topic_read_hot { background-image: url("./images/topic_read_hot.gif"); }
-.topic_read_hot_mine { background-image: url("./images/topic_read_hot_mine.gif"); }
-.topic_read_locked { background-image: url("./images/topic_read_locked.gif"); }
-.topic_read_locked_mine { background-image: url("./images/topic_read_locked_mine.gif"); }
-.pm_unread,
-.topic_unread { background-image: url("./images/topic_unread.gif"); }
-.topic_unread_mine { background-image: url("./images/topic_unread_mine.gif"); }
-.topic_unread_hot { background-image: url("./images/topic_unread_hot.gif"); }
-.topic_unread_hot_mine { background-image: url("./images/topic_unread_hot_mine.gif"); }
-.topic_unread_locked { background-image: url("./images/topic_unread_locked.gif"); }
-.topic_unread_locked_mine { background-image: url("./images/topic_unread_locked_mine.gif"); }
+ background-color: #cfe1f6;
+}
+
+/* icon images */
+.site_logo { background-image: url("./images/site_logo.svg"); }
+.contact-icon { background-image: url("./images/icons_contact.png"); }
+
+/* profile icons */
+.pm-icon { background-position: 0 0; }
+.email-icon { background-position: -21px 0; }
+.jabber-icon { background-position: -80px 0; }
+.phpbb_icq-icon { background-position: -61px 0; }
+.phpbb_wlm-icon { background-position: -182px 0; }
+.phpbb_aol-icon { background-position: -244px 0; }
+.phpbb_website-icon { background-position: -40px 0; }
+.phpbb_youtube-icon { background-position: -98px 0; }
+.phpbb_facebook-icon { background-position: -119px 0; }
+.phpbb_googleplus-icon { background-position: -140px 0; }
+.phpbb_skype-icon { background-position: -161px 0; }
+.phpbb_twitter-icon { background-position: -203px 0; }
+.phpbb_yahoo-icon { background-position: -224px 0; }
+
+/* forum icons & topic icons */
+.global_read { background-image: url("./images/announce_read.gif"); }
+.global_read_mine { background-image: url("./images/announce_read_mine.gif"); }
+.global_read_locked { background-image: url("./images/announce_read_locked.gif"); }
+.global_read_locked_mine { background-image: url("./images/announce_read_locked_mine.gif"); }
+.global_unread { background-image: url("./images/announce_unread.gif"); }
+.global_unread_mine { background-image: url("./images/announce_unread_mine.gif"); }
+.global_unread_locked { background-image: url("./images/announce_unread_locked.gif"); }
+.global_unread_locked_mine { background-image: url("./images/announce_unread_locked_mine.gif"); }
+
+.announce_read { background-image: url("./images/announce_read.gif"); }
+.announce_read_mine { background-image: url("./images/announce_read_mine.gif"); }
+.announce_read_locked { background-image: url("./images/announce_read_locked.gif"); }
+.announce_read_locked_mine { background-image: url("./images/announce_read_locked_mine.gif"); }
+.announce_unread { background-image: url("./images/announce_unread.gif"); }
+.announce_unread_mine { background-image: url("./images/announce_unread_mine.gif"); }
+.announce_unread_locked { background-image: url("./images/announce_unread_locked.gif"); }
+.announce_unread_locked_mine { background-image: url("./images/announce_unread_locked_mine.gif"); }
+
+.forum_link { background-image: url("./images/forum_link.gif"); }
+.forum_read { background-image: url("./images/forum_read.gif"); }
+.forum_read_locked { background-image: url("./images/forum_read_locked.gif"); }
+.forum_read_subforum { background-image: url("./images/forum_read_subforum.gif"); }
+.forum_unread { background-image: url("./images/forum_unread.gif"); }
+.forum_unread_locked { background-image: url("./images/forum_unread_locked.gif"); }
+.forum_unread_subforum { background-image: url("./images/forum_unread_subforum.gif"); }
+
+.sticky_read { background-image: url("./images/sticky_read.gif"); }
+.sticky_read_mine { background-image: url("./images/sticky_read_mine.gif"); }
+.sticky_read_locked { background-image: url("./images/sticky_read_locked.gif"); }
+.sticky_read_locked_mine { background-image: url("./images/sticky_read_locked_mine.gif"); }
+.sticky_unread { background-image: url("./images/sticky_unread.gif"); }
+.sticky_unread_mine { background-image: url("./images/sticky_unread_mine.gif"); }
+.sticky_unread_locked { background-image: url("./images/sticky_unread_locked.gif"); }
+.sticky_unread_locked_mine { background-image: url("./images/sticky_unread_locked_mine.gif"); }
+.pm_read,
+.topic_read { background-image: url("./images/topic_read.gif"); }
+.topic_moved { background-image: url("./images/topic_moved.gif"); }
+.topic_read_mine { background-image: url("./images/topic_read_mine.gif"); }
+.topic_read_hot { background-image: url("./images/topic_read_hot.gif"); }
+.topic_read_hot_mine { background-image: url("./images/topic_read_hot_mine.gif"); }
+.topic_read_locked { background-image: url("./images/topic_read_locked.gif"); }
+.topic_read_locked_mine { background-image: url("./images/topic_read_locked_mine.gif"); }
-/*
---------------------------------------------------------------
-Colours and backgrounds for cp.css
--------------------------------------------------------------- */
+.pm_unread,
+.topic_unread { background-image: url("./images/topic_unread.gif"); }
+.topic_unread_mine { background-image: url("./images/topic_unread_mine.gif"); }
+.topic_unread_hot { background-image: url("./images/topic_unread_hot.gif"); }
+.topic_unread_hot_mine { background-image: url("./images/topic_unread_hot_mine.gif"); }
+.topic_unread_locked { background-image: url("./images/topic_unread_locked.gif"); }
+.topic_unread_locked_mine { background-image: url("./images/topic_unread_locked_mine.gif"); }
-/* Main CP box
-----------------------------------------*/
+/* colours and backgrounds for cp.css */
-.panel-container h3, .panel-container hr, .cp-menu hr {
- border-color: #A4B3BF;
+/* main cp box */
+.panel-container h3,
+.panel-container hr,
+.cp-menu hr {
+ border-color: #c9dee8;
}
.panel-container .panel li.row {
- border-bottom-color: #B5C1CB;
- border-top-color: #F9F9F9;
+ border-top-color: #fafafa;
+ border-bottom-color: #c9dee8;
}
ul.cplist {
- border-top-color: #B5C1CB;
+ border-top-color: #c9dee8;
}
-.panel-container .panel li.header dd, .panel-container .panel li.header dt {
+.panel-container .panel li.header dd,
+.panel-container .panel li.header dt {
color: #000000;
}
.panel-container table.table1 thead th {
- color: #333333;
- border-bottom-color: #333333;
+ border-bottom-color: #212121;
+ color: #212121;
}
-.cp-main .pm-message {
- border-color: #DBDEE2;
- background-color: #FFFFFF;
-}
-
-/* CP tabbed menu
-----------------------------------------*/
+/* cp tabbed menu */
.tabs .tab > a {
- background: #BACCD9;
- color: #536482;
+ background: #c0d3dd;
+ color: #47536b;
}
.tabs .tab > a:hover {
- background: #DDEDFB;
- color: #D31141;
+ background: #e6f7ff;
+ color: #d41142;
}
-.tabs .activetab > a,
-.tabs .activetab > a:hover {
- background-color: #CADCEB; /* Old browsers */ /* FF3.6+ */
- background-image: -webkit-linear-gradient(top, #E2F2FF 0%, #CADCEB 100%);
- background-image: linear-gradient(to bottom, #E2F2FF 0%,#CADCEB 100%); /* W3C */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#E2F2FF', endColorstr='#CADCEB',GradientType=0 ); /* IE6-9 */
- border-color: #CADCEB;
- box-shadow: 0 1px 1px #F2F9FF inset;
- color: #333333;
+/* responsive tabs */
+.responsive-tab .responsive-tab-link:before {
+ border-color: #47536b;
}
+.responsive-tab .responsive-tab-link:hover:before {
+ border-color: #d41142;
+}
+
+.tabs .activetab > a,
.tabs .activetab > a:hover {
- color: #000000;
+ background-color: #c9dee8;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#e6f7ff), to(#c9dee8));
+ background-image: linear-gradient(to bottom, #e6f7ff 0%, #c9dee8 100%);
+ border-color: #c9dee8;
+ -webkit-box-shadow: 0 1px 1px #e6f7ff inset;
+ box-shadow: 0 1px 1px #e6f7ff inset;
+ color: #212121;
}
-/* Mini tabbed menu used in MCP
-----------------------------------------*/
+/* mini tabbed menu used in mcp */
.minitabs .tab > a {
- background-color: #E1EBF2;
+ background-color: #dbe9f0;
}
.minitabs .activetab > a,
.minitabs .activetab > a:hover {
- background-color: #F9F9F9;
- color: #333333;
+ background-color: #fafafa;
+ color: #212121;
}
-/* Responsive tabs
-----------------------------------------*/
-.responsive-tab .responsive-tab-link:before {
- border-color: #536482;
-}
+/* ucp navigation menu */
-.responsive-tab .responsive-tab-link:hover:before {
- border-color: #D31141;
-}
-
-/* UCP navigation menu
-----------------------------------------*/
-
-/* Link styles for the sub-section links */
+/* link styles for the sub-section links */
.navigation a {
- color: #333;
- background: #CADCEB; /* Old browsers */ /* FF3.6+ */
- background: -webkit-linear-gradient(left, #B4C4D1 50%, #CADCEB 100%);
- background: linear-gradient(to right, #B4C4D1 50%,#CADCEB 100%); /* W3C */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#B4C4D1', endColorstr='#CADCEB',GradientType=1 ); /* IE6-9 */
+ background: #c0d3dd;
+ background-image: -webkit-gradient(linear, left top, right top, color-stop(50%, #aab9c0), to(#c0d3dd));
+ background-image: linear-gradient(to right, #aab9c0 50%, #c0d3dd 100%);
+ color: #212121;
}
.rtl .navigation a {
- background: #B4C4D1; /* Old browsers */ /* FF3.6+ */
- background: -webkit-linear-gradient(left, #CADCEB 50%, #B4C4D1 100%);
- background: linear-gradient(to right, #CADCEB 50%,#B4C4D1 100%); /* W3C */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#CADCEB', endColorstr='#B4C4D1',GradientType=1 ); /* IE6-9 */
+ background: #afc5cf;
+ background-image: -webkit-gradient(linear, left top, right top, color-stop(50%, #c0d3dd), to(#aab9c0));
+ background-image: linear-gradient(to right, #c0d3dd 50%, #aab9c0 100%);
}
.navigation a:hover {
- background: #AABAC6;
- color: #BC2A4D;
- filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+ background: #aab9c0;
+ color: #d41142;
}
.navigation .active-subsection a {
- background: #F9F9F9;
- color: #D31141;
- filter: progid:DXImageTransform.Microsoft.gradient(enabled = false);
+ background: #fafafa;
+ color: #d41142;
}
.navigation .active-subsection a:hover {
- color: #D31141;
-}
-
-@media only screen and (max-width: 900px), only screen and (max-device-width: 900px)
-{
- #navigation a, .rtl #navigation a {
- background: #B2C2CF;
- }
+ color: #d41142;
}
-/* Preferences pane layout
-----------------------------------------*/
+/* preferences pane layout */
.panel-container h2 {
- color: #333333;
+ color: #212121;
}
.panel-container .panel {
- background-color: #F9F9F9;
+ background-color: #fafafa;
}
.cp-main .pm {
- background-color: #FFFFFF;
+ background-color: #ffffff;
}
-/* Friends list */
+/* friends list */
.cp-mini {
- background-color: #EEF5F9;
+ background-color: #edf4f7;
}
dl.mini dt {
- color: #425067;
+ color: #47536b;
}
-/* PM Styles
-----------------------------------------*/
-/* PM Message history */
+/* pm styles */
+
+/* pm message history */
.current {
color: #000000 !important;
}
-/* PM marking colours */
-.pmlist li.pm_message_reported_colour, .pm_message_reported_colour {
- border-left-color: #BC2A4D;
- border-right-color: #BC2A4D;
+/* pm marking colours */
+.pmlist li.pm_message_reported_colour,
+.pm_message_reported_colour {
+ border-right-color: #ec1349;
+ border-left-color: #ec1349;
}
-.pmlist li.pm_marked_colour, .pm_marked_colour {
- border-color: #FF6600;
+.pmlist li.pm_marked_colour,
+.pm_marked_colour {
+ border-color: #ff9500;
}
-.pmlist li.pm_replied_colour, .pm_replied_colour {
- border-color: #A9B8C2;
+.pmlist li.pm_replied_colour,
+.pm_replied_colour {
+ border-color: #a3b8c2;
}
-.pmlist li.pm_friend_colour, .pm_friend_colour {
- border-color: #5D8FBD;
+.pmlist li.pm_friend_colour,
+.pm_friend_colour {
+ border-color: #4582a1;
}
-.pmlist li.pm_foe_colour, .pm_foe_colour {
+.pmlist li.pm_foe_colour,
+.pm_foe_colour {
border-color: #000000;
}
-/* Avatar gallery */
+/* avatar gallery */
.gallery label {
- background: #FFFFFF;
- border-color: #CCC;
+ background: #ffffff;
+ border-color: #dedede;
}
.gallery label:hover {
- background-color: #EEE;
+ background-color: #ededed;
}
-/*
---------------------------------------------------------------
-Colours and backgrounds for forms.css
--------------------------------------------------------------- */
+/* colours and backgrounds for forms.css */
-/* General form styles
-----------------------------------------*/
+/* general form styles */
select {
- border-color: #666666;
- background-color: #FAFAFA;
- color: #000;
+ background-color: #fafafa;
+ border-color: #616161;
+ color: #000000;
}
label {
- color: #425067;
+ color: #47536b;
}
option.disabled-option {
- color: graytext;
+ color: #7f7f7f;
}
-/* Definition list layout for forms
----------------------------------------- */
+/* definition list layout for forms */
dd label {
- color: #333;
+ color: #212121;
}
fieldset.fields1 {
background-color: transparent;
}
-/* Hover effects */
+/* hover effects */
fieldset dl:hover dt label {
color: #000000;
}
@@ -978,191 +981,178 @@ fieldset.fields2 dl:hover dt label {
color: inherit;
}
-/* Quick-login on index page */
-fieldset.quick-login input.inputbox {
- background-color: #F2F3F3;
-}
-
-/* Posting page styles
-----------------------------------------*/
-
+/* posting page styles */
.message-box textarea {
- color: #333333;
+ color: #212121;
}
.message-box textarea.drag-n-drop {
- outline-color: rgba(102, 102, 102, 0.5);
+ outline-color: rgba(97, 97, 97, 0.5);
}
.message-box textarea.drag-n-drop-highlight {
- outline-color: rgba(17, 163, 234, 0.5);
+ outline-color: rgba(19, 164, 236, 0.5);
}
-/* Input field styles
----------------------------------------- */
+/* input field styles */
.inputbox {
- background-color: #FFFFFF;
- border-color: #B4BAC0;
- color: #333333;
+ background-color: #ffffff;
+ border-color: #bdbdbd;
+ color: #212121;
}
-.inputbox:-moz-placeholder {
- color: #333333;
+.inputbox:-moz-placeholder,
+.inputbox::-webkit-input-placeholder {
+ color: #212121;
}
-.inputbox::-webkit-input-placeholder {
- color: #333333;
+.inputbox:hover,
+.inputbox:focus {
+ border-color: #13a4ec;
}
-.inputbox:hover {
- border-color: #11A3EA;
+.inputbox:focus:-moz-placeholder,
+.inputbox:focus::-webkit-input-placeholder {
+ color: transparent;
}
-.inputbox:focus {
- border-color: #11A3EA;
+input.disabled {
+ color: #616161;
}
-.inputbox:focus:-moz-placeholder {
- color: transparent;
+/* jquery popups */
+.phpbb_alert {
+ background-color: #ffffff;
+ border-color: #9e9e9e;
}
-.inputbox:focus::-webkit-input-placeholder {
- color: transparent;
+.darken {
+ background-color: #000000;
}
+/* stylelint-disable at-rule-no-vendor-prefix */
-/* Form button styles
----------------------------------------- */
+@-webkit-keyframes colors {
+ 0% {
+ stroke: #4285f4;
+ }
-a.button1, input.button1, input.button3, a.button2, input.button2 {
- color: #000;
- background-color: #EFEFEF; /* Old browsers */ /* FF3.6+ */
- background-image: -webkit-linear-gradient(top, #D2D2D2 0%, #EFEFEF 100%);
- background-image: linear-gradient(to bottom, #D2D2D2 0%,#EFEFEF 100%); /* W3C */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#D2D2D2', endColorstr='#EFEFEF',GradientType=0 ); /* IE6-9 */
-}
+ 25% {
+ stroke: #de3e35;
+ }
-a.button1, input.button1 {
- border-color: #666666;
-}
+ 50% {
+ stroke: #f7c223;
+ }
-input.button3 {
- background-image: none;
-}
+ 75% {
+ stroke: #1b9a59;
+ }
-/* Alternative button */
-a.button2, input.button2, input.button3 {
- border-color: #666666;
+ 100% {
+ stroke: #4285f4;
+ }
}
-/* <a> button in the style of the form buttons */
-a.button1, a.button2 {
- color: #000000;
-}
+/* stylelint-enable at-rule-no-vendor-prefix */
-/* Hover states */
-a.button1:hover, input.button1:hover, a.button2:hover, input.button2:hover, input.button3:hover {
- border-color: #D31141;
- color: #D31141;
- background-color: #D2D2D2; /* Old browsers */ /* FF3.6+ */
- background-image: -webkit-linear-gradient(top, #EFEFEF 0%, #D2D2D2 100%);
- background-image: linear-gradient(to bottom, #EFEFEF 0%,#D2D2D2 100%); /* W3C */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#EFEFEF', endColorstr='#D2D2D2',GradientType=0 ); /* IE6-9 */
-}
-/* Focus states */
-input.button1:focus, input.button2:focus, input.button3:focus {
- border-color: #11A3EA;
- color: #0F4987;
-}
+@keyframes colors {
+ 0% {
+ stroke: #4285f4;
+ }
-input.disabled {
- color: #666666;
-}
+ 25% {
+ stroke: #de3e35;
+ }
-/* jQuery popups
----------------------------------------- */
-.phpbb_alert {
- background-color: #FFFFFF;
- border-color: #999999;
-}
-.darken {
- background-color: #000000;
-}
+ 50% {
+ stroke: #f7c223;
+ }
-.loading_indicator {
- background-color: #000000;
- background-image: url("./images/loading.gif");
+ 75% {
+ stroke: #1b9a59;
+ }
+
+ 100% {
+ stroke: #4285f4;
+ }
}
-.dropdown-extended ul li {
- border-top-color: #B9B9B9;
+.dropdown-extended .dropdown-extended-item {
+ border-top-color: #bdbdbd;
}
-.dropdown-extended ul li:hover {
- background-color: #CFE1F6;
+.dropdown-extended .dropdown-extended-item:hover {
+ background-color: #d4e6f7;
color: #000000;
}
-.dropdown-extended .header, .dropdown-extended .footer {
- border-color: #B9B9B9;
+.dropdown-extended a.mark_read {
+ background-color: #ffffff;
+}
+
+.dropdown-extended .header,
+.dropdown-extended .footer {
+ border-color: #bdbdbd;
color: #000000;
}
.dropdown-extended .footer {
- border-top-style: solid;
border-top-width: 1px;
+ border-top-style: solid;
}
.dropdown-extended .header {
- background-color: #F1F8FF; /* Old browsers */ /* FF3.6+ */
- background-image: -webkit-linear-gradient(top, #F1F8FF 0%, #CADCEB 100%);
- background-image: linear-gradient(to bottom, #F1F8FF 0%,#CADCEB 100%); /* W3C */
- filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#F1F8FF', endColorstr='#CADCEB',GradientType=0 ); /* IE6-9 */
+ background-color: #e6f7ff;
+ background-image: -webkit-gradient(linear, left top, left bottom, from(#e6f7ff), to(#c9dee8));
+ background-image: linear-gradient(to bottom, #e6f7ff 0%, #c9dee8 100%);
}
.dropdown .pointer {
- border-color: #B9B9B9 transparent;
+ border-color: #bdbdbd transparent;
}
.dropdown .pointer-inner {
- border-color: #FFF transparent;
+ border-color: #ffffff transparent;
}
-.dropdown-extended .pointer-inner {
- border-color: #F1F8FF transparent;
+.dropdown-extended-pointer .pointer-inner {
+ border-color: #e6f7ff transparent;
}
.dropdown .dropdown-contents {
- background: #fff;
- border-color: #B9B9B9;
+ background: #ffffff;
+ border-color: #bdbdbd;
+ -webkit-box-shadow: 1px 3px 5px rgba(0, 0, 0, 0.2);
box-shadow: 1px 3px 5px rgba(0, 0, 0, 0.2);
}
.dropdown-up .dropdown-contents {
+ -webkit-box-shadow: 1px 0 5px rgba(0, 0, 0, 0.2);
box-shadow: 1px 0 5px rgba(0, 0, 0, 0.2);
}
-.dropdown li, .dropdown li li {
- border-color: #DCDCDC;
+.dropdown li,
+.dropdown li li {
+ border-color: #dedede;
}
.dropdown li.separator {
- border-color: #DCDCDC;
+ border-color: #dedede;
}
-/* Notifications
----------------------------------------- */
-
-.notification_list p.notification-time {
- color: #4C5D77;
+/* notifications */
+.notification-time {
+ color: #47536b;
}
-li.notification-reported strong, li.notification-disapproved strong {
- color: #D31141;
+.notification-reported strong,
+.notification-disapproved strong {
+ color: #d41142;
}
.badge {
- background-color: #D31141;
+ background-color: #d41142;
color: #ffffff;
}
diff --git a/phpBB/styles/prosilver/theme/common.css b/phpBB/styles/prosilver/theme/common.css
index eb04c66223..54048d500b 100644
--- a/phpBB/styles/prosilver/theme/common.css
+++ b/phpBB/styles/prosilver/theme/common.css
@@ -1,64 +1,69 @@
-/* General Markup Styles
----------------------------------------- */
+/* -------------------------------------------------------------- /*
+ $Common
+/* -------------------------------------------------------------- */
+/* stylelint-disable selector-max-compound-selectors */
+/* stylelint-disable selector-no-qualifying-type */
+
html {
font-size: 100%;
+
/* Always show a scrollbar for short pages - stops the jump when the scrollbar appears. non-IE browsers */
height: 101%;
}
body {
font-family: Verdana, Helvetica, Arial, sans-serif;
- font-size: 10px;
+ font-size: 16px;
line-height: normal;
+ word-wrap: break-word;
margin: 0;
padding: 12px 0;
- word-wrap: break-word;
-webkit-print-color-adjust: exact;
}
h1 {
/* Forum name */
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
- margin-right: 200px;
- margin-top: 15px;
+ font-size: 20px;
font-weight: bold;
- font-size: 2em;
+ margin-top: 15px;
+ margin-right: 200px;
}
h2 {
/* Forum header titles */
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
+ font-size: 20px;
font-weight: normal;
- font-size: 2em;
- margin: 0.8em 0 0.2em 0;
+ margin: 0.8em 0 0.2em;
}
h2.solo {
- margin-bottom: 1em;
+ margin-bottom: 20px;
}
h3 {
/* Sub-headers (also used as post headers, but defined later) */
font-family: Arial, Helvetica, sans-serif;
+ font-size: 12px;
font-weight: bold;
text-transform: uppercase;
border-bottom: 1px solid transparent;
+ margin-top: 20px;
margin-bottom: 3px;
padding-bottom: 2px;
- font-size: 1.05em;
- margin-top: 20px;
}
h4 {
/* Forum and topic list titles */
- font-family: "Trebuchet MS", Verdana, Helvetica, Arial, Sans-serif;
- font-size: 1.3em;
+ font-family: "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif;
+ font-size: 13px;
}
p {
- line-height: 1.3em;
- font-size: 1.1em;
- margin-bottom: 1.5em;
+ font-size: 11px;
+ line-height: 14px;
+ margin-bottom: 16px;
}
img {
@@ -68,10 +73,10 @@ img {
hr {
border: 0 solid transparent;
border-top-width: 1px;
- height: 1px;
- margin: 5px 0;
display: block;
clear: both;
+ height: 1px;
+ margin: 5px 0;
}
hr.dashed {
@@ -88,12 +93,13 @@ p.right {
}
p.jumpbox-return {
+ float: left;
margin-top: 10px;
margin-bottom: 0;
- float: left;
}
-b, strong {
+b,
+strong {
font-weight: bold;
}
@@ -101,7 +107,8 @@ b, strong {
font-weight: bold;
}
-i, em {
+i,
+em {
font-style: italic;
}
@@ -125,36 +132,36 @@ li {
display: list-item;
}
-ul ul, ol ul {
+ul ul,
+ol ul {
list-style-type: circle;
}
-ol ol ul, ol ul ul, ul ol ul, ul ul ul {
+ol ol ul,
+ol ul ul,
+ul ol ul,
+ul ul ul {
list-style-type: square;
}
-a:hover { text-decoration: underline; }
+a:hover {
+ text-decoration: underline;
+}
/* Main blocks
---------------------------------------- */
.wrap {
border: 1px solid transparent;
border-radius: 8px;
- margin: 0 auto;
- max-width: 1152px;
min-width: 625px;
+ max-width: 1152px;
+ margin: 0 auto;
padding: 15px;
}
-@media only screen and (max-width: 1220px), only screen and (max-device-width: 1220px) {
- .wrap {
- margin: 0 12px;
- }
-}
-
.page-body {
- margin: 4px 0;
clear: both;
+ margin: 4px 0;
}
.page-footer {
@@ -195,51 +202,51 @@ a:hover { text-decoration: underline; }
/* Round cornered boxes and backgrounds
---------------------------------------- */
.headerbar {
+ border-radius: 7px;
margin-bottom: 4px;
padding: 5px;
- border-radius: 7px;
}
.navbar {
- padding: 3px 10px;
border-radius: 7px;
+ padding: 3px 10px;
}
.forabg {
+ border-radius: 7px;
+ clear: both;
margin-bottom: 4px;
padding: 5px;
- clear: both;
- border-radius: 7px;
}
.forumbg {
+ border-radius: 7px;
+ clear: both;
margin-bottom: 4px;
padding: 5px;
- clear: both;
- border-radius: 7px;
}
.panel {
+ border-radius: 7px;
margin-bottom: 4px;
padding: 5px 10px;
- border-radius: 7px;
}
.post {
- padding: 5px 10px;
- margin-bottom: 4px;
background-repeat: no-repeat;
background-position: 100% 0;
border-radius: 7px;
position: relative;
+ margin-bottom: 4px;
+ padding: 5px 10px;
}
.rowbg {
- margin: 5px 5px 2px 5px;
+ margin: 5px 5px 2px;
}
/* Horizontal lists
-----------------------------------------*/
+---------------------------------------- */
.navbar ul.linklist {
padding: 2px 0;
list-style-type: none;
@@ -255,20 +262,22 @@ ul.linklist {
}
ul.linklist > li {
+ font-size: 11px;
+ line-height: 24px;
float: left;
- font-size: 1.1em;
- line-height: 2.2em;
- list-style-type: none;
+ width: auto;
margin-right: 7px;
padding-top: 1px;
- width: auto;
+ list-style-type: none;
}
-ul.linklist > li.rightside, p.rightside, a.rightside {
+ul.linklist > li.rightside,
+p.rightside,
+a.rightside {
+ text-align: right;
float: right;
margin-right: 0;
margin-left: 7px;
- text-align: right;
}
ul.navlinks {
@@ -276,17 +285,17 @@ ul.navlinks {
}
ul.leftside {
+ text-align: left;
float: left;
- margin-left: 0;
margin-right: 5px;
- text-align: left;
+ margin-left: 0;
}
ul.rightside {
+ text-align: right;
float: right;
- margin-left: 5px;
margin-right: -5px;
- text-align: right;
+ margin-left: 5px;
}
ul.linklist li.responsive-menu {
@@ -294,7 +303,8 @@ ul.linklist li.responsive-menu {
margin: 0 5px 0 0;
}
-.hasjs ul.linklist.leftside, .hasjs ul.linklist.rightside {
+.hasjs ul.linklist.leftside,
+.hasjs ul.linklist.rightside {
max-width: 48%;
}
@@ -315,18 +325,18 @@ ul.linklist .dropdown {
}
ul.linklist .dropdown-up .dropdown {
- bottom: 18px;
top: auto;
+ bottom: 18px;
}
/* Bulletin icons for list items
-----------------------------------------*/
+---------------------------------------- */
ul.linklist.bulletin > li:before {
- display: inline-block;
- content: "\2022";
font-size: inherit;
line-height: inherit;
+ display: inline-block;
padding-right: 4px;
+ content: "\2022";
}
ul.linklist.bulletin > li:first-child:before,
@@ -344,8 +354,8 @@ ul.linklist.bulletin > li.no-bulletin:before {
/* Profile in overall_header.html */
.header-profile {
- display: inline-block;
vertical-align: top;
+ display: inline-block;
}
a.header-avatar,
@@ -354,23 +364,23 @@ a.header-avatar:hover {
}
a.header-avatar img {
- margin-bottom: 2px;
- max-height: 20px;
vertical-align: middle;
width: auto;
+ max-height: 20px;
+ margin-bottom: 2px;
}
a.header-avatar span:after {
- content: '\f0dd';
- display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
- padding-left: 6px;
- padding-top: 2px;
vertical-align: top;
+ display: inline-block;
+ padding-top: 2px;
+ padding-left: 6px;
+ content: "\f0dd";
}
/* Dropdown menu
-----------------------------------------*/
+---------------------------------------- */
.dropdown-container {
position: relative;
}
@@ -388,15 +398,15 @@ a.header-avatar span:after {
}
.dropdown {
- display: none;
- position: absolute;
- left: 0;
- top: 1.2em;
- z-index: 2;
border: 1px solid transparent;
border-radius: 5px;
- padding: 9px 0 0;
+ position: absolute;
+ z-index: 2;
+ top: 1.2em;
+ left: 0;
+ display: none;
margin-right: -500px;
+ padding: 9px 0 0;
}
.dropdown.live-search {
@@ -413,11 +423,12 @@ a.header-avatar span:after {
padding: 0 0 9px;
}
-.dropdown-left .dropdown, .nojs .rightside .dropdown {
- left: auto;
+.dropdown-left .dropdown,
+.nojs .rightside .dropdown {
right: 0;
- margin-left: -500px;
+ left: auto;
margin-right: 0;
+ margin-left: -500px;
}
.dropdown-button-control .dropdown {
@@ -429,38 +440,42 @@ a.header-avatar span:after {
bottom: 24px;
}
-.dropdown .pointer, .dropdown .pointer-inner {
- position: absolute;
- width: 0;
- height: 0;
+.dropdown .pointer,
+.dropdown .pointer-inner {
border-top-width: 0;
+ border-right: 10px dashed transparent;
border-bottom: 10px solid transparent;
border-left: 10px dashed transparent;
- border-right: 10px dashed transparent;
- -webkit-transform: rotate(360deg); /* better anti-aliasing in webkit */
+ position: absolute;
display: block;
+ width: 0;
+ height: 0;
+ -webkit-transform: rotate(360deg); /* better anti-aliasing in webkit */
+ transform: rotate(360deg);
}
-.dropdown-up .pointer, .dropdown-up .pointer-inner {
- border-bottom-width: 0;
+.dropdown-up .pointer,
+.dropdown-up .pointer-inner {
border-top: 10px solid transparent;
+ border-bottom-width: 0;
}
.dropdown .pointer {
+ z-index: 3;
+ top: -1px;
right: auto;
left: 10px;
- top: -1px;
- z-index: 3;
}
.dropdown-up .pointer {
- bottom: -1px;
top: auto;
+ bottom: -1px;
}
-.dropdown-left .dropdown .pointer, .nojs .rightside .dropdown .pointer {
- left: auto;
+.dropdown-left .dropdown .pointer,
+.nojs .rightside .dropdown .pointer {
right: 10px;
+ left: auto;
}
.dropdown .pointer-inner {
@@ -470,19 +485,19 @@ a.header-avatar span:after {
}
.dropdown-up .pointer-inner {
- bottom: auto;
top: -11px;
+ bottom: auto;
}
.dropdown .dropdown-contents {
- z-index: 2;
- overflow: hidden;
- overflow-y: auto;
border: 1px solid transparent;
border-radius: 5px;
- padding: 5px;
position: relative;
+ z-index: 2;
+ overflow: hidden;
+ overflow-y: auto;
max-height: 300px;
+ padding: 5px;
}
.dropdown-contents a {
@@ -498,13 +513,9 @@ a.header-avatar span:after {
border-top: 1px solid transparent;
}
-.jumpbox .dropdown-select {
- margin: 0;
-}
-
.jumpbox .dropdown-contents {
- padding: 0;
text-decoration: none;
+ padding: 0;
}
.jumpbox .dropdown-contents li {
@@ -512,44 +523,35 @@ a.header-avatar span:after {
}
.jumpbox .dropdown-contents a {
- margin-right: 20px;
- padding: 5px 10px;
text-decoration: none;
width: 100%;
+ margin-right: 20px;
+ padding: 5px 10px;
}
.jumpbox .spacer {
display: inline-block;
- width: 0px;
+ width: 0;
}
.jumpbox .spacer + .spacer {
width: 20px;
}
-.dropdown-contents a {
- display: block;
- padding: 5px;
-}
-
.jumpbox .dropdown-select {
margin: 0;
}
-.jumpbox .dropdown-contents a {
- text-decoration: none;
-}
-
.dropdown li {
- display: list-item;
+ font-size: 11px !important;
+ line-height: normal !important;
+ text-align: left;
+ white-space: nowrap;
border-top: 1px dotted transparent;
+ display: list-item;
float: none !important;
- line-height: normal !important;
- font-size: 1em !important;
- list-style: none;
margin: 0;
- white-space: nowrap;
- text-align: left;
+ list-style: none;
}
.dropdown-contents > li {
@@ -560,7 +562,9 @@ a.header-avatar span:after {
padding-right: 0;
}
-.dropdown li:first-child, .dropdown li.separator + li, .dropdown li li {
+.dropdown li:first-child,
+.dropdown li.separator + li,
+.dropdown li li {
border-top: 0;
}
@@ -577,7 +581,9 @@ a.header-avatar span:after {
padding-left: 18px;
}
-.wrap .dropdown li, .dropdown.wrap li, .dropdown-extended li {
+.wrap .dropdown li,
+.dropdown.wrap li,
+.dropdown-extended li {
white-space: normal;
}
@@ -586,22 +592,23 @@ a.header-avatar span:after {
padding: 0;
}
-.dropdown li.separator:first-child, .dropdown li.separator:last-child {
+.dropdown li.separator:first-child,
+.dropdown li.separator:last-child {
display: none !important;
}
/* Responsive breadcrumbs
-----------------------------------------*/
+---------------------------------------- */
.breadcrumbs .crumb {
- float: left;
font-weight: bold;
word-wrap: normal;
+ float: left;
}
.breadcrumbs .crumb:before {
- content: '\2039';
font-weight: bold;
padding: 0 0.5em;
+ content: "\2039";
}
.breadcrumbs .crumb:first-child:before {
@@ -609,24 +616,46 @@ a.header-avatar span:after {
}
.breadcrumbs .crumb a {
+ vertical-align: bottom;
white-space: nowrap;
text-overflow: ellipsis;
- vertical-align: bottom;
overflow: hidden;
}
-.breadcrumbs.wrapped .crumb a { letter-spacing: -.3px; }
-.breadcrumbs.wrapped .crumb.wrapped-medium a { letter-spacing: -.4px; }
-.breadcrumbs.wrapped .crumb.wrapped-tiny a { letter-spacing: -.5px; }
+.breadcrumbs.wrapped .crumb a {
+ letter-spacing: -0.019em;
+}
-.breadcrumbs .crumb.wrapped-max a { max-width: 120px; }
-.breadcrumbs .crumb.wrapped-wide a { max-width: 100px; }
-.breadcrumbs .crumb.wrapped-medium a { max-width: 80px; }
-.breadcrumbs .crumb.wrapped-small a { max-width: 60px; }
-.breadcrumbs .crumb.wrapped-tiny a { max-width: 40px; }
+.breadcrumbs.wrapped .crumb.wrapped-medium a {
+ letter-spacing: -0.025em;
+}
+
+.breadcrumbs.wrapped .crumb.wrapped-tiny a {
+ letter-spacing: -0.031em;
+}
+
+.breadcrumbs .crumb.wrapped-max a {
+ max-width: 120px;
+}
+
+.breadcrumbs .crumb.wrapped-wide a {
+ max-width: 100px;
+}
+
+.breadcrumbs .crumb.wrapped-medium a {
+ max-width: 80px;
+}
+
+.breadcrumbs .crumb.wrapped-small a {
+ max-width: 60px;
+}
+
+.breadcrumbs .crumb.wrapped-tiny a {
+ max-width: 40px;
+}
/* Table styles
-----------------------------------------*/
+---------------------------------------- */
table.table1 {
width: 100%;
}
@@ -636,10 +665,10 @@ table.table1 {
}
table.table1 thead th {
+ font-size: 10px;
font-weight: normal;
+ line-height: 13px;
text-transform: uppercase;
- line-height: 1.3em;
- font-size: 1em;
padding: 0 0 4px 3px;
}
@@ -652,32 +681,72 @@ table.table1 tbody tr {
}
table.table1 td {
- font-size: 1.1em;
+ font-size: 11px;
}
table.table1 tbody td {
- padding: 5px;
border-top: 1px solid transparent;
+ padding: 5px;
}
table.table1 tbody th {
- padding: 5px;
- border-bottom: 1px solid transparent;
text-align: left;
+ border-bottom: 1px solid transparent;
+ padding: 5px;
}
/* Specific column styles */
-table.table1 .name { text-align: left; }
-table.table1 .center { text-align: center; }
-table.table1 .reportby { width: 15%; }
-table.table1 .posts { text-align: center; width: 7%; }
-table.table1 .joined { text-align: left; width: 15%; }
-table.table1 .active { text-align: left; width: 15%; }
-table.table1 .mark { text-align: center; width: 7%; }
-table.table1 .info { text-align: left; width: 30%; }
-table.table1 .info div { width: 100%; white-space: normal; overflow: hidden; }
-table.table1 .autocol { line-height: 2em; white-space: nowrap; }
-table.table1 thead .autocol { padding-left: 1em; }
+table.table1 .name {
+ text-align: left;
+}
+
+table.table1 .center {
+ text-align: center;
+}
+
+table.table1 .reportby {
+ width: 15%;
+}
+
+table.table1 .posts {
+ text-align: center;
+ width: 7%;
+}
+
+table.table1 .joined {
+ text-align: left;
+ width: 15%;
+}
+
+table.table1 .active {
+ text-align: left;
+ width: 15%;
+}
+
+table.table1 .mark {
+ text-align: center;
+ width: 7%;
+}
+
+table.table1 .info {
+ text-align: left;
+ width: 30%;
+}
+
+table.table1 .info div {
+ white-space: normal;
+ overflow: hidden;
+ width: 100%;
+}
+
+table.table1 .autocol {
+ line-height: 22px;
+ white-space: nowrap;
+}
+
+table.table1 thead .autocol {
+ padding-left: 10px;
+}
table.table1 span.rank-img {
float: right;
@@ -689,10 +758,10 @@ table.info td {
}
table.info tbody th {
- padding: 3px;
+ font-weight: normal;
text-align: right;
vertical-align: top;
- font-weight: normal;
+ padding: 3px;
}
.forumbg table.table1 {
@@ -704,12 +773,13 @@ table.info tbody th {
}
.color_palette_placeholder table {
- border-collapse: separate;
border-spacing: 1px;
+ border-collapse: separate;
}
/* Misc layout styles
---------------------------------------- */
+
/* column[1-2] styles are containers for two column layouts */
.column1 {
float: left;
@@ -725,9 +795,9 @@ table.info tbody th {
/* General classes for placing floating blocks */
.left-box {
+ text-align: left;
float: left;
width: auto;
- text-align: left;
max-width: 100%;
}
@@ -736,53 +806,56 @@ table.info tbody th {
}
.right-box {
+ text-align: right;
float: right;
width: auto;
- text-align: right;
max-width: 100%;
}
dl.details {
- /*font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif;*/
- font-size: 1.1em;
+ font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif;
+ font-size: 11px;
}
dl.details dt {
+ text-align: right;
+ display: block;
float: left;
clear: left;
width: 30%;
- text-align: right;
- display: block;
}
dl.details dd {
- margin-left: 0;
- padding-left: 5px;
- margin-bottom: 5px;
+ text-overflow: ellipsis;
float: left;
- width: 65%;
overflow: hidden;
- text-overflow: ellipsis;
+ width: 65%;
+ margin-bottom: 5px;
+ margin-left: 0;
+ padding-left: 5px;
}
-.clearfix, fieldset dl, ul.topiclist dl, dl.polls {
+.clearfix,
+fieldset dl,
+ul.topiclist dl,
+dl.polls {
overflow: hidden;
}
fieldset.fields1 ul.recipients {
- list-style-type: none;
line-height: 1.8;
- max-height: 150px;
overflow-y: auto;
+ max-height: 150px;
+ list-style-type: none;
}
fieldset.fields1 dd.recipients {
clear: left;
- margin-left: 1em;
+ margin-left: 11px;
}
-fieldset.fields1 ul.recipients input.button2{
- font-size: 0.8em;
+fieldset.fields1 ul.recipients input.button2 {
+ font-size: 12px;
margin-right: 0;
padding: 0;
}
@@ -803,12 +876,12 @@ fieldset.fields1 dl.pmlist dd.recipients {
}
.forabg + .action-bar {
- margin-top: 2em;
+ margin-top: 12px;
}
.action-bar .button {
- margin-right: 5px;
float: left;
+ margin-right: 5px;
}
.action-bar .button-search {
@@ -818,8 +891,8 @@ fieldset.fields1 dl.pmlist dd.recipients {
/* Pagination
---------------------------------------- */
.pagination {
- float: right;
text-align: right;
+ float: right;
width: auto;
}
@@ -828,39 +901,40 @@ fieldset.fields1 dl.pmlist dd.recipients {
}
.action-bar .pagination .button {
- margin-right: 0;
float: none;
+ margin-right: 0;
}
.pagination > ul {
display: inline-block;
- list-style: none !important;
margin-left: 5px;
+ list-style: none;
}
.pagination > ul > li {
- display: inline-block !important;
- padding: 0;
font-size: 100%;
line-height: normal;
vertical-align: middle;
+ display: inline-block;
+ padding: 0;
}
-.pagination li a, .pagination li span {
+.pagination li a,
+.pagination li span {
border-radius: 2px;
padding: 2px 5px;
}
.pagination li.active span {
- display: inline-block;
+ font-family: "Open Sans", "Droid Sans", Verdana, Arial, Helvetica;
font-size: 13px;
font-weight: normal;
- font-family: "Open Sans", "Droid Sans", Verdana, Arial, Helvetica;
line-height: 1.4;
text-align: center;
- white-space: nowrap;
vertical-align: middle;
+ white-space: nowrap;
border: 1px solid transparent;
+ display: inline-block;
}
.pagination li.ellipsis span {
@@ -878,6 +952,7 @@ fieldset.fields1 dl.pmlist dd.recipients {
.pagination li.page-jump a i {
font-size: 21px;
+ line-height: 21px;
}
.pagination .arrow a {
@@ -895,38 +970,32 @@ fieldset.fields1 dl.pmlist dd.recipients {
margin: 0;
}
-.row .pagination li a, .row .pagination li span {
+.row .pagination li a,
+.row .pagination li span {
+ font-size: 9px;
border-radius: 2px;
padding: 1px 3px;
- font-size: 9px;
}
/* jQuery popups
---------------------------------------- */
.phpbb_alert {
border: 1px solid transparent;
- display: none;
- left: 0;
- padding: 0 25px 20px 25px;
position: fixed;
- right: 0;
- top: 150px;
z-index: 50;
+ top: 150px;
+ right: 0;
+ left: 0;
+ display: none;
width: 620px;
margin: 0 auto;
-}
-
-@media only screen and (max-height: 500px), only screen and (max-device-width: 500px)
-{
- .phpbb_alert {
- top: 25px;
- }
+ padding: 0 25px 20px;
}
.phpbb_alert .alert_close {
float: right;
- margin-right: -36px;
margin-top: -8px;
+ margin-right: -36px;
}
.phpbb_alert p {
@@ -945,40 +1014,118 @@ fieldset.fields1 dl.pmlist dd.recipients {
.phpbb_alert div.alert_text > select,
.phpbb_alert div.alert_text > textarea,
.phpbb_alert div.alert_text > input {
- font-size: 1.1em;
+ font-size: 11px;
}
.darkenwrapper {
- display: none;
position: relative;
z-index: 44;
+ display: none;
}
.darken {
+ opacity: 0.5;
position: fixed;
- left: 0;
+ z-index: 45;
top: 0;
+ left: 0;
width: 100%;
height: 100%;
- opacity: 0.5;
- z-index: 45;
}
.loading_indicator {
- background: center center no-repeat;
- border-radius: 5px;
- display: none;
- opacity: 0.8;
- margin-top: -50px;
- margin-left: -50px;
- height: 50px;
- width: 50px;
position: fixed;
- left: 50%;
- top: 50%;
z-index: 51;
+ top: 50%;
+ left: 50%;
+ display: none;
+}
+
+.loader {
+ width: 48px;
+ height: 48px;
+ padding: 12px;
+}
+
+.spinner {
+ -webkit-animation: rotator 1s linear infinite;
+ animation: rotator 1s linear infinite;
}
+/* stylelint-disable no-unknown-animations */
+.spinner-path {
+ -webkit-transform-origin: center;
+ transform-origin: center;
+ -webkit-animation: dash 1s ease-in-out infinite, colors 4s ease-in-out infinite;
+ animation: dash 1s ease-in-out infinite, colors 4s ease-in-out infinite;
+ stroke-dasharray: 187;
+ stroke-dashoffset: 0;
+}
+/* stylelint-enable no-unknown-animations */
+
+/* stylelint-disable at-rule-no-vendor-prefix */
+@-webkit-keyframes rotator {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ -webkit-transform: rotate(270deg);
+ transform: rotate(270deg);
+ }
+}
+
+@keyframes rotator {
+ 0% {
+ -webkit-transform: rotate(0deg);
+ transform: rotate(0deg);
+ }
+
+ 100% {
+ -webkit-transform: rotate(270deg);
+ transform: rotate(270deg);
+ }
+}
+
+@-webkit-keyframes dash {
+ 0% {
+ stroke-dashoffset: 187;
+ }
+
+ 50% {
+ -webkit-transform: rotate(135deg);
+ transform: rotate(135deg);
+ stroke-dashoffset: 46.75;
+ }
+
+ 100% {
+ -webkit-transform: rotate(450deg);
+ transform: rotate(450deg);
+ stroke-dashoffset: 187;
+ }
+}
+
+@keyframes dash {
+ 0% {
+ stroke-dashoffset: 187;
+ }
+
+ 50% {
+ -webkit-transform: rotate(135deg);
+ transform: rotate(135deg);
+ stroke-dashoffset: 46.75;
+ }
+
+ 100% {
+ -webkit-transform: rotate(450deg);
+ transform: rotate(450deg);
+ stroke-dashoffset: 187;
+ }
+}
+/* stylelint-enable at-rule-no-vendor-prefix */
+
+
/* Miscellaneous styles
---------------------------------------- */
.copyright {
@@ -994,7 +1141,7 @@ fieldset.fields1 dl.pmlist dd.recipients {
}
.small {
- font-size: 0.9em !important;
+ font-size: 90% !important;
}
.titlespace {
@@ -1006,26 +1153,27 @@ fieldset.fields1 dl.pmlist dd.recipients {
}
.error {
+ font-size: 10px;
font-weight: bold;
- font-size: 1em;
}
div.rules {
+ font-size: 11px;
+ border-radius: 7px;
margin: 10px 0;
- font-size: 1.1em;
padding: 5px 10px;
- border-radius: 7px;
}
-div.rules ul, div.rules ol {
+div.rules ul,
+div.rules ol {
margin-left: 20px;
}
p.post-notice {
position: relative;
- padding: 5px;
min-height: 14px;
- margin-bottom: 1em;
+ margin-bottom: 11px;
+ padding: 5px;
}
form > p.post-notice strong {
@@ -1037,39 +1185,41 @@ form > p.post-notice strong {
}
.top-anchor {
- display: block;
position: absolute;
top: -20px;
+ display: block;
}
.clear {
- display: block;
- clear: both;
font-size: 1px;
line-height: 1px;
background: transparent;
+ display: block;
+ clear: both;
}
/* Inner box-model clearing */
.inner:after,
ul.linklist:after,
.action-bar:after,
-.notification_text:after,
+.notification-text:after,
.tabs-container:after,
.tabs > ul:after,
.minitabs > ul:after,
.postprofile .avatar-container:after {
- clear: both;
- content: '';
display: block;
+ clear: both;
+ content: "";
}
+/* stylelint-disable declaration-property-unit-whitelist */
.emoji {
- min-height: 18px;
+ width: 1em;
min-width: 18px;
height: 1em;
- width: 1em;
+ min-height: 18px;
}
+/* stylelint-enable declaration-property-unit-whitelist */
.smilies {
vertical-align: text-bottom;
@@ -1086,45 +1236,44 @@ ul.linklist:after,
}
.member-search strong {
- font-size: 0.95em;
+ font-size: 11px;
}
.dropdown-extended {
- display: none;
z-index: 1;
+ display: none;
}
-.dropdown-extended ul {
- max-height: 350px;
- overflow-y: auto;
- overflow-x: hidden;
+.dropdown-extended .dropdown-extended-list {
clear: both;
+ overflow-x: hidden;
+ overflow-y: auto;
+ max-height: 350px;
}
-.dropdown-extended ul li {
- padding: 0;
- margin: 0 !important;
- float: none;
+.dropdown-extended .dropdown-extended-item {
border-top: 1px solid;
- list-style-type: none;
- font-size: 0.95em;
- clear: both;
position: relative;
+ float: none;
+ clear: both;
+ margin: 0 !important;
+ padding: 0;
+ list-style-type: none;
}
-.dropdown-extended ul li:first-child {
+.dropdown-extended .dropdown-extended-item:first-child {
border-top: none;
}
-.dropdown-extended ul li.no_notifications {
+.dropdown-extended .dropdown-extended-item.no-notifications {
padding: 10px;
}
.dropdown-extended .dropdown-contents {
- max-height: none;
- padding: 0;
position: absolute;
width: 340px;
+ max-height: none;
+ padding: 0;
}
.nojs .dropdown-extended .dropdown-contents {
@@ -1132,40 +1281,43 @@ ul.linklist:after,
}
.dropdown-extended .header {
- padding: 0 10px;
font-family: Arial, "Helvetica Neue", Helvetica, Arial, sans-serif;
font-weight: bold;
+ line-height: 33px;
text-align: left;
- text-shadow: 1px 1px 1px white;
text-transform: uppercase;
- line-height: 3em;
border-bottom: 1px solid;
border-radius: 5px 5px 0 0;
+
+ /* needs moved to colurs.css */
+ text-shadow: 1px 1px 1px #ffffff;
+ padding: 0 10px;
}
-.dropdown-extended .header .header_settings {
- float: right;
+.dropdown-extended .header .header-settings {
font-weight: normal;
text-transform: none;
+ float: right;
}
-.dropdown-extended .header .header_settings a {
+.dropdown-extended .header .header-settings a {
display: inline-block;
padding: 0 5px;
}
.dropdown-extended .header:after {
- content: '';
display: table;
clear: both;
+ content: "";
}
.dropdown-extended .footer {
+ font-size: 12px;
text-align: center;
- font-size: 1.1em;
}
-.dropdown-extended ul li a, .dropdown-extended ul li.no-url {
+.dropdown-extended .notification-block,
+.dropdown-extended .dropdown-extended-item.no-url {
padding: 8px;
}
@@ -1173,78 +1325,79 @@ ul.linklist:after,
padding: 5px 0;
}
-.dropdown-extended ul li a, .notification_list dt > a, .dropdown-extended .footer > a {
- display: block;
+.dropdown-extended .dropdown-extended-item a,
+.notification-menu dt > a,
+.dropdown-extended .footer > a {
text-decoration: none;
+ display: block;
}
-.notification_list ul li img {
+.notification-avatar,
+.notification-menu .notification-list .notification-item .avatar,
+.notification-menu .notification-list .notification-item .gravatar {
float: left;
- max-height: 50px;
- max-width: 50px;
width: auto !important;
+ max-width: 50px;
height: auto !important;
+ max-height: 50px;
margin-right: 5px;
}
-.notification_list ul li p {
+.notification-item p {
margin-bottom: 4px;
- font-size: 1em;
}
-.notification_list p.notification-reference,
-.notification_list p.notification-location,
-.notification_list li a p.notification-reason {
- overflow: hidden;
- text-overflow: ellipsis;
+.notification-reference,
+.notification-location,
+.notification-reason {
white-space: nowrap;
+ text-overflow: ellipsis;
+ overflow: hidden;
}
-.notification_list p.notification-time {
- font-size: 0.9em;
- margin: 0;
+.notification-time {
+ font-size: 10px;
text-align: right;
+ margin: 0;
}
-.notification_list div.notifications {
+.notification-menu .notifications {
margin-left: 50px;
padding: 5px;
}
-.notification_list div.notifications a {
+.notification-menu .notifications a {
display: block;
}
-.notification_list p.notifications_title {
+.notifications-title {
font-family: "Trebuchet MS", Arial, Helvetica, sans-serif;
- font-size: 1.2em !important;
+ font-size: 13px !important;
}
-.notification_list p.notifications_title strong {
+.notifications-title strong {
font-weight: bold;
}
-.notification_list p.notifications_time {
- font-size: 0.9em !important;
+.notifications-time {
+ font-size: 10px !important;
}
-.notification_text {
+.notification-text {
margin-left: 58px;
}
.badge {
- border-radius: 10px;
- opacity: 0.8;
- text-align: center;
- white-space: nowrap;
font-size: 10px;
line-height: 1;
- float: right;
- display: inline-block;
- margin-left: 3px;
- vertical-align: baseline;
+ text-align: center;
+ white-space: nowrap;
+ border-radius: 10px;
+ opacity: 0.8;
position: relative;
top: 3px;
+ float: right;
+ margin-left: 3px;
padding: 4px 6px;
}
@@ -1253,7 +1406,7 @@ ul.linklist:after,
}
/* Navbar specific list items
-----------------------------------------*/
+---------------------------------------- */
.linklist .quick-links {
margin: 0 7px 0 0;
@@ -1275,7 +1428,7 @@ ul.linklist:after,
width: 50px;
}
-.dropdown .clone.hidden {
+.dropdown .clone.hidden {
display: none;
}
@@ -1286,3 +1439,6 @@ ul.linklist:after,
.dropdown .clone.hidden + li {
border-top: none;
}
+
+/* stylelint-enable selector-max-compound-selectors */
+/* stylelint-enable selector-no-qualifying-type */
diff --git a/phpBB/styles/prosilver/theme/content.css b/phpBB/styles/prosilver/theme/content.css
index 807633864c..90c0b2b54b 100644
--- a/phpBB/styles/prosilver/theme/content.css
+++ b/phpBB/styles/prosilver/theme/content.css
@@ -1,16 +1,25 @@
-/* Content Styles
----------------------------------------- */
+/* -------------------------------------------------------------- /*
+ $Content
+/* -------------------------------------------------------------- */
+
+/* stylelint-disable selector-max-compound-selectors */
+/* stylelint-disable selector-no-qualifying-type */
+
+ul.forums,
+ul.topics {
+ border-radius: 4px;
+}
ul.topiclist {
display: block;
- list-style-type: none;
margin: 0;
+ list-style-type: none;
}
-ul.topiclist li {
+ul.topiclist > li {
display: block;
- list-style-type: none;
margin: 0;
+ list-style-type: none;
}
ul.topiclist dl {
@@ -21,15 +30,16 @@ ul.topiclist li.row dl {
margin: 2px 0;
}
-ul.topiclist dt, ul.topiclist dd {
+ul.topiclist dt,
+ul.topiclist dd {
display: block;
float: left;
}
ul.topiclist dt {
+ font-size: 11px;
width: 100%;
margin-right: -440px;
- font-size: 1.1em;
}
ul.topiclist.missing-column dt {
@@ -46,8 +56,8 @@ ul.topiclist.two-columns dt {
ul.topiclist dt .list-inner {
margin-right: 440px;
- padding-left: 5px;
padding-right: 5px;
+ padding-left: 5px;
}
ul.topiclist.missing-column dt .list-inner {
@@ -64,15 +74,14 @@ ul.topiclist.two-columns dt .list-inner {
ul.topiclist dd {
border-left: 1px solid transparent;
- padding: 4px 0;
-webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
box-sizing: border-box;
+ padding: 4px 0;
}
ul.topiclist li.row dd {
- padding: 4px 0 999px 0;
margin-bottom: -995px;
+ padding: 4px 0 999px;
}
ul.topiclist dfn {
@@ -84,8 +93,20 @@ ul.topiclist dfn {
.forum-image {
float: left;
- padding-top: 5px;
margin-right: 5px;
+ padding-top: 5px;
+}
+
+.forum-desc {
+ display: block;
+}
+
+.forum-mods {
+ display: block;
+}
+
+.forum-subs {
+ display: block;
}
li.row {
@@ -93,19 +114,34 @@ li.row {
border-bottom: 1px solid transparent;
}
+li.row:first-child {
+ border-top: 0;
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+ padding-top: 1px;
+}
+
+li.row:last-child {
+ border-bottom: 0;
+ border-bottom-right-radius: 4px;
+ border-bottom-left-radius: 4px;
+ margin-bottom: 1px;
+}
+
li.row strong {
font-weight: normal;
}
-li.header dt, li.header dd {
- line-height: 1em;
+li.header dt,
+li.header dd {
+ font-family: Arial, Helvetica, sans-serif;
+ font-size: 10px;
+ line-height: 10px;
+ text-transform: uppercase;
border-left-width: 0;
- margin: 2px 0 4px 0;
+ margin: 2px 0 4px;
padding-top: 2px;
padding-bottom: 2px;
- font-size: 1em;
- font-family: Arial, Helvetica, sans-serif;
- text-transform: uppercase;
}
li.header dt {
@@ -119,28 +155,29 @@ li.header dt .list-inner {
}
li.header dd {
- padding-left: 1px;
-webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
box-sizing: border-box;
+ padding-left: 1px;
}
-li.header dl.row-item dt, li.header dl.row-item dd {
+li.header dl.row-item dt,
+li.header dl.row-item dd {
min-height: 0;
}
li.header dl.row-item dt .list-inner {
+ padding-right: 50px;
+
/* Tweak for headers alignment when folder icon used */
padding-left: 0;
- padding-right: 50px;
}
/* Forum list column styles */
.row .list-inner { padding: 4px 0; }
dl.row-item {
- background-position: 10px 50%; /* Position of folder icon */
background-repeat: no-repeat;
+ background-position: 10px 50%; /* Position of folder icon */
background-size: 32px;
}
@@ -154,7 +191,8 @@ dl.row-item dt .list-inner {
padding-left: 52px; /* Space for folder icon */
}
-dl.row-item dt, dl.row-item dd {
+dl.row-item dt,
+dl.row-item dd {
min-height: 35px;
}
@@ -162,100 +200,117 @@ dl.row-item dt a {
display: inline;
}
-dl a.row-item-link { /* topic row icon links */
- display: block;
- width: 30px;
- height: 30px;
- padding: 0;
+/* topic row icon links */
+dl a.row-item-link {
position: absolute;
top: 50%;
left: 0;
+ display: block;
+ width: 30px;
+ height: 30px;
margin-top: -15px;
margin-left: 9px;
+ padding: 0;
}
-dd.posts, dd.topics, dd.views, dd.extra, dd.mark {
- width: 80px;
+dd.posts,
+dd.topics,
+dd.views,
+dd.extra,
+dd.mark {
+ font-size: 12px;
+ line-height: 26px;
text-align: center;
- line-height: 2.2em;
- font-size: 1.2em;
+ width: 80px;
}
-dd.posts, dd.topics, dd.views {
+dd.posts,
+dd.topics,
+dd.views {
width: 95px;
}
/* List in forum description */
dl.row-item dt ol,
dl.row-item dt ul {
+ margin-left: 10px;
list-style-position: inside;
- margin-left: 1em;
}
-dl.row-item dt li {
+dl.row-item dt > ul li {
display: list-item;
list-style-type: inherit;
}
-dd.lastpost, dd.redirect, dd.moderation, dd.time, dd.info {
+dd.lastpost,
+dd.redirect,
+dd.moderation,
+dd.time,
+dd.info {
+ font-size: 11px;
width: 250px;
- font-size: 1.1em;
}
dd.redirect {
- line-height: 2.5em;
+ line-height: 26px;
}
dd.time {
- line-height: 200%;
+ line-height: 22px;
}
-dd.lastpost > span, ul.topiclist dd.info > span, ul.topiclist dd.time > span, dd.redirect > span, dd.moderation > span {
+dd.lastpost > span,
+ul.topiclist dd.info > span,
+ul.topiclist dd.time > span,
+dd.redirect > span,
+dd.moderation > span {
display: block;
padding-left: 5px;
}
-dd.extra, dd.mark {
- line-height: 200%;
+dd.extra,
+dd.mark {
+ line-height: 24px;
}
dd.option {
- width: 125px;
- line-height: 200%;
+ font-size: 11px;
+ line-height: 22px;
text-align: center;
- font-size: 1.1em;
+ width: 125px;
}
/* Post body styles
-----------------------------------------*/
+---------------------------------------- */
.postbody {
- padding: 0;
- line-height: 1.48em;
- width: 76%;
- float: left;
+ line-height: 16px;
position: relative;
+ float: left;
+ width: 76%;
+ padding: 0;
}
.postbody .ignore {
- font-size: 1.1em;
+ font-size: 11px;
}
.postbody h3.first {
/* The first post on the page uses this */
- font-size: 1.7em;
+ font-size: 17px;
}
.postbody h3 {
+ font-family: "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif;
+ font-size: 15px;
+ line-height: 19px;
+ text-transform: none;
+ border: none;
+
/* Postbody requires a different h3 format - so change it here */
float: left;
- font-size: 1.5em;
- padding: 2px 0 0 0;
margin-top: 0 !important;
- margin-bottom: 0.3em !important;
- text-transform: none;
- border: none;
- font-family: "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif;
- line-height: 125%;
+ margin-bottom: 4px !important;
+ padding: 2px 0 0;
}
.postbody h3 img {
@@ -269,38 +324,37 @@ dd.option {
}
.postbody .content {
- font-size: 1.3em;
+ font-size: 13px;
overflow-x: auto;
}
.postbody img.postimage {
- max-width: 100%;
-webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
box-sizing: border-box;
+ max-width: 100%;
}
.search .postbody {
- width: 68%
+ width: 68%;
}
/* Topic review panel
-----------------------------------------*/
+---------------------------------------- */
.panel .review {
- margin-top: 2em;
+ margin-top: 20px;
}
.topicreview {
- padding-right: 5px;
overflow: auto;
height: 300px;
+ padding-right: 5px;
}
.topicreview .postbody {
- width: auto;
float: none;
- margin: 0;
+ width: auto;
height: auto;
+ margin: 0;
}
.topicreview .post {
@@ -316,7 +370,7 @@ dd.option {
}
/* MCP Post details
-----------------------------------------*/
+---------------------------------------- */
.post_details {
/* This will only work in IE7+, plus the others */
overflow: auto;
@@ -324,24 +378,25 @@ dd.option {
}
/* Content container styles
-----------------------------------------*/
+---------------------------------------- */
.content {
+ font-family: "Lucida Grande", "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif;
+ font-size: 13px;
+ line-height: 18px;
clear: both;
- min-height: 3em;
overflow: hidden;
- line-height: 1.4em;
- font-family: "Lucida Grande", "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif;
- font-size: 1em;
+ min-height: 30px;
padding-bottom: 1px;
}
-.content h2, .panel h2 {
+.content h2,
+.panel h2 {
+ font-size: 16px;
font-weight: normal;
border-bottom: 1px solid transparent;
- font-size: 1.6em;
- margin-top: 0.5em;
- margin-bottom: 0.5em;
- padding-bottom: 0.5em;
+ margin-top: 8px;
+ margin-bottom: 8px;
+ padding-bottom: 8px;
}
.panel h3 {
@@ -349,24 +404,21 @@ dd.option {
}
.panel p {
- font-size: 1.2em;
- margin-bottom: 1em;
- line-height: 1.4em;
+ font-size: 12px;
+ line-height: 16px;
+ margin-bottom: 12px;
}
.content p {
font-family: "Lucida Grande", "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif;
- font-size: 1.2em;
- margin-bottom: 1em;
- line-height: 1.4em;
}
dl.faq {
font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif;
- font-size: 1.1em;
- margin-top: 1em;
- margin-bottom: 2em;
- line-height: 1.4em;
+ font-size: 11px;
+ line-height: 15px;
+ margin-top: 11px;
+ margin-bottom: 22px;
}
dl.faq dt {
@@ -374,42 +426,43 @@ dl.faq dt {
}
.content dl.faq {
- font-size: 1.2em;
- margin-bottom: 0.5em;
+ font-size: 12px;
+ margin-bottom: 6px;
}
.content li {
list-style-type: inherit;
}
-.content ul, .content ol {
+.content ul,
+.content ol {
margin: 0.8em 0 0.9em 3em;
}
.posthilit {
- padding: 0 2px 1px 2px;
+ padding: 0 2px 1px;
}
/* Post author */
p.author {
- margin-bottom: 0.6em;
- padding: 0 0 5px 0;
font-family: Verdana, Helvetica, Arial, sans-serif;
- font-size: 1em;
- line-height: 1.2em;
+ font-size: 10px;
+ line-height: 12px;
clear: both;
+ margin-bottom: 8px;
+ padding: 0 0 5px;
}
/* Post signature */
.signature {
- margin-top: 1.5em;
- padding-top: 0.2em;
- font-size: 1.1em;
+ font-size: 11px;
+ line-height: 16px;
border-top: 1px solid transparent;
clear: left;
- line-height: 140%;
overflow: hidden;
width: 100%;
+ margin-top: 16px;
+ padding-top: 2px;
}
.signature.standalone {
@@ -418,75 +471,72 @@ p.author {
}
dd .signature {
+ border: none;
+ clear: none;
margin: 0;
padding: 0;
- clear: none;
- border: none;
}
.signature li {
list-style-type: inherit;
}
-.signature ul, .signature ol {
- margin: 0.8em 0 0.9em 3em;
+.signature ul,
+.signature ol {
+ margin: 10px 0 10px 33px;
}
/* Post noticies */
.notice {
font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif;
- width: auto;
- margin-top: 1.5em;
- padding-top: 0.2em;
- font-size: 1em;
+ font-size: 10px;
+ line-height: 13px;
border-top: 1px dashed transparent;
clear: left;
- line-height: 130%;
+ width: auto;
+ margin-top: 15px;
+ padding-top: 2px;
}
/* Jump to post link for now */
ul.searchresults {
- list-style: none;
text-align: right;
clear: both;
+ list-style: none;
}
/* BB Code styles
-----------------------------------------*/
+---------------------------------------- */
+
/* Quote block */
blockquote {
border: 1px solid transparent;
- font-size: 0.95em;
- margin: 1em 1px 1em 25px;
overflow: hidden;
+ margin: 10px 1px 10px 25px;
padding: 5px;
}
blockquote blockquote {
/* Nested quotes */
- font-size: 1em;
- margin: 1em 1px 1em 15px;
+ margin: 10px 1px 10px 15px;
}
blockquote cite {
+ font-weight: bold;
+
/* Username/source of quoter */
font-style: normal;
- font-weight: bold;
display: block;
- font-size: 0.9em;
-}
-
-blockquote cite cite {
- font-size: 1em;
}
-blockquote cite:before, .uncited:before {
+blockquote cite:before,
+.uncited:before {
padding-right: 5px;
}
blockquote cite > div {
- float: right;
font-weight: normal;
+ float: right;
}
.postbody .content li blockquote {
@@ -496,20 +546,20 @@ blockquote cite > div {
/* Code block */
.codebox {
- border: 1px solid transparent;
- font-size: 1em;
- margin: 1em 0 1.2em 0;
+ font-size: 13px;
word-wrap: normal;
+ border: 1px solid transparent;
+ margin: 13px 0 16px;
}
.codebox p {
+ font-size: 10px !important;
+ font-weight: bold;
text-transform: uppercase;
border-bottom: 1px solid transparent;
+ display: block;
margin-bottom: 0;
padding: 3px;
- font-size: 0.8em !important;
- font-weight: bold;
- display: block;
}
blockquote .codebox {
@@ -517,29 +567,28 @@ blockquote .codebox {
}
.codebox code {
- overflow: auto;
+ font: 12px Monaco, "Andale Mono", "Courier New", Courier, monospace;
+ line-height: 15px;
display: block;
+ overflow: auto;
height: auto;
max-height: 200px;
padding: 5px 3px;
- font: 0.9em Monaco, "Andale Mono","Courier New", Courier, monospace;
- line-height: 1.3em;
}
/* Attachments
-----------------------------------------*/
+---------------------------------------- */
.attachbox {
font-size: 13px;
+ border: 1px dashed transparent;
float: left;
+ clear: left;
+ -webkit-box-sizing: border-box;
+ box-sizing: border-box;
width: auto;
max-width: 100%;
margin: 5px 5px 5px 0;
padding: 6px;
- border: 1px dashed transparent;
- clear: left;
- -webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
- box-sizing: border-box;
}
.attachbox dt {
@@ -548,11 +597,11 @@ blockquote .codebox {
}
.attachbox dd {
- margin-top: 4px;
- padding-top: 4px;
- clear: left;
border-top: 1px solid transparent;
+ clear: left;
overflow-x: auto;
+ margin-top: 4px;
+ padding-top: 4px;
}
.attachbox dd dd {
@@ -560,31 +609,32 @@ blockquote .codebox {
}
.attachbox p {
- line-height: 110%;
font-weight: normal;
+ line-height: 12px;
clear: left;
}
-.attachbox p.stats
-{
- line-height: 110%;
+.attachbox p.stats {
font-weight: normal;
+ line-height: 12px;
clear: left;
}
.attach-image {
- margin: 3px 0;
max-width: 100%;
+ margin: 3px 0;
}
.attach-image img {
border: 1px solid transparent;
-/* cursor: move; */
+
+ /* cursor: move; */
cursor: default;
}
/* Inline image thumbnails */
-div.inline-attachment dl.thumbnail, div.inline-attachment dl.file {
+div.inline-attachment dl.thumbnail,
+div.inline-attachment dl.file {
display: block;
margin-bottom: 4px;
}
@@ -599,11 +649,11 @@ dl.file {
}
dl.file dt {
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-weight: bold;
text-transform: none;
margin: 0;
padding: 0;
- font-weight: bold;
- font-family: Verdana, Arial, Helvetica, sans-serif;
}
dl.file dd {
@@ -612,14 +662,15 @@ dl.file dd {
}
dl.thumbnail img {
- padding: 3px;
border: 1px solid transparent;
+ -webkit-box-sizing: border-box;
box-sizing: border-box;
+ padding: 3px;
}
dl.thumbnail dd {
- font-style: italic;
font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-style: italic;
}
.attachbox dl.thumbnail dd {
@@ -631,16 +682,16 @@ dl.thumbnail dt a:hover img {
}
/* Post poll styles
-----------------------------------------*/
+---------------------------------------- */
fieldset.polls {
font-family: "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif;
}
fieldset.polls dl {
- margin-top: 5px;
+ line-height: 13px;
border-top: 1px solid transparent;
- padding: 5px 0 0 0;
- line-height: 120%;
+ margin-top: 5px;
+ padding: 5px 0 0;
}
fieldset.polls dl.voted {
@@ -648,23 +699,23 @@ fieldset.polls dl.voted {
}
fieldset.polls dt {
+ font-size: 11px;
text-align: left;
- float: left;
+ border-right: none;
display: block;
+ float: left;
width: 30%;
- border-right: none;
- padding: 0;
margin: 0;
- font-size: 1.1em;
+ padding: 0;
}
fieldset.polls dd {
+ font-size: 11px;
+ border-left: none;
float: left;
width: 10%;
- border-left: none;
- padding: 0 5px;
margin-left: 0;
- font-size: 1.1em;
+ padding: 0 5px;
}
fieldset.polls dd.resultbar {
@@ -676,59 +727,66 @@ fieldset.polls dd input {
}
fieldset.polls dd div {
- text-align: right;
font-family: Arial, Helvetica, sans-serif;
font-weight: bold;
- padding: 2px 2px 0 2px;
+ text-align: right;
overflow: visible;
min-width: 8px;
+ padding: 2px 2px 0;
}
-.pollbar1, .pollbar2, .pollbar3, .pollbar4, .pollbar5 {
- border-bottom: 1px solid transparent;
+.pollbar1,
+.pollbar2,
+.pollbar3,
+.pollbar4,
+.pollbar5 {
border-right: 1px solid transparent;
+ border-bottom: 1px solid transparent;
}
.vote-submitted {
- font-size: 1.2em;
+ font-size: 12px;
font-weight: bold;
text-align: center;
}
/* Poster profile block
-----------------------------------------*/
+---------------------------------------- */
.postprofile {
- margin: 5px 0 10px 0;
- min-height: 80px;
border: 1px solid transparent;
border-width: 0 0 0 1px;
- width: 22%;
float: right;
- display: inline;
+ width: 22%;
+ min-height: 80px;
+ margin: 5px 0 10px;
}
-.postprofile dd, .postprofile dt {
- line-height: 1.2em;
+.postprofile dd,
+.postprofile dt {
+ font-size: 10px;
+ line-height: 12px;
margin-left: 8px;
}
.postprofile dd {
- overflow: hidden;
text-overflow: ellipsis;
+ overflow: hidden;
}
.postprofile strong {
font-weight: normal;
}
-.postprofile dt.no-profile-rank, .postprofile dd.profile-rank, .postprofile .search-result-date {
+.postprofile dt.no-profile-rank,
+.postprofile dd.profile-rank,
+.postprofile .search-result-date {
margin-bottom: 10px;
}
/* Post-profile avatars */
.postprofile .has-avatar .avatar-container {
- margin-bottom: 3px;
overflow: hidden;
+ margin-bottom: 3px;
}
.postprofile .avatar {
@@ -739,8 +797,8 @@ fieldset.polls dd div {
.postprofile .avatar img {
display: block;
- height: auto !important;
max-width: 100%;
+ height: auto !important;
}
.postprofile .profile-posts a {
@@ -767,13 +825,7 @@ dd.profile-contact {
margin-right: -14px;
}
-.online {
- background-image: none;
- background-position: 100% 0;
- background-repeat: no-repeat;
-}
-
-/* Poster profile used by search*/
+/* Poster profile used by search */
.search .postprofile {
width: 30%;
}
@@ -793,8 +845,8 @@ dl.pmlist dt textarea {
}
dl.pmlist dd {
- margin-left: 61% !important;
margin-bottom: 2px;
+ margin-left: 61% !important;
}
.action-bar div.dl_links {
@@ -802,8 +854,8 @@ dl.pmlist dd {
}
div.dl_links {
- display: inline-block;
text-transform: none;
+ display: inline-block;
}
.dl_links strong {
@@ -811,9 +863,9 @@ div.dl_links {
}
.dl_links ul {
- list-style-type: none;
- margin: 0;
display: inline-block;
+ margin: 0;
+ list-style-type: none;
}
.dl_links li {
@@ -825,10 +877,10 @@ div.dl_links {
}
.ellipsis-text {
+ white-space: nowrap;
+ text-overflow: ellipsis;
display: inline-block;
overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
}
table.fixed-width-table {
@@ -836,20 +888,37 @@ table.fixed-width-table {
}
/* Show scrollbars for items with overflow on iOS devices
-----------------------------------------*/
-.postbody .content::-webkit-scrollbar, .topicreview::-webkit-scrollbar, .post_details::-webkit-scrollbar, .codebox code::-webkit-scrollbar, .attachbox dd::-webkit-scrollbar, .attach-image::-webkit-scrollbar, .dropdown-extended ul::-webkit-scrollbar {
+---------------------------------------- */
+.postbody .content::-webkit-scrollbar,
+.topicreview::-webkit-scrollbar,
+.post_details::-webkit-scrollbar,
+.codebox code::-webkit-scrollbar,
+.attachbox dd::-webkit-scrollbar,
+.attach-image::-webkit-scrollbar,
+.dropdown-extended ul::-webkit-scrollbar {
+ border-radius: 3px;
width: 8px;
height: 8px;
-webkit-appearance: none;
- background: rgba(0, 0, 0, .1);
- border-radius: 3px;
}
-.postbody .content::-webkit-scrollbar-thumb, .topicreview::-webkit-scrollbar-thumb, .post_details::-webkit-scrollbar-thumb, .codebox code::-webkit-scrollbar-thumb, .attachbox dd::-webkit-scrollbar-thumb, .attach-image::-webkit-scrollbar-thumb, .dropdown-extended ul::-webkit-scrollbar-thumb {
- background: rgba(0, 0, 0, .3);
+.postbody .content::-webkit-scrollbar-thumb,
+.topicreview::-webkit-scrollbar-thumb,
+.post_details::-webkit-scrollbar-thumb,
+.codebox code::-webkit-scrollbar-thumb,
+.attachbox dd::-webkit-scrollbar-thumb,
+.attach-image::-webkit-scrollbar-thumb,
+.dropdown-extended ul::-webkit-scrollbar-thumb {
border-radius: 3px;
}
-#memberlist tr.inactive, #team tr.inactive {
+/* Factor out this ID */
+/* stylelint-disable selector-no-id */
+.memberlist tr.inactive,
+.team tr.inactive {
font-style: italic;
}
+/* stylelint-enable selector-no-id */
+
+/* stylelint-enable selector-max-compound-selectors */
+/* stylelint-enable selector-no-qualifying-type */
diff --git a/phpBB/styles/prosilver/theme/cp.css b/phpBB/styles/prosilver/theme/cp.css
index 0041417022..eb80e6040e 100644
--- a/phpBB/styles/prosilver/theme/cp.css
+++ b/phpBB/styles/prosilver/theme/cp.css
@@ -1,13 +1,16 @@
-/* Control Panel Styles
----------------------------------------- */
+/* -------------------------------------------------------------- /*
+ $Contorl Panel
+/* -------------------------------------------------------------- */
+/* stylelint-disable selector-max-compound-selectors */
+/* stylelint-disable selector-no-qualifying-type */
/* Main CP box
-----------------------------------------*/
+---------------------------------------- */
.cp-menu {
- float:left;
+ float: left;
width: 19%;
- margin-top: 1em;
+ margin-top: 10px;
margin-bottom: 5px;
}
@@ -21,30 +24,31 @@
}
.panel-container .panel p {
- font-size: 1.1em;
+ font-size: 11px;
}
.panel-container .panel ol {
- margin-left: 2em;
- font-size: 1.1em;
+ font-size: 11px;
+ margin-left: 22px;
}
.panel-container .panel li.row {
- border-bottom: 1px solid transparent;
border-top: 1px solid transparent;
+ border-bottom: 1px solid transparent;
}
ul.cplist {
- margin-bottom: 5px;
border-top: 1px solid transparent;
+ margin-bottom: 5px;
}
-.panel-container .panel li.header dd, .panel-container .panel li.header dt {
+.panel-container .panel li.header dd,
+.panel-container .panel li.header dt {
margin-bottom: 2px;
}
.panel-container table.table1 {
- margin-bottom: 1em;
+ margin-bottom: 10px;
}
.panel-container table.table1 thead th {
@@ -61,21 +65,22 @@ ul.cplist {
.cp-main .pm-message {
border: 1px solid transparent;
- margin: 10px 0;
- width: auto;
float: none;
+ width: auto;
+ margin: 10px 0;
}
.pm-message h2 {
padding-bottom: 5px;
}
-.cp-main .postbody h3, .cp-main .box2 h3 {
+.cp-main .postbody h3,
+.cp-main .box2 h3 {
margin-top: 0;
}
.panel-container .postbody p.author {
- font-size: 1.1em;
+ font-size: 11px;
}
.cp-main .buttons {
@@ -93,41 +98,45 @@ ul.cplist {
.tabs-container h2 {
float: left;
- margin-bottom: 0px;
+ margin-bottom: 0;
}
/* CP tabs shared
-----------------------------------------*/
-.tabs, .minitabs {
+---------------------------------------- */
+.tabs,
+.minitabs {
line-height: normal;
}
-.tabs > ul, .minitabs > ul {
- list-style: none;
+.tabs > ul,
+.minitabs > ul {
+ position: relative;
margin: 0;
padding: 0;
- position: relative;
+ list-style: none;
}
-.tabs .tab, .minitabs .tab {
+.tabs .tab,
+.minitabs .tab {
+ font-size: 10px;
+ font-weight: bold;
+ line-height: 14px;
display: block;
float: left;
- font-size: 1em;
- font-weight: bold;
- line-height: 1.4em;
}
-.tabs .tab > a, .minitabs .tab > a {
+.tabs .tab > a,
+.minitabs .tab > a {
+ white-space: nowrap;
+ text-decoration: none;
+ position: relative;
display: block;
padding: 5px 9px;
- position: relative;
- text-decoration: none;
- white-space: nowrap;
cursor: pointer;
}
/* CP tabbed menu
-----------------------------------------*/
+---------------------------------------- */
.tabs {
margin: 20px 0 0 7px;
}
@@ -144,11 +153,11 @@ ul.cplist {
}
/* Mini tabbed menu used in MCP
-----------------------------------------*/
+---------------------------------------- */
.minitabs {
float: right;
- margin: 15px 7px 0 0;
max-width: 50%;
+ margin: 15px 7px 0 0;
}
.minitabs .tab {
@@ -165,45 +174,47 @@ ul.cplist {
}
/* Responsive tabs
-----------------------------------------*/
+---------------------------------------- */
.responsive-tab {
position: relative;
}
.responsive-tab > a.responsive-tab-link {
- display: block;
- font-size: 1.6em;
+ font-size: 16px;
+ line-height: 14px;
+ text-decoration: none;
position: relative;
+ display: block;
width: 16px;
- line-height: 0.9em;
- text-decoration: none;
}
.responsive-tab .responsive-tab-link:before {
- content: '';
+ border-top: 6px double rgba(0, 0, 0, 0);
+ border-bottom: 2px solid rgba(0, 0, 0, 0);
position: absolute;
- left: 10px;
top: 7px;
- height: .125em;
+ left: 10px;
width: 14px;
- border-bottom: 0.125em solid transparent;
- border-top: 0.375em double transparent;
+ height: 2px;
+ content: "";
}
-.tabs .dropdown, .minitabs .dropdown {
+.tabs .dropdown,
+.minitabs .dropdown {
+ font-size: 11px;
+ font-weight: normal;
top: 20px;
margin-right: -2px;
- font-size: 1.1em;
- font-weight: normal;
}
.minitabs .dropdown {
margin-right: -4px;
}
-.tabs .dropdown-up .dropdown, .minitabs .dropdown-up .dropdown {
- bottom: 20px;
+.tabs .dropdown-up .dropdown,
+.minitabs .dropdown-up .dropdown {
top: auto;
+ bottom: 20px;
}
.tabs .dropdown li {
@@ -215,7 +226,8 @@ ul.cplist {
}
/* UCP navigation menu
-----------------------------------------*/
+---------------------------------------- */
+
/* Container for sub-navigation list */
.navigation {
width: 100%;
@@ -228,18 +240,19 @@ ul.cplist {
/* Default list state */
.navigation li {
- display: inline;
font-weight: bold;
+ display: inline;
margin: 1px 0;
padding: 0;
}
/* Link styles for the sub-section links */
.navigation a {
+ font-size: 10px;
+ text-decoration: none;
display: block;
- padding: 5px;
margin: 1px 0;
- text-decoration: none;
+ padding: 5px;
}
.navigation a:hover {
@@ -247,20 +260,21 @@ ul.cplist {
}
/* Preferences pane layout
-----------------------------------------*/
+---------------------------------------- */
.cp-main h2 {
border-bottom: none;
- padding: 0;
margin-left: 10px;
+ padding: 0;
}
/* Friends list */
.cp-mini {
- margin: 10px 15px 10px 5px;
- max-height: 200px;
+ font-size: 10px;
+ border-radius: 7px;
overflow-y: auto;
+ max-height: 200px;
+ margin: 10px 15px 10px 5px;
padding: 5px 10px;
- border-radius: 7px;
}
dl.mini dt {
@@ -280,14 +294,15 @@ dl.mini dd {
}
/* PM Styles
-----------------------------------------*/
+---------------------------------------- */
+
/* Defined rules list for PM options */
ol.def-rules {
padding-left: 0;
}
ol.def-rules li {
- line-height: 180%;
+ line-height: 18px;
padding: 1px;
}
@@ -301,75 +316,62 @@ ol.def-rules li {
}
/* DEPRECATED 3.2.6
-.pmlist li.pm_message_reported_colour, .pm_message_reported_colour {
- border-left-color: transparent;
+.pmlist li.pm_message_reported_colour,
+.pm_message_reported_colour {
border-right-color: transparent;
+ border-left-color: transparent;
}
*/
-.pmlist li.pm_message_reported_colour, .pm_message_reported_colour,
-.pmlist li.pm_marked_colour, .pm_marked_colour,
-.pmlist li.pm_replied_colour, .pm_replied_colour,
-.pmlist li.pm_friend_colour, .pm_friend_colour,
-.pmlist li.pm_foe_colour, .pm_foe_colour {
- padding: 0;
+.pmlist li.pm_message_reported_colour,
+.pm_message_reported_colour,
+.pmlist li.pm_marked_colour,
+.pm_marked_colour,
+.pmlist li.pm_replied_colour,
+.pm_replied_colour,
+.pmlist li.pm_friend_colour,
+.pm_friend_colour,
+.pmlist li.pm_foe_colour,
+.pm_foe_colour {
border: solid 3px transparent;
border-width: 0 3px;
+ padding: 0;
}
.pm-legend {
+ border-right-width: 0;
border-left-width: 10px;
border-left-style: solid;
- border-right-width: 0;
margin-bottom: 3px;
padding-left: 3px;
}
/* Avatar gallery */
.gallery label {
+ text-align: center;
+ border: 1px solid transparent;
position: relative;
float: left;
+ width: auto;
margin: 10px;
padding: 5px;
- width: auto;
- border: 1px solid transparent;
- text-align: center;
}
-/* Responsive *CP navigation
-----------------------------------------*/
-@media only screen and (max-width: 900px), only screen and (max-device-width: 900px)
-{
- .nojs .tabs a span, .nojs .minitabs a span {
- max-width: 40px;
- overflow: hidden;
- text-overflow: ellipsis;
- letter-spacing: -.5px;
- }
-
- .cp-menu, .navigation, .cp-main {
- float: none;
- width: auto;
- margin: 0;
- }
-
- .navigation {
- padding: 0;
- margin: 0 auto;
- max-width: 320px;
- }
-
- .navigation a {
- background-image: none;
- }
-
- .navigation li:first-child a {
- border-top-left-radius: 5px;
- border-top-right-radius: 5px;
- }
-
- .navigation li:last-child a {
- border-bottom-left-radius: 5px;
- border-bottom-right-radius: 5px;
- }
+.cplist .topictitle {
+ line-height: 30px;
}
+
+p.notification-title,
+p.notification-forum,
+p.notification-reason,
+p.notification-time {
+ line-height: 14px;
+ margin-bottom: 4px;
+}
+
+p.notification-time {
+ margin-bottom: 0;
+}
+
+/* stylelint-enable selector-max-compound-selectors */
+/* stylelint-enable selector-no-qualifying-type */
diff --git a/phpBB/styles/prosilver/theme/en/icon_user_online.gif b/phpBB/styles/prosilver/theme/en/icon_user_online.gif
deleted file mode 100644
index 6b571ffce0..0000000000
--- a/phpBB/styles/prosilver/theme/en/icon_user_online.gif
+++ /dev/null
Binary files differ
diff --git a/phpBB/styles/prosilver/theme/en/stylesheet.css b/phpBB/styles/prosilver/theme/en/stylesheet.css
index 604b299488..ae0d2f152d 100644
--- a/phpBB/styles/prosilver/theme/en/stylesheet.css
+++ b/phpBB/styles/prosilver/theme/en/stylesheet.css
@@ -1,2 +1 @@
-/* Online image */
-.online { background-image: url("./icon_user_online.gif"); }
+/* language specific styles go here */
diff --git a/phpBB/styles/prosilver/theme/forms.css b/phpBB/styles/prosilver/theme/forms.css
index 99c898f41e..ceafd5b21f 100644
--- a/phpBB/styles/prosilver/theme/forms.css
+++ b/phpBB/styles/prosilver/theme/forms.css
@@ -1,30 +1,34 @@
-/* Form Styles
----------------------------------------- */
+/* -------------------------------------------------------------- /*
+ $Forms
+/* -------------------------------------------------------------- */
+
+/* stylelint-disable selector-max-compound-selectors */
+/* stylelint-disable selector-no-qualifying-type */
/* General form styles
-----------------------------------------*/
+---------------------------------------- */
fieldset {
- border-width: 0;
font-family: Verdana, Helvetica, Arial, sans-serif;
- font-size: 1.1em;
+ font-size: 11px;
+ border-width: 0;
}
input {
+ font-family: Verdana, Helvetica, Arial, sans-serif;
+ font-size: 11px;
font-weight: normal;
vertical-align: middle;
padding: 0 3px;
- font-size: 1em;
- font-family: Verdana, Helvetica, Arial, sans-serif;
}
select {
font-family: Verdana, Helvetica, Arial, sans-serif;
+ font-size: 11px;
font-weight: normal;
- cursor: pointer;
vertical-align: middle;
border: 1px solid transparent;
padding: 1px;
- font-size: 1em;
+ cursor: pointer;
}
select:focus {
@@ -32,25 +36,25 @@ select:focus {
}
option {
- padding-right: 1em;
+ padding-right: 11px;
}
select optgroup option {
- padding-right: 1em;
font-family: Verdana, Helvetica, Arial, sans-serif;
+ padding-right: 11px;
}
textarea {
font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif;
+ font-size: 11px;
+ line-height: 18px;
width: 60%;
padding: 2px;
- font-size: 1em;
- line-height: 1.4em;
}
label {
- cursor: default;
padding-right: 5px;
+ cursor: default;
}
label input {
@@ -68,27 +72,16 @@ fieldset dl {
}
fieldset dt {
- float: left;
- width: 40%;
text-align: left;
display: block;
+ float: left;
+ width: 40%;
}
fieldset dd {
- margin-left: 41%;
vertical-align: top;
margin-bottom: 3px;
-}
-
-/* Specific layout 1 */
-fieldset.fields1 dt {
- width: 15em;
- border-right-width: 0;
-}
-
-fieldset.fields1 dd {
- margin-left: 15em;
- border-left-width: 0;
+ margin-left: 41%;
}
fieldset.fields1 div {
@@ -100,15 +93,21 @@ fieldset.fields1 .live-search div {
margin-bottom: 0;
}
-/* Specific layout 2 */
-fieldset.fields2 dt {
- width: 15em;
+/* Specific layouts */
+fieldset.fields2 dt,
+fieldset.fields1 dt {
border-right-width: 0;
+ width: 165px;
}
fieldset.fields2 dd {
- margin-left: 16em;
border-left-width: 0;
+ margin-left: 176px;
+}
+
+fieldset.fields1 dd {
+ border-left-width: 0;
+ margin-left: 165px;
}
/* Form elements */
@@ -121,7 +120,8 @@ dd label {
white-space: nowrap;
}
-dd input, dd textarea {
+dd input,
+dd textarea {
margin-right: 3px;
}
@@ -144,8 +144,8 @@ dd textarea {
/* Browser-specific tweaks */
button::-moz-focus-inner {
+ border: 0;
padding: 0;
- border: 0
}
/* Quick-login on index page */
@@ -158,8 +158,8 @@ fieldset.quick-login input {
}
fieldset.quick-login input.inputbox {
- width: 15%;
vertical-align: middle;
+ width: 15%;
margin-right: 5px;
}
@@ -171,7 +171,7 @@ fieldset.quick-login label {
/* Display options on viewtopic/viewforum pages */
fieldset.display-options {
text-align: center;
- margin: 3px 0 5px 0;
+ margin: 3px 0 5px;
}
fieldset.display-options label {
@@ -184,17 +184,17 @@ fieldset.display-options a {
}
.dropdown fieldset.display-options {
- font-size: 1em;
+ font-size: 11px;
margin: 0;
padding: 0;
}
.dropdown fieldset.display-options label {
+ text-align: right;
+ white-space: nowrap;
display: block;
margin: 4px;
padding: 0;
- text-align: right;
- white-space: nowrap;
}
.dropdown fieldset.display-options select {
@@ -203,10 +203,10 @@ fieldset.display-options a {
/* Display actions for ucp and mcp pages */
fieldset.display-actions {
+ line-height: 22px;
text-align: right;
- line-height: 2em;
white-space: nowrap;
- padding-right: 1em;
+ padding-right: 11px;
}
fieldset.display-actions label {
@@ -214,19 +214,20 @@ fieldset.display-actions label {
padding-right: 2px;
}
+/* Not used anywhere */
fieldset.sort-options {
- line-height: 2em;
+ line-height: 22px;
}
-/* MCP forum selection*/
+/* MCP forum selection */
fieldset.forum-selection {
- margin: 5px 0 3px 0;
float: right;
+ margin: 5px 0 3px;
}
fieldset.forum-selection2 {
- margin: 13px 0 3px 0;
float: right;
+ margin: 13px 0 3px;
}
/* Submit button fieldset */
@@ -241,15 +242,17 @@ fieldset.submit-buttons input {
}
/* Posting page styles
-----------------------------------------*/
+---------------------------------------- */
/* Buttons used in the editor */
.format-buttons {
- margin: 15px 0 2px 0;
+ margin: 15px 0 2px;
}
-.format-buttons input, .format-buttons select {
+.format-buttons input,
+.format-buttons select {
vertical-align: middle;
+ margin-bottom: 3px;
}
/* Main message box */
@@ -259,25 +262,22 @@ fieldset.submit-buttons input {
.message-box textarea {
font-family: "Trebuchet MS", Verdana, Helvetica, Arial, sans-serif;
+ font-size: 13px;
+ outline: 3px dashed transparent;
+ outline-offset: -4px;
width: 450px;
- height: 270px;
min-width: 100%;
max-width: 100%;
- font-size: 1.2em;
+ height: 270px;
resize: vertical;
- outline: 3px dashed transparent;
- outline-offset: -4px;
- -webkit-transition: all .5s ease, height 1ms linear;
- -moz-transition: all .5s ease, height 1ms linear;
- -ms-transition: all .5s ease, height 1ms linear;
- -o-transition: all .5s ease, height 1ms linear;
- transition: all .5s ease, height 1ms linear;
+ -webkit-transition: all 0.5s ease, height 1ms linear;
+ transition: all 0.5s ease, height 1ms linear;
}
/* Emoticons panel */
.smiley-box {
- width: 18%;
float: right;
+ width: 18%;
}
.smiley-box img {
@@ -291,15 +291,27 @@ fieldset.submit-buttons input {
padding: 2px;
}
-.inputbox:hover, .inputbox:focus {
+.inputbox:hover,
+.inputbox:focus {
border: 1px solid transparent;
outline-style: none;
}
-input.inputbox { width: 85%; }
-input.medium { width: 50%; }
-input.narrow { width: 25%; }
-input.tiny { width: 150px; }
+input.inputbox {
+ width: 85%;
+}
+
+input.medium {
+ width: 50%;
+}
+
+input.narrow {
+ width: 25%;
+}
+
+input.tiny {
+ width: 150px;
+}
textarea.inputbox {
width: 85%;
@@ -314,11 +326,14 @@ input[type="number"] {
}
input[type="search"] {
- -webkit-appearance: textfield;
-webkit-box-sizing: content-box;
+ box-sizing: content-box;
+ -webkit-appearance: textfield;
}
-input[type="search"]::-webkit-search-decoration, input[type="search"]::-webkit-search-results-button, input[type="search"]::-webkit-search-results-decoration {
+input[type="search"]::-webkit-search-decoration,
+input[type="search"]::-webkit-search-results-button,
+input[type="search"]::-webkit-search-results-decoration {
display: none;
}
@@ -326,65 +341,19 @@ input[type="search"]::-webkit-search-cancel-button {
cursor: pointer;
}
-/* Form button styles
----------------------------------------- */
-input.button1, input.button2 {
- font-size: 1em;
-}
-
-a.button1, input.button1, input.button3, a.button2, input.button2 {
- width: auto !important;
- padding-top: 1px;
- padding-bottom: 1px;
- font-family: "Lucida Grande", Verdana, Helvetica, Arial, sans-serif;
- background: transparent none repeat-x top left;
- line-height: 1.5;
-}
-
-a.button1, input.button1 {
- font-weight: bold;
- border: 1px solid transparent;
-}
-
-input.button3 {
- padding: 0;
- margin: 0;
- line-height: 5px;
- height: 12px;
- background-image: none;
- font-variant: small-caps;
-}
-
-input[type="button"], input[type="submit"], input[type="reset"], input[type="checkbox"], input[type="radio"], .search-results li {
+input[type="button"],
+input[type="submit"],
+input[type="reset"],
+input[type="checkbox"],
+input[type="radio"],
+.search-results li {
cursor: pointer;
}
-/* Alternative button */
-a.button2, input.button2, input.button3 {
- border: 1px solid transparent;
-}
-
-/* <a> button in the style of the form buttons */
-a.button1, a.button2 {
- text-decoration: none;
- padding: 0 3px;
- vertical-align: text-bottom;
-}
-
-/* Hover states */
-a.button1:hover, input.button1:hover, a.button2:hover, input.button2:hover, input.button3:hover {
- border: 1px solid transparent;
-}
-
input.disabled {
font-weight: normal;
}
-/* Focus states */
-input.button1:focus, input.button2:focus, input.button3:focus {
- outline-style: none;
-}
-
/* Topic and forum Search */
.search-box {
float: left;
@@ -395,11 +364,10 @@ input.button1:focus, input.button2:focus, input.button3:focus {
border-right-width: 0;
border-radius: 4px 0 0 4px;
float: left;
- height: 24px;
- padding: 3px;
-webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
box-sizing: border-box;
+ height: 24px;
+ padding: 3px;
}
/* Search box (header)
@@ -408,13 +376,17 @@ input.button1:focus, input.button2:focus, input.button3:focus {
border-radius: 4px;
display: block;
float: right;
- margin-right: 5px;
margin-top: 30px;
+ margin-right: 5px;
}
-.search-header .inputbox { border: 0; }
+.search-header .inputbox {
+ border: 0;
+}
-.navbar .linklist > li.responsive-search { display: none; }
+.navbar .linklist > li.responsive-search {
+ display: none;
+}
input.search {
background-image: none;
@@ -423,7 +395,21 @@ input.search {
padding-left: 17px;
}
-.full { width: 95%; }
-.medium { width: 50%;}
-.narrow { width: 25%;}
-.tiny { width: 10%;}
+.full {
+ width: 95%;
+}
+
+.medium {
+ width: 50%;
+}
+
+.narrow {
+ width: 25%;
+}
+
+.tiny {
+ width: 10%;
+}
+
+/* stylelint-enable selector-max-compound-selectors */
+/* stylelint-enable selector-no-qualifying-type */
diff --git a/phpBB/styles/prosilver/theme/icons.css b/phpBB/styles/prosilver/theme/icons.css
index 3ac598486c..1268627d51 100644
--- a/phpBB/styles/prosilver/theme/icons.css
+++ b/phpBB/styles/prosilver/theme/icons.css
@@ -1,28 +1,35 @@
-/* --------------------------------------------------------------
+/* -------------------------------------------------------------- /*
$Icons
--------------------------------------------------------------- */
+/* -------------------------------------------------------------- */
/* Global module setup
---------------------------------*/
+---------------------------------------- */
/* Renamed version of .fa class for agnostic usage of icon fonts.
* Just change the name of the font after the 14/1 to the name of
* the font you wish to use.
*/
-.icon, .button .icon, blockquote cite:before, .uncited:before {
+.icon,
+.button .icon,
+blockquote cite:before,
+.uncited:before {
+ font-family: FontAwesome;
+ font-size: 14px;
+ font-weight: normal;
+ font-style: normal;
+ font-variant: normal;
+ line-height: 1;
display: inline-block;
- font-weight: normal;
- font-style: normal;
- font-variant: normal;
- font-family: FontAwesome;
- font-size: 14px;
- line-height: 1;
- text-rendering: auto; /* optimizelegibility throws things off #1094 */
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
+ /* stylelint-disable order/properties-order */
+ -moz-osx-font-smoothing: grayscale;
+ -webkit-font-smoothing: antialiased;
+ /* stylelint-enable order/properties-order */
+ text-rendering: auto; /* optimizelegibility throws things off #1094 */
}
-.icon:before { padding-right: 2px; }
+.icon:before {
+ padding-right: 2px;
+}
.button .icon:before {
padding-right: 0;
@@ -48,49 +55,50 @@
/* icon modifiers */
.icon-tiny {
+ font-size: 16px;
+ vertical-align: text-bottom;
width: 12px;
+ -webkit-transform: scale(0.65, 0.75);
transform: scale(0.65, 0.75);
- vertical-align: text-bottom;
- font-size: 16px;
}
-.arrow-left .icon {
- float: left;
+.arrow-right .icon {
+ float: right;
}
.arrow-left:hover .icon {
- margin-left: -5px;
margin-right: 5px;
+ margin-left: -5px;
}
-.arrow-right .icon {
- float: right;
+.arrow-left .icon {
+ float: left;
}
.arrow-right:hover .icon {
- margin-left: 5px;
margin-right: -5px;
+ margin-left: 5px;
}
.post-buttons .dropdown-contents .icon {
- float: right;
- margin-left: 5px;
+ float: right;
+ margin-left: 5px;
}
.alert_close .icon:before {
+ border-radius: 50%;
+ display: block;
+ width: 11px;
+ height: 12px;
padding: 0;
- border-radius: 50%;
- width: 11px;
- display: block;
- line-height: .9;
- height: 12px;
}
-blockquote cite:before, .uncited:before {
- content: '\f10d'; /* Font Awesome quote-left */
+blockquote cite:before,
+.uncited:before {
+ content: "\f10d"; /* Font Awesome quote-left */
}
-.rtl blockquote cite:before, .rtl .uncited:before {
- content: '\f10e'; /* Font Awesome quote-right */
+.rtl blockquote cite:before,
+.rtl .uncited:before {
+ content: "\f10e"; /* Font Awesome quote-right */
}
-
diff --git a/phpBB/styles/prosilver/theme/images/loading.gif b/phpBB/styles/prosilver/theme/images/loading.gif
deleted file mode 100644
index e1ed0883e0..0000000000
--- a/phpBB/styles/prosilver/theme/images/loading.gif
+++ /dev/null
Binary files differ
diff --git a/phpBB/styles/prosilver/theme/links.css b/phpBB/styles/prosilver/theme/links.css
index 6a61e9a262..3a8407e2a6 100644
--- a/phpBB/styles/prosilver/theme/links.css
+++ b/phpBB/styles/prosilver/theme/links.css
@@ -1,15 +1,16 @@
-/* Link Styles
----------------------------------------- */
+/* -------------------------------------------------------------- /*
+ $Links
+/* -------------------------------------------------------------- */
/* Links adjustment to correctly display an order of rtl/ltr mixed content */
a {
- direction: ltr;
- unicode-bidi: embed;
text-decoration: none;
+
/* we use links inline more often then not so to address several bugs with
IE and some other browsers we render all links as inlineblock by default */
display: inline-block;
-
+ direction: ltr;
+ unicode-bidi: embed;
}
/* Coloured usernames */
@@ -20,28 +21,33 @@ a {
}
/* Links on gradient backgrounds */
-.forumbg .header a, .forabg .header a, th a {
+.forumbg .header a,
+.forabg .header a,
+th a {
text-decoration: none;
}
-.forumbg .header a:hover, .forabg .header a:hover, th a:hover {
+.forumbg .header a:hover,
+.forabg .header a:hover,
+th a:hover {
text-decoration: underline;
}
+/* stylelint-disable selector-no-qualifying-type */
+
/* Notification mark read link */
.dropdown-extended a.mark_read {
- background-position: center center;
background-repeat: no-repeat;
+ background-position: center center;
border-radius: 3px 0 0 3px;
- display: none;
- margin-top: -20px;
position: absolute;
z-index: 2;
- right: 0;
top: 50%;
+ right: 0;
+ display: none;
-webkit-box-sizing: border-box;
- -moz-box-sizing: border-box;
box-sizing: border-box;
+ margin-top: -20px;
}
.dropdown-extended li:hover a.mark_read {
@@ -53,13 +59,16 @@ a {
}
.jumpbox-cat-link,
-.jumpbox-forum-link { font-weight: bold; }
+.jumpbox-forum-link {
+ font-weight: bold;
+}
/* Links for forum/topic lists */
-a.forumtitle {
- font-family: "Trebuchet MS", Helvetica, Arial, Sans-serif;
- font-size: 1.2em;
+a.forumtitle,
+a.topictitle {
+ font-family: "Trebuchet MS", Helvetica, Arial, sans-serif;
+ font-size: 13px;
font-weight: bold;
text-decoration: none;
}
@@ -69,10 +78,6 @@ a.forumtitle:hover {
}
a.topictitle {
- font-family: "Trebuchet MS", Helvetica, Arial, Sans-serif;
- font-size: 1.2em;
- font-weight: bold;
- text-decoration: none;
display: inline;
}
@@ -90,7 +95,7 @@ a.lastsubject:hover {
}
.row-item a:hover {
- text-decoration: none
+ text-decoration: none;
}
.row-item .topictitle:hover,
@@ -111,25 +116,28 @@ a.lastsubject:hover {
text-decoration: none;
}
-.signature a, .signature a:hover {
- border: none;
+.signature a,
+.signature a:hover {
text-decoration: underline;
+ border: none;
}
/* Profile links */
-.postprofile a, .postprofile dt.author a {
+.postprofile a,
+.postprofile dt.author a {
font-weight: bold;
text-decoration: none;
}
-.postprofile a:hover, .postprofile dt.author a:hover {
+.postprofile a:hover,
+.postprofile dt.author a:hover {
text-decoration: underline;
}
/* Profile searchresults */
.search .postprofile a {
- text-decoration: none;
font-weight: normal;
+ text-decoration: none;
}
.search .postprofile a:hover {
@@ -149,20 +157,20 @@ a.lastsubject:hover {
.back2top .top {
float: right;
- margin-right: -10px;
margin-top: 0;
+ margin-right: -10px;
}
/* Arrow links */
.arrow-up {
- padding-left: 10px;
text-decoration: none;
border-bottom-width: 0;
+ padding-left: 10px;
}
.arrow-up:hover {
-
+ /* add hover styles here */
}
.arrow-down {
@@ -170,7 +178,7 @@ a.lastsubject:hover {
}
.arrow-down:hover {
-
+ /* add hover styles here */
}
.arrow-left:hover {
diff --git a/phpBB/styles/prosilver/theme/normalize.css b/phpBB/styles/prosilver/theme/normalize.css
index 23d84492c8..16857d5499 100644
--- a/phpBB/styles/prosilver/theme/normalize.css
+++ b/phpBB/styles/prosilver/theme/normalize.css
@@ -1,424 +1,465 @@
-/*! normalize.css v3.0.3 | MIT License | github.com/necolas/normalize.css */
+/* stylelint-disable */
+
+/*! normalize.css v5.0.0 | MIT License | github.com/necolas/normalize.css */
/**
- * 1. Set default font family to sans-serif.
- * 2. Prevent iOS and IE text size adjust after device orientation change,
- * without disabling user zoom.
+ * 1. Change the default font family in all browsers (opinionated).
+ * 2. Correct the line height in all browsers.
+ * 3. Prevent adjustments of font size after orientation changes in
+ * IE on Windows Phone and in iOS.
*/
+/* Document
+ ========================================================================== */
+
html {
- font-family: sans-serif; /* 1 */
- -ms-text-size-adjust: 100%; /* 2 */
- -webkit-text-size-adjust: 100%; /* 2 */
+ font-family: sans-serif; /* 1 */
+ line-height: 1.15; /* 2 */
+ -ms-text-size-adjust: 100%; /* 3 */
+ -webkit-text-size-adjust: 100%; /* 3 */
}
+/* Sections
+ ========================================================================== */
+
/**
- * Remove default margin.
+ * Remove the margin in all browsers (opinionated).
*/
body {
- margin: 0;
+ margin: 0;
}
-/* HTML5 display definitions
- ========================================================================== */
-
/**
- * Correct `block` display not defined for any HTML5 element in IE 8/9.
- * Correct `block` display not defined for `details` or `summary` in IE 10/11
- * and Firefox.
- * Correct `block` display not defined for `main` in IE 11.
+ * Add the correct display in IE 9-.
*/
article,
aside,
-details,
-figcaption,
-figure,
footer,
header,
-hgroup,
-main,
-menu,
nav,
-section,
-summary {
- display: block;
+section {
+ display: block;
}
/**
- * 1. Correct `inline-block` display not defined in IE 8/9.
- * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
+ * Correct the font size and margin on `h1` elements within `section` and
+ * `article` contexts in Chrome, Firefox, and Safari.
*/
-audio,
-canvas,
-progress,
-video {
- display: inline-block; /* 1 */
- vertical-align: baseline; /* 2 */
+h1 {
+ font-size: 2em;
+ margin: 0.67em 0;
}
+/* Grouping content
+ ========================================================================== */
+
/**
- * Prevent modern browsers from displaying `audio` without controls.
- * Remove excess height in iOS 5 devices.
+ * Add the correct display in IE 9-.
+ * 1. Add the correct display in IE.
*/
-audio:not([controls]) {
- display: none;
- height: 0;
+figcaption,
+figure,
+main { /* 1 */
+ display: block;
}
/**
- * Address `[hidden]` styling not present in IE 8/9/10.
- * Hide the `template` element in IE 8/9/10/11, Safari, and Firefox < 22.
+ * Add the correct margin in IE 8.
*/
-[hidden],
-template {
- display: none;
+figure {
+ margin: 1em 40px;
}
-/* Links
- ========================================================================== */
+/**
+ * 1. Add the correct box sizing in Firefox.
+ * 2. Show the overflow in Edge and IE.
+ */
+
+hr {
+ box-sizing: content-box; /* 1 */
+ height: 0; /* 1 */
+ overflow: visible; /* 2 */
+}
/**
- * Remove the gray background color from active links in IE 10.
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
+ */
+
+pre {
+ font-family: monospace, monospace; /* 1 */
+ font-size: 1em; /* 2 */
+}
+
+/* Text-level semantics
+ ========================================================================== */
+
+/**
+ * 1. Remove the gray background on active links in IE 10.
+ * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
*/
a {
- background-color: transparent;
+ background-color: transparent; /* 1 */
+ -webkit-text-decoration-skip: objects; /* 2 */
}
/**
- * Improve readability of focused elements when they are also in an
- * active/hover state.
+ * Remove the outline on focused links when they are also active or hovered
+ * in all browsers (opinionated).
*/
a:active,
a:hover {
- outline: 0;
+ outline-width: 0;
}
-/* Text-level semantics
- ========================================================================== */
-
/**
- * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
+ * 1. Remove the bottom border in Firefox 39-.
+ * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
*/
abbr[title] {
- border-bottom: 1px dotted;
+ border-bottom: none; /* 1 */
+ text-decoration: underline; /* 2 */
+ text-decoration: underline dotted; /* 2 */
}
/**
- * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
+ * Prevent the duplicate application of `bolder` by the next rule in Safari 6.
*/
b,
strong {
- font-weight: bold;
+ font-weight: inherit;
}
/**
- * Address styling not present in Safari and Chrome.
+ * Add the correct font weight in Chrome, Edge, and Safari.
*/
-dfn {
- font-style: italic;
+b,
+strong {
+ font-weight: bolder;
}
/**
- * Address variable `h1` font-size and margin within `section` and `article`
- * contexts in Firefox 4+, Safari, and Chrome.
+ * 1. Correct the inheritance and scaling of font size in all browsers.
+ * 2. Correct the odd `em` font sizing in all browsers.
*/
-h1 {
- font-size: 2em;
- margin: 0.67em 0;
+code,
+kbd,
+samp {
+ font-family: monospace, monospace; /* 1 */
+ font-size: 1em; /* 2 */
}
/**
- * Address styling not present in IE 8/9.
+ * Add the correct font style in Android 4.3-.
+ */
+
+dfn {
+ font-style: italic;
+}
+
+/**
+ * Add the correct background and color in IE 9-.
*/
mark {
- background: #ff0;
- color: #000;
+ background-color: #ff0;
+ color: #000;
}
/**
- * Address inconsistent and variable font size in all browsers.
+ * Add the correct font size in all browsers.
*/
small {
- font-size: 80%;
+ font-size: 80%;
}
/**
- * Prevent `sub` and `sup` affecting `line-height` in all browsers.
+ * Prevent `sub` and `sup` elements from affecting the line height in
+ * all browsers.
*/
sub,
sup {
- font-size: 75%;
- line-height: 0;
- position: relative;
- vertical-align: baseline;
+ font-size: 75%;
+ line-height: 0;
+ position: relative;
+ vertical-align: baseline;
}
-sup {
- top: -0.5em;
+sub {
+ bottom: -0.25em;
}
-sub {
- bottom: -0.25em;
+sup {
+ top: -0.5em;
}
/* Embedded content
- ========================================================================== */
+ ========================================================================== */
/**
- * Remove border when inside `a` element in IE 8/9/10.
+ * Add the correct display in IE 9-.
*/
-img {
- border: 0;
+audio,
+video {
+ display: inline-block;
}
/**
- * Correct overflow not hidden in IE 9/10/11.
+ * Add the correct display in iOS 4-7.
*/
-svg:not(:root) {
- overflow: hidden;
+audio:not([controls]) {
+ display: none;
+ height: 0;
}
-/* Grouping content
- ========================================================================== */
-
/**
- * Address margin not present in IE 8/9 and Safari.
+ * Remove the border on images inside links in IE 10-.
*/
-figure {
- margin: 1em 40px;
+img {
+ border-style: none;
}
/**
- * Address differences between Firefox and other browsers.
+ * Hide the overflow in IE.
*/
-hr {
- box-sizing: content-box;
- height: 0;
+svg:not(:root) {
+ overflow: hidden;
}
+/* Forms
+ ========================================================================== */
+
/**
- * Contain overflow in all browsers.
+ * 1. Change the font styles in all browsers (opinionated).
+ * 2. Remove the margin in Firefox and Safari.
*/
-pre {
- overflow: auto;
+button,
+input,
+optgroup,
+select,
+textarea {
+ font-family: sans-serif; /* 1 */
+ font-size: 100%; /* 1 */
+ line-height: 1.15; /* 1 */
+ margin: 0; /* 2 */
}
/**
- * Address odd `em`-unit font size rendering in all browsers.
+ * Show the overflow in IE.
+ * 1. Show the overflow in Edge.
*/
-code,
-kbd,
-pre,
-samp {
- font-family: monospace, monospace;
- font-size: 1em;
+button,
+input { /* 1 */
+ overflow: visible;
}
-/* Forms
- ========================================================================== */
-
/**
- * Known limitation: by default, Chrome and Safari on OS X allow very limited
- * styling of `select`, unless a `border` property is set.
+ * Remove the inheritance of text transform in Edge, Firefox, and IE.
+ * 1. Remove the inheritance of text transform in Firefox.
*/
+button,
+select { /* 1 */
+ text-transform: none;
+}
+
/**
- * 1. Correct color not being inherited.
- * Known issue: affects color of disabled elements.
- * 2. Correct font properties not being inherited.
- * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
+ * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
+ * controls in Android 4.
+ * 2. Correct the inability to style clickable types in iOS and Safari.
*/
button,
-input,
-optgroup,
-select,
-textarea {
- color: inherit; /* 1 */
- font: inherit; /* 2 */
- margin: 0; /* 3 */
+html [type="button"], /* 1 */
+[type="reset"],
+[type="submit"] {
+ -webkit-appearance: button; /* 2 */
}
/**
- * Address `overflow` set to `hidden` in IE 8/9/10/11.
+ * Remove the inner border and padding in Firefox.
*/
-button {
- overflow: visible;
+button::-moz-focus-inner,
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner {
+ border-style: none;
+ padding: 0;
}
/**
- * Address inconsistent `text-transform` inheritance for `button` and `select`.
- * All other form control elements do not inherit `text-transform` values.
- * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
- * Correct `select` style inheritance in Firefox.
+ * Restore the focus styles unset by the previous rule.
*/
-button,
-select {
- text-transform: none;
+button:-moz-focusring,
+[type="button"]:-moz-focusring,
+[type="reset"]:-moz-focusring,
+[type="submit"]:-moz-focusring {
+ outline: 1px dotted ButtonText;
}
/**
- * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
- * and `video` controls.
- * 2. Correct inability to style clickable `input` types in iOS.
- * 3. Improve usability and consistency of cursor style between image-type
- * `input` and others.
+ * Change the border, margin, and padding in all browsers (opinionated).
*/
-button,
-html input[type="button"], /* 1 */
-input[type="reset"],
-input[type="submit"] {
- -webkit-appearance: button; /* 2 */
- cursor: pointer; /* 3 */
+fieldset {
+ border: 1px solid #c0c0c0;
+ margin: 0 2px;
+ padding: 0.35em 0.625em 0.75em;
}
/**
- * Re-set default cursor for disabled elements.
+ * 1. Correct the text wrapping in Edge and IE.
+ * 2. Correct the color inheritance from `fieldset` elements in IE.
+ * 3. Remove the padding so developers are not caught out when they zero out
+ * `fieldset` elements in all browsers.
*/
-button[disabled],
-html input[disabled] {
- cursor: default;
+legend {
+ box-sizing: border-box; /* 1 */
+ color: inherit; /* 2 */
+ display: table; /* 1 */
+ max-width: 100%; /* 1 */
+ padding: 0; /* 3 */
+ white-space: normal; /* 1 */
}
/**
- * Remove inner padding and border in Firefox 4+.
+ * 1. Add the correct display in IE 9-.
+ * 2. Add the correct vertical alignment in Chrome, Firefox, and Opera.
*/
-button::-moz-focus-inner,
-input::-moz-focus-inner {
- border: 0;
- padding: 0;
+progress {
+ display: inline-block; /* 1 */
+ vertical-align: baseline; /* 2 */
}
/**
- * Address Firefox 4+ setting `line-height` on `input` using `!important` in
- * the UA stylesheet.
+ * Remove the default vertical scrollbar in IE.
*/
-input {
- line-height: normal;
+textarea {
+ overflow: auto;
}
/**
- * It's recommended that you don't attempt to style these elements.
- * Firefox's implementation doesn't respect box-sizing, padding, or width.
- *
- * 1. Address box sizing set to `content-box` in IE 8/9/10.
- * 2. Remove excess padding in IE 8/9/10.
+ * 1. Add the correct box sizing in IE 10-.
+ * 2. Remove the padding in IE 10-.
*/
-input[type="checkbox"],
-input[type="radio"] {
- box-sizing: border-box; /* 1 */
- padding: 0; /* 2 */
+[type="checkbox"],
+[type="radio"] {
+ box-sizing: border-box; /* 1 */
+ padding: 0; /* 2 */
}
/**
- * Fix the cursor style for Chrome's increment/decrement buttons. For certain
- * `font-size` values of the `input`, it causes the cursor style of the
- * decrement button to change from `default` to `text`.
+ * Correct the cursor style of increment and decrement buttons in Chrome.
*/
-input[type="number"]::-webkit-inner-spin-button,
-input[type="number"]::-webkit-outer-spin-button {
- height: auto;
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+ height: auto;
}
/**
- * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
- * 2. Address `box-sizing` set to `border-box` in Safari and Chrome.
+ * 1. Correct the odd appearance in Chrome and Safari.
+ * 2. Correct the outline style in Safari.
*/
-input[type="search"] {
- -webkit-appearance: textfield; /* 1 */
- box-sizing: content-box; /* 2 */
+[type="search"] {
+ -webkit-appearance: textfield; /* 1 */
+ outline-offset: -2px; /* 2 */
}
/**
- * Remove inner padding and search cancel button in Safari and Chrome on OS X.
- * Safari (but not Chrome) clips the cancel button when the search input has
- * padding (and `textfield` appearance).
+ * Remove the inner padding and cancel buttons in Chrome and Safari on macOS.
*/
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
- -webkit-appearance: none;
+[type="search"]::-webkit-search-cancel-button,
+[type="search"]::-webkit-search-decoration {
+ -webkit-appearance: none;
}
/**
- * Define consistent border, margin, and padding.
+ * 1. Correct the inability to style clickable types in iOS and Safari.
+ * 2. Change font properties to `inherit` in Safari.
*/
-fieldset {
- border: 1px solid #c0c0c0;
- margin: 0 2px;
- padding: 0.35em 0.625em 0.75em;
+::-webkit-file-upload-button {
+ -webkit-appearance: button; /* 1 */
+ font: inherit; /* 2 */
}
-/**
- * 1. Correct `color` not being inherited in IE 8/9/10/11.
- * 2. Remove padding so people aren't caught out if they zero out fieldsets.
+/* Interactive
+ ========================================================================== */
+
+/*
+ * Add the correct display in IE 9-.
+ * 1. Add the correct display in Edge, IE, and Firefox.
*/
-legend {
- border: 0; /* 1 */
- padding: 0; /* 2 */
+details, /* 1 */
+menu {
+ display: block;
+}
+
+/*
+ * Add the correct display in all browsers.
+ */
+
+summary {
+ display: list-item;
}
+/* Scripting
+ ========================================================================== */
+
/**
- * Remove default vertical scrollbar in IE 8/9/10/11.
+ * Add the correct display in IE 9-.
*/
-textarea {
- overflow: auto;
+canvas {
+ display: inline-block;
}
/**
- * Don't inherit the `font-weight` (applied by a rule above).
- * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
+ * Add the correct display in IE.
*/
-optgroup {
- font-weight: bold;
+template {
+ display: none;
}
-/* Tables
- ========================================================================== */
+/* Hidden
+ ========================================================================== */
/**
- * Remove most spacing between table cells.
+ * Add the correct display in IE 10-.
*/
-table {
- border-collapse: collapse;
- border-spacing: 0;
+[hidden] {
+ display: none;
}
-td,
-th {
- padding: 0;
-}
+/* stylelint-enable */
diff --git a/phpBB/styles/prosilver/theme/plupload.css b/phpBB/styles/prosilver/theme/plupload.css
index b1f3ae2da8..118d63d397 100644
--- a/phpBB/styles/prosilver/theme/plupload.css
+++ b/phpBB/styles/prosilver/theme/plupload.css
@@ -1,6 +1,10 @@
+/* -------------------------------------------------------------- /*
+ $Plupload
+/* -------------------------------------------------------------- */
+
.attach-panel-multi {
display: none;
- margin-bottom: 1em;
+ margin-bottom: 10px;
}
.attach-row-tpl {
@@ -20,8 +24,8 @@
}
.attach-comment .inputbox {
- resize: vertical;
width: 100%;
+ resize: vertical;
}
.attach-filesize {
@@ -32,12 +36,12 @@
width: 5%;
}
-.attach-filesize, .attach-status {
+.attach-filesize,
+.attach-status {
text-align: center;
}
.attach-controls {
- display: inline-block;
float: right;
}
@@ -46,45 +50,46 @@
}
.file-total-progress {
- height: 2px;
- display: block;
position: relative;
- margin: 4px -10px -6px -10px;
+ display: block;
+ height: 2px;
+ margin: 4px -10px -6px;
}
.file-progress {
- background-color: #CCCCCC;
- display:inline-block;
- height: 8px;
+ background-color: #cccccc;
+ display: inline-block;
width: 50px;
+ height: 8px;
}
-.file-progress-bar, .file-total-progress-bar {
- background-color: green;
+.file-progress-bar,
+.file-total-progress-bar {
+ background-color: #008000;
display: block;
- height: 100%;
width: 0;
+ height: 100%;
}
.file-status.file-working {
- background: url('./images/plupload/throbber.gif');
+ background: url("./images/plupload/throbber.gif");
}
.file-status.file-uploaded {
- background: url('./images/plupload/done.gif');
+ background: url("./images/plupload/done.gif");
}
.file-status.file-error {
- background: url('./images/plupload/error.gif');
+ background: url("./images/plupload/error.gif");
}
.file-status {
display: inline-block;
- height: 16px;
width: 16px;
+ height: 16px;
}
.file-name {
- max-width: 65%;
vertical-align: bottom;
+ max-width: 65%;
}
diff --git a/phpBB/styles/prosilver/theme/print.css b/phpBB/styles/prosilver/theme/print.css
index ee916dce51..a846ed34de 100644
--- a/phpBB/styles/prosilver/theme/print.css
+++ b/phpBB/styles/prosilver/theme/print.css
@@ -1,25 +1,47 @@
-/* Print Style Sheet
----------------------------------------- */
+/* -------------------------------------------------------------- /*
+ $Print
+/* -------------------------------------------------------------- */
+/* stylelint-disable selector-max-compound-selectors */
/* Lots still TODO here! */
/* General markup styles */
* {
- padding: 0;
margin: 0;
+ padding: 0;
}
body {
- font: 11pt Verdana, Arial, Helvetica, sans-serif;
- color:#000000;
+ font-family: Verdana, Arial, Helvetica, sans-serif;
+ font-size: 14px;
+ color: #000000;
}
-a:link { color: #000000; text-decoration: none; }
-a:visited { color: #000000; text-decoration: none; }
-a:active { color: #000000; text-decoration: none; }
+a:link {
+ text-decoration: none;
+ color: #000000;
+}
+
+a:visited {
+ text-decoration: none;
+ color: #000000;
+}
+
+a:active {
+ text-decoration: none;
+ color: #000000;
+}
+
+img,
+.noprint,
+.navbar,
+.box1,
+.divider,
+.signature {
+ display: none;
+}
-img, .noprint, .navbar, .box1, .divider, .signature { display: none; }
/* Display smilies (Bug #47265) */
.content img {
display: inline;
@@ -27,124 +49,184 @@ img, .noprint, .navbar, .box1, .divider, .signature { display: none; }
/* Container for the main body */
.wrap {
- margin: 0 2em;
+ margin: 0 30px;
}
-p { font-size: 85%; }
-.copyright { font-size: 75%; }
-.page-number { float:right; width: auto; text-align: right; font-size: 75%; }
+p {
+ font-size: 85%;
+}
-h1, h2, h3, h1 a, h2 a, h3 a {
- font-family: "Trebuchet MS",georgia,Verdana,Sans-serif;
- color: #000000;
- background: none;
- text-decoration: none;
+.copyright {
+ font-size: 75%;
+}
+
+.page-number {
+ font-size: 75%;
+ text-align: right;
+ float: right;
+ width: auto;
+}
+
+h1,
+h2,
+h3,
+h1 a,
+h2 a,
+h3 a {
+ font-family: "Trebuchet MS", georgia, Verdana, sans-serif;
font-weight: bold;
+ text-decoration: none;
+ background: none;
+ color: #000000;
}
-h1 { font-size: 20pt; }
-h2 { font-size: 16pt; margin-top: 1em; }
-h3 { font-size: 14pt; margin-top: 1em; }
+h1 {
+ font-size: 26px;
+}
+
+h2 {
+ font-size: 21px;
+ margin-top: 20px;
+}
+
+h3 {
+ font-size: 18px;
+ margin-top: 20px;
+}
.content {
- font-size: 11pt;
- line-height: 14pt;
- margin-bottom: 1em;
font-family: "Lucida Grande", "Trebuchet MS", Verdana, Arial, Helvetica, sans-serif;
+ font-size: 14px;
+ line-height: 18px;
overflow: hidden;
+ margin-bottom: 14px;
+}
+
+.postbody .content {
+ font-size: 14px;
}
/* CSS2 Print tip from: http://www.alistapart.com/articles/goingtoprint/ */
-.postbody a:link, .postbody a:visited, .postbody a:hover, .postbody a:active {
- text-decoration: underline;
- padding: 0.1em 0.2em;
- margin: -0.1em -0.2em;
- color: #666;
- background: none;
+.postbody a:link,
+.postbody a:visited,
+.postbody a:hover,
+.postbody a:active {
font-size: 100%;
+ background: none;
+ color: #666666;
+ padding: 2px 4px;
}
-html>body .postbody a:link:after, html>body .postbody a:visited:after {
- content: " (" attr(href) ") ";
+html > body .postbody a:link:after,
+html > body .postbody a:visited:after {
font-size: 90%;
text-decoration: none;
+ content: " (" attr(href) ") ";
}
hr {
- height: 1px;
background-color: #999999;
border-width: 0;
+ height: 1px;
}
.author {
font-family: Verdana, Arial, Helvetica, sans-serif;
font-size: 75%;
- margin-bottom: 0.6em;
}
.date {
font-family: Verdana, Arial, Helvetica, sans-serif;
- float: right;
- position: relative;
- text-align: right;
font-size: 75%;
+ text-align: right;
+ position: relative;
+ float: right;
}
/* Don't want to print url for names or titles in content area */
-.postbody .author a:link, .postbody .author a:visited,
-html>body .postbody .author a:link:after,
-html>body .postbody .author a:visited:after,
-.postquote .quote-by a:link, .postquote .quote-by a:visited,
-html>body .postquote .quote-by a:link:after,
-html>body .postquote .quote-by a:visited:after,
-html>body .postbody h1 a:link:after, html>body .postbody h2 a:link:after {
+.postbody .author a:link,
+.postbody .author a:visited,
+html > body .postbody .author a:link:after,
+html > body .postbody .author a:visited:after,
+.postquote .quote-by a:link,
+.postquote .quote-by a:visited,
+html > body .postquote .quote-by a:link:after,
+html > body .postquote .quote-by a:visited:after,
+html > body .postbody h1 a:link:after,
+html > body .postbody h2 a:link:after,
+.post-buttons a:after {
text-decoration: none;
- content: "";
+ content: "" !important;
}
/* Poster profile */
-.postprofile { display: none; }
-.grip-show { display:none; }
+.postprofile {
+ display: none;
+}
+
+.grip-show {
+ display: none;
+}
/* Quote */
-.postquote, blockquote {
+.postquote,
+blockquote {
font-size: 85%;
- margin: 1em 18% 1em 4%;
- padding: 0.5em;
- position: relative;
- line-height: 1.5em;
+ line-height: 18px;
border: 1px #999999 solid;
+ position: relative;
+ margin: 12px 154px 12px 34px;
+ padding: 6px;
+}
+
+.postquote img {
+ display: none;
+}
+
+.postquote span {
+ display: block;
+}
+
+.postquote span .postquote {
+ font-size: 100%;
}
-.postquote img { display: none; }
-.postquote span { display: block; }
-.postquote span .postquote { font-size: 100%; }
-.quote-by, blockquote cite {
- color: black;
- display : block;
+.quote-by,
+blockquote cite {
font-weight: bold;
+ color: #000000;
+ display: block;
}
/* List */
-ol, ul {
- margin-left: 15pt
+ol,
+ul {
+ margin-left: 20px;
}
/* Misc page elements */
-div.spacer { clear: both; }
+.spacer {
+ clear: both;
+}
code { display: block; }
/* Accessibility tweaks: Mozilla.org */
-.skip_link { display: none; }
+.skip_link {
+ display: none;
+}
-.codebox p { display: none; }
+.codebox p {
+ display: none;
+}
/* stylelint-disable declaration-property-unit-whitelist */
.emoji {
- min-height: 18px;
+ width: 1em;
min-width: 18px;
height: 1em;
- width: 1em;
+ min-height: 18px;
}
/* stylelint-enable declaration-property-unit-whitelist */
+
+/* stylelint-enable selector-max-compound-selectors */
diff --git a/phpBB/styles/prosilver/theme/responsive.css b/phpBB/styles/prosilver/theme/responsive.css
index ca4054c27f..deccb00503 100644
--- a/phpBB/styles/prosilver/theme/responsive.css
+++ b/phpBB/styles/prosilver/theme/responsive.css
@@ -1,14 +1,19 @@
-/* Responsive Design
----------------------------------------- */
+/* -------------------------------------------------------------- /*
+ $Responsive
+/* -------------------------------------------------------------- */
+/* stylelint-disable selector-max-compound-selectors */
+/* stylelint-disable selector-no-qualifying-type */
@media (max-width: 320px) {
- select, .inputbox {
+ select,
+ .inputbox {
max-width: 240px;
}
}
/* Notifications list
-----------------------------------------*/
+---------------------------------------------------------------- */
+
@media (max-width: 350px) {
.dropdown-extended .dropdown-contents {
width: auto;
@@ -25,16 +30,16 @@
}
.action-bar .search-box .inputbox ::-moz-placeholder {
- content: "Search...";
- }
+ content: "Search...";
+ }
- .action-bar .search-box .inputbox :-ms-input-placeholder {
- content: "Search...";
- }
+ .action-bar .search-box .inputbox :-ms-input-placeholder {
+ content: "Search...";
+ }
- .action-bar .search-box .inputbox ::-webkit-input-placeholder {
- content: "Search...";
- }
+ .action-bar .search-box .inputbox ::-webkit-input-placeholder {
+ content: "Search...";
+ }
}
@media (max-width: 500px) {
@@ -42,7 +47,8 @@
white-space: normal;
}
- select, .inputbox {
+ select,
+ .inputbox {
max-width: 260px;
}
@@ -54,10 +60,11 @@
width: 100%;
}
- dl.details dt, dl.details dd {
- width: auto;
- float: none;
+ dl.details dt,
+ dl.details dd {
text-align: left;
+ float: none;
+ width: auto;
}
dl.details dd {
@@ -65,20 +72,24 @@
}
p.responsive-center {
- float: none;
text-align: center;
+ float: none;
margin-bottom: 5px;
}
+ .phpbb_alert {
+ top: 25px;
+ }
+
.action-bar > div {
margin-bottom: 5px;
- }
+ }
.action-bar > .pagination {
+ text-align: center;
float: none;
clear: both;
padding-bottom: 1px;
- text-align: center;
}
.action-bar > .pagination li.page-jump {
@@ -95,13 +106,28 @@
}
.attach-controls {
- margin-top: 5px;
width: 100%;
+ margin-top: 5px;
}
.quick-links .dropdown-trigger span {
display: none;
}
+
+ .rtl dl.details dt,
+ .rtl dl.details dd {
+ text-align: right;
+ float: none;
+ }
+
+ .rtl dl.details dd {
+ margin-right: 20px;
+ margin-left: 0;
+ }
+
+ .rtl .captcha-panel dd.captcha {
+ margin-right: 0;
+ }
}
@media (max-width: 550px) {
@@ -116,16 +142,39 @@
ul.topiclist.forums dd.lastpost {
display: none;
}
+
+ /* RTL */
+
+ /* .topiclist lists
+ ---------------------------------------- */
+ .rtl ul.topiclist.forums dt {
+ margin-left: 0;
+ }
+
+ .rtl ul.topiclist.forums dt .list-inner {
+ margin-left: 0;
+ }
}
@media (max-width: 700px) {
- .responsive-hide { display: none !important; }
- .responsive-show { display: block !important; }
- .responsive-show-inline { display: inline !important; }
- .responsive-show-inline-block { display: inline-block !important; }
+ .responsive-hide {
+ display: none !important;
+ }
+
+ .responsive-show {
+ display: block !important;
+ }
+
+ .responsive-show-inline {
+ display: inline !important;
+ }
+
+ .responsive-show-inline-block {
+ display: inline-block !important;
+ }
/* Content wrappers
- ----------------------------------------*/
+ ---------------------------------------------------------------- */
html {
height: auto;
}
@@ -137,29 +186,37 @@
.wrap {
border: none;
border-radius: 0;
- margin: 0;
min-width: 290px;
+ margin: 0;
padding: 0 5px;
}
/* Common block wrappers
- ----------------------------------------*/
- .headerbar, .navbar, .forabg, .forumbg, .post, .panel {
+ ---------------------------------------------------------------- */
+ .headerbar,
+ .navbar,
+ .forabg,
+ .forumbg,
+ .post,
+ .panel {
border-radius: 0;
- margin-left: -5px;
margin-right: -5px;
+ margin-left: -5px;
}
- .cp-main .forabg, .cp-main .forumdb, .cp-main .post, .cp-main .panel {
+ .cp-main .forabg,
+ .cp-main .forumdb,
+ .cp-main .post,
+ .cp-main .panel {
border-radius: 7px;
}
/* Logo block
- ----------------------------------------*/
+ ---------------------------------------------------------------- */
.site-description {
+ text-align: center;
float: none;
width: auto;
- text-align: center;
}
.logo {
@@ -169,40 +226,45 @@
padding: 10px;
}
- .site-description h1, .site-description p {
+ .site-description h1,
+ .site-description p {
+ line-height: 24px;
text-align: inherit;
+ text-overflow: ellipsis;
float: none;
- margin: 5px;
- line-height: 1.2em;
overflow: hidden;
- text-overflow: ellipsis;
+ margin: 5px;
}
- .site-description p, .search-header {
+ .site-description p,
+ .search-header {
display: none;
}
/* Navigation
- ----------------------------------------*/
+ ---------------------------------------------------------------- */
.headerbar + .navbar {
margin-top: -5px;
}
/* Search
- ----------------------------------------*/
- .responsive-search { display: block !important; }
+ ---------------------------------------------------------------- */
+ .responsive-search {
+ display: block !important;
+ }
- /* .topiclist lists
- ----------------------------------------*/
+ /* Forums and topicslists
+ ---------------------------------------------------------------- */
li.header dt {
+ font-size: 12px;
+ line-height: 12px;
text-align: center;
text-transform: none;
- line-height: 1em;
- font-size: 1.2em;
padding-bottom: 4px;
}
- ul.topiclist li.header dt, ul.topiclist li.header dt .list-inner {
+ ul.topiclist li.header dt,
+ ul.topiclist li.header dt .list-inner {
margin-right: 0 !important;
padding-right: 0;
}
@@ -211,10 +273,14 @@
display: none !important;
}
- ul.topiclist dt, ul.topiclist dt .list-inner,
- ul.topiclist.missing-column dt, ul.topiclist.missing-column dt .list-inner,
- ul.topiclist.two-long-columns dt, ul.topiclist.two-long-columns dt .list-inner,
- ul.topiclist.two-columns dt, ul.topiclist.two-columns dt .list-inner {
+ ul.topiclist dt,
+ ul.topiclist dt .list-inner,
+ ul.topiclist.missing-column dt,
+ ul.topiclist.missing-column dt .list-inner,
+ ul.topiclist.two-long-columns dt,
+ ul.topiclist.two-long-columns dt .list-inner,
+ ul.topiclist.two-columns dt,
+ ul.topiclist.two-columns dt .list-inner {
margin-right: 0;
}
@@ -233,33 +299,28 @@
ul.topiclist dd {
display: none;
}
- ul.topiclist dd.mark {
- display: block;
- }
- /* Forums and topics lists
- ----------------------------------------*/
ul.topiclist.forums dt {
margin-right: -250px;
}
ul.topiclist dd.mark {
- display: block;
+ text-align: left;
position: absolute;
- right: 5px;
top: 0;
- margin: 0;
+ right: 5px;
+ display: block;
width: auto;
min-width: 0;
- text-align: left;
+ margin: 0;
}
- ul.topiclist.forums dd.topics dfn, ul.topiclist.topics dd.posts dfn {
+ ul.topiclist.forums dd.topics dfn,
+ ul.topiclist.topics dd.posts dfn {
+ font-weight: normal;
position: relative;
left: 0;
- width: auto;
display: inline;
- font-weight: normal;
}
li.row .responsive-show strong {
@@ -269,13 +330,13 @@
ul.topiclist li.row dt a.subforum {
vertical-align: bottom;
- overflow: hidden;
text-overflow: ellipsis;
+ overflow: hidden;
max-width: 100px;
}
/* Pagination
- ----------------------------------------*/
+ ---------------------------------------------------------------- */
.pagination > ul {
margin: 5px 0 0;
}
@@ -285,19 +346,24 @@
}
/* Responsive tables
- ----------------------------------------*/
- table.responsive, table.responsive tbody, table.responsive tr, table.responsive td {
+ ---------------------------------------------------------------- */
+ table.responsive,
+ table.responsive tbody,
+ table.responsive tr,
+ table.responsive td {
display: block;
}
- table.responsive thead, table.responsive th {
+ table.responsive thead,
+ table.responsive th {
display: none;
}
- table.responsive.show-header thead, table.responsive.show-header th:first-child {
+ table.responsive.show-header thead,
+ table.responsive.show-header th:first-child {
+ text-align: left !important;
display: block;
width: auto !important;
- text-align: left !important;
}
table.responsive.show-header th:first-child span.rank-img {
@@ -309,8 +375,8 @@
}
table.responsive td {
- width: auto !important;
text-align: left !important;
+ width: auto !important;
padding: 4px;
}
@@ -323,8 +389,8 @@
}
table.responsive td > dfn:after {
- content: ':';
padding-right: 5px;
+ content: ":";
}
table.responsive span.rank-img {
@@ -337,20 +403,26 @@
}
/* Forms
- ----------------------------------------*/
- fieldset dt, fieldset.fields1 dt, fieldset.fields2 dt {
- width: auto;
+ ---------------------------------------------------------------- */
+ fieldset dt,
+ fieldset.fields1 dt,
+ fieldset.fields2 dt {
float: none;
+ width: auto;
}
- fieldset dd, fieldset.fields1 dd, fieldset.fields2 dd {
- margin-left: 0px;
+ fieldset dd,
+ fieldset.fields1 dd,
+ fieldset.fields2 dd {
+ margin-left: 0;
}
- textarea, dd textarea, .message-box textarea {
- width: 100%;
- -moz-box-sizing: border-box;
+ textarea,
+ dd textarea,
+ .message-box textarea {
+ -webkit-box-sizing: border-box;
box-sizing: border-box;
+ width: 100%;
}
dl.pmlist dt {
@@ -367,7 +439,8 @@
padding-left: 20px;
}
- .smiley-box, .message-box {
+ .smiley-box,
+ .message-box {
float: none;
width: auto;
}
@@ -380,7 +453,9 @@
display: none;
}
- .colour-palette, .colour-palette tbody, .colour-palette tr {
+ .colour-palette,
+ .colour-palette tbody,
+ .colour-palette tr {
display: block;
}
@@ -389,14 +464,15 @@
margin-right: 2px;
}
- .horizontal-palette td:nth-child(2n), .vertical-palette tr:nth-child(2n) {
+ .horizontal-palette td:nth-child(2n),
+ .vertical-palette tr:nth-child(2n) {
display: none;
}
fieldset.quick-login label {
+ white-space: normal;
display: block;
margin-bottom: 5px;
- white-space: normal;
}
fieldset.quick-login label > span {
@@ -411,21 +487,23 @@
}
fieldset.quick-login label[for="autologin"] {
- display: inline-block;
text-align: right;
+ display: inline-block;
min-width: 50%;
}
/* User profile
- ----------------------------------------*/
- .column1, .column2, .left-box.profile-details {
+ ---------------------------------------------------------------- */
+ .column1,
+ .column2,
+ .left-box.profile-details {
float: none;
- width: auto;
clear: both;
+ width: auto;
}
/* Polls
- ----------------------------------------*/
+ ---------------------------------------------------------------- */
fieldset.polls dt {
width: 90%;
}
@@ -438,46 +516,51 @@
width: 20%;
}
- fieldset.polls dd.resultbar, fieldset.polls dd.poll_option_percent {
+ fieldset.polls dd.resultbar,
+ fieldset.polls dd.poll_option_percent {
margin-top: 5px;
}
/* Post
- ----------------------------------------*/
+ ---------------------------------------------------------------- */
.postbody {
position: inherit;
}
- .postprofile, .postbody, .search .postbody {
+ .postprofile,
+ .postbody,
+ .search .postbody {
display: block;
- width: auto;
float: none;
- padding: 0;
+ width: auto;
min-height: 0;
+ padding: 0;
}
.post .postprofile {
+ border-width: 0 0 1px;
+ overflow: hidden;
width: auto;
- border-width: 0 0 1px 0;
- padding-bottom: 5px;
+ min-height: 40px;
margin: 0;
margin-bottom: 5px;
- min-height: 40px;
- overflow: hidden;
+ padding-bottom: 5px;
}
.postprofile dd {
display: none;
}
- .postprofile dt, .postprofile dd.profile-rank, .search .postprofile dd {
+ .postprofile dt,
+ .postprofile dd.profile-rank,
+ .search .postprofile dd {
display: block;
margin: 0;
}
.postprofile .has-avatar .avatar-container {
- margin: 0;
overflow: inherit;
+ margin: 0;
}
.postprofile .avatar-container:after {
@@ -495,28 +578,23 @@
}
.has-profile .postbody h3 {
- margin-left: 0 !important;
margin-right: 0 !important;
+ margin-left: 0 !important;
}
.has-profile .post-buttons {
- right: 30px;
- top: 15px;
- }
-
- .online {
- background-size: 40px;
+ margin: 5px;
}
/* Misc stuff
- ----------------------------------------*/
+ ---------------------------------------------------------------- */
h2 {
- margin-top: .5em;
+ margin-top: 12px;
}
p {
- margin-bottom: .5em;
overflow: hidden;
+ margin-bottom: 8px;
}
p.rightside {
@@ -551,33 +629,206 @@
.attach-comment dfn {
width: 100%;
}
+
+ /* RTL */
+
+ /* .topiclist lists
+ ---------------------------------------- */
+ .rtl ul.topiclist li.header dt,
+ .rtl ul.topiclist li.header dt .list-inner {
+ margin-left: 0 !important;
+ padding-left: 0;
+ }
+
+ .rtl ul.topiclist dt,
+ .rtl ul.topiclist dt .list-inner,
+ .rtl ul.topiclist.missing-column dt,
+ .rtl ul.topiclist.missing-column dt .list-inner,
+ .rtl ul.topiclist.two-long-columns dt,
+ .rtl ul.topiclist.two-long-columns dt .list-inner,
+ .rtl ul.topiclist.two-columns dt,
+ .rtl ul.topiclist.two-columns dt .list-inner {
+ margin-left: 0;
+ }
+
+ .rtl ul.topiclist dt .list-inner.with-mark {
+ padding-left: 34px;
+ }
+
+ /* Forums and topics lists
+ ---------------------------------------- */
+ .rtl ul.topiclist.forums dt {
+ margin-left: -250px;
+ }
+
+ .rtl ul.topiclist.forums dt .list-inner {
+ margin-left: 250px;
+ }
+
+ .rtl ul.topiclist dd.mark {
+ text-align: right;
+ right: auto;
+ left: 5px;
+ }
+
+ .rtl table.responsive.show-header thead,
+ .rtl table.responsive.show-header th:first-child {
+ text-align: right !important;
+ }
+
+ .rtl table.responsive td {
+ text-align: right !important;
+ }
+
+ /* User profile
+ ---------------------------------------- */
+ .rtl .column1,
+ .rtl .column2,
+ .rtl .left-box.profile-details {
+ float: none;
+ }
+
+ /* Post
+ ---------------------------------------- */
+ .rtl .postprofile,
+ .rtl .postbody,
+ .rtl .search .postbody {
+ float: none;
+ }
+
+ .rtl .post .postprofile {
+ border-width: 0 0 1px;
+ }
+
+ .rtl .postprofile dt,
+ .rtl .postprofile dd.profile-rank,
+ .rtl .search .postprofile dd {
+ margin: 0;
+ }
+
+ .rtl .postprofile .avatar {
+ margin-right: 0;
+ margin-left: 5px;
+ }
+
+ .rtl .has-profile .post-buttons {
+ left: 20px;
+ }
+
+ /* Forms
+ ---------------------------------------- */
+ .rtl fieldset dt,
+ .rtl fieldset.fields1 dt,
+ .rtl fieldset.fields2 dt {
+ float: none;
+ }
+
+ .rtl fieldset dd,
+ .rtl fieldset.fields1 dd,
+ .rtl fieldset.fields2 dd {
+ margin-right: 20px;
+ }
}
@media (min-width: 700px) {
- .postbody { width: 70%; }
+ .postbody {
+ width: 70%;
+ }
}
@media (min-width: 850px) {
- .postbody { width: 76%; }
+ .postbody {
+ width: 76%;
+ }
}
@media (max-width: 850px) {
- .postprofile { width: 28%; }
-
-
+ .postprofile {
+ width: 28%;
+ }
}
@media (min-width: 701px) and (max-width: 950px) {
-
ul.topiclist dt {
- margin-right: -410px;
+ margin-right: -410px;
}
ul.topiclist dt .list-inner {
- margin-right: 410px;
+ margin-right: 410px;
+ }
+
+ dd.posts,
+ dd.topics,
+ dd.views {
+ width: 80px;
+ }
+}
+
+/* Responsive *CP navigation
+---------------------------------------- */
+@media (max-width: 900px) {
+ .nojs .tabs a span,
+ .nojs .minitabs a span {
+ letter-spacing: -0.03em;
+ text-overflow: ellipsis;
+ overflow: hidden;
+ max-width: 40px;
+ }
+
+ .cp-menu,
+ .navigation,
+ .cp-main {
+ float: none;
+ width: auto;
+ margin: 0;
}
- dd.posts, dd.topics, dd.views {
- width: 80px;
+ .navigation {
+ max-width: 320px;
+ margin: 0 auto;
+ padding: 0;
+ }
+
+ .navigation a {
+ background-image: none;
+ }
+
+ .navigation li:first-child a {
+ border-top-left-radius: 5px;
+ border-top-right-radius: 5px;
+ }
+
+ .navigation li:last-child a {
+ border-bottom-right-radius: 5px;
+ border-bottom-left-radius: 5px;
+ }
+
+ .rtl .cp-menu,
+ .rtl .navigation,
+ .rtl .cp-main {
+ float: none;
+ }
+
+ .navigation a,
+ .rtl .navigation a {
+ background: #b2c2cf;
+ }
+}
+
+@media (max-width: 992px) {
+ .row .pagination {
+ text-align: left;
+ float: left;
+ margin-top: 4px;
+ margin-bottom: 4px;
+ }
+}
+
+@media (max-width: 1220px) {
+ .wrap {
+ margin: 0 12px;
}
}
+
+/* stylelint-enable selector-max-compound-selectors */
+/* stylelint-enable selector-no-qualifying-type */
diff --git a/phpBB/styles/prosilver/theme/stylesheet.css b/phpBB/styles/prosilver/theme/stylesheet.css
index c402d563c6..a436c1668a 100644
--- a/phpBB/styles/prosilver/theme/stylesheet.css
+++ b/phpBB/styles/prosilver/theme/stylesheet.css
@@ -7,15 +7,17 @@
--------------------------------------------------------------
*/
-@import url("normalize.css?v=3.3");
-@import url("base.css?v=3.3");
-@import url("utilities.css?v=3.3");
-@import url("common.css?v=3.3");
-@import url("links.css?v=3.3");
-@import url("content.css?v=3.3");
-@import url("buttons.css?v=3.3");
-@import url("cp.css?v=3.3");
-@import url("forms.css?v=3.3");
-@import url("icons.css?v=3.3");
-@import url("colours.css?v=3.3");
-@import url("responsive.css?v=3.3");
+@import url("normalize.css?v=4.0");
+@import url("base.css?v=4.0");
+@import url("utilities.css?v=4.0");
+@import url("common.css?v=4.0");
+@import url("links.css?v=4.0");
+@import url("content.css?v=4.0");
+@import url("buttons.css?v=4.0");
+@import url("cp.css?v=4.0");
+@import url("forms.css?v=4.0");
+@import url("icons.css?v=4.0");
+@import url("colours.css?v=4.0");
+@import url("responsive.css?v=4.0");
+@import url("bidi.css?v=4.0");
+@import url("tweaks.css?v=4.0");
diff --git a/phpBB/styles/prosilver/theme/tweaks.css b/phpBB/styles/prosilver/theme/tweaks.css
index ba82551f85..4b3b7afd24 100644
--- a/phpBB/styles/prosilver/theme/tweaks.css
+++ b/phpBB/styles/prosilver/theme/tweaks.css
@@ -1,41 +1,4 @@
-/* Style Sheet Tweaks
-
-These style definitions are IE 8 & 9 only.
-They are required due to the poor CSS support in IE browsers.
-------------------------------------------------------------------------------*/
-
-/* IE 8 Tweaks (value)\9 equates to IE <= 8
-------------------------------------------------------------------------------*/
-
-/* Clear float fix */
-.inner, ul.linklist { zoom: 1\9; }
-
-/* Align checkboxes/radio buttons nicely */
-dd label input { vertical-align: text-bottom\9; }
-
-/* Fixes header-avatar aspect-ratio */
-.header-avatar img { height: 20px\9; }
-
-/* IE8 often can't handle max-width in %, so we use px instead */
-.postprofile .avatar img { max-width: 150px\9; }
-
-
-/* IE 9 Tweaks
-------------------------------------------------------------------------------*/
-
-/* Border-radius bleed fix in IE9 */
-.search-header, .search-header .inputbox, .search-header a.button {
- border-radius: 0;
-}
-
-.headerbar, .forumbg {
- background-image: url("./images/bg_header.gif");
-}
-
-.forabg {
- background-image: url("./images/bg_list.gif");
-}
-
-.tabs .tab > a {
- border-radius: 0;
-}
+/* -------------------------------------------------------------- /*
+ $Tweaks
+/* -------------------------------------------------------------- /*
+/* -------------------------------------------------------------- */
diff --git a/phpBB/styles/prosilver/theme/utilities.css b/phpBB/styles/prosilver/theme/utilities.css
index cbb8127d1c..ab47754d5d 100644
--- a/phpBB/styles/prosilver/theme/utilities.css
+++ b/phpBB/styles/prosilver/theme/utilities.css
@@ -1,26 +1,26 @@
-/* --------------------------------------------------------------
+/* -------------------------------------------------------------- /*
$Utilities
--------------------------------------------------------------- */
+/* -------------------------------------------------------------- */
.sr-only {
+ border: 0;
position: absolute;
+ overflow: hidden;
+ clip: rect(0, 0, 0, 0);
width: 1px;
height: 1px;
margin: -1px;
padding: 0;
- overflow: hidden;
- clip: rect(0, 0, 0, 0);
- border: 0;
}
.sr-only-focusable:active,
.sr-only-focusable:focus {
- position: static;
- width: auto;
- height: auto;
- margin: 0;
- overflow: visible;
- clip: auto;
+ position: static;
+ overflow: visible;
+ clip: auto;
+ width: auto;
+ height: auto;
+ margin: 0;
}
.clearfix:before,
@@ -31,36 +31,55 @@
.container-fluid:after,
.row:before,
.row:after {
- content: " ";
display: table;
+ content: " ";
}
+
.clearfix:after,
.container:after,
.container-fluid:after,
-.row:after { clear: both }
+.row:after {
+ clear: both;
+}
.center-block {
display: block;
- margin-left: auto;
margin-right: auto;
+ margin-left: auto;
}
-.pull-right { float: right !important }
-.pull-left { float: left !important }
-.hide { display: none !important }
-.show { display: block !important }
-.invisible { visibility: hidden }
+.pull-right {
+ float: right !important;
+}
+
+.pull-left {
+ float: left !important;
+}
+
+.hide {
+ display: none !important;
+}
+
+.show {
+ display: block !important;
+}
+
+.invisible {
+ visibility: hidden;
+}
.text-hide {
font: 0/0 a;
- color: transparent;
- text-shadow: none;
background-color: transparent;
border: 0;
+ text-shadow: none;
+ color: transparent;
}
.hidden {
- display: none ;
+ display: none;
}
-.affix { position: fixed }
+.affix {
+ position: fixed;
+}
diff --git a/phpBB/vendor-ext/.git-keep b/phpBB/vendor-ext/.git-keep
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/phpBB/vendor-ext/.git-keep
diff --git a/tests/attachment/delete_test.php b/tests/attachment/delete_test.php
index 59669c87e9..26f6d11bfc 100644
--- a/tests/attachment/delete_test.php
+++ b/tests/attachment/delete_test.php
@@ -21,20 +21,18 @@ class phpbb_attachment_delete_test extends \phpbb_database_test_case
/** @var \phpbb\db\driver\driver_interface */
protected $db;
- /** @var \phpbb\filesystem\filesystem */
- protected $filesystem;
-
/** @var \phpbb\event\dispatcher_interface */
protected $dispatcher;
/** @var \phpbb\attachment\resync */
protected $resync;
+ /** @var \phpbb\storage\storage */
+ protected $storage;
+
/** @var \phpbb\attachment\delete */
protected $attachment_delete;
- protected $phpbb_root_path;
-
public function getDataSet()
{
return $this->createXMLDataSet(dirname(__FILE__) . '/fixtures/resync.xml');
@@ -42,24 +40,17 @@ class phpbb_attachment_delete_test extends \phpbb_database_test_case
public function setUp(): void
{
- global $phpbb_root_path;
-
parent::setUp();
$this->config = new \phpbb\config\config(array());
$this->db = $this->new_dbal();
- $db = $this->db;
$this->resync = new \phpbb\attachment\resync($this->db);
- $this->filesystem = $this->createMock('\phpbb\filesystem\filesystem', array('remove', 'exists'));
- $this->filesystem->expects($this->any())
- ->method('remove')
- ->willReturn(false);
- $this->filesystem->expects($this->any())
+ $this->storage = $this->createMock('\phpbb\storage\storage');
+ $this->storage->expects($this->any())
->method('exists')
->willReturn(true);
- $this->phpbb_root_path = $phpbb_root_path;
$this->dispatcher = new \phpbb_mock_event_dispatcher();
- $this->attachment_delete = new \phpbb\attachment\delete($this->config, $this->db, $this->dispatcher, $this->filesystem, $this->resync, $phpbb_root_path);
+ $this->attachment_delete = new \phpbb\attachment\delete($this->config, $this->db, $this->dispatcher, $this->resync, $this->storage);
}
public function data_attachment_delete()
@@ -106,25 +97,24 @@ class phpbb_attachment_delete_test extends \phpbb_database_test_case
*/
public function test_attachment_delete_success($remove_success, $exists_success, $expected, $throw_exception = false)
{
- $this->filesystem = $this->createMock('\phpbb\filesystem\filesystem', array('remove', 'exists'));
+ $this->storage = $this->createMock('\phpbb\storage\storage', array('delete', 'exists'));
if ($throw_exception)
{
- $this->filesystem->expects($this->any())
- ->method('remove')
- ->willThrowException(new \phpbb\filesystem\exception\filesystem_exception);;
+ $this->storage->expects($this->any())
+ ->method('delete')
+ ->willThrowException(new \phpbb\storage\exception\exception);
}
else
{
- $this->filesystem->expects($this->any())
- ->method('remove')
+ $this->storage->expects($this->any())
+ ->method('delete')
->willReturn($remove_success);
}
-
- $this->filesystem->expects($this->any())
+ $this->storage->expects($this->any())
->method('exists')
->willReturn($exists_success);
- $this->attachment_delete = new \phpbb\attachment\delete($this->config, $this->db, $this->dispatcher, $this->filesystem, $this->resync, $this->phpbb_root_path);
+ $this->attachment_delete = new \phpbb\attachment\delete($this->config, $this->db, $this->dispatcher, $this->resync, $this->storage);
$this->assertSame($expected, $this->attachment_delete->unlink_attachment('foobar'));
}
}
diff --git a/tests/attachment/fixtures/resync.xml b/tests/attachment/fixtures/resync.xml
index af04701b4a..b06d2db3e2 100644
--- a/tests/attachment/fixtures/resync.xml
+++ b/tests/attachment/fixtures/resync.xml
@@ -58,7 +58,6 @@
<table name="phpbb_extension_groups">
<column>cat_id</column>
<column>group_id</column>
- <column>download_mode</column>
<column>upload_icon</column>
<column>max_filesize</column>
<column>allow_group</column>
@@ -68,7 +67,6 @@
<row>
<value>1</value>
<value>1</value>
- <value>1</value>
<value> </value>
<value>1000</value>
<value>1</value>
diff --git a/tests/attachment/upload_test.php b/tests/attachment/upload_test.php
index a3f51dd34e..eb7067b263 100644
--- a/tests/attachment/upload_test.php
+++ b/tests/attachment/upload_test.php
@@ -39,6 +39,9 @@ class phpbb_attachment_upload_test extends \phpbb_database_test_case
/** @var \phpbb\plupload\plupload */
protected $plupload;
+ /** @var \phpbb\storage\storage */
+ protected $storage;
+
/** @var \phpbb\user */
protected $user;
@@ -51,8 +54,12 @@ class phpbb_attachment_upload_test extends \phpbb_database_test_case
/** @var \phpbb\attachment\upload */
protected $upload;
+ /** @var \phpbb\filesystem\filesystem */
private $filesystem;
+ /** @var \phpbb\filesystem\temp */
+ protected $temp;
+
/** @var \Symfony\Component\DependencyInjection\ContainerInterface */
protected $container;
@@ -75,7 +82,6 @@ class phpbb_attachment_upload_test extends \phpbb_database_test_case
$this->auth = new \phpbb\auth\auth();
$this->config = new \phpbb\config\config(array(
- 'upload_path' => '',
'img_create_thumbnail' => true,
));
$config = $this->config;
@@ -96,27 +102,29 @@ class phpbb_attachment_upload_test extends \phpbb_database_test_case
$guessers[3]->set_priority(-2);
$this->mimetype_guesser = new \phpbb\mimetype\guesser($guessers);
$this->plupload = new \phpbb\plupload\plupload($phpbb_root_path, $this->config, $this->request, new \phpbb\user($this->language, '\phpbb\datetime'), $this->php_ini, $this->mimetype_guesser);
+
+ $this->storage = $this->createMock('\phpbb\storage\storage');
+ $this->storage->expects($this->any())
+ ->method('free_space')
+ ->willReturn(1024*1024); // 1gb
+
$factory_mock = $this->getMockBuilder('\phpbb\files\factory')
->disableOriginalConstructor()
->getMock();
$factory_mock->expects($this->any())
->method('get')
- ->willReturn(new \phpbb\files\filespec(
- $this->filesystem,
+ ->willReturn(new \phpbb\files\filespec_storage(
$this->language,
$this->php_ini,
new \FastImageSize\FastImageSize(),
- $this->phpbb_root_path,
$this->mimetype_guesser
));
$this->container = new phpbb_mock_container_builder($phpbb_root_path, $phpEx);
- $this->container->set('files.filespec', new \phpbb\files\filespec(
- $this->filesystem,
+ $this->container->set('files.filespec_storage', new \phpbb\files\filespec_storage(
$this->language,
$this->php_ini,
new \FastImageSize\FastImageSize(),
- $phpbb_root_path,
new \phpbb\mimetype\guesser(array(
'mimetype.extension_guesser' => new \phpbb\mimetype\extension_guesser(),
))));
@@ -127,7 +135,7 @@ class phpbb_attachment_upload_test extends \phpbb_database_test_case
$this->plupload,
$this->request
));
- $this->container->set('files.types.local', new \phpbb\files\types\local(
+ $this->container->set('files.types.local_storage', new \phpbb\files\types\local_storage(
$factory_mock,
$this->language,
$this->php_ini,
@@ -136,9 +144,9 @@ class phpbb_attachment_upload_test extends \phpbb_database_test_case
$this->factory = new \phpbb\files\factory($this->container);
$this->files_upload = new \phpbb\files\upload($this->filesystem, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
$this->phpbb_dispatcher = new phpbb_mock_event_dispatcher();
+ $this->temp = new \phpbb\filesystem\temp($this->filesystem, '');
$this->user = new \phpbb\user($this->language, '\phpbb\datetime');
-
$this->upload = new \phpbb\attachment\upload(
$this->auth,
$this->cache,
@@ -148,8 +156,9 @@ class phpbb_attachment_upload_test extends \phpbb_database_test_case
$this->mimetype_guesser,
$this->phpbb_dispatcher,
$this->plupload,
- $this->user,
- $this->phpbb_root_path
+ $this->storage,
+ $this->temp,
+ $this->user
);
}
@@ -205,7 +214,7 @@ class phpbb_attachment_upload_test extends \phpbb_database_test_case
public function test_init_error()
{
- $filespec = $this->getMockBuilder('\phpbb\files\filespec')
+ $filespec = $this->getMockBuilder('\phpbb\files\filespec_storage')
->disableOriginalConstructor()
->getMock();
$filespec->expects($this->any())
@@ -217,14 +226,14 @@ class phpbb_attachment_upload_test extends \phpbb_database_test_case
$filespec->expects($this->any())
->method('set_upload_ary')
->willReturnSelf();
- $this->container->set('files.filespec', $filespec);
+ $this->container->set('files.filespec_storage', $filespec);
$factory_mock = $this->getMockBuilder('\phpbb\files\factory')
->disableOriginalConstructor()
->getMock();
$factory_mock->expects($this->any())
->method('get')
->willReturn($filespec);
- $this->container->set('files.types.local', new \phpbb\files\types\local(
+ $this->container->set('files.types.local_storage', new \phpbb\files\types\local_storage(
$factory_mock,
$this->language,
$this->php_ini,
@@ -240,8 +249,9 @@ class phpbb_attachment_upload_test extends \phpbb_database_test_case
$this->mimetype_guesser,
$this->phpbb_dispatcher,
$this->plupload,
- $this->user,
- $this->phpbb_root_path
+ $this->storage,
+ $this->temp,
+ $this->user
);
$filedata = $this->upload->upload('foobar', 1, true);
@@ -336,7 +346,7 @@ class phpbb_attachment_upload_test extends \phpbb_database_test_case
*/
public function test_image_upload($is_image, $plupload_active, $config_data, $expected)
{
- $filespec = $this->getMockBuilder('\phpbb\files\filespec')
+ $filespec = $this->getMockBuilder('\phpbb\files\filespec_storage')
->setMethods(array(
'init_error',
'is_image',
@@ -344,11 +354,9 @@ class phpbb_attachment_upload_test extends \phpbb_database_test_case
'is_uploaded',
))
->setConstructorArgs(array(
- $this->filesystem,
$this->language,
$this->php_ini,
new \FastImageSize\FastImageSize(),
- $this->phpbb_root_path,
$this->mimetype_guesser,
$this->plupload
))
@@ -370,14 +378,14 @@ class phpbb_attachment_upload_test extends \phpbb_database_test_case
$filespec->expects($this->any())
->method('move_file')
->willReturn(false);
- $this->container->set('files.filespec', $filespec);
+ $this->container->set('files.filespec_storage', $filespec);
$factory_mock = $this->getMockBuilder('\phpbb\files\factory')
->disableOriginalConstructor()
->getMock();
$factory_mock->expects($this->any())
->method('get')
->willReturn($filespec);
- $this->container->set('files.types.local', new \phpbb\files\types\local(
+ $this->container->set('files.types.local_storage', new \phpbb\files\types\local_storage(
$factory_mock,
$this->language,
$this->php_ini,
@@ -406,8 +414,9 @@ class phpbb_attachment_upload_test extends \phpbb_database_test_case
$this->mimetype_guesser,
$this->phpbb_dispatcher,
$plupload,
- $this->user,
- $this->phpbb_root_path
+ $this->storage,
+ $this->temp,
+ $this->user
);
$filedata = $this->upload->upload('foobar', 1, true, '', false, array(
diff --git a/tests/avatar/manager_test.php b/tests/avatar/manager_test.php
index 81a0655e02..331792ae38 100644
--- a/tests/avatar/manager_test.php
+++ b/tests/avatar/manager_test.php
@@ -35,7 +35,7 @@ class phpbb_avatar_manager_test extends \phpbb_database_test_case
->method('get')
->will($this->returnArgument(0));
- $filesystem = new \phpbb\filesystem\filesystem();
+ $storage = $this->createMock('\phpbb\storage\storage');
// Prepare dependencies for avatar manager and driver
$this->config = new \phpbb\config\config(array());
@@ -44,7 +44,6 @@ class phpbb_avatar_manager_test extends \phpbb_database_test_case
new \phpbb\symfony_request(
new phpbb_mock_request()
),
- $filesystem,
$this->createMock('\phpbb\request\request'),
$phpbb_root_path,
$phpEx
@@ -83,6 +82,8 @@ class phpbb_avatar_manager_test extends \phpbb_database_test_case
$files_factory = new \phpbb\files\factory($phpbb_container);
+ $php_ini = new \bantu\IniGetWrapper\IniGetWrapper;
+
foreach ($this->avatar_drivers() as $driver)
{
if ($driver !== 'upload')
@@ -96,7 +97,7 @@ class phpbb_avatar_manager_test extends \phpbb_database_test_case
{
$cur_avatar = $this->getMockBuilder('\phpbb\avatar\driver\\' . $driver)
->setMethods(array('get_name'))
- ->setConstructorArgs(array($this->config, $phpbb_root_path, $phpEx, $filesystem, $path_helper, $dispatcher, $files_factory, $cache))
+ ->setConstructorArgs(array($this->config, $phpbb_root_path, $phpEx, $storage, $path_helper, $dispatcher, $files_factory, $php_ini))
->getMock();
}
$cur_avatar->expects($this->any())
diff --git a/tests/console/cron/cron_list_test.php b/tests/console/cron/cron_list_test.php
index 8c7424c50d..69ae53c128 100644
--- a/tests/console/cron/cron_list_test.php
+++ b/tests/console/cron/cron_list_test.php
@@ -97,7 +97,6 @@ class phpbb_console_command_cron_list_test extends phpbb_test_case
$mock_router,
new \phpbb\symfony_request($request),
$request,
- new \phpbb\filesystem\filesystem(),
$phpbb_root_path,
$pathEx
);
diff --git a/tests/console/cron/run_test.php b/tests/console/cron/run_test.php
index 8402f9dd3e..16b2548d09 100644
--- a/tests/console/cron/run_test.php
+++ b/tests/console/cron/run_test.php
@@ -73,7 +73,6 @@ class phpbb_console_command_cron_run_test extends phpbb_database_test_case
$mock_router,
new \phpbb\symfony_request($request),
$request,
- new \phpbb\filesystem\filesystem(),
$phpbb_root_path,
$phpEx
);
@@ -149,7 +148,6 @@ class phpbb_console_command_cron_run_test extends phpbb_database_test_case
$mock_router,
new \phpbb\symfony_request($request),
$request,
- new \phpbb\filesystem\filesystem(),
$phpbb_root_path,
$phpEx
);
@@ -192,7 +190,6 @@ class phpbb_console_command_cron_run_test extends phpbb_database_test_case
$mock_router,
new \phpbb\symfony_request($request),
$request,
- new \phpbb\filesystem\filesystem(),
$phpbb_root_path,
$phpEx
);
diff --git a/tests/content_visibility/delete_post_test.php b/tests/content_visibility/delete_post_test.php
index 1c1796a1fc..35a8eedb80 100644
--- a/tests/content_visibility/delete_post_test.php
+++ b/tests/content_visibility/delete_post_test.php
@@ -298,6 +298,8 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case
$db = $this->new_dbal();
$phpbb_dispatcher = new phpbb_mock_event_dispatcher();
+ $storage = $this->createMock('\phpbb\storage\storage');
+
// Create auth mock
$auth = $this->createMock('\phpbb\auth\auth');
$auth->expects($this->any())
@@ -309,7 +311,7 @@ class phpbb_content_visibility_delete_post_test extends phpbb_database_test_case
$lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx);
$lang = new \phpbb\language\language($lang_loader);
$user = new \phpbb\user($lang, '\phpbb\datetime');
- $attachment_delete = new \phpbb\attachment\delete($config, $db, new \phpbb_mock_event_dispatcher(), new \phpbb\filesystem\filesystem(), new \phpbb\attachment\resync($db), $phpbb_root_path);
+ $attachment_delete = new \phpbb\attachment\delete($config, $db, new \phpbb_mock_event_dispatcher(), new \phpbb\attachment\resync($db), $storage);
$phpbb_dispatcher = new phpbb_mock_event_dispatcher();
diff --git a/tests/controller/common_helper_route.php b/tests/controller/common_helper_route.php
index bdaf8ee682..4575adbfc3 100644
--- a/tests/controller/common_helper_route.php
+++ b/tests/controller/common_helper_route.php
@@ -91,7 +91,6 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
$this->filesystem = new \phpbb\filesystem\filesystem();
$this->phpbb_path_helper = new \phpbb\path_helper(
$this->symfony_request,
- $this->filesystem,
$this->request,
$phpbb_root_path,
$phpEx
@@ -106,7 +105,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
$container->setParameter('core.environment', PHPBB_ENVIRONMENT);
$cache_path = $phpbb_root_path . 'cache/twig';
$context = new \phpbb\template\context();
- $loader = new \phpbb\template\twig\loader($this->filesystem, '');
+ $loader = new \phpbb\template\twig\loader('');
$twig = new \phpbb\template\twig\environment(
$this->config,
$this->filesystem,
@@ -137,7 +136,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
);
$loader = new \Symfony\Component\Routing\Loader\YamlFileLoader(
- new \phpbb\routing\file_locator($this->filesystem, dirname(__FILE__) . '/')
+ new \phpbb\routing\file_locator(dirname(__FILE__) . '/')
);
$resources_locator = new \phpbb\routing\resources_locator\default_resources_locator(dirname(__FILE__) . '/', PHPBB_ENVIRONMENT, $this->extension_manager);
$this->router = new phpbb_mock_router($container, $resources_locator, $loader, dirname(__FILE__) . '/', 'php', false);
@@ -185,7 +184,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
public function test_helper_url_no_rewrite($route, $params, $is_amp, $session_id, $expected, $description)
{
$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0'));
- $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php');
+ $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php');
$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper);
static::assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id), $description);
}
@@ -229,7 +228,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
public function test_helper_url_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description)
{
$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1'));
- $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php');
+ $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php');
$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper);
static::assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id), $description);
}
@@ -273,7 +272,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
public function test_helper_url_absolute($route, $params, $is_amp, $session_id, $expected, $description)
{
$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0'));
- $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php');
+ $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php');
$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper);
static::assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::ABSOLUTE_URL), $description);
}
@@ -317,7 +316,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
public function test_helper_url_relative_path($route, $params, $is_amp, $session_id, $expected, $description)
{
$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0'));
- $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php');
+ $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php');
$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper);
static::assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::RELATIVE_PATH), $description);
}
@@ -361,7 +360,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
public function test_helper_url_network($route, $params, $is_amp, $session_id, $expected, $description)
{
$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '0'));
- $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php');
+ $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php');
$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper);
static::assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::NETWORK_PATH), $description);
}
@@ -405,7 +404,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
public function test_helper_url_absolute_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description)
{
$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1'));
- $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php');
+ $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php');
$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper);
static::assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::ABSOLUTE_URL), $description);
}
@@ -446,7 +445,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
public function test_helper_url_relative_path_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description)
{
$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1'));
- $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php');
+ $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php');
$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper);
static::assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::RELATIVE_PATH), $description);
}
@@ -490,7 +489,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
public function test_helper_url_network_with_rewrite($route, $params, $is_amp, $session_id, $expected, $description)
{
$this->config = new \phpbb\config\config(['enable_mod_rewrite' => '1']);
- $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php');
+ $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php');
$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper);
static::assertEquals($expected, $this->helper->route($route, $params, $is_amp, $session_id, UrlGeneratorInterface::NETWORK_PATH), $description);
}
@@ -522,7 +521,7 @@ abstract class phpbb_controller_common_helper_route extends phpbb_test_case
'server_protocol' => $server_protocol,
));
- $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->filesystem, $this->root_path, 'php');
+ $this->routing_helper = new \phpbb\routing\helper($this->config, $this->router, $this->symfony_request, $this->request, $this->root_path, 'php');
$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $this->symfony_request, $this->request, $this->routing_helper);
static::assertEquals($expected, $this->helper->route('controller1', array(), false, false, $type));
}
diff --git a/tests/controller/controller_test.php b/tests/controller/controller_test.php
index ddc1921b0e..89631552af 100644
--- a/tests/controller/controller_test.php
+++ b/tests/controller/controller_test.php
@@ -45,7 +45,7 @@ class phpbb_controller_controller_test extends phpbb_test_case
$container->setParameter('core.environment', PHPBB_ENVIRONMENT);
$loader = new \Symfony\Component\Routing\Loader\YamlFileLoader(
- new \phpbb\routing\file_locator(new \phpbb\filesystem\filesystem(), dirname(__FILE__) . '/')
+ new \phpbb\routing\file_locator(dirname(__FILE__) . '/')
);
$resources_locator = new \phpbb\routing\resources_locator\default_resources_locator(dirname(__FILE__) . '/', PHPBB_ENVIRONMENT, $this->extension_manager);
$router = new phpbb_mock_router($container, $resources_locator, $loader, dirname(__FILE__) . '/', 'php', false);
diff --git a/tests/cron/manager_test.php b/tests/cron/manager_test.php
index f025e38cd5..3cfc17fdeb 100644
--- a/tests/cron/manager_test.php
+++ b/tests/cron/manager_test.php
@@ -97,7 +97,6 @@ class phpbb_cron_manager_test extends \phpbb_test_case
$mock_router,
new \phpbb\symfony_request($request),
$request,
- new \phpbb\filesystem\filesystem(),
$phpbb_root_path,
$phpEx
);
diff --git a/tests/dbal/migrator_test.php b/tests/dbal/migrator_test.php
index 7d6b100449..947da726b3 100644
--- a/tests/dbal/migrator_test.php
+++ b/tests/dbal/migrator_test.php
@@ -69,6 +69,7 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case
dirname(__FILE__) . '/../../phpBB/',
'php',
'phpbb_',
+ self::get_core_tables(),
$tools,
new \phpbb\db\migration\helper()
);
@@ -79,7 +80,6 @@ class phpbb_dbal_migrator_test extends phpbb_database_test_case
$container,
$this->db,
$this->config,
- new phpbb\filesystem\filesystem(),
'phpbb_ext',
dirname(__FILE__) . '/../../phpBB/',
'php',
diff --git a/tests/di/fixtures/config/production/container/environment.yml b/tests/di/fixtures/config/production/container/environment.yml
index 0af08f0849..2792b24162 100644
--- a/tests/di/fixtures/config/production/container/environment.yml
+++ b/tests/di/fixtures/config/production/container/environment.yml
@@ -22,6 +22,11 @@ services:
ext.manager:
class: phpbb\extension\manager_mock
+ config:
+ class: phpbb\config\config
+ arguments:
+ - []
+
template.twig.environment:
class: Exception
arguments:
diff --git a/tests/di/fixtures/config/test/container/environment.yml b/tests/di/fixtures/config/test/container/environment.yml
index 0a9e4b5e77..356eb4b008 100644
--- a/tests/di/fixtures/config/test/container/environment.yml
+++ b/tests/di/fixtures/config/test/container/environment.yml
@@ -19,6 +19,11 @@ services:
dispatcher:
class: phpbb\db\driver\container_mock
+ config:
+ class: phpbb\config\config
+ arguments:
+ - []
+
template.twig.environment:
class: Exception
arguments:
diff --git a/tests/di/fixtures/ext/vendor/enabled_4/di/extension.php b/tests/di/fixtures/ext/vendor/enabled_4/di/extension.php
index 8e5ed6c52c..2164077d8e 100644
--- a/tests/di/fixtures/ext/vendor/enabled_4/di/extension.php
+++ b/tests/di/fixtures/ext/vendor/enabled_4/di/extension.php
@@ -17,6 +17,7 @@ use phpbb\extension\di\extension_base;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
+use phpbb\filesystem\helper as filesystem_helper;
/**
* Container core extension
@@ -25,8 +26,7 @@ class extension extends extension_base
{
protected function load_services(ContainerBuilder $container)
{
- $filesystem = new \phpbb\filesystem\filesystem();
- $loader = new YamlFileLoader($container, new FileLocator($filesystem->realpath($this->ext_path)));
+ $loader = new YamlFileLoader($container, new FileLocator(filesystem_helper::realpath($this->ext_path)));
$loader->load('environment.yml');
}
}
diff --git a/tests/di/fixtures/other_config/production/container/environment.yml b/tests/di/fixtures/other_config/production/container/environment.yml
index c0d2f87bab..aeb552eeb7 100644
--- a/tests/di/fixtures/other_config/production/container/environment.yml
+++ b/tests/di/fixtures/other_config/production/container/environment.yml
@@ -19,6 +19,11 @@ services:
ext.manager:
class: phpbb\extension\manager_mock
+ config:
+ class: phpbb\config\config
+ arguments:
+ - []
+
template.twig.environment:
class: Exception
arguments:
diff --git a/tests/email/email_parsing_test.php b/tests/email/email_parsing_test.php
index 629df9abb6..a7f76d50a2 100644
--- a/tests/email/email_parsing_test.php
+++ b/tests/email/email_parsing_test.php
@@ -39,7 +39,6 @@ class phpbb_email_parsing_test extends phpbb_test_case
$filesystem = new \phpbb\filesystem\filesystem();
$phpbb_path_helper = new \phpbb\path_helper(
$symfony_request,
- $filesystem,
$request,
$phpbb_root_path,
$phpEx
@@ -73,7 +72,7 @@ class phpbb_email_parsing_test extends phpbb_test_case
$phpbb_path_helper,
$cache_path,
null,
- new \phpbb\template\twig\loader($filesystem, ''),
+ new \phpbb\template\twig\loader(''),
new \phpbb\event\dispatcher($phpbb_container),
array(
'cache' => false,
diff --git a/tests/extension/finder_test.php b/tests/extension/finder_test.php
index 7649b4f19a..c86b81f147 100644
--- a/tests/extension/finder_test.php
+++ b/tests/extension/finder_test.php
@@ -243,7 +243,7 @@ class phpbb_extension_finder_test extends phpbb_test_case
public function test_get_classes_create_cache()
{
$cache = new phpbb_mock_cache;
- $finder = new \phpbb\finder(new \phpbb\filesystem\filesystem(), dirname(__FILE__) . '/', $cache, 'php', '_custom_cache_name');
+ $finder = new \phpbb\finder(dirname(__FILE__) . '/', $cache, 'php', '_custom_cache_name');
$finder->set_extensions(array_keys($this->extension_manager->all_enabled()));
$files = $finder->suffix('_class.php')->get_files();
@@ -283,7 +283,6 @@ class phpbb_extension_finder_test extends phpbb_test_case
);
$finder = new \phpbb\finder(
- new \phpbb\filesystem\filesystem(),
dirname(__FILE__) . '/',
new phpbb_mock_cache(array(
'_ext_finder' => array(
diff --git a/tests/extension/manager_test.php b/tests/extension/manager_test.php
index 3ab0f608d1..5eac7d1951 100644
--- a/tests/extension/manager_test.php
+++ b/tests/extension/manager_test.php
@@ -167,6 +167,7 @@ class phpbb_extension_manager_test extends phpbb_database_test_case
$phpbb_root_path,
$php_ext,
$table_prefix,
+ self::get_core_tables(),
array(),
new \phpbb\db\migration\helper()
);
@@ -176,7 +177,6 @@ class phpbb_extension_manager_test extends phpbb_database_test_case
$container,
$db,
$config,
- new \phpbb\filesystem\filesystem(),
'phpbb_ext',
dirname(__FILE__) . '/',
$php_ext,
diff --git a/tests/extension/metadata_manager_test.php b/tests/extension/metadata_manager_test.php
index a2f0542979..2e1a85a013 100644
--- a/tests/extension/metadata_manager_test.php
+++ b/tests/extension/metadata_manager_test.php
@@ -52,13 +52,12 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case
$container = new phpbb_mock_container_builder();
$cache_path = $this->phpbb_root_path . 'cache/twig';
$context = new \phpbb\template\context();
- $loader = new \phpbb\template\twig\loader(new \phpbb\filesystem\filesystem(), '');
+ $loader = new \phpbb\template\twig\loader('');
$filesystem = new \phpbb\filesystem\filesystem();
$phpbb_path_helper = new \phpbb\path_helper(
new \phpbb\symfony_request(
new phpbb_mock_request()
),
- $filesystem,
$this->createMock('\phpbb\request\request'),
$this->phpbb_root_path,
$this->phpEx
@@ -88,6 +87,7 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case
$this->phpbb_root_path,
'php',
$this->table_prefix,
+ self::get_core_tables(),
array(),
new \phpbb\db\migration\helper()
);
@@ -97,7 +97,6 @@ class phpbb_extension_metadata_manager_test extends phpbb_database_test_case
$container,
$this->db,
$this->config,
- new \phpbb\filesystem\filesystem(),
'phpbb_ext',
$this->phpbb_root_path,
$this->phpEx,
diff --git a/tests/feed/attachments_base_test.php b/tests/feed/attachments_base_test.php
index 3798056f10..df91d8cc5d 100644
--- a/tests/feed/attachments_base_test.php
+++ b/tests/feed/attachments_base_test.php
@@ -35,7 +35,6 @@ class phpbb_feed_attachments_base_test extends phpbb_database_test_case
new \phpbb\symfony_request(
new phpbb_mock_request()
),
- $this->filesystem,
$this->createMock('\phpbb\request\request'),
$phpbb_root_path,
'php'
diff --git a/tests/files/types_remote_test.php b/tests/files/types_remote_test.php
index d42a609fbb..3b3d61acac 100644
--- a/tests/files/types_remote_test.php
+++ b/tests/files/types_remote_test.php
@@ -15,10 +15,15 @@ require_once dirname(__FILE__) . '/type_foo.php';
class phpbb_files_types_remote_test extends phpbb_test_case
{
+ /** @var string */
private $path;
+ /** @var \phpbb\filesystem\filesystem */
private $filesystem;
+ /** @var \phpbb\filesystem\temp */
+ private $temp;
+
/** @var \phpbb\config\config */
protected $config;
@@ -49,7 +54,9 @@ class phpbb_files_types_remote_test extends phpbb_test_case
$this->config->set('remote_upload_verify', 0);
$this->request = $this->createMock('\phpbb\request\request');
+ $cache_path = $phpbb_root_path . 'cache/files';
$this->filesystem = new \phpbb\filesystem\filesystem();
+ $this->temp = new \phpbb\filesystem\temp($this->filesystem, $cache_path);
$this->language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx));
$this->php_ini = new \bantu\IniGetWrapper\IniGetWrapper;
@@ -71,7 +78,7 @@ class phpbb_files_types_remote_test extends phpbb_test_case
public function test_upload_fsock_fail()
{
- $type_remote = new \phpbb\files\types\remote($this->config, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
+ $type_remote = new \phpbb\files\types\remote($this->config, $this->factory, $this->temp, $this->language, $this->php_ini, $this->request);
$upload = new \phpbb\files\upload($this->filesystem, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
$upload->set_allowed_extensions(array('png'));
$type_remote->set_upload($upload);
@@ -106,7 +113,7 @@ class phpbb_files_types_remote_test extends phpbb_test_case
$php_ini->expects($this->any())
->method('getString')
->willReturn($max_file_size);
- $type_remote = new \phpbb\files\types\remote($this->config, $this->factory, $this->language, $php_ini, $this->request, $this->phpbb_root_path);
+ $type_remote = new \phpbb\files\types\remote($this->config, $this->factory, $this->temp, $this->language, $php_ini, $this->request);
$upload = new \phpbb\files\upload($this->filesystem, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
$upload->set_allowed_extensions(array('png'));
$type_remote->set_upload($upload);
@@ -118,7 +125,7 @@ class phpbb_files_types_remote_test extends phpbb_test_case
public function test_upload_wrong_path()
{
- $type_remote = new \phpbb\files\types\foo($this->config, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
+ $type_remote = new \phpbb\files\types\foo($this->config, $this->factory, $this->temp, $this->language, $this->php_ini, $this->request);
$upload = new \phpbb\files\upload($this->filesystem, $this->factory, $this->language, $this->php_ini, $this->request, $this->phpbb_root_path);
$upload->set_allowed_extensions(array('png'));
$type_remote->set_upload($upload);
diff --git a/tests/filesystem/helper_clean_path_test.php b/tests/filesystem/helper_clean_path_test.php
new file mode 100644
index 0000000000..d1b5a18f02
--- /dev/null
+++ b/tests/filesystem/helper_clean_path_test.php
@@ -0,0 +1,52 @@
+<?php
+/**
+*
+* This file is part of the phpBB Forum Software package.
+*
+* @copyright (c) phpBB Limited <https://www.phpbb.com>
+* @license GNU General Public License, version 2 (GPL-2.0)
+*
+* For full copyright and license information, please see
+* the docs/CREDITS.txt file.
+*
+*/
+
+use phpbb\filesystem\helper as filesystem_helper;
+
+class phpbb_filesystem_helper_clean_path_test extends phpbb_test_case
+{
+
+ public function setUp(): void
+ {
+ parent::setUp();
+ }
+
+ public function clean_path_data()
+ {
+ yield ['foo', 'foo'];
+ yield ['foo/bar', 'foo/bar'];
+ yield ['foo/bar/', 'foo/bar/'];
+ yield ['foo/./bar', 'foo/bar'];
+ yield ['foo/./././bar', 'foo/bar'];
+ yield ['foo/bar/.', 'foo/bar'];
+ yield ['./foo/bar', './foo/bar'];
+ yield ['../foo/bar', '../foo/bar'];
+ yield ['./../foo/bar', './../foo/bar'];
+ yield ['././../foo/bar', './../foo/bar'];
+ yield ['one/two/three', 'one/two/three'];
+ yield ['one/two/../three', 'one/three'];
+ yield ['one/../two/three', 'two/three'];
+ yield ['one/two/..', 'one'];
+ yield ['one/two/../', 'one/'];
+ yield ['one/two/../three/../four', 'one/four'];
+ yield ['one/two/three/../../four', 'one/four'];
+ }
+
+ /**
+ * @dataProvider clean_path_data
+ */
+ public function test_clean_path($input, $expected)
+ {
+ $this->assertEquals($expected, filesystem_helper::clean_path($input));
+ }
+}
diff --git a/tests/filesystem/helper_is_absolute_test.php b/tests/filesystem/helper_is_absolute_test.php
new file mode 100644
index 0000000000..16356386d1
--- /dev/null
+++ b/tests/filesystem/helper_is_absolute_test.php
@@ -0,0 +1,64 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+use phpbb\filesystem\helper as filesystem_helper;
+
+class phpbb_filesystem_helper_is_absolute_test extends phpbb_test_case
+{
+
+ public function setUp(): void
+ {
+ parent::setUp();
+ }
+
+ static public function is_absolute_data()
+ {
+ // Empty
+ yield ['', false];
+
+ // Absolute unix style
+ yield ['/etc/phpbb', true];
+ // Unix does not support \ so that is not an absolute path
+ yield ['\etc\phpbb', false];
+
+ // Absolute windows style
+ yield ['c:\windows', true];
+ yield ['C:\Windows', true];
+ yield ['c:/windows', true];
+ yield ['C:/Windows', true];
+
+ // Executable
+ yield ['etc/phpbb', false];
+ yield ['explorer.exe', false];
+
+ // Relative subdir
+ yield ['Windows\System32', false];
+ yield ['Windows\System32\explorer.exe', false];
+ yield ['Windows/System32', false];
+ yield ['Windows/System32/explorer.exe', false];
+
+ // Relative updir
+ yield ['..\Windows\System32', false];
+ yield ['..\Windows\System32\explorer.exe', false];
+ yield ['../Windows/System32', false];
+ yield ['../Windows/System32/explorer.exe', false];
+ }
+
+ /**
+ * @dataProvider is_absolute_data
+ */
+ public function test_is_absolute($path, $expected)
+ {
+ $this->assertEquals($expected, filesystem_helper::is_absolute_path($path));
+ }
+}
diff --git a/tests/filesystem/helper_realpath_test.php b/tests/filesystem/helper_realpath_test.php
new file mode 100644
index 0000000000..bfb871384b
--- /dev/null
+++ b/tests/filesystem/helper_realpath_test.php
@@ -0,0 +1,83 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+use phpbb\filesystem\helper as filesystem_helper;
+
+class phpbb_filesystem_helper_realpath_test extends phpbb_test_case
+{
+ protected static $filesystem_helper_phpbb_own_realpath;
+
+ static public function setUpBeforeClass()
+ {
+ parent::setUpBeforeClass();
+
+ self::$filesystem_helper_phpbb_own_realpath = new ReflectionMethod('\phpbb\filesystem\helper', 'phpbb_own_realpath');
+ self::$filesystem_helper_phpbb_own_realpath->setAccessible(true);
+ }
+
+ public function setUp(): void
+ {
+ parent::setUp();
+ }
+
+ public function realpath_resolve_absolute_without_symlinks_data()
+ {
+ // Constant data
+ yield [__DIR__, __DIR__];
+ yield [__DIR__ . '/../filesystem/../filesystem', __DIR__];
+ yield [__DIR__ . '/././', __DIR__];
+ yield [__DIR__ . '/non_existent', false];
+
+ yield [__FILE__, __FILE__];
+ yield [__FILE__ . '../', false];
+ }
+
+ public function realpath_resolve_relative_without_symlinks_data()
+ {
+ if (!function_exists('getcwd'))
+ {
+ yield [];
+ }
+ else
+ {
+ $relative_path = filesystem_helper::make_path_relative(__DIR__, getcwd());
+
+ yield [$relative_path, __DIR__];
+ yield [$relative_path . '../filesystem/../filesystem', __DIR__];
+ yield [$relative_path . '././', __DIR__];
+
+ yield [$relative_path . 'helper_realpath_test.php', __FILE__];
+ }
+ }
+
+ /**
+ * @dataProvider realpath_resolve_absolute_without_symlinks_data
+ */
+ public function test_realpath_absolute_without_links($path, $expected)
+ {
+ $this->assertEquals($expected, self::$filesystem_helper_phpbb_own_realpath->invoke(null, $path));
+ }
+
+ /**
+ * @dataProvider realpath_resolve_relative_without_symlinks_data
+ */
+ public function test_realpath_relative_without_links($path, $expected)
+ {
+ if (!function_exists('getcwd'))
+ {
+ $this->markTestSkipped('phpbb_own_realpath() cannot be tested with relative paths: getcwd is not available.');
+ }
+
+ $this->assertEquals($expected, self::$filesystem_helper_phpbb_own_realpath->invoke(null, $path));
+ }
+}
diff --git a/tests/functional/fileupload_remote_test.php b/tests/functional/fileupload_remote_test.php
index 25fc9f0508..f327981960 100644
--- a/tests/functional/fileupload_remote_test.php
+++ b/tests/functional/fileupload_remote_test.php
@@ -19,6 +19,9 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case
/** @var \phpbb\filesystem\filesystem_interface */
protected $filesystem;
+ /** @var \phpbb\filesystem\temp */
+ protected $temp;
+
/** @var \phpbb\files\factory */
protected $factory;
@@ -53,6 +56,7 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case
$config['remote_upload_verify'] = 0;
$this->filesystem = new \phpbb\filesystem\filesystem();
+ $this->temp = new \phpbb\filesystem\temp($this->filesystem, '');
$this->language = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx));
$this->request = $this->createMock('\phpbb\request\request');
$this->php_ini = new \bantu\IniGetWrapper\IniGetWrapper;
@@ -61,7 +65,7 @@ class phpbb_functional_fileupload_remote_test extends phpbb_functional_test_case
$container->set('files.filespec', new \phpbb\files\filespec($this->filesystem, $this->language, $this->php_ini, new \FastImageSize\FastImageSize(), $this->phpbb_root_path));
$this->factory = new \phpbb\files\factory($container);
$container->set('files.factory', $this->factory);
- $container->set('files.types.remote', new \phpbb\files\types\remote($config, $this->factory, $this->language, $this->php_ini, $this->request, $phpbb_root_path));
+ $container->set('files.types.remote', new \phpbb\files\types\remote($config, $this->factory, $this->temp, $this->language, $this->php_ini, $this->request));
$this->phpbb_root_path = $phpbb_root_path;
}
diff --git a/tests/functional/notification_test.php b/tests/functional/notification_test.php
index 91fc962846..4ca1d4b637 100644
--- a/tests/functional/notification_test.php
+++ b/tests/functional/notification_test.php
@@ -77,12 +77,12 @@ class phpbb_functional_notification_test extends phpbb_functional_test_case
$crawler = self::request('GET', 'ucp.php?i=ucp_notifications');
// At least one notification should exist
- $this->assertGreaterThan(0, $crawler->filter('#notification_list_button strong')->text());
+ $this->assertGreaterThan(0, $crawler->filter('#notification-button strong')->text());
// Get form token
$link = $crawler->selectLink($this->lang('NOTIFICATIONS_MARK_ALL_READ'))->link()->getUri();
$crawler = self::request('GET', substr($link, strpos($link, 'ucp.')));
- $this->assertCount(1, $crawler->filter('#notification_list_button strong.badge.hidden'));
- $this->assertEquals("0", $crawler->filter('#notification_list_button strong.badge.hidden')->text());
+ $this->assertCount(1, $crawler->filter('#notification-button strong.badge.hidden'));
+ $this->assertEquals("0", $crawler->filter('#notification-button strong.badge.hidden')->text());
}
}
diff --git a/tests/functions/build_url_test.php b/tests/functions/build_url_test.php
index 1519549d3e..d1e3481b38 100644
--- a/tests/functions/build_url_test.php
+++ b/tests/functions/build_url_test.php
@@ -27,7 +27,6 @@ class phpbb_build_url_test extends phpbb_test_case
new \phpbb\symfony_request(
new phpbb_mock_request()
),
- new \phpbb\filesystem\filesystem(),
$this->createMock('\phpbb\request\request'),
$phpbb_root_path,
'php'
diff --git a/tests/functions_user/delete_user_test.php b/tests/functions_user/delete_user_test.php
index 7e414dad86..52fb4f3d42 100644
--- a/tests/functions_user/delete_user_test.php
+++ b/tests/functions_user/delete_user_test.php
@@ -39,8 +39,11 @@ class phpbb_functions_user_delete_user_test extends phpbb_database_test_case
$phpbb_dispatcher = new phpbb_mock_event_dispatcher();
$phpbb_container = new phpbb_mock_container_builder();
$phpbb_container->set('notification_manager', new phpbb_mock_notification_manager());
+
+ $storage = $this->createMock('\phpbb\storage\storage');
+
// Works as a workaround for tests
- $phpbb_container->set('attachment.manager', new \phpbb\attachment\delete($config, $db, new \phpbb_mock_event_dispatcher(), new \phpbb\filesystem\filesystem(), new \phpbb\attachment\resync($db), $phpbb_root_path));
+ $phpbb_container->set('attachment.manager', new \phpbb\attachment\delete($config, $db, new \phpbb_mock_event_dispatcher(), new \phpbb\attachment\resync($db), $storage));
$phpbb_container->set(
'auth.provider.db',
new phpbb_mock_auth_provider()
diff --git a/tests/migrator/convert_timezones_test.php b/tests/migrator/convert_timezones_test.php
index 4bb0aec34f..5bb8d7ab93 100644
--- a/tests/migrator/convert_timezones_test.php
+++ b/tests/migrator/convert_timezones_test.php
@@ -64,7 +64,8 @@ class phpbb_migrator_convert_timezones_test extends phpbb_database_test_case
$factory->get($this->db),
$phpbb_root_path,
$phpEx,
- 'phpbb_'
+ 'phpbb_',
+ self::get_core_tables()
);
}
diff --git a/tests/migrator/get_callable_from_step_test.php b/tests/migrator/get_callable_from_step_test.php
index b0abb6199c..809b977d57 100644
--- a/tests/migrator/get_callable_from_step_test.php
+++ b/tests/migrator/get_callable_from_step_test.php
@@ -43,6 +43,7 @@ class get_callable_from_step_test extends phpbb_database_test_case
$phpbb_root_path,
$php_ext,
$table_prefix,
+ self::get_core_tables(),
array($module_tools),
new \phpbb\db\migration\helper()
);
diff --git a/tests/migrator/schema_generator_test.php b/tests/migrator/schema_generator_test.php
index 1349b98953..dd7158cbfd 100644
--- a/tests/migrator/schema_generator_test.php
+++ b/tests/migrator/schema_generator_test.php
@@ -41,7 +41,7 @@ class schema_generator_test extends phpbb_test_case
protected function get_schema_generator(array $class_names)
{
- $this->generator = new \phpbb\db\migration\schema_generator($class_names, $this->config, $this->db, $this->db_tools, $this->phpbb_root_path, $this->php_ext, $this->table_prefix);
+ $this->generator = new \phpbb\db\migration\schema_generator($class_names, $this->config, $this->db, $this->db_tools, $this->phpbb_root_path, $this->php_ext, $this->table_prefix, phpbb_database_test_case::get_core_tables());
return $this->generator;
}
diff --git a/tests/notification/convert_test.php b/tests/notification/convert_test.php
index d4a33ff537..d1707cc70f 100644
--- a/tests/notification/convert_test.php
+++ b/tests/notification/convert_test.php
@@ -36,7 +36,8 @@ class phpbb_notification_convert_test extends phpbb_database_test_case
$factory->get($this->db),
$phpbb_root_path,
$phpEx,
- 'phpbb_'
+ 'phpbb_',
+ self::get_core_tables()
);
}
diff --git a/tests/notification/group_request_test.php b/tests/notification/group_request_test.php
index b935b180d9..f5f0013770 100644
--- a/tests/notification/group_request_test.php
+++ b/tests/notification/group_request_test.php
@@ -60,7 +60,6 @@ class phpbb_notification_group_request_test extends phpbb_tests_notification_bas
new \phpbb\symfony_request(
new phpbb_mock_request()
),
- new \phpbb\filesystem\filesystem(),
$this->getMockBuilder('\phpbb\request\request')->disableOriginalConstructor()->getMock(),
$phpbb_root_path,
$phpEx
diff --git a/tests/notification/submit_post_base.php b/tests/notification/submit_post_base.php
index 466d3ec07f..fe0e937837 100644
--- a/tests/notification/submit_post_base.php
+++ b/tests/notification/submit_post_base.php
@@ -91,6 +91,9 @@ abstract class phpbb_notification_submit_post_base extends phpbb_database_test_c
// Language
$lang = new \phpbb\language\language(new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx));
+ // Storage
+ $storage = $this->createMock('\phpbb\storage\storage');
+
// User
$user = $this->createMock('\phpbb\user', array(), array(
$lang,
@@ -125,6 +128,7 @@ abstract class phpbb_notification_submit_post_base extends phpbb_database_test_c
$phpbb_container->set('cache', $cache);
$phpbb_container->set('text_formatter.utils', new \phpbb\textformatter\s9e\utils());
$phpbb_container->set('dispatcher', $phpbb_dispatcher);
+ $phpbb_container->set('storage.attachment', $storage);
$phpbb_container->setParameter('core.root_path', $phpbb_root_path);
$phpbb_container->setParameter('core.php_ext', $phpEx);
$phpbb_container->setParameter('tables.notifications', 'phpbb_notifications');
diff --git a/tests/pagination/pagination_test.php b/tests/pagination/pagination_test.php
index 073ba1d5cd..cd7420a0eb 100644
--- a/tests/pagination/pagination_test.php
+++ b/tests/pagination/pagination_test.php
@@ -39,12 +39,11 @@ class phpbb_pagination_pagination_test extends phpbb_template_template_test_case
$this->config = new \phpbb\config\config(array('enable_mod_rewrite' => '1'));
- $filesystem = new \phpbb\filesystem\filesystem();
$manager = new phpbb_mock_extension_manager(dirname(__FILE__) . '/', array());
$loader = new \Symfony\Component\Routing\Loader\YamlFileLoader(
- new \phpbb\routing\file_locator($filesystem, dirname(__FILE__) . '/')
+ new \phpbb\routing\file_locator(dirname(__FILE__) . '/')
);
$resources_locator = new \phpbb\routing\resources_locator\default_resources_locator(dirname(__FILE__) . '/', PHPBB_ENVIRONMENT, $manager);
$router = new phpbb_mock_router(new phpbb_mock_container_builder(), $resources_locator, $loader, dirname(__FILE__) . '/', 'php', false);
@@ -58,7 +57,7 @@ class phpbb_pagination_pagination_test extends phpbb_template_template_test_case
$request
);
- $this->routing_helper = new \phpbb\routing\helper($this->config, $router, $symfony_request, $request, $filesystem, '', 'php');
+ $this->routing_helper = new \phpbb\routing\helper($this->config, $router, $symfony_request, $request, '', 'php');
$this->helper = new phpbb_mock_controller_helper($this->template, $this->user, $this->config, $symfony_request, $request, $this->routing_helper);
$this->pagination = new \phpbb\pagination($this->template, $this->user, $this->helper, $phpbb_dispatcher);
}
diff --git a/tests/path_helper/path_helper_test.php b/tests/path_helper/path_helper_test.php
index 31182c2daf..bca0f0eb07 100644
--- a/tests/path_helper/path_helper_test.php
+++ b/tests/path_helper/path_helper_test.php
@@ -11,6 +11,8 @@
*
*/
+use phpbb\filesystem\helper as filesystem_helper;
+
class phpbb_path_helper_test extends phpbb_test_case
{
/** @var \phpbb\path_helper */
@@ -21,14 +23,12 @@ class phpbb_path_helper_test extends phpbb_test_case
{
parent::setUp();
- $filesystem = new \phpbb\filesystem\filesystem();
- $this->set_phpbb_root_path($filesystem);
+ $this->set_phpbb_root_path();
$this->path_helper = new \phpbb\path_helper(
new \phpbb\symfony_request(
new phpbb_mock_request()
),
- new \phpbb\filesystem\filesystem(),
$this->createMock('\phpbb\request\request'),
$this->phpbb_root_path,
'php'
@@ -43,9 +43,9 @@ class phpbb_path_helper_test extends phpbb_test_case
* any time we wish to use it in one of these functions (and
* also in general for everything else)
*/
- public function set_phpbb_root_path($filesystem)
+ public function set_phpbb_root_path()
{
- $this->phpbb_root_path = $filesystem->clean_path(dirname(__FILE__) . '/../../phpBB/');
+ $this->phpbb_root_path = filesystem_helper::clean_path(dirname(__FILE__) . '/../../phpBB/');
}
public function test_get_web_root_path()
@@ -56,8 +56,7 @@ class phpbb_path_helper_test extends phpbb_test_case
public function basic_update_web_root_path_data()
{
- $filesystem = new \phpbb\filesystem\filesystem();
- $this->set_phpbb_root_path($filesystem);
+ $this->set_phpbb_root_path();
return array(
array(
@@ -75,7 +74,7 @@ class phpbb_path_helper_test extends phpbb_test_case
),
array(
$this->phpbb_root_path . $this->phpbb_root_path . 'test.php',
- $filesystem->clean_path($this->phpbb_root_path . $this->phpbb_root_path . 'test.php'),
+ filesystem_helper::clean_path($this->phpbb_root_path . $this->phpbb_root_path . 'test.php'),
),
);
}
@@ -90,7 +89,7 @@ class phpbb_path_helper_test extends phpbb_test_case
public function update_web_root_path_data()
{
- $this->set_phpbb_root_path(new \phpbb\filesystem\filesystem());
+ $this->set_phpbb_root_path();
return array(
array(
@@ -181,7 +180,6 @@ class phpbb_path_helper_test extends phpbb_test_case
$path_helper = new \phpbb\path_helper(
$symfony_request,
- new \phpbb\filesystem\filesystem(),
$this->createMock('\phpbb\request\request'),
$this->phpbb_root_path,
'php'
diff --git a/tests/privmsgs/delete_user_pms_test.php b/tests/privmsgs/delete_user_pms_test.php
index 9d6ba7a917..f1d717f03c 100644
--- a/tests/privmsgs/delete_user_pms_test.php
+++ b/tests/privmsgs/delete_user_pms_test.php
@@ -91,8 +91,11 @@ class phpbb_privmsgs_delete_user_pms_test extends phpbb_database_test_case
$phpbb_container = new phpbb_mock_container_builder();
$phpbb_container->set('notification_manager', new phpbb_mock_notification_manager());
+
+ $storage = $this->createMock('\phpbb\storage\storage');
+
// Works as a workaround for tests
- $phpbb_container->set('attachment.manager', new \phpbb\attachment\delete(new \phpbb\config\config(array()), $db, new \phpbb_mock_event_dispatcher(), new \phpbb\filesystem\filesystem(), new \phpbb\attachment\resync($db), $phpbb_root_path));
+ $phpbb_container->set('attachment.manager', new \phpbb\attachment\delete(new \phpbb\config\config(array()), $db, new \phpbb_mock_event_dispatcher(), new \phpbb\attachment\resync($db), $storage));
phpbb_delete_user_pms($delete_user);
diff --git a/tests/security/redirect_test.php b/tests/security/redirect_test.php
index 8bde1488d8..4630bc8dc5 100644
--- a/tests/security/redirect_test.php
+++ b/tests/security/redirect_test.php
@@ -68,7 +68,6 @@ class phpbb_security_redirect_test extends phpbb_security_test_base
new \phpbb\symfony_request(
new phpbb_mock_request()
),
- new \phpbb\filesystem\filesystem(),
$this->createMock('\phpbb\request\request'),
$phpbb_root_path,
'php'
diff --git a/tests/storage/adapter/local_subfolders_test.php b/tests/storage/adapter/local_subfolders_test.php
new file mode 100644
index 0000000000..de02fceefa
--- /dev/null
+++ b/tests/storage/adapter/local_subfolders_test.php
@@ -0,0 +1,136 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+ class phpbb_storage_adapter_local_subfolders_test extends phpbb_test_case
+ {
+ protected $adapter;
+
+ protected $path;
+
+ protected $filesystem;
+
+ public function setUp(): void
+ {
+ parent::setUp();
+
+ $this->filesystem = new \phpbb\filesystem\filesystem();
+ $phpbb_root_path = getcwd() . DIRECTORY_SEPARATOR;
+
+ $this->adapter = new \phpbb\storage\adapter\local($this->filesystem, new \FastImageSize\FastImageSize(), new \phpbb\mimetype\guesser(array(new \phpbb\mimetype\extension_guesser)), $phpbb_root_path);
+ $this->adapter->configure(['path' => 'test_path', 'subfolders' => true]);
+
+ $this->path = $phpbb_root_path . 'test_path/';
+ mkdir($this->path);
+ }
+
+ public function tearDown(): void
+ {
+ $this->adapter = null;
+ rmdir($this->path);
+ }
+
+ public function test_put_contents()
+ {
+ $this->adapter->put_contents('file.txt', 'abc');
+ $this->assertTrue(file_exists($this->path . '3d/8e/file.txt'));
+ $this->assertEquals(file_get_contents($this->path . '3d/8e/file.txt'), 'abc');
+ unlink($this->path . '3d/8e/file.txt');
+ rmdir($this->path . '3d/8e');
+ rmdir($this->path . '3d');
+ }
+
+ public function test_get_contents()
+ {
+ mkdir($this->path . '3d/8e', 0777, true);
+ file_put_contents($this->path . '3d/8e/file.txt', 'abc');
+ $this->assertEquals($this->adapter->get_contents('file.txt'), 'abc');
+ unlink($this->path . '3d/8e/file.txt');
+ rmdir($this->path . '3d/8e');
+ rmdir($this->path . '3d');
+ }
+
+ public function test_exists()
+ {
+ mkdir($this->path . '3d/8e', 0777, true);
+ touch($this->path . '3d/8e/file.txt');
+ $this->assertTrue($this->adapter->exists('file.txt'));
+ $this->assertFalse($this->adapter->exists('3d/8e/file.txt'));
+ unlink($this->path . '3d/8e/file.txt');
+ rmdir($this->path . '3d/8e');
+ rmdir($this->path . '3d');
+ }
+
+ public function test_delete_file()
+ {
+ mkdir($this->path . '3d/8e', 0777, true);
+ touch($this->path . '3d/8e/file.txt');
+ $this->assertTrue(file_exists($this->path . '3d/8e/file.txt'));
+ $this->adapter->delete('file.txt');
+ $this->assertFalse(file_exists($this->path . '3d/8e/file.txt'));
+ $this->assertFalse(file_exists($this->path . '3d'));
+ }
+
+ public function test_rename()
+ {
+ mkdir($this->path . '3d/8e', 0777, true);
+ touch($this->path . '3d/8e/file.txt');
+ $this->adapter->rename('file.txt', 'file2.txt');
+ $this->assertFalse(file_exists($this->path . '3d/8e/file.txt'));
+ $this->assertTrue(file_exists($this->path . '27/36/file2.txt'));
+ $this->assertFalse(file_exists($this->path . '3d'));
+ unlink($this->path . '27/36/file2.txt');
+ rmdir($this->path . '27/36');
+ rmdir($this->path . '27');
+ }
+
+ public function test_copy()
+ {
+ mkdir($this->path . '3d/8e', 0777, true);
+ file_put_contents($this->path . '3d/8e/file.txt', 'abc');
+ $this->adapter->copy('file.txt', 'file2.txt');
+ $this->assertEquals(file_get_contents($this->path . '3d/8e/file.txt'), 'abc');
+ $this->assertEquals(file_get_contents($this->path . '27/36/file2.txt'), 'abc');
+ unlink($this->path . '3d/8e/file.txt');
+ rmdir($this->path . '3d/8e');
+ rmdir($this->path . '3d');
+ unlink($this->path . '27/36/file2.txt');
+ rmdir($this->path . '27/36');
+ rmdir($this->path . '27');
+ }
+
+ public function test_read_stream()
+ {
+ mkdir($this->path . '3d/8e', 0777, true);
+ touch($this->path . '3d/8e/file.txt');
+ $stream = $this->adapter->read_stream('file.txt');
+ $this->assertTrue(is_resource($stream));
+ fclose($stream);
+ unlink($this->path . '3d/8e/file.txt');
+ rmdir($this->path . '3d/8e');
+ rmdir($this->path . '3d');
+ }
+
+ public function test_write_stream()
+ {
+ file_put_contents($this->path . 'file.txt', 'abc');
+ $stream = fopen($this->path . 'file.txt', 'rb');
+ $this->adapter->write_stream('file2.txt', $stream);
+ fclose($stream);
+ $this->assertEquals(file_get_contents($this->path . '27/36/file2.txt'), 'abc');
+ unlink($this->path . 'file.txt');
+ unlink($this->path . '27/36/file2.txt');
+ rmdir($this->path . '27/36');
+ rmdir($this->path . '27');
+ }
+
+ }
diff --git a/tests/storage/adapter/local_test.php b/tests/storage/adapter/local_test.php
new file mode 100644
index 0000000000..e44f0e2023
--- /dev/null
+++ b/tests/storage/adapter/local_test.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ *
+ * This file is part of the phpBB Forum Software package.
+ *
+ * @copyright (c) phpBB Limited <https://www.phpbb.com>
+ * @license GNU General Public License, version 2 (GPL-2.0)
+ *
+ * For full copyright and license information, please see
+ * the docs/CREDITS.txt file.
+ *
+ */
+
+ class phpbb_storage_adapter_local_test extends phpbb_test_case
+ {
+ protected $adapter;
+
+ protected $path;
+
+ protected $filesystem;
+
+ public function setUp(): void
+ {
+ parent::setUp();
+
+ $this->filesystem = new \phpbb\filesystem\filesystem();
+ $phpbb_root_path = getcwd() . DIRECTORY_SEPARATOR;
+
+ $this->adapter = new \phpbb\storage\adapter\local($this->filesystem, new \FastImageSize\FastImageSize(), new \phpbb\mimetype\guesser(array(new \phpbb\mimetype\extension_guesser)), $phpbb_root_path);
+ $this->adapter->configure(['path' => 'test_path', 'subfolders' => false]);
+
+ $this->path = $phpbb_root_path . 'test_path/';
+ mkdir($this->path);
+ }
+
+ public function tearDown(): void
+ {
+ $this->adapter = null;
+ rmdir($this->path);
+ }
+
+ public function test_put_contents()
+ {
+ $this->adapter->put_contents('file.txt', 'abc');
+ $this->assertTrue(file_exists($this->path . 'file.txt'));
+ $this->assertEquals(file_get_contents($this->path . 'file.txt'), 'abc');
+ unlink($this->path . 'file.txt');
+ }
+
+ public function test_get_contents()
+ {
+ file_put_contents($this->path . 'file.txt', 'abc');
+ $this->assertEquals($this->adapter->get_contents('file.txt'), 'abc');
+ unlink($this->path . 'file.txt');
+ }
+
+ public function test_exists()
+ {
+ touch($this->path . 'file.txt');
+ $this->assertTrue($this->adapter->exists('file.txt'));
+ $this->assertFalse($this->adapter->exists('noexist.txt'));
+ unlink($this->path . 'file.txt');
+ }
+
+ public function test_delete_file()
+ {
+ touch($this->path . 'file.txt');
+ $this->assertTrue(file_exists($this->path . 'file.txt'));
+ $this->adapter->delete('file.txt');
+ $this->assertFalse(file_exists($this->path . 'file.txt'));
+ }
+
+ public function test_rename()
+ {
+ touch($this->path . 'file.txt');
+ $this->adapter->rename('file.txt', 'file2.txt');
+ $this->assertFalse(file_exists($this->path . 'file.txt'));
+ $this->assertTrue(file_exists($this->path . 'file2.txt'));
+ $this->assertFalse(file_exists($this->path . 'file.txt'));
+ unlink($this->path . 'file2.txt');
+ }
+
+ public function test_copy()
+ {
+ file_put_contents($this->path . 'file.txt', 'abc');
+ $this->adapter->copy('file.txt', 'file2.txt');
+ $this->assertEquals(file_get_contents($this->path . 'file.txt'), 'abc');
+ $this->assertEquals(file_get_contents($this->path . 'file2.txt'), 'abc');
+ unlink($this->path . 'file.txt');
+ unlink($this->path . 'file2.txt');
+ }
+
+ public function test_read_stream()
+ {
+ touch($this->path . 'file.txt');
+ $stream = $this->adapter->read_stream('file.txt');
+ $this->assertTrue(is_resource($stream));
+ fclose($stream);
+ unlink($this->path . 'file.txt');
+ }
+
+ public function test_write_stream()
+ {
+ file_put_contents($this->path . 'file.txt', 'abc');
+ $stream = fopen($this->path . 'file.txt', 'rb');
+ $this->adapter->write_stream('file2.txt', $stream);
+ fclose($stream);
+ $this->assertEquals(file_get_contents($this->path . 'file2.txt'), 'abc');
+ unlink($this->path . 'file.txt');
+ unlink($this->path . 'file2.txt');
+ }
+
+ }
diff --git a/tests/template/extension_test.php b/tests/template/extension_test.php
index d633001060..5d73aed91e 100644
--- a/tests/template/extension_test.php
+++ b/tests/template/extension_test.php
@@ -15,7 +15,7 @@ require_once dirname(__FILE__) . '/template_test_case.php';
class phpbb_template_extension_test extends phpbb_template_template_test_case
{
- protected function setup_engine(array $new_config = array())
+ protected function setup_engine(array $new_config = [])
{
global $config, $phpbb_container, $phpbb_dispatcher, $phpbb_root_path, $phpEx;
@@ -28,6 +28,7 @@ class phpbb_template_extension_test extends phpbb_template_template_test_case
$lang_loader = new \phpbb\language\language_file_loader($phpbb_root_path, $phpEx);
$this->lang = $lang = new \phpbb\language\language($lang_loader);
$this->user = new \phpbb\user($lang, '\phpbb\datetime');
+ $this->user->style['style_path'] = 'chameleon';
global $auth, $request, $symfony_request, $user;
$user = new phpbb_mock_user();
@@ -39,23 +40,33 @@ class phpbb_template_extension_test extends phpbb_template_template_test_case
$auth->method('acl_get')
->willReturn(true);
- $filesystem = new \phpbb\filesystem\filesystem();
+ $filesystem = $this->createMock('\phpbb\filesystem\filesystem');
+ $filesystem->expects($this->any())
+ ->method('exists')
+ ->with($this->stringContains('theme/png/'))
+ ->will($this->returnValueMap([
+ ['phpBB/styles/chameleon/theme/png/phone.png', true],
+ ['phpBB/styles/chameleon/theme/png/pencil.png', true],
+ ['phpBB/styles/chameleon/theme/png/user.png', false],
+ ]));
$request = new phpbb_mock_request;
$symfony_request = new \phpbb\symfony_request(
$request
);
$phpbb_path_helper = new \phpbb\path_helper(
$symfony_request,
- $filesystem,
$request,
$phpbb_root_path,
$phpEx
);
+ $storage = $this->getMockBuilder('\phpbb\storage\storage')
+ ->disableOriginalConstructor()
+ ->getMock();
$phpbb_dispatcher = new phpbb_mock_event_dispatcher();
$phpbb_container = new phpbb_mock_container_builder();
$files = new phpbb\files\factory($phpbb_container);
- $upload_avatar_driver = new phpbb\avatar\driver\upload($config, $phpbb_root_path, $phpEx, $filesystem, $phpbb_path_helper, $phpbb_dispatcher, $files);
+ $upload_avatar_driver = new phpbb\avatar\driver\upload($config, $phpbb_root_path, $phpEx, $storage, $phpbb_path_helper, $phpbb_dispatcher, $files, new \bantu\IniGetWrapper\IniGetWrapper());
$upload_avatar_driver->set_name('avatar.driver.upload');
$phpbb_container->set('avatar.manager', new \phpbb\avatar\manager($config, $phpbb_dispatcher, [
$upload_avatar_driver,
@@ -71,7 +82,7 @@ class phpbb_template_extension_test extends phpbb_template_template_test_case
$cache_path = $phpbb_root_path . 'cache/twig';
$context = new \phpbb\template\context();
- $loader = new \phpbb\template\twig\loader($filesystem);
+ $loader = new \phpbb\template\twig\loader([]);
$twig = new \phpbb\template\twig\environment(
$config,
$filesystem,
@@ -80,12 +91,12 @@ class phpbb_template_extension_test extends phpbb_template_template_test_case
null,
$loader,
new \phpbb\event\dispatcher($phpbb_container),
- array(
+ [
'cache' => false,
'debug' => false,
'auto_reload' => true,
'autoescape' => false,
- )
+ ]
);
$this->template = new phpbb\template\twig\twig(
$phpbb_path_helper,
@@ -98,11 +109,17 @@ class phpbb_template_extension_test extends phpbb_template_template_test_case
new \phpbb\template\twig\extension($context, $twig, $this->lang),
new \phpbb\template\twig\extension\avatar(),
new \phpbb\template\twig\extension\config($config),
+ new \phpbb\template\twig\extension\icon($this->user),
new \phpbb\template\twig\extension\username(),
]
);
$twig->setLexer(new \phpbb\template\twig\lexer($twig));
- $this->template->set_custom_style('tests', $this->template_path);
+
+ $this->template->set_custom_style('tests', [
+ $this->template_path,
+ $phpbb_root_path . 'styles/all/imgs',
+ $phpbb_root_path . 'styles/all/template',
+ ]);
}
public function data_template_extensions()
@@ -251,8 +268,287 @@ class phpbb_template_extension_test extends phpbb_template_template_test_case
/**
* @dataProvider data_template_extensions
*/
- public function test_get_user_avatar($file, $vars, $block_vars, $destroy_array, $expected, $lang_vars = [])
+ public function test_template_extensions($file, $vars, $block_vars, $destroy_array, $expected, $lang_vars = [])
{
$this->run_template($file, $vars, $block_vars, $destroy_array, $expected, $lang_vars);
}
+
+ public function data_template_icon_extension()
+ {
+ return [
+ /** Font: default */
+ [
+ [
+ 'type' => 'font',
+ 'icon' => 'phone',
+ 'title' => 'ICON_PHONE',
+ 'hidden' => false,
+ 'classes' => '',
+ 'attributes' => [],
+ ],
+ [
+ 'ICON_PHONE' => 'Phone icon',
+ ],
+ '<i class="o-icon o-icon-font fa-phone"></i><span>Phone icon</span>',
+
+ ],
+ /** Font: all options */
+ [
+ [
+ 'type' => 'font',
+ 'icon' => 'pencil',
+ 'title' => 'ICON_PENCIL',
+ 'hidden' => true,
+ 'classes' => 'a-class another-class',
+ 'attributes' => [
+ 'data-attr-1' => 'true',
+ 'data-attr-2' => 'two',
+ ],
+ ],
+ [
+ 'ICON_PENCIL' => 'Pencil icon',
+ ],
+ '<i class="o-icon o-icon-font fa-pencil a-class another-class" title="Pencil icon" aria-hidden="true" data-attr-1="true" data-attr-2="two"></i>
+ <span class="sr-only">Pencil icon</span>'
+ ],
+ /** Font: icons array */
+ [
+ [
+ 'type' => 'font',
+ 'icon' => [
+ 'bullhorn' => false,
+ 'star' => false,
+ 'lock' => true,
+ 'fire' => false,
+ 'file' => true,
+ ],
+ 'title' => 'ICON_TOPIC',
+ 'hidden' => false,
+ 'classes' => '',
+ 'attributes' => [],
+ ],
+ [
+ 'ICON_TOPIC' => 'Topic icon',
+ ],
+ '<i class="o-icon o-icon-font fa-lock"></i>
+ <span>Topic icon</span>',
+ ],
+ /** Font: icons array with no key for the default */
+ [
+ [
+ 'type' => 'font',
+ 'icon' => [
+ 'bullhorn' => false,
+ 'star' => false,
+ 'lock' => false,
+ 'fire' => false,
+ 'file',
+ ],
+ 'title' => 'ICON_TOPIC',
+ 'hidden' => false,
+ 'classes' => '',
+ 'attributes' => [],
+ ],
+ [
+ 'ICON_TOPIC' => 'Topic icon',
+ ],
+ '<i class="o-icon o-icon-font fa-file"></i>
+ <span>Topic icon</span>',
+ ],
+ /** Iconify: default */
+ [
+ [
+ 'type' => 'iconify',
+ 'icon' => 'fa:phone',
+ 'title' => '',
+ 'hidden' => false,
+ 'classes' => '',
+ 'attributes' => [],
+ ],
+ [],
+ '<i class="iconify o-icon-src-fa o-icon" data-icon="fa:phone" data-inline="true"></i>',
+ ],
+ /** Iconify: all options */
+ [
+ [
+ 'type' => 'iconify',
+ 'icon' => 'mdi:pencil',
+ 'title' => 'ICON_PENCIL',
+ 'hidden' => true,
+ 'classes' => 'icon-lg',
+ 'attributes' => [
+ 'style' => 'color: #12a3eb;',
+ ],
+ ],
+ [
+ 'ICON_PENCIL' => 'Pencil icon',
+ ],
+ '<i class="iconify o-icon-src-mdi o-icon icon-lg" title="Pencil icon" aria-hidden="true" data-icon="mdi:pencil" data-inline="true" style="color: #12a3eb;"></i>
+ <span class="sr-only">Pencil icon</span>',
+ ],
+ /** PNG: default */
+ [
+ [
+ 'type' => 'png',
+ 'icon' => 'phone',
+ 'title' => 'ICON_PHONE',
+ 'hidden' => false,
+ 'classes' => '',
+ 'attributes' => [],
+ ],
+ [
+ 'ICON_PHONE' => 'Phone icon',
+ ],
+ '<img class="o-icon o-icon-png png-phone" src="phpBB/styles/chameleon/theme/png/phone.png" alt="Phone icon" />',
+ ],
+ /** PNG: all options */
+ [
+ [
+ 'type' => 'png',
+ 'icon' => 'pencil',
+ 'title' => 'ICON_PENCIL',
+ 'hidden' => true,
+ 'classes' => 'my-class',
+ 'attributes' => [
+ 'data-url' => 'my-test-url/test-page.php?u=2',
+ ],
+ ],
+ [
+ 'ICON_PENCIL' => 'Pencil icon',
+ ],
+ '<img class="o-icon o-icon-png png-pencil my-class" src="phpBB/styles/chameleon/theme/png/pencil.png" alt="Pencil icon" data-url="my-test-url/test-page.php?u=2" />',
+ ],
+ /** PNG: Not found */
+ [
+ [
+ 'type' => 'png',
+ 'icon' => 'user',
+ 'title' => 'ICON_USER',
+ 'hidden' => false,
+ 'classes' => 'my-class',
+ 'attributes' => [],
+ ],
+ [
+ 'ICON_USER' => 'User icon',
+ ],
+ '<svg class="o-icon o-icon-svg svg-404 my-class" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" aria-labelledby="icon_user-123456789" role="img">
+ <title id="icon_user-123456789">User icon</title>
+ <g fill="none" fill-rule="evenodd">
+ <path fill="#D8D8D8" d="M0 0h512v512H0z"></path>
+ <path fill="#979797" fill-rule="nonzero" d="M8 6.586l496 496v2.828L8 9.414z"></path>
+ <path fill="#979797" fill-rule="nonzero" d="M504 7.586v2.828l-496 496v-2.828z"></path>
+ </g>
+ </svg>',
+ ],
+ /** SVG: default */
+ [
+ [
+ 'type' => 'svg',
+ 'icon' => 'phone',
+ 'title' => 'ICON_PHONE',
+ 'hidden' => false,
+ 'classes' => '',
+ 'attributes' => [],
+ ],
+ [
+ 'ICON_PHONE' => 'Phone icon',
+ ],
+ '<svg class="o-icon o-icon-svg svg-phone" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-labelledby="icon_phone-123456789" role="img">
+ <title id="icon_phone-123456789">Phone icon</title>
+ <path fill="none" d="M0 0h24v24H0z"></path>
+ <path d="M20.01 15.38c-1.23 0-2.42-.2-3.53-.56-.35-.12-.74-.03-1.01.24l-1.57 1.97c-2.83-1.35-5.48-3.9-6.89-6.83l1.95-1.66c.27-.28.35-.67.24-1.02-.37-1.11-.56-2.3-.56-3.53 0-.54-.45-.99-.99-.99H4.19C3.65 3 3 3.24 3 3.99 3 13.28 10.73 21 20.01 21c.71 0 .99-.63.99-1.18v-3.45c0-.54-.45-.99-.99-.99z"></path>
+ </svg>',
+ ],
+ /** SVG: all options */
+ [
+ [
+ 'type' => 'svg',
+ 'icon' => 'pencil',
+ 'title' => 'ICON_PENCIL',
+ 'hidden' => true,
+ 'classes' => 'my-svg-class',
+ 'attributes' => [
+ 'data-ajax' => 'my_ajax_callback',
+ ],
+ ],
+ [
+ 'ICON_PENCIL' => 'Pencil icon',
+ ],
+ '<svg class="o-icon o-icon-svg svg-pencil my-svg-class" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" aria-hidden="true" aria-labelledby="icon_pencil-123456789" role="img" data-ajax="my_ajax_callback">
+ <title id="icon_pencil-123456789">Pencil icon</title>
+ <path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"></path>
+ <path d="M0 0h24v24H0z" fill="none"></path>
+ </svg>',
+ ],
+ /** SVG: Not found */
+ [
+ [
+ 'type' => 'svg',
+ 'icon' => 'not-existent',
+ 'title' => 'Just a title',
+ 'hidden' => false,
+ 'classes' => '',
+ 'attributes' => [],
+ ],
+ [],
+ '<svg class="o-icon o-icon-svg svg-404" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" aria-labelledby="just_a_title-123456789" role="img">
+ <title id="just_a_title-123456789">Just a title</title>
+ <g fill="none" fill-rule="evenodd">
+ <path fill="#D8D8D8" d="M0 0h512v512H0z"></path>
+ <path fill="#979797" fill-rule="nonzero" d="M8 6.586l496 496v2.828L8 9.414z"></path>
+ <path fill="#979797" fill-rule="nonzero" d="M504 7.586v2.828l-496 496v-2.828z"></path>
+ </g>
+ </svg>',
+ ],
+ /** SVG: Sanitization */
+ [
+ [
+ 'type' => 'svg',
+ 'icon' => 'dirty',
+ 'title' => '',
+ 'hidden' => false,
+ 'classes' => '',
+ 'attributes' => [],
+ ],
+ [],
+ '<svg class="o-icon o-icon-svg svg-dirty" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 728 242" role="img">
+ <path fill-rule="evenodd" d="M139.05,117.4938 C139.05,129.1958 137.603,139.9498 134.718,149.7578 C131.832,159.5708 127.634,168.0768 122.129,175.2728 C116.623,182.4748 109.764,188.0558 101.554,192.0128 C93.344,195.9698 83.915,197.9538 73.267,197.9538 C65.142,197.9538 57.877,195.9278 51.473,191.8788 C45.064,187.8288 40.057,182.6558 36.45,176.3528 L36.45,240.6138 L25.194,240.6138 C21.976,240.6138 18.85,240.0268 15.811,238.8578 C12.774,237.6858 10.091,236.0228 7.77,233.8638 C5.446,231.7038 3.569,229.0918 2.144,226.0338 C0.713,222.9698 0,219.4608 0,215.5038 L0,127.4828 C0,115.4258 1.393,104.3558 4.185,94.2728 C6.974,84.1948 11.34,75.5548 17.28,68.3538 C23.22,61.1558 30.78,55.5748 39.96,51.6128 C49.14,47.6558 60.117,45.6728 72.9,45.6728 C82.62,45.6728 91.53,47.6978 99.63,51.7488 C107.729,55.7978 114.703,61.1558 120.555,67.8138 C126.402,74.4748 130.95,82.1238 134.19,90.7628 C137.43,99.4038 139.05,108.3128 139.05,117.4938 Z M101.79,126.9438 C101.79,109.6638 98.942,97.1548 93.247,89.4138 C87.552,81.6758 78.831,77.8028 67.087,77.8028 C56.966,77.8028 49.241,81.7178 43.909,89.5478 C38.576,97.3788 35.91,107.5958 35.91,120.1938 C35.91,134.7728 39.205,146.0248 45.803,153.9438 C52.401,161.8658 61.121,165.8238 71.968,165.8238 C80.823,165.8238 88.007,162.2708 93.521,155.1588 C99.031,148.0488 101.79,138.6458 101.79,126.9438 Z M267.5684,194.7134 C260.0084,194.7134 254.0224,192.6464 249.6134,188.5034 C245.2014,184.3644 242.9994,178.3364 242.9994,170.4134 L242.9994,111.0134 C242.9994,105.0734 242.2264,99.9894 240.6914,95.7584 C239.1554,91.5304 237.0754,88.1094 234.4514,85.4984 C231.8274,82.8914 228.7524,80.9544 225.2244,79.6934 C221.6984,78.4364 217.9434,77.8034 213.9644,77.8034 C211.0714,77.8034 208.0844,78.3894 205.0124,79.5584 C201.9374,80.7314 199.0894,82.6634 196.4654,85.3634 C193.8414,88.0634 191.7194,91.5734 190.0904,95.8934 C188.4634,100.2134 187.6484,105.6134 187.6484,112.0934 L187.6484,194.7134 L175.8574,194.7134 C167.2764,194.7134 161.0244,192.5534 157.0914,188.2334 C153.1604,183.9134 151.1984,177.9734 151.1984,170.4134 L151.1984,0.3134 L162.4544,0.3134 C171.0314,0.3134 177.4184,2.4734 181.6204,6.7934 C185.8174,11.1134 187.9194,16.6944 187.9194,23.5334 L188.1884,65.1134 C189.4454,62.9534 191.2014,60.7514 193.4534,58.4984 C195.7024,56.2504 198.1784,54.1784 200.8794,52.2884 C203.5784,50.3984 206.5484,48.8244 209.7894,47.5634 C213.0284,46.3064 216.3574,45.6734 219.7784,45.6734 C238.6784,45.6734 253.3474,51.1194 263.7894,62.0084 C274.2254,72.9014 279.4484,88.6954 279.4484,109.3934 L279.4484,194.7134 L267.5684,194.7134 Z M436.0442,117.4938 C436.0442,129.1958 434.5982,139.9498 431.7122,149.7578 C428.8272,159.5708 424.6282,168.0768 419.1242,175.2728 C413.6182,182.4748 406.7582,188.0558 398.5482,192.0128 C390.3392,195.9698 380.9102,197.9538 370.2622,197.9538 C362.1372,197.9538 354.8722,195.9278 348.4682,191.8788 C342.0592,187.8288 337.0522,182.6558 333.4442,176.3528 L333.4442,240.6138 L322.1882,240.6138 C318.9702,240.6138 315.8442,240.0268 312.8062,238.8578 C309.7682,237.6858 307.0862,236.0228 304.7652,233.8638 C302.4412,231.7038 300.5632,229.0918 299.1382,226.0338 C297.7082,222.9698 296.9942,219.4608 296.9942,215.5038 L296.9942,127.4828 C296.9942,115.4258 298.3872,104.3558 301.1802,94.2728 C303.9682,84.1948 308.3352,75.5548 314.2742,68.3538 C320.2152,61.1558 327.7742,55.5748 336.9542,51.6128 C346.1352,47.6558 357.1112,45.6728 369.8942,45.6728 C379.6142,45.6728 388.5242,47.6978 396.6252,51.7488 C404.7242,55.7978 411.6982,61.1558 417.5502,67.8138 C423.3972,74.4748 427.9442,82.1238 431.1842,90.7628 C434.4252,99.4038 436.0442,108.3128 436.0442,117.4938 Z M398.7842,126.9438 C398.7842,109.6638 395.9362,97.1548 390.2412,89.4138 C384.5462,81.6758 375.8262,77.8028 364.0812,77.8028 C353.9602,77.8028 346.2352,81.7178 340.9032,89.5478 C335.5712,97.3788 332.9042,107.5958 332.9042,120.1938 C332.9042,134.7728 336.1992,146.0248 342.7982,153.9438 C349.3952,161.8658 358.1162,165.8238 368.9622,165.8238 C377.8172,165.8238 385.0022,162.2708 390.5152,155.1588 C396.0252,148.0488 398.7842,138.6458 398.7842,126.9438 Z M581.5745,137.4732 C581.5745,146.8342 579.8615,155.1152 576.4445,162.3132 C573.0225,169.5152 568.3855,175.5892 562.5395,180.5382 C556.6875,185.4912 549.9375,189.2252 542.2895,191.7432 C534.6355,194.2662 526.5835,195.5232 518.1245,195.5232 L498.1435,195.5232 C463.7605,195.5232 446.5745,180.8552 446.5745,151.5132 L446.5745,17.3232 C448.7345,16.6062 451.7925,15.7502 455.7535,14.7582 C459.7105,13.7712 463.9895,12.8262 468.5795,11.9232 C473.1685,11.0252 477.8475,10.3032 482.6195,9.7632 C487.3855,9.2232 491.6645,8.9532 495.4445,8.9532 L517.8535,8.9532 C526.6705,8.9532 534.7715,10.0792 542.1545,12.3282 C549.5325,14.5812 555.9235,17.8212 561.3245,22.0482 C566.7235,26.2802 570.9095,31.4092 573.8785,37.4382 C576.8485,43.4712 578.3345,50.2632 578.3345,57.8232 C578.3345,68.0832 575.7225,76.5002 570.5035,83.0692 C565.2815,89.6412 558.0845,94.2732 548.9045,96.9732 C553.5835,98.2352 557.9025,100.3062 561.8645,103.1832 C565.8215,106.0652 569.2895,109.3512 572.2585,113.0382 C575.2285,116.7302 577.5245,120.7332 579.1435,125.0532 C580.7635,129.3732 581.5745,133.5162 581.5745,137.4732 Z M544.3135,138.5532 C544.3135,128.4752 541.7495,121.5432 536.6195,117.7632 C531.4895,113.9832 523.5245,112.0932 512.7235,112.0932 L483.2935,112.0932 L483.2935,150.1632 C483.2935,153.4042 484.8215,156.1502 487.8835,158.3982 C490.9425,160.6512 494.8115,161.7732 499.4945,161.7732 L514.6145,161.7732 C524.6925,161.7732 532.1645,159.6592 537.0245,155.4282 C541.8835,151.2012 544.3135,145.5742 544.3135,138.5532 Z M541.3435,61.0632 C541.3435,57.1062 540.4875,53.7312 538.7795,50.9382 C537.0665,48.1502 534.8645,45.9432 532.1645,44.3232 C529.4635,42.7032 526.4015,41.5342 522.9845,40.8132 C519.5625,40.0962 516.1415,39.7332 512.7235,39.7332 L498.9545,39.7332 C496.6125,39.7332 494.0005,39.9612 491.1245,40.4082 C488.2425,40.8602 485.5425,41.2642 483.0245,41.6232 L483.0245,83.4732 L511.3745,83.4732 C519.6515,83.4732 526.7175,81.7182 532.5695,78.2082 C538.4165,74.6982 541.3435,68.9862 541.3435,61.0632 Z M727.3733,137.4732 C727.3733,146.8342 725.6603,155.1152 722.2433,162.3132 C718.8213,169.5152 714.1843,175.5892 708.3383,180.5382 C702.4863,185.4912 695.7363,189.2252 688.0883,191.7432 C680.4343,194.2662 672.3823,195.5232 663.9233,195.5232 L643.9423,195.5232 C609.5593,195.5232 592.3733,180.8552 592.3733,151.5132 L592.3733,17.3232 C594.5333,16.6062 597.5913,15.7502 601.5523,14.7582 C605.5093,13.7712 609.7883,12.8262 614.3783,11.9232 C618.9673,11.0252 623.6463,10.3032 628.4183,9.7632 C633.1843,9.2232 637.4633,8.9532 641.2433,8.9532 L663.6523,8.9532 C672.4693,8.9532 680.5703,10.0792 687.9533,12.3282 C695.3313,14.5812 701.7223,17.8212 707.1233,22.0482 C712.5223,26.2802 716.7083,31.4092 719.6773,37.4382 C722.6473,43.4712 724.1333,50.2632 724.1333,57.8232 C724.1333,68.0832 721.5213,76.5002 716.3023,83.0692 C711.0803,89.6412 703.8833,94.2732 694.7033,96.9732 C699.3823,98.2352 703.7013,100.3062 707.6633,103.1832 C711.6203,106.0652 715.0883,109.3512 718.0573,113.0382 C721.0273,116.7302 723.3233,120.7332 724.9423,125.0532 C726.5623,129.3732 727.3733,133.5162 727.3733,137.4732 Z M690.1123,138.5532 C690.1123,128.4752 687.5483,121.5432 682.4183,117.7632 C677.2883,113.9832 669.3233,112.0932 658.5223,112.0932 L629.0923,112.0932 L629.0923,150.1632 C629.0923,153.4042 630.6203,156.1502 633.6823,158.3982 C636.7413,160.6512 640.6103,161.7732 645.2933,161.7732 L660.4133,161.7732 C670.4913,161.7732 677.9633,159.6592 682.8233,155.4282 C687.6823,151.2012 690.1123,145.5742 690.1123,138.5532 Z M687.1423,61.0632 C687.1423,57.1062 686.2863,53.7312 684.5783,50.9382 C682.8653,48.1502 680.6633,45.9432 677.9633,44.3232 C675.2623,42.7032 672.2003,41.5342 668.7833,40.8132 C665.3613,40.0962 661.9403,39.7332 658.5223,39.7332 L644.7533,39.7332 C642.4113,39.7332 639.7993,39.9612 636.9233,40.4082 C634.0413,40.8602 631.3413,41.2642 628.8233,41.6232 L628.8233,83.4732 L657.1733,83.4732 C665.4503,83.4732 672.5163,81.7182 678.3683,78.2082 C684.2153,74.6982 687.1423,68.9862 687.1423,61.0632z"></path>
+ </svg>',
+ ],
+ ];
+ }
+
+ /**
+ * @dataProvider data_template_icon_extension
+ */
+ public function test_template_icon_extension($vars, $lang_vars, $expected)
+ {
+ $file = 'extension_icon_test.html';
+
+ $this->template->set_filenames(['test' => $file]);
+ $this->template->assign_vars($vars);
+
+ foreach ($lang_vars as $name => $value)
+ {
+ self::$language_reflection_lang->setValue($this->lang, array_merge(
+ self::$language_reflection_lang->getValue($this->lang),
+ [$name => $value]
+ ));
+ }
+
+ $expected = str_replace(["\n", "\r", "\t"], '', $expected);
+ $output = str_replace(["\n", "\r", "\t"], '', $this->display('test'));
+
+ /**
+ * SVGs need their random identifier replaced (normalized).
+ * The 'user' is a PNG, but not existent, so it returns a 404 SVG.
+ */
+ if ($vars['type'] === 'svg' || $vars['icon'] === 'user')
+ {
+ $prefix = strtolower(str_replace(' ', '_', $vars['title'])) . '-';
+ $output = preg_replace('/' . $prefix . '\d+/', $prefix . '123456789', $output);
+ }
+
+ $this->assertEquals($expected, $output, "Testing {$file}");
+ }
}
diff --git a/tests/template/includephp_test.php b/tests/template/includephp_test.php
index 722e10e42d..baf2eed11b 100644
--- a/tests/template/includephp_test.php
+++ b/tests/template/includephp_test.php
@@ -11,6 +11,8 @@
*
*/
+use phpbb\filesystem\helper as filesystem_helper;
+
require_once dirname(__FILE__) . '/template_test_case.php';
class phpbb_template_includephp_test extends phpbb_template_template_test_case
@@ -39,9 +41,8 @@ class phpbb_template_includephp_test extends phpbb_template_template_test_case
{
global $phpbb_root_path;
- $filesystem = new \phpbb\filesystem\filesystem();
$path_to_php = str_replace('\\', '/', dirname(__FILE__)) . '/templates/_dummy_include.php.inc';
- $this->assertTrue($filesystem->is_absolute_path($path_to_php));
+ $this->assertTrue(filesystem_helper::is_absolute_path($path_to_php));
$template_text = "Path is absolute.\n<!-- INCLUDEPHP $path_to_php -->";
$cache_dir = $phpbb_root_path . 'cache/';
diff --git a/tests/template/template_allfolder_test.php b/tests/template/template_allfolder_test.php
index a9a8ecc287..de4d663fb8 100644
--- a/tests/template/template_allfolder_test.php
+++ b/tests/template/template_allfolder_test.php
@@ -39,7 +39,6 @@ class phpbb_template_allfolder_test extends phpbb_template_template_test_case
new \phpbb\symfony_request(
new phpbb_mock_request()
),
- $filesystem,
$this->createMock('\phpbb\request\request'),
$phpbb_root_path,
$phpEx
@@ -59,7 +58,7 @@ class phpbb_template_allfolder_test extends phpbb_template_template_test_case
$container = new phpbb_mock_container_builder();
$cache_path = $phpbb_root_path . 'cache/twig';
$context = new \phpbb\template\context();
- $loader = new \phpbb\template\twig\loader(new \phpbb\filesystem\filesystem(), '');
+ $loader = new \phpbb\template\twig\loader('');
$twig = new \phpbb\template\twig\environment(
$config,
$filesystem,
diff --git a/tests/template/template_events_test.php b/tests/template/template_events_test.php
index 9243390937..7693e84db9 100644
--- a/tests/template/template_events_test.php
+++ b/tests/template/template_events_test.php
@@ -144,7 +144,6 @@ Zeta test event in all',
new \phpbb\symfony_request(
new phpbb_mock_request()
),
- new \phpbb\filesystem\filesystem(),
$this->createMock('\phpbb\request\request'),
$phpbb_root_path,
$phpEx
@@ -153,7 +152,7 @@ Zeta test event in all',
$container = new phpbb_mock_container_builder();
$cache_path = $phpbb_root_path . 'cache/twig';
$context = new \phpbb\template\context();
- $loader = new \phpbb\template\twig\loader(new \phpbb\filesystem\filesystem(), '');
+ $loader = new \phpbb\template\twig\loader('');
$twig = new \phpbb\template\twig\environment(
$config,
$filesystem,
diff --git a/tests/template/template_includecss_test.php b/tests/template/template_includecss_test.php
index 5f9875a556..9f90a00b1a 100644
--- a/tests/template/template_includecss_test.php
+++ b/tests/template/template_includecss_test.php
@@ -34,7 +34,6 @@ class phpbb_template_template_includecss_test extends phpbb_template_template_te
new \phpbb\symfony_request(
new phpbb_mock_request()
),
- $filesystem,
$this->createMock('\phpbb\request\request'),
$phpbb_root_path,
$phpEx
@@ -45,7 +44,7 @@ class phpbb_template_template_includecss_test extends phpbb_template_template_te
$container = new phpbb_mock_container_builder();
$cache_path = $phpbb_root_path . 'cache/twig';
$context = new \phpbb\template\context();
- $loader = new \phpbb\template\twig\loader(new \phpbb\filesystem\filesystem(), '');
+ $loader = new \phpbb\template\twig\loader('');
$twig = new \phpbb\template\twig\environment(
$config,
$filesystem,
diff --git a/tests/template/template_test_case.php b/tests/template/template_test_case.php
index 0389088ec8..3a64d70f30 100644
--- a/tests/template/template_test_case.php
+++ b/tests/template/template_test_case.php
@@ -86,7 +86,6 @@ class phpbb_template_template_test_case extends phpbb_test_case
new \phpbb\symfony_request(
new phpbb_mock_request()
),
- $filesystem,
$this->createMock('\phpbb\request\request'),
$phpbb_root_path,
$phpEx
@@ -97,7 +96,7 @@ class phpbb_template_template_test_case extends phpbb_test_case
$container = new phpbb_mock_container_builder();
$cache_path = $phpbb_root_path . 'cache/twig';
$context = new \phpbb\template\context();
- $loader = new \phpbb\template\twig\loader(new \phpbb\filesystem\filesystem(), '');
+ $loader = new \phpbb\template\twig\loader('');
$twig = new \phpbb\template\twig\environment(
$config,
$filesystem,
diff --git a/tests/template/template_test_case_with_tree.php b/tests/template/template_test_case_with_tree.php
index c0238b6f03..d21baa3fd4 100644
--- a/tests/template/template_test_case_with_tree.php
+++ b/tests/template/template_test_case_with_tree.php
@@ -28,7 +28,6 @@ class phpbb_template_template_test_case_with_tree extends phpbb_template_templat
new \phpbb\symfony_request(
new phpbb_mock_request()
),
- $filesystem,
$this->createMock('\phpbb\request\request'),
$phpbb_root_path,
$phpEx
@@ -40,7 +39,7 @@ class phpbb_template_template_test_case_with_tree extends phpbb_template_templat
$container = new phpbb_mock_container_builder();
$cache_path = $phpbb_root_path . 'cache/twig';
$context = new \phpbb\template\context();
- $loader = new \phpbb\template\twig\loader(new \phpbb\filesystem\filesystem(), '');
+ $loader = new \phpbb\template\twig\loader('');
$twig = new \phpbb\template\twig\environment(
$config,
$filesystem,
diff --git a/tests/template/templates/extension_icon_test.html b/tests/template/templates/extension_icon_test.html
new file mode 100644
index 0000000000..4ea6eb0410
--- /dev/null
+++ b/tests/template/templates/extension_icon_test.html
@@ -0,0 +1 @@
+{{ Icon(type, icon, title, hidden, classes, attributes) }}
diff --git a/tests/template/templates/svg/dirty.svg b/tests/template/templates/svg/dirty.svg
new file mode 100644
index 0000000000..29c1500ffe
--- /dev/null
+++ b/tests/template/templates/svg/dirty.svg
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" >
+<svg viewBox="0 0 728 242" xmlns="http://www.w3.org/2000/svg" class="c-hero-logo t-hero-logo" aria-labelledby="site_title">
+ <title id="site_title">phpBB</title>
+ <path fill-rule="evenodd" d="M139.05,117.4938 C139.05,129.1958 137.603,139.9498 134.718,149.7578 C131.832,159.5708 127.634,168.0768 122.129,175.2728 C116.623,182.4748 109.764,188.0558 101.554,192.0128 C93.344,195.9698 83.915,197.9538 73.267,197.9538 C65.142,197.9538 57.877,195.9278 51.473,191.8788 C45.064,187.8288 40.057,182.6558 36.45,176.3528 L36.45,240.6138 L25.194,240.6138 C21.976,240.6138 18.85,240.0268 15.811,238.8578 C12.774,237.6858 10.091,236.0228 7.77,233.8638 C5.446,231.7038 3.569,229.0918 2.144,226.0338 C0.713,222.9698 0,219.4608 0,215.5038 L0,127.4828 C0,115.4258 1.393,104.3558 4.185,94.2728 C6.974,84.1948 11.34,75.5548 17.28,68.3538 C23.22,61.1558 30.78,55.5748 39.96,51.6128 C49.14,47.6558 60.117,45.6728 72.9,45.6728 C82.62,45.6728 91.53,47.6978 99.63,51.7488 C107.729,55.7978 114.703,61.1558 120.555,67.8138 C126.402,74.4748 130.95,82.1238 134.19,90.7628 C137.43,99.4038 139.05,108.3128 139.05,117.4938 Z M101.79,126.9438 C101.79,109.6638 98.942,97.1548 93.247,89.4138 C87.552,81.6758 78.831,77.8028 67.087,77.8028 C56.966,77.8028 49.241,81.7178 43.909,89.5478 C38.576,97.3788 35.91,107.5958 35.91,120.1938 C35.91,134.7728 39.205,146.0248 45.803,153.9438 C52.401,161.8658 61.121,165.8238 71.968,165.8238 C80.823,165.8238 88.007,162.2708 93.521,155.1588 C99.031,148.0488 101.79,138.6458 101.79,126.9438 Z M267.5684,194.7134 C260.0084,194.7134 254.0224,192.6464 249.6134,188.5034 C245.2014,184.3644 242.9994,178.3364 242.9994,170.4134 L242.9994,111.0134 C242.9994,105.0734 242.2264,99.9894 240.6914,95.7584 C239.1554,91.5304 237.0754,88.1094 234.4514,85.4984 C231.8274,82.8914 228.7524,80.9544 225.2244,79.6934 C221.6984,78.4364 217.9434,77.8034 213.9644,77.8034 C211.0714,77.8034 208.0844,78.3894 205.0124,79.5584 C201.9374,80.7314 199.0894,82.6634 196.4654,85.3634 C193.8414,88.0634 191.7194,91.5734 190.0904,95.8934 C188.4634,100.2134 187.6484,105.6134 187.6484,112.0934 L187.6484,194.7134 L175.8574,194.7134 C167.2764,194.7134 161.0244,192.5534 157.0914,188.2334 C153.1604,183.9134 151.1984,177.9734 151.1984,170.4134 L151.1984,0.3134 L162.4544,0.3134 C171.0314,0.3134 177.4184,2.4734 181.6204,6.7934 C185.8174,11.1134 187.9194,16.6944 187.9194,23.5334 L188.1884,65.1134 C189.4454,62.9534 191.2014,60.7514 193.4534,58.4984 C195.7024,56.2504 198.1784,54.1784 200.8794,52.2884 C203.5784,50.3984 206.5484,48.8244 209.7894,47.5634 C213.0284,46.3064 216.3574,45.6734 219.7784,45.6734 C238.6784,45.6734 253.3474,51.1194 263.7894,62.0084 C274.2254,72.9014 279.4484,88.6954 279.4484,109.3934 L279.4484,194.7134 L267.5684,194.7134 Z M436.0442,117.4938 C436.0442,129.1958 434.5982,139.9498 431.7122,149.7578 C428.8272,159.5708 424.6282,168.0768 419.1242,175.2728 C413.6182,182.4748 406.7582,188.0558 398.5482,192.0128 C390.3392,195.9698 380.9102,197.9538 370.2622,197.9538 C362.1372,197.9538 354.8722,195.9278 348.4682,191.8788 C342.0592,187.8288 337.0522,182.6558 333.4442,176.3528 L333.4442,240.6138 L322.1882,240.6138 C318.9702,240.6138 315.8442,240.0268 312.8062,238.8578 C309.7682,237.6858 307.0862,236.0228 304.7652,233.8638 C302.4412,231.7038 300.5632,229.0918 299.1382,226.0338 C297.7082,222.9698 296.9942,219.4608 296.9942,215.5038 L296.9942,127.4828 C296.9942,115.4258 298.3872,104.3558 301.1802,94.2728 C303.9682,84.1948 308.3352,75.5548 314.2742,68.3538 C320.2152,61.1558 327.7742,55.5748 336.9542,51.6128 C346.1352,47.6558 357.1112,45.6728 369.8942,45.6728 C379.6142,45.6728 388.5242,47.6978 396.6252,51.7488 C404.7242,55.7978 411.6982,61.1558 417.5502,67.8138 C423.3972,74.4748 427.9442,82.1238 431.1842,90.7628 C434.4252,99.4038 436.0442,108.3128 436.0442,117.4938 Z M398.7842,126.9438 C398.7842,109.6638 395.9362,97.1548 390.2412,89.4138 C384.5462,81.6758 375.8262,77.8028 364.0812,77.8028 C353.9602,77.8028 346.2352,81.7178 340.9032,89.5478 C335.5712,97.3788 332.9042,107.5958 332.9042,120.1938 C332.9042,134.7728 336.1992,146.0248 342.7982,153.9438 C349.3952,161.8658 358.1162,165.8238 368.9622,165.8238 C377.8172,165.8238 385.0022,162.2708 390.5152,155.1588 C396.0252,148.0488 398.7842,138.6458 398.7842,126.9438 Z M581.5745,137.4732 C581.5745,146.8342 579.8615,155.1152 576.4445,162.3132 C573.0225,169.5152 568.3855,175.5892 562.5395,180.5382 C556.6875,185.4912 549.9375,189.2252 542.2895,191.7432 C534.6355,194.2662 526.5835,195.5232 518.1245,195.5232 L498.1435,195.5232 C463.7605,195.5232 446.5745,180.8552 446.5745,151.5132 L446.5745,17.3232 C448.7345,16.6062 451.7925,15.7502 455.7535,14.7582 C459.7105,13.7712 463.9895,12.8262 468.5795,11.9232 C473.1685,11.0252 477.8475,10.3032 482.6195,9.7632 C487.3855,9.2232 491.6645,8.9532 495.4445,8.9532 L517.8535,8.9532 C526.6705,8.9532 534.7715,10.0792 542.1545,12.3282 C549.5325,14.5812 555.9235,17.8212 561.3245,22.0482 C566.7235,26.2802 570.9095,31.4092 573.8785,37.4382 C576.8485,43.4712 578.3345,50.2632 578.3345,57.8232 C578.3345,68.0832 575.7225,76.5002 570.5035,83.0692 C565.2815,89.6412 558.0845,94.2732 548.9045,96.9732 C553.5835,98.2352 557.9025,100.3062 561.8645,103.1832 C565.8215,106.0652 569.2895,109.3512 572.2585,113.0382 C575.2285,116.7302 577.5245,120.7332 579.1435,125.0532 C580.7635,129.3732 581.5745,133.5162 581.5745,137.4732 Z M544.3135,138.5532 C544.3135,128.4752 541.7495,121.5432 536.6195,117.7632 C531.4895,113.9832 523.5245,112.0932 512.7235,112.0932 L483.2935,112.0932 L483.2935,150.1632 C483.2935,153.4042 484.8215,156.1502 487.8835,158.3982 C490.9425,160.6512 494.8115,161.7732 499.4945,161.7732 L514.6145,161.7732 C524.6925,161.7732 532.1645,159.6592 537.0245,155.4282 C541.8835,151.2012 544.3135,145.5742 544.3135,138.5532 Z M541.3435,61.0632 C541.3435,57.1062 540.4875,53.7312 538.7795,50.9382 C537.0665,48.1502 534.8645,45.9432 532.1645,44.3232 C529.4635,42.7032 526.4015,41.5342 522.9845,40.8132 C519.5625,40.0962 516.1415,39.7332 512.7235,39.7332 L498.9545,39.7332 C496.6125,39.7332 494.0005,39.9612 491.1245,40.4082 C488.2425,40.8602 485.5425,41.2642 483.0245,41.6232 L483.0245,83.4732 L511.3745,83.4732 C519.6515,83.4732 526.7175,81.7182 532.5695,78.2082 C538.4165,74.6982 541.3435,68.9862 541.3435,61.0632 Z M727.3733,137.4732 C727.3733,146.8342 725.6603,155.1152 722.2433,162.3132 C718.8213,169.5152 714.1843,175.5892 708.3383,180.5382 C702.4863,185.4912 695.7363,189.2252 688.0883,191.7432 C680.4343,194.2662 672.3823,195.5232 663.9233,195.5232 L643.9423,195.5232 C609.5593,195.5232 592.3733,180.8552 592.3733,151.5132 L592.3733,17.3232 C594.5333,16.6062 597.5913,15.7502 601.5523,14.7582 C605.5093,13.7712 609.7883,12.8262 614.3783,11.9232 C618.9673,11.0252 623.6463,10.3032 628.4183,9.7632 C633.1843,9.2232 637.4633,8.9532 641.2433,8.9532 L663.6523,8.9532 C672.4693,8.9532 680.5703,10.0792 687.9533,12.3282 C695.3313,14.5812 701.7223,17.8212 707.1233,22.0482 C712.5223,26.2802 716.7083,31.4092 719.6773,37.4382 C722.6473,43.4712 724.1333,50.2632 724.1333,57.8232 C724.1333,68.0832 721.5213,76.5002 716.3023,83.0692 C711.0803,89.6412 703.8833,94.2732 694.7033,96.9732 C699.3823,98.2352 703.7013,100.3062 707.6633,103.1832 C711.6203,106.0652 715.0883,109.3512 718.0573,113.0382 C721.0273,116.7302 723.3233,120.7332 724.9423,125.0532 C726.5623,129.3732 727.3733,133.5162 727.3733,137.4732 Z M690.1123,138.5532 C690.1123,128.4752 687.5483,121.5432 682.4183,117.7632 C677.2883,113.9832 669.3233,112.0932 658.5223,112.0932 L629.0923,112.0932 L629.0923,150.1632 C629.0923,153.4042 630.6203,156.1502 633.6823,158.3982 C636.7413,160.6512 640.6103,161.7732 645.2933,161.7732 L660.4133,161.7732 C670.4913,161.7732 677.9633,159.6592 682.8233,155.4282 C687.6823,151.2012 690.1123,145.5742 690.1123,138.5532 Z M687.1423,61.0632 C687.1423,57.1062 686.2863,53.7312 684.5783,50.9382 C682.8653,48.1502 680.6633,45.9432 677.9633,44.3232 C675.2623,42.7032 672.2003,41.5342 668.7833,40.8132 C665.3613,40.0962 661.9403,39.7332 658.5223,39.7332 L644.7533,39.7332 C642.4113,39.7332 639.7993,39.9612 636.9233,40.4082 C634.0413,40.8602 631.3413,41.2642 628.8233,41.6232 L628.8233,83.4732 L657.1733,83.4732 C665.4503,83.4732 672.5163,81.7182 678.3683,78.2082 C684.2153,74.6982 687.1423,68.9862 687.1423,61.0632z"></path>
+</svg>
diff --git a/tests/template/templates/svg/pencil.svg b/tests/template/templates/svg/pencil.svg
new file mode 100644
index 0000000000..c9c021d811
--- /dev/null
+++ b/tests/template/templates/svg/pencil.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><title>My fake title!</title><path d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/><path d="M0 0h24v24H0z" fill="none"/></svg>
diff --git a/tests/template/templates/svg/phone.svg b/tests/template/templates/svg/phone.svg
new file mode 100644
index 0000000000..5fbfe196ba
--- /dev/null
+++ b/tests/template/templates/svg/phone.svg
@@ -0,0 +1 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path fill="none" d="M0 0h24v24H0z"/><path d="M20.01 15.38c-1.23 0-2.42-.2-3.53-.56-.35-.12-.74-.03-1.01.24l-1.57 1.97c-2.83-1.35-5.48-3.9-6.89-6.83l1.95-1.66c.27-.28.35-.67.24-1.02-.37-1.11-.56-2.3-.56-3.53 0-.54-.45-.99-.99-.99H4.19C3.65 3 3 3.24 3 3.99 3 13.28 10.73 21 20.01 21c.71 0 .99-.63.99-1.18v-3.45c0-.54-.45-.99-.99-.99z"/></svg>
diff --git a/tests/test_framework/phpbb_database_test_case.php b/tests/test_framework/phpbb_database_test_case.php
index 9b873fbf68..5ef545781c 100644
--- a/tests/test_framework/phpbb_database_test_case.php
+++ b/tests/test_framework/phpbb_database_test_case.php
@@ -60,7 +60,7 @@ abstract class phpbb_database_test_case extends TestCase
$setup_extensions = static::setup_extensions();
- $finder = new \phpbb\finder(new \phpbb\filesystem\filesystem(), $phpbb_root_path, null, $phpEx);
+ $finder = new \phpbb\finder($phpbb_root_path, null, $phpEx);
$finder->core_path('phpbb/db/migration/data/');
if (!empty($setup_extensions))
{
@@ -75,14 +75,13 @@ abstract class phpbb_database_test_case extends TestCase
if (!file_exists(self::$schema_file))
{
-
global $table_prefix;
$db = new \phpbb\db\driver\sqlite3();
$factory = new \phpbb\db\tools\factory();
$db_tools = $factory->get($db, true);
- $schema_generator = new \phpbb\db\migration\schema_generator($classes, new \phpbb\config\config(array()), $db, $db_tools, $phpbb_root_path, $phpEx, $table_prefix);
+ $schema_generator = new \phpbb\db\migration\schema_generator($classes, new \phpbb\config\config(array()), $db, $db_tools, $phpbb_root_path, $phpEx, $table_prefix, self::get_core_tables());
file_put_contents(self::$schema_file, json_encode($schema_generator->get_schema()));
}
@@ -353,4 +352,23 @@ abstract class phpbb_database_test_case extends TestCase
$this->assertTrue(true);
}
}
+
+ static public function get_core_tables() : array
+ {
+ global $phpbb_root_path, $table_prefix;
+
+ static $core_tables = [];
+
+ if (empty($tables))
+ {
+ $tables_yml_data = \Symfony\Component\Yaml\Yaml::parseFile($phpbb_root_path . '/config/default/container/tables.yml');
+
+ foreach ($tables_yml_data['parameters'] as $parameter => $table)
+ {
+ $core_tables[str_replace('tables.', '', $parameter)] = str_replace('%core.table_prefix%', $table_prefix, $table);
+ }
+ }
+
+ return $core_tables;
+ }
}
diff --git a/tests/test_framework/phpbb_database_test_connection_manager.php b/tests/test_framework/phpbb_database_test_connection_manager.php
index fec4709fbd..e4c1a194cc 100644
--- a/tests/test_framework/phpbb_database_test_connection_manager.php
+++ b/tests/test_framework/phpbb_database_test_connection_manager.php
@@ -365,15 +365,16 @@ class phpbb_database_test_connection_manager
{
global $phpbb_root_path, $phpEx, $table_prefix;
- $finder = new \phpbb\finder(new \phpbb\filesystem\filesystem(), $phpbb_root_path, null, $phpEx);
+ $finder = new \phpbb\finder($phpbb_root_path, null, $phpEx);
$classes = $finder->core_path('phpbb/db/migration/data/')
->get_classes();
$db = new \phpbb\db\driver\sqlite3();
$factory = new \phpbb\db\tools\factory();
$db_tools = $factory->get($db, true);
+ $tables = phpbb_database_test_case::get_core_tables();
- $schema_generator = new \phpbb\db\migration\schema_generator($classes, new \phpbb\config\config(array()), $db, $db_tools, $phpbb_root_path, $phpEx, $table_prefix);
+ $schema_generator = new \phpbb\db\migration\schema_generator($classes, new \phpbb\config\config(array()), $db, $db_tools, $phpbb_root_path, $phpEx, $table_prefix, $tables);
$db_table_schema = $schema_generator->get_schema();
}
diff --git a/tests/test_framework/phpbb_functional_test_case.php b/tests/test_framework/phpbb_functional_test_case.php
index 19062aa148..4f7271e313 100644
--- a/tests/test_framework/phpbb_functional_test_case.php
+++ b/tests/test_framework/phpbb_functional_test_case.php
@@ -249,6 +249,7 @@ class phpbb_functional_test_case extends phpbb_test_case
$phpbb_root_path,
$phpEx,
self::$config['table_prefix'],
+ phpbb_database_test_case::get_core_tables(),
array(),
new \phpbb\db\migration\helper()
);
@@ -259,7 +260,6 @@ class phpbb_functional_test_case extends phpbb_test_case
$container,
$db,
$config,
- new phpbb\filesystem\filesystem(),
self::$config['table_prefix'] . 'ext',
dirname(__FILE__) . '/',
$phpEx,
diff --git a/tests/test_framework/phpbb_session_test_case.php b/tests/test_framework/phpbb_session_test_case.php
index 530d8c6b48..18da5e9b08 100644
--- a/tests/test_framework/phpbb_session_test_case.php
+++ b/tests/test_framework/phpbb_session_test_case.php
@@ -29,14 +29,12 @@ abstract class phpbb_session_test_case extends phpbb_database_test_case
{
parent::setUp();
- global $symfony_request, $phpbb_filesystem, $phpbb_path_helper, $request, $phpbb_root_path, $phpEx;
+ global $symfony_request, $phpbb_path_helper, $request, $phpbb_root_path, $phpEx;
$symfony_request = new \phpbb\symfony_request(
new phpbb_mock_request()
);
- $phpbb_filesystem = new \phpbb\filesystem\filesystem();
$phpbb_path_helper = new \phpbb\path_helper(
$symfony_request,
- $phpbb_filesystem,
$this->createMock('\phpbb\request\request'),
$phpbb_root_path,
$phpEx
diff --git a/tests/test_framework/phpbb_ui_test_case.php b/tests/test_framework/phpbb_ui_test_case.php
index 243db39d69..1fbfd22dbe 100644
--- a/tests/test_framework/phpbb_ui_test_case.php
+++ b/tests/test_framework/phpbb_ui_test_case.php
@@ -486,6 +486,7 @@ class phpbb_ui_test_case extends phpbb_test_case
$phpbb_root_path,
$phpEx,
self::$config['table_prefix'],
+ phpbb_database_test_case::get_core_tables(),
array(),
new \phpbb\db\migration\helper()
);
@@ -497,7 +498,6 @@ class phpbb_ui_test_case extends phpbb_test_case
$container,
$db,
$config,
- new phpbb\filesystem(),
$user,
self::$config['table_prefix'] . 'ext',
dirname(__FILE__) . '/',
diff --git a/travis/check-stylesheet.sh b/travis/check-stylesheet.sh
new file mode 100755
index 0000000000..743b65db9b
--- /dev/null
+++ b/travis/check-stylesheet.sh
@@ -0,0 +1,24 @@
+#!/bin/bash
+#
+# This file is part of the phpBB Forum Software package.
+#
+# @copyright (c) phpBB Limited <https://www.phpbb.com>
+# @license GNU General Public License, version 2 (GPL-2.0)
+#
+# For full copyright and license information, please see
+# the docs/CREDITS.txt file.
+#
+set -e
+set +x
+
+NOTESTS=$1
+
+if [ "$NOTESTS" == '1' ]
+then
+ npm install -g > /dev/null
+ npm install > /dev/null
+ set -x
+ node_modules/stylelint/bin/stylelint.js "phpBB/styles/prosilver/theme/*.css"
+ # Disable admin stylelint for now
+ node_modules/stylelint/bin/stylelint.js "phpBB/adm/style/*.css"
+fi